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

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

[第183回]


●ブレークプログラム(2)

前回はブレークポイントを設定して、ブレークしたときに実行されるプログラムのリストをお見せしたところで終わってしまいました。
このところ多忙でなかなか落ち着いて書いている時間がありません。
今回も中途で終わってしまうかもしれません。

ま。
できるところまでやりましょう。
前回お見せしたブレーク処理プログラムの先頭の部分です。
              ;;;
              ;;;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
一体何をやっているのでしょう?
おわかりになりますでしょうか?

前回説明しましたように、ブレーク動作はブレークポイントアドレスの中味をFFで置き換えるところから始まります。
プログラムが実行(または再開)されて、置き換えられたFFコードのところまで来て、それを実行すると、FFはRST7の命令コードですから、0038H番地のRST7ルーチンがコールされます。
ジャンプではないことに注目してください。

RST7はジャンプではなくて、コールですから、0038Hから書かれているプログラムが実行される前に、FFコードの次のアドレス(つまりブレークポイントの次のアドレス)をスタックに保存(PUSH)してから、0038Hのプログラムが実行されます。

途中ちょっと中継点を通りますが、最終的に0038Hから上のリストのところに来ます。
その間はジャンプだけですからスタックもレジスタ、フラグも変化しません。
上のリストのところに来た時点では、プログラムカウンタは変化してしまっています。
しかしスタックにはブレークポイントの次のアドレスが入れられています。

EX (SP),HL
DEC HL
LD (PCL),HL

というように実行することで、ワークエリアのPCLには、ブレークポイントを設定したアドレスが保存されます。
このアドレスはユーザープログラムの実行が再開されるときの、実行開始アドレスになります。
指定したアドレスの命令が実行される直前にブレークしますから、ユーザープログラムの実行を再開するときは、そのブレークしたアドレスから再開されます。

上のプログラム部分の次の命令にいきます。

POP HL
LD (SPBF),SP

ここでPOP HLを実行すると、さきほどEX (SP),HLでスタックトップの値と交換したHLの値がもとのHLに戻ります。
と同時にSP(スタックポインタ)の値が、ブレーク直前の値になります。
それをSPBFに保存します。

さてその次です。
次はSP(スタックポインタ)にIレジスタの保存場所IREGをセットして、CPUのレジスタを全部PUSHしています。

   
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

じつはIREG以下のアドレスにIX、IY…全レジスタの保存エリアがあるのです。
LD命令を使わないで、こうすることによって、効率良くレジスタの値を保存することができます。
最後にIレジスタを保存します。

ブレークの処理の主たる作業はそこまでで終わりです。
ここからあとのところは、ZB3BASICのもとになったシステムの痕跡がそのまま残っています。
ここは参考にはなりません。

   
   
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   

最後のBRK1:のところは必要な作業です。
ブレークポイントを設定するときに、ワークエリアに保存しておいた、ユーザープログラムのもともとの命令コードをブレークポイントを設定したアドレスのメモリに戻します。
これでFFに置き換えたところが元通りになりました。
最後にレジスタダンプ(RGDSP)を行なって、システムのエントリポイントに戻ります。

参考までに。
RGDSPルーチンです。
              ;;;
              ;;;REGISTER DISP
1AFD CD1B10   RGDSP:CALL CRLF   
1B00 11B81F   LD DE,RGTBL   
1B03 AF       XOR A
1B04 CD1810   CALL DEDSP   
1B07 0608     LD B,08
1B09 1193F0   LD DE,ACC1   
1B0C CD331B   CALL RGDPS
1B0F 0602     LD B,02
1B11 119CF0   LD DE,PCH   
1B14 CD331B   CALL RGDPS
1B17 0602     LD B,02
1B19 1197F0   LD DE,IXH   
1B1C CD331B   CALL RGDPS
1B1F 3A98F0   LD A,(IREG)   
1B22 67       LD H,A
1B23 CD4B10   CALL HXDP2   
1B26 CD3910   CALL SPCDP
1B29 3A92F0   LD A,(FLG1)
1B2C CD6610   CALL BITDP
1B2F CD1B10   CALL CRLF
1B32 C9       RET
              ;;;REGISTER DISP(SUB)
1B33 1A       RGDPS:LD A,(DE)
1B34 67       LD H,A
1B35 1B       DEC DE
1B36 1A       LD A,(DE)
1B37 6F       LD L,A
1B38 CD4E10   CALL HXDP4   
1B3B CD3910   CALL SPCDP
1B3E 1B       DEC DE
1B3F 10F2     DJNZ RGDPS
1B41 C9       RET
              ;;;

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

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