home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-03-01 | 26.8 KB | 1,307 lines |
- ;
- ; Program: DIFF
- ; Author: Carson Wilson
- ; Version: 3.0
- ; Date: 16 February 89
-
- vers equ 30
-
- ; Changes: Linked to corrected ZSGSTPCP routine.
- ; Added "(no stamp)" informative message.
- ; Cleaned up and organized code.
-
- ; Author: Carson Wilson
- ; Version: 2.9
- ; Date: 29 December 88
- ; Changes: Corrected premature termination error message - said
- ; "Source 1 .." when source 2 terminated prematurely,
- ; and "Source 2 .." for source 1.
- ; Fixed bugs which caused DIFF to abort during multiple
- ; compares when the files were different or with datestamp
- ; only (/D) option.
- ; Fixed bug introduced by Quiet code which caused files with
- ; same name, different stamp to be treated as equal files.
- ; Swapped OPEN12 and OPEN21 for greater efficiency.
- ; Slash before options now optional if three parameters are
- ; specified.
- ; Added terminating CR to restore cursor on exit.
- ; Linked with new version of ZSLIB which supports Z3PLUS
- ; datestamps.
- ; Note: Could use reorganization for clarity around CABORT:
-
- ; Author: Carson Wilson
- ; Version: 2.7
- ; Date: 4 September 88
- ;
- ; Changes: Changed /D option to /I (ignore datestamps) option.
- ; Added /D option (use datestamps only).
- ; Added /Q (quiet) option.
- ; Patchable options label now "[DIMQV>".
- ; Use ZSLIB PRDAT2 instead of PRDAT3.
- ; Help now does not show ZSDOS options unless ZSDOS present.
- ; Changed "File n is more recent" to "Source n...."
- ; Linked with SYSLIB 3.6 SCOMP routine due to SYSLIB4 bug.
- ; No longer gives "advance" prompt unless multiple compare.
-
- ; Author: Carson Wilson
- ; Version: 2.6
- ; Date: 24 August 88
- ; Changes: TPA overflow test for high-memory versions.
- ;
- ; Register 0 set according to file date comparison:
- ; REG 0 0 if one or both stamps missing or /I,
- ; REG 0 1 if file 1 more recent,
- ; REG 0 2 if file 2 more recent,
- ; REG 0 3 if file dates match.
- ;
- ; ZCPR program error flag set by default & reset only if both
- ; files found and names and dates, or data match (at EQUAL).
- ;
- ; Added local stack and QUIT routine.
- ;
- ; Use SETDMA for fast buffer loading.
- ;
- ; Allow abort during VERIFY with ^c.
- ;
- ; Use IX for file offset. NOTE: assumes OS preserves IX.
- ;
- ; Patchable options shown in help.
- ;
- ; FCBs now parsed by Z33 CCP, so can use options with only
- ; one file name, e.g., "DIFF myfile /d", and directory/user
- ; parse is same as CCP. This also saves considerable code.
- ;
- ; Implemented DSEG for shorter program length.
- ;
- ; Added patchable option defaults.
- ;
- ; Changed C(ompare) option to V(erbose) option, making brief
- ; output the default.
- ;
- ; Use (z3eadr) to detect ZCPR 3.3 environment,
- ; so that we can run with BGii. NOTE: if installed with Z3INS,
- ; will now run under ANY environment, with unpredictable results.
- ;
- ; Added "loaded at nnnn hex" message.
- ;
- ; Chains to Z33 error handler on wildcard names or bad directory.
- ;
- ; Removed reference to CAPS routine, shortening code length.
- ;
- ; Translated to lower case and Z80 opcodes.
- ;
- ; Added datestamp comparison for ZSDOS or DosDisk systems. Idea
- ; based on DATSWEEP by Bridger Mitchell. See DIFF26.DOC for
- ; details.
- ;
- ; Assembly: Z80ASM, SLRNK, Z3LIB, ZSLIB, SYSLIB.
- ;
- ; AUTHOR: Richard Conn
- ; VERSION: 2.0
- ; DATE: 18 MAY 84
- ; PREVIOUS VERSIONS: 1.6 (16 JAN 83)
- ; PREVIOUS VERSIONS: 1.5 (9 JAN 83), 1.4 (6 JAN 83), 1.3 (4 JAN 83)
- ; PREVIOUS VERSIONS: 1.2 (19 DEC 82), 1.1 (8 DEC 82), 1.0 (24 JULY 82)
- ; DERIVATION: COMPARE, VERSION 1.1
-
- ; SIZE OF BUFFER
-
- blimit equ 32 ; NUMBER OF 128-BYTE BLOCKS
- bsize equ blimit*128 ; 4K
-
- false equ 0
- true equ not false
- no equ false
- yes equ true
-
- ; CP/M Constants
-
- cpm equ 0 ; CP/M Warm Boot
- fcb1 equ 05ch
- fcb2 equ 06ch
- defdma equ 80h
- buff equ cpm+80h ; Temporary Buffer
- cr equ 0dh
- lf equ 0ah
- tab equ 9
- bell equ 7
- ctrlc equ 'C'-'@'
- ctrlx equ 'X'-'@'
-
- ; BDOS functions
-
- prints equ 9 ; Print string
- setdmaf equ 26
-
- ; ZCPR constants
- ;
- ; Z33 error codes
- ;
- ecambig equ 8 ; Ambiguous file specification
- ecbaddir equ 2 ; Bad directory specification
- ecnofile equ 10 ; File not found
-
- public $memry ; SLRNK fills in
-
- ; Externals
-
- ext getstp,prdat2,ptimm1 ; ZSLIB
- ext dostyp,cpmver,gstpcp
-
- ext retcst,puter3 ; Z33LIB (or new Z3LIB)
-
- ext z3init,getcrt,puter2,putreg ; Z3LIB
-
- ext phl4hc,phldc,pa2hc,padc ; SYSLIB
- ext bdos,initfcb,sksp,sknsp
- ext logud,retud
- ext f$open,f$close,f$read
- ext cin,cout,crlf,moveb,print,pstr
- ext compb,condin,setdma
-
- ; ======================================================
- ;
- ; CODE BEGINS
- ;
- entry:
- jp start
- db 'Z3ENV'
- db 3 ; Type-3 environment
- z3eadr:
- dw 0 ; Filled in by CCP
- loadadr:
- dw entry
- ;
- ; Patchable option defaults
- ;
- db '[DIMQV>' ; Label for patcher
- donlyd: db no ; D atestamp only
- ignord: db no ; I gnore datestamps
- multd: db no ; M ultiple runs
- quietd: db no ; Q uiet
- verbd: db no ; V erbose
- ;
- start:
- ld hl,(z3eadr) ; Point to ZCPR3 environment
- ;
- ; Start of Program -- Initialize ZCPR3 Environment
- ;
- ld a,h
- or l
- jr nz,gotz33 ; Filled in at run time if Z33
- call print
- db bell,'Need ZCPR 3.3 or greater',0
- ret
- gotz33:
- ld (stksav),sp
- ld sp,ourstk
-
- call z3init ;initialize the ZCPR3 Env and the VLIB Env
- ;
- ; Set operations flags from patchable defaults
- ;
- ld bc,5 ; 5 options
- ld de,donly ; Target in data segment
- ld hl,donlyd ; Source at top of file
- ldir ; Copy defaults for GO
-
- call getcrt ; GET CRT CHARACTERISTICS
- inc hl ; PT TO TEXT LINE COUNT
- inc hl
- ld a,(hl) ; GET line COUNT
- ld (lset),a ; SET COUNTER
- ;
- ; Extract command line information
- ;
- ld a,(fcb1+1)
- cp ' ' ; No parameters?
- jp z,prhelp ; PRINT HELP IF SO
- cp '/' ; ASKING FOR HELP?
- jp z,prhelp
- ;
- ; Abort to error handler on illegal directories
- ;
- ld a,(06bh) ; Get Z33 bad dir. flag (0=ok)
- ld b,a
- ld a,(07bh) ; Flag for FCB2
- or b
- jr z,zdirsok
- ld a,ecbaddir ; Error code
- jp z33err ; Chain to EH
- ;
- ; Warm boot if TPA overflow
- ;
- zdirsok:
- ld hl,(6) ; Get BDOS/RSX addr.
- $memry equ $+1 ; Initialized by linker
- ld bc,0 ; Get last byte used by DIFF
- or a ; Clear carry
- sbc hl,bc ; Last address < max. TPA?
- jr nc,tpaok ; Yes
- call print
- db bell,'TPA overflow',0
- jp 0 ; Warm boot
- ;
- ; Parse command line
- ;
- tpaok:
- call retud ; B = current disk 0..15
- ld ix,fcb1
- ld iy,fcb2
- ;
- ; Store drives, users for display
- ;
- ld a,(ix) ; Source drive
- or a
- jr nz,stores
- ld a,b ; Disk from RETUD above
- inc a ; To 1..16
- stores:
- ld (sdisk),a
- ld a,(iy)
- or a
- jr nz,stored
- ld a,b
- inc a ; To 1..16
- stored:
- ld (ddisk),a
-
- ld a,(ix+13) ; Store users
- ld (suser),a
- ld a,(iy+13)
- ld (duser),a
- ;
- ; Move FCB2 to high memory
- ;
- ld hl,fcb2
- ld de,fcbd
- ld b,12 ; Drive, name
- call moveb
- ;
- ld a,(iy+1)
- cp '/' ; 2nd name given?
- jr z,onename ; No
- cp ' '
- jr nz,twoname ; Yes
- ;
- ; No 2nd name, so copy 1st to 2nd
- ;
- onename: ; Set 2nd name to same as first
- ld hl,fcb1+1
- ld de,fcbd+1
- ld b,11 ; 11 BYTES
- call moveb
- twoname:
- ld hl,fcb1 ; SET UP SOURCE FCB
- call qcheck ; NO AMBIGUOUS ENTRIES PERMITTED
- ld hl,fcbd ; SET UP DESTINATION FCB
- call qcheck ; NO AMBIGUOUS ENTRIES PERMITTED
- ;
- ld hl,buff+1
- call sksp ; Skip parm1...
- call sknsp
- call sksp
- ld a,'/'
- cp (hl) ; "/"parm2?
- jr z,gotopt ; Yes, parse options
- call sknsp
- call sksp
- gotopt: inc (hl)
- dec (hl) ; Terminator?
- call nz,opts ; No, parse option(s)
-
- ; ----------------------------------------------------
- ;
- ; Compare files (re-enter here for multiple compares)
-
- mloop:
-
- ; Set program error flag and register 0 to defaults
-
- ld a,0ffh
- call puter2 ; Set program error flag TRUE
- xor a
- ld b,a
- call putreg ; Set register 0 to 0
-
- ; Print banner
-
- call banner
- ld a,(mult) ; Multiple runs?
- or a
- jr z,mloop1 ; No, print names (and dates if used)
- call qtest
- jr nz,mloop1 ; Override /M if quiet
-
- call print
- db cr,lf,' Strike ^C to Abort or RETURN to Proceed: ',0
- call cin ; GET RESPONSE
- cp ctrlc ; ABORT?
- jp z,dabort1
- ld c,13 ; RESET DISKS
- call bdos
- mloop1:
- ;
- ; Use datestamps?
- ;
- call prs1 ; Print source file name one
- ld a,(ignor) ; Test flag
- or a
- jr z,dodate ; If stamps, don't show second name now
- mloop1a:
- call prs2 ; Print name two
- jp open12 ; And go compare if needed
- ;
- ; Test if names equal
- ;
- dodate:
- ld de,fcb1+1
- ld hl,fcbd+1
- ld b,11
- call compb ; SYSLIB
- ld a,0
- jr z,storen ; Names match
- ld a,0ffh
- storen:
- ld (names),a ; 0=names match
- ;
- ; Display stamps
- ;
- call space1
- call logs ; Log to source disk/user
-
- ld de,fcb1
- ld hl,sdatbuf
- call getstp
- jr z,dodat0 ; Got stamp
- call gstpcp ; Try for CP/M Plus stamp
- jr z,dodat0 ; Got stamp
- call noserr ; Say no stamp
- jr mloop1a ; Skip stamps
- dodat0:
- ld hl,smodbuf
- call qprdat2 ; Try to print modify
- ld (smodok),a ; Save as flag (0=ok)
- jr z,dodat1 ; Modify ok
-
- ld hl,sdatbuf ; Try to print create
- call qprdat2
- jr z,dodat1 ; Got stamp
- call noserr ; Say no stamp
- jr mloop1a ; Skip stamps
- dodat1:
- call space1
- call qtest
- call z,ptimm1 ; Show time
-
- ld a,(smodok) ; Got source modify?
- or a
- ld hl,cstring
- jr nz,dodat2 ; No, say create
- ld hl,mstring
- dodat2:
- call qtest ; If not quiet
- call z,pstr ; ..say create or modify
- ;
- ; Got source stamp, now look for dest.
- ;
- call prs2 ; Print name 2
- call space1
- call logd ; Log to dest. disk/user
-
- ld de,fcbd ; Search for dest. stamp
- ld hl,ddatbuf
- call getstp
- jr z,dodat3 ; Got stamp
- call gstpcp ; Try for CP/M Plus stamp
- jr z,dodat3 ; Got stamp
- call noserr
- jp open21 ; No dest stamp, skip compare
- dodat3: ld hl,dmodbuf
- call qprdat2
- ld (dmodok),a ; Save (0=ok)
- jr z,dodat4
-
- ld hl,ddatbuf
- call qprdat2
- jr z,dodat4 ; Got stamp
- call noserr ; Say no stamp
- jr open21 ; Skip stamps
- dodat4:
- call space1
- call qtest
- call z,ptimm1 ; Show time
-
- ld hl,mstring ; Say modify
- ld a,(dmodok) ; Using modify?
- or a
- jr z,dodat5 ; Yes
- ld hl,cstring ; No, say create
- dodat5:
- call qtest
- call z,pstr ; Say create or modify
-
- ld hl,smodbuf ; Point to modify
- ld a,(smodok) ; Got source modify stamp?
- or a
- jr z,dodat6 ; Yes
- ld hl,sdatbuf ; No, use create
- dodat6:
- ld de,dmodbuf ; Point to dest. modify
- ld a,(dmodok) ; ok?
- or a
- jr z,dodat7 ; Yes
- ld de,ddatbuf ; No, use dest. create
- dodat7:
- ld b,5 ; Test 5 bytes yy mm dd hh mm
- call compb ; SYSLIB
- ld b,0 ; Set register 0
- ld a,3 ; Dates match
- ld hl,dmatstr
- jr z,dodat8
- ld a,2 ; File 2 more recent
- ld hl,twostr
- jr c,dodat8
- ld a,1 ; File 1 more recent
- ld hl,onestr
- dodat8:
- call putreg
- push af ; Save flags
- call qtest
- jr nz,dodat9 ; No display if quiet
- call crlf
- call pstr ; Show dates status
- dodat9:
- pop af ; Get flags
- jp nz,open21 ; Stamps don't match, compare data
-
- ld a,(names)
- or a ; Names match?
- jp z,equal1 ; Yes, exit or loop back for next test
-
- ; --------------------------------------------
- ;
- ; Open files for data compare
- ;
- ; Open source 2, then source 1
- ;
- open21:
- ld a,(donly)
- or a
- jp nz,mloop2 ; Quit if datestamp only test
-
- call logd ; Log in dest
- ld de,fcbd ; TRY TO OPEN SOURCE 2
- call initfcb ; INIT FCB
- call f$open
- jp nz,f2err
-
- call logs ; LOG IN SOURCE
- ld de,fcb1 ; TRY TO OPEN SOURCE 1
- call initfcb ; Init FCB in case /i option used
- call f$open ; Z IF NO ERROR
- jp nz,f1err
- jr compare
- ;
- ; Open source 1, then source 2
- ;
- open12:
- ld a,(donly)
- or a
- jp nz,mloop2 ; Quit if datestamp only test
-
- call logs ; LOG IN SOURCE
- ld de,fcb1 ; TRY TO OPEN SOURCE 1
- call initfcb ; Init FCB in case /i option used
- call f$open ; Z IF NO ERROR
- jp nz,f1err
- ;
- call logd ; LOG IN DEST DISK/USER
- ld de,fcbd ; TRY TO OPEN SOURCE 2
- call initfcb ; INIT FCB
- call f$open
- jp nz,f2err
- ;
- ; Both files open. Compare data.
- ;
- compare:
- xor a ; A=0
- ld (first),a ; SET FLAG FOR FIRST ERROR
- ld ix,0 ; Init offset
- call verify ; PERFORM VERIFICATION
- ld a,(first) ; ANY ERRORS?
- or a ; Match?
- jp nz,mloop2 ; No
- ;
- ; Files identical. Tell user.
- ;
- equal:
- call qtest
- jr nz,equal1 ; No display if quiet
- call print
- db cr,lf,' Files are identical',0
- ;
- ; Files identical or names and dates match. Reset program error flag
- ;
- equal1:
- xor a ; No errors, so files match
- call puter2 ; Reset ZCPR program error flag
- mloop2:
- ld a,(mult) ; CHECK FOR MULTIPLE RUNS
- cpl
- ld b,a ; 0ffh=single
- ld a,(quiet) ; 0ffh=quiet
- or b ; Single or quiet?
- jp nz,quitlf ; Yes, exit
- ;
- ; Back for next test (multiple run)
- ;
- call crlf ; NEW LINES
- jp mloop
-
- ; -----------------------------------------
- ;
- ; File open errors
- ;
- f1err:
- call prs1a
- jr ferr
- f2err:
- call prs2a
- ferr:
- call print
- db '- not found',0
- jp mloop2
-
- ; No stamp error
-
- noserr:
- call qtest
- ret nz ; Don't print if quiet
- call print
- db '(no stamp) ',0
- ret
-
- ; ----------------------------------------------
- ;
- ; Parse command line options
- ;
- opts:
- ld a,(hl) ; GET NEXT OPTION CHAR
- inc hl ; PT TO NEXT
- or a ; END OF LINE?
- ret z
- cp ' ' ; SKIP SPACES
- jr z,opts
- cp ',' ; ..commas..
- jr z,opts
- cp '/' ; ..and slashes
- jr z,opts
- ld de,otab ; PT TO OPTION TABLE
- ld b,a ; OPTION CHAR IN B
- opts1:
- ld a,(de) ; GET TABLE CHAR
- or a ; OPTION NOT FOUND?
- jp z,prhelp
- cp b ; MATCH?
- jr z,opts2
- inc de ; SKIP TO NEXT
- inc de
- inc de
- jr opts1
- opts2:
- ex de,hl ; USE HL
- inc hl ; GET ADDRESS
- ld a,(hl) ; GET LOW
- inc hl
- ld h,(hl) ; GET HIGH
- ld l,a ; PUT LOW
- ex de,hl ; DE PTS TO OPTION ADDRESS, HL TO NEXT BYTE
- ld bc,opts ; SET UP RETURN ADDRESS
- push bc
- push de ; SET UP OPTION ADDRESS
- ret ; "RUN" OPTION
- ;
- ; Option table
- ;
- otab:
- db 'D' ; Test dates only
- dw sdonlyf
- db 'I'
- dw signorf
- db 'M' ; Multiple run
- dw smultf
- db 'Q' ; Quiet
- dw squietf
- db 'V' ; Verbose
- dw sverbf
- db 0 ; End of table
- ;
- ; Set use dates only
- ;
- sdonlyf:
- ld a,(donlyd)
- cpl ; Reverse default
- ld (donly),a
- ret
- ;
- ; Set ignore date flag
- ;
- signorf:
- ld a,(ignord)
- cpl ; Reverse default
- ld (ignor),a
- ret
- ;
- ; Set multiple run flag
- ;
- smultf:
- ld a,(multd)
- cpl ; Reverse default
- ld (mult),a
- ret
- ;
- ; Set DIFF quiet flag
- ;
- squietf:
- ld a,(quietd)
- cpl ; Reverse default
- ld (quiet),a
- ret
- ;
- ; Set verbose flag
- ;
- sverbf:
- ld a,(verbd)
- cpl ; Reverse default
- ld (verb),a
- ret
- ;
- ; Skip to non-blank char
- ;
- sblank:
- ld a,(hl) ; GET CHAR
- inc hl ; PT TO NEXT
- cp ' ' ; BLANK?
- jr z,sblank
- dec hl ; PT TO NON-BLANK
- ret
-
- ; ------------------------------------------------
- ;
- ; Print help message
- ;
- prhelp:
- call banner1 ; PRINT BANNER
- call print
- db cr,lf
- db ' Syntax:',cr,lf
- db tab,'DIFF /',tab,tab,tab,tab,tab,'- help',cr,lf
- db tab,'DIFF [dir:]ufn [dir:][ufn] [/][options]'
- db tab,'- compare',cr,lf
- db ' Options:',cr,lf,0
- call dostyp ; Extended BDOS?
- jr z,prhelp1 ; No
- cp 'S' ; Yes
- jr z,prhelp2 ; Ok if ZSDOS,
- cp 'D'
- jr z,prhelp2 ; ..or ZDDOS..
- jr prhelp3 ; Else forget it
- prhelp1:
- ld a,(cpmver) ; We have CP/M
- cp 30h ; Plus?
- jr c,prhelp3 ; No
- prhelp2:
- call print
- db tab,'D - test Datestamps only',tab,tab,0 ; tab to col 49
- ld a,(donlyd)
- call printd ; Show patched default
- call print
- db tab,'I - Ignore datestamps',tab,tab,tab,0
- ld a,(ignord)
- call printd
- prhelp3:
- call print
- db tab,'M - Multiple runs with disk change',tab,0
- ld a,(multd)
- call printd
- call print
- db tab,'Q - Quiet',tab,tab,tab,tab,0
- ld a,(quietd)
- call printd
- call print
- db tab,'V - Verbose',tab,tab,tab,tab,0
- ld a,(verbd)
- call printd
- call print
- db ' Results stored in Program Error Flag and Register 0.'
- db 0
- jp quitlf
- ;
- ; PRINTD - Show default option in help screen.
- ;
- ; 0 = (off)
- ;
- printd:
- or a
- jr z,prind1 ; Off if zero, else on
- call print
- db '(on)',cr,lf,0
- ret
- prind1:
- call print
- db '(off)',cr,lf,0
- ret
-
- ; ---------------------------------------------------
- ;
- ; Check for any question marks from HL+1 to HL+11
- ; Affect only AF registers if OK
- ;
- qcheck:
- push hl ; SAVE HL
- push bc ; SAVE BC
- inc hl ; PT TO FIRST CHAR
- ld b,11 ; 11 BYTES
- ld c,'?' ; SCAN FOR '?'
- qc:
- ld a,(hl) ; GET BYTE
- cp c ; '?'?
- jr z,qc1
- inc hl ; PT TO NEXT
- dec b ; COUNT DOWN
- jr nz,qc
- pop bc ; RESTORE
- pop hl
- ret
- qc1:
- pop bc ; RESTORE AND ABORT
- pop hl
- pop de ; DROP RETURN ADDRESS
-
- ; fall thru
-
- ld a,ecambig ; Ambiguous file spec. error
- ;
- ; Chain to Z33 error handler.
- ; Set error, ECP, and external program bits of command status flag
- ; to tell CCP there is an error, to go straight to the error handler
- ; (not the ECP), and not to alter the command error byte at z3msg+0:
- ;
- z33err:
- call retcst ; Z33LIB return command status byte
- ld (hl),00001110b
- call puter3 ; Z33LIB set command error byte
- jp quit ; Return to CCP with bits set
-
- ; -------------------------------------------------
- ;
- ; Print banner
- ;
- banner:
- call qtest
- ret nz ; Don't print if quiet
- banner1:
- call print
- db cr,lf
- db 'DIFF, Version ',vers/10+'0','.',(vers mod 10)+'0'
- db ' - Compare files (loaded at ',0
- ld hl,(loadadr)
- call phl4hc
- call print
- db 'h)'
- db 0
- ret
-
- ; ----------------------------------------------------
- ;
- ; Print names of source files
- ; PRS1 -- source file 1
- ; PRS2 -- source file 2
- ;
- prs1:
- call qtest
- ret nz
- prs1a:
- call print
- db cr,lf,' Source 1: ',0
- ld hl,sdisk ; PT TO FIRST BYTE
- call prud
- ld de,fcb1 ; SOURCE FCB
- jp prfna ; PRINT FILE NAME
-
- prs2:
- call qtest
- ret nz
- prs2a:
- call print
- db cr,lf,' Source 2: ',0
- ld hl,ddisk ; PT TO FIRST BYTE
- call prud
- ld de,fcbd ; DESTINATION FCB
- jp prfna ; PRINT FILE NAME
-
- ; ---------------------------------------------
- ;
- ; MAIN VERIFY ROUTINE
- ;
- verify:
- ld a,(quiet)
- ld b,a
- ld a,(verb)
- or b ; Quiet or verbose mode?
- call z,prdot ; No, show progress with '.'
- ;
- ld hl,buff1 ; Point for load
- push hl ; SAVE PTR
- call logs ; LOG IN SOURCE 1
- ld de,fcb1 ; SOURCE 1 FCB
- call load ; READ IN BLOCK
- ld a,(bcnt) ; GET OLD BLOCK COUNT
- ld (bcnt1),a ; SAVE IT - bcnt1 stores blocks for fcb1
- ld hl,buff2 ; Point for load
- push hl ; SAVE PTR
- call logd ; LOG IN SOURCE 2
- ld de,fcbd ; SOURCE 2 FCB
- call load ; READ IN BLOCK
- pop de ; DE PTS TO BUFF 2
- pop hl ; HL PTS TO BUFF 1
- ld a,(bcnt) ; CHECK FOR NO BLOCK READ - bcnt = fcbd blks
- ld b,a
- ld a,(bcnt1)
- or b
- ret z ; DONE IF NONE READ
- ;
- ; Verify loaded buffers by comparing them and printing differences
- ;
- verblock:
- call condin ; Get input, if any
- cp ctrlc ; Abort?
- jp z,dabort
- ld b,128 ; SCAN ONE BLOCK
- verbl:
- ld a,(de) ; GET BYTE
- cp (hl) ; COMPARE
- call nz,nomatch ; PRINT DIFFERENCE or quit
- inc ix ; Inc offset <crw>
- inc hl ; PT TO NEXT
- inc de
- djnz verbl ; Count down bytes
- ;
- ld a,(bcnt) ; COUNT DOWN blocks
- dec a
- ld (bcnt),a
- ld a,(bcnt1)
- dec a
- ld (bcnt1),a
- jr z,vereq
- ld a,(bcnt) ; CHECK FIRST BUFFER COUNT
- or a
- jr nz,verblock ; CONTINUE COMPARE IF NOT EMPTY
- vereq:
- ld a,(bcnt) ; CHECK FOR BOTH DONE
- ld b,a
- ld a,(bcnt1)
- or b ; IF ZERO, BOTH DONE AT SAME TIME AND CONTINUE
- jp z,verify
-
- ld a,(bcnt1) ; CHECK FOR ONE DONE BEFORE THE OTHER
- or a ; 2ND DONE?
- ld c,'1' ; GET LETTER
- jr z,done1
- ld c,'2' ; GET LETTER
-
- ; One file is shorter than the other -- say so and quit or return
-
- done1:
- call qtest
- jp nz,quit ; Don't print if quiet
-
- call print
- db cr,lf,' Source ',0
- ld a,c
- call cout ; PRINT LETTER
- call print
- db ' has terminated prematurely',0
-
- cabort: ; Abort this compare
- ld a,0ffh
- ld (first),a ; Flag shows files were different
- call print
- db cr,lf,' Files are different',0
- ret ; Back for next or quit
- ;
- ; Match error
- ;
- nomatch:
- call qtest
- jp nz,quit ; Don't print if quiet
- ;
- ld a,(verb) ; Get verbose flag
- or a ; Z=simple compare
- jr nz,nmat0
- pop hl ; Drop return address (VERIFY)
- jr cabort ; Abort or back for next
- nmat0:
- push hl ; SAVE REGS
- push de
- push bc
- ld a,(first) ; FIRST TIME THRU?
- or a ; 0=YES
- jp z,nmat3
- ld a,(lcnt) ; CHECK FOR NEW SCREEN
- or a ; ZERO IF DONE
- jp nz,nmat4
- call print
- db cr,lf,' DIFF: Strike RETURN to Continue, ^C to Abort',0
- ld a,(mult) ; In multiple run?
- or a
- jr z,nmat1 ; No
- call print
- db ', or ^X to Advance',0
- nmat1: call print
- db ' - ',0
- call cin ; GET RESPONSE
- cp ctrlc ; ABORT?
- jr z,nmat2
- cp ctrlx ; ADVANCE?
- jp nz,nmat3 ; No
- ld a,(mult) ; Yes, see if multiple run
- or a
- jp z,nmat3 ; No, ignore ^x
- pop bc ; Yes, advance. CLEAR REGS
- pop de
- pop hl
- pop de ; CLEAR STACK
- call print
- db cr,lf,' DIFF Advancing',0
- ret ; RETURN TO VERIFY CALLER
- nmat2:
- pop bc ; CLEAR REGS
- pop de
- pop hl
- dabort: pop de ; Clear stack
- dabort1:call print
- db cr,lf,' DIFF Aborting',0
- quitlf: ld a,cr ; Quit with CRLF
- call qcout
- ld a,lf
- call qcout
- quit: ld sp,(stksav)
- ret ; RETURN TO OPSYS
- nmat3:
- ld a,0ffh ; CLEAR FIRST TIME FLAG
- ld (first),a
- call header ; PRINT HEADING AND RETURN NEW LINE COUNT
- nmat4:
- dec a ; COUNT DOWN 1 LINE
- ld (lcnt),a ; NEW LINE COUNT
- call crlf
- push hl ; SAVE HL
- push ix ; Get offset to HL
- pop hl
- call phl4hc ; PRINT AS HEX
- call spacer ; PRINT SPACES
- call phldc ; PRINT AS DEC
- pop hl ; RESTORE HL
- call spacer
- call spacer
- ld a,' '
- call cout
- ld a,(hl) ; GET SOURCE 1 VALUE
- call prval ; PRINT AS HEX, DEC, ASCII
- call spacer ; 10 SPACES
- call spacer
- call spacer
- call spacer
- call spacer
- ld a,(de) ; GET SOURCE 2 VALUE
- call prval ; PRINT AS HEX, DEC, ASCII
- pop bc ; RESTORE REGS
- pop de
- pop hl
- ret
-
- ; ----------------------------------------------
-
- ; Print header and return new line count in A
-
- header:
- push de ; SAVE REGS
- push hl
- call print
- db cr,lf,' Rel Offset ',0
- ld hl,sdisk ; PRINT DISK/USER
- call prud
- ld de,fcb1
- call prfn ; PRINT FILE NAME
- call spacer ; 5 SPACES
- call spacer
- ld hl,ddisk ; PRINT DISK/USER
- call prud
- ld de,fcbd
- call prfn ; PRINT FILE NAME
- call print
- db cr,lf,' Hex Dec Hex Dec Asc Hex Dec Asc',0
- ld a,(lset) ; SET LINE COUNT
- sub 1 ; ADJUST FOR HEADING AND FOOTER
- ld (lcnt),a
- pop hl
- pop de ; RESTORE REGS
- ret
-
- ; ------------------------------------
-
- ; Print A as hex, dec, and ASCII
-
- prval:
- call spacer ; 3 SPACES
- call space1
- call pa2hc ; PRINT AS HEX
- call spacer
- call padc ; PRINT AS DEC
- call spacer
- and 7fh ; MASK OUT MSB
- cp 7fh ; DOT FOR <DEL>
- jr z,prdot
- cp ' ' ; PRINT DOT IF LESS THAN <SP>
- jp nc,cout
- prdot:
- ld a,'.' ; PRINT DOT
- jp cout
-
- ; -----------------------------
-
- ; Print 2 spaces
-
- spacer:
- call space1
- space1:
- push af
- ld a,' '
- call qcout
- pop af
- ret
-
- ; --------------------------------------------------------
- ;
- ; Load buffer at HL from file whose FCB is pted to by DE
- ; On output, bcnt=number of blocks loaded (up to blimit)
- ;
- load:
- xor a ; A=0
- ld (bcnt),a ; SET BLOCK COUNT
-
- ; Main load loop
-
- load1:
- call setdma ; To (hl)
- call f$read ; READ A BLOCK
- or a ; END OF FILE?
- ret nz ; RETURN IF DONE
-
- ld bc,128
- add hl,bc ; Point to next block
- ld a,(bcnt) ; GET BLOCK COUNT
- inc a ; INCREMENT IT
- ld (bcnt),a ; SET IT
- cp blimit ; LAST BLOCK READ?
- jr nz,load1
- ret
-
- ; ----------------------------------------------------------
- ;
- ; Log in source (logs) and destination (logd) drives/users
- ;
- logs:
- ld a,(sdisk) ; GET DISK
- dec a ; A=0
- ld b,a
- ld a,(suser) ; GET USER
- ld c,a
- call logud ; LOG IN
- ret
- logd:
- ld a,(ddisk) ; GET DISK
- dec a ; A=0
- ld b,a
- ld a,(duser) ; GET USER
- ld c,a
- call logud ; LOG IN
- ret
-
- ; -----------------------------------------------
- ;
- ; Print disk/user pted to by HL (2 bytes)
- ;
- prud:
- ld a,(hl) ; GET DISK
- add a,'A'-1 ; CONVERT TO LETTER
- call cout
- inc hl ; PT TO USER
- ld a,(hl) ; GET USER
- call padc ; PRINT AS DEC
- call print
- db ': ',0
- ret
-
- ; ----------------------------------------------
- ;
- ; Print file name whose fcb is pted to by DE
- ;
- prfn:
- call qtest
- ret nz ; Don't print if quiet
- prfna:
- push hl ; SAVE REGS
- push de
- push bc
- ex de,hl ; FN PTED TO BY HL
- inc hl ; PT TO FIRST CHAR
- ld b,8 ; 8 CHARS
- call prfn1
- ld a,'.'
- call cout
- ld b,3 ; 3 CHARS FOR FILE TYPE
- call prfn1
- call space1
- pop bc ; RESTORE REGS
- pop de
- pop hl
- ret
- prfn1:
- ld a,(hl) ; GET CHAR
- inc hl ; PT TO NEXT
- call cout ; PRINT
- dec b ; COUNT DOWN
- jr nz,prfn1
- ret
-
- ; ----------------------------------------------------
-
- ; Special Quiet Output Routines for /Q option
-
- ;
- ; QTEST - Test quiet flag
- ;
- ; Exit: (NZ) if quiet active
- ; Uses: - <F>
- qtest:
- push bc
- ld b,a
- ld a,(quiet)
- or a ; Set Z flag
- ld a,b
- pop bc
- ret
- ;
- ; QCOUT - Print char. in A unless quiet option active
- ; Uses: <F>
- ;
- qcout:
- call qtest
- ret nz ; Quit if quiet
- jp cout ; Print char & return
- ;
- ; QPRDAT2 - Print date at HL, or just test if quiet option
- ;
- ; Exit: (Z) and A=0 if month ok.
- ; (NZ) and A=0FFh if not ok.
- ; Date printed if not quiet.
- ; Uses: - <AF>
- qprdat2:
- call qtest
- jp z,prdat2 ; Print & return if not quiet
-
- push hl
- inc hl ; Test month
- ld a,(hl)
- or a
- jr z,errexit
- cp 13h
- jr nc,errexit
- xor a ; No error return
- jr exit
- errexit:
- or 0ffh ; Error return
- exit:
- pop hl
- ret
-
- ; =================================================
- ;
- ; DATA AREAS
- ;
- ; Initialized data
- ;
- cstring:
- db ' - created ',0
- mstring:
- db ' - last modified ',0
- dmatstr:
- db ' File dates match ',0
- twostr:
- db ' Source 2 is more recent ',0
- onestr:
- db ' Source 1 is more recent ',0
-
- ; ------------------------------------------------
- ;
- ; Uninitialized RAM
- ;
- DSEG
-
- ; The next five data items must be contiguous and in the same
- ; order as the patchable default options at label DONLYD.
-
- donly: ds 1 ; Test datstamps only (0=test data also)
- ignor: ds 1 ; Ignore dates flag (0=use dates)
- mult: ds 1 ; Multiple run flag (0=no mult runs)
- quiet: ds 1 ; Quiet mode (0=not quiet)
- verb: ds 1 ; Verbose flag (0=simple compare)
-
- names: ds 1 ; 0=names match
-
- smodok: ds 1 ; Source modify year flag
- dmodok: ds 1 ; Dest.
- offset: ds 2 ; RELATIVE OFFSET
-
- first: ds 1 ; ERROR INDIC
-
- lset: ds 1 ; NUMBER OF TEXT LINES ON SCREEN
- lcnt: ds 1 ; LINE COUNT
-
- sdisk: ds 1 ; SOURCE DISK (MUST BE FOLLOWED BY SUSER)
- suser: ds 1 ; SOURCE USER
-
- ddisk: ds 1 ; DEST DISK (MUST BE FOLLOWED BY DUSER)
- duser: ds 1 ; DEST USER
-
- fcbd: ds 36 ; DESTINATION FCB
-
- bcnt: ds 1 ; BUFFER COUNT
- bcnt1: ds 1 ; SECOND BUFFER COUNT
-
- sdatbuf: ; Buffer for 1st file's stamp <crw>
- ds 10 ; Create, access stamps
- smodbuf:ds 5 ; Modify stamp
- ds 113 ; For future ZSDOS compat.
-
- ddatbuf:
- ds 10 ; Create, access stamps
- dmodbuf:ds 5 ; Modify stamp
- ds 113
-
- stksav: ds 2 ; Entry stack
- ds 60 ; Local stack
- ourstk:
-
- buff1:
- ds bsize+1 ; File compare buffers
- buff2:
- ds bsize+1
-
- end
-
- ; END DIFF.Z80