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

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

[第43回]

●メモリダンププログラム(2)ASCII文字ダンプ

前回作ったメモリダンププログラムはメモリ内容を16進数で表示するだけでしたので、今回は、それを文字コードとみなして文字表示も行なうように、プログラムを追加しました。

●ASCII文字ダンプを追加したソースプログラムリストです

ちょっと考えるとなんだかむつかしそうですが、思ったより簡単にできてしまいます。
下のリストで ********** をつけてコメントしたところを追加するだけです。

; BDOS TEST3 DUMP MEMORY
;
     ORG $8100
     FCALL=$8005
;
TOP:LD H,00
LOOP:PUSH HL
        LD E,3F;?
        LD C,02
        CALL FCALL          
        LD C,01
        CALL FCALL
        CP 1A;^z?
        POP HL
        RET Z
        CP 0D;[enter]?
        JP Z,NEXT
        CALL HTOB1
        JP C,WHATDP
        RLCA
        RLCA
        RLCA
        RLCA
        LD H,A
        PUSH HL
        LD C,01
        CALL FCALL
        CP 1A;^z?
        POP HL
        RET Z
        CALL HTOB1
        JP C,WHATDP
        OR H
        LD H,A
NEXT:LD L,00
; memory dump
        CALL CRLF
        LD B,10;=16
LOOP1:CALL HEX4DP;address disp
        PUSH HL;for ascii dump ************ この行を追加 *******
        LD C,08
LOOP2:CALL SPDP;space disp
        LD A,(HL)
        CALL B2HEXDP;data disp
        INC HL
        DEC C
        JP NZ,LOOP2
        LD A,2D;"-"
        CALL ADP
        LD C,08
LOOP3:LD A,(HL)
        CALL B2HEXDP
        CALL SPDP
        INC HL
        DEC C
        JP NZ,LOOP3
;ascii dump          ************* ここから ************
        POP HL
        LD C,10;=16
ASCII:LD A,(HL)
        CP 20
        JP NC,ASCII2
        LD A,2E;"."
ASCII2:CALL ADP
        INC HL
        DEC C
        JP NZ,ASCII           ************** ここまで追加 ********
;
        CALL CRLF
        DEC B
        JP NZ,LOOP1
        CALL CRLF
        JP LOOP
WHATDP:CALL CRLF
        LD DE,WHATT
        LD C,09
        CALL FCALL
        CALL CRLF
        JP TOP
WHATT:"what"
        DB 3F;?
        DB 24;$
;
;CL & LF
CRLF:LD A,0D
        CALL ADP
        LD A,0A
        JP ADP
;space disp
SPDP:LD A,20
;A disp
ADP:PUSH BC
        PUSH HL
        LD E,A
        LD C,02
        CALL FCALL
        POP HL
        POP BC
        RET
;binary to hex, 2bytes data to ascii 4charactors,HL to HL,DE
B2HEX4:LD A,H
        CALL B2HEX2
        EX DE,HL
        LD A,E
;binary to hex, 1byte data to ascii 2charactors,A to DE
B2HEX2:PUSH AF
        RRCA
        RRCA
        RRCA
        RRCA
        CALL B2HEX1
        LD D,A
        POP AF
        CALL B2HEX1
        LD E,A
        RET
;binary to hex, low 4bit to ascii 1charactor
B2HEX1:AND 0F
        ADD A,30
        CP 3A
        RET C;0-9
        ADD A,07;A-F
        RET
;hex to binary, ascii 1charactor to low 4bit 
HTOB1:CP 30;>="0"?
        RET C;no
        CP 3A;<="9"?
        JP C,HTOB1_2;yes,"0" to "9"
        CP 41;>="A" ?
        RET C;no
        CP 47;<="F"?
        JP C,HTOB1_1
        CP 61;>="a"?
        RET C;no
        CP 67;<="f"?
        CCF
        RET C;no
HTOB1_1:ADD A,09;41 to 46 -> 4A to 4F,or 61 to 67 -> 6A to 6F
HTOB1_2:AND 0F
        RET
;HL(bynary 2bytes) to asckii 4bytes & disp
HEX4DP:PUSH BC
        PUSH HL
        CALL B2HEX4;binary 2 bytes to ascii HEX 4bytes
        PUSH DE
        EX DE,HL
        CALL DEDP
        POP DE
        CALL DEDP
        POP HL
        POP BC
        RET
;A(binary) to asckii 2bytes HEX & disp
B2HEXDP:PUSH BC
        PUSH HL
        CALL B2HEX2
        CALL DEDP
        POP HL
        POP BC
        RET
;
;DE(asckii 2bytes) disp
DEDP:PUSH DE
        LD E,D
        LD C,02
        CALL FCALL
        POP DE
        LD C,02
        CALL FCALL
        RET
;

00〜1Fは文字コードではなくて、制御用に使われていますから、それをそのまま文字として表示しようとすると、画面表示が乱れてしまいます。
たとえば0Dは行の先頭にカーソルを移動してしまいますし、0Aはカーソルを下に送ってしまいます。
そこで20Hよりも小さいコードは、”.”に置き換えて表示するようにしてあります。
(実はこれだけではまだ十分ではないことがじきにわかります)

●アセンブルして実行してみました

下の画面では、まずftest3dm.txtをアセンブルしています。



ftest3dm.binが作成されました。
そのあと、zb3[Enter]と入力して、ND80ZVとのUSB接続に成功しました。
ここで”z”を入力すると、ZB3BASICが起動します。

”z”を入力してZB3BASICが起動したあとの画面です。



ZB3BASICが起動したあと、/LDコマンドでftest3dm.binを8100Hにロードしています。
ASCII文字表示を追加したため、プログラムサイズが256バイトを超えてしまいました。
ですから今回は2ページのサイズでSAVEすることになります。

JP D233[Enter]でCP/Mが起動しました。

DIR[Enter]の入力で、ディレクトリを表示させています。

8100Hにロードしたプログラムをdm.comの名前でRAMディスクにSAVEします。
DM.COMはすでに保存されています。
同じ名前でSAVEすると、先に保存されていたファイルが新しいファイルで上書きされます。

そのあと、dm[Enter]と入力して、メモリダンププログラムの実行を開始しました。
?が表示されました。

●新しいDMプログラムの実行

上位アドレス88を入力してRAMディスクのディレクトリエリアを表示させてみました。



文字表示が行なわれて、ファイル名が表示されるようになりました。
それはよいのですが、なんだかおかしな表示が出ています。
漢字の「裏」という文字がびっしり表示されてしまいました。

実はもともとASCIIコードは7ビットで構成されていて、最上位ビットは使われていません。
当初は使われていなかった80H〜のコードに半角カナを割り当てて使ったりしましたが、もちろんそれは日本だけのルールで、外国ではそれぞれ別の使われ方をしました。
よくメールのタイトルなどに半角カナは使わないほうがよい、と言われたりしているのは、そのためです。
全角文字としての漢字も80Hより上のコードを使って表現されています。
当然8ビットでは足りないので2バイト16ビットを使います。
そのことから考えると、どうやら「裏」という漢字はE5E5というコードのようです。

うむむ。
これはちょうと目障りですねえ。

実は。
目障りなんてものじゃありませんでした。
こんなひどいことになってしまいました。



これはやっぱりなんとかしなければ駄目なようです。

ところで、ZB3BASICのマシン語モニタコマンドにもDMがあります。
そちらは、どうでしょうか?
CP/Mを終了してZB3BASICに戻って、DMコマンドを実行してみました。



00〜1Fだけではなくて、80Hより大きいコードも”.”に置き換えています。

そういえば、MSDOSのDEBUGコマンドにもメモリダンプの機能がありました。
そちらも試してみましょう。

[第41回]で保存したramdisk.binをデバッグコマンドで開いてみました。



メモリダンプはd[Enter]です。
ファイル名を指定してdebugコマンドを実行すると、ファイルのデータは0100Hからのメモリアドレスに読み込まれます。
なんだかCP/Mのルールを踏襲しているようですねえ。
debugコマンドでも、やはり80H以上のコードは”.”に置き換えるようです。

あ。
でもここではE5しか見えていませんね。
ほんとに80H以上のコードを”.”に置き換えてしまうのか、念の為に確かめてみましょう。



コード80は一番上の行にあります。
やっぱり”.”に置き換えられています。

●コード80H以上も”.”に置き換える

もう一度プログラム変更です。
今度は、ASCII文字表示の部分のみを下に示します。

;ascii dump
	POP HL
	LD C,10;=16
ASCII:LD A,(HL)
	CP 20
	JP C,ASCII1
	CP 80
	JP C,ASCII2
ASCII1:LD A,2E;"."
ASCII2:CALL ADP
	INC HL
	DEC C
	JP NZ,ASCII

下はZASM.COMでアセンブルして作成されたアセンブルリストです。

2012/2/24  9:42  ftest3dm.txt
END=8218
              ; BDOS TEST3 DUMP MEMORY
              ;
                   ORG $8100
                   FCALL=$8005
              ;
8100 2600     TOP:LD H,00
8102 E5       LOOP:PUSH HL
8103 1E3F       LD E,3F;?
8105 0E02       LD C,02
8107 CD0580     CALL FCALL          
810A 0E01       LD C,01
810C CD0580     CALL FCALL
810F FE1A       CP 1A;^z?
8111 E1         POP HL
8112 C8         RET Z
8113 FE0D       CP 0D;[enter]?
8115 CA3581     JP Z,NEXT
8118 CDD381     CALL HTOB1
811B DA8681     JP C,WHATDP
811E 07         RLCA
811F 07         RLCA
8120 07         RLCA
8121 07         RLCA
8122 67         LD H,A
8123 E5         PUSH HL
8124 0E01       LD C,01
8126 CD0580     CALL FCALL
8129 FE1A       CP 1A;^z?
812B E1         POP HL
812C C8         RET Z
812D CDD381     CALL HTOB1
8130 DA8681     JP C,WHATDP
8133 B4         OR H
8134 67         LD H,A
8135 2E00     NEXT:LD L,00
              ; memory dump
8137 CD9D81     CALL CRLF
813A 0610       LD B,10;=16
813C CDEF81   LOOP1:CALL HEX4DP;address disp
813F E5         PUSH HL;for ascii dump
8140 0E08       LD C,08
8142 CDA781   LOOP2:CALL SPDP;space disp
8145 7E         LD A,(HL)
8146 CD0082     CALL B2HEXDP;data disp
8149 23         INC HL
814A 0D         DEC C
814B C24281     JP NZ,LOOP2
814E 3E2D       LD A,2D;"-"
8150 CDA981     CALL ADP
8153 0E08       LD C,08
8155 7E       LOOP3:LD A,(HL)
8156 CD0082     CALL B2HEXDP
8159 CDA781     CALL SPDP
815C 23         INC HL
815D 0D         DEC C
815E C25581     JP NZ,LOOP3
              ;ascii dump
8161 E1         POP HL
8162 0E10       LD C,10;=16
8164 7E       ASCII:LD A,(HL)
8165 FE20       CP 20
8167 DA6F81     JP C,ASCII1
816A FE80       CP 80
816C DA7181     JP C,ASCII2
816F 3E2E     ASCII1:LD A,2E;"."
8171 CDA981   ASCII2:CALL ADP
8174 23         INC HL
8175 0D         DEC C
8176 C26481     JP NZ,ASCII
              ;
8179 CD9D81     CALL CRLF
817C 05         DEC B
817D C23C81     JP NZ,LOOP1
8180 CD9D81     CALL CRLF
8183 C30281     JP LOOP
8186 CD9D81   WHATDP:CALL CRLF
8189 119781     LD DE,WHATT
818C 0E09       LD C,09
818E CD0580     CALL FCALL
8191 CD9D81     CALL CRLF
8194 C30081     JP TOP
8197 77686174 WHATT:"what"
819B 3F         DB 3F;?
819C 24         DB 24;$
              ;
              ;CL & LF
819D 3E0D     CRLF:LD A,0D
819F CDA981     CALL ADP
81A2 3E0A       LD A,0A
81A4 C3A981     JP ADP
              ;space disp
81A7 3E20     SPDP:LD A,20
              ;A disp
81A9 C5       ADP:PUSH BC
81AA E5         PUSH HL
81AB 5F         LD E,A
81AC 0E02       LD C,02
81AE CD0580     CALL FCALL
81B1 E1         POP HL
81B2 C1         POP BC
81B3 C9         RET
              ;binary to hex, 2bytes data to ascii 4charactors,HL to HL,DE
81B4 7C       B2HEX4:LD A,H
81B5 CDBA81     CALL B2HEX2
81B8 EB         EX DE,HL
81B9 7B         LD A,E
              ;binary to hex, 1byte data to ascii 2charactors,A to DE
81BA F5       B2HEX2:PUSH AF
81BB 0F         RRCA
81BC 0F         RRCA
81BD 0F         RRCA
81BE 0F         RRCA
81BF CDC981     CALL B2HEX1
81C2 57         LD D,A
81C3 F1         POP AF
81C4 CDC981     CALL B2HEX1
81C7 5F         LD E,A
81C8 C9         RET
              ;binary to hex, low 4bit to ascii 1charactor
81C9 E60F     B2HEX1:AND 0F
81CB C630       ADD A,30
81CD FE3A       CP 3A
81CF D8         RET C;0-9
81D0 C607       ADD A,07;A-F
81D2 C9         RET
              ;hex to binary, ascii 1charactor to low 4bit 
81D3 FE30     HTOB1:CP 30;>="0"?
81D5 D8         RET C;no
81D6 FE3A       CP 3A;<="9"?
81D8 DAEC81     JP C,HTOB1_2;yes,"0" to "9"
81DB FE41       CP 41;>="A" ?
81DD D8         RET C;no
81DE FE47       CP 47;<="F"?
81E0 DAEA81     JP C,HTOB1_1
81E3 FE61       CP 61;>="a"?
81E5 D8         RET C;no
81E6 FE67       CP 67;<="f"?
81E8 3F         CCF
81E9 D8         RET C;no
81EA C609     HTOB1_1:ADD A,09;41 to 46 -> 4A to 4F,or 61 to 67 -> 6A to 6F
81EC E60F     HTOB1_2:AND 0F
81EE C9         RET
              ;HL(bynary 2bytes) to asckii 4bytes & disp
81EF C5       HEX4DP:PUSH BC
81F0 E5         PUSH HL
81F1 CDB481     CALL B2HEX4;binary 2 bytes to ascii HEX 4bytes
81F4 D5         PUSH DE
81F5 EB         EX DE,HL
81F6 CD0B82     CALL DEDP
81F9 D1         POP DE
81FA CD0B82     CALL DEDP
81FD E1         POP HL
81FE C1         POP BC
81FF C9         RET
              ;A(binary) to asckii 2bytes HEX & disp
8200 C5       B2HEXDP:PUSH BC
8201 E5         PUSH HL
8202 CDBA81     CALL B2HEX2
8205 CD0B82     CALL DEDP
8208 E1         POP HL
8209 C1         POP BC
820A C9         RET
              ;
              ;DE(asckii 2bytes) disp
820B D5       DEDP:PUSH DE
820C 5A         LD E,D
820D 0E02       LD C,02
820F CD0580     CALL FCALL
8212 D1         POP DE
8213 0E02       LD C,02
8215 CD0580     CALL FCALL
8218 C9         RET
              ;
              
ADP          =81A9  ASCII        =8164  ASCII1       =816F  
ASCII2       =8171  B2HEX1       =81C9  B2HEX2       =81BA  
B2HEX4       =81B4  B2HEXDP      =8200  CRLF         =819D  
DEDP         =820B  FCALL        =8005  HEX4DP       =81EF  
HTOB1        =81D3  HTOB1_1      =81EA  HTOB1_2      =81EC  
LOOP         =8102  LOOP1        =813C  LOOP2        =8142  
LOOP3        =8155  NEXT         =8135  SPDP         =81A7  
TOP          =8100  WHATDP       =8186  WHATT        =8197  

●こういうときにWindowsは便利です

ZASM.COMはコマンドプロンプトで実行します。
普通ならば一旦ZB3BASICを終了しなければなりません。
というのは、昔のDOS時代の話です。
せっかくのWindowsですから、こういうときこそ、しっかり利用してしまいましょう。

もうひとつコマンドプロンプトを立ち上げて、同じディレクトリに行って作業すればよいのです。



これはWindows98SEの画面です。
私のところでは、まだ健在なのです。
左のDOSプロンプトでZASMを実行しておいて、それから右のDOSプロンプトに戻って、それをロードすればよいのです。
/LD ftest3dm.bin,8100[Enter]の実行後、jp d233[Enter]でCP/Mに戻って、もう一度dm.comをSAVEしてから、あらためてdm.comを実行してみました。

今度は80H以上のコードも”.”に置き換えて表示されるようになりました。



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

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