mirror of
https://github.com/microsoft/MS-DOS.git
synced 2024-12-01 10:05:48 +00:00
214 lines
3.3 KiB
NASM
214 lines
3.3 KiB
NASM
; 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
|
||
|