home *** CD-ROM | disk | FTP | other *** search
- ; Binary compare file 1 and file 2. By C.B. Falconer.
- ;
- ; d>FDIFF [-o] [d[u]:]file1.typ [d[u]:][file2.typ]
- ; compares file1.typ to file2.typ
- ; (with full du addressing, across users, drives)
- ; the (optional) -options cause:
- ; n no page pauses
- ; number offset for 1st file byte
- ; (default 0, 0100h for .COM files)
- ; (number must be the last option)
- ;
- ; 1.1 86/12/02 Minor changes to use BUFFLIB 1.4, keep under 2k
- ;
- ; EX: d>FDIFF -n100 c3:fdiff.obj
- ; compares c3:fdiff.obj against current du:fdiff.obj,
- ; with initial address set to 0100h.
- ;
- ; SEE BUFFERS.DOC for linking instructions
- ;
- ver equ 11
- ;
- boot equ 0
- tfcb equ boot+05ch
- defdma equ boot+080h
- @cin equ 1
- @csta equ 11
- ;
- cr equ 0dh
- lf equ 0ah
- tab equ 9
- stksize equ 128; includes b.ohead
- multi equ 1
- nopause equ 2; flag word bits
- delta equ 080h; a difference found
- ;
- extrn .dos, b.ohead, .bfgetc
- extrn .bfropen, .pfnmdu, .xltusr
- extrn .skipblks, .nextch, .qnum
- extrn .couta, .tadzs, .tfnam, .t2hx, .t4hx, .crlf
- extrn .endata; End of data storage segment
- ;
- jmp begin; around patch area
- ;
- ; patchable constants
- lpp: db 20; lines per page before pause
- ;
- begin: lhld 6; set stack at top of memory
- mvi l,0
- sphl
- ; " "
- ; allocate the largest possible buffer
- lxi d,-.endata-stksize
- dad d; form size of memory available
- ora a; split into two buffers
- mov a,h ! rar ! mov h,a
- mov a,l ! rar ! mov l,a
- push h; save buffer size
- ; " "
- ; mark end of command line, just in case.
- ; Done by most CCPs, but undocumented. CCPLUS is documented
- ; lxi h,defdma
- ; mov a,m; line length
- ; inx h ! add l ! mov l,a
- ; adc h ! sub l ! mov h,a
- ; mvi m,0; mark eol
- ; " "
- call clear; flags and counters
- ; " "
- ; check for a verify flag
- lxi d,defdma+1
- call .skipblks
- cpi '-'
- jnz parse; no options
- call .nextch
- flgs1: call setup; some flag
- jc parse; not a valid flag, start over
- cpi ' '
- jnz flgs1; check another
- jmp parse1; field terminated. ptr past options
- ;
- ; parse the file names
- parse: call clear; in case bad options altered
- lxi d,defdma+1; set command scanning pointer
- ; " "
- ; Entry when command line options found
- parse1: lxi h,fcbin
- call .pfnmdu; will parse an empty line into
- lda fcbin+1; a blank FCB.
- sui ' '
- jz exit; no file specified, give help
- mov a,b; designated user
- call .xltusr; convert 0 into current, etc
- sta inuser; needed for chksame and show
- mov a,b; but bfropen needs original form
- pop b; get buffer size back
- push d; save input scan pointer
- lxi d,fcbin
- lxi h,.endata
- call .bfropen; open buffered file for read
- mvi a,1
- jc exit; can't find it, abort
- lxi h,.endata+b.ohead
- dad b; now rounded down to 128 mult.
- shld @outbuff; allocate output buffer
- pop d; restore input scan pointer
- push h; @outbuff
- push b; save buffer size
- lxi h,fcbout
- push h
- call .pfnmdu
- mov a,b; designated user
- call .xltusr; convert to standard form
- sta outuser; save for future
- lda fcbout+1
- cpi ' '
- cz filejam; no 2nd file, copy file1 name
- mov a,b
- pop d; fcbout
- pop b; buffer size
- pop h; @outbuff
- call .bfropen; open buffered file for read
- mvi a,2
- jc exit; can't find file2
- call chksame; ensure not comparing against self
- call chkcom; to set base to 0100h for .COMs
- ; " "
- ; All files open, files different, and buffers assigned.
- ; Compare fcbin and fcbout in largest possible blocks
- diff: lxi h,address
- call incrm; keep track of address
- lxi h,.endata
- call .bfgetc
- jc donea
- mov b,a
- lhld @outbuff
- call .bfgetc
- jc doneb
- cmp b
- jz diff
- ; " "
- ; show difference
- mov c,a
- call chkhdg; and set delta flag
- call pausechk
- lhld base
- lxi d,address
- ldax d ! add l ! mov l,a ! inx d
- ldax d ! adc h ! mov h,a ! inx d
- ldax d ! aci 0
- call .t2hx
- call .t4hx
- call tabber
- mov a,b
- xra c
- call .t2hx; show different bits
- ; " "
- call show; show file 1
- mov b,c
- call show; show file 2
- call .crlf
- jmp diff
- ;
- ; clear variables
- ; a,f,h,l
- clear: xra a ! mov h,a ! mov l,a
- sta flags; default all off
- sta line; on screen for differences
- shld base; default 0
- dcr a ! dcx h; all 0ffh
- shld address
- sta address+2; set to -1 (will increment)
- ret
- ;
- ; show values for b
- show: call tabber; show file 1
- mov a,b
- call .t2hx; show in hex
- call blks3
- mov a,b
- call ascii; ascii char or blank
- call blks3
- mov a,b
- jmp .tadzs; show in decimal
- ;
- ; 3 blanks
- blks3: call blk
- blks2: call blk
- jmp blk
- ;
- ; Check for the initial header. Mark files not identical.
- ; a,f,d,e,h,l
- chkhdg: lxi h,flags
- push b
- mov c,m
- mov a,c
- ori delta
- mov m,a
- xra c
- pop b
- rp; delta was already set
- ; " "
- ; output page heading
- ; a,f,d,e,h,l
- hdg: call .crlf
- call tabber
- call tabber
- lxi d,fcbin
- lda inuser
- call .tfnam
- call tabber
- lxi d,fcbout
- lda outuser
- call .tfnam
- call .crlf
- mvi a,7
- jmp msg
- ;
- ; Tab console over
- ; a,f
- tabber: mvi a,tab
- jmp .couta
- ;
- ; show a as char if printable, else as blank
- ; a,f
- ascii: ani 07fh
- cpi 07fh
- jz blk
- cpi ' '
- jnc .couta
- ; " "
- ; blank to console
- ; a,f
- blk: mvi a,' '
- jmp .couta
- ;
- ; check for pagination pause
- pausechk:
- mvi a,@csta
- call .dos
- ora a
- cnz abtchk
- lda flags
- ani nopause
- rnz
- lxi h,line
- inr m
- lda lpp; lines per page
- cmp m
- rnc
- mvi m,0
- mvi a,8
- call msg; [more]
- pc1: call abtchk
- cpi cr
- jnz pc1
- mvi a,9
- call msg; wipe out the [more]
- jmp hdg
- ;
- ; console char ready - check for abort. Return char.
- ; a,f
- abtchk: mvi a,@cin
- call .dos
- cpi 3
- jz boot; cntrl-c
- ret
- ;
- ; EOF on file1, check for eof on file 2
- donea: lhld @outbuff
- call .bfgetc
- mvi a,5
- jnc exit; file 1 shorter
- lda flags
- ora a
- jm boot; differences
- mvi a,6; same length
- jmp exit; files identical
- ;
- ; EOF on file2 and not file1
- doneb: mvi a,4
- ; " "
- ; Output message no. (a) and exit
- ; a,f,d,e,h,l
- exit: call msg
- jmp boot
- ;
- ; output message # (a)
- ; a,f,h,l
- msg: lxi h,msgtbl
- add a
- mov e,a ! mvi d,0 ! dad d
- mov e,m ! inx h ! mov d,m
- mvi a,9
- jmp .dos
- ;
- msgtbl: dw msg0, msg1, msg2, msg3, msg4
- dw msg5, msg6, msg7, msg8, msg9
- ;
- msg0:
- db 'FDIFF v', ver/10+'0', '.', ver MOD 10 + '0'
- db ' by C.B. Falconer.',cr,lf,lf
- db 'Usage: FDIFF [-n000] [d[u]:]file1.ft [d[u]:][file2.ft]'
- db cr,lf,lf
- db ' Default file2 is file1 when du''s different',cr,lf
- db ' Optional -n for no page pauses, -000 (hex) sets base'
- db cr,lf,lf
- db 'ex: FDIFF -100 a3:fdiff.obj',cr,lf
- db 'compare a3:fdiff.obj with current du:fdiff.obj,'
- db ' using addresses from 0100h'
- db cr,lf,'$'
- msg1: db 'Can''t find file1$'
- msg2: db 'Can''t find file2$'
- msg3: db 'File2 is same file as file1$'
- msg4: db 'file2 EOF before file1$'
- msg5: db 'file1 EOF before file2$'
- msg6: db 'No differences$'
- msg7: db 'Addr.',tab,'bits',tab,'Hex Asc. Dec.',tab
- db 'Hex Asc. Dec.',cr,lf,'$'
- msg8: db '[more]$'
- msg9: db ' $'
- ;
- ; jam file 2 name to file 1 name
- filejam:
- push h ! push d ! push b
- lxi d,fcbout+1
- lxi h,fcbin+1
- mvi b,11
- fj1: mov a,m ! ani 7fh; delete attrib bits
- stax d ! inx h ! inx d
- dcr b ! jnz fj1; more
- pop b ! pop d ! pop h
- ret
- ;
- ; check for same output file as input, or no output
- ; a,f,b,c,d,e,h,l (allowed)
- chksame:
- lda outuser
- mov b,a
- lda inuser
- xra b
- ani 01fh
- rnz; in/out different
- lxi h,fcbout
- lxi d,fcbin
- mvi b,12; check for different drives
- chk4: ldax d ! xra m; ignore attrib bits.
- ani 7fh ! rnz; in/out different
- inx h ! inx d
- dcr b ! jnz chk4; check more
- mvi a,3
- jmp exit; files same if here
- ;
- ; If either file is of type .COM, and base has not been set,
- ; jam the base value to 0100h.
- chkcom: lhld base
- mov a,l ! ora h ! rnz; already set
- lxi d,fcbin+9
- call cmp
- lxi d,fcbout+9
- cnz cmp; check fcbout if not fcbin.COM
- rnz; not a .com file
- lxi h,0100h
- shld base
- ret
- ;
- ; compare de^ for "COM". z flag if so
- cmp: lxi h,comtyp
- mvi b,3
- cmp1: ldax d ! cmp m ! rnz
- dcr b ! jnz cmp1
- ret
- ;
- comtyp: db 'COM'
- ;
- ; setup sets the appropriate flag and returns the next char
- ; a,f,h,l
- setup: lxi h,flags
- cpi 'N'
- jnz setup3
- mvi a,nopause
- ora m ! mov m,a
- jmp .nextch
- ;
- ; check for numeric input
- setup3: call .qnum
- rc; not a valid option
- lxi h,0
- setup4: ani 0fh
- dad h ! dad h ! dad h ! dad h
- ora l ! mov l,a
- call .nextch
- call qhex
- jnc setup4
- shld base
- cmc
- ret
- ;
- ; check for valid hex digit, convert if so,
- ; else return carry and unchanged a
- ; a,f
- qhex: call .qnum
- rnc
- cpi 'A'
- rc
- cpi 'F'+1
- cmc
- rc
- sui 7
- ret
- ;
- ; increment 24 bit long word hl^ in memory
- incrm: inr m ! rnz
- inx h ! inr m ! rnz
- inx h ! inr m
- ret
- ;
- ; --------- Data Segment --------
- ; Link this AFTER all the code segments
- ;
- dseg
- flags: ds 1; verify flag
- base: ds 2; display base
- address: ds 3; current display address
- line: ds 1; on current screen
- inuser: ds 1; user # for input file
- fcbin: ds 36; input file fcb
- outuser: ds 1; user # for output file
- fcbout: ds 36; output file fcb
- @outbuff: ds 2; location of 2nd file buffer
- ;
- ; This must be the last program storage, see linking above.
- ; Now uses BUFFLIB .endata. Alternatively use a separate dseg file.
- ;buffer: ds 0; =.endata; actually rest of memory
- ;
- end
- l╡