Mercurial > repos > simple16
comparison src/asm.c @ 55:f9846719aa26
Remove old 48K limit in assembler
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 31 Aug 2016 22:41:05 -0700 |
parents | 51672bd41cdd |
children | c44170825b16 |
comparison
equal
deleted
inserted
replaced
54:bce01001a8c1 | 55:f9846719aa26 |
---|---|
43 uint16_t base; | 43 uint16_t base; |
44 uint8_t first_shift; | 44 uint8_t first_shift; |
45 uint8_t second_shift; | 45 uint8_t second_shift; |
46 uint8_t expected_args; | 46 uint8_t expected_args; |
47 } inst_info; | 47 } inst_info; |
48 | |
49 #define MAX_SIZE (4*1024*1024) | |
48 | 50 |
49 label *add_label(label_meta *labels, char *name, uint16_t address, uint8_t valid) | 51 label *add_label(label_meta *labels, char *name, uint16_t address, uint8_t valid) |
50 { | 52 { |
51 if (labels->num_labels == labels->label_storage) { | 53 if (labels->num_labels == labels->label_storage) { |
52 labels->label_storage *= 2; | 54 labels->label_storage *= 2; |
190 } | 192 } |
191 } | 193 } |
192 free(meta->labels); | 194 free(meta->labels); |
193 } | 195 } |
194 | 196 |
195 int handle_dc(char size, char *linebuf, uint8_t *outbuf, uint16_t *pc, label_meta *meta) | 197 int handle_dc(char size, char *linebuf, uint8_t *outbuf, uint32_t *pc, label_meta *meta) |
196 { | 198 { |
197 char *arg; | 199 char *arg; |
198 long value; | 200 long value; |
199 char *start = linebuf; | 201 char *start = linebuf; |
200 char *orig = strdup(linebuf); | 202 char *orig = strdup(linebuf); |
259 { | 261 { |
260 case 'b': | 262 case 'b': |
261 if (value < -128 || value > 255) { | 263 if (value < -128 || value > 255) { |
262 fprintf(stderr, "WARNING: %s is too large to fit in a byte\n", arg); | 264 fprintf(stderr, "WARNING: %s is too large to fit in a byte\n", arg); |
263 } | 265 } |
264 if (*pc >= 48 * 1024) { | 266 if (*pc >= MAX_SIZE) { |
265 fputs("ERROR: Hit end of ROM space\n", stderr); | 267 fputs("ERROR: Hit end of ROM space\n", stderr); |
266 free(orig); | 268 free(orig); |
267 return 0; | 269 return 0; |
268 } | 270 } |
269 outbuf[(*pc)++] = value; | 271 outbuf[(*pc)++] = value; |
270 break; | 272 break; |
271 case 'w': | 273 case 'w': |
272 if (value < -32768 || value > 65535) { | 274 if (value < -32768 || value > 65535) { |
273 fprintf(stderr, "WARNING: %s is too large to fit in a word\n", arg); | 275 fprintf(stderr, "WARNING: %s is too large to fit in a word\n", arg); |
274 } | 276 } |
275 if (*pc >= 48 * 1024 - 1) { | 277 if (*pc >= MAX_SIZE - 1) { |
276 fputs("ERROR: Hit end of ROM space\n", stderr); | 278 fputs("ERROR: Hit end of ROM space\n", stderr); |
277 free(orig); | 279 free(orig); |
278 return 0; | 280 return 0; |
279 } | 281 } |
280 outbuf[(*pc)++] = value >> 8; | 282 outbuf[(*pc)++] = value >> 8; |
281 outbuf[(*pc)++] = value; | 283 outbuf[(*pc)++] = value; |
282 break; | 284 break; |
283 case 'l': | 285 case 'l': |
284 if (*pc >= 48 * 1024 - 3) { | 286 if (*pc >= MAX_SIZE - 3) { |
285 fputs("ERROR: Hit end of ROM space\n", stderr); | 287 fputs("ERROR: Hit end of ROM space\n", stderr); |
286 free(orig); | 288 free(orig); |
287 return 0; | 289 return 0; |
288 } | 290 } |
289 outbuf[(*pc)++] = value >> 24; | 291 outbuf[(*pc)++] = value >> 24; |
295 } | 297 } |
296 free(orig); | 298 free(orig); |
297 return 1; | 299 return 1; |
298 } | 300 } |
299 | 301 |
300 int process_arg(uint16_t *inst, char *arg, int arg_shift, int immed_min, int immed_max, label_meta *meta, uint16_t pc) | 302 int process_arg(uint16_t *inst, char *arg, int arg_shift, int immed_min, int immed_max, label_meta *meta, uint32_t pc) |
301 { | 303 { |
302 long value; | 304 long value; |
303 if (arg[0] == 'r' && arg[1] >= '0' && arg[1] <= '9' && (arg[2] == 0 || arg[3] == 0)) { | 305 if (arg[0] == 'r' && arg[1] >= '0' && arg[1] <= '9' && (arg[2] == 0 || arg[3] == 0)) { |
304 //posible register | 306 //posible register |
305 value = strtol(arg+1, NULL, 10); | 307 value = strtol(arg+1, NULL, 10); |
401 outbuf[pc] = inst >> 8; | 403 outbuf[pc] = inst >> 8; |
402 outbuf[pc+1] = inst; | 404 outbuf[pc+1] = inst; |
403 return 1; | 405 return 1; |
404 } | 406 } |
405 | 407 |
406 uint8_t handle_incbin(char *cur, uint8_t *outbuf, uint16_t *pc) | 408 uint8_t handle_incbin(char *cur, uint8_t *outbuf, uint32_t *pc) |
407 { | 409 { |
408 char * end = strchr(cur, ';'); | 410 char * end = strchr(cur, ';'); |
409 if (end) { | 411 if (end) { |
410 *end = 0; | 412 *end = 0; |
411 } else { | 413 } else { |
419 FILE *incfile = fopen(cur, "rb"); | 421 FILE *incfile = fopen(cur, "rb"); |
420 if (!incfile) { | 422 if (!incfile) { |
421 fprintf(stderr, "Failed to open inclued file %s for reading\n", cur); | 423 fprintf(stderr, "Failed to open inclued file %s for reading\n", cur); |
422 return 0; | 424 return 0; |
423 } | 425 } |
424 size_t read = fread(outbuf + *pc, 1, 48*1024-*pc, incfile); | 426 size_t read = fread(outbuf + *pc, 1, MAX_SIZE-*pc, incfile); |
425 fclose(incfile); | 427 fclose(incfile); |
426 *pc += read; | 428 *pc += read; |
427 return 1; | 429 return 1; |
428 } | 430 } |
429 | 431 |
430 uint8_t assemble_file(FILE *input, FILE *output) | 432 uint8_t assemble_file(FILE *input, FILE *output) |
431 { | 433 { |
432 //fixed size buffers are lame, but so are lines longer than 4K characters | 434 //fixed size buffers are lame, but so are lines longer than 4K characters |
433 //this is good enough for the really simple first version | 435 //this is good enough for the really simple first version |
434 char linebuf[4096]; | 436 char linebuf[4096]; |
435 //maximum program size is 48KB | 437 uint8_t outbuf[MAX_SIZE]; |
436 uint8_t outbuf[48*1024]; | 438 uint32_t pc = 0; |
437 uint16_t pc = 0; | |
438 | 439 |
439 size_t num_labels = 0; | 440 size_t num_labels = 0; |
440 size_t label_storage = 1024; | 441 size_t label_storage = 1024; |
441 label_meta labels = { | 442 label_meta labels = { |
442 .labels = malloc(sizeof(label) * 1024), | 443 .labels = malloc(sizeof(label) * 1024), |