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),