-
Notifications
You must be signed in to change notification settings - Fork 0
/
hex2bin.asm
224 lines (211 loc) · 3.87 KB
/
hex2bin.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
; 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 DX,HEADER
MOV AH,9
INT 21H
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
MOV DX,BYEMES
MOV AH,9
INT 21H
EXIT:
INT 20H
NOROOM:
MOV DX,DIRFUL
JMP QUIT
HEADER: DB 13,10,'Seattle Computer Products 8086 Hex Converter Version 1.02A'
DB 13,10,'Copyright 1979-1983 by Seattle Computer Products, Inc.'
DB 13,10,13,10,'$'
HEX: DB "HEX"
BYEMES: DB "Done.",0Dh,0Ah,"$"
ERRMES: DB "Error in HEX file--conversion, aborted",0Dh,0Ah,"$"
NOFILE: DB "File not found",0Dh,0Ah,"$"
ADDR: DB "Address out of range--conversion, aborted",0Dh,0Ah,"$"
DIRFUL: DB "Disk directory full",0Dh,0Ah,"$"
OFFSET: DS 2
SEGSIZ: DS 2
SIGN: DS 1
BUFFER: DS BUFSIZ
START:
STARTSEG EQU (START+15)/16