home *** CD-ROM | disk | FTP | other *** search
- ; Program: SDIFF - Size Difference
- ; Author: Rob Friefeld
- ; Version: 1.5
- ; Date: 28 Jun 1992
-
- .comment \
-
- Displays file size in records, kbytes and bytes.
- If two files named, shows size difference in bytes.
- Byte count does not include any trailing 0's or ^Z's.
- Byte count OK to 65534 record file size.
-
- Version 1.5 (Rob Friefeld) 6/28/92
- Corrected error in decimal output routine.
- New COUT routine in v1.4 did not filter high bits.
- Under CP/M, user number is not displayed.
-
-
- Version 1.4 release by Bruce Morgen 6/17/92
- Altered help screen to reflect whether
- "DU:|DIR:" or only "D:" will work in the current
- environment as suggested by Howard Goldstein.
-
- Version 1.4 beta by Bruce Morgen 6/2/92
- Fixed program so it would run sensibly under
- non-ZCPR3 systems, albeit sans DU: support.
- Shortened and simplified code in several
- places to cut a record from the COMfile size.
- Altered filename display to show both DU: and
- DIR: when appropriate. Made source M80-
- compatible for the SLR/ZMAC-impaired.
-
- Version 1.3
- Uses more elegant decimal conversion routine
- adapted from Gene Pizzetta's work on ZSLIB36.
- Size is about the same as "brute force" method.
-
- Version 1.2
- Byte count does not include trailing ^Z's.
- Accepts afn on command line.
-
- Version 1.1
- More robust command line parsing, thanks to warnings from
- Howard Goldstein.
-
- \
-
- ; ----- Externals ---------------
-
-
- .request b24tdc
- ext b24tdc ; Convert 24-bit quantity to ASCII decimal
-
- .request z3lib,syslib
- ext z3init,dutdir
- ext retud,logud,initfcb,bdos
- ext phldc,pafdc
-
- public cout,cout7 ; Internal routines use BDOS
-
-
- ; ----- Equates -----------------
-
- vers equ 15
-
- bdose equ 5
- fcb1 equ 5ch
- fcb2 equ 6ch
- tbuf equ 80h
- sfirst equ 17
-
- bell equ 7
- cr equ 0dh
- lf equ 0ah
-
-
- ; Move 3 byte quantity
- mov24 macro dest,src
- exx
- ld hl,src
- ld de,dest
- ld bc,3
- ldir
- exx
- endm
-
-
- ; ----- Type 1 Header -----------
-
- entry:
- jp start
- db 'Z3ENV',1
- z3eadr: dw 0
-
-
- ; ----- Program Start -----------
-
- start:
- sub a ; Test for z80 cpu
- jp pe,notz80 ; 8080, 8085 set parity flag Even
-
- ld (stack),sp
- ld sp,stack
-
- ; ----- Inits -------------------
-
- ld hl,(z3eadr) ; ENV address installed?
- ld a,h
- or l
- ld (zcprflg),a ; If not, don't call DUTDIR later.
-
- call Z3INIT
-
-
- ; ----- Command Line Parse ------
-
- optchk:
- ld hl,(fcb1+1)
- ld a,l
- ld de,'//'
- sbc hl,de ; carry already clear from above
- jr z,jzinfo ; // = help
-
- cp ' ' ; FCB1 blank?
- jzinfo: jp z,info ; No file name
-
-
- ; ----- Init file system --------
-
- ; Command line possibilities are:
- ; 1 filespec (where filespec = [du|dir]afn)
- ; 2 filespecs
- ; 1 filespec and 2nd DU only
-
- file_init:
- ld de,fcb1 ; Extract DU from FCB1
- call ducvrt
- ld (du1),bc
-
- ld e,fcb2 ; Extract DU from FCB2 (D =0)
- call ducvrt
- ld (du2),bc
- ld hl,tbuf ; Point to TBUFF character count
- ld b,h ; B = H = 0
- ld c,(hl) ; Count in BC
- add hl,bc ; Point to last character
- ld c,b ; C = B = 0
- endlp: ld a,(hl) ; Get character
- dec hl ; Point to previous one
- cp ' '+1 ; Blank or control character?
- jr c,endlp ; Loop if so
- cp ':' ; Make a colon a 255, else zero
- jr nz,colon
- dec c ; Result of colon search in C
- colon: inc de ; If no file2 name, copy 1st name
- ld a,(de)
- sub ' '
- push af ; save 2nd file result on stack
- jr nz,got2
- or c ; Result of colon search in C
- got2: ld (fflag),a ; Set files flag, Z = 1 file NZ = 2 files
- pop af
- jr nz,finit1 ; 2nd name was entered
- ld l,fcb1+1 ; H = 0
- ld c,11 ; B = 0
- ldir
- finit1:
- ld l,fcb2+1 ; Keep 2nd file name (H =0)
- ld de,fbuf
- ld c,11 ; B = 0
- ldir
-
-
- ; ----- Main --------------------
-
- sdiff:
- call logdu1 ; Log in 1st file du
- call pentry ; Print it's info
- mov24 b1,bcount ; Save byte count for comparison
- call print24bq ; Print byte count
-
- ld a,(fflag) ; 2 files?
- or a
- jp z,exit ; No, done
-
- ld hl,fbuf ; Recover 2nd file name
- ld bc,11
- ld de,fcb1+1
- ldir
- call logdu2 ; Log in 2nd file DU
- call pentry ; Print it's stuff
- mov24 b2,bcount
- call print24bq
-
- call print
- dc cr,lf,lf,' Difference:'
-
- mov24 bcount,b2 ; Subtract byte counts
- ld hl,b1
- ld de,bcount
- call sub24bq
- jr nc,sdiff2 ; F2-F1 >= 0
- mov24 bcount,b1 ; Else, reverse subtraction
- ld hl,b2
- call sub24bq
- sdiff2:
- call print24bq
- jp exit
-
-
- ; ----- Print info for file -----
-
- pentry:
- ld de,fcb1
- call wildcvrt ; Convert possible afn
-
- call crlf
- call pfile ; Print file name
- call crlf
- call readend ; Read last record
- jr nz,filesize
- jp nofile ; Bad read
-
-
- ; ----- Read last record
-
- ; EXIT: Z if no file
- ;
- ; DOS Function 23H is used. It returns the record number after the last
- ; record of the file in FCB+21H. If the last record was 0FFFFh, an ovfl
- ; bit is set. This routine does not make use of that fact.
-
- readend:
- ld de,fcb1 ; Init FCB1
- call INITFCB
-
- ld c,0fh ; Open file
- call BDOS
- inc a
- ret z ; Couldn't open for some reason
-
- ld c,23h ; Get end address
- call BDOS
- ld hl,(7dh) ; Record past end
- ld (recnt),hl
- dec hl ; -1
- ld (7dh),hl ; ..now last record
- ld c,21h ; Read random
- call BDOS
- ld c,10h ; Close file
- call BDOS
- or -1 ; Ret NZ
- ret
-
-
- ; ----- Display file size
-
- filesize:
- ld hl,bcount ; Init byte count
- xor a
- ld b,3
- ld (hl),a
- inc hl
- djnz $-2
-
- ld hl,(recnt) ; Get file end address
- ld a,h ; If 0 length or 8meg, this will be 0
- or l
- jr z,filemin
-
- call PHLDC ; Print RECORDS
- call print
- dc ' Rec'
-
- ld e,0 ; Compute KBYTES (HL was saved)
- ld b,3 ; /8
- files2:
- srl h ; /2
- rr l
- rr e ; Track CY
- djnz files2
- files3:
- ld a,h ; Less than 1k?
- or l
- jr z,files5
-
- xor a
- cp e
- jr z,files4
- inc hl
- files4:
- call PHLDC ; Print KBYTES
- call print
- dc 'k'
- jr files6
- files5:
- call print
- dc ' <1k'
- jr files6
-
- filemin:
- ld a,(recnt+2) ; Check ovfl
- or a
- jr nz,filemax
- call print
- dc ' 0 length file.'
- ret
- filemax:
- call print
- dc ' 8 megabyte file.'
- ret
-
- files6:
- call print
- dc ' '
-
- ; Compute byte count from # records and examination of last record
-
- getbytes:
- ld hl,tbuf+80h ; Point to end of last record
- ld b,80h
- gbytes1:
- dec hl ; Now backscan for nulls or ^Z's
- ld a,(hl)
- or a
- jr z,gbytes2
- cp 'Z'-'@'
- jr nz,saveby
- gbytes2:
- djnz gbytes1
-
- saveby:
- ld a,b ; Count of terminal 0's
- ld hl,(recnt) ; Convert records to bytes (*128)
- dec hl ; Compute 1 less
- or a ; Clear CY
- ld bc,7*256+0 ; 2**7 in B, mult ovfl in C
- savebylp:
- sla l
- rl h
- rl c ; If CY, move it into C
- djnz savebylp
-
- add a,l ; Now add back portion of last rec filled
- ld l,a
- ld a,b ; A = B = 0
- adc a,h
- ld h,a
- ld a,b ; A = B = 0
- adc a,c
- ld (bcount),hl ; Save 24-bit count
- ld (bcount+2),a ; High byte
- ret
-
-
- ; ----- Exits -------------------
-
- info:
- call print
- db 'SDIFF, Vers ',vers/10+'0','.',vers mod 10+'0'
- db ' - Show Size Difference of Two Files',cr,lf
- dc ' Syntax: SDIFF [d'
- call zdudir
- call print
- dc ':]ufn1 [d'
- call zdudir
- call print
- dc ':][ufn2]'
- exit:
- call crlf
- ld sp,(stack)
- ret
-
- zdudir:
- ld a,(zcprflg)
- or a
- ret z
- call print
- dc 'u|dir'
- ret
-
- nofile:
- call print
- dc ' No file'
- jr exit
-
-
- notz80: ld de,nz80msg
- ld c,9 ; Bdos print function
- jp bdose ; Exit with a return to ccp from dos
- nz80msg:
- db 'Need Z80/Z180 CPU$'
-
-
- ; ----- Print 24-bit Number -----
-
- print24bq:
- ld hl,bcount ; 3 byte number
- ld de,asbuf ; ASCII string destination
- call B24TDC ; Convert number
- call print24 ; Print string, formatted
- call print
- dc ' bytes'
- ret
-
-
- ; Print 8 digit ASCII string
- ; Output is right justified in 10 char field: dd,ddd,ddd
- ; Enter: DE -> string
-
- print24:
- push hl
- push de
- push bc
-
- ex de,hl ; HL -> string
- ld bc,7*256+0 ; Loop through 7 digits; C is 0 suppression flg
- p24loop:
- ld a,(hl)
- call printdec
- ld a,b ; Print "," when B = 6,3
- cp 6
- call z,comma
- cp 3
- call z,comma
- inc hl
- djnz p24loop
- ld a,(hl)
- pop bc
- pop de
- pop hl
- jr chrout ; Print 8th digit no matter what,
- ; then return to caller.
-
- ; Print ASCII digit in A. Print space if leading '0'.
- ; C = '0' suppression flag (Z = ON)
-
- printdec:
- cp '0' ; Print digit <> '0'
- jr nz,printdec1
- inc c ; Else, check suppression flag first
- dec c
- jr z,comma1 ; Flag ON, print space
- printdec1:
- inc c ; Make suppression flag NZ
- jr chrout
-
- ; Print comma if suppression flag off, else print space
-
- comma: xor a
- or c
- ld a,','
- jr nz,chrout
- comma1:
- ld a,' '
- chrout: jp cout7
-
-
- ;
- ; Subtract one 24-bit quantity from another. Store result in subtrahend.
- ; Entry: HL -> minuend
- ; DE -> subtrahend - remainder
-
- sub24bq:
- push hl
- push de
- push bc
- ld b,3
- xor a
- s24lp:
- ld a,(de)
- sbc a,(hl)
- ld (de),a
- inc de
- inc hl
- djnz s24lp
- pop bc
- pop de
- pop hl
- ret
-
-
- ; Log in 1st user/disk
- ;
- logdu1: ld bc,(du1)
- jr jlogud
- ;
- ; Log in 2nd user/disk
- ;
- logdu2: ld bc,(du2)
- jlogud: jp LOGUD
-
-
- ; ----- Convert DU
-
- ; Convert Z3FCB DU into DU in BC
- ;
- ; Enter: DE -> fcb
- ; Exit: BC = DU
- ; Uses: BC,AF
-
- ducvrt:
- call RETUD ; Get current disk/user
- ld a,(zcprflg)
- or a
- jr z,ducv1 ; only Z3 has user at code FCB+13
- push hl
- ld hl,13
- add hl,de
- ld c,(hl) ; User
- pop hl
- ducv1: ld a,(de) ; Drive
- dec a
- ret m
- ld b,a
- ret
-
- ; WILDCVRT - convert afn to first match ufn (assumes DOS DMA = 80h)
- ;
- ; Enter: DE -> afn fcb
- ; Exit: Z flag set if error
- ; Uses: AF,HL,BC
-
- wildcvrt:
- push hl
- push bc
-
- ld c,sfirst
- call BDOS
- cp 0ffh
- jr z,wldcx ; Nothing found -- error
-
- push de ; Move name to .DE+1
- inc de
- rrca
- rrca
- rrca
- add a,81h
- ld l,a
- ld bc,11 ; Move 11 chars
- ld h,b
- ldir
- pop de
- wldcx: pop bc
- pop hl
- ret
-
-
- ; ----- Print File Name
-
- pfile:
- call RETUD ; Get logged DU
- ld a,b ; Drive in B 0..15
- add a,'A'
- call cout7
- ld a,(zcprflg) ; If no ZCPR, don't print user
- or a
- jr z,pfile3
- ld a,c ; User in C
- call PAFDC
- call DUTDIR ; Is there an NDR entry for this DU?
- jr z,pfile3 ; No
- pfile2:
- call print ; DU/DIR divider
- dc '/'
- call pfile4
- pfile3:
- call print
- dc ':'
- ld hl,fcb1+1 ; Point to file name
- call pfile4 ; Print FILENAME
- ld a,(hl) ; Quit if no TYP
- cp ' '
- ret z
- call print
- dc '.'
- ld b,3
- jr pfile4a
-
- pfile4:
- ld b,8 ; Loop counter
- pfile4a:
- ld a,(hl) ; Print non-blanks
- inc hl
- cp ' '
- call nz,cout7
- djnz pfile4a
- ret
-
-
- ; ----- Console Output
-
- cout7:
- push af
- and 7fh
- jr cout1
- cout: ; Print char in A
- push af
- cout1: push hl
- push de
- push bc
- ld e,a
- ld c,6 ; Use BDOS function
- call bdose
- pop bc
- pop de
- pop hl
- pop af
- ret
-
-
- ; ----- In-line string print
-
- print:
- ex (sp),hl
- ld a,(hl)
- inc hl
- ex (sp),hl
- or a
- ret z
- call cout7
- ret m
- jr print
-
-
- crlf:
- call print
- dc cr,lf
- ret
-
-
- ; ----- Data --------------------
-
- dseg
-
- ds 60 ; Stack
- stack: ds 2
-
- zcprflg:
- ds 1 ; ZCPR running flag
- du1: ds 2 ; DU for file 1
- du2: ds 2 ; DU for file 2
- fbuf: ds 11 ; File name storage
- fflag: ds 1 ; Files flag
-
- recnt: ds 2 ; Temp - record count
- freeby: ds 1 ; Free bytes
- bcount: ds 3 ; 24-bit byte count
- b1: ds 3 ; File 1 count
- b2: ds 3 ; File 2 count
- asbuf: ds 8 ; Decimal count ASCII string
-
- end
-