;************************************************************************ ;* * ;* UNLOAD22: This is an enhancement of the old unload 2.1 * ;* It has the ability to output 8 byte,16 byte, 32 byte, or * ;* 64 byte Intel hex records. It also no-longer requires the * ;* input file to be .COM, it can be anything. Also fixed the * ;* EOF record output, the previous style of EOF record has been * ;* known to cause some equipment/software to "choke". * ;* * ;* --->Needs MAC and SEQIO.LIB to assemble<--- * ;* * ;************************************************************************ ;* * ;* Revision history: * ;* * ;*09/05/87 Major revision. Added run-time switch for record size, * ;* allowed file types other than .COM to be used, and added * ;* code to output a true EOF record instead of the "fake" * ;* MAC style previously output by the program. Also added * ;* COMMENTS, the program was poorly commented. * ;* By Mark D. Pickerill. * ;* * ;*05/20/81 Modified for 32 bytes/record instead of 16, for less * ;* overhead in the .HEX output file, by Dav Holle. * ;* * ;*11/07/80 Modified to default to 100H, increase size of buffers, * ;* add signon message. By Keith Petersen, W8SDZ * ;* * ;*Originally from CPMUG 29.23 * ;* * ;*To use, type: UNLOAD <.EXT> * ;* * ;*Where: is the source file, <.EXT> if not given defaults * ;* to .COM * ;* .HEX will be the output file * ;* is the optional start address in hex (default=100) * ;* is the optional record size, where /X is: * ;* * ;* /S Small, 08 bytes per record * ;* /M Medium, 16 bytes per record (default) * ;* /L Large, 32 bytes per record * ;* /E Extra, 64 bytes per record * ;* Note that this format is known to make PIP's [H] "choke" * ;* * ;************************************************************************ ; FCB2 EQU 006CH ; Location of second fcb FCB1EXT:EQU 0065H ; Location of ext field of first fcb ORG 100H ; Start of tpa MACLIB SEQIO ; Define macro library used LHLD 6 ; Get base of bdos DCX H ; Back off one byte SPHL ; Set stack there CALL SIGNON ; Jump around message w/msg addr on stack DB CR,LF,'UNLOAD ver 2.2',CR,LF,'$' DB '09/05/87' ; Revision date (doesn't print) SIGNON: POP D ; Get msg adr MVI C,@MSG ; Print it CALL @BDOS ; Do it MVI A,16 ; Default record size STA SIZE ; Store it LDA FCB1EXT ; Point to file ext field of fcb1 CPI ' ' ; Ext specified? CZ PUTCOM ; No ext, force default to .com LXI H,0100H ; Default unload adrs LXI D,FCB2+1 ; Look at first location of second fcb LDAX D ; Get option adrs CPI '/' ; Check first for no address, opt. rec size CZ SETSIZE ; Yes, change size CPI ' ' ; Any given? JZ INITFL ; No, default to 0100h LXI H,0 ; Zero 16 bit accumulator MVI B,0 ; Zero b (unused) ; ADRLUP: LDAX D ; Get char CPI '/' ; Change size switch? CZ SETSIZE ; Yes INX D ; Point to next SUI '0' ; Remove numeric bias JC INITFL ; CPI 10 ; Punctuation? JC ADDNIB ; No SUI 7 ; Yes, remove punctuation bias JC INITFL ; Not valid hex, actually was punctuation CPI 16 ; Higher than f? JNC INITFL ; Yes, invalid ; ADDNIB: DAD H ; Multiply 16 bit accumulator by 2 DAD H ; 4 DAD H ; 8 DAD H ; 16 MOV C,A ; Move current value DAD B ; Add in current value to 16 bit acc JMP ADRLUP ; And do until garbage is found ; SETSIZE:INX D ; Point to next LDAX D ; Get it CPI 'S' ; Small (08)? MVI B,08D ; In-case it is... JZ SETIT ; Yes CPI 'M' ; Medium (16)? MVI B,16D ; In-case it is... JZ SETIT ; Yes CPI 'L' ; Large (32)? MVI B,32D ; In-case it is... JZ SETIT ; Yes CPI 'E' ; Extra (64)? MVI B,64D ; In-case it is... JZ SETIT ; Yes MVI B,16D ; Garbage, retain default SETIT: MOV A,B ; Get desired setting STA SIZE ; Set mem location MVI A,' ' ; To force termination of option search routine RET ; Go home ; PUTCOM: MVI B,3 ; Three bytes in .com LXI H,FCB1EXT ; Point to fcb1 ext field LXI D,COM ; Point to the word 'com' PUTLP: LDAX D ; Get byte MOV M,A ; Put byte DCR B ; Count down INX H ; Increment destination INX D ; Increment source JNZ PUTLP ; Loop til done RET ; Go home ; COM: DB 'COM' ; Com files are default ; INITFL: PUSH H ; Save load address ; FILE INFILE,SOURCE,,1,COM,2048 ; Invoke macro FILE INFILE,SOURCE,,1,,2048 ; Invoke macro FILE OUTFILE,OUTPUT,,1,HEX,2048 ; Invoke macro POP H ; Restore load address ; ADRDON: SHLD LODADR ; Save unload address UNLOOP: GET SOURCE ; Get byte of source JZ GEOF ; Done, generate eof record PUSH PSW ; Save it MVI A,':' ; Get a colon PUT OUTPUT ; Write it to the output XRA A ; Zero acc STA CHEKS ; And store in checksum byte LDA SIZE ; Get record size CALL PUTBYTE ; Output the record lenth LDA LODADR+1 ; Get msb of load address CALL PUTBYTE ; Output it LDA LODADR ; Now the lsb CALL PUTBYTE ; Output it XRA A ; Record type 00 CALL PUTBYTE ; Dump it LDA SIZE ; Get record size MOV B,A ; And put in b POP PSW ; Recover current byte LINLUP: PUSH B ; Save line count CALL PUTBYTE ; Output current byte POP B ; Recover line count DCR B ; Decrement it JZ NEXTL ; If done, process end of line GET SOURCE ; If not, get next byte JMP LINLUP ; And loop until a whole line is done ; NEXTL: LDA CHEKS ; Get checksum CALL PUTBYTE ; Output it MVI A,CR ; A carriage return PUT OUTPUT ; Dump it MVI A,LF ; A line feed PUT OUTPUT ; Dump it LHLD LODADR ; Get load address LDA SIZE ; Get record size MOV E,A ; Into e MVI D,00 ; Zero msb of de DAD D ; Add in line length for next record JMP ADRDON ; Do til done with file ; PUTBYTE:MOV C,A ; Save byte in c LDA CHEKS ; Get current checksum SUB C ; Subtract current byte (auto 2's comp.) STA CHEKS ; Put back MOV A,C ; Restore current byte RRC ; Get msn RRC ; Takes RRC ; Four RRC ; Rotates CALL PUTNIB ; Stuff nybble MOV A,C ; Get lsn back, and drop into putnib ; PUTNIB: ANI 0FH ; Strip upper nybble ADI '0' ; Add numeric bias CPI '9'+1 ; 9 or less? JC PUTNB1 ; Yes ADI 7 ; No, add in alpha bias PUTNB1: PUSH B ; Save b PUT OUTPUT ; Write the ascii byte POP B ; Restore b RET ; Go home ; GEOF: MVI A,':' ; A colon PUT OUTPUT ; Output it MVI B,3 ; 5 bytes GEOF1: XRA A ; Generate a zero PUSH B ; Save count CALL PUTBYTE ; Output the zero POP B ; Recover count DCR B ; Decrement JNZ GEOF1 ; Do till done MVI A,01H ; Record type 01, eof CALL PUTBYTE ; Output it MVI A,0FFH ; Checksum for eof record CALL PUTBYTE ; Output it MVI A,CR ; Output the cr PUT OUTPUT ; Do it MVI A,LF ; Output the lf PUT OUTPUT ; Do that too FINIS OUTPUT ; Close output file LXI D,DMSG ; Tell world we're done MVI C,@MSG ; Function # CALL @BDOS ; Do it JMP 0 ; Good bye ; DMSG: DB 'Done',CR,LF,'$' ; Message ; SIZE: DS 1 ; Record size storage LODADR: DS 2 ; Load address storage CHEKS: DS 1 ; Checksum storage BUFFERS EQU $ ; Input/output buffers go here ; END ;