; ;-------------------------------------------------------------------------; TITLE MAKELUX.Z80 - Relocator/Merger for LUX.COM | ; written by Robert W. Kramer III from MAKELUX7.COM | ;-------------------------------------------------------------------------; ; ; Update History ; ; 05/17/88 v8.0 - Decompiled MAKELUX7.COM and commented source ; - Fixed to preserve IX register before making any ; BDOS calls. (This should allow more Sysops to ; compile their own versions). I've never been ; able to use MAKELUX on my QX-10 for this reason, ; since the QX-10 uses and does not preserve the ; IX and IY registers. ;- ;------------------ ; Define Constants ;------------------ ; LF EQU 10 ; Line Feed CR EQU 13 ; Carriage Return BDOS EQU 0005H ; BDOS entry TBUF EQU 0080H ; Default DMA address WRCON EQU 2 ; Write console OPEN EQU 15 ; Open file CLOSE EQU 16 ; Close file SEARCHF EQU 17 ; Search first DELETE EQU 19 ; Delete file READ EQU 20 ; Read file WRITE EQU 21 ; Write file MAKE EQU 22 ; Make file SETDMA EQU 26 ; Set DMA RLEN EQU 128 ; CP/M physical record length ; ; Save old stack, initialize new one for this program ; START: LD (STACK),SP ; Save current stack pointer LD SP,STACK ; Initialize new one ; ; Make sure LUX.CO0 and LUX.CO1 are on the current drive/user ; LD DE,TBUF ; Set to defaut DMA LD C,SETDMA CALL SPBDOS ; For directory operations LD DE,FCB0 ; LUX.CO0 LD C,SEARCHF ; Search first CALL SPBDOS INC A ; Found? JP Z,NOCO0 ; No LD DE,FCB1 ; LUX.CO1 LD C,SEARCHF ; Search first CALL SPBDOS INC A ; Found? JP Z,NOCO1 ; No LD DE,FCB0 ; LUX.CO0 LD C,OPEN ; Open file CALL SPBDOS INC A ; Open ok? JP Z,OPNERR ; No ; ; Read LUX.CO0 into memory ; LD HL,CO0BEG ; Start reading into memory at CO0BEG LD DE,RLEN ; Plus 128 RDCO0: ADD HL,DE ; Increment for next 128 bytes (1 record) EX DE,HL ; New destination in DE LD C,SETDMA ; Set DMA to it CALL SPBDOS PUSH DE ; Save current read position LD DE,FCB0 ; LUX.CO0 LD C,READ ; Read record CALL SPBDOS POP DE ; Restore read position EX DE,HL ; DE=128, HL=current read position OR A ; Read ok? JR Z,RDCO0 ; Yes, keep reading until EOF LD (CO0END),HL ; Save end address of LUX.CO0 ; ; LUX.CO0 is in memory, open LUX.CO1 and merge the two together ; XOR A LD (FCB1+12),A ; First extent LD (FCB1+32),A ; First record LD DE,FCB1 ; LUX.CO1 LD C,OPEN ; Open file CALL SPBDOS INC A ; Open ok? JP Z,OPNER1 ; No LD HL,CO0BEG+RLEN ; Start 1 record into CO0 LD IX,MRGBUF ; Start of merge buffer R01ED: LD (IX+0),0 ; Null to start LD B,8 ; Count down 8 bits R01F3: CALL GETCHR ; Get a character from LUX.CO1 JR C,R0207 ; Carry set=end of file CP (HL) ; Same as current byte from LUX.CO0? JR Z,R01FC ; Yes SCF ; Else set carry R01FC: RL (IX+0) ; Rotate current byte in merge buffer left INC HL ; Next C0O byte DJNZ R01F3 ; Count down 8 bits INC IX ; Then next merge buffer byte JR R01ED ; Zero it and start over ; ; Now get size of result and combine with LUX.COM ; R0207: LD HL,(CO0END) ; End of LUX.CO0 read buffer LD DE,CO0BEG+RLEN ; End of this program XOR A ; Clear carry for subtract SBC HL,DE ; Get buffer size LD A,L ; LSB OR A ; Already an even page? JR Z,R0217 ; Yes LD L,0 ; Else make it even INC H ; And account for byte loss R0217: LD (CO0SIZ),HL ; Save size LD DE,T0380 ADD HL,DE LD A,L OR A ; On an even page? JR Z,R0229 ; Yes CP RLEN ; Is it an even record? JR Z,R0229 ; Yes LD L,0 ; Set for even page INC H ; But don't leave anything out R0229: LD B,7 R022B: SRL H RR L DJNZ R022B LD A,L LD (RCDCNT),A LD DE,FCB2 ; LUX.COM LD C,DELETE ; Delete any existing with that name CALL SPBDOS LD DE,FCB2 ; LUX.COM LD C,MAKE ; Make LUX.COM CALL SPBDOS INC A ; Make ok? JP Z,DIRFUL ; No LD HL,T0380 LD DE,RLEN LD A,(RCDCNT) ; Get the record count LD B,A ; Into B for count down WRTLUX: ADD HL,DE ; Add 128 bytes (1 record) to current position EX DE,HL ; DE=current buffer position, HL=128 LD C,SETDMA ; Set new DMA address CALL SPBDOS PUSH DE ; Save it LD DE,FCB2 ; LUX.COM LD C,WRITE ; Write a record CALL SPBDOS POP DE ; Get back buffer position EX DE,HL ; HL=128, DE=current buffer position OR A ; Write ok? JP NZ,DSKFUL ; No DJNZ WRTLUX ; One less record to write LD DE,FCB2 ; LUX.COM LD C,CLOSE ; Close file CALL SPBDOS INC A ; Close ok? JP Z,DSKFUL ; No EXIT: LD SP,(STACK) ; Restore stack RET ; Exit ; GETCHR: PUSH DE PUSH HL NXTBYT: LD A,(BYTCNT) ; Get bytes read INC A ; One more LD (BYTCNT),A ; Save it CP 81H ; Read all of this record yet? JR Z,NXTRCD ; Yes, go get another one LD HL,(OUTPTR) ; Get current position pointer LD A,(HL) ; And character in A INC HL ; Increment for next time LD (OUTPTR),HL ; And save pointer POP HL ; Restore registers POP DE OR A ; Clear carry RET ; NXTRCD: XOR A LD (BYTCNT),A ; Reset current byte count LD DE,TBUF ; Position to start of default CP/M DMA LD (OUTPTR),DE ; Store new position LD C,SETDMA ; Set DMA CALL SPBDOS LD DE,FCB1 ; LUX.CO1 LD C,READ ; Read a record CALL SPBDOS OR A ; Read ok? JR Z,NXTBYT ; Yes, continue POP HL ; Else restore registers POP DE SCF ; And set carry (We're done) RET ; ; Inline print routine, terminates with null ; ILPRT: EX (SP),HL ; Get start of string ILPLP: LD A,(HL) ; Get the character OR A ; Terminating null? JR Z,ILPDN ; Yes, all done CALL TYPE ; Else output to console INC HL ; Increment to next character JR ILPLP ; And loop ILPDN: EX (SP),HL ; Restore return address RET ; ; Output to console, strips high bits, saves all registers. ; TYPE: PUSH AF PUSH BC AND 7FH ; Strip parity LD E,A ; Character in E for LD C,WRCON ; BDOS Write console function CALL SPBDOS POP BC POP AF RET ; ; Make BDOS call, save all but AF, IY and alternate registers ; (Some BIOS' like the QX-10's 2.25B do not preserve the IY and IX registers) ; SPBDOS: PUSH BC PUSH DE PUSH HL PUSH IX CALL BDOS POP IX POP HL POP DE POP BC RET ; ; Error messages ; NOCO0: CALL ILPRT DB 'LUX.CO0 not found - Aborting' DB CR,LF DB 0 JP EXIT ; NOCO1: CALL ILPRT DB 'LUX.CO1 not found - Aborting' DB CR,LF DB 0 JP EXIT ; OPNERR: CALL ILPRT DB 'LUX.CO0 open error - Aborting' DB CR,LF DB 0 JP EXIT ; OPNER1: CALL ILPRT DB 'LUX.CO1 open error - Aborting' DB CR,LF DB 0 JP EXIT ; DIRFUL: CALL ILPRT DB 'No directory space - Aborting' DB CR,LF DB 0 JP EXIT ; DSKFUL: CALL ILPRT DB 'Disk full - aborting' DB CR,LF DB 0 LD DE,FCB2 ; LUX.COM LD C,CLOSE ; Close file CALL SPBDOS LD DE,FCB2 ; LUX.COM LD C,DELETE ; Delete file CALL SPBDOS JP EXIT ; All done ; ;-------------------------------------------------------------------------- ; Data Storage ; DS 80 ; 40 level stack STACK EQU $-2 OUTPTR: DW 0 ; Current position in output buffer BYTCNT: DB RLEN ; Byte counter RCDCNT: DB 0 ; Record count CO0END: DW 0 ; Ending address of LUX.CO0 ; ; File Control Blocks ; FCB0: DB 0,'LUX CO0',0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0 FCB1: DB 0,'LUX CO1',0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0 FCB2: DB 0,'LUX COM',0,0,0 DB 0,0,0,0,0,0,0 T0380: DS RLEN T0400: DB 0CDH,14H,1,21H,80H,4,0EDH,5BH,7EH,1,0EDH,4BH,7CH,1 DB 0EDH,0B0H,2AH,7EH,1,0E9H,3AH,6,0,0FEH,6,20H,2AH,2AH DB 1,0,6,4,23H,5EH,23H,56H,23H,0E5H,0AFH,0EDH,52H,0E1H DB 30H,19H,10H,0F2H,2AH,1,0,11H,0FDH,0DH,0AFH,0EDH,52H DB 0EDH,5BH,6,0,7BH,0BDH,20H,6,7AH,0BCH,20H,2,18H,6,2AH DB 6,0,25H,18H,3,2AH,6,0,2EH,0,0EDH,5BH,7CH,1,0AFH,0EDH DB 52H,22H,7EH,1,4CH,0EDH,5BH,7CH,1,0DDH,21H,80H,1,21H DB 80H,4,6,8,0DDH,0CBH,0,16H,30H,3,7EH,81H,77H,23H,1BH DB 7BH,0B2H,0C8H,10H,0F0H,0DDH,23H,18H,0EAH CO0SIZ: DS 4 MRGBUF: DS 640 CO0BEG: DS RLEN ; Beginning of LUX.CO0 read in here END