home *** CD-ROM | disk | FTP | other *** search
- ;Program: TRIM
- ;Version: 1.0
- ;Author: Bruce Morgen
- ;Date: June 25, 1988
-
- ;Purpose: To truncate COM files at a requested address, used to
- ; delete unneeded DSEG from the output of linkers like
- ; DRI's LINK, L80, ZLINK, etc. Replaces the following
- ; ZEX script, adding DU:/DIR: response and much speed:
- ;
- ; ^$ ? ?
- ; a0:ddtz $1.com
- ; k100 $2
- ; y
- ; g0
-
- ;NOTE: Should be linked to a high address (8000h or so). TRIM
- ; is totally useless at a standard-TPA tool (although it
- ; could readily be re-written as one)! ZCPR 3.3 or later
- ; (or BGii 1.13 or later) is therefore required.
-
- CR EQU 13 ; ASCII
- LF EQU 10 ; "
- BEL EQU 7 ; "
- BDOSE EQU 0005H ; DOS entry vector
- PRNSTR EQU 9 ; Print string function #
- CLOSEF EQU 16 ; Close file " "
- TPA EQU 100H ; Normal Transient Program Area
- FCB1 EQU 05CH ; Default FCB #1
- FCB2 EQU 06CH ; " " "2
- Z3ENV EQU 00 ; Dummy value for Z3 environment
-
- PUBLIC COUT ; Make SYSLIB use ours
-
- EXTRN Z3LOG,EPRINT,EPSTR,BOUT
- EXTRN PFN2,EVAL16,PUTUD,GETUD
- EXTRN F$OPEN,F$READ,F$DELETE
- EXTRN F$MOPEN,F$WRITE,SETDMA
- EXTRN FILLBC,INITFCB
-
- ; TYPE 3 HEADER
-
- ; Code modified as suggested by Charles Irvine to function correctly with
- ; interrupts enabled. Program will abort with an error message when not
- ; loaded to the correct address (attempt to run it under CP/M or Z30).
-
- ENTRY:
- JR START0 ; Must use relative jump
- NOP ; Filler
- DB 'Z3ENV',3 ; Type-3 environment
- Z3EADR:
- DW Z3ENV ; Filled in by Z33
- DW ENTRY ; Intended load address
-
- START0:
- LD HL,0 ; Point to warmboot entry
- LD A,(HL) ; Save the byte there
- DI ; Protect against interrupts
- LD (HL),0C9H ; Replace warmboot with a return opcode
- RST 0 ; Call address 0, pushing RETADDR
- ; Onto stack
- RETADDR:
- LD (HL),A ; Restore byte at 0
- DEC SP ; Get stack pointer to point
- DEC SP ; To the value of RETADDR
- POP HL ; Get it into HL and restore stack
- EI ; We can allow interrupts again
- LD DE,RETADDR ; This is where we should be
- XOR A ; Clear carry flag
- PUSH HL ; Save address again
- SBC HL,DE ; Subtract -- we should have 0 now
- POP HL ; Restore value of RETADDR
- JR Z,START ; If addresses matched, begin real code
-
- LD DE,NOTZ33MSG-RETADDR ; Offset to message
- ADD HL,DE
- EX DE,HL ; Switch pointer to message into DE
- HLPEXT: LD C,PRNSTR
- JP BDOSE ; Return via BDOS print string function
- NOTZ33MSG:
- DB 'Not Z33+$' ; Abort message if not Z33-compatible
-
- START: LD A,(FCB1+1) ; Point to first token
- CP '/' ; Help query?
- JR Z,HELP ; Then honor it
- CP ' ' ; Blank?
- JR NZ,NOHELP ; No? Proceed...
- HELP: LD DE,HLP ; Otherwise point to help screen
- JR HLPEXT ; BDOS-print and go home...
- ; CPR stack more than suffices, we need only 14 or so levels...
- NOHELP: CALL PUTUD ; Save entry drive & user
- LD HL,FCB2+1 ; Point to second token
- CALL EVAL16 ; Compute to binary in DE, A = E
- OR D ; Test for a zero result
- JP Z,NOZERO ; Call that an error
- LD (HL),0 ; Null-terminate for printing
- LD HL,ENTRY ; Get our origin
- SBC HL,DE ; Subtract requested address
- JP C,TOOBIG ; Request can't be past ENTRY
- JP Z,TOOBIG ; Or right at it
- LD (SIZE),DE ; Otherwise save it away
- LD HL,FCB1+9 ; Point to filename extension
- LD A,(HL) ; Check for a blank one
- CP ' '
- JR NZ,GOTTYP ; Assume "COM" if it's blank
- LD (HL),'C'
- INC HL
- LD (HL),'O'
- INC HL
- LD (HL),'M'
- GOTTYP: CALL EPRINT ; Announce our function
- DB 'Trimming ',0
- LD DE,FCB1+1 ; Point at and print filename
- CALL PFN2
- CALL EPRINT ; Preface end address
- DB ' to 0',0
- LD HL,FCB2 ; Find first non-'0' digit
- FINDA0: INC HL
- LD A,(HL)
- CP '0'+1
- JR C,FINDA0
- CALL EPSTR ; Print end address
- LD A,'h' ; Say it's a hex number
- CALL BOUT
- DEC DE ; Point to FCB
- CALL Z3LOG ; Log in as per Z3 parse
- CALL INITFCB ; Initialize for BDOS
- CALL F$OPEN ; Open 'er up
- JP NZ,OPNERR ; A = 0 and Z if no BDOS error
- LD HL,TPA ; Point to TPA
- LD BC,ENTRY-TPA
- CALL FILLBC ; Zero-fill BC bytes, saving HL
- CALL EPRINT ; Announce next process, " "
- DB CR,LF,'Reading ',0
- JR RDSTRT ; Jump into read loop
- RDLOOP: PUSH HL ; Save new DMA pointer
- LD BC,(SIZE) ; Get end address
- XOR A ; Clears carry flag
- SBC HL,BC ; Subtract
- POP HL ; Get back new DMA pointer
- JR NC,DODEL ; Read done if bigger than end
- RDSTRT: CALL SETDMA ; Set DMA address
- CALL DOT ; Print a dot
- LD BC,128 ; Offset to next DMA address
- ADD HL,BC ; Add it in for next loop around
- CALL F$READ ; Read a record, saving regs.
- OR A ; Zero means good read
- JR Z,RDLOOP
- DEC A ; One means done reading file
- JR NZ,READERR ; Anything else is a DOS snafu
- CALL DOT ; Last dot...
- DODEL: CALL F$DELETE ; Kill old file
- CALL INITFCB ; Re-init FCB
- CALL F$MOPEN ; Make new file and open it
- JR NZ,OPNERR ; Branch on fatal error
- CALL EPRINT ; Announce next process
- DB CR,LF,'Writing ',0
- LD HL,TPA ; Start DMA at the bottom
- WRTLOOP:
- CALL SETDMA ; Set DMA
- CALL DOT ; DOT's right...
- CALL F$WRITE ; Write a record
- OR A ; Need a zero here
- JR NZ,WRITERR ; or it's a DOS failure
- LD BC,128 ; Offset to next DMA pointer
- ADD HL,BC ; Add it in for loop
- PUSH HL ; Test it against end address
- LD BC,(SIZE)
- XOR A
- SBC HL,BC
- POP HL
- JR C,WRTLOOP ; Loop if it's smaller
- DONE: LD C,CLOSEF ; BDOS function #16
- CALL BDOSE ; Call BDOS Bros.
- INC A ; Test for FFh
- JR Z,CLSERR ; That's an error
- CALL EPRINT ; Announce success
- DB BEL,CR,LF,'Done!',0
- EXIT: JP GETUD ; Reassert home drive & user,
- ; exeunt all...
-
- DOT: LD A,'.' ; Get a dot
- COUT: JP BOUT ; Print via BDOS
-
- ; ERROR EXIT ROUTINE
- ;
- NOZERO: LD HL,NZSTRG
- JR ERROR
- ;
- TOOBIG: LD HL,TBSTRG
- JR ERROR
- ;
- OPNERR: LD HL,OPNSTR
- JR ERROR
- ;
- READERR:LD HL,READSTRG
- JR ERROR
- ;
- WRITERR:LD HL,WRTSTRG
- JR ERROR
- ;
- CLSERR: LD HL,CLSSTR
- ;
- ERROR: CALL EPRINT ; Say it's an error
- DB BEL,CR,LF,'Fatal error: ',0
- CALL EPSTR ; Specify
- JR EXIT ; Go home
- ;
- NZSTRG: DB 'Zero-length requested, use SAVE',0
- ;
- TBSTRG: DB 'Can''t create a file that large',0
- ;
- OPNSTR: DB 'DOS failed to open file',0
- ;
- READSTRG:
- DB 'DOS attempted to read unwritten data',0
- ;
- WRTSTRG:DB 'DOS failed to write',0
- ;
- CLSSTR: DB 'DOS can''t close file',0
-
- ; HELP SCREEN
- HLP: DB 'TRIM, Version 1.0',CR,LF
- DB 'Syntax:',CR,LF
- DB ' TRIM FILENAME HEXADDR',CR,LF
- DB 'Saves a copy of "FILENAME" with',CR,LF
- DB 'a highest address of "HEXADDR"',CR,LF,'$'
-
- ; DATA AREA
- DSEG ; I know, why bother...
- SIZE: DS 2 ; Requested end address
-
- END