BREAK実験
PCからZ80プログラムのデバッグができるよう、BREAKサブルーチンを作ってみました。
call BREAK
を実行するとレジスタの内容をRAMにダンプしてHALTします。
PCからはBUSRQでRAMを覗くなり書き換えるなりして、気が済んだらNMIでZ80の実行を再開させます。
ORG_PG: equ 0x0800 STACK: equ 0xf000 REGDMP: equ 0xc000 org 0x0000 ld sp,STACK ; Turn off LED ld a,0 out 0,a ; Jump to the entry point jp ORG_PG ; NMI: Continue from the next instruction of "call BREAK" org 0x0066 retn BREAK: ; Save A, BC, DE, HL, IX, IY ld (REGDMP),a ld (REGDMP+1),a ; @TODO save flag register ld (REGDMP+2),bc ld (REGDMP+4),de ld (REGDMP+6),hl ld (REGDMP+8),ix ld (REGDMP+10),iy ; Save SP, PC ld (REGDMP+12),sp pop hl push hl ld (REGDMP+14),hl ld hl,(REGDMP+6) ; It's time for Arduino to control the bus halt ; Returns here from NMI ret ; Main program org ORG_PG ld a,0xAA ld bc,0x1234 ld de,0x5678 ld hl,0x9ABC call BREAK ; Turn on LED ld a,1 out 0,a halt
BREAK後にREGDMPのデータを覗くと…
cmd?> dump c000 16 AA AA 34 12 78 56 BC 9A AF BF 00 00 FE EF 0E 08
とりあえず動作する模様。080EH がld a,1
のアドレスです。
はじめNMIがPCを退避することを分かってなかったので、SPの位置が想定とズレてしまいプログラム暴走しまくりでした。
これだけ見事に間違えれば NMI → RETN のセットは忘れないでしょう。
[残課題]
次はCUIツールを改良します。現状はプロセス内の独自プロンプトから連続的にコマンド入力する形式ですが、git のように1コマンド1プロセスとした方が便利だしメンテも楽そうです。