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

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

[第163回]


●DMコマンド(2)

今回は、DMコマンドでROMと同じアドレス0000〜7FFFに置いたRAMの中味を表示するにはどのようにすればよいか、ということについて説明をいたします。

まずはじめに下の画像を見てください。
DMコマンドを実行して、アドレス0000〜007Fのメモリの中味を表示しています。



同じことを2回実行しているように見えますが、表示されているメモリの中味は全然違います。
でもアドレスはどちらも0000〜007Fで同じです。
よく見ますと下側のDMコマンドは、
DM@0000,007F
になっています。
普通のDMコマンドは「DM」とアドレスとの間はスペースで区切りますが、下側のDMコマンドはスペースの代わりに@を使っています。

DMコマンドの機能を拡張して、DMの後に@をつけたときは、0000〜7FFFの範囲のRAMの内容を表示するようにしました。
そのようにすることで、同じアドレス0000〜7FFFに置いたROMの内容もRAMの内容もどちらも表示することができるようになりました。

上側のDMの後ろがスペースになっている今までと同じ形式のDMコマンドで表示されているのはROMの0000〜007Fの内容です。
下側のDM@コマンドで表示されているのはRAMの0000〜007Fの内容です。

下はそのように変更したDMコマンドのプログラムリスト(アセンブルリスト)です。
ND80ZVのROMに書かれているプログラムですが、今回は0000〜7FFFのRAMの内容も表示できるように一部を書き換えました。

              ;
19F5 CD6C10   DM:CALL ATMKCK
19F8 CD5110   CALL ADRD
19FB CD0B1A   DM1:CALL DMSB
19FE CD5410   CALL BREAK
1A01 CD2710   CALL HDCMP
1A04 28F5     JR Z,*DM1
1A06 38F3     JR C,*DM1
1A08 C3A418   JP ENTRY
              ;
1A0B E5       DMSB:PUSH HL
1A0C E5       PUSH HL
1A0D CD4E10   CALL HXDP4
1A10 E1       POP HL
1A11 CD3910   CALL SPCDP
1A14 0608     LD B,08
1A16 CD3910   DM2:CALL SPCDP
1A19 CD5A1A   CALL DM2SB
1A1C 10F8     DJNZ *DM2
1A1E 3E2D     LD A,2D
1A20 CD1510   CALL ADISP
1A23 CD5A1A   CALL DM2SB
1A26 0607     LD B,07
1A28 CD3910   DM22:CALL SPCDP
1A2B CD5A1A   CALL DM2SB
1A2E 10F8     DJNZ *DM22
1A30 E1       POP HL
1A31 CD3910   CALL SPCDP
1A34 CD3910   CALL SPCDP
1A37 0610     LD B,10
1A39 CDC41C   DM3:CALL MEMRD
1A3C CD451A   CALL DM4
1A3F 23       INC HL
1A40 10F7     DJNZ *DM3
1A42 C31B10   JP CRLF
              ;
1A45 FE20     DM4:CP 20
1A47 380C     JR C,*DM5
1A49 FE80     CP 80
1A4B 380A     JR C,ADSPJ
1A4D FEA0     CP A0
1A4F 3804     JR C,*DM5
1A51 FEE0     CP E0
1A53 3802     JR C,ADSPJ
1A55 3E2E     DM5:LD A,2E
1A57 C31510   ADSPJ:JP ADISP
              ;
1A5A E5       DM2SB:PUSH HL
1A5B CDC41C   	CALL MEMRD
1A5E 67       	LD H,A
1A5F CD4B10   CALL HXDP2
1A62 E1       POP HL
1A63 23       INC HL
1A64 C9       RET

書き換える前のリストはこちらです。

             ;
19F2 13       DM:INC DE
19F3 CD5110   CALL ADRD
19F6 CD061A   DM1:CALL DMSB
19F9 CD5410   CALL BREAK
19FC CD2710   CALL HDCMP
19FF 28F5     JR Z,*DM1
1A01 38F3     JR C,*DM1
1A03 C3A118   JP ENTRY
              ;
1A06 E5       DMSB:PUSH HL
1A07 E5       PUSH HL
1A08 CD4E10   CALL HXDP4
1A0B E1       POP HL
1A0C CD3910   CALL SPCDP
1A0F 0608     LD B,08
1A11 CD3910   DM2:CALL SPCDP
1A14 CD531A   CALL DM2SB
1A17 10F8     DJNZ *DM2
1A19 3E2D     LD A,2D
1A1B CD1510   CALL ADISP
1A1E CD531A   CALL DM2SB
1A21 0607     LD B,07
1A23 CD3910   DM22:CALL SPCDP
1A26 CD531A   CALL DM2SB
1A29 10F8     DJNZ *DM22
1A2B E1       POP HL
1A2C CD3910   CALL SPCDP
1A2F CD3910   CALL SPCDP
1A32 0610     LD B,10
1A34 7E       DM3:LD A,(HL)
1A35 CD3E1A   CALL DM4
1A38 23       INC HL
1A39 10F9     DJNZ *DM3
1A3B C31B10   JP CRLF
              ;
1A3E FE20     DM4:CP 20
1A40 380C     JR C,*DM5
1A42 FE80     CP 80
1A44 380A     JR C,ADSPJ
1A46 FEA0     CP A0
1A48 3804     JR C,*DM5
1A4A FEE0     CP E0
1A4C 3802     JR C,ADSPJ
1A4E 3E2E     DM5:LD A,2E
1A50 C31510   ADSPJ:JP ADISP
              ;
1A53 E5       DM2SB:PUSH HL
1A54 66       LD H,(HL)
1A55 CD4B10   CALL HXDP2
1A58 E1       POP HL
1A59 23       INC HL
1A5A C9       RET

どこを書き換えたのかといいますと、たった3箇所だけを書き換えました。
まず先頭の
DM:INC DE
を、
DM:CALL ATMKCK
に書き換えました。

2箇所目は、
DM3:LD A,(HL)
を、
DM3:CALL MEMRD
に書き換えました。

そして3箇所目は、DM2SBルーチンの
LD H,(HL)

CALL MEMRD
LD H,A
に書き換えました。

下は新たに追加したATMKCKサブルーチンのリストです。

              ;check '@'
167C 1A       ATMKCK:LD A,(DE)
167D 32D1F2   	LD (RAMCK),A
1680 13       	INC DE
1681 FE20     	CP 20
1683 C8       	RET Z
1684 FE2C     	CP 2C
1686 C8       	RET Z
1687 FE40     	CP 40;@
1689 C8       	RET Z
168A C33010   	JP WHTDP

コマンドの先頭で@をチェックしています。
コマンドの中でチェックした結果を確認できるように、ワークエリアRAMCKにその文字コードを保存します。
@のときは文字コード40HがRAMCKに入ります。
スペースのときは20Hが、またカンマのときは2CHが入ります。

下は、こちらも新たに追加したMEMRDサブルーチンです。

1CC4 3AD1F2   MEMRD:LD A,(RAMCK)
1CC7 FE40     	CP 40;@
1CC9 CA42D2   	JP Z,RAMRD
1CCC 7E       	LD A,(HL)
1CCD C9       	RET

LD A,(HL)を変更して、その代わりにこのMEMRDを実行します。
’DM@’のときは、RAMRDにジャンプします。
それ以外のときはLD A,(HL)を実行します。

このRAMRDが重要です。
アドレスがD242になっています。
このアドレスはCP/M互換DOSのBIOSプログラムのアドレスです。

下はCP/M互換DOSのBIOSの先頭にあるジャンプ命令部分です。
下のほうに
JP RAMRD
が見えます。 

              ;
D200 C395D2   	JP SETEN2
D203 C3F2D2   BOOT:JP WBOOTJ
D206 C3F9D2   	JP CONSTJ
D209 C31BD3   	JP CONINJ
D20C C33BD3   	JP CONOUTJ
D20F C35BD3   	JP LISTJ
D212 C35CD3   	JP PUNCHJ
D215 C36ED3   	JP READERJ
D218 C38DD3   	JP HOMEJ
D21B C398D3   	JP SELDSKJ
D21E C3B4D3   	JP SETTRKJ
D221 C3BCD3   	JP SETSECJ
D224 C3C2D3   	JP SETDMAJ
D227 C3C8D3   	JP READJ
D22A C331D4   	JP WRITEJ
D22D C351D4   	JP PRSTATJ
D230 C352D4   	JP SECTRNJ
D233 C377D2   	JP SETENTRY
D236 C355D4   	JP ZREENTJ
D239 C3BED2   	JP RTRAM
D23C C36ED4   	JP LOADZ
D23F C3D2D2   	JP RAMWR
D242 C3DED2   	JP RAMRD
D245 C3E6D2   	JP RAMJP
              ;

そしてこちらがそのジャンプ先、RAMWRとRAMRDです。

              ;
D2D2 3EFF     RAMWR:LD A,FF
D2D4 D39C     	OUT (9C),A
D2D6 F1       	POP AF
D2D7 77       	LD (HL),A
D2D8 F5       RAMWR2:PUSH AF
D2D9 AF       	XOR A
D2DA D39C     	OUT (9C),A
D2DC F1       	POP AF
D2DD C9       	RET
              ;
D2DE 3EFF     RAMRD:LD A,FF
D2E0 D39C     	OUT (9C),A
D2E2 7E       	LD A,(HL)
D2E3 C3D8D2   	JP RAMWR2

RAMRDでは、最初に
LD A,FF
OUT (9C),A
を実行して、RAMを選択します。
この時点でROMは非選択になります。

DMコマンドからこのルーチンにジャンプしてきて、ここでROMを非選択にしてもCPUが暴走しないのは、このルーチンがROM/RAMの切り換えに影響されない、アドレス8000〜FFFFの範囲のRAMに書かれているからです。

そして
LD A,(HL)
を実行します。

最後に
XOR A
OUT (9C),A
を実行して、ROMを選択します。

以上のようにすることで、0000〜7FFFの範囲に割り付けられたROMに書かれたDMコマンドプログラムで、同じアドレスのRAMの内容を読んで表示することが可能になりました。

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

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