|
|
1.1 ! root 1: ! 2: #include <assert.h> ! 3: #include <stdio.h> ! 4: #include <stdlib.h> ! 5: #include <string.h> ! 6: #include <ctype.h> ! 7: #include <stdarg.h> ! 8: #include "dict.h" ! 9: ! 10: #define LAB_LEN 32 ! 11: #define BASE 0x1c ! 12: FILE *fin; ! 13: FILE *fout; ! 14: char buf[4096]; ! 15: Dict labels; ! 16: int dump_labels = 0; ! 17: int line_no = 0; ! 18: int last_op_addr; ! 19: enum SIZE { BYTE, WORD, LONG, LONG_FIXUP }; ! 20: ! 21: /* to convert weird move sizes to standard sizes */ ! 22: const int move_size[4] = { 1, 3, 2, 0 }; ! 23: const char *Bcc_str[16] = { ! 24: "ra",NULL,"hi","ls","cc","cs","ne","eq", ! 25: "vc","vs","pl","mi","ge","lt","gt","le" ! 26: }; ! 27: const char *DBcc_str[16] = { ! 28: "t","f","hi","ls","cc","cs","ne","eq", ! 29: "vc","vs","pl","mi","ge","lt","gt","le" ! 30: }; ! 31: ! 32: #define check(ch) do { \ ! 33: if (*pos != (ch)) error ("Expected '%c'", ch); \ ! 34: pos++; \ ! 35: } while (0); ! 36: #define check_whitespace() do { \ ! 37: if (!isspace (*pos)) error ("Line malformed."); \ ! 38: while (isspace (*pos)) pos++; \ ! 39: } while (0); ! 40: ! 41: #define get_bitpos() ((int)ftell (fout)) ! 42: #define set_bitpos(pos) (fseek (fout,pos,SEEK_SET)) ! 43: ! 44: #define F_DREG (1<<0) ! 45: #define F_AREG (1<<1) ! 46: #define F_IND (1<<2) ! 47: #define F_POST (1<<3) ! 48: #define F_PRE (1<<4) ! 49: #define F_OFFSET (1<<5) ! 50: #define F_INDEX (1<<6) ! 51: #define F_MEM_W (1<<7) ! 52: #define F_MEM_L (1<<8) ! 53: #define F_IMM (1<<9) ! 54: #define F_PC_OFFSET (1<<10) ! 55: #define F_PC_INDEX (1<<11) ! 56: ! 57: #define F_NOLABELS (1<<12) ! 58: ! 59: #define F_NOIMM_NOPC_NOAREG (F_DREG | F_IND | F_POST | F_PRE | \ ! 60: F_OFFSET | F_INDEX | F_MEM_W | F_MEM_L) ! 61: #define F_ALL (0xffffffff & (~(F_NOLABELS))) ! 62: #define F_ALL_NOAREG (F_ALL & (~F_AREG)) ! 63: ! 64: typedef union Opcode { ! 65: unsigned short code; ! 66: struct move { ! 67: uint src_reg : 3; ! 68: uint src_mode : 3; ! 69: uint dest_mode : 3; ! 70: uint dest_reg : 3; ! 71: uint size : 2; ! 72: uint op : 2; ! 73: } move; ! 74: struct adr_index { ! 75: int displacement : 8; ! 76: uint zeros : 3; ! 77: uint ind_size : 1; ! 78: uint reg : 3; ! 79: uint reg_type : 1; ! 80: } adr_index; ! 81: struct addq { ! 82: uint dest_reg : 3; ! 83: uint dest_mode : 3; ! 84: uint size : 2; ! 85: uint issub : 1; ! 86: uint data : 3; ! 87: uint op : 4; ! 88: } addq; ! 89: struct jmp { ! 90: uint dest_reg : 3; ! 91: uint dest_mode : 3; ! 92: uint op : 10; ! 93: } jmp; ! 94: struct addi { ! 95: uint dest_reg : 3; ! 96: uint dest_mode : 3; ! 97: uint size : 2; ! 98: uint OP6 : 8; ! 99: } addi; ! 100: /* size and effective address */ ! 101: struct type1 { ! 102: uint ea_reg : 3; ! 103: uint ea_mode : 3; ! 104: uint size : 2; ! 105: uint op : 8; ! 106: } type1; ! 107: /* reg, opmode, ea */ ! 108: struct type2 { ! 109: uint ea_reg : 3; ! 110: uint ea_mode : 3; ! 111: uint op_mode : 3; ! 112: uint reg : 3; ! 113: uint op : 4; ! 114: } type2; ! 115: struct MemShift { ! 116: uint ea_reg : 3; ! 117: uint ea_mode : 3; ! 118: uint OP3 : 2; ! 119: uint dr : 1; ! 120: uint type : 2; ! 121: uint OP0x1c : 5; ! 122: } MemShift; ! 123: struct ASx { ! 124: uint reg : 3; ! 125: uint OP0 : 2; ! 126: uint ir : 1; ! 127: uint size : 2; ! 128: uint dr : 1; ! 129: uint count_reg : 3; ! 130: uint OP0xe : 4; ! 131: } ASx; ! 132: struct abcd { ! 133: uint src_reg : 3; ! 134: uint rm : 1; ! 135: uint OP16 : 5; ! 136: uint dest_reg : 3; ! 137: uint OP12 : 4; ! 138: } abcd; ! 139: struct addx { ! 140: uint src_reg : 3; ! 141: uint rm : 1; ! 142: uint OP0 : 2; ! 143: uint size : 2; ! 144: uint OP1 : 1; ! 145: uint dest_reg : 3; ! 146: uint op : 4; ! 147: } addx; ! 148: struct cmpm { ! 149: uint src_reg : 3; ! 150: uint OP1_1 : 3; ! 151: uint size : 2; ! 152: uint OP2_1 : 1; ! 153: uint dest_reg : 3; ! 154: uint OP0xb : 4; ! 155: } cmpm; ! 156: /* branches */ ! 157: struct DBcc { ! 158: uint reg : 3; ! 159: uint OP25 : 5; ! 160: uint cond : 4; ! 161: uint OP5 : 4; ! 162: } DBcc; ! 163: struct Bcc { ! 164: int displacement : 8; ! 165: uint cond : 4; ! 166: uint op : 4; ! 167: } Bcc; ! 168: struct bra { ! 169: int displacement : 8; ! 170: uint op : 8; ! 171: } bra; ! 172: struct movem { ! 173: uint dest_reg : 3; ! 174: uint dest_mode : 3; ! 175: uint sz : 1; ! 176: uint ONE : 3; ! 177: uint dr : 1; ! 178: uint NINE : 5; ! 179: } movem; ! 180: struct lea { ! 181: uint dest_reg : 3; ! 182: uint dest_mode : 3; ! 183: uint SEVEN : 3; ! 184: uint reg : 3; ! 185: uint FOUR : 4; ! 186: } lea; ! 187: struct moveq { ! 188: int data : 8; ! 189: uint ZERO : 1; ! 190: uint reg : 3; ! 191: uint SEVEN : 4; ! 192: } moveq; ! 193: struct exg { ! 194: uint dest_reg : 3; ! 195: uint op_mode : 5; ! 196: uint OP1 : 1; ! 197: uint src_reg : 3; ! 198: uint OP0xc : 4; ! 199: } exg; ! 200: } Opcode; ! 201: ! 202: struct Fixup { ! 203: int rel_to; ! 204: int line_no; ! 205: int size; ! 206: int adr; ! 207: char label[LAB_LEN]; ! 208: struct Fixup *next; ! 209: }; ! 210: ! 211: struct Label { ! 212: const char *name; ! 213: int val; ! 214: enum LAB_TYPE { ! 215: L_ADDR, ! 216: L_CONST ! 217: } type; ! 218: }; ! 219: ! 220: struct ImmVal { ! 221: int has_label; ! 222: char label[LAB_LEN]; ! 223: int val; ! 224: }; ! 225: ! 226: struct Fixup *fix_first = NULL; ! 227: struct Fixup *fix_last = NULL; ! 228: void add_fixup (int adr, int size, const char *label) ! 229: { ! 230: struct Fixup *fix = malloc (sizeof (struct Fixup)); ! 231: fix->adr = adr; ! 232: fix->size = size; ! 233: fix->next = NULL; ! 234: fix->rel_to = (last_op_addr + 2) - BASE; ! 235: fix->line_no = line_no; ! 236: strcpy (fix->label, label); ! 237: if (fix_first == NULL) fix_first = fix; ! 238: if (fix_last == NULL) fix_last = fix; ! 239: else { ! 240: fix_last->next = fix; ! 241: fix_last = fix; ! 242: } ! 243: } ! 244: ! 245: void error (const char *format, ...) ! 246: { ! 247: va_list argptr; ! 248: ! 249: printf ("Error at line %d: ", line_no); ! 250: va_start (argptr, format); ! 251: vprintf (format, argptr); ! 252: va_end (argptr); ! 253: printf ("\n"); ! 254: ! 255: fclose (fout); ! 256: remove ("aout.prg"); ! 257: exit (0); ! 258: } ! 259: ! 260: void add_label (const char *name, int type, int val) ! 261: { ! 262: struct Label *lab = malloc (sizeof (struct Label)); ! 263: if (dict_get (&labels, name)) error ("Label %s redefined.", name); ! 264: lab->val = val; ! 265: lab->type = type; ! 266: dict_set (&labels, name, lab); ! 267: } ! 268: ! 269: struct Label *get_label (const char *name) ! 270: { ! 271: struct Label *lab; ! 272: struct Node *n = dict_get (&labels, name); ! 273: ! 274: if (n == NULL) return NULL; ! 275: lab = n->obj; ! 276: lab->name = n->key; ! 277: return lab; ! 278: } ! 279: ! 280: void wr_byte(unsigned char x) ! 281: { ! 282: fputc (x, fout); ! 283: } ! 284: ! 285: void wr_short(short x) ! 286: { ! 287: wr_byte((unsigned char)((x>>8) & 0xff)); ! 288: wr_byte((unsigned char)(x & 0xff)); ! 289: } ! 290: ! 291: void wr_int(int x) ! 292: { ! 293: wr_byte((unsigned char)((x>>24) & 0xff)); ! 294: wr_byte((unsigned char)((x>>16) & 0xff)); ! 295: wr_byte((unsigned char)((x>>8) & 0xff)); ! 296: wr_byte((unsigned char)(x & 0xff)); ! 297: } ! 298: ! 299: ! 300: static inline int get_size (int ch) ! 301: { ! 302: switch (ch) { ! 303: case 'b': return BYTE; ! 304: case 'w': return WORD; ! 305: case 'l': return LONG; ! 306: default: error ("Invalid size '.%c'.", ch); return 0; ! 307: } ! 308: } ! 309: ! 310: char *rd_label (char *buf, char *lab_buf) ! 311: { ! 312: char snipped; ! 313: char *pos = buf; ! 314: ! 315: if (!isalpha (*buf)) error ("Label expected."); ! 316: /* label */ ! 317: do { ! 318: pos++; ! 319: } while (isalnum (*pos) || (*pos == '_')); ! 320: /* snip */ ! 321: snipped = *pos; ! 322: *pos = '\0'; ! 323: ! 324: if (strlen (buf) > LAB_LEN-1) error ("Label too long."); ! 325: strncpy (lab_buf, buf, LAB_LEN); ! 326: lab_buf[LAB_LEN-1] = '\0'; ! 327: *pos = snipped; ! 328: return pos; ! 329: } ! 330: ! 331: ! 332: void check_range (int *val, enum SIZE size) ! 333: { ! 334: switch (size) { ! 335: case BYTE: if ((*val < -128) || (*val > 255)) goto err; ! 336: if (*val > 127) *val -= 256; ! 337: break; ! 338: case WORD: if ((*val < -32768) || (*val > 65535)) goto err; ! 339: if (*val > 32767) *val -= 65536; ! 340: break; ! 341: default: break; ! 342: } ! 343: return; ! 344: err: ! 345: error ("Data too large."); ! 346: } ! 347: ! 348: ! 349: char *get_imm (char *buf, struct ImmVal *imm, int flags) ! 350: { ! 351: struct Label *lab; ! 352: ! 353: imm->has_label = 0; ! 354: while (isspace (*buf)) buf++; ! 355: if (flags & F_IMM) { ! 356: if (*buf != '#') goto err; ! 357: buf++; ! 358: } ! 359: if (*buf == '$') { ! 360: /* hex value */ ! 361: buf++; ! 362: if (sscanf (&buf[0], "%x", &imm->val) != 1) goto err; ! 363: while (isxdigit (*buf)) buf++; ! 364: } else if (isdigit (*buf) || (*buf == '-')) { ! 365: /* dec value */ ! 366: if (sscanf (&buf[0], "%d", &imm->val) != 1) goto err; ! 367: if (*buf == '-') buf++; ! 368: while (isdigit (*buf)) buf++; ! 369: } else if (isalpha (*buf)) { ! 370: /* label */ ! 371: buf = rd_label (buf, imm->label); ! 372: lab = get_label (imm->label); ! 373: imm->val = 0; ! 374: if (lab) { ! 375: if (lab->type == L_CONST) imm->val = lab->val; ! 376: else imm->has_label = 1; ! 377: } else { ! 378: imm->has_label = 1; ! 379: } ! 380: if ((flags & F_NOLABELS) && (imm->has_label)) { ! 381: error ("Label not allowed."); ! 382: } ! 383: } else { ! 384: goto err; ! 385: } ! 386: return buf; ! 387: err: ! 388: error ("Malformed immediate value."); ! 389: return NULL; ! 390: } ! 391: ! 392: void check_end (const char *buf) ! 393: { ! 394: while (isspace (*buf)) buf++; ! 395: if (*buf) error ("Garbage at end of line."); ! 396: } ! 397: ! 398: typedef struct ea_t { ! 399: int mode; ! 400: int reg; ! 401: int op_size; ! 402: struct ImmVal imm; ! 403: union Ext { ! 404: short ext; ! 405: struct { ! 406: int displacement : 8; ! 407: int ZERO : 3; ! 408: uint size : 1; ! 409: uint reg : 3; ! 410: uint d_or_a : 1; ! 411: } _; ! 412: } ext; ! 413: } ea_t; ! 414: ! 415: void wr_ea (ea_t *ea) ! 416: { ! 417: if (ea->mode == 5) { ! 418: if (ea->imm.has_label) error ("Relative not allowed."); ! 419: wr_short (ea->imm.val); ! 420: return; ! 421: } ! 422: if (ea->mode == 6) { ! 423: if (ea->imm.has_label) error ("Relative not allowed."); ! 424: wr_short (ea->ext.ext); ! 425: return; ! 426: } ! 427: if (ea->mode == 7) { ! 428: /* $xxx.w */ ! 429: if (ea->reg == 0) { ! 430: wr_short (ea->imm.val); ! 431: return; ! 432: } ! 433: /* $xxx.l */ ! 434: else if (ea->reg == 1) { ! 435: if (ea->imm.has_label) goto abs_lab32; ! 436: wr_int (ea->imm.val); ! 437: return; ! 438: } ! 439: /* immediate */ ! 440: else if (ea->reg == 4) { ! 441: if (ea->imm.has_label) { ! 442: if (ea->op_size != LONG) ! 443: error ("Relative not allowed."); ! 444: goto abs_lab32; ! 445: } ! 446: if (ea->op_size == LONG) { ! 447: wr_int (ea->imm.val); ! 448: } else if (ea->op_size == WORD) { ! 449: wr_short (ea->imm.val); ! 450: } else { ! 451: wr_short (ea->imm.val & 0xff); ! 452: } ! 453: return; ! 454: } ! 455: /* PC + offset */ ! 456: else if (ea->reg == 2) { ! 457: if (ea->imm.has_label) goto rel_lab16; ! 458: error ("Absolute value not allowed."); ! 459: return; ! 460: } ! 461: /* PC + INDEX + OFFSET */ ! 462: else if (ea->reg == 3) { ! 463: if (!ea->imm.has_label) error ("Absolute value not allowed."); ! 464: wr_short (ea->ext.ext); ! 465: add_fixup (get_bitpos()-1, BYTE, ea->imm.label); ! 466: return; ! 467: } ! 468: } ! 469: return; ! 470: rel_lab16: ! 471: /* resolve a relative 16-bit label (offset) */ ! 472: wr_short (0); ! 473: add_fixup (get_bitpos()-2, WORD, ea->imm.label); ! 474: return; ! 475: abs_lab32: ! 476: /* resolve an absolute 32-bit label */ ! 477: wr_int (0); ! 478: add_fixup (get_bitpos ()-4, LONG_FIXUP, ea->imm.label); ! 479: } ! 480: ! 481: char *get_reg (char *buf, int *reg_num, int flags) ! 482: { ! 483: int type; ! 484: while (isspace (*buf)) buf++; ! 485: if ((flags & F_AREG) && (buf[0] == 'a')) type = 8; ! 486: else if ((flags & F_DREG) && (buf[0] == 'd')) type = 0; ! 487: else goto err; ! 488: buf++; ! 489: if (sscanf (&buf[0], "%d", reg_num) != 1) goto err; ! 490: ! 491: *reg_num += type; ! 492: while (isdigit (*buf)) buf++; ! 493: return buf; ! 494: err: ! 495: error ("Expected a register."); ! 496: return NULL; ! 497: } ! 498: ! 499: char *get_ea (char *pos, ea_t *ea, int op_size, int flags) ! 500: { ! 501: int reg; ! 502: int size; ! 503: char *orig; ! 504: ea->imm.has_label = 0; ! 505: ea->op_size = op_size; ! 506: while (isspace (*pos)) pos++; ! 507: orig = pos; ! 508: if ((pos[0] == 'd') && isdigit (pos[1])) { ! 509: pos++; ! 510: if (sscanf (&pos[0], "%d", &ea->reg) != 1) goto poopdog; ! 511: ea->mode = 0; ! 512: if ((ea->reg < 0) || (ea->reg > 7)) goto poopdog; ! 513: while (isdigit (*pos)) pos++; ! 514: if (!(flags & F_DREG)) goto err; ! 515: return pos; ! 516: } ! 517: if ((pos[0] == 'a') && isdigit (pos[1])) { ! 518: pos++; ! 519: if (sscanf (&pos[0], "%d", &ea->reg) != 1) goto poopdog; ! 520: ea->mode = 1; ! 521: if ((ea->reg < 0) || (ea->reg > 7)) goto poopdog; ! 522: while (isdigit (*pos)) pos++; ! 523: if (!(flags & F_AREG)) goto err; ! 524: return pos; ! 525: } ! 526: poopdog: ! 527: pos = orig; ! 528: if ((*pos == '#') && (flags & F_IMM)) { ! 529: pos = get_imm (pos, &ea->imm, F_IMM); ! 530: check_range (&ea->imm.val, op_size); ! 531: ea->mode = 7; ! 532: ea->reg = 4; ! 533: return pos; ! 534: } ! 535: if ((flags & F_PRE) && (pos[0] == '-') && (pos[1] == '(')) { ! 536: pos += 2; ! 537: pos = get_reg (pos, &ea->reg, F_AREG); ! 538: check (')'); ! 539: ea->mode = 0x4; ! 540: return pos; ! 541: } ! 542: if ((flags & (F_IND | F_POST)) && (pos[0] == '(')) { ! 543: check ('('); ! 544: pos = get_reg (pos, &ea->reg, F_AREG); ! 545: check (')'); ! 546: if ((flags & F_POST) && (pos[0] == '+')) { ! 547: ea->mode = 3; ! 548: return ++pos; ! 549: } else if (flags & F_IND) { ! 550: ea->mode = 2; ! 551: return pos; ! 552: } else goto err; ! 553: } ! 554: if ((*pos == '$') || isdigit (*pos) || (*pos == '-') || isalpha (*pos)) { ! 555: if (isalpha (*pos)) { ! 556: pos = get_imm (pos, &ea->imm, 0); ! 557: } else if (*pos == '$') { ! 558: pos++; ! 559: if (sscanf (pos, "%x", &ea->imm.val) != 1) goto err; ! 560: while (isxdigit (*pos)) pos++; ! 561: } else { ! 562: if (sscanf (pos, "%d", &ea->imm.val) != 1) goto err; ! 563: if (*pos == '-') pos++; ! 564: while (isdigit (*pos)) pos++; ! 565: } ! 566: /* Immediate memory (not label) */ ! 567: if ((*pos == '.') && (flags & (F_MEM_W | F_MEM_L))) { ! 568: pos++; ! 569: size = get_size (*pos); ! 570: pos++; ! 571: ea->mode = 0x7; ! 572: if (size == WORD) { ! 573: ea->reg = 0; ! 574: if ((ea->imm.val < 0) || (ea->imm.val > 65535)) error ("Immediate value too large."); ! 575: } ! 576: else if (size == LONG) ea->reg = 1; ! 577: else error ("Bad size."); ! 578: return pos; ! 579: } ! 580: while (isspace (*pos)) pos++; ! 581: if (((*pos == ',') || (*pos == '\0')) && (flags & F_MEM_L)) { ! 582: /* Immed memory with label */ ! 583: ea->mode = 0x7; ! 584: ea->reg = 1; ! 585: return pos; ! 586: } ! 587: if (*pos != '(') goto err; ! 588: /* adr reg or pc indexed or offset */ ! 589: pos++; ! 590: if ((pos[0] == 'p') && (pos[1] == 'c')) { ! 591: /* pc relative */ ! 592: pos += 2; ! 593: if ((pos [0] == ')') && (flags & F_PC_OFFSET)) { ! 594: if ((ea->imm.val < -32768) || (ea->imm.val > 32767)) error ("Immediate value too large."); ! 595: ea->mode = 7; ! 596: ea->reg = 2; ! 597: return ++pos; ! 598: } ! 599: if (!(flags & F_PC_INDEX)) goto err; ! 600: check (','); ! 601: pos = get_reg (pos, ®, F_AREG | F_DREG); ! 602: ea->ext.ext = 0; ! 603: if (reg > 7) { ! 604: ea->ext._.reg = reg-8; ! 605: ea->ext._.d_or_a = 1; ! 606: } else { ! 607: ea->ext._.reg = reg; ! 608: ea->ext._.d_or_a = 0; ! 609: } ! 610: check ('.'); ! 611: if (pos[0] == 'l') { ! 612: ea->ext._.size = 1; ! 613: } else if (pos[0] == 'w') { ! 614: ea->ext._.size = 0; ! 615: } else error ("Index register must have size."); ! 616: pos++; ! 617: check (')'); ! 618: ea->mode = 7; ! 619: ea->reg = 3; ! 620: return pos; ! 621: } else { ! 622: /* adr with index/offset */ ! 623: pos = get_reg (pos, &ea->reg, F_AREG); ! 624: if ((flags & F_OFFSET) && (pos[0] == ')')) { ! 625: /* with offset only */ ! 626: if ((ea->imm.val < -32768) || (ea->imm.val > 32767)) error ("Immediate value too large."); ! 627: ea->mode = 5; ! 628: return ++pos; ! 629: } ! 630: if (!(flags & F_INDEX)) goto err; ! 631: check (','); ! 632: pos = get_reg (pos, ®, F_AREG | F_DREG); ! 633: if ((ea->imm.val < -128) || (ea->imm.val > 127)) error ("Immediate value too large."); ! 634: ea->ext.ext = 0; ! 635: ea->ext._.displacement = ea->imm.val; ! 636: if (reg > 7) { ! 637: ea->ext._.reg = reg-8; ! 638: ea->ext._.d_or_a = 1; ! 639: } else { ! 640: ea->ext._.reg = reg; ! 641: ea->ext._.d_or_a = 0; ! 642: } ! 643: check ('.'); ! 644: if (pos[0] == 'l') { ! 645: ea->ext._.size = 1; ! 646: } else if (pos[0] == 'w') { ! 647: ea->ext._.size = 0; ! 648: } else error ("Index register must have size."); ! 649: pos++; ! 650: check (')'); ! 651: ea->mode = 6; ! 652: return pos; ! 653: } ! 654: } ! 655: error ("Illegal effective address."); ! 656: err: ! 657: error ("Malformed effective address. Valid modes are: %s%s%s%s%s%s%s%s%s%s%s%s", ! 658: (flags & F_DREG ? "dreg " : ""), ! 659: (flags & F_AREG ? "areg " : ""), ! 660: (flags & F_IND ? "indirect " : ""), ! 661: (flags & F_POST ? "postincrement ": ""), ! 662: (flags & F_PRE ? "predecrement ": ""), ! 663: (flags & F_OFFSET ? "areg-offset ": ""), ! 664: (flags & F_OFFSET ? "areg-offset-index ": ""), ! 665: (flags & F_MEM_W ? "absolute.w ": ""), ! 666: (flags & F_MEM_L ? "absolute.l ": ""), ! 667: (flags & F_IMM ? "immediate ": ""), ! 668: (flags & F_PC_OFFSET ? "pc-relative ": ""), ! 669: (flags & F_PC_INDEX ? "pc-rel-index ": "")); ! 670: return NULL; ! 671: } ! 672: ! 673: int _reg_num (char *cunt) ! 674: { ! 675: int is_areg; ! 676: int num; ! 677: ! 678: if (cunt[0] == 'a') is_areg = 8; ! 679: else is_areg = 0; ! 680: cunt++; ! 681: ! 682: if (sscanf (cunt, "%d", &num) != 1) return -1; ! 683: num += is_areg; ! 684: ! 685: while (isdigit (*cunt)) cunt++; ! 686: if (isalpha (*cunt)) return -1; ! 687: return num; ! 688: } ! 689: ! 690: /* movem is a wanking cunt of doom */ ! 691: /* this is such a sinful mess :-) */ ! 692: char *parse_movem (char *pos, int size) ! 693: { ! 694: union Opcode op; ! 695: char *start = pos; ! 696: char lab1[LAB_LEN]; ! 697: int lo, hi; ! 698: /* d0-7,a0-7 */ ! 699: int regs[16]; ! 700: int dr = 0; /* reg to mem */ ! 701: ea_t ea; ! 702: memset (regs, 0, 16*sizeof(int)); ! 703: try_again: ! 704: if ((pos[0] == 'a') || (pos[0] == 'd')) { ! 705: more_to_come: ! 706: pos = rd_label (pos, lab1); ! 707: lo = _reg_num (lab1); ! 708: if (lo == -1) { ! 709: mess: ! 710: /* mem to reg */ ! 711: dr = 1; ! 712: pos = start; ! 713: pos = get_ea (pos, &ea, size, F_IND | F_POST | F_INDEX | F_OFFSET | F_MEM_W | F_MEM_L | F_PC_OFFSET | F_PC_INDEX); ! 714: if (pos[0] != ',') goto err; ! 715: pos++; ! 716: goto try_again; ! 717: } ! 718: ! 719: if (*pos == '-') { ! 720: /* range of fucking registers */ ! 721: pos++; ! 722: if (sscanf (pos, "%d", &hi) != 1) goto err; ! 723: pos++; ! 724: if ((hi < 0) || (hi > 7)) goto err; ! 725: if (lo > 7) hi += 8; ! 726: } else { ! 727: hi = lo; ! 728: } ! 729: for (; lo<=hi; lo++) regs[lo] = 1; ! 730: if (pos[0] == '/') { ! 731: pos++; ! 732: goto more_to_come; ! 733: } ! 734: } else { ! 735: goto mess; ! 736: } ! 737: if (!dr) { ! 738: /* reg to mem */ ! 739: if (pos[0] != ',') goto err; ! 740: pos++; ! 741: pos = get_ea (pos, &ea, size, F_IND | F_PRE | F_INDEX | F_OFFSET | F_MEM_W | F_MEM_L); ! 742: } ! 743: op.code = 0x4880; ! 744: op.movem.sz = (size == WORD ? 0 : 1); ! 745: op.movem.dr = dr; ! 746: op.movem.dest_reg = ea.reg; ! 747: op.movem.dest_mode = ea.mode; ! 748: wr_short (op.code); ! 749: ! 750: hi = 0; ! 751: if (ea.mode == 0x4) { ! 752: /* predecrement mode */ ! 753: for (lo=0; lo < 16; lo++) { ! 754: if (regs[15-lo]) hi |= (1<<lo); ! 755: } ! 756: } else { ! 757: for (lo=0; lo < 16; lo++) { ! 758: if (regs[lo]) hi |= (1<<lo); ! 759: } ! 760: } ! 761: wr_short (hi); ! 762: /* movem seems to count offsets relative to the ! 763: * register bitfield... */ ! 764: last_op_addr += 2; ! 765: wr_ea (&ea); ! 766: return pos; ! 767: err: ! 768: error ("your movem is all wanked up."); ! 769: return NULL; ! 770: } ! 771: ! 772: int asm_pass1 () ! 773: { ! 774: int i, reg, size; ! 775: union Opcode op; ! 776: struct ImmVal imm; ! 777: char lab1[LAB_LEN]; ! 778: char *equ_lab; ! 779: char *pos; ! 780: ea_t ea; ! 781: ea_t ea2; ! 782: ! 783: wr_short (0x601a); ! 784: wr_int (0); ! 785: wr_int (0); ! 786: wr_int (0); ! 787: wr_int (0); ! 788: wr_int (0); ! 789: wr_int (0); ! 790: wr_short (0); ! 791: ! 792: dict_init (&labels); ! 793: ! 794: while (fgets (buf, sizeof (buf), fin)) { ! 795: last_op_addr = get_bitpos (); ! 796: line_no++; ! 797: pos = &buf[0]; ! 798: /* comments */ ! 799: equ_lab = NULL; ! 800: while (isspace (*pos)) pos++; ! 801: if (*pos == '\0') continue; ! 802: if (*pos == '*') continue; ! 803: else if (isalpha (*pos)) { ! 804: equ_lab = pos; ! 805: pos = rd_label (pos, lab1); ! 806: if (*pos == ':') { ! 807: /* add label */ ! 808: add_label (lab1, L_ADDR, get_bitpos () - BASE); ! 809: if (dump_labels) { ! 810: printf ("0x%x: %s\n", get_bitpos () - BASE, lab1); ! 811: } ! 812: equ_lab = NULL; ! 813: pos++; ! 814: check_whitespace (); ! 815: if (*pos == '\0') continue; ! 816: } ! 817: while (isspace (*pos)) pos++; ! 818: } ! 819: /* EQU */ ! 820: if (strncmp (pos, "equ", 3) == 0) { ! 821: pos += 3; ! 822: check_whitespace(); ! 823: if (!equ_lab) error ("EQU without label."); ! 824: pos = get_imm (pos, &imm, F_NOLABELS); ! 825: add_label (lab1, L_CONST, imm.val); ! 826: continue; ! 827: } ! 828: if (equ_lab) { ! 829: pos = equ_lab; ! 830: equ_lab = NULL; ! 831: } ! 832: ! 833: /* DC.X */ ! 834: if (strncmp (pos, "dc.", 3) == 0) { ! 835: size = get_size (pos[3]); ! 836: pos += 4; ! 837: check_whitespace(); ! 838: if ((size == BYTE) && (*pos == '"')) { ! 839: thing: ! 840: pos++; ! 841: while (*pos != '"') { ! 842: wr_byte (*pos); ! 843: pos++; ! 844: } ! 845: /* double '""' escapes */ ! 846: pos++; ! 847: if (*pos == '"') { ! 848: wr_byte ('"'); ! 849: goto thing; ! 850: } ! 851: while (isspace (*pos)) pos++; ! 852: if (*pos != ',') { ! 853: check_end (pos); ! 854: continue; ! 855: } ! 856: pos++; ! 857: } ! 858: while (isdigit (*pos) || isalpha (*pos) || (*pos == '$')) { ! 859: pos = get_imm (pos, &imm, 0); ! 860: if (imm.has_label) { ! 861: switch (size) { ! 862: case BYTE: case WORD: error ("Labels may only be used with dc.l."); ! 863: case LONG: default: ! 864: wr_int (0); ! 865: add_fixup (get_bitpos()-4, LONG_FIXUP, imm.label); ! 866: break; ! 867: } ! 868: } else { ! 869: switch (size) { ! 870: case BYTE: wr_byte (imm.val); break; ! 871: case WORD: wr_short (imm.val); break; ! 872: case LONG: default: wr_int (imm.val); break; ! 873: } ! 874: } ! 875: while (isspace (*pos)) pos++; ! 876: if (*pos != ',') break; ! 877: pos++; ! 878: while (isspace (*pos)) pos++; ! 879: } ! 880: check_end (pos); ! 881: continue; ! 882: } ! 883: /* DS.X */ ! 884: if (strncmp (pos, "ds.", 3) == 0) { ! 885: size = get_size (pos[3]); ! 886: pos += 4; ! 887: check_whitespace(); ! 888: pos = get_imm (pos, &imm, F_NOLABELS); ! 889: check_end (pos); ! 890: for (i=0; i<imm.val; i++) { ! 891: if (size == BYTE) wr_byte (0); ! 892: else if (size == WORD) wr_short (0); ! 893: else wr_int (0); ! 894: } ! 895: continue; ! 896: } ! 897: /* odd address checking */ ! 898: if (last_op_addr & 0x1) error ("Odd address."); ! 899: /* ADDQ/SUBQ */ ! 900: if ((strncmp (pos, "addq", 4)==0) || ! 901: (strncmp (pos, "subq", 4)==0)) { ! 902: op.code = 0x5000; ! 903: op.addq.issub = (pos[0] == 's'); ! 904: pos += 4; ! 905: check ('.'); ! 906: size = get_size (pos[0]); ! 907: pos++; ! 908: check_whitespace(); ! 909: pos = get_imm (pos, &imm, F_NOLABELS | F_IMM); ! 910: if ((imm.val < 1) || (imm.val > 8)) error ("Immediate value too large."); ! 911: if (imm.val == 8) imm.val = 0; ! 912: check (','); ! 913: pos = get_ea (pos, &ea, LONG, F_DREG | F_AREG | F_IND | F_POST | F_PRE | F_INDEX | F_OFFSET | F_MEM_W | F_MEM_L); ! 914: if ((size == BYTE) && (ea.mode == 1)) error ("Bad size for address reg direct."); ! 915: check_end (pos); ! 916: op.addq.dest_reg = ea.reg; ! 917: op.addq.dest_mode = ea.mode; ! 918: op.addq.size = size; ! 919: op.addq.data = imm.val; ! 920: wr_short (op.code); ! 921: wr_ea (&ea); ! 922: continue; ! 923: } ! 924: /* NOP */ ! 925: if (strncmp (pos, "nop", 3) == 0) { ! 926: pos += 3; ! 927: check_end (pos); ! 928: wr_short (0x4e71); ! 929: continue; ! 930: } ! 931: /* NOT/NEGX/NEG */ ! 932: if (strncmp (pos, "not", 3) == 0) { ! 933: pos += 3; ! 934: check ('.'); ! 935: size = get_size (pos[0]); ! 936: pos++; ! 937: check_whitespace(); ! 938: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG); ! 939: check_end (pos); ! 940: op.code = 0x4600; ! 941: op.type1.size = size; ! 942: op.type1.ea_reg = ea.reg; ! 943: op.type1.ea_mode = ea.mode; ! 944: wr_short (op.code); ! 945: wr_ea (&ea); ! 946: continue; ! 947: } ! 948: if (strncmp (pos, "negx", 4) == 0) { ! 949: pos += 4; ! 950: check ('.'); ! 951: size = get_size (pos[0]); ! 952: pos++; ! 953: check_whitespace(); ! 954: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG); ! 955: check_end (pos); ! 956: op.code = 0x4000; ! 957: op.type1.size = size; ! 958: op.type1.ea_reg = ea.reg; ! 959: op.type1.ea_mode = ea.mode; ! 960: wr_short (op.code); ! 961: wr_ea (&ea); ! 962: continue; ! 963: } ! 964: if (strncmp (pos, "neg", 3) == 0) { ! 965: pos += 3; ! 966: check ('.'); ! 967: size = get_size (pos[0]); ! 968: pos++; ! 969: check_whitespace(); ! 970: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG); ! 971: check_end (pos); ! 972: op.code = 0x4400; ! 973: op.type1.size = size; ! 974: op.type1.ea_reg = ea.reg; ! 975: op.type1.ea_mode = ea.mode; ! 976: wr_short (op.code); ! 977: wr_ea (&ea); ! 978: continue; ! 979: } ! 980: /* DIVS/DIVU */ ! 981: if (strncmp (pos, "div", 3) == 0) { ! 982: pos += 3; ! 983: if (pos[0] == 's') op.code = 0x81c0; ! 984: else op.code = 0x80c0; ! 985: pos++; ! 986: check_whitespace(); ! 987: pos = get_ea (pos, &ea, WORD, F_ALL_NOAREG); ! 988: check (','); ! 989: pos = get_reg (pos, &i, F_DREG); ! 990: check_end (pos); ! 991: op.type2.reg = i; ! 992: op.type2.ea_mode = ea.mode; ! 993: op.type2.ea_reg = ea.reg; ! 994: wr_short (op.code); ! 995: wr_ea (&ea); ! 996: continue; ! 997: } ! 998: /* MULS/MULU */ ! 999: if (strncmp (pos, "mul", 3) == 0) { ! 1000: pos += 3; ! 1001: if (pos[0] == 's') op.code = 0xc1c0; ! 1002: else op.code = 0xc0c0; ! 1003: pos++; ! 1004: check_whitespace(); ! 1005: pos = get_ea (pos, &ea, WORD, F_ALL_NOAREG); ! 1006: check (','); ! 1007: pos = get_reg (pos, &i, F_DREG); ! 1008: check_end (pos); ! 1009: op.type2.reg = i; ! 1010: op.type2.ea_mode = ea.mode; ! 1011: op.type2.ea_reg = ea.reg; ! 1012: wr_short (op.code); ! 1013: wr_ea (&ea); ! 1014: continue; ! 1015: } ! 1016: /* ADDI/SUBI */ ! 1017: if ((strncmp (pos, "addi", 4) == 0) || ! 1018: (strncmp (pos, "subi", 4) == 0)) { ! 1019: if (pos[0] == 'a') op.code = 0x0600; ! 1020: else op.code = 0x0400; ! 1021: pos += 4; ! 1022: check ('.'); ! 1023: size = get_size (pos[0]); ! 1024: pos++; ! 1025: check_whitespace(); ! 1026: pos = get_ea (pos, &ea2, size, F_IMM); ! 1027: check (','); ! 1028: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG); ! 1029: check_end (pos); ! 1030: op.type1.size = size; ! 1031: op.type1.ea_reg = ea.reg; ! 1032: op.type1.ea_mode = ea.mode; ! 1033: wr_short (op.code); ! 1034: if (size == BYTE) { ! 1035: wr_short (ea2.imm.val & 0xff); ! 1036: } else if (size == WORD) { ! 1037: wr_short (ea2.imm.val); ! 1038: } else { ! 1039: wr_int (ea2.imm.val); ! 1040: } ! 1041: wr_ea (&ea); ! 1042: continue; ! 1043: } ! 1044: /* ADDA/SUBA */ ! 1045: if ((strncmp (pos, "adda", 4) == 0) || ! 1046: (strncmp (pos, "suba", 4) == 0)) { ! 1047: if (pos[0] == 'a') op.code = 0xd000; ! 1048: else op.code = 0x9000; ! 1049: pos += 4; ! 1050: check ('.'); ! 1051: size = get_size (pos[0]); ! 1052: if (size == BYTE) error ("Crap size for adda."); ! 1053: pos++; ! 1054: check_whitespace(); ! 1055: pos = get_ea (pos, &ea, size, F_ALL); ! 1056: check (','); ! 1057: pos = get_reg (pos, ®, F_AREG); ! 1058: check_end (pos); ! 1059: op.type2.reg = reg; ! 1060: if (size == WORD) size = 3; ! 1061: else size = 7; ! 1062: op.type2.op_mode = size; ! 1063: op.type2.ea_reg = ea.reg; ! 1064: op.type2.ea_mode = ea.mode; ! 1065: wr_short (op.code); ! 1066: wr_ea (&ea); ! 1067: continue; ! 1068: } ! 1069: /* ADDX/SUBX */ ! 1070: if ((strncmp (pos, "addx", 4) == 0) || ! 1071: (strncmp (pos, "subx", 4) == 0)) { ! 1072: if (pos[0] == 'a') op.code = 0xd100; ! 1073: else op.code = 0x9100; ! 1074: pos += 4; ! 1075: check ('.'); ! 1076: size = get_size (pos[0]); ! 1077: op.addx.size = size; ! 1078: pos++; ! 1079: check_whitespace(); ! 1080: pos = get_ea (pos, &ea, size, F_DREG | F_PRE); ! 1081: if (ea.mode == 0) { ! 1082: /* Dn,Dn mode */ ! 1083: check (','); ! 1084: op.addx.src_reg = ea.reg; ! 1085: op.addx.rm = 0; ! 1086: pos = get_reg (pos, &i, F_DREG); ! 1087: check_end (pos); ! 1088: op.addx.dest_reg = i; ! 1089: wr_short (op.code); ! 1090: } else { ! 1091: /* -(An),-(An) mode */ ! 1092: check (','); ! 1093: op.addx.src_reg = ea.reg; ! 1094: op.addx.rm = 1; ! 1095: pos = get_ea (pos, &ea, size, F_PRE); ! 1096: op.addx.dest_reg = ea.reg; ! 1097: wr_short (op.code); ! 1098: } ! 1099: check_end (pos); ! 1100: continue; ! 1101: } ! 1102: /* ADD/SUB */ ! 1103: if ((strncmp (pos, "add", 3) == 0) || ! 1104: (strncmp (pos, "sub", 3) == 0)) { ! 1105: if (pos[0] == 'a') op.code = 0xd000; ! 1106: else op.code = 0x9000; ! 1107: pos += 3; ! 1108: check ('.'); ! 1109: size = get_size (pos[0]); ! 1110: pos++; ! 1111: check_whitespace(); ! 1112: pos = get_ea (pos, &ea, size, F_ALL); ! 1113: check (','); ! 1114: pos = get_ea (pos, &ea2, size, F_DREG | F_IND | F_POST | F_PRE | F_OFFSET | F_INDEX | F_MEM_W | F_MEM_L); ! 1115: if (ea2.mode == 0) { ! 1116: /* data reg dest */ ! 1117: op.type2.reg = ea2.reg; ! 1118: op.type2.op_mode = size; ! 1119: op.type2.ea_reg = ea.reg; ! 1120: op.type2.ea_mode = ea.mode; ! 1121: wr_short (op.code); ! 1122: wr_ea (&ea); ! 1123: } else { ! 1124: /* ea dest */ ! 1125: if (ea.mode != 0) error ("One operand must be a data register."); ! 1126: op.type2.reg = ea.reg; ! 1127: op.type2.op_mode = size+4; ! 1128: op.type2.ea_reg = ea2.reg; ! 1129: op.type2.ea_mode = ea2.mode; ! 1130: wr_short (op.code); ! 1131: wr_ea (&ea2); ! 1132: } ! 1133: check_end (pos); ! 1134: continue; ! 1135: } ! 1136: /* BCHG/BCLR/BSET/BTST */ ! 1137: if ((strncmp (pos, "bchg", 4)==0) || ! 1138: (strncmp (pos, "bclr", 4)==0) || ! 1139: (strncmp (pos, "bset", 4)==0) || ! 1140: (strncmp (pos, "btst", 4)==0)) { ! 1141: int type; ! 1142: switch (pos[2]) { ! 1143: /* bchg */ ! 1144: case 'h': type = 0; break; ! 1145: /* bclr */ ! 1146: case 'l': type = 1; break; ! 1147: /* bset */ ! 1148: case 'e': type = 2; break; ! 1149: /* btst */ ! 1150: default: case 's': type = 3; break; ! 1151: } ! 1152: pos += 4; ! 1153: check_whitespace(); ! 1154: pos = get_ea (pos, &ea, BYTE, F_IMM | F_DREG); ! 1155: if (ea.mode == 0) { ! 1156: /* Dn,<ea> mode */ ! 1157: switch (type) { ! 1158: case 0: op.code = 0x0140; break; ! 1159: case 1: op.code = 0x0180; break; ! 1160: case 2: op.code = 0x01c0; break; ! 1161: case 3: op.code = 0x0100; break; ! 1162: } ! 1163: op.type2.reg = ea.reg; ! 1164: check (','); ! 1165: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG); ! 1166: op.type2.ea_reg = ea.reg; ! 1167: op.type2.ea_mode = ea.mode; ! 1168: wr_short (op.code); ! 1169: wr_ea (&ea); ! 1170: continue; ! 1171: } else { ! 1172: /* IMM,<ea> mode */ ! 1173: check_range (&ea.imm.val, BYTE); ! 1174: imm.val = ea.imm.val; ! 1175: switch (type) { ! 1176: case 0: op.code = 0x0840; break; ! 1177: case 1: op.code = 0x0880; break; ! 1178: case 2: op.code = 0x08c0; break; ! 1179: case 3: op.code = 0x0800; break; ! 1180: } ! 1181: check (','); ! 1182: if (type == 3) { ! 1183: pos = get_ea (pos, &ea, size, F_DREG | F_IND | F_POST | F_PRE | F_OFFSET | F_INDEX | F_MEM_W | F_MEM_L | F_PC_OFFSET | F_PC_INDEX); ! 1184: } else { ! 1185: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG); ! 1186: } ! 1187: op.type2.ea_mode = ea.mode; ! 1188: op.type2.ea_reg = ea.reg; ! 1189: wr_short (op.code); ! 1190: wr_short (imm.val & 0xff); ! 1191: wr_ea (&ea); ! 1192: continue; ! 1193: } ! 1194: check_end (pos); ! 1195: continue; ! 1196: } ! 1197: /* ASx/LSx/ROx ROXx */ ! 1198: if ((strncmp (pos, "ls", 2) == 0) || ! 1199: (strncmp (pos, "as", 2) == 0) || ! 1200: (strncmp (pos, "ro", 2) == 0)) { ! 1201: char dir; ! 1202: int type; ! 1203: dir = pos[2]; ! 1204: if (pos[0] == 'a') type = 0; ! 1205: else if (pos[0] == 'l') type = 1; ! 1206: else if (pos[0] == 'r') { ! 1207: if (pos[2] == 'x') { ! 1208: type = 2; ! 1209: dir = pos[3]; ! 1210: } ! 1211: else type = 3; ! 1212: } else { ! 1213: goto blork; ! 1214: } ! 1215: if ((dir != 'l') && (dir != 'r')) goto blork; ! 1216: dir = (dir == 'l' ? 1 : 0); ! 1217: while (isalpha (*pos)) pos++; ! 1218: check ('.'); ! 1219: size = get_size (pos[0]); ! 1220: pos++; ! 1221: check_whitespace(); ! 1222: pos = get_ea (pos, &ea, size, F_DREG | F_IND | F_POST | F_PRE | F_OFFSET | F_INDEX | F_MEM_W | F_MEM_L | F_IMM); ! 1223: if (ea.mode == 0) { ! 1224: /* data reg type */ ! 1225: check (','); ! 1226: pos = get_reg (pos, ®, F_DREG); ! 1227: check_end (pos); ! 1228: if (type == 1) op.code = 0xe008; ! 1229: else if (type == 0) op.code = 0xe000; ! 1230: else if (type == 2) op.code = 0xe010; ! 1231: else op.code = 0xe018; ! 1232: op.ASx.count_reg = ea.reg; ! 1233: op.ASx.dr = dir; ! 1234: op.ASx.size = size; ! 1235: op.ASx.ir = 1; ! 1236: op.ASx.reg = reg; ! 1237: wr_short (op.code); ! 1238: continue; ! 1239: } else if ((ea.mode == 7) && (ea.reg == 4)) { ! 1240: /* imm,Dn type */ ! 1241: check (','); ! 1242: pos = get_reg (pos, ®, F_DREG); ! 1243: check_end (pos); ! 1244: if (type == 1) op.code = 0xe008; ! 1245: else if (type == 0) op.code = 0xe000; ! 1246: else if (type == 2) op.code = 0xe010; ! 1247: else op.code = 0xe018; ! 1248: if ((ea.imm.val < 1) || (ea.imm.val > 8)) error ("Bad immediate value."); ! 1249: if (ea.imm.val == 8) ea.imm.val = 0; ! 1250: op.ASx.count_reg = ea.imm.val; ! 1251: op.ASx.dr = dir; ! 1252: op.ASx.size = size; ! 1253: op.ASx.ir = 0; ! 1254: op.ASx.reg = reg; ! 1255: wr_short (op.code); ! 1256: continue; ! 1257: } else { ! 1258: /* ea mode */ ! 1259: if (size != WORD) error ("Illegal size."); ! 1260: check_end (pos); ! 1261: if (type == 1) op.code = 0xe2c0; ! 1262: else if (type == 0) op.code = 0xe0c0; ! 1263: else if (type == 2) op.code = 0xe4c0; ! 1264: else op.code = 0xe6c0; ! 1265: op.ASx.dr = dir; ! 1266: op.type1.ea_reg = ea.reg; ! 1267: op.type1.ea_mode = ea.mode; ! 1268: wr_short (op.code); ! 1269: wr_ea (&ea); ! 1270: continue; ! 1271: } ! 1272: continue; ! 1273: } ! 1274: blork: ! 1275: /* ANDI/EORI/ORI */ ! 1276: if ((strncmp (pos, "andi", 4) == 0) || ! 1277: (strncmp (pos, "eori", 4) == 0) || ! 1278: (strncmp (pos, "ori", 3) == 0)) { ! 1279: if (pos[0] == 'a') { ! 1280: op.code = 0x0200; ! 1281: } else if (pos[0] == 'e') { ! 1282: op.code = 0x0a00; ! 1283: } else { ! 1284: op.code = 0x0000; ! 1285: } ! 1286: while (isalpha (*pos)) pos++; ! 1287: check ('.'); ! 1288: size = get_size (pos[0]); ! 1289: pos++; ! 1290: check_whitespace(); ! 1291: pos = get_imm (pos, &imm, F_NOLABELS | F_IMM); ! 1292: check_range (&imm.val, size); ! 1293: check (','); ! 1294: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG); ! 1295: check_end (pos); ! 1296: op.type1.ea_reg = ea.reg; ! 1297: op.type1.ea_mode = ea.mode; ! 1298: op.type1.size = size; ! 1299: wr_short (op.code); ! 1300: if (size == BYTE) { ! 1301: wr_short (imm.val & 0xff); ! 1302: } else if (size == WORD) { ! 1303: wr_short (imm.val); ! 1304: } else { ! 1305: wr_int (imm.val); ! 1306: } ! 1307: wr_ea (&ea); ! 1308: continue; ! 1309: } ! 1310: /* AND/OR */ ! 1311: if ((strncmp (pos, "and", 3) == 0) || ! 1312: (strncmp (pos, "or", 2) == 0)) { ! 1313: if (pos[0] == 'a') op.code = 0xc000; ! 1314: else op.code = 0x8000; ! 1315: while (isalpha (*pos)) pos++; ! 1316: check ('.'); ! 1317: size = get_size (pos[0]); ! 1318: pos++; ! 1319: check_whitespace(); ! 1320: pos = get_ea (pos, &ea, size, F_ALL_NOAREG); ! 1321: check (','); ! 1322: pos = get_ea (pos, &ea2, size, F_NOIMM_NOPC_NOAREG); ! 1323: check_end (pos); ! 1324: if (ea2.mode == 0) { ! 1325: /* data reg dest */ ! 1326: op.type2.reg = ea2.reg; ! 1327: op.type2.op_mode = size; ! 1328: op.type2.ea_reg = ea.reg; ! 1329: op.type2.ea_mode = ea.mode; ! 1330: wr_short (op.code); ! 1331: wr_ea (&ea); ! 1332: } else { ! 1333: /* ea dest */ ! 1334: if (ea.mode != 0) error ("One operand must be a data register."); ! 1335: op.type2.reg = ea.reg; ! 1336: op.type2.op_mode = size+4; ! 1337: op.type2.ea_reg = ea2.reg; ! 1338: op.type2.ea_mode = ea2.mode; ! 1339: wr_short (op.code); ! 1340: wr_ea (&ea2); ! 1341: } ! 1342: continue; ! 1343: } ! 1344: /* EOR */ ! 1345: if (strncmp (pos, "eor", 3) == 0) { ! 1346: op.code = 0xb000; ! 1347: pos += 3; ! 1348: check ('.'); ! 1349: size = get_size (pos[0]); ! 1350: pos++; ! 1351: check_whitespace(); ! 1352: pos = get_reg (pos, ®, F_DREG); ! 1353: check (','); ! 1354: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG); ! 1355: check_end (pos); ! 1356: op.type2.reg = reg; ! 1357: size += 4; ! 1358: op.type2.op_mode = size; ! 1359: op.type2.ea_reg = ea.reg; ! 1360: op.type2.ea_mode = ea.mode; ! 1361: wr_short (op.code); ! 1362: wr_ea (&ea); ! 1363: continue; ! 1364: } ! 1365: /* SWAP */ ! 1366: if (strncmp (pos, "swap", 4) == 0) { ! 1367: pos += 4; ! 1368: pos = get_reg (pos, ®, F_DREG); ! 1369: op.code = 0x4840; ! 1370: op.type2.ea_reg = reg; ! 1371: check_end (pos); ! 1372: wr_short (op.code); ! 1373: continue; ! 1374: } ! 1375: /* BSR */ ! 1376: if (strncmp (pos, "bsr", 3) == 0) { ! 1377: pos += 3; ! 1378: check ('.'); ! 1379: size = pos[0]; ! 1380: pos++; ! 1381: check_whitespace(); ! 1382: pos = rd_label (pos, lab1); ! 1383: check_end (pos); ! 1384: op.code = 0x6100; ! 1385: wr_short (op.code); ! 1386: if (size == 's') { ! 1387: add_fixup (get_bitpos()-1, BYTE, lab1); ! 1388: } else if (size == 'w') { ! 1389: wr_short (0); ! 1390: add_fixup (get_bitpos()-2, WORD, lab1); ! 1391: } else { ! 1392: error ("Invalid size '.%c'.", size); ! 1393: } ! 1394: continue; ! 1395: } ! 1396: /* Bcc.S */ ! 1397: if (pos[0] == 'b') { ! 1398: for (i=0; i<16; i++) { ! 1399: if (Bcc_str [i] == NULL) continue; ! 1400: if (strncmp (&pos[1], Bcc_str[i], 2)==0) break; ! 1401: } ! 1402: if (i==16) goto fuckit; ! 1403: pos += 3; ! 1404: check ('.'); ! 1405: size = pos[0]; ! 1406: pos++; ! 1407: check_whitespace(); ! 1408: pos = rd_label (pos, lab1); ! 1409: check_end (pos); ! 1410: op.code = 0x6000 | (i<<8); ! 1411: wr_short (op.code); ! 1412: if (size == 's') { ! 1413: add_fixup (get_bitpos()-1, BYTE, lab1); ! 1414: } else if (size == 'w') { ! 1415: wr_short (0); ! 1416: add_fixup (get_bitpos()-2, WORD, lab1); ! 1417: } else { ! 1418: error ("Invalid size '.%c'.", size); ! 1419: } ! 1420: continue; ! 1421: } ! 1422: /* DBcc */ ! 1423: if ((pos[0] == 'd') && (pos[1] == 'b')) { ! 1424: pos = rd_label (&pos[2], lab1); ! 1425: for (i=0; i<16; i++) { ! 1426: if (strncmp (lab1, DBcc_str[i], 2)==0) break; ! 1427: } ! 1428: if (i==16) { ! 1429: if (strncmp (lab1, "ra", 2)==0) { ! 1430: i = 1; ! 1431: } else { ! 1432: goto fuckit; ! 1433: } ! 1434: } ! 1435: while (isalpha (*pos)) pos++; ! 1436: check_whitespace(); ! 1437: pos = get_reg (pos, ®, F_DREG); ! 1438: check (','); ! 1439: pos = rd_label (pos, lab1); ! 1440: check_end (pos); ! 1441: op.code = 0x50c8; ! 1442: op.DBcc.reg = reg; ! 1443: op.DBcc.cond = i; ! 1444: wr_short (op.code); ! 1445: wr_short (0); ! 1446: add_fixup (get_bitpos()-2, WORD, lab1); ! 1447: continue; ! 1448: } ! 1449: fuckit: ! 1450: /* CLR */ ! 1451: if (strncmp (pos, "clr", 3) == 0) { ! 1452: pos += 3; ! 1453: check ('.'); ! 1454: size = get_size (pos[0]); ! 1455: pos++; ! 1456: check_whitespace(); ! 1457: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG); ! 1458: check_end (pos); ! 1459: op.code = 0x4200; ! 1460: op.type1.size = size; ! 1461: op.type1.ea_reg = ea.reg; ! 1462: op.type1.ea_mode = ea.mode; ! 1463: wr_short (op.code); ! 1464: wr_ea (&ea); ! 1465: continue; ! 1466: } ! 1467: /* CMPI */ ! 1468: if (strncmp (pos, "cmpi", 4) == 0) { ! 1469: pos += 4; ! 1470: check ('.'); ! 1471: size = get_size (*pos); ! 1472: pos++; ! 1473: check_whitespace(); ! 1474: pos = get_imm (pos, &imm, F_NOLABELS | F_IMM); ! 1475: check_range (&imm.val, size); ! 1476: check (','); ! 1477: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG); ! 1478: check_end (pos); ! 1479: op.code = 0x0c00; ! 1480: op.type1.ea_reg = ea.reg; ! 1481: op.type1.ea_mode = ea.mode; ! 1482: op.type1.size = size; ! 1483: wr_short (op.code); ! 1484: if (size == BYTE) { ! 1485: wr_short (imm.val & 0xff); ! 1486: } else if (size == WORD) { ! 1487: wr_short (imm.val); ! 1488: } else { ! 1489: wr_int (imm.val); ! 1490: } ! 1491: wr_ea (&ea); ! 1492: continue; ! 1493: } ! 1494: /* CMPA */ ! 1495: if (strncmp (pos, "cmpa", 4) == 0) { ! 1496: pos += 4; ! 1497: check ('.'); ! 1498: size = get_size (*pos); ! 1499: pos++; ! 1500: if (size == BYTE) error ("Size must be word or long."); ! 1501: check_whitespace(); ! 1502: pos = get_ea (pos, &ea, size, F_ALL); ! 1503: check (','); ! 1504: pos = get_reg (pos, &i, F_AREG); ! 1505: check_end (pos); ! 1506: ! 1507: op.code = 0xb000; ! 1508: op.type2.reg = i; ! 1509: op.type2.op_mode = (size == WORD ? 3 : 7); ! 1510: op.type2.ea_mode = ea.mode; ! 1511: op.type2.ea_reg = ea.reg; ! 1512: wr_short (op.code); ! 1513: wr_ea (&ea); ! 1514: continue; ! 1515: } ! 1516: /* CMPM */ ! 1517: if (strncmp (pos, "cmpm", 4) == 0) { ! 1518: pos += 4; ! 1519: check ('.'); ! 1520: size = get_size (*pos); ! 1521: pos++; ! 1522: check_whitespace (); ! 1523: pos = get_ea (pos, &ea, size, F_POST); ! 1524: op.code = 0xb108; ! 1525: op.cmpm.src_reg = ea.reg; ! 1526: op.cmpm.size = size; ! 1527: check (','); ! 1528: pos = get_ea (pos, &ea, size, F_POST); ! 1529: op.cmpm.dest_reg = ea.reg; ! 1530: wr_short (op.code); ! 1531: continue; ! 1532: } ! 1533: /* CMP */ ! 1534: if (strncmp (pos, "cmp", 3) == 0) { ! 1535: pos += 3; ! 1536: check ('.'); ! 1537: size = get_size (*pos); ! 1538: pos++; ! 1539: check_whitespace(); ! 1540: pos = get_ea (pos, &ea, size, F_ALL); ! 1541: check (','); ! 1542: if ((size == BYTE) && (ea.mode == 0x1)) ! 1543: error ("Bad size for address register gropery."); ! 1544: pos = get_reg (pos, &i, F_DREG); ! 1545: check_end (pos); ! 1546: ! 1547: op.code = 0xb000; ! 1548: op.type2.reg = i; ! 1549: op.type2.op_mode = size; ! 1550: op.type2.ea_mode = ea.mode; ! 1551: op.type2.ea_reg = ea.reg; ! 1552: wr_short (op.code); ! 1553: wr_ea (&ea); ! 1554: continue; ! 1555: } ! 1556: /* EXG */ ! 1557: if (strncmp (pos, "exg", 3) == 0) { ! 1558: pos += 3; ! 1559: op.code = 0xc100; ! 1560: check_whitespace(); ! 1561: pos = get_reg (pos, ®, F_DREG | F_AREG); ! 1562: check (','); ! 1563: if (reg > 7) { ! 1564: /* Ax,Ay mode */ ! 1565: op.exg.op_mode = 0x9; ! 1566: op.exg.src_reg = reg; ! 1567: pos = get_reg (pos, ®, F_AREG); ! 1568: op.exg.dest_reg = reg; ! 1569: } else { ! 1570: /* Dx,Xn mode */ ! 1571: op.exg.src_reg = reg; ! 1572: pos = get_reg (pos, ®, F_AREG | F_DREG); ! 1573: if (reg > 7) { ! 1574: op.exg.op_mode = 0x11; ! 1575: } else { ! 1576: op.exg.op_mode = 0x8; ! 1577: } ! 1578: op.exg.dest_reg = reg; ! 1579: } ! 1580: check_end (pos); ! 1581: wr_short (op.code); ! 1582: continue; ! 1583: } ! 1584: /* EXT */ ! 1585: if (strncmp (pos, "ext", 3) == 0) { ! 1586: pos += 3; ! 1587: check ('.'); ! 1588: size = get_size (pos[0]); ! 1589: pos++; ! 1590: check_whitespace(); ! 1591: if (size == BYTE) error ("Ext dislikes bytes."); ! 1592: pos = get_reg (pos, ®, F_DREG); ! 1593: check_end (pos); ! 1594: op.code = 0x4800; ! 1595: op.type2.ea_reg = reg; ! 1596: op.type2.op_mode = size+1; ! 1597: wr_short (op.code); ! 1598: continue; ! 1599: } ! 1600: ! 1601: ! 1602: /* MOVEM */ ! 1603: if (strncmp (pos, "movem.", 6)==0) { ! 1604: pos += 6; ! 1605: size = get_size (pos[0]); ! 1606: pos++; ! 1607: if (size == BYTE) error ("Movem dislikes bytes."); ! 1608: check_whitespace(); ! 1609: /* register to memory */ ! 1610: pos = parse_movem (pos, size); ! 1611: check_end (pos); ! 1612: continue; ! 1613: } ! 1614: /* RTE */ ! 1615: if (strncmp (pos, "rte", 3) == 0) { ! 1616: check_end (&pos[3]); ! 1617: wr_short (0x4e73); ! 1618: continue; ! 1619: } ! 1620: /* RTS */ ! 1621: if (strncmp (pos, "rts", 3) == 0) { ! 1622: check_end (&pos[3]); ! 1623: wr_short (0x4e75); ! 1624: continue; ! 1625: } ! 1626: /* ILLEGAL */ ! 1627: if (strncmp (pos, "illegal", 7) == 0) { ! 1628: check_end (&pos[7]); ! 1629: wr_short (0x4afc); ! 1630: continue; ! 1631: } ! 1632: /* HOSTCALL -- Not 68000 */ ! 1633: if (strncmp (pos, "hostcall", 8) == 0) { ! 1634: pos += 8; ! 1635: check_end (pos); ! 1636: wr_short (0x000a); ! 1637: continue; ! 1638: } ! 1639: if (strncmp (pos, "hcall", 5) == 0) { ! 1640: pos += 5; ! 1641: check_whitespace(); ! 1642: pos = get_imm (pos, &imm, F_IMM | F_NOLABELS); ! 1643: check_end (pos); ! 1644: check_range (&imm.val, WORD); ! 1645: wr_short (0x000b); ! 1646: wr_short (imm.val); ! 1647: continue; ! 1648: } ! 1649: /* RESET */ ! 1650: if (strncmp (pos, "reset", 5) == 0) { ! 1651: check_end (&pos[5]); ! 1652: wr_short (0x4e70); ! 1653: continue; ! 1654: } ! 1655: /* TRAP */ ! 1656: if (strncmp (pos, "trap", 4) == 0) { ! 1657: /* TRAPV */ ! 1658: if (pos[4] == 'v') { ! 1659: check_end (&pos[5]); ! 1660: wr_short (0x4e76); ! 1661: continue; ! 1662: } ! 1663: pos += 4; ! 1664: check_whitespace(); ! 1665: pos = get_imm (pos, &imm, F_IMM | F_NOLABELS); ! 1666: check_end (pos); ! 1667: if ((imm.val < 0) || (imm.val > 15)) { ! 1668: error ("Trap vector out of range."); ! 1669: continue; ! 1670: } ! 1671: wr_short (0x4e40 | imm.val); ! 1672: continue; ! 1673: } ! 1674: /* LINK */ ! 1675: if (strncmp (pos, "link", 4) == 0) { ! 1676: pos += 4; ! 1677: check_whitespace(); ! 1678: pos = get_reg (pos, ®, F_AREG); ! 1679: check (','); ! 1680: pos = get_imm (pos, &imm, F_IMM | F_NOLABELS); ! 1681: check_end (pos); ! 1682: check_range (&imm.val, WORD); ! 1683: op.code = 0x4e50; ! 1684: op.type1.ea_reg = reg; ! 1685: wr_short (op.code); ! 1686: wr_short (imm.val); ! 1687: continue; ! 1688: } ! 1689: /* UNLK */ ! 1690: if (strncmp (pos, "unlk", 4) == 0) { ! 1691: pos += 4; ! 1692: check_whitespace(); ! 1693: pos = get_reg (pos, ®, F_AREG); ! 1694: check_end (pos); ! 1695: op.code = 0x4e58; ! 1696: op.type1.ea_reg = reg; ! 1697: wr_short (op.code); ! 1698: continue; ! 1699: } ! 1700: /* MOVEQ */ ! 1701: if (strncmp (pos, "moveq", 5) == 0){ ! 1702: pos += 5; ! 1703: check_whitespace(); ! 1704: pos = get_imm (pos, &imm, F_NOLABELS | F_IMM); ! 1705: check_range (&imm.val, BYTE); ! 1706: check (','); ! 1707: pos = get_ea (pos, &ea, LONG, F_DREG); ! 1708: check_end (pos); ! 1709: op.code = 0x7000; ! 1710: op.moveq.reg = ea.reg; ! 1711: op.moveq.data = imm.val; ! 1712: wr_short (op.code); ! 1713: continue; ! 1714: } ! 1715: /* MOVEA */ ! 1716: if (strncmp (pos, "movea.", 6) == 0) { ! 1717: pos += 6; ! 1718: size = get_size (pos[0]); ! 1719: pos++; ! 1720: check_whitespace(); ! 1721: pos = get_ea (pos, &ea, size, F_ALL); ! 1722: check (','); ! 1723: pos = get_reg (pos, &i, F_AREG); ! 1724: check_end (pos); ! 1725: is_movea: ! 1726: if (size == BYTE) error ("Illegal size."); ! 1727: size = move_size[size]; ! 1728: op.code = 0; ! 1729: op.move.size = size; ! 1730: op.move.dest_reg = i; ! 1731: op.move.dest_mode = 1; ! 1732: op.move.src_reg = ea.reg; ! 1733: op.move.src_mode = ea.mode; ! 1734: wr_short (op.code); ! 1735: wr_ea (&ea); ! 1736: continue; ! 1737: } ! 1738: /* MOVE */ ! 1739: if (strncmp (pos, "move.", 5) == 0) { ! 1740: pos += 5; ! 1741: size = get_size (pos[0]); ! 1742: pos++; ! 1743: check_whitespace(); ! 1744: pos = get_ea (pos, &ea, size, F_ALL); ! 1745: check (','); ! 1746: pos = get_ea (pos, &ea2, size, F_AREG | F_DREG | F_IND | F_PRE | F_POST | F_INDEX | F_OFFSET | F_MEM_W | F_MEM_L); ! 1747: check_end (pos); ! 1748: ! 1749: if ((ea.mode == 7) && (ea.reg == 1) && (ea.imm.has_label)) { ! 1750: if (strcmp (ea.imm.label, "sr")==0) { ! 1751: /* move from sr */ ! 1752: if (size != WORD) error ("Illegal size."); ! 1753: op.code = 0x40c0; ! 1754: op.type1.ea_reg = ea2.reg; ! 1755: op.type1.ea_mode = ea2.mode; ! 1756: wr_short (op.code); ! 1757: wr_ea (&ea2); ! 1758: continue; ! 1759: } ! 1760: } ! 1761: if (ea2.mode == 1) { ! 1762: i = ea2.reg; ! 1763: goto is_movea; ! 1764: } ! 1765: if ((ea2.mode == 7) && (ea2.reg == 1) && (ea2.imm.has_label)) { ! 1766: if (strcmp (ea2.imm.label, "sr")==0) { ! 1767: /* move to status reg */ ! 1768: if (size != WORD) error ("Illegal size."); ! 1769: op.code = 0x46c0; ! 1770: op.type1.ea_reg = ea.reg; ! 1771: op.type1.ea_mode = ea.mode; ! 1772: wr_short (op.code); ! 1773: wr_ea (&ea); ! 1774: continue; ! 1775: } ! 1776: } ! 1777: size = move_size[size]; ! 1778: op.code = 0; ! 1779: op.move.size = size; ! 1780: op.move.dest_reg = ea2.reg; ! 1781: op.move.dest_mode = ea2.mode; ! 1782: op.move.src_reg = ea.reg; ! 1783: op.move.src_mode = ea.mode; ! 1784: wr_short (op.code); ! 1785: wr_ea (&ea); ! 1786: wr_ea (&ea2); ! 1787: continue; ! 1788: } ! 1789: /* TST */ ! 1790: if (strncmp (pos, "tst.", 4) == 0) { ! 1791: pos += 4; ! 1792: size = get_size (pos[0]); ! 1793: pos++; ! 1794: check_whitespace(); ! 1795: pos = get_ea (pos, &ea, size, F_NOIMM_NOPC_NOAREG); ! 1796: check_end (pos); ! 1797: op.code = 0x4a00; ! 1798: op.type1.size = size; ! 1799: op.type1.ea_reg = ea.reg; ! 1800: op.type1.ea_mode = ea.mode; ! 1801: wr_short (op.code); ! 1802: wr_ea (&ea); ! 1803: continue; ! 1804: } ! 1805: /* PEA */ ! 1806: if (strncmp (pos, "pea", 3) == 0) { ! 1807: pos += 3; ! 1808: check_whitespace(); ! 1809: pos = get_ea (pos, &ea, LONG, F_IND | F_OFFSET | F_INDEX | F_MEM_W | F_MEM_L | F_PC_OFFSET | F_PC_INDEX); ! 1810: check_end (pos); ! 1811: op.code = 0x4840; ! 1812: op.type2.ea_reg = ea.reg; ! 1813: op.type2.ea_mode = ea.mode; ! 1814: wr_short (op.code); ! 1815: wr_ea (&ea); ! 1816: continue; ! 1817: } ! 1818: /* LEA */ ! 1819: if (strncmp (pos, "lea", 3) == 0) { ! 1820: pos += 3; ! 1821: check_whitespace(); ! 1822: pos = get_ea (pos, &ea, LONG, F_IND | F_OFFSET | F_INDEX | F_MEM_W | F_MEM_L | F_PC_OFFSET | F_PC_INDEX); ! 1823: check (','); ! 1824: pos = get_reg (pos, &size, F_AREG); ! 1825: check_end (pos); ! 1826: op.code = 0x41e0; ! 1827: op.type2.ea_reg = ea.reg; ! 1828: op.type2.ea_mode = ea.mode; ! 1829: op.type2.reg = size-8; ! 1830: wr_short (op.code); ! 1831: wr_ea (&ea); ! 1832: continue; ! 1833: } ! 1834: ! 1835: /* JSR */ ! 1836: if (strncmp (pos, "jsr", 3) == 0) { ! 1837: pos += 3; ! 1838: check_whitespace(); ! 1839: pos = get_ea (pos, &ea, LONG, F_IND | F_OFFSET | ! 1840: F_INDEX | F_MEM_W | F_MEM_L | F_PC_OFFSET | F_PC_INDEX); ! 1841: check_end (pos); ! 1842: op.code = 0x4e80; ! 1843: op.type1.ea_reg = ea.reg; ! 1844: op.type1.ea_mode = ea.mode; ! 1845: wr_short (op.code); ! 1846: wr_ea (&ea); ! 1847: continue; ! 1848: } ! 1849: /* JMP */ ! 1850: if (strncmp (pos, "jmp", 3) == 0) { ! 1851: pos += 3; ! 1852: check_whitespace(); ! 1853: pos = get_ea (pos, &ea, LONG, F_IND | F_OFFSET | ! 1854: F_INDEX | F_MEM_W | F_MEM_L | F_PC_OFFSET | F_PC_INDEX); ! 1855: check_end (pos); ! 1856: op.code = 0x4ec0; ! 1857: op.type1.ea_reg = ea.reg; ! 1858: op.type1.ea_mode = ea.mode; ! 1859: wr_short (op.code); ! 1860: wr_ea (&ea); ! 1861: continue; ! 1862: } ! 1863: /* Scc */ ! 1864: if (pos[0] == 's') { ! 1865: pos = rd_label (&pos[1], lab1); ! 1866: for (i=0; i<16; i++) { ! 1867: if (strncmp (lab1, DBcc_str[i], 2)==0) break; ! 1868: } ! 1869: if (i==16) goto fuckit2; ! 1870: while (isalpha (*pos)) pos++; ! 1871: check_whitespace(); ! 1872: pos = get_ea (pos, &ea, BYTE, F_NOIMM_NOPC_NOAREG); ! 1873: check_end (pos); ! 1874: op.code = 0x50c0; ! 1875: op.DBcc.cond = i; ! 1876: op.type1.ea_reg = ea.reg; ! 1877: op.type1.ea_mode = ea.mode; ! 1878: wr_short (op.code); ! 1879: wr_ea (&ea); ! 1880: continue; ! 1881: } ! 1882: fuckit2: ! 1883: error ("Unknown opcode %s.", pos); ! 1884: } ! 1885: /* write text section length */ ! 1886: size = get_bitpos () - BASE; ! 1887: set_bitpos (2); ! 1888: wr_int (size); ! 1889: /* empty reloc table for the moment */ ! 1890: set_bitpos (size + BASE); ! 1891: wr_int (0); ! 1892: return size + BASE; ! 1893: } ! 1894: ! 1895: int asm_pass2 (int fixup_pos) ! 1896: { ! 1897: struct Label *lab; ! 1898: struct Fixup *fix; ! 1899: int last_adr = BASE; ! 1900: int _first = 1; ! 1901: int dist; ! 1902: int num_relocs = 0; ! 1903: ! 1904: fix = fix_first; ! 1905: ! 1906: while (fix) { ! 1907: line_no = fix->line_no; ! 1908: lab = get_label (fix->label); ! 1909: if (!lab) { ! 1910: error ("Undefined label '%s'.", fix->label); ! 1911: } ! 1912: if (lab->type == L_CONST) { ! 1913: error ("Illegal absolute value."); ! 1914: } ! 1915: set_bitpos (fix->adr); ! 1916: if (fix->size == BYTE) { ! 1917: dist = lab->val - fix->rel_to; ! 1918: if ((dist < -128) || (dist > 127)) { ! 1919: error ("Offset too big (%d).", dist); ! 1920: } ! 1921: wr_byte (dist); ! 1922: } else if (fix->size == WORD) { ! 1923: dist = lab->val - fix->rel_to; ! 1924: if ((dist < -32768) || (dist > 32767)) { ! 1925: error ("Offset too big (%d).", dist); ! 1926: } ! 1927: wr_short (dist); ! 1928: } else if (fix->size >= LONG) { ! 1929: num_relocs++; ! 1930: wr_int (lab->val); ! 1931: set_bitpos (fixup_pos); ! 1932: if (_first) { ! 1933: wr_int (fix->adr - BASE); ! 1934: last_adr = fix->adr; ! 1935: fixup_pos+=4; ! 1936: _first = 0; ! 1937: } else { ! 1938: dist = fix->adr - last_adr; ! 1939: while (dist > 254) { ! 1940: wr_byte (1); ! 1941: dist -= 254; ! 1942: fixup_pos++; ! 1943: } ! 1944: wr_byte (dist); ! 1945: last_adr = fix->adr; ! 1946: fixup_pos++; ! 1947: } ! 1948: } else {error ("Unknown size in fixup tab.");} ! 1949: fix = fix->next; ! 1950: } ! 1951: set_bitpos (fixup_pos); ! 1952: if (_first) wr_int (0); ! 1953: else wr_byte (0); ! 1954: ! 1955: return num_relocs; ! 1956: } ! 1957: ! 1958: int main (int argc, char **argv) ! 1959: { ! 1960: int size, num; ! 1961: if (argc == 1) { ! 1962: printf ("Usage: ./as68k [--dump-labels] file.s\n"); ! 1963: exit (0); ! 1964: } ! 1965: ! 1966: argv++; ! 1967: ! 1968: if (strcmp (*argv, "--dump-labels") == 0) { ! 1969: argv++; ! 1970: dump_labels = 1; ! 1971: } ! 1972: if ((fin = fopen (*argv, "r"))==NULL) { ! 1973: printf ("Error. Cannot open %s.\n", *argv); ! 1974: exit (0); ! 1975: } ! 1976: ! 1977: fout = fopen ("aout.prg", "w"); ! 1978: ! 1979: printf ("Pass 1\n"); ! 1980: size = asm_pass1 (); ! 1981: printf ("Pass 2\n"); ! 1982: num = asm_pass2 (size); ! 1983: fseek (fout, 0, SEEK_END); ! 1984: size = ftell (fout); ! 1985: ! 1986: printf ("Done! %d bytes and %d relocations.\n", size, num); ! 1987: return 0; ! 1988: } ! 1989:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.