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

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

[第108回]


●ファンクションコール21H(ランダムリード)

ファンクションコール21Hはランダムファイルのレコードの読み出しを行ないます。
レコードb指定してコールすると、ランダムファイルのそのレコードbフデータ128バイトがDMAエリアに読み出されます。

●テストプログラムFTST21.TXT

ファンクションコール21HのテストプログラムFTST21.TXTのソースリストです。

; BDOS TEST21 function21 random read
;2012/3/4 3/7 4/16 4/17 4/27
;
        ORG $8100
        FCALL=$8005
        NMBRTBL=$8300
        FCB=$805C
        FCBR0=$807D
        FCBR1=$807E
        FCBR2=$807F
        DMA=$8080
;
        LD C,0F;open file
        LD DE,FCB
        CALL FCALL
        INC A;if FFH?
        JP Z,OPENERR
;
        XOR A
        LD (FCBR2),A
        LD HL,NMBRTBL
        PUSH HL
LOOP:POP HL
        LD A,(HL)
        LD (FCBR0),A
        INC HL
        LD A,(HL)
        CP FF
        JP Z,END
        LD (FCBR1),A
        INC HL
        PUSH HL
;
        LD C,21;random read
        LD DE,FCB
        CALL FCALL
        OR A
        JP NZ,READERR
;data disp
        LD HL,DMA
        LD E,(HL)
        INC HL
        LD D,(HL)
        EX DE,HL
        CALL HEX4DP
        CALL CRLF
        JP LOOP
;
READERR:POP HL
        OR 30
        PUSH AF
        LD DE,ERRT
        CALL MSGOUT
        POP AF
        LD E,A
        LD C,02
        CALL FCALL
        RET
;
END:LD DE,OK
        JP MSGOUT
;
OPENERR:LD DE,CANTOPN
MSGOUT:LD C,09
        CALL FCALL
        RET
;
;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
;
CANTOPN:"can'"
        "t op"
        "en!"
        DB 0D
        DB 0A
        DB 24;$
OK:"end"
        DB 0D
        DB 0A
        DB 24;$
ERRT:"err "
        DB 24;$
;

ランダムファイルの読み出しも、基本的にはシーケンシャルファイルの読み出しと同じ手順です。
シーケンシャルファイルの読み出しは[第46回]で説明をしました。
最初にファイル名情報が書き込まれたFCBを指定してファイルをオープンします。
ファイルオープンはファンクションコール0FHです。

レコードを読み出すためのレコードbヘ[第106回]で作成した2バイトのレコードcfータをそのまま使います。
ですからCP/Mプログラムも、[第106回]で1ブロックを8セクタに変更したプログラムをそのまま使いました。

レコードbフ下位バイトをFCBの先頭から34バイト目(アドレス807D、本来は007D)に書き込みます。
テストプログラムではそのアドレスにFCBR0という名前をつけました。
レコードbフ上位バイトをFCBの先頭から35バイト目(アドレス807E、本来は007E)に書き込みます。
テストプログラムではそのアドレスにFCBR1という名前をつけました。
36バイト目(アドレス807E、本来は007E)には00を書き込みます。
テストプログラムではそのアドレスにFCBR2という名前をつけました。

DEレジスタにFCBエリアの先頭アドレスを入れて、Cレジスタに21Hを入れて、システムをコールします。
読み出したデータはDMAエリア(デフォルトでは8080H。本来は0080H)に格納されます。

読み出しに成功するとAレジスタに00が入ります。
失敗したときは、Aレジスタに00以外の値が入るのですが、その意味は「応用CP/M」(村瀬康治著。アスキー出版局)では以下のように説明されています(122頁)。
01 ディレクトリに登録されていないブロックを指定した。
02 ランダムモードにならない(?)。
03 現在のロジカルエクステントをクローズできない(意味不明)。
04 登録されていないエクステントを指定した。
05 読み出しモードにならない(?)。
06 物理的な範囲を超えてアクセスした。

なおインターネットのCP/Mサイト(http://www.seasip.demon.co.uk/Cpm/index.html)のファンクションコール33(21H)の説明ページ(http://www.seasip.demon.co.uk/Cpm/bdos.html#33)では上記のうち02と05はありません。

今回はテストですから読み出したレコードの先頭の2バイトだけを16進数で表示します。
レコードのデータはレコードbニ同じ2バイトの値が、下位、上位の順で書き込まれていますから、読み出したデータは順序を逆にして上位、下位の順で表示します。
16進数で表示するためのサブルーチンは[第42回]で作ったメモリダンププログラムのものをそのままコピーして使いました。

●テストプログラムFTST21.TXTのアセンブル

FTST21.TXTをZASM.COMでアセンブルします。
下はアセンブルの結果作成されたアセンブルリストです。

2012/4/27  17:53  ftst21.txt
END=81F6
              ; BDOS TEST21 function21 random read
              ;2012/3/4 3/7 4/16 4/17 4/27
              ;
                      ORG $8100
                      FCALL=$8005
                NMBRTBL=$8300
                      FCB=$805C
                FCBR0=$807D
                FCBR1=$807E
                FCBR2=$807F
                      DMA=$8080
              ;
8100 0E0F             LD C,0F;open file
8102 115C80           LD DE,FCB
8105 CD0580           CALL FCALL
8108 3C               INC A;if FFH?
8109 CA5981           JP Z,OPENERR
              ;
810C AF               XOR A
810D 327F80           LD (FCBR2),A
8110 210083     LD HL,NMBRTBL
8113 E5         PUSH HL
8114 E1       LOOP:POP HL
8115 7E         LD A,(HL)
8116 327D80     LD (FCBR0),A
8119 23         INC HL
811A 7E         LD A,(HL)
811B FEFF       CP FF
811D CA5381     JP Z,END
8120 327E80     LD (FCBR1),A
8123 23         INC HL
8124 E5         PUSH HL
              ;
8125 0E21       LD C,21;random read
8127 115C80     LD DE,FCB
812A CD0580     CALL FCALL
812D B7         OR A
812E C24181     JP NZ,READERR
              ;data disp
8131 218080     LD HL,DMA
8134 5E         LD E,(HL)
8135 23         INC HL
8136 56         LD D,(HL)
8137 EB         EX DE,HL
8138 CDB481     CALL HEX4DP
813B CD6281     CALL CRLF
813E C31481     JP LOOP
              ;
8141 E1       READERR:POP HL
8142 F630       OR 30
8144 F5         PUSH AF
8145 11F281     LD DE,ERRT
8148 CD5C81     CALL MSGOUT
814B F1         POP AF
814C 5F         LD E,A
814D 0E02       LD C,02
814F CD0580     CALL FCALL
8152 C9         RET
              ;
8153 11EC81   END:LD DE,OK
8156 C35C81     JP MSGOUT
              ;
8159 11DE81   OPENERR:LD DE,CANTOPN
815C 0E09     MSGOUT:LD C,09
815E CD0580           CALL FCALL
8161 C9               RET
              ;
              ;CL & LF
8162 3E0D     CRLF:LD A,0D
8164 CD6E81     CALL ADP
8167 3E0A       LD A,0A
8169 C36E81     JP ADP
              ;space disp
816C 3E20     SPDP:LD A,20
              ;A disp
816E C5       ADP:PUSH BC
816F E5         PUSH HL
8170 5F         LD E,A
8171 0E02       LD C,02
8173 CD0580     CALL FCALL
8176 E1         POP HL
8177 C1         POP BC
8178 C9         RET
              ;binary to hex, 2bytes data to ascii 4charactors,HL to HL,DE
8179 7C       B2HEX4:LD A,H
817A CD7F81     CALL B2HEX2
817D EB         EX DE,HL
817E 7B         LD A,E
              ;binary to hex, 1byte data to ascii 2charactors,A to DE
817F F5       B2HEX2:PUSH AF
8180 0F         RRCA
8181 0F         RRCA
8182 0F         RRCA
8183 0F         RRCA
8184 CD8E81     CALL B2HEX1
8187 57         LD D,A
8188 F1         POP AF
8189 CD8E81     CALL B2HEX1
818C 5F         LD E,A
818D C9         RET
              ;binary to hex, low 4bit to ascii 1charactor
818E E60F     B2HEX1:AND 0F
8190 C630       ADD A,30
8192 FE3A       CP 3A
8194 D8         RET C;0-9
8195 C607       ADD A,07;A-F
8197 C9         RET
              ;hex to binary, ascii 1charactor to low 4bit 
8198 FE30     HTOB1:CP 30;>="0"?
819A D8         RET C;no
819B FE3A       CP 3A;<="9"?
819D DAB181     JP C,HTOB1_2;yes,"0" to "9"
81A0 FE41       CP 41;>="A" ?
81A2 D8         RET C;no
81A3 FE47       CP 47;<="F"?
81A5 DAAF81     JP C,HTOB1_1
81A8 FE61       CP 61;>="a"?
81AA D8         RET C;no
81AB FE67       CP 67;<="f"?
81AD 3F         CCF
81AE D8         RET C;no
81AF C609     HTOB1_1:ADD A,09;41 to 46 -> 4A to 4F,or 61 to 67 -> 6A to 6F
81B1 E60F     HTOB1_2:AND 0F
81B3 C9         RET
              ;HL(bynary 2bytes) to asckii 4bytes & disp
81B4 C5       HEX4DP:PUSH BC
81B5 E5         PUSH HL
81B6 CD7981     CALL B2HEX4;binary 2 bytes to ascii HEX 4bytes
81B9 D5         PUSH DE
81BA EB         EX DE,HL
81BB CDD081     CALL DEDP
81BE D1         POP DE
81BF CDD081     CALL DEDP
81C2 E1         POP HL
81C3 C1         POP BC
81C4 C9         RET
              ;A(binary) to asckii 2bytes HEX & disp
81C5 C5       B2HEXDP:PUSH BC
81C6 E5         PUSH HL
81C7 CD7F81     CALL B2HEX2
81CA CDD081     CALL DEDP
81CD E1         POP HL
81CE C1         POP BC
81CF C9         RET
              ;
              ;DE(asckii 2bytes) disp
81D0 D5       DEDP:PUSH DE
81D1 5A         LD E,D
81D2 0E02       LD C,02
81D4 CD0580     CALL FCALL
81D7 D1         POP DE
81D8 0E02       LD C,02
81DA CD0580     CALL FCALL
81DD C9         RET
              ;
81DE 63616E27 CANTOPN:"can'"
81E2 74206F70         "t op"
81E6 656E21           "en!"
81E9 0D               DB 0D
81EA 0A               DB 0A
81EB 24               DB 24;$
81EC 656E64   OK:"end"
81EF 0D               DB 0D
81F0 0A               DB 0A
81F1 24               DB 24;$
81F2 65727220 ERRT:"err "
81F6 24               DB 24;$
              ;
ADP          =816E  B2HEX1       =818E  B2HEX2       =817F  
B2HEX4       =8179  B2HEXDP      =81C5  CANTOPN      =81DE  
CRLF         =8162  DEDP         =81D0  DMA          =8080  
END          =8153  ERRT         =81F2  FCALL        =8005  
FCB          =805C  FCBR0        =807D  FCBR1        =807E  
FCBR2        =807F  HEX4DP       =81B4  HTOB1        =8198  
HTOB1_1      =81AF  HTOB1_2      =81B1  LOOP         =8114  
MSGOUT       =815C  NMBRTBL      =8300  OK           =81EC  
OPENERR      =8159  READERR      =8141  SPDP         =816C  

●プログラムのセーブと実行

ZB3BASICで、
/ld ftst21.bin,8100[Enter]
と入力して、FTST21.BINを8100にロードしてから、
jp d233[Enter]
でCP/Mを起動しました。

ND80ZVに接続しました
0001 0000 - z
1000 00C3 - 
*** nd80z3 basic ****
>/ld ftst21.bin,8100
>loading FTST21.BIN ...00f7(247)bytes loaded,from 8100 to 81F6
>jp d233

a>b:
b>save 1 ftst21.com
b>dir
B: TEST     RAF : FTST21   COM
b>ftst21 a:test.raf
01A2
03B5
009E
0044
03B6
01A7
009F
009A
03B3
01A5
0098
0047
0042
end

b>ftst21 test.raf
01A2
03B5
009E
0044
03B6
01A7
009F
009A
03B3
01A5
0098
0047
0042
end

b>

Aドライブには空きがありませんから、テストプログラムはBドライブにセーブします。
a>b:[Enter]
と入力してカレントドライブをBドライブにしてから、
save 1 ftst21.com[Enter]
と入力して、FTST21.COMというファイル名でBドライブにセーブしました。
そのあとDIRコマンドを実行して、FTST21.COMがセーブされたことを確認しました。

ftst21 a:test.raf[Enter]
と入力して、AドライブのランダムアクセスファイルTEST.RAFを読み出しました。

そのあと続いて
ftst21 test.raf[Enter]
と入力して、BドライブのランダムアクセスファイルTEST.RAFを読み出しました。
どちらの場合も、あらかじめ作成したレコードcfータと同じデータが読み出されました。


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

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