Annotation of frontvm/as68k/as68k.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.