home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
JSAGE
/
ZSUS
/
PROGPACK
/
HLOAD.LBR
/
HLOAD.AQM
/
HLOAD.ASM
Wrap
Assembly Source File
|
2000-06-30
|
7KB
|
333 lines
; HEXLOAD - Load a Hex file anywhere in memory
;
TITLE 'HEXLOAD - Load a hex file, (1-12/17/82)'
PAGE 60
;
; This program will load a hex file at its org address,
; wherever this is in memory, as long as it does not overlay
; HLOAD itself. Usage is:
;
; HLOAD file-name
;
; If no file type is given, HEX is assumed. If the file is
; not found, the file (with the HEX type) is looked for on the
; A drive. After the file is loaded, control is returned to
; CP/M without a warm-start.
;
; HLOAD differs from the LOAD command of CP/M in that it does
; not create a .COM file, and it does not expect the .HEX file
; to be ORGed at 100H. It is useful for loading memory
; outside the normal CP/M boundaries. For example, I use it
; to load an extended CBIOS, by including the command
;
; HLOAD CBIOSOVR
;
; as my auto-start-up command.
;
;
; This program requires MAC and MACRO.LIB to assemble.
;
;
; Author:
; Don McClimans
; Inti Electronics Corporation
; 41 Washburn Pk.
; Rochester, NY 14620
; 716-271-6280
;
; Send all comments, bugs, etc. to the author at the above
; address.
;
; This program is in the public domain, and may be freely
; copied or used for any purpose.
;
;
; Revision List (reverse order):
; 1 12/17/82 Original design by DPM
;
; The standard Intel Hex format consists of lines like this:
;
; :nnaaaa00xxxxxxxx...xxkk
;
; where nn is the number of data bytes on the line, aaaa is
; the address to load at, xx are series of data bytes, and kk
; is a checksum. The checksum (kk) is formed by subtracting
; each byte of the line (including nn and each half of the
; address aaaa), in 8-bit arithmetic, from zero (thus the sum
; including kk should be zero). The final line of a file
; should contain a byte count of zero - the address field in
; this line gives the starting address, which is ignored by
; this program.
;
;
; Load Macro file
;
MACLIB MACRO ;DR Standard MACRO library
;
;
; Start of Program
;
ORG 100H
START:
LXI H,0 ;Get system stack pointer
DAD SP
LXI SP,STACK ;Set to use local stack
PUSH H ;Preserve system stack pointer
;
; Try to open the file
;
DISKIO OPEN,FCB ;Open file name as given
CPI 0FFH ;Was open good
JNZ FILEOPEN ;Yes - go process
;No - try same name with HEX
MOVE HEXTYPE,FCBTYPE,3 ;file type
DISKIO OPEN,FCB ;Try to open it again
CPI 0FFH ;Was open good?
JNZ FILEOPEN ;Yes - go process
;No - try same name, with HEX
MVI A,1 ; on the A drive
STA FCBDRIVE
DISKIO OPEN,FCB ;Try to open it again
CPI 0FFH ;Was open good?
JNZ FILEOPEN ;Yes - go process
;
PRINT 'File Not Found' ;Give errror message
PRINT
JMP RETCPM
;
; Entry here when file is open
;
FILEOPEN:
MVI A,0 ;Initialize variables
STA LINENUM
STA LINENUM+1
LXI H,BUFR+128
SHLD BUFPTR
;
; Entry here to start reading a new line
; Skip leading CR, LF, and blanks
; Quit on EOF (Ctrl-Z)
;
NEWLINE:
XRA A ;Zero the checksum
STA CHECKSUM
LXI H,LINENUM
INR M ;Increment line number
JNC SKIPTOCOLON
INX H
INR M
SKIPTOCOLON:
CALL READBYTE
CPI CR
JZ SKIPTOCOLON
CPI LF
JZ NEWLINE
CPI ' '
JZ SKIPTOCOLON
CPI EOFCH ;Is it ctrl-Z?
JZ CLOSEFILE ;Yes - quit
CPI STARTCH ;Is it a colon?
JZ GETLENGTH ;Yes - go process
BADNUM:
PRINT 'HLOAD: Error in line '
DECOUT LINENUM
PRINT
JMP CLOSEFILE
;
; Entry here after colon read - get the number of data bytes
;
GETLENGTH:
CALL READBYTE
STA NUMBUFF
CALL READBYTE
STA NUMBUFF+1
XRA A ;zero the third byte
STA NUMBUFF+2
HEXIN NUMBUFF
JC BADNUM ;Quit if errror
CALL ADDTOCHECK
STA NUMBYTES
ANA A ;Was number of bytes zero?
JZ CLOSEFILE ;Yes - we are done
;
; Length has been read - get the address to load at.
;
CALL READBYTE
STA NUMBUFF
CALL READBYTE
STA NUMBUFF+1
CALL READBYTE
STA NUMBUFF+2
CALL READBYTE
STA NUMBUFF+3
XRA A ;zero the fifth byte
STA NUMBUFF+4
HEXIN NUMBUFF
JC BADNUM ;Quit if errror
SHLD LOADADR
CALL ADDTOCHECK
MOV A,H
CALL ADDTOCHECK
;
; Address has ben read. Read the next two zero's, and throw
; away.
;
CALL READBYTE
CALL READBYTE
;
; Read all the data bytes and store them.
;
; Entry here to read the next byte and store it in the correct
; memory location. The NUMBYTES counter is decremented till
; it reaches zero
;
NEXTBYTE:
CALL READBYTE
STA NUMBUFF
CALL READBYTE
STA NUMBUFF+1
XRA A ;zero the third byte
STA NUMBUFF+2
HEXIN NUMBUFF
JC BADNUM ;Quit if errror
PUSH PSW ;Preserve registers
LHLD LOADADR ;Get load address
MOV A,H ;And check that it is not
ANA A ;in HLOAD memory image
JZ LOADOK ;High byte 00, so below HLOAD
LXI D,HLOADEND ;Subtract last address of HLOAD
DAD D
JC LOADOK
;
PRINT 'HLOAD: Load address overlays HLOAD in line '
DECOUT LINENUM
PRINT
POP PSW
JMP CLOSEFILE
;
LOADOK:
POP PSW ;Restore byte
LHLD LOADADR
MOV M,A ;Store into memory
INX H
SHLD LOADADR
CALL ADDTOCHECK
LXI H,NUMBYTES ;Decrement Counter
DCR M
JNZ NEXTBYTE ;Loop till Zero
;
; Entry here when all bytes read
; Get the checksum and add it in - then check for zero
; checksum
;
CALL READBYTE
STA NUMBUFF
CALL READBYTE
STA NUMBUFF+1
XRA A ;Zero the third byte
STA NUMBUFF+2
HEXIN NUMBUFF
JC BADNUM
CALL ADDTOCHECK
LDA CHECKSUM
ANA A
JZ NEWLINE
;
; Entry here with checksum error
;
PRINT 'HLOAD: Checksum error in line '
DECOUT LINENUM
PRINT ;Fall into CLOSEFILE
;
; Entry here to close the file and return to CP/M
;
CLOSEFILE:
DISKIO CLOSE,FCB
;
; Entry here to return to CPM
;
RETCPM:
POP H ;Get system stack
SPHL
RET
;
;
; SUBROUTINES:
;
; READBYTE: Read a byte from the file. Return Ctrl-Z for all
; EOF's. Byte returned in A register - Uses all regs
;
READBYTE:
LHLD BUFPTR ;Get buffer pointer
MOV A,H ;See if at 100H (past end)
DCR A
JNZ NOREAD ;No - so get next byte
; ;Yes - so read a sector
DISKIO READ,FCB
ORA A ;Read errors?
JZ READOK ;No - go process sector
DCR A ;Was A 1 meaning EOF?
JNZ RDERR ;No - go process error
MVI A,EOFCH ;Yes - return eof character
RET ;and return
;
RDERR:
PRINT 'Read error at line'
DECOUT LINENUM ;Print error message
PRINT
MVI A,EOFCH ;and return eof character
RET
;
READOK:
LXI H,BUFR ;Start at beginning of buffer
;
NOREAD:
MOV A,M ;Get next byte
INX H ;Increment pointer
SHLD BUFPTR
RET
;
; ADDTOCHECH - Add A register to CHECKSUM
; All registers preserved
;
ADDTOCHECK:
PUSH H
PUSH PSW
LXI H,CHECKSUM
ADD M
MOV M,A
POP PSW
POP H
RET
;
;
; Equates
;
STARTCH: EQU ':' ;Colon
EOFCH: EQU 26 ;Ctrl-Z
FCB: EQU 05CH ;Address of default FCB
FCBTYPE: EQU 065H ;Address of type in FCB
FCBDRIVE: EQU 05CH ;Address of drive number in FCB
BUFR: EQU 080H ;Standard "DMA" buffer
BDOS: EQU 5 ;BDOS call location
;
; Constants
;
HEXTYPE: DB 'HEX' ;Default file type
;
; Variables
;
DS 80H ;Local stack
STACK: EQU $
LINENUM: DS 2 ;Number of lines read
NUMBUFF: DS 5 ;Buffer for number conversion
NUMBYTES: DS 1 ;Number of data bytes on line
LOADADR: DS 2 ;Address to load next byte at
CHECKSUM: DS 1 ;Working checksum
BUFPTR: DS 2 ;Pointer into BUFR
HLOADEND: EQU 1-$
;
; End of program
;
END START