1 #include <stdio.h>
2 #include <string.h>
3 #include "defs.h"
4 #include "externs.h"
5 #include "protos.h"
6
7
8 /* ----
9 * println()
10 * ----
11 * prints the contents of prlnbuf
12 */
13
14 void
println(void)15 println(void)
16 {
17 int nb, cnt;
18 int i;
19
20 /* check if output possible */
21 if (list_level == 0)
22 return;
23 if (!xlist || !asm_opt[OPT_LIST] || (expand_macro && !asm_opt[OPT_MACRO]))
24 return;
25
26 /* update line buffer if necessary */
27 if (continued_line)
28 strcpy(prlnbuf, tmplnbuf);
29
30 /* output */
31 if (data_loccnt == -1)
32 /* line buffer */
33 fprintf(lst_fp, "%s\n", prlnbuf);
34 else {
35 /* line buffer + data bytes */
36 loadlc(data_loccnt, 0);
37
38 /* number of bytes */
39 nb = loccnt - data_loccnt;
40
41 /* check level */
42 if ((data_level > list_level) && (nb > 3))
43 /* doesn't match */
44 fprintf(lst_fp, "%s\n", prlnbuf);
45 else {
46 /* ok */
47 cnt = 0;
48 for (i = 0; i < nb; i++) {
49 if (bank >= RESERVED_BANK) {
50 prlnbuf[16 + (3*cnt)] = '-';
51 prlnbuf[17 + (3*cnt)] = '-';
52 }
53 else {
54 hexcon(2, rom[bank][data_loccnt]);
55 prlnbuf[16 + (3*cnt)] = hex[1];
56 prlnbuf[17 + (3*cnt)] = hex[2];
57 }
58 data_loccnt++;
59 cnt++;
60 if (cnt == data_size) {
61 cnt = 0;
62 fprintf(lst_fp, "%s\n", prlnbuf);
63 clearln();
64 loadlc(data_loccnt, 0);
65 }
66 }
67 if (cnt)
68 fprintf(lst_fp, "%s\n", prlnbuf);
69 }
70 }
71 }
72
73
74 /* ----
75 * clearln()
76 * ----
77 * clear prlnbuf
78 */
79
80 void
clearln(void)81 clearln(void)
82 {
83 int i;
84
85 for (i = 0; i < SFIELD; i++)
86 prlnbuf[i] = ' ';
87 prlnbuf[i] = 0;
88 }
89
90
91 /* ----
92 * loadlc()
93 * ----
94 * load 16 bit value in printable form into prlnbuf
95 */
96
97 void
loadlc(int offset,int pos)98 loadlc(int offset, int pos)
99 {
100 int i;
101
102 if (pos)
103 i = 16;
104 else
105 i = 7;
106
107 if (pos == 0) {
108 if (bank >= RESERVED_BANK) {
109 prlnbuf[i++] = '-';
110 prlnbuf[i++] = '-';
111 }
112 else {
113 hexcon(2, bank);
114 prlnbuf[i++] = hex[1];
115 prlnbuf[i++] = hex[2];
116 }
117 prlnbuf[i++] = ':';
118 offset += page << 13;
119 }
120 hexcon(4, offset);
121 prlnbuf[i++] = hex[1];
122 prlnbuf[i++] = hex[2];
123 prlnbuf[i++] = hex[3];
124 prlnbuf[i] = hex[4];
125 }
126
127
128 /* ----
129 * hexcon()
130 * ----
131 * convert number supplied as argument to hexadecimal in hex[digit]
132 */
133
134 void
hexcon(int digit,int num)135 hexcon(int digit, int num)
136 {
137 for (; digit > 0; digit--) {
138 hex[digit] = (num & 0x0f) + '0';
139 if (hex[digit] > '9')
140 hex[digit] += 'A' - '9' - 1;
141 num >>= 4;
142 }
143 }
144
145
146 /* ----
147 * putbyte()
148 * ----
149 * store a byte in the rom
150 */
151
152 void
putbyte(int offset,int data)153 putbyte(int offset, int data)
154 {
155 if (bank >= RESERVED_BANK)
156 return;
157 if (offset < 0x2000) {
158 rom[bank][offset] = (data) & 0xFF;
159 map[bank][offset] = section + (page << 5);
160
161 /* update rom size */
162 if (bank > max_bank)
163 max_bank = bank;
164 }
165 }
166
167
168 /* ----
169 * putword()
170 * ----
171 * store a word in the rom
172 */
173
174 void
putword(int offset,int data)175 putword(int offset, int data)
176 {
177 if (bank >= RESERVED_BANK)
178 return;
179 if (offset < 0x1FFF) {
180 /* low byte */
181 rom[bank][offset] = (data) & 0xFF;
182 map[bank][offset] = section + (page << 5);
183
184 /* high byte */
185 rom[bank][offset+1] = (data >> 8) & 0xFF;
186 map[bank][offset+1] = section + (page << 5);
187
188 /* update rom size */
189 if (bank > max_bank)
190 max_bank = bank;
191 }
192 }
193
194
195 /* ----
196 * putbuffer()
197 * ----
198 * copy a buffer at the current location
199 */
200
201 void
putbuffer(void * data,int size)202 putbuffer(void *data, int size)
203 {
204 int addr;
205
206 /* check size */
207 if (size == 0)
208 return;
209
210 /* check if the buffer will fit in the rom */
211 if (bank >= RESERVED_BANK) {
212 addr = loccnt + size;
213
214 if (addr > 0x1FFF) {
215 fatal_error("PROC overflow!");
216 return;
217 }
218 }
219 else {
220 addr = loccnt + size + (bank << 13);
221
222 if (addr > rom_limit) {
223 fatal_error("ROM overflow!");
224 return;
225 }
226
227 /* copy the buffer */
228 if (pass == LAST_PASS) {
229 if (data) {
230 memcpy(&rom[bank][loccnt], data, size);
231 memset(&map[bank][loccnt], section + (page << 5), size);
232 }
233 else {
234 memset(&rom[bank][loccnt], 0, size);
235 memset(&map[bank][loccnt], section + (page << 5), size);
236 }
237 }
238 }
239
240 /* update the location counter */
241 bank += (loccnt + size) >> 13;
242 loccnt = (loccnt + size) & 0x1FFF;
243
244 /* update rom size */
245 if (bank < RESERVED_BANK) {
246 if (bank > max_bank) {
247 if (loccnt)
248 max_bank = bank;
249 else
250 max_bank = bank - 1;
251 }
252 }
253 }
254
255
256 /* ----
257 * write_srec()
258 * ----
259 */
260
261 void
write_srec(char * file,char * ext,int base)262 write_srec(char *file, char *ext, int base)
263 {
264 unsigned char data, chksum;
265 char fname[128];
266 int addr, dump, cnt, pos, i, j;
267 FILE *fp;
268
269 /* status message */
270 if (!strcmp(ext, "mx"))
271 printf("writing mx file... ");
272 else
273 printf("writing s-record file... ");
274
275 /* flush output */
276 fflush(stdout);
277
278 /* add the file extension */
279 strcpy(fname, file);
280 strcat(fname, ".");
281 strcat(fname, ext);
282
283 /* open the file */
284 if ((fp = fopen(fname, "w")) == NULL) {
285 printf("can not open file '%s'!\n", fname);
286 return;
287 }
288
289 /* dump the rom */
290 dump = 0;
291 cnt = 0;
292 pos = 0;
293
294 for (i = 0; i <= max_bank; i++) {
295 for (j = 0; j < 8192; j++) {
296 if (map[i][j] != 0xFF) {
297 /* data byte */
298 if (cnt == 0)
299 pos = j;
300 cnt++;
301 if (cnt == 32)
302 dump = 1;
303 }
304 else {
305 /* free byte */
306 if (cnt)
307 dump = 1;
308 }
309 if (j == 8191)
310 if (cnt)
311 dump = 1;
312
313 /* dump */
314 if (dump) {
315 dump = 0;
316 addr = base + (i << 13) + pos;
317 chksum = cnt + ((addr >> 16) & 0xFF) +
318 ((addr >> 8) & 0xFF) +
319 ((addr) & 0xFF) +
320 4;
321
322 /* number, address */
323 fprintf(fp, "S2%02X%06X", cnt + 4, addr);
324
325 /* code */
326 while (cnt) {
327 data = rom[i][pos++];
328 chksum += data;
329 fprintf(fp, "%02X", data);
330 cnt--;
331 }
332
333 /* chksum */
334 fprintf(fp, "%02X\n", (~chksum) & 0xFF);
335 }
336 }
337 }
338
339 /* starting address */
340 addr = ((map[0][0] >> 5) << 13);
341 chksum = ((addr >> 8) & 0xFF) + (addr & 0xFF) + 4;
342 fprintf(fp, "S804%06X%02X", addr, (~chksum) & 0xFF);
343
344 /* ok */
345 fclose(fp);
346 printf("OK\n");
347 }
348
349
350 /* ----
351 * fatal_error()
352 * ----
353 * stop compilation
354 */
355
356 void
fatal_error(char * stptr)357 fatal_error(char *stptr)
358 {
359 error(stptr);
360 stop_pass = 1;
361 }
362
363
364 /* ----
365 * error()
366 * ----
367 * error printing routine
368 */
369
370 void
error(char * stptr)371 error(char *stptr)
372 {
373 warning(stptr);
374 errcnt++;
375 }
376
377
378 /* ----
379 * warning()
380 * ----
381 * warning printing routine
382 */
383
384 void
warning(char * stptr)385 warning(char *stptr)
386 {
387 int i, temp;
388
389 /* put the source line number into prlnbuf */
390 i = 4;
391 temp = slnum;
392 while (temp != 0) {
393 prlnbuf[i--] = temp % 10 + '0';
394 temp /= 10;
395 }
396
397 /* update the current file name */
398 if (infile_error != infile_num) {
399 infile_error = infile_num;
400 printf("#[%i] %s\n", infile_num, input_file[infile_num].name);
401 }
402
403 /* output the line and the error message */
404 loadlc(loccnt, 0);
405 printf("%s\n", prlnbuf);
406 printf(" %s\n", stptr);
407 }
408
409