home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
utils
/
filutl
/
unload22.lbr
/
UNLOAD22.AZM
/
UNLOAD22.ASM
Wrap
Assembly Source File
|
1987-09-10
|
8KB
|
229 lines
;************************************************************************
;* *
;* 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 <FILENAME><.EXT> <ADDR></X> *
;* *
;*Where: <FILENAME> is the source file, <.EXT> if not given defaults *
;* to .COM *
;* <FILENAME>.HEX will be the output file *
;* <ADDR> is the optional start address in hex (default=100) *
;* </X> 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 ;