0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

NECV30で8080側から8086側の関数を呼ぶ

0
Posted at

目的

昨日、NECのV30で8080の実験をする環境を整えました。
z80アセンブラで生成した機械語をV30実機上で実行

しかし今の方法では8080モードから8086モードへ戻って画面表示をして止めています。
今回は8080側から画面表示をする時にだけ8086モードへ遷移し、必要な処理をしてから又8080モードへ戻るように変更します。

8080側でCALLN命令を実行すると、IVTに実行した8086の処理へ飛べます。
8086側でiretを実行すると又8080側へ戻れます。

実装

20260920201348_7be7121884f7ef6dda3c125c7fdf18b7
nasm -f bin 8086.asm -o 8086.bin
z80asm -o 8080.bin 8080.asm
cat 8086.bin 8080.bin > test.bin
lsblk
sudo dd if=test.bin of=/dev/sdb bs=512 count=3 conv=notrunc
8086.asm
org 0x7C00

start:
    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, 0x7C00

    ; ディスクから第2(8086モード作業場),3(8080側)セクタを 0x7E00 に読み込む
    mov ah, 0x02        ; INT 13h 2: 読み込み
    mov al, 2           ; 読み込むセクタ数 = 1
    mov ch, 0           ; シリンダ = 0
    mov cl, 2           ; セクタ番号 = 2(1始まり)
    mov dh, 0           ; ヘッド = 0
    mov dl, 0x80        ; ドライブ番号
    mov bx, 0x7E00      ; 読み込み先アドレス
    int 0x13
    jc disk_error       ; エラー時に無限ループ

    ; 読み込んだコードへ跳ぶ(第2セクタ)
    jmp 0x0000:0x7E00

disk_error:
    jmp $

times 510-($-$$) db 0
dw 0xAA55


; 8080コード入口
%define TARGET_VECC 0x80
%define TARGET_ADDR (TARGET_VECC * 4)

%define IVT_40 (0x40 * 4)   ; 0x0100

BUFFER_ADDR equ 0x6000  ; 8080モード用の文字バッファ

start2:
    cli
    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, 0x7C00

    ; --- IVT 0x80 に 8080コードの開始地点を登録 ---
    mov word [TARGET_ADDR], 0x8000 ; オフセット
    mov word [TARGET_ADDR + 2], 0           ; セグメント(CS)
    
   ; IVT 0x40 に CS=0, IP=print_addr を登録
   print_addr equ (print - start2) + 0x7E00
   mov word [IVT_40], print_addr   ; IP
   mov word [IVT_40 + 2], 0        ; CS
    
    call init_8080buffer

    ; 8080モードへ移行
    db 0x0F, 0xFF, TARGET_VECC 
    
hlt_loop:
    hlt
    jmp hlt_loop
    
print:
    xor ax, ax
    mov ds, ax
    mov ax, 0xB800
    mov es, ax
    call copy_8080buffer_to_vram ; バッファからVRAMに複製
    iret

;-----------------------
; 8080用画面バッファからVRAMへ複製
;-----------------------
copy_8080buffer_to_vram:
    push ax
    push cx
    push si
    push di
    push ds
    push es

    xor ax, ax
    mov ds, ax
    mov si, BUFFER_ADDR

    mov ax, 0B800h
    mov es, ax
    xor di, di

    mov cx, 4000          ; 80*25*2
    rep movsb ; DS:SI → ES:DI

    pop es
    pop ds
    pop di
    pop si
    pop cx
    pop ax
    ret
    
;-----------------------
; 8080画面出力用BUFFER初期化
;-----------------------
init_8080buffer:
    push ax
    push cx
    push es
    push di

    ; ES=0x0000 DI=0x6000
    xor ax, ax
    mov es, ax
    mov di, BUFFER_ADDR

    mov cx, 80*25
    mov ax, 0x0720    ; AH=属性, AL=' '
    cld
    rep stosw ; ES:[DI] ← AX , DI ← DI + 2

    pop di
    pop es
    pop cx
    pop ax
    ret

times 512-($-start2) db 0
8080.asm
org 0x8000

ld a, 0
ld b, 9   ; 9回ループ

sum_loop:
    add a, b
    dec b
    jp nz, sum_loop

    ; ここでAに合計が入っている (45)
    ; ASCII 55=- よって-が表示される
    
    ld (0x6000), a
    ld a, 0x4f
    ld (0x6001), a

    ; CALLN 40h → IVT 0x40 の 8086 print を呼ぶ
    db 0xED, 0xED, 0x40 ; calln 0x40

    ;db 0xed,0xfd;
    
ds 512 - ($ - 0x8000)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?