2012.7.25
前へ
次へ
ホームページトップへ戻る

復活!CP/M ワンボードマイコンでCP/Mを!
CP/MがTK−80互換のワンボードマイコンの上で復活します
ND80ZVとMYCPU80の上でCP/Mが走ります

[第182回]


●ブレーク処理プログラム

前回および前々回では、ND80ZVのZB3BASICのマシン語デバッグ機能のひとつであります、ブレークポイントの設定とブレーク時のレジスタダンプについて説明をいたしました。
マシン語デバッグには欠かせないブレークとレジスタダンプ機能ですが、一体どういう仕組みなのか興味をお持ちの方も多いと思います。
そこで今回はブレーク処理プログラムについて、実際のリストをお見せして、それをもとに簡単な説明を加えてみたいと思います。

前回までのところでは、ND80ZVシステムROMに含まれておりますZB3BASICのもともとのブレーク機能を、フルRAMの状態で機能するようにプログラム変更して、それを使ってMBASICやFORTRAN80の解析を行なったことについて書きましたが、今回説明に使うリストはそのような変更を行なう前のものです。
ものには順序というものがありますので、まずは順をおって説明をしていくことにいたします。

ブレーク機能はそれほど難しいものでも、複雑なものでもなく、TK−80モニタにも搭載されている機能です。
基本は1バイトのサブルーチンコール命令RSTです。
8080やZ80にはRST0〜RST7の8通りの命令があり、RST0以外ならいずれを使ってもよいのですが一般にはRST7(命令コードFF)が使われます。

考え方は意外に簡単です。
あらかじめブレーク後の処理プログラムをRST7のジャンプ先(正確にはコール先)アドレス(0038H)に書いておいて、あとはブレークしたいアドレスに書かれている命令をFFで置き換えるだけです(このときそこに書かれていた命令コードはワークエリアに保存しておきます)。

下はあるプログラムの一部です。

8050 3E05   LD A,05
8052 D381   OUT (81),A

ここで、8050にブレークポイントを設定します。
ブレークポイントの設定コマンドはBPです。
BP 8050[Enter]
というように使います。

上で書きましたように、ブレークポイントの設定プログラムは、指定されたアドレスのメモリ内容をワークエリアに保存した上で、そこをFFで書き換えます。

8050 FF05 ………3Eはワークエリアに保存する
8052 D381

このように書き換えたあと、そのプログラムを実行します。
すると、アドレス8050Hに来ると、命令コードのFFが実行されるため、アドレス0038Hにジャンプします。
アドレス0038Hには、ブレーク処理ルーチンへのジャンプ命令が書いてありますから、そこでブレーク処理が行なわれます。

ブレーク処理そのものは巧妙なテクニックを使います。
そのときのレジスタの内容やスタックポインタの値をワークエリアに保存したうえで、スタックそのものの内容も書き換えないように注意しながら、そのときのCPUの全レジスタの値を画面表示します。

●ブレークポイントの設定(BP)

実際のプログラムリストです。
ND80ZVのモニタROMに書き込まれているZB3BASICのBPルーチンです。
ブレークポイントを設定するだけではなくて、その設定を解除するための命令など、ほかの機能も含んでいるため、ちょっと長いプログラムになっていますが、コアになる部分はシンプルなものです。

              ;;;
              ;;;BP SET
1BE4 3EC3     BP:LD A,C3
1BE6 32CCFF   LD (RST7JC),A   
1BE9 21421B   LD HL,BROUT   
1BEC 22CDFF   LD (RST7JA),HL   
1BEF 13       INC DE
1BF0 D5       PUSH DE
1BF1 CD4510   CALL ASHX4   
1BF4 DA1B1C   JP C,BPST3   
1BF7 C1       POP BC
1BF8 2280F0   LD (BRKAD),HL   
1BFB 1A       LD A,(DE)
1BFC FE2C     CP 2C ; ,
1BFE C20D1C   JP NZ,BPST1
1C01 13       INC DE
1C02 1A       LD A,(DE)
1C03 E607     AND 07
1C05 87       ADD A,A
1C06 F6E0     OR E0
1C08 D301     OUT (01),A
1C0A C30F1C   JP BPST2
1C0D 3E80     BPST1:LD A,80
1C0F 3283F0   BPST2:LD (BRKCK),A
1C12 7E       LD A,(HL)
1C13 3282F0   LD (BRKBF),A
1C16 36FF     LD (HL),FF
1C18 C3A118   JP ENTRY   
1C1B D1       BPST3:POP DE
1C1C 1A       LD A,(DE)
1C1D FE44     CP 44
1C1F CA3C1C   JP Z,BPST4   
1C22 FE30     CP 30
1C24 C23010   JP NZ,WHTDP   
1C27 3A83F0   LD A,(BRKCK)   
1C2A B7       OR A
1C2B CAA118   JP Z,ENTRY
1C2E 2A80F0   BPST6:LD HL,(BRKAD)   
1C31 3A82F0   LD A,(BRKBF)   
1C34 77       LD (HL),A
1C35 AF       BPST5:XOR A
1C36 3283F0   LD (BRKCK),A   
1C39 C3A118   JP ENTRY   
1C3C 3A83F0   BPST4:LD A,(BRKCK)   
1C3F B7       OR A
1C40 CAA118   JP Z,ENTRY
1C43 2A80F0   LD HL,(BRKAD)   
1C46 CD4E10   CALL HXDP4
1C49 CD1B10   CALL CRLF
1C4C C3A118   JP ENTRY   

アドレス1C12H〜1C1AHで、指定したメモリアドレスの値をBRKBFに保存して、代わりにFFを書き込んで、システムのエントリポイントにジャンプします。
それだけで準備完了です。

●ブレークプログラム

こちらはFFコードを実行したあと実行されるブレーク処理ルーチンです。
ここでは巧妙なテクニックが使われています。
ブレーク処理で最も大切なことは、そのときのCPUの状態をそのまま保存する、ということです。
そんなことができるのでしょうか?

              ;;;
              ;;;BREAK ENTRY
1B42 F3       BROUT:DI
1B43 E3       EX (SP),HL
1B44 2B       DEC HL
1B45 229BF0   LD (PCL),HL   
1B48 E1       POP HL
1B49 ED7399F0 LD (SPBF),SP   
1B4D 3198F0   LD SP,IREG   
1B50 DDE5     PUSH IX
1B52 FDE5     PUSH IY
1B54 F5       PUSH AF
1B55 C5       PUSH BC
1B56 D5       PUSH DE
1B57 E5       PUSH HL
1B58 08       EX AF,AF'
1B59 F5       PUSH AF
1B5A D9       EXX
1B5B C5       PUSH BC
1B5C D5       PUSH DE
1B5D E5       PUSH HL
1B5E ED57     LD A,I
1B60 3298F0   LD (IREG),A   
1B63 2100F5   LD HL,STC
1B66 1100ED   LD DE,STCWK
1B69 010003   LD BC,$0300
1B6C EDB0     LDIR
1B6E 3100F8   LD SP,SPTOP
1B71 3AE6FE   LD A,(EIMK)
1B74 B7       OR A
1B75 CA791B   JP Z,BROUT2
1B78 FB       EI
1B79 3A83F0   BROUT2:LD A,(BRKCK)   
1B7C B7       OR A
1B7D CA981B   JP Z,BRK2
1B80 AF       XOR A
1B81 3283F0   LD (BRKCK),A   
1B84 2A80F0   LD HL,(BRKAD)   
1B87 7C       LD A,H
1B88 FE40     CP 40
1B8A D2941B   JP NC,BRK1
1B8D DB01     IN A,(01)
1B8F E67F     AND 7F
1B91 3283F0   LD (BRKCK),A
1B94 3A82F0   BRK1:LD A,(BRKBF)
1B97 77       LD (HL),A
1B98 CDFD1A   BRK2:CALL RGDSP
1B9B C3A118   JP ENTRY   

リストを見ながら何をやっているのか説明をするつもりだったのですが、このところ多忙で、本日もちょっと時間がなくなってしまいました。
この続きは次回にすることにいたします。
次回までに、ここでは一体何をやっているのか、皆様も一度じっくり考えてみてくださいませ。

ワンボードマイコンでCP/Mを![第182回]
2012.7.25upload

前へ
次へ
ホームページトップへ戻る