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

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

[第393回]


●ランダムWRITE(ファンクション22H)

昨日はCP/M互換DOSの操作説明書の最終段階でまたまた苦戦いたしまして、とうとうホームページの更新ができませんでした。
実は。
ちょいと前からいやーな予感がしていたのです。
Zドライブの関係の機能を拡充するなどした結果、ZBDOSのファイルREAD/WRITEのあたりも大幅に書き換えてしまいました。
こんなに大幅に書き換えてしまったら、ランダムアクセスでこけてしまうのでは…。

それでランダムREADとランダムWRITEは後回しにしてきたのですが、いつまでも手をつけないわけにもいきませんので、昨日は意を決して、テスト作業にかかったのですけれど。
ものの見事にこけてしまいました。

ZBDOSのランダムREAD、ランダムWRITEは部分的にシーケンシャルREAD、シーケンシャルWRITEとつながっていたのですが、とりあえずそのつながりは無視してシーケンシャルREAD、シーケンシャルWRITEだけ大幅に書き換えてしまったために、ランダムアクセスのところがめちゃめちゃな動きになってしまいました。

結局。
本日たっぷり1日かかって、やっとランダムアクセスがまともに動くところまで修復することができました。
結果としてランダムREADについては特に問題はなく、ランダムWRITEのみのプログラム修正で済みました。
ランダムWRITE(ファンクション22H)については、[第216回]から[第224回]まで、試行錯誤を重ねながらテストをしてきました。
[第217回]のテストが一応最終的なものなのですが、その後にすこしレコードb追加して[第223回]で再実行しています。
いかにもまとまりを欠いている感じです。
今回はもう少し整理した形でテストを行ないましたので、以下にその過程をお見せすることにいたします。

●テスト用レコード番号データの作成

前にテストをしたときはテストプログラムが読み込むレコード番号データはCM@コマンドで直接メモリに書き込んで作成しました。
しかしその作業をテストのたびに行なうというのも面倒な話ですし。
(あ、今気が付きました。そのようにして作成したものをセーブしておけばよかった)
ということで、それを作成するプログラムを作りました。

こちらがソースプログラムです。
メモリアドレスの0300からデータを書き込んでいくだけの単純なプログラムです。

;raf test data sakusei
;2013/4/20
;
	ORG $0100
	LD DE,$0300
	LD HL,DATA
LOOP:LD C,(HL)
	INC HL
	LD B,(HL)
	EX DE,HL
	LD (HL),C
	INC HL
	LD (HL),B
	EX DE,HL
	INC HL
	INC DE
	INC BC
	LD A,B
	OR C
	JP NZ,LOOP
	RET
DATA:DW $01A2
DW $03B5
DW $009E
DW $0044
DW $03B6
DW $01A7
DW $009F
DW $009A
DW $03B3
DW $01A5
DW $0098
DW $0047
DW $0042
DW $0028
DW $00C7
DW $0182
DW $03E5
DW $FFFF
; 

こちらがアセンブルリストです。

2013/4/20  9:26  raftdout.txt
END=013A
              ;raf test data sakusei
              ;2013/4/20
              ;
              	ORG $0100
0100 110003   	LD DE,$0300
0103 211701   	LD HL,DATA
0106 4E       LOOP:LD C,(HL)
0107 23       	INC HL
0108 46       	LD B,(HL)
0109 EB       	EX DE,HL
010A 71       	LD (HL),C
010B 23       	INC HL
010C 70       	LD (HL),B
010D EB       	EX DE,HL
010E 23       	INC HL
010F 13       	INC DE
0110 03       	INC BC
0111 78       	LD A,B
0112 B1       	OR C
0113 C20601   	JP NZ,LOOP
0116 C9       	RET
0117 A201     DATA:DW $01A2
0119 B503     DW $03B5
011B 9E00     DW $009E
011D 4400     DW $0044
011F B603     DW $03B6
0121 A701     DW $01A7
0123 9F00     DW $009F
0125 9A00     DW $009A
0127 B303     DW $03B3
0129 A501     DW $01A5
012B 9800     DW $0098
012D 4700     DW $0047
012F 4200     DW $0042
0131 2800     DW $0028
0133 C700     DW $00C7
0135 8201     DW $0182
0137 E503     DW $03E5
0139 FFFF     DW $FFFF
              ;DATA         =0117  LOOP         =0106   

●テストプログラムVFTST20B

今回あらためてテストをしてみますと、1つのレコードを書き込むのにけっこう時間がかかることがわかりました。
全部終わるまで何も表示されないままだとちょっと不安になってしまいます。
そこで1レコード処理するごとにレコード番号を表示するようにプログラムを変更しました。

こちらがソースプログラムです。

; BDOS TEST20-2 function22 random write
;2012/3/4 3/7 4/16 4/17 4/27
;9/15
;
        ORG $0100
        FCALL=$0005
        NMBRTBL=$0300
        FCB=$005C
        FCBR0=$007D
        FCBR1=$007E
        FCBR2=$007F
        DMA=$0080
;
        LD C,16;make file
        LD DE,FCB
        CALL FCALL
        INC A;if FFH?
        JP Z,DFULERR
;
        XOR A
        LD (FCBR2),A
        LD HL,NMBRTBL
        PUSH HL
LOOP:POP HL
        LD A,(HL)
        LD (FCBR0),A
        LD C,A
        INC HL
        LD A,(HL)
        CP FF
        JP Z,CLOSE
        LD (FCBR1),A
        LD B,A
        INC HL
        PUSH HL
        LD H,B
        LD L,C
        CALL HEX4DP
        CALL CRLF
;data fill
        LD HL,DMA
        LD D,40
LOOP2:LD (HL),C
        INC HL
        LD (HL),B
        INC HL
        DEC D
        JP NZ,LOOP2
;
        LD C,22;random write
        LD DE,FCB
        CALL FCALL
        OR A
        JP Z,LOOP
        POP HL
        OR 30
        PUSH AF
        LD DE,ERRT
        CALL MSGOUT
        POP AF
        LD E,A
        LD C,02
        CALL FCALL
        RET
;
CLOSE:LD C,10;close
        LD DE,FCB
        CALL FCALL
        INC A;if FFH?
        JP Z,CLOSERR
        LD DE,OK
        JP MSGOUT
;
DFULERR:LD DE,DFULL
        JP MSGOUT
CLOSERR:LD DE,CANTCLS
MSGOUT:LD C,09
        CALL FCALL
        RET
;
;CL & LF
CRLF:LD A,0D
        CALL ADP
        LD A,0A
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
;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
;DE(asckii 2bytes) disp
DEDP:PUSH DE
        LD E,D
        LD C,02
        CALL FCALL
        POP DE
        LD C,02
        CALL FCALL
        RET
;
CANTOPN:"can'"
        "t op"
        "en!"
        DB 0D
        DB 0A
        DB 24;$
DFULL:"disk"
        " ful"
        "l!"
        DB 0D
        DB 0A
        DB 24;$
CANTCLS:"can'"
        "t cl"
        "ose!"
        DB 0D
        DB 0A
        DB 24;$
OK:"done"
        DB 0D
        DB 0A
        DB 24;$
ERRT:"err "
        DB 24;$
; 

こちらがアセンブルリストです。

2013/5/11  11:33  vftst20b.txt
END=0200
              ; BDOS TEST20-2 function22 random write
              ;2012/3/4 3/7 4/16 4/17 4/27
              ;9/15
              ;
                ORG $0100
                FCALL=$0005
                NMBRTBL=$0300
                FCB=$005C
                FCBR0=$007D
                FCBR1=$007E
                FCBR2=$007F
                DMA=$0080
              ;
0100 0E16             LD C,16;make file
0102 115C00           LD DE,FCB
0105 CD0500           CALL FCALL
0108 3C               INC A;if FFH?
0109 CA6C01           JP Z,DFULERR
              ;
010C AF               XOR A
010D 327F00           LD (FCBR2),A
0110 210003     LD HL,NMBRTBL
0113 E5         PUSH HL
0114 E1       LOOP:POP HL
0115 7E         LD A,(HL)
0116 327D00     LD (FCBR0),A
0119 4F         LD C,A
011A 23         INC HL
011B 7E         LD A,(HL)
011C FEFF       CP FF
011E CA5A01     JP Z,CLOSE
0121 327E00     LD (FCBR1),A
0124 47         LD B,A
0125 23         INC HL
0126 E5         PUSH HL
0127 60         LD H,B
0128 69         LD L,C
0129 CDAC01     CALL HEX4DP
012C CD7B01     CALL CRLF
              ;data fill
012F 218000     LD HL,DMA
0132 1640       LD D,40
0134 71       LOOP2:LD (HL),C
0135 23         INC HL
0136 70         LD (HL),B
0137 23         INC HL
0138 15         DEC D
0139 C23401     JP NZ,LOOP2
              ;
013C 0E22       LD C,22;random write
013E 115C00     LD DE,FCB
0141 CD0500     CALL FCALL
0144 B7         OR A
0145 CA1401     JP Z,LOOP
0148 E1         POP HL
0149 F630       OR 30
014B F5         PUSH AF
014C 11FC01     LD DE,ERRT
014F CD7501     CALL MSGOUT
0152 F1         POP AF
0153 5F         LD E,A
0154 0E02       LD C,02
0156 CD0500     CALL FCALL
0159 C9         RET
              ;
015A 0E10     CLOSE:LD C,10;close
015C 115C00     LD DE,FCB
015F CD0500     CALL FCALL
0162 3C         INC A;if FFH?
0163 CA7201     JP Z,CLOSERR
0166 11F501     LD DE,OK
0169 C37501     JP MSGOUT
              ;
016C 11D901   DFULERR:LD DE,DFULL
016F C37501     JP MSGOUT
0172 11E601   CLOSERR:LD DE,CANTCLS
0175 0E09     MSGOUT:LD C,09
0177 CD0500           CALL FCALL
017A C9               RET
              ;
              ;CL & LF
017B 3E0D     CRLF:LD A,0D
017D CD8201     CALL ADP
0180 3E0A       LD A,0A
0182 C5       ADP:PUSH BC
0183 E5         PUSH HL
0184 5F         LD E,A
0185 0E02       LD C,02
0187 CD0500     CALL FCALL
018A E1         POP HL
018B C1         POP BC
018C C9         RET
              ;binary to hex, 2bytes data to ascii 4charactors,HL to HL,DE
018D 7C       B2HEX4:LD A,H
018E CD9301     CALL B2HEX2
0191 EB         EX DE,HL
0192 7B         LD A,E
              ;binary to hex, 1byte data to ascii 2charactors,A to DE
0193 F5       B2HEX2:PUSH AF
0194 0F         RRCA
0195 0F         RRCA
0196 0F         RRCA
0197 0F         RRCA
0198 CDA201     CALL B2HEX1
019B 57         LD D,A
019C F1         POP AF
019D CDA201     CALL B2HEX1
01A0 5F         LD E,A
01A1 C9         RET
              ;binary to hex, low 4bit to ascii 1charactor
01A2 E60F     B2HEX1:AND 0F
01A4 C630       ADD A,30
01A6 FE3A       CP 3A
01A8 D8         RET C;0-9
01A9 C607       ADD A,07;A-F
01AB C9         RET
              ;HL(bynary 2bytes) to asckii 4bytes & disp
01AC C5       HEX4DP:PUSH BC
01AD E5         PUSH HL
01AE CD8D01     CALL B2HEX4;binary 2 bytes to ascii HEX 4bytes
01B1 D5         PUSH DE
01B2 EB         EX DE,HL
01B3 CDBD01     CALL DEDP
01B6 D1         POP DE
01B7 CDBD01     CALL DEDP
01BA E1         POP HL
01BB C1         POP BC
01BC C9         RET
              ;DE(asckii 2bytes) disp
01BD D5       DEDP:PUSH DE
01BE 5A         LD E,D
01BF 0E02       LD C,02
01C1 CD0500     CALL FCALL
01C4 D1         POP DE
01C5 0E02       LD C,02
01C7 CD0500     CALL FCALL
01CA C9         RET
              ;
01CB 63616E27 CANTOPN:"can'"
01CF 74206F70         "t op"
01D3 656E21           "en!"
01D6 0D               DB 0D
01D7 0A               DB 0A
01D8 24               DB 24;$
01D9 6469736B DFULL:"disk"
01DD 2066756C         " ful"
01E1 6C21             "l!"
01E3 0D               DB 0D
01E4 0A               DB 0A
01E5 24               DB 24;$
01E6 63616E27 CANTCLS:"can'"
01EA 7420636C         "t cl"
01EE 6F736521         "ose!"
01F2 0D               DB 0D
01F3 0A               DB 0A
01F4 24               DB 24;$
01F5 646F6E65 OK:"done"
01F9 0D               DB 0D
01FA 0A               DB 0A
01FB 24               DB 24;$
01FC 65727220 ERRT:"err "
0200 24               DB 24;$
              ;
ADP          =0182  B2HEX1       =01A2  B2HEX2       =0193  
B2HEX4       =018D  CANTCLS      =01E6  CANTOPN      =01CB  
CLOSE        =015A  CLOSERR      =0172  CRLF         =017B  
DEDP         =01BD  DFULERR      =016C  DFULL        =01D9  
DMA          =0080  ERRT         =01FC  FCALL        =0005  
FCB          =005C  FCBR0        =007D  FCBR1        =007E  
FCBR2        =007F  HEX4DP       =01AC  LOOP         =0114  
LOOP2        =0134  MSGOUT       =0175  NMBRTBL      =0300  
OK           =01F5  

じつはこのプログラムは終わり方に手抜きがあります。
本当はFFFFをチェックして終わるところを、FFXXで終わってしまいます。
でもテストプログラムですから、まあ、こんなものでもよろしいでしょう。

●最初に仮想ディスクドライブを空にする

空にしないとテストができないわけではありません。
しかし、前にテストをしたときはディスクドライブに他のプログラムなどが入っていたために、あとでセクタに書き込まれたデータをVFDUMPで確認するときに、セクタbフ算出がやや面倒でした。
そこで今回はRAFTDOUT.COMとVFTST20B.COMだけをセーブしておいて、そこにTEST.RAFを作成しました。
同じことをしていただければ、ここでお見せする画面と同じ結果を得ることができます。

仮想FDDをクリアする一番簡単な方法は、仮想FDDを削除してしまうことです。
エクスプローラで削除してもいいですが、DOSプロンプト(コマンドプロンプト)の中でERASEコマンドを使うほうが簡単です。

ERASE C.VFD[Enter]
と入力すると仮想FDDのCドライブが削除されます。
そうしておいてZB3DOSを起動します。

まだデバッグ中ですのでZB3DOS2Tになっています。

/CPM[Enter]
と入力するとCP/M互換DOSが起動して、仮想Cドライブが作成されます。

ZドライブからVFTST20B.COMとRAFTDOUT.COMを仮想Cドライブにコピーします。
テスト用のレコード番号データを作成するため、
RAFTDOUT[Enter]
と入力します。
これで準備は完了です。

VFTST20B TEST.RAF[Enter]
と入力します。


レコード番号が読み込まれ、番号ごとに128バイトのレコードがランダムレコードとして作成されます。

ZB3[Enter]
と入力してCP/M互換DOSを終了します。
参考までにRAFTDOUT.COMの実行により0300〜に作成されたレコード番号データをDM@コマンドで表示させてみました。
そのあと/EXIT[Enter]
でZB3DOSを終了しました。

VFDUMPを実行して、仮想Cドライブの中身を確認しています。
VFDUMP[Enter]
でドライブbフ入力要求が表示されます。
C[Enter]
と入力すると、セクタ番号の入力になりますから、
0[Enter]
と入力します。
セクタ0の内容が表示されました。
TEST.RAFのFCBが複数作成されています。
このあたりのことについては、[第216回]から[第224回]を参照してください。

1[Enter]
と入力してセクタ1を表示させました。

データブロックのブロック番号だけは異なりますが、そのほかは[第223回]の結果と同じです。

レコードデータが書き込まれたセクタも確認してみましょう。
ここでは最後のデータ03E5の書き込まれたセクタを見てみます。
03E5はエクステントbO7のレコード65になります。
エクステント内レコードの65はブロック6のレコード5です。
エクステント07のブロック6のところを見ますと、000Bになっています。
ブロックナンバー000BのbO5セクタに03E5のデータがあることになります。
ブロック番号とセクタ番号から、先頭を0000とするセクタb簡単に求めることができます。
000Bを1桁シフトして000B0として、そこに5を加算した000B5を10進数に直せばよいのです。
B5の10進数は181です。
セクタbP81を表示させました。

03E5が書き込まれていることが確認できました。

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

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