; T4GEN.Z80 ; ; Generates a type-4 Z-System program, from a pair of Intel HEX format ; files. The input files result from the assembly or linking of the ; same source, first with a 0 org, then with a 100h org. ; ; SYNTAX: ; ; T4GEN <[du:|dir:]fn1> [du:|dir:][] ; ; where designates the pair of input files, and provides an ; output file identifier (optional) which will be prefixed with 'T4'. ; If is not defined, the output file identifier defaults to . ; ; Both input files must share the same directory and , and are ; distinguished by a of .HX0 (assembled at org = 0), or of .HX1 ; (assembled at org = 100h), respectively. The output file is assigned ; a .COM . ; History -- ; Date Version Author & Comments ; ---- ------- ----------------- ; 04/08/89 1.0 - Release ; ; 04/03/89 0.1 - Inserted default DU restoration ; 4 locations marked (0.1) ; - Updated READBF, LOADBF to vers. 0.1 ; - Corrected error messages ; ; 04/01/89 0.0 L. VanHemelryck - First code ; ; ;================[ Equates and External Routines ]================ ; VERS EQU 10 ; CR EQU 0DH LF EQU 0AH ; BOOT: EQU 0000H ; Jump to Boot Entry FCB1: EQU 005CH ; Default primary FCB FCB2: EQU 006CH ; Default secondary FCB ; ;- ; Work Area Structure PIVOT: EQU 0 ; Work area Reference Pivot FCB$OFS: EQU PIVOT ; Offset to FCB EX$OFFST: EQU FCB$OFS + 12 ; EXtent offset CR$OFFST: EQU FCB$OFS + 32 ; Current Record offset ; WORKBUF: EQU PIVOT + 36 BCNT$OFS: EQU WORKBUF ; Offset to Record Buffer counter BPNT$OFS: EQU BCNT$OFS + 1 ; Offset to Record Buffer pointer RCBF$OFS: EQU BPNT$OFS + 2 ; Offset to Record Buffer ; (128-byte Record Buffer) NEXT$OFS: EQU RCBF$OFS + 128 ; Offset to next Load Address RQST$OFS: EQU NEXT$OFS + 2 ; Offset to requested Load Address HXCT$OFS: EQU RQST$OFS + 2 ; Offset to HEX byte/line counter ;- ; EXT INITWA,READHX,LOADBF,REWFIL,BAKFILL ; T4GLIB EXT Z3INIT,Z3LOG,QPRINT ; Z3LIB EXT PUTUD,GETUD,PRINT,PSTR,MOVEB ; SYSLIB EXT F$OPEN,F$MAKE,F$CLOSE,BDOS ; SYSLIB ; ; ;================[ Beginning of Program ]================ ; DB 'Z3ENV' DB 1 Z3ENV: DW 0 DB VERS ; START: LD HL,(Z3ENV) CALL Z3INIT ; ; Save away current DU CALL PUTUD ; ; Print signon message CALL QPRINT ; DB 'T4GEN v. ',(VERS/10) + '0','.' DB (VERS MOD 10) + '0',CR,LF,0 ; ; Check for no parameters (help) LD A,(FCB1 + 1) CP ' ' JP Z,HELP CP '/' JP Z,HELP ; ; Check 2nd parameter ; (If none, use 1st) LD A,(FCB2) OR A JP Z,NODU2 ; No DU: for Parm2 ; LD A,(FCB2 + 1) CP ' ' JP NZ,SETUP ; If not blank ; LD HL,FCB1 + 1 ;| Copy Parm1 name LD DE,FCB2 + 1 ;| LD B,11 ;| CALL MOVEB ;| Copy string ; JP SETUP ; NODU2: LD A,(FCB2 + 1) CP ' ' JP NZ,SETUP ; If not blank ; LD HL,FCB1 ;| Copy Parm1 LD DE,FCB2 ;| LD B,14 ;| Drive # + + User # CALL MOVEB ;| Copy string ; ;- ; Set-up File Control Blocks (Default mode) SETUP: LD HL,FCB1 LD DE,HX0FCB LD B,9 ; Drive # + CALL MOVEB ; Copy string ; LD HL,FCB1 LD DE,HX1FCB LD B,9 ; Drive # + CALL MOVEB ; Copy string ; LD A,(FCB2) ; A = Drive # LD (COMFCB),A LD HL,FCB2 + 1 LD DE,COMFCB + 3 LD B,6 ; File identifier CALL MOVEB ; Copy string ;- ;- ; Initialize Work Areas CALL GETUD ; Restore DU at entry (0.1) LD DE,FCB1 CALL Z3LOG ; Log into DU LD DE,HX0FCB CALL F$OPEN ; Open file ; CP 0FFH JP Z,NOTOPN ; If unable to open ; LD DE,HX1FCB CALL F$OPEN ; Open file ; CP 0FFH JP Z,NOTOPN ; If unable to open ; CALL GETUD ; Restore DU at entry (0.1) LD DE,FCB2 CALL Z3LOG ; Log into DU LD DE,COMFCB CALL F$MAKE ; Create file ; CP 0FFH JP Z,NSPACE ; If no directory space ; LD HL,HX0FCB ; HL =. CALL INITWA ; Set file FCB and buffer ; LD HL,HX1FCB ; HL =. CALL INITWA ; Set file FCB and buffer ; LD HL,COMFCB ; HL =. CALL INITWA ; Set file FCB and buffer ;- ;- ; Translate *.HX1 and load into *.COM LD DE,-100H ; Preset byte counter ; to ignore page 0 LD$COM: LD HL,HX1FCB ; HL =. CALL READHX ; Read HEX input ; JP C,REWIND ; On EOF (or Error) ; LD HL,COMFCB ; HL =. CALL LOADBF ; Insert in buffer ; INC DE ; Bytes loaded count JP LD$COM ;- REWIND: EX DE,HL LD (FILSIZ),HL ; Save byte count EX DE,HL CALL GETUD ; Restore DU at entry (0.1) LD DE,FCB1 CALL Z3LOG ; Log into DU CALL REWFIL ; Rewind file ; ;- ; Discard Page 0 conversion of *.HX1 LD B,0 HX1PG0: LD HL,HX1FCB CALL READHX ; Read HEX input ; DEC B JP NZ,HX1PG0 ;- ;- ; Build Relocation Map. BLDMAP: LD B,0 ; Clear Map byte LD C,10000000B ; Set MS-bit BLDMP1: LD HL,HX0FCB ; HL =.<*.HX0 work area Pivot> CALL READHX ; Read HEX input ; JP C,TERMAP ; Terminate Map on EOF ; LD D,A ; Save *.HX0 byte LD HL,HX1FCB ; HL =.<*.HX1 work area Pivot> CALL READHX ; Read HEX input ; JP C,TERMAP ; Terminate Map on EOF ; SUB D ; A = (*.HX1 byte)-(*.HX0 byte) JP Z,BLDMP2 ; If identical ; CP 1 JP NZ,PHASER ; Phase error ; LD A,B OR C ; Set bit in Map byte LD B,A BLDMP2: LD A,C RRCA ; Next bit LD C,A JP NC,BLDMP1 ; If Map byte not completed ; LD HL,COMFCB ; HL =. LD A,B CALL LOADBF ; Insert in buffer ; JP BLDMAP ; Build next Map byte ;- ;- ; Terminate Relocation Map TERMAP: LD HL,COMFCB ; HL =. LD A,C CP 10000000B ; Next bit to be set Map JP Z,TERMP1 ; Discard blank byte ; LD A,B CALL LOADBF ; Insert in buffer ; TERMP1: CALL BAKFILL ; Backfill record with nulls ;- ;- ; Insert Page 0 Header CALL GETUD ; Restore DU at entry (0.1) LD DE,FCB2 CALL Z3LOG ; Log into DU CALL REWFIL ; Rewind T4*.COM ; LD DE,LDROVL ; DE =. LD B,0 ; Clear counter PG0OVL: LD A,(DE) CALL LOADBF ; Insert in buffer ; INC DE ; Bump pointer DEC B ; Count it JP NZ,PG0OVL ; If more to go ;- CALL LOADBF ; Dummy entry to trigger ; record transfer to disk ; LD DE,COMFCB CALL F$CLOSE ; Close file ; JP MNEXIT ; Done ; ; ;================[ Error Handling and Exit ]================ ; ; ----------------- MTONER:: LD HL,MNERMSG ; Non-monotonic message (Global) JP DISPLA ; ; ----------------- PHASER: LD HL,PHERMSG ; Phase error message JP DISPLA ; ; ----------------- PHS2ER:: LD HL,IOERMSG ; I/O error on phase 2 msg (Global) JP DISPLA ; ; ----------------- NOTOPN: LD HL,INERMSG ; Cannot open input message JP DISPLA ; ; ----------------- WRITER:: LD HL,WERMSG ; Write error message JP DISPLA ; ; ----------------- NSPACE: LD HL,OTERMSG ; Cannot create output message DISPLA: CALL PSTR ; Display string ; MNEXIT: CALL GETUD ; Restore DU at entry ; JP BOOT ; Exit ; ; ;================[ Help ]================ ; ;- HELP: CALL PRINT ; DEFM 'Syntax is:',CR,LF DEFM ' T4GEN <[du:|dir:]fn1> [du:|dir:][]',CR,LF DEFM 'Where:',CR,LF DEFM ' fn1 = filename of input file pair:',CR,LF DEFM ' .HX0/.HX1',CR,LF DEFM ' fn2 = filename of output file (optional)',CR,LF DEFB 0 JP MNEXIT ;- ; ;================[ Error Messages ]================ ; ;- MNERMSG: DEFM 'HEX Files not Monotonic',0 PHERMSG: DEFM 'Phase error',0 INERMSG: DEFM 'Cannot open input files',0 OTERMSG: DEFM 'Cannot create output file',0 IOERMSG: DEFM 'Disk I/O error on phase 2',0 WERMSG: DEFM 'Write Error',0 ;- ; ;================[ File Work Areas ]================ ; ;- ; HX0 Work Area HX0FCB: DEFS 9 ; Drive # & DEFM 'HX0' ; DEFS 1 ; EXtent (Set by INITWA) DEFB 00H,00H,00H,00H,00H,00H,00H,00H DEFB 00H,00H,00H,00H,00H,00H,00H,00H DEFB 00H,00H,00H DEFS 1 ; Current Record (Set by INITWA) DEFS 3 ; *.HX0 Record Buffer DEFS 1 ; Counter (Set by INITWA) DEFS 2 ; Pointer DEFS 128 ; Record buffer ; READHEX scratchpad DEFS 2 ; Next load Addr. (Set by INITWA) DEFS 2 ; Req. load Addr. (from HEX input) DEFS 1 ; # inputs in Line (Set by INITWA) ;- ;- ; HX1 Work Area HX1FCB: DEFS 9 ; Drive # & DEFM 'HX1' ; DEFS 1 ; EXtent (Set by INITWA) DEFB 00H,00H,00H,00H,00H,00H,00H,00H DEFB 00H,00H,00H,00H,00H,00H,00H,00H DEFB 00H,00H,00H DEFS 1 ; Current Record (Set by INITWA) DEFS 3 ; *.HX1 Record Buffer DEFS 1 ; Counter (Set by INITWA) DEFS 2 ; Pointer DEFS 128 ; Record buffer ; READHEX scratchpad DEFS 2 ; Next load Addr. (Set by INITWA) DEFS 2 ; Req. load Addr. (from HEX input) DEFS 1 ; # inputs in Line (Set by INITWA) ;- ;- ; COM Work Area COMFCB: DEFS 1 ; Drive # DEFM 'T4' ; Prefix DEFS 6 ; File identifier DEFM 'COM' ; DEFS 1 ; EXtent (Set by INITWA) DEFB 00H,00H,00H,00H,00H,00H,00H,00H DEFB 00H,00H,00H,00H,00H,00H,00H,00H DEFB 00H,00H,00H DEFS 1 ; Current Record (Set by INITWA) DEFS 3 ; COM Record Buffer DEFS 1 ; Counter (Set by INITWA) DEFS 2 ; Pointer DEFS 128 ; Record buffer ; READHEX scratchpad DEFS 2 ; Next load Addr. (Set by INITWA) DEFS 2 ; Req. load Addr. (from HEX input) DEFS 1 ; # inputs in Line (Set by INITWA) ;- ; ;================[ Overlay Loader Code ]================ ; ; LDROVL: EQU $ FILSIZ: EQU $ + 1 ; Byte count buffer INCLUDE T4LDR.LIB ; Insert page 0 type-4 Header END START