mirror of
https://github.com/microsoft/MS-DOS.git
synced 2024-12-01 18:15:47 +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
|
|||
|
|