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

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

[第441回]


●ファイル内容比較プログラム

前回からの続きです。
ファイルが正しくコピーされたかどうかを確認するには、コピー元のファイルとコピー先のファイルの内容を1バイトずつ比較してみるのが一番手っ取り早い方法です。
ファイル内容の比較はWindowsのアプリケーションでもいろいろあるようです。
Windowsの場合には頭でちょいと考えるほど簡単ではありません。
たとえばWord文書でちょいと1行追加しただけでも、先頭から逐次比較するような方法では、変更箇所から後ろは全部不一致になってしまいますから、使い物になりません。
でもそれはWindowsでのお話です。
幸いにして今回の問題の解決のためには、ようはオリジナルに対して100%完全なコピーがなされているかどうか(おそらくはコピーミスが発生している)ということを確認すればよいわけですから、それほど困難ではありません。
実はそのモデルはもうずいぶん以前に作っています。
[第55回][第59回]で「ファイル内容比較プログラム」として作ったのがそれです。
そこで作ったFTST6CMPをもとにして、現在のZB3DOSの規格に合ったファイル内容比較プログラムを作りました。
下がそのソースプログラムリストです。

; BDOS TEST6 COMPARE
;2012/3/7
;2013/7/12
;
        ORG $0100
        FCALL=$0005
        FCB=$005C
        FCB2=$006C
        RECNO=$007C
        DMA1=$0080
        DMA2=$0300
        BYTECNTR=$0380
        AWK=$0382
        FCBWK=$038C
        RECNO2=$03AC
;
        LD HL,FCB2
        LD DE,FCBWK
        LD B,11;=17
LOOP1:LD A,(HL)
        LD (DE),A
        INC HL
        INC DE
        DEC B
        JP NZ,LOOP1
;
        LD C,0F;open
        LD DE,FCB
        CALL FCALL
        INC A;if FFH?
        JP Z,NOFILERR
;
        LD C,0F;open
        LD DE,FCBWK
        CALL FCALL
        INC A;if FFH?
        JP Z,NOFILERR
;
        XOR A
        LD (RECNO),A
        LD (RECNO2),A
        LD HL,BYTECNTR
        LD (HL),A
        INC HL
        LD (HL),A
;
LOOP2:LD C,1A;DMA address set
        LD DE,DMA1
        CALL FCALL
        LD C,14;read
        LD DE,FCB
        CALL FCALL
        OR A
        JP NZ,CMPEND;read end
;
        LD C,1A;DMA address set
        LD DE,DMA2
        CALL FCALL
        LD C,14;read
        LD DE,FCBWK
        CALL FCALL
        OR A
        JP NZ,CMPEND;read end
;
        LD C,80
        LD HL,DMA1
        LD DE,DMA2
LOOP3:LD A,(DE)
        CP (HL)
        CALL NZ,NOTEQ
        INC HL
        INC DE
        PUSH HL
        LD HL,(BYTECNTR)
        INC HL
        LD (BYTECNTR),HL
        POP HL
        DEC C
        JP NZ,LOOP3
        JP LOOP2
;
NOFILERR:LD DE,CANTOPN
        LD C,09
        JP FCALL
CMPEND:LD HL,(BYTECNTR)
        CALL HEX4DP
        LD DE,BYTE
        LD C,09
        JP FCALL
;
NOTEQ:PUSH BC
        PUSH DE
        PUSH HL
        LD HL,(BYTECNTR)
        CALL HEX4DP
        CALL SPDP
        POP HL
        LD A,(HL)
        LD (AWK),A
        POP DE
        LD A,(DE)
        PUSH DE
        PUSH HL
        PUSH AF
        LD A,(AWK)
        CALL B2HEXDP
        LD A,2D;"-"
        CALL ADP
        POP AF
        CALL B2HEXDP
        CALL CRLF
        POP HL
        POP DE
        POP BC
        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
;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
;
;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
;
CANTOPN:"can'"
        "t op"
        "en!"
        DB 0D
        DB 0A
        DB 24;$
BYTE:"H by"
        "tes "
        "ok$"
;


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

2013/7/12  16:10  fcmp.txt
END=0236
              ; BDOS TEST6 COMPARE
              ;2012/3/7
              ;2013/7/12
              ;
                ORG $0100
                FCALL=$0005
                FCB=$005C
                FCB2=$006C
                RECNO=$007C
                DMA1=$0080
                DMA2=$0300
                BYTECNTR=$0380
                AWK=$0382
                FCBWK=$038C
                RECNO2=$03AC
              ;
0100 216C00     LD HL,FCB2
0103 118C03     LD DE,FCBWK
0106 0611       LD B,11;=17
0108 7E       LOOP1:LD A,(HL)
0109 12         LD (DE),A
010A 23         INC HL
010B 13         INC DE
010C 05         DEC B
010D C20801     JP NZ,LOOP1
              ;
0110 0E0F       LD C,0F;open
0112 115C00     LD DE,FCB
0115 CD0500     CALL FCALL
0118 3C         INC A;if FFH?
0119 CA7C01     JP Z,NOFILERR
              ;
011C 0E0F       LD C,0F;open
011E 118C03     LD DE,FCBWK
0121 CD0500     CALL FCALL
0124 3C         INC A;if FFH?
0125 CA7C01     JP Z,NOFILERR
              ;
0128 AF         XOR A
0129 327C00     LD (RECNO),A
012C 32AC03     LD (RECNO2),A
012F 218003     LD HL,BYTECNTR
0132 77         LD (HL),A
0133 23         INC HL
0134 77         LD (HL),A
              ;
0135 0E1A     LOOP2:LD C,1A;DMA address set
0137 118000     LD DE,DMA1
013A CD0500     CALL FCALL
013D 0E14       LD C,14;read
013F 115C00           LD DE,FCB
0142 CD0500           CALL FCALL
0145 B7               OR A
0146 C28401           JP NZ,CMPEND;read end
              ;
0149 0E1A       LD C,1A;DMA address set
014B 110003     LD DE,DMA2
014E CD0500     CALL FCALL
0151 0E14       LD C,14;read
0153 118C03     LD DE,FCBWK
0156 CD0500     CALL FCALL
0159 B7         OR A
015A C28401     JP NZ,CMPEND;read end
              ;
015D 0E80       LD C,80
015F 218000     LD HL,DMA1
0162 110003     LD DE,DMA2
0165 1A       LOOP3:LD A,(DE)
0166 BE         CP (HL)
0167 C49201     CALL NZ,NOTEQ
016A 23         INC HL
016B 13         INC DE
016C E5         PUSH HL
016D 2A8003     LD HL,(BYTECNTR)
0170 23         INC HL
0171 228003     LD (BYTECNTR),HL
0174 E1         POP HL
0175 0D         DEC C
0176 C26501     JP NZ,LOOP3
0179 C33501     JP LOOP2
              ;
017C 111E02   NOFILERR:LD DE,CANTOPN
017F 0E09       LD C,09
0181 C30500           JP FCALL
0184 2A8003   CMPEND:LD HL,(BYTECNTR)
0187 CDD501     CALL HEX4DP
018A 112C02     LD DE,BYTE
018D 0E09       LD C,09
018F C30500     JP FCALL
              ;
0192 C5       NOTEQ:PUSH BC
0193 D5         PUSH DE
0194 E5         PUSH HL
0195 2A8003     LD HL,(BYTECNTR)
0198 CDD501     CALL HEX4DP
019B CDC801     CALL SPDP
019E E1         POP HL
019F 7E         LD A,(HL)
01A0 328203     LD (AWK),A
01A3 D1         POP DE
01A4 1A         LD A,(DE)
01A5 D5         PUSH DE
01A6 E5         PUSH HL
01A7 F5         PUSH AF
01A8 3A8203     LD A,(AWK)
01AB CDE601     CALL B2HEXDP
01AE 3E2D       LD A,2D;"-"
01B0 CDCA01     CALL ADP
01B3 F1         POP AF
01B4 CDE601     CALL B2HEXDP
01B7 CDBE01     CALL CRLF
01BA E1         POP HL
01BB D1         POP DE
01BC C1         POP BC
01BD C9         RET
              ;
              ;CL & LF
01BE 3E0D     CRLF:LD A,0D
01C0 CDCA01     CALL ADP
01C3 3E0A       LD A,0A
01C5 C3CA01     JP ADP
              ;space disp
01C8 3E20     SPDP:LD A,20
              ;A disp
01CA C5       ADP:PUSH BC
01CB E5         PUSH HL
01CC 5F         LD E,A
01CD 0E02       LD C,02
01CF CD0500     CALL FCALL
01D2 E1         POP HL
01D3 C1         POP BC
01D4 C9         RET
              ;HL(bynary 2bytes) to asckii 4bytes & disp
01D5 C5       HEX4DP:PUSH BC
01D6 E5         PUSH HL
01D7 CDFF01     CALL B2HEX4;binary 2 bytes to ascii HEX 4bytes
01DA D5         PUSH DE
01DB EB         EX DE,HL
01DC CDF101     CALL DEDP
01DF D1         POP DE
01E0 CDF101     CALL DEDP
01E3 E1         POP HL
01E4 C1         POP BC
01E5 C9         RET
              ;A(binary) to asckii 2bytes HEX & disp
01E6 C5       B2HEXDP:PUSH BC
01E7 E5         PUSH HL
01E8 CD0502     CALL B2HEX2
01EB CDF101     CALL DEDP
01EE E1         POP HL
01EF C1         POP BC
01F0 C9         RET
              ;
              ;DE(asckii 2bytes) disp
01F1 D5       DEDP:PUSH DE
01F2 5A         LD E,D
01F3 0E02       LD C,02
01F5 CD0500     CALL FCALL
01F8 D1         POP DE
01F9 0E02       LD C,02
01FB CD0500     CALL FCALL
01FE C9         RET
              ;
              ;binary to hex, 2bytes data to ascii 4charactors,HL to HL,DE
01FF 7C       B2HEX4:LD A,H
0200 CD0502     CALL B2HEX2
0203 EB         EX DE,HL
0204 7B         LD A,E
              ;binary to hex, 1byte data to ascii 2charactors,A to DE
0205 F5       B2HEX2:PUSH AF
0206 0F         RRCA
0207 0F         RRCA
0208 0F         RRCA
0209 0F         RRCA
020A CD1402     CALL B2HEX1
020D 57         LD D,A
020E F1         POP AF
020F CD1402     CALL B2HEX1
0212 5F         LD E,A
0213 C9         RET
              ;binary to hex, low 4bit to ascii 1charactor
0214 E60F     B2HEX1:AND 0F
0216 C630       ADD A,30
0218 FE3A       CP 3A
021A D8         RET C;0-9
021B C607       ADD A,07;A-F
021D C9         RET
              ;
021E 63616E27 CANTOPN:"can'"
0222 74206F70         "t op"
0226 656E21           "en!"
0229 0D               DB 0D
022A 0A               DB 0A
022B 24               DB 24;$
022C 48206279 BYTE:"H by"
0230 74657320   "tes "
0234 6F6B24     "ok$"
              ;
ADP          =01CA  AWK          =0382  B2HEX1       =0214  
B2HEX2       =0205  B2HEX4       =01FF  B2HEXDP      =01E6  
BYTE         =022C  BYTECNTR     =0380  CANTOPN      =021E  
CMPEND       =0184  CRLF         =01BE  DEDP         =01F1  
DMA1         =0080  DMA2         =0300  FCALL        =0005  
FCB          =005C  FCB2         =006C  FCBWK        =038C  
HEX4DP       =01D5  LOOP1        =0108  LOOP2        =0135  
LOOP3        =0165  NOFILERR     =017C  NOTEQ        =0192  
RECNO        =007C  RECNO2       =03AC  SPDP         =01C8  


さっそく実行してみました。
下はそのときのログファイルです。
ここではもとのFTST6CMPをもとにして作った直後のプログラムを使いましたので、プログラム名はFCMP.COMではなくてVFTST6CP.COMになっていますが内容は上のリストと同じです。


logfile nd80zlog\07121004.txt open

ND80ZVに接続しました
0001 0000 - z
1000 00C3 - *** nd80z3 basic ****
>/cpm
loading zbds4k.bin ...19c1(6593)bytes loaded,from CC00 to E5C0
drive D ................................
drive C ................................
drive B ................................
drive A ................................

A>b:
B>dir
B: MTPLUS   000 : MTPLUS   001 : MTPLUS   002 : MTPLUS   003
B: MTPLUS   004 : MTPLUS   005 : MTPLUS   006 : MTPLUS   COM
B: HELLO    PAS : LINKMT   COM : PASLIB   ERL : HELLO    ERL
B: HELLO    COM
B>copy z:vftst6cp.com
VFTST6CPCOM to VFTST6CPCOM... done

B>vftst6cp linkmt.com c:linkmt.com

B>vftst6cp paslib.erl c:paslib.erl
4000 E5-F0
4001 E5-0A
4002 E5-A0
4003 E5-22
4004 E5-23
4005 E5-26
4006 E5-2A
4007 E5-46
4008 E5-73
4009 E5-00
400A E5-22
400B E5-6A
400C E5-7A
400D E5-B2
400E E5-2C
400F E5-E0
4010 E5-00
4011 E5-00
4012 E5-85
4013 E5-D1
4014 E5-D1
4015 E5-55
4016 E5-13
4017 E5-91
4018 E5-56
4019 E5-15
401A E5-20
401B E5-34
401C E5-74
401D E5-E4
401E E5-29
401F E5-40
4020 E5-C0
4021 E5-04
4022 E5-D4
4023 E5-BC
4024 E5-09
4025 E5-86
4026 E5-00
4027 E5-00
4028 E5-30
4029 E5-E8
402A E5-48
402B E5-03
402C E5-0E
402D E5-C3
402E E5-00
402F E5-88
4030 E5-40
4031 E5-00
4032 E5-02
4033 E5-F0
4034 E5-8C
4035 E5-AC
4036 E5-EB
4037 E5-08
4038 E5-8F
4039 E5-40
403A E5-01
403B E5-97
403C E5-28
403D E5-87
403E E5-00
403F E5-00
4040 E5-39
4041 E5-44
4042 E5-20
4043 E5-20
4044 E5-03
4045 E5-95
4046 E5-9A
4047 E5-00
4048 E5-00
4049 E5-08
404A E5-68
404B E5-50
404C E5-01
404D E5-78
404E E5-46
404F E5-56
4050 E5-75
4051 E5-84
4052 E5-48
4053 E5-20
4054 E5-00
4055 E5-C9
4056 E5-F8
4057 E5-3E
4058 E5-D2
4059 E5-A8
405A E5-A0
405B E5-02
405C E5-1A
405D E5-42
405E E5-00
405F E5-5E
4060 E5-11
4061 E5-95
4062 E5-9D
4063 E5-61
4064 E5-11
4065 E5-E0
4066 E5-00
4067 E5-32
4069 E5-10
406A E5-80
406B E5-40
406C E5-0E
406D E5-B7
406E E5-09
406F E5-CD
4070 E5-87
4071 E5-61
4072 E5-40
4073 E5-44
4074 E5-20
4075 E5-10
4076 E5-00
4077 E5-8B
4078 E5-02
4079 E5-00
407A E5-0A
407B E5-B0
407C E5-20
407D E5-03
407E E5-94
407F E5-43
4080 4C-37
4081 40-49
4082 0B-E4
4083 C2-9A


最初にLINKMT.COMを疑ったのですが、これはOKでした。
比較して相違するところがなければ何も表示されません。
次にPASLIB.ERLを比較したところ、なんと、ぶわっと不一致箇所が表示されました。
表示は延々と続きましたので途中で強制的にブレークしました。

エラーの原因はここにありました。
表示の最初の4桁はファイルの先頭を0000としたときの、その先頭からのバイト数です。
次の2桁は比較元のファイルのデータでその次の2桁が比較先のデータです。
先頭からのバイト数が4000から不一致が発生しています。
4000H=16384ですから16KBです。

おおお。
やっぱりそこか。
ZB3DOSのファイルシステムでは、1つのファイルディレクトリでは16KBのデータしか管理できません。
16KBを越えるファイルの場合には同じファイル名のディレクトリが複数作られて、エクステント番号でそれが管理されます。
ちょうど16KBを越えて新しいエクステントが作成されたところでエラーが発生していますから、そのタイミングで何かおかしなことが起きたことに間違いはありません。
16KBを越えるサイズのファイルコピーはもっと前から行なっていて、途中で何回かプログラム変更の度にいろいろな不具合が発生してそれをつぶしてきています。
今回もそれにからむトラブルです。
この前からDIRバッファとDMAバッファに関して大幅なプログラム変更を行ないましたから、それが影響している可能性が大です。

というところで本日は時間がなくなってしまいました。
この続きはまた次回にいたします。

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

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