2015.2.8

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

MYCPU80でCP/Mを!
超巨大基板の8080互換HCMOS・CPUでCP/Mを走らせてしまおうという、なんとも狂気なプロジェクトです!


[第125回]


●ファンクション23

ファンクション23はファイルサイズの取得です。
ファイルサイズ(レコード数)を取得してFCBの第34、35バイト目に格納します。
ここで使われるFCBについては「ワンボードマイコンでCP/Mを!」[第148回]で説明をしています。
そこではファンクション23のテストもしていますが、ランダムアクセスファイルも含めた最終的なテストは「ワンボードマイコンでCP/Mを!」[第226回]で行なっています。
そこで使っているテストプログラムはVFTST22です。

テストプログラムVFTST22のソースプログラムをインテルニーモニックに書き直してMFTST22を作りました。

●テストプログラムMFTST22

MFTST22のソースプログラムです。

; BDOS TEST22 function23 file size get
;2012/3/4 3/7 4/16 4/17 4/27
;10/3
;
        ORG $0100
        FCALL=$0005
        FCB=$005C
        FCBR0=$007D
        FCBR1=$007E
        FCBR2=$007F
        DMA=$0080
;
        MVI C,0F;open file
        LXI D,FCB
        CALL FCALL
        INR A;if FFH?
        JZ OPENERR
;
        MVI C,23;file size read
        LXI D,FCB
        CALL FCALL
;
        LDA FCBR2
        CALL B2HEXDP
        CALL SPDP
        LDA FCBR1
        CALL B2HEXDP
        CALL SPDP
        LDA FCBR0
        CALL B2HEXDP
        CALL CRLF
        LXI D,OK
        JMP MSGOUT
;
OPENERR:LXI D,CANTOPN
MSGOUT:MVI C,09
        CALL FCALL
        RET
;
;CL & LF
CRLF:MVI A,0D
        CALL ADP
        MVI A,0A
        JMP ADP
;space disp
SPDP:MVI A,20
;A disp
ADP:PUSH B
        PUSH H
        MOV E,A
        MVI C,02
        CALL FCALL
        POP H
        POP B
        RET
;binary to hex, 2bytes data to ascii 4charactors,HL to HL,DE
B2HEX4:MOV A,H
        CALL B2HEX2
        XCHG
        MOV A,E
;binary to hex, 1byte data to ascii 2charactors,A to DE
B2HEX2:PUSH PSW
        RRC
        RRC
        RRC
        RRC
        CALL B2HEX1
        MOV D,A
        POP PSW
        CALL B2HEX1
        MOV E,A
        RET
;binary to hex, low 4bit to ascii 1charactor
B2HEX1:ANI 0F
        ADI 30
        CPI 3A
        RC;0-9
        ADI 07;A-F
        RET
;hex to binary, ascii 1charactor to low 4bit 
HTOB1:CPI 30;>="0"?
        RC;no
        CPI 3A;<="9"?
        JC HTOB1_2;yes,"0" to "9"
        CPI 41;>="A" ?
        RC;no
        CPI 47;<="F"?
        JC HTOB1_1
        CPI 61;>="a"?
        RC;no
        CPI 67;<="f"?
        CMC
        RC;no
HTOB1_1:ADI 09;41 to 46 -> 4A to 4F,or 61 to 67 -> 6A to 6F
HTOB1_2:ANI 0F
        RET
;HL(bynary 2bytes) to asckii 4bytes & disp
HEX4DP:PUSH B
        PUSH H
        CALL B2HEX4;binary 2 bytes to ascii HEX 4bytes
        PUSH D
        XCHG
        CALL DEDP
        POP D
        CALL DEDP
        POP H
        POP B
        RET
;A(binary) to asckii 2bytes HEX & disp
B2HEXDP:PUSH B
        PUSH H
        CALL B2HEX2
        CALL DEDP
        POP H
        POP B
        RET
;
;DE(asckii 2bytes) disp
DEDP:PUSH D
        MOV E,D
        MVI C,02
        CALL FCALL
        POP D
        MVI C,02
        CALL FCALL
        RET
;
CANTOPN:"can'"
        "t op"
        "en!"
        DB 0D
        DB 0A
        DB 24;$
OK:"end"
        DB 0D
        DB 0A
        DB 24;$
;

下はMFTST22のアセンブルリストです。

2015/2/2  18:8  mftst22.txt
END=01CD
              ; BDOS TEST22 function23 file size get
              ;2012/3/4 3/7 4/16 4/17 4/27
              ;10/3
              ;
                      ORG $0100
                      FCALL=$0005
                      FCB=$005C
                FCBR0=$007D
                FCBR1=$007E
                FCBR2=$007F
                      DMA=$0080
              ;
0100 0E0F             MVI C,0F;open file
0102 115C00           LXI D,FCB
0105 CD0500           CALL FCALL
0108 3C               INR A;if FFH?
0109 CA3501           JZ OPENERR
              ;
010C 0E23       MVI C,23;file size read
010E 115C00     LXI D,FCB
0111 CD0500     CALL FCALL
              ;
0114 3A7F00           LDA FCBR2
0117 CDA101     CALL B2HEXDP
011A CD4801     CALL SPDP
011D 3A7E00     LDA FCBR1
0120 CDA101     CALL B2HEXDP
0123 CD4801     CALL SPDP
0126 3A7D00     LDA FCBR0
0129 CDA101     CALL B2HEXDP
012C CD3E01     CALL CRLF
012F 11C801     LXI D,OK
0132 C33801     JMP MSGOUT
              ;
0135 11BA01   OPENERR:LXI D,CANTOPN
0138 0E09     MSGOUT:MVI C,09
013A CD0500           CALL FCALL
013D C9               RET
              ;
              ;CL & LF
013E 3E0D     CRLF:MVI A,0D
0140 CD4A01     CALL ADP
0143 3E0A       MVI A,0A
0145 C34A01     JMP ADP
              ;space disp
0148 3E20     SPDP:MVI A,20
              ;A disp
014A C5       ADP:PUSH B
014B E5         PUSH H
014C 5F         MOV E,A
014D 0E02       MVI C,02
014F CD0500     CALL FCALL
0152 E1         POP H
0153 C1         POP B
0154 C9         RET
              ;binary to hex, 2bytes data to ascii 4charactors,HL to HL,DE
0155 7C       B2HEX4:MOV A,H
0156 CD5B01     CALL B2HEX2
0159 EB         XCHG
015A 7B         MOV A,E
              ;binary to hex, 1byte data to ascii 2charactors,A to DE
015B F5       B2HEX2:PUSH PSW
015C 0F         RRC
015D 0F         RRC
015E 0F         RRC
015F 0F         RRC
0160 CD6A01     CALL B2HEX1
0163 57         MOV D,A
0164 F1         POP PSW
0165 CD6A01     CALL B2HEX1
0168 5F         MOV E,A
0169 C9         RET
              ;binary to hex, low 4bit to ascii 1charactor
016A E60F     B2HEX1:ANI 0F
016C C630       ADI 30
016E FE3A       CPI 3A
0170 D8         RC;0-9
0171 C607       ADI 07;A-F
0173 C9         RET
              ;hex to binary, ascii 1charactor to low 4bit 
0174 FE30     HTOB1:CPI 30;>="0"?
0176 D8         RC;no
0177 FE3A       CPI 3A;<="9"?
0179 DA8D01     JC HTOB1_2;yes,"0" to "9"
017C FE41       CPI 41;>="A" ?
017E D8         RC;no
017F FE47       CPI 47;<="F"?
0181 DA8B01     JC HTOB1_1
0184 FE61       CPI 61;>="a"?
0186 D8         RC;no
0187 FE67       CPI 67;<="f"?
0189 3F         CMC
018A D8         RC;no
018B C609     HTOB1_1:ADI 09;41 to 46 -> 4A to 4F,or 61 to 67 -> 6A to 6F
018D E60F     HTOB1_2:ANI 0F
018F C9         RET
              ;HL(bynary 2bytes) to asckii 4bytes & disp
0190 C5       HEX4DP:PUSH B
0191 E5         PUSH H
0192 CD5501     CALL B2HEX4;binary 2 bytes to ascii HEX 4bytes
0195 D5         PUSH D
0196 EB         XCHG
0197 CDAC01     CALL DEDP
019A D1         POP D
019B CDAC01     CALL DEDP
019E E1         POP H
019F C1         POP B
01A0 C9         RET
              ;A(binary) to asckii 2bytes HEX & disp
01A1 C5       B2HEXDP:PUSH B
01A2 E5         PUSH H
01A3 CD5B01     CALL B2HEX2
01A6 CDAC01     CALL DEDP
01A9 E1         POP H
01AA C1         POP B
01AB C9         RET
              ;
              ;DE(asckii 2bytes) disp
01AC D5       DEDP:PUSH D
01AD 5A         MOV E,D
01AE 0E02       MVI C,02
01B0 CD0500     CALL FCALL
01B3 D1         POP D
01B4 0E02       MVI C,02
01B6 CD0500     CALL FCALL
01B9 C9         RET
              ;
01BA 63616E27 CANTOPN:"can'"
01BE 74206F70         "t op"
01C2 656E21           "en!"
01C5 0D               DB 0D
01C6 0A               DB 0A
01C7 24               DB 24;$
01C8 656E64   OK:"end"
01CB 0D               DB 0D
01CC 0A               DB 0A
01CD 24               DB 24;$
              ;
ADP          =014A  B2HEX1       =016A  B2HEX2       =015B  
B2HEX4       =0155  B2HEXDP      =01A1  CANTOPN      =01BA  
CRLF         =013E  DEDP         =01AC  DMA          =0080  
FCALL        =0005  FCB          =005C  FCBR0        =007D  
FCBR1        =007E  FCBR2        =007F  HEX4DP       =0190  
HTOB1        =0174  HTOB1_1      =018B  HTOB1_2      =018D  
MSGOUT       =0138  OK           =01C8  OPENERR      =0135  
SPDP         =0148    

●MFTST22の実行

「ワンボードマイコンでCP/Mを!」[第226回]を開いて、その画像をバックにしてMFTST22を実行しました。



「ワンボードマイコンでCP/Mを!」[第226回]ではランダムアクセスファイルTEST.RAFとF80.COMのファイルサイズを調べています。
同じことをしてみるため、F80.COMをAドライブにコピーしてからMFTST22を実行しました。
順序が逆ですが、それは問題ではありませんでしょう。
あれ?
F80.COMのファイルサイズが1セクタ(1レコード)違っていますねえ。
なぜでしょう?

VFDUMPを実行してディレクトリを確認してみました。



F80.COMのディレクトリは2つ作られています。
2番目のFCBの16バイト目が、「ワンボードマイコンでCP/Mを!」[第226回]のテスト画面では60Hなのに、今回のテストでは61Hになっています。
おお、そうでした。
理由がわかりました。
その確認のため、F80.COMの最後のセクタ(レコード)を表示させてみました。



最後のブロックは0049Hです。
セクタ数(レコード数)は80H+61H=E1H(225)です。
16レコード/ブロックですから225/16を計算すると14余り1になります。
つまりF80.COMは14ブロックを完全に使い、最後の15ブロック目は1セクタ(レコード)のみ使っていることになります。
F80.COMのディレクトリを確認すると、ブロックbヘ、
3B、3C、3D、3E、3F、40、41、42、43、44、45、46、47、48、49
ですから計算が合います。
つまりブロックbS9Hの第1セクタがF80.COMの最終セクタ(レコード)ということになります。
求めるセクタbヘ49H=73から
73×16=1178
になります。
VFDUMPでセクタbP168を表示してみたところ、最初から終わりまで1Aで埋められていました。

そういうことだったのでした。
[第109回]のTYPEコマンドのところで説明しましたように、COPYコマンドはZドライブからA〜Dドライブにファイルをコピーするときに「機械的に」エンドコードを追加してしまいます。
TXTファイルのときはそれでよいのですけれど、そうではないファイルのときには全く無駄なことをしていることになります。
F80.COMはおそらくちょうどファイルエンドがセクタの終わりになっていたため、COPYコマンドによってその次のセクタの全部に1Aが書き込まれてしまったのでした。

今回のような結果を見ると、ちょっとなんだかなあ、という気がしないでもありませんが。
ま、しかしCOPYコマンドはもともとCP/Mにあるコマンドではなくて、ZB3DOS独自の機能として追加したコマンドですので。
そういうことでもいいか、ということにいたしましょう。

MYCPU80でCP/Mを![第125回]
2015.2.8upload

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