; 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