MS-DOS/v1.25/source/HEX2BIN.ASM
2018-09-21 17:51:26 -07:00

214 lines
3.3 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; HEX2BIN version 1.02
; Converts Intel hex format files to straight binary
FCB: EQU 5CH
READ: EQU 20
SETDMA: EQU 26
OPEN: EQU 15
CLOSE: EQU 16
CREATE: EQU 22
DELETE: EQU 19
BLKWRT: EQU 40
GETSEG: EQU 38
BUFSIZ: EQU 1024
ORG 100H
PUT 100H
HEX2BIN:
MOV DI,FCB+9
CMP B,[DI]," "
JNZ HAVEXT
MOV SI,HEX
MOVB
MOVW
HAVEXT:
;Get load offset (default is -100H)
MOV CL,4 ;Needed for shifts
MOV [OFFSET],-100H
MOV SI,FCB+11H ;Scan second FCB for offset
LODB
CMP AL," " ;Check if offset present
JZ HAVOFF
MOV B,[SIGN],0 ;Assume positive sign for now
CMP AL,"+"
JZ GETOFF ;Get a positive offset
CMP AL,"-"
JNZ GETOFF1 ;If not + or -, then not signed
MOV B,[SIGN],1 ;Flag as negative offset
GETOFF:
LODB ;Eat sign
GETOFF1:
CALL HEXCHK ;Check for valid hex character
JC HAVOFF ;No offset if not valid
XOR BX,BX ;Intialize offset sum to 0
CONVOFF:
SHL BX,CL ;Multiply current sum by 16
OR BL,AL ;Add in current hex digit
LODB ;Get next digit
CALL HEXCHK ;And convert it to binary
JNC CONVOFF ;Loop until all hex digits read
TEST B,[SIGN],-1 ;Check if offset was to be negative
JZ SAVOFF
NEG BX
SAVOFF:
MOV [OFFSET],BX
HAVOFF:
MOV DX,STARTSEG
MOV AX,DS
ADD DX,AX ;Compute load segment
MOV AH,GETSEG
INT 33
MOV ES,DX
SEG ES
MOV CX,[6] ;Get size of segment
MOV [SEGSIZ],CX
XOR AX,AX
MOV DI,AX
MOV BP,AX
SHR CX
REP
STOW ;Fill entire segment with zeros
MOV AH,OPEN
MOV DX,FCB
INT 21H
OR AL,AL
JNZ NOFIL
MOV B,[FCB+32],0
MOV [FCB+14],BUFSIZ ;Set record size to buffer size
MOV DX,BUFFER
MOV AH,SETDMA
INT 33
MOV AH,READ
MOV DX,FCB ;All set up for sequential reads
MOV SI,BUFFER+BUFSIZ ;Flag input buffer as empty
READHEX:
CALL GETCH
CMP AL,":" ;Search for : to start line
JNZ READHEX
CALL GETBYT ;Get byte count
MOV CL,AL
MOV CH,0
JCXZ DONE
CALL GETBYT ;Get high byte of load address
MOV BH,AL
CALL GETBYT ;Get low byte of load address
MOV BL,AL
ADD BX,[OFFSET] ;Add in offset
MOV DI,BX
CALL GETBYT ;Throw away type byte
READLN:
CMP DI,[SEGSIZ]
JAE ADERR
CALL GETBYT ;Get data byte
STOB
CMP DI,BP ;Check if this is the largest address so far
JBE HAVBIG
MOV BP,DI ;Save new largest
HAVBIG:
LOOP READLN
JP READHEX
NOFIL:
MOV DX,NOFILE
QUIT:
MOV AH,9
INT 21H
INT 20H
ADERR:
MOV DX,ADDR
JMP SHOWERR
GETCH:
CMP SI,BUFFER+BUFSIZ
JNZ NOREAD
INT 21H
CMP AL,1
JZ ERROR
MOV SI,BUFFER
NOREAD:
LODB
CMP AL,1AH
JZ DONE
RET
GETBYT:
CALL HEXDIG
MOV BL,AL
CALL HEXDIG
SHL BL
SHL BL
SHL BL
SHL BL
OR AL,BL
RET
HEXCHK:
SUB AL,"0"
JC RET
CMP AL,10
JC CMCRET
SUB AL,"A"-"0"-10
JC RET
CMP AL,16
CMCRET:
CMC
RET
HEXDIG:
CALL GETCH
CALL HEXCHK
JNC RET
ERROR:
MOV DX,ERRMES
SHOWERR:
MOV AH,9
INT 21H
DONE:
MOV [FCB+9],4F00H+"C" ;"CO"
MOV B,[FCB+11],"M"
MOV DX,FCB
MOV AH,CREATE
INT 21H
OR AL,AL
JNZ NOROOM
XOR AX,AX
MOV [FCB+33],AX
MOV [FCB+35],AX ;Set RR field
INC AX
MOV [FCB+14],AX ;Set record size
XOR DX,DX
PUSH DS
PUSH ES
POP DS ;Get load segment
MOV AH,SETDMA
INT 21H
POP DS
MOV CX,BP
MOV AH,BLKWRT
MOV DX,FCB
INT 21H
MOV AH,CLOSE
INT 21H
EXIT:
INT 20H
NOROOM:
MOV DX,DIRFUL
JMP QUIT
HEX: DB "HEX"
ERRMES: DB "Error in HEX file--conversion aborted$"
NOFILE: DB "File not found$"
ADDR: DB "Address out of range--conversion aborted$"
DIRFUL: DB "Disk directory full$"
OFFSET: DS 2
SEGSIZ: DS 2
SIGN: DS 1
BUFFER: DS BUFSIZ
START:
STARTSEG EQU (START+15)/16