home *** CD-ROM | disk | FTP | other *** search
-
-
- ; ------------------------------------------------------------
- ; LOHD.ASM is a revision of Digital Research's LOAD.COM, which
- ; is evidently a PL/M program. The revision has reduced its
- ; volume by 2/3, but its execution is disk-bound to the point
- ; that the speed difference is not outwardly apparent. Other
- ; changes include:
- ; 1. An origin below 0100H - CP/M's transient origin - no
- ; longer produces an error condition if it is 0000H. Thus a
- ; file assembled to origin 0000 can be passed from .HEX to
- ; .COM, such as if it were the code for a self-relocating
- ; program such as DDT.
- ; 2. The .COM buffer is zeroed before each use, so that
- ; gaps in the code sequence, the result of a <ds> or of an
- ; <org>, are filled with zeroes rather than being left to
- ; gather whatever trash is in the buffer as they are found.
- ; The .COM code is passed through a one-page window, so that
- ; any origin redefined below that range will draw an error
- ; message, as in LOAD.COM.
- ;
- ; [Harold V. McIntosh, 22 September 1983]
- ; ------------------------------------------------------------
-
-
- BDOS equ 0005H
- TFCB equ 005CH
- TSIZ equ 0080H
- TORG equ 0100H
- CSIZ equ 0100H ;size of .COM buffer
- HSIZ equ 0400H ;size of hexfile buffer
-
- LF equ 0AH
- CR equ 0DH
-
- ; -------------
- org 0100H
- ; -------------
-
- begn: lxi h,0000
- dad sp
- shld stak ;save sp
- lxi sp,stak ;stackend
- lxi h,CSIZ
- shld cinx ;.COM index
- call cbuz ;clear CBUF
- lxi h,HSIZ
- shld hinx ;hexfile index
- lda TFCB+1
- cpi ' '
- jnz nnul
- lxi d,logo
- call mssg
- lxi d,tuto
- call mssg
- jmp gbye ;normal exit
-
- nnul: mvi c,021H ;count
- lxi d,TFCB ;source
- lxi h,HFCB ;.HEX FCB = destination
- call miuc
-
- mvi c,4 ;count
- lxi d,X01F7 ;'hex' = source
- lxi h,HFCB+9;.HEX ext = destination
- call miuc
-
- lxi d,HFCB ;.HEX FCB
- mvi c,15 ;(0F) open file
- call BDOS
- cpi 0FFH
- lxi d,X01FB ;'can''t open source'
- jz tema ;type err mess w/addr
-
- mvi c,3 ;count
- lxi d,X020E ;'COM' = source
- lxi h,TFCB+9;destination
- call miuc
-
- lxi d,TFCB
- mvi c,19 ;(13) delete file
- call BDOS
-
- lxi d,TFCB
- mvi c,22 ;(16) create file
- call BDOS
-
- lxi d,TFCB
- mvi c,15 ;(0F) open file
- call BDOS
- cpi 0FFH
- lxi d,X0211 ;'no more directory'
- jz tema ;type err mess w/addr
-
- call hefi ;process the .HEX file
-
- lxi d,TFCB
- mvi c,16 ;(10) close file
- call BDOS
- cpi 0FFH
- lxi d,X0229 ;'can''t close file'
- jz tema ;type err mess w/addr
-
- fini: call crlf ;CR,LF
- gbye: lhld stak ;save sp
- sphl
- ret
-
- ; Type CR, LF.
-
- crlf: mvi a,CR
- call cona ;console from A
- mvi a,LF
- jmp cona ;console from A
-
- word: mov a,h
- call byte ;type A as two nibbles
- mov a,l
- byte: push psw
- rar
- rar
- rar
- rar
- call nibl ;type A as hex
- pop psw
- nibl: ani 0FH
- adi 90H
- daa
- aci 40H
- daa
- cona: push h
- push d
- mov e,a
- mvi c,2 ;(02) write console
- call BDOS
- pop d
- pop h
- ret
-
- ; Type message at (DE).
-
- mssg: call crlf ;CR,LF
- mess: mvi c,9 ;(09) type buffer
- jmp BDOS
-
- ; Type error message with address.
-
- tema: push d
- lxi d,X0129 ;'error'
- call mssg ;type CRLF, mssg
- pop d
- call mess ;type mess at (DE)
- lxi d,X0131 ;'load address'
- call mess ;type mess at (DE)
- lhld cinx ;.COM index
- call word ;type HL in four nibbles
- jmp gbye ;normal exit
-
- ; Block move.
-
- miuc: ldax d
- mov m,a
- inx h
- inx d
- dcr c
- jnz miuc
- ret
-
- ; Get next hexfile element.
-
- nxhx: lhld hinx ;hexfile index
- inx h
- lxi d,HSIZ
- mov a,l
- sub e
- mov a,h
- sbb d
- jc nxhv ;byte available
- lxi h,0000
- nxhy: shld hinx ;hexfile index
- lxi d,HSIZ
- mov a,l
- sub e
- mov a,h
- sbb d
- jnc nxhu ;reset hexfile, read 1st element
- lxi d,HBUF
- dad d
- xchg
- mvi c,26 ;(1A) set DMA address
- call BDOS
- lxi d,HFCB ;.HEX FCB
- mvi c,20 ;(14) read one record
- call BDOS
- cpi 000H
- jz nxhz ;add record to hexfile
- cpi 001H
- lxi d,X0141 ;'disk read'
- jnz tema ;type err mess w/addr
- lhld hinx ;hexfile index
- lxi d,HBUF ;hexfile buffer
- dad d
- mvi m,01AH ;^Z
- lxi h,HSIZ-1
- shld hinx ;hexfile index
- nxhz: lhld hinx ;hexfile index
- lxi d,TSIZ
- dad d
- jmp nxhy ;no more refills
-
- nxhu: lxi h,0000
- nxhv: shld hinx ;hexfile index
- lxi d,HBUF ;hexfile buffer
- dad d
- mov a,m
- ret
-
- ; Start reading the .HEX file, and keep going.
-
- hefi: lxi h,0FFFFH
- shld mina ;minimum address
- lxi h,0000
- shld maxa ;maximum address
- shld byco ;byte counter
- xra a
- sta reco ;record counter
- lxi h,TORG
- shld ladr ;load address
- shld rbrk ;record breakpoint
- shld cinx ;.COM index
- lxi h,HBUF ;hexfile buffer
- mvi m,01AH ;^Z
- inhx: call nxhx ;next hexfile element
- sui ':'
- jnz inhx ;advance to ":"
- mov d,a ;checksum in D
- call hexb ;assemble byte, augment checksum
- mov e,a ;bytecount in E
- cpi 00H
- jnz nlin ;this isn't "end" line
- lhld cinx ;.COM index
- xchg
- elin: lhld rbrk ;record breakpoint
- mov a,l ;cmp(HL,DE)
- sub e
- mov a,h
- sbb d
- jnc stat ;type statistics
- xra a
- call comb ;insert byte in .COM buffer
- jmp elin ;fill out buffer with zeroes
-
- nlin: lhld byco ;byte counter
- push d
- mvi d,00
- dad d
- pop d
- shld byco ;byte counter
- call hexb ;assemble byte, augment checksum
- push psw
- call hexb ;assemble byte, augment checksum
- pop h
- mov l,a
- ora h
- jnz horg ;high (non-zero) origin
- shld rbrk ;record breakpoint
- horg: shld ladr ;load address
- shld cinx ;.COM index
- lhld mina ;minimum address
- inx h
- mov a,h
- ora l
- jnz nmin
- lhld cinx ;.COM index
- shld mina ;minimum address
- nmin: call hexb ;assemble byte, augment checksum
- ihli: call hexb ;assemble byte, augment checksum
- call comb ;insert byte in .COM buffer
- dcr e
- jnz ihli
- push d
- lhld maxa ;maximum address
- xchg
- lhld cinx ;.COM index
- mov a,e
- sub l
- mov a,d
- sbb h
- jnc nmax
- dcx h
- shld maxa ;maximum address
- nmax: pop d
- call hexb ;assemble byte, augment checksum
- mov a,d
- cpi 00H
- jz inhx ;on to next line
- lxi d,X01A8 ;'check sum error'
- call mssg ;type CRLF, mssg
- jmp erst ;type error statistics
-
- ; Type summary of statistics.
-
- stat: lxi d,X01B9 ;'first address'
- call mssg ;type CRLF, mssg
- lhld mina ;minimum address
- call word ;type HL in four nibbles
- lxi d,X01C8 ;'last address'
- call mssg ;type CRLF, mssg
- lhld maxa ;maximum address
- call word ;type HL in four nibbles
- lxi d,X01D7 ;'bytes read'
- call mssg ;type CRLF, mssg
- lhld byco ;byte counter
- call word ;type HL in four nibbles
- lxi d,X01E6 ;'records written'
- call mssg ;type CRLF, mssg
- lda reco ;record counter
- call byte ;type A as two nibbles
- jmp crlf ;CR,LF
-
- ; Insert byte in .COM buffer.
-
- comb: push d
- push psw
- lhld rbrk ;record breakpoint
- xchg
- lhld cinx ;.COM index
- mov a,l ;cmp(HL,DE)
- sub e
- mov a,h
- sbb d
- lxi d,X014B ;'inverted load address'
- jc tema ;type err mess w/addr
- lxi d,CSIZ ;nc means 'rbrk .le. index'
- lhld rbrk ;record breakpoint
- dad d
- xchg
- lhld cinx ;.COM index
- mov a,l ;cmp(HL,DE)
- sub e
- mov a,h
- sbb d
- cnc budi ;send CBUF to disk
- lxi d,CBUF ;.COM buffer
- mvi h,00
- dad d
- pop psw
- mov m,a
- lhld cinx ;.COM index
- inx h
- shld cinx ;.COM index
- pop d
- ret
-
- ; Send CBUF to disk.
-
- budi: push h
- call budj
- pop h
- ret
-
- budj: mvi c,26 ;(1A) set DMA address
- lxi d,CBUF
- call BDOS
-
- call budk ;record to disk
-
- lxi d,CBUF+TSIZ
- mvi c,26 ;(1A) set DMA address
- call BDOS
-
- call budk ;record to disk
-
- ; Fill CBUF with zeroes.
-
- cbuz: xra a
- mvi b,2 ;CBUF holds 2 records
- lxi h,CBUF
- cbuy: mvi c,TSIZ
- cbux: mov m,a
- inx h
- dcr c
- jnz cbux
- dcr b
- jnz cbuy
- ret
-
- budk: lhld rbrk ;record breakpoint
- lxi d,TSIZ
- dad d
- shld rbrk ;record breakpoint
- lxi h,reco ;record counter
- inr m
-
- lxi d,TFCB
- mvi c,21 ;(15) write one record
- call BDOS
- cpi 00H
- lxi d,X0161 ;'disk write'
- jnz tema ;type err mess w/addr
- ret
-
- ; Type error statistics.
-
- erst: lxi d,X016C ;'load address'
- call mssg ;type CRLF, mssg
- lhld ladr ;load address
- call word ;type HL in four nibbles
- lxi d,X017B ;'error address'
- call mssg ;type CRLF, mssg
- lhld cinx ;.COM index
- call word ;type HL in four nibbles
- lxi d,X018A ;'bytes read'
- call mssg ;type CRLF, mssg
- call tyla ;type load address:
- ersu: lhld cinx ;.COM index
- xchg
- lhld ladr ;load address
- mov a,l
- sub e
- mov a,h
- sbb d
- jnc fini ;CR,LF,exit
- lhld ladr ;load address
- mov a,l
- ani 00FH
- cpi 000H
- jnz ersv
- call tyla ;type load address:
- ersv: lhld rbrk ;record breakpoint
- xchg
- lhld ladr ;load address
- mov a,l
- sub e
- mov l,a
- mov a,h
- sbb d
- mov h,a
- lxi b,CBUF ;.COM buffer
- dad b
- mov a,m
- call byte ;type A as two nibbles
- lhld ladr ;load address
- inx h
- shld ladr ;load address
- mvi a,' '
- call cona ;console from A
- jmp ersu
-
- ; Type <load address>:.
-
- tyla: call crlf ;CR,LF
- lhld ladr ;load address
- call word ;type HL in four nibbles
- mvi a,':'
- call cona ;console from A
- mvi a,' '
- jmp cona ;console from A
-
- ; Make up general hexdigit.
-
- hexn: call nxhx ;next hexfile element
- sui '0'
- cpi 10 ;ten
- rc
- sui 7 ;seven
- cpi 10 ;ten
- jc nhex
- cpi 16 ;sixteen
- rc
- nhex: lxi d,X0196 ;'invalid hex digit'
- call mssg ;type CRLF, mssg
- jmp erst ;type error statistics
-
- ; Join hexinhx nibbles to form byte.
-
- hexb: push b
- push h
- push d
- call hexn ;general hexdigit
- add a
- add a
- add a
- add a
- push psw
- call hexn ;general hexdigit
- pop b
- ora b
- mov b,a
- pop d
- add d
- mov d,a
- mov a,b
- pop h
- pop b
- ret
-
- logo: db ' LOHD/ICUAP',CR,LF
- db 'Universidad Autonoma de Puebla',CR,LF
- db ' September 22, 1983',CR,LF,'$'
-
- tuto: db 'LOHD.ASM is a variant of Digital Research''s LOAD.COM',CR,LF
- db 'which was reduced to 2/3 its original volume by using',CR,LF
- db 'machine language rather than PL/M. It accepts 0000H as',CR,LF
- db 'an origin lower than 0100H, facilitating the generation',CR,LF
- db 'of the master file for a self-relocating program. Gaps',CR,LF
- db 'caused by <ds> or <org> are filled with zeroes rather',CR,LF
- db 'than trash from the memory.',CR,LF
- db CR,LF
- db ' LOHD [X:]FILE[.QQQ]',CR,LF
- db CR,LF
- db 'will read [X:]FILE.HEX to produce [X:]FILE.COM.',CR,LF
- db '$'
- X0129: db 'error: $'
- X0131: db ', load address $'
- X0141: db 'Disk read$'
- X014B: db 'Load address cannot be accomodated'
- X0161: db 'Disk write$'
- X016C: db 'Load address $'
- X017B: db 'Error address $'
- X018A: db 'Bytes read:$'
- X0196: db 'Invalid hex digit$'
- X01A8: db 'Check sum error $'
- X01B9: db 'First address $'
- X01C8: db 'Last address $'
- X01D7: db 'Bytes read $'
- X01E6: db 'Records written $'
- X01F7: db 'HEX',00
- X01FB: db 'Can''t open source$'
- X020E: db 'COM'
- X0211: db 'Disk or Directory full$'
- X0229: db 'Cannot close file$'
-
- HFCB: ds 21H ;.HEX FCB
- HBUF: ds HSIZ+1 ;hexfile buffer (400H)
- hinx: ds 2 ;hexfile index
- cinx: ds 2 ;.COM index
- ladr: ds 2 ;load address
- mina: ds 2 ;minimum address
- maxa: ds 2 ;maximum address
- byco: ds 2 ;byte counter
- CBUF: ds 100H ;.COM buffer
- reco: ds 1 ;record counter
- rbrk: ds 2 ;record breakpoint
- ds 20H
- stak: ds 2 ;stackend
-
- end
-