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

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

[第115回]


●シーケンシャルファイルとランダムファイル(2)

前回は、シーケンシャルファイルをオープンして、そのファイルにランダムライトのファンクションコールで、ランダムにレコードを書き込んでしまうという、メチャクチャなことをやりました。
まあメチャクチャというのは、「シーケンシャルファイルとランダムファイルは違うだろう」という「常識」から見たら、そのように思うということでありまして、実は(少なくともCP/Mに限っては)シーケンシャルファイルもランダムファイルも基本的には同じものなのです。

ですからシーケンシャルファイルをランダムにアクセスすることだって自由にできてしまいます。
あ。
その逆はちょっと難しいところがあるのですけれど…。

それで。
前回はシーケンシャルファイルにレコードをランダムにライト(書き込み)しました。
そこで、今回はシーケンシャルファイルをランダムにリード(読み出し)してみます。

●テストプログラムFTST24−2

シーケンシャルファイルをオープンして、ランダムにリードしてしまうプログラムです。
こちらがそのソースプログラムFTST24−2.TXTです。

; BDOS TEST24-2 file read(random read)
; from ftest4-1.txt & ftest3dm.txt & ftst21.txt
;2012/2/28
;4/30 5/2
;
        ORG $8100
        FCALL=$8005
        FCB=$805C
        RECNO=$807C
        FCBR0=$807D
        FCBR1=$807E
        FCBR2=$807F
        DMA=$8080
        NMBRTBL=$8400
;
        LD C,0F;open
        LD DE,FCB
        CALL FCALL
        INC A;if FFH?
        JP Z,OPENERR
;
        XOR A
        LD (FCBR2),A
        LD (FCBR1),A
        LD HL,NMBRTBL
        PUSH HL
LOOP:POP HL
        LD A,(HL)
        LD (FCBR0),A
        CP FF
        JP Z,END
        INC HL
        PUSH HL
;
        LD C,21;random read
        LD DE,FCB
        CALL FCALL
        OR A
        JP NZ,READERR
;
        LD HL,DMA
        LD A,(HL)
        CALL B2HEXDP
        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;$
;

前回でも使ったシーケンシャルファイルTEST.SAFをファイルオープンして、あらかじめ作成しておいたレコードu\にしたがってランダムにレコードを読んで、そのデータの1バイトを16進数で表示します。

こちらがアセンブルリストFTST24−2.LSTです。

2012/5/2  11:9  ftst24-2.txt
END=81F0
              ; BDOS TEST24-2 file read(random read)
              ; from ftest4-1.txt & ftest3dm.txt & ftst21.txt
              ;2012/2/28
              ;4/30 5/2
              ;
                      ORG $8100
                      FCALL=$8005
                      FCB=$805C
                      RECNO=$807C
                FCBR0=$807D
                FCBR1=$807E
                FCBR2=$807F
                      DMA=$8080
                NMBRTBL=$8400
              ;
8100 0E0F             LD C,0F;open
8102 115C80           LD DE,FCB
8105 CD0580           CALL FCALL
8108 3C               INC A;if FFH?
8109 CA5481           JP Z,OPENERR
              ;
810C AF               XOR A
810D 327F80           LD (FCBR2),A
8110 327E80     LD (FCBR1),A
8113 210084     LD HL,NMBRTBL
8116 E5         PUSH HL
8117 E1       LOOP:POP HL
8118 7E         LD A,(HL)
8119 327D80     LD (FCBR0),A
811C FEFF       CP FF
811E CA4E81     JP Z,END
8121 23         INC HL
8122 E5         PUSH HL
              ;
8123 0E21       LD C,21;random read
8125 115C80     LD DE,FCB
8128 CD0580     CALL FCALL
812B B7         OR A
812C C23C81     JP NZ,READERR
              ;
812F 218080           LD HL,DMA
8132 7E         LD A,(HL)
8133 CDC081           CALL B2HEXDP
8136 CD5D81           CALL CRLF
8139 C31781           JP LOOP
              ;
813C E1       READERR:POP HL
813D F630       OR 30
813F F5         PUSH AF
8140 11EC81     LD DE,ERRT
8143 CD5781     CALL MSGOUT
8146 F1         POP AF
8147 5F         LD E,A
8148 0E02       LD C,02
814A CD0580     CALL FCALL
814D C9         RET
              ;
814E 11E681   END:LD DE,OK
8151 C35781     JP MSGOUT
              ;
8154 11D981   OPENERR:LD DE,CANTOPN
8157 0E09     MSGOUT:LD C,09
8159 CD0580           CALL FCALL
815C C9               RET
              ;
              ;CL & LF
815D 3E0D     CRLF:LD A,0D
815F CD6981     CALL ADP
8162 3E0A       LD A,0A
8164 C36981     JP ADP
              ;space disp
8167 3E20     SPDP:LD A,20
              ;A disp
8169 C5       ADP:PUSH BC
816A E5         PUSH HL
816B 5F         LD E,A
816C 0E02       LD C,02
816E CD0580     CALL FCALL
8171 E1         POP HL
8172 C1         POP BC
8173 C9         RET
              ;binary to hex, 2bytes data to ascii 4charactors,HL to HL,DE
8174 7C       B2HEX4:LD A,H
8175 CD7A81     CALL B2HEX2
8178 EB         EX DE,HL
8179 7B         LD A,E
              ;binary to hex, 1byte data to ascii 2charactors,A to DE
817A F5       B2HEX2:PUSH AF
817B 0F         RRCA
817C 0F         RRCA
817D 0F         RRCA
817E 0F         RRCA
817F CD8981     CALL B2HEX1
8182 57         LD D,A
8183 F1         POP AF
8184 CD8981     CALL B2HEX1
8187 5F         LD E,A
8188 C9         RET
              ;binary to hex, low 4bit to ascii 1charactor
8189 E60F     B2HEX1:AND 0F
818B C630       ADD A,30
818D FE3A       CP 3A
818F D8         RET C;0-9
8190 C607       ADD A,07;A-F
8192 C9         RET
              ;hex to binary, ascii 1charactor to low 4bit 
8193 FE30     HTOB1:CP 30;>="0"?
8195 D8         RET C;no
8196 FE3A       CP 3A;<="9"?
8198 DAAC81     JP C,HTOB1_2;yes,"0" to "9"
819B FE41       CP 41;>="A" ?
819D D8         RET C;no
819E FE47       CP 47;<="F"?
81A0 DAAA81     JP C,HTOB1_1
81A3 FE61       CP 61;>="a"?
81A5 D8         RET C;no
81A6 FE67       CP 67;<="f"?
81A8 3F         CCF
81A9 D8         RET C;no
81AA C609     HTOB1_1:ADD A,09;41 to 46 -> 4A to 4F,or 61 to 67 -> 6A to 6F
81AC E60F     HTOB1_2:AND 0F
81AE C9         RET
              ;HL(bynary 2bytes) to asckii 4bytes & disp
81AF C5       HEX4DP:PUSH BC
81B0 E5         PUSH HL
81B1 CD7481     CALL B2HEX4;binary 2 bytes to ascii HEX 4bytes
81B4 D5         PUSH DE
81B5 EB         EX DE,HL
81B6 CDCB81     CALL DEDP
81B9 D1         POP DE
81BA CDCB81     CALL DEDP
81BD E1         POP HL
81BE C1         POP BC
81BF C9         RET
              ;A(binary) to asckii 2bytes HEX & disp
81C0 C5       B2HEXDP:PUSH BC
81C1 E5         PUSH HL
81C2 CD7A81     CALL B2HEX2
81C5 CDCB81     CALL DEDP
81C8 E1         POP HL
81C9 C1         POP BC
81CA C9         RET
              ;
              ;DE(asckii 2bytes) disp
81CB D5       DEDP:PUSH DE
81CC 5A         LD E,D
81CD 0E02       LD C,02
81CF CD0580     CALL FCALL
81D2 D1         POP DE
81D3 0E02       LD C,02
81D5 CD0580     CALL FCALL
81D8 C9         RET
              ;
81D9 63616E27 CANTOPN:"can'"
81DD 74206F70         "t op"
81E1 656E             "en"
81E3 0D               DB 0D
81E4 0A               DB 0A
81E5 24               DB 24;$
81E6 656E64   OK:"end"
81E9 0D               DB 0D
81EA 0A               DB 0A
81EB 24               DB 24;$
81EC 65727220 ERRT:"err "
81F0 24               DB 24;$
              ;
ADP          =8169  B2HEX1       =8189  B2HEX2       =817A  
B2HEX4       =8174  B2HEXDP      =81C0  CANTOPN      =81D9  
CRLF         =815D  DEDP         =81CB  DMA          =8080  
END          =814E  ERRT         =81EC  FCALL        =8005  
FCB          =805C  FCBR0        =807D  FCBR1        =807E  
FCBR2        =807F  HEX4DP       =81AF  HTOB1        =8193  
HTOB1_1      =81AA  HTOB1_2      =81AC  LOOP         =8117  
MSGOUT       =8157  NMBRTBL      =8400  OK           =81E6  
OPENERR      =8154  READERR      =813C  RECNO        =807C  
SPDP         =8167  

●準備

まず最初にレコードu\を作成します。
アドレス8400Hから、CMコマンドで作成します。
TEST.SAFのレコードはbO0〜bOFの16レコードです。
シーケンシャルファイルですから、レコードはその順に並んでいます。
今回はそれをランダムに読み出してみます。
ランダムですから、文字通りランダムでよいのですけれど、ここはいっそのこと全く逆の順番で読み出してみることにします。
レコード番号表は、0Fから始まって00まで逆順に作成しました。

logfile nd80zlog\05021051.txt open

ND80ZVに接続しました
0001 0000 - z
1000 00C3 - 
*** nd80z3 basic ****
>cm 8400
8400 1A-0f
8401 28-0e
8402 10-0d
8403 11-0c
8404 90-0b
8405 0A-0a
8406 04-09
8407 00-08
8408 30-07
8409 30-06
840A 00-05
840B 42-04
840C 45-03
840D 01-02
840E C0-01
840F 85-00
8410 73-ff
8411 BE-
>

●テストプログラムの実行

アドレス8100HにFTST24−2.BINをロードしたあと、
jp d233[Enter]
でCP/Mを起動しました。
そのあと
save 1 ftst24−2.com[Enter]
と入力して、FTST24−2.COMのファイル名でAドライブにセーブし、
ftst24−2 test.saf[Enter]
と入力して、プログラムを実行しました。

>/ld ftst24-2.bin,8100
loading FTST24-2.BIN ...00f1(241)bytes loaded,from 8100 to 81F0
>jp d233

a>dir
A: FTST23   COM : TEST     SAF : FTST24   COM
a>save 1 ftst24-2.com
a>ftst24-2 test.saf
0F
0E
0D
0C
0B
0A
09
08
07
06
05
04
03
02
01
00
end

a>

結果は何のトラブルもなく、みごとに逆順で読み出すことができました。

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

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