Annotation of frontvm/dis68k/dis68k.c, revision 1.1.1.1

1.1       root        1: 
                      2: #include <stdio.h>
                      3: #include <stdlib.h>
                      4: #include <string.h>
                      5: #include <stdarg.h>
                      6: 
                      7: static int end;
                      8: static int base = 0x1c;
                      9: static unsigned char *buffer;
                     10: static int buf_pos = 0;
                     11: static unsigned short *labels;
                     12: static int pass = 1;
                     13: static unsigned char *probs;
                     14: static enum GUESSMODE {
                     15:        GUESS_NONE,
                     16:        GUESS_SIMPLE,
                     17:        GUESS_WALK
                     18: } guessmode;
                     19: 
                     20: static int walk_stack[1024];
                     21: static int *ws_top = &walk_stack[0];
                     22: 
                     23: #define PUSH_WS(pos)   do { ws_top++; *ws_top = (pos); } while (0);
                     24: #define POP_WS()       (*(ws_top--))
                     25: 
                     26: /* label flags */
                     27: #define F_LABEL                (1<<0)
                     28: #define F_USELAB       (1<<1)
                     29: #define F_DUNNO                (1<<2)
                     30: #define F_GUESS_DATA   (1<<3)
                     31: #define F_GUESS_STRING (1<<4)
                     32: #define F_WALKED_CODE  (1<<5)
                     33: #define F_CODE_STOP    (1<<6)
                     34: #define F_LABEL_TABLE  (1<<7)
                     35: #define F_LABEL_MAJOR  (1<<8)
                     36: 
                     37: static void output (const char *format, ...)
                     38: {
                     39:        va_list argptr;
                     40: 
                     41:        if (pass == 1) return;
                     42:        va_start (argptr, format);
                     43:        vprintf (format, argptr);
                     44:        va_end (argptr);
                     45: }
                     46: 
                     47: static void output_lab (int adr)
                     48: {
                     49:        if (labels[adr] & F_LABEL_MAJOR) output ("L%x", adr);
                     50:        else output ("l%x", adr);
                     51: }
                     52: 
                     53: unsigned char rd_byte(void)
                     54: {
                     55:        return buffer[buf_pos++];
                     56: }
                     57: 
                     58: short rd_short(void)
                     59: {
                     60:        short t1, t2;
                     61:        t1 = rd_byte();
                     62:        t2 = rd_byte();
                     63:        return ((t1 << 8) | t2);
                     64: }
                     65: 
                     66: int rd_int(void)
                     67: {
                     68:        short t1, t2, t3, t4;
                     69:        t1 = rd_byte();
                     70:        t2 = rd_byte();
                     71:        t3 = rd_byte();
                     72:        t4 = rd_byte();
                     73:        return ((t1 << 24) | (t2 << 16) | (t3 << 8) | t4);
                     74: }
                     75: 
                     76: void wr_byte(unsigned char x)
                     77: {
                     78:        buffer [buf_pos++] = x;
                     79: }
                     80: 
                     81: void wr_short(short x)
                     82: {
                     83:        wr_byte((unsigned char)((x>>8) & 0xff));
                     84:        wr_byte((unsigned char)(x & 0xff));
                     85: }
                     86: 
                     87: void wr_int(int x)
                     88: {
                     89:        wr_byte((unsigned char)((x>>24) & 0xff));
                     90:        wr_byte((unsigned char)((x>>16) & 0xff));
                     91:        wr_byte((unsigned char)((x>>8) & 0xff));
                     92:        wr_byte((unsigned char)(x & 0xff));
                     93: }
                     94: 
                     95: const char *size_str[4] = { ".b", ".w", ".l", ".?" };
                     96: /* to convert weird move sizes to standard sizes */
                     97: const int move_size[4] = { 3, 0, 2, 1 };
                     98: const char *Bcc_str[16] = {
                     99:        NULL,NULL,"hi","ls","cc","cs","ne","eq",
                    100:        "vc","vs","pl","mi","ge","lt","gt","le"
                    101: };
                    102: 
                    103: const char *DBcc_str[16] = {
                    104:        "t","ra","hi","ls","cc","cs","ne","eq",
                    105:        "vc","vs","pl","mi","ge","lt","gt","le"
                    106: };
                    107: 
                    108: const char *Scc_str[16] = {
                    109:        "t","f","hi","ls","cc","cs","ne","eq",
                    110:        "vc","vs","pl","mi","ge","lt","gt","le"
                    111: };
                    112: 
                    113: typedef union Opcode {
                    114:        unsigned short code;
                    115:        struct move {
                    116:                uint src_reg : 3;
                    117:                uint src_mode : 3;
                    118:                uint dest_mode : 3;
                    119:                uint dest_reg : 3;
                    120:                uint size : 2;
                    121:                uint op : 2;
                    122:        } move;
                    123:        struct adr_index {
                    124:                int displacement : 8;
                    125:                uint zeros : 3;
                    126:                uint ind_size : 1;
                    127:                uint reg : 3;
                    128:                uint reg_type : 1;
                    129:        } adr_index;
                    130:        struct addq {
                    131:                uint dest_reg : 3;
                    132:                uint dest_mode : 3;
                    133:                uint size : 2;
                    134:                uint issub : 1;
                    135:                uint data : 3;
                    136:                uint op : 4;
                    137:        } addq;
                    138:        struct jmp {
                    139:                uint dest_reg : 3;
                    140:                uint dest_mode : 3;
                    141:                uint op : 10;
                    142:        } jmp;
                    143:        struct addi {
                    144:                uint dest_reg : 3;
                    145:                uint dest_mode : 3;
                    146:                uint size : 2;
                    147:                uint OP6 : 8;
                    148:        } addi;
                    149:        /* size and effective address */
                    150:        struct type1 {
                    151:                uint ea_reg : 3;
                    152:                uint ea_mode : 3;
                    153:                uint size : 2;
                    154:                uint op : 8;
                    155:        } type1;
                    156:        /* reg, opmode, ea */
                    157:        struct type2 {
                    158:                uint ea_reg : 3;
                    159:                uint ea_mode : 3;
                    160:                uint op_mode : 3;
                    161:                uint reg : 3;
                    162:                uint op : 4;
                    163:        } type2;
                    164:        struct MemShift {
                    165:                uint ea_reg : 3;
                    166:                uint ea_mode : 3;
                    167:                uint OP3 : 2;
                    168:                uint dr : 1;
                    169:                uint type : 2;
                    170:                uint OP0x1c : 5;
                    171:        } MemShift;
                    172:        struct ASx {
                    173:                uint reg : 3;
                    174:                uint OP0 : 2;
                    175:                uint ir : 1;
                    176:                uint size : 2;
                    177:                uint dr : 1;
                    178:                uint count_reg : 3;
                    179:                uint OP0xe : 4;
                    180:        } ASx;
                    181:        struct abcd {
                    182:                uint src_reg : 3;
                    183:                uint rm : 1;
                    184:                uint OP16 : 5;
                    185:                uint dest_reg : 3;
                    186:                uint OP12 : 4;
                    187:        } abcd;
                    188:        struct addx {
                    189:                uint src_reg : 3;
                    190:                uint rm : 1;
                    191:                uint OP0 : 2;
                    192:                uint size : 2;
                    193:                uint OP1 : 1;
                    194:                uint dest_reg : 3;
                    195:                uint op : 4;
                    196:        } addx;
                    197:        struct cmpm {
                    198:                uint src_reg : 3;
                    199:                uint OP1_1 : 3;
                    200:                uint size : 2;
                    201:                uint OP2_1 : 1;
                    202:                uint dest_reg : 3;
                    203:                uint OP0xb : 4;
                    204:        } cmpm;
                    205:        /* branches */
                    206:        struct DBcc {
                    207:                uint reg : 3;
                    208:                uint OP25 : 5;
                    209:                uint cond : 4;
                    210:                uint OP5 : 4;
                    211:        } DBcc;
                    212:        struct Bcc {
                    213:                int displacement : 8;
                    214:                uint cond : 4;
                    215:                uint op : 4;
                    216:        } Bcc;
                    217:        struct bra {
                    218:                int displacement : 8;
                    219:                uint op : 8;
                    220:        } bra;
                    221:        struct movem {
                    222:                uint dest_reg : 3;
                    223:                uint dest_mode : 3;
                    224:                uint sz : 1;
                    225:                uint ONE : 3;
                    226:                uint dr : 1;
                    227:                uint NINE : 5;
                    228:        } movem;
                    229:        struct lea {
                    230:                uint dest_reg : 3;
                    231:                uint dest_mode : 3;
                    232:                uint SEVEN : 3;
                    233:                uint reg : 3;
                    234:                uint FOUR : 4;
                    235:        } lea;
                    236:        struct moveq {
                    237:                int data : 8;
                    238:                uint ZERO : 1;
                    239:                uint reg : 3;
                    240:                uint SEVEN : 4;
                    241:        } moveq;
                    242:        struct exg {
                    243:                uint dest_reg : 3;
                    244:                uint op_mode : 5;
                    245:                uint OP1 : 1;
                    246:                uint src_reg : 3;
                    247:                uint OP0xc : 4;
                    248:        } exg;
                    249: } Opcode;
                    250: 
                    251: /*
                    252:  * Skip size is used when there is immediate data, for addressing
                    253:  * modes $addr(Ax,Dy.s), and the PC flavoured version of that.
                    254:  * The immediate data comes first and must be skipped
                    255:  */
                    256: int is_adrmod (int mode, int reg, int op_size, int skip_size)
                    257: {
                    258:        Opcode ext;
                    259:        switch (skip_size) {
                    260:                case -1: skip_size = 0; break;
                    261:                case  0: case 1: skip_size = 2; break;
                    262:                default: skip_size = 4; break;
                    263:        }
                    264:        switch (mode) {
                    265:                case 0: case 1: case 2: case 3: case 4:
                    266:                        return 1;
                    267:                case 5: return 1;
                    268:                case 6: buf_pos += skip_size;
                    269:                        ext.code = rd_short ();
                    270:                        buf_pos -= 2 + skip_size;
                    271:                        if (ext.adr_index.zeros != 0) return 0;
                    272:                        else return 1;
                    273:                case 7: 
                    274:                        switch (reg) {
                    275:                                case 0: return 1;
                    276:                                case 1: return 1;
                    277:                                case 4:
                    278:                                        if (op_size == 0) {
                    279:                                                if (rd_byte () != 0) {
                    280:                                                        buf_pos--;
                    281:                                                        return 0;
                    282:                                                }
                    283:                                                buf_pos--;
                    284:                                                return 1;
                    285:                                        } else if (op_size == 2) {
                    286:                                                if (buf_pos <= end-4) return 1;
                    287:                                                else return 0;
                    288:                                        } else if (op_size == 1) {
                    289:                                                if (buf_pos <= end-2) return 1;
                    290:                                                else return 0;
                    291:                                        } else {
                    292:                                                return 0;
                    293:                                        }
                    294:                                        break;
                    295:                                case 2:
                    296:                                        if (buf_pos <= end-2) return 1;
                    297:                                        else return 0;
                    298:                                case 3: buf_pos += skip_size;
                    299:                                        ext.code = rd_short ();
                    300:                                        buf_pos -= 2 + skip_size;
                    301:                                        if (ext.adr_index.zeros != 0) return 0;
                    302:                                        else return 1;
                    303:                                default:
                    304:                                        return 0;
                    305:                        }
                    306:                        break;
                    307:                default:
                    308:                        return 0;
                    309:        }
                    310:                        
                    311: }
                    312: 
                    313: /* returns abs address if possible or 0xdeadbeef if not */
                    314: uint put_adrmod (int mode, int reg, int op_size)
                    315: {
                    316:        uint temp;
                    317:        Opcode ext;
                    318:        switch (mode) {
                    319:                case 0: output ("d%d", reg); break;
                    320:                case 1: output ("a%d", reg); break;
                    321:                case 2: output ("(a%d)", reg); break;
                    322:                case 3: output ("(a%d)+", reg); break;
                    323:                case 4: output ("-(a%d)", reg); break;
                    324:                case 5: output ("%hd(a%d)", rd_short(), reg); break;
                    325:                case 6: ext.code = rd_short ();
                    326:                        if (ext.adr_index.zeros != 0) output ("???");
                    327:                        output ("%hd(a%d,", ext.adr_index.displacement, reg);
                    328:                        if (ext.adr_index.reg_type) {
                    329:                                output ("a%d", ext.adr_index.reg);
                    330:                        } else {
                    331:                                output ("d%d", ext.adr_index.reg);
                    332:                        }
                    333:                        if (ext.adr_index.ind_size) {
                    334:                                output (".l)");
                    335:                        } else {
                    336:                                output (".w)");
                    337:                        }
                    338:                        break;
                    339:                case 7: 
                    340:                        switch (reg) {
                    341:                                case 0: output ("$%hx.w", rd_short()); break;
                    342:                                case 1: temp = rd_int ();
                    343:                                        if (labels[buf_pos-4] & F_USELAB) output_lab (temp);
                    344:                                        else output ("$%x.l", temp);
                    345:                                        return temp;
                    346:                                case 4:
                    347:                                        if (op_size == 0) {
                    348:                                                if (rd_byte () != 0) output ("???");
                    349:                                                output ("#$%x", rd_byte ());
                    350:                                        } else if (op_size == 2) {
                    351:                                                output ("#");
                    352:                                                if (labels[buf_pos] & F_USELAB) output_lab (rd_int ());
                    353:                                                else output ("$%x", rd_int ());
                    354:                                        } else if (op_size == 1) {
                    355:                                                output ("#$%hx", rd_short ());
                    356:                                        } else {
                    357:                                                output ("#???");
                    358:                                        }
                    359:                                        break;
                    360:                                case 2:
                    361:                                        temp = buf_pos;
                    362:                                        temp += rd_short ();
                    363:                                        labels [temp] |= F_LABEL | F_LABEL_MAJOR;
                    364:                                        output_lab (temp);
                    365:                                        output ("(pc)");
                    366:                                        return temp;
                    367:                                case 3: temp = buf_pos;
                    368:                                        ext.code = rd_short ();
                    369:                                        if (ext.adr_index.zeros != 0) output ("???");
                    370:                                        labels [temp + ext.adr_index.displacement] |= F_LABEL | F_LABEL_MAJOR;
                    371:                                        output_lab (temp + ext.adr_index.displacement);
                    372:                                        if (ext.adr_index.reg_type) {
                    373:                                                output ("(pc,a%d", ext.adr_index.reg);
                    374:                                        } else {
                    375:                                                output ("(pc,d%d", ext.adr_index.reg);
                    376:                                        }
                    377:                                        if (ext.adr_index.ind_size) {
                    378:                                                output (".l)");
                    379:                                        } else {
                    380:                                                output (".w)");
                    381:                                        }
                    382:                                        break;
                    383:                                default:
                    384:                                        output ("???"); break;
                    385:                        }
                    386:                        break;
                    387:                default:
                    388:                        output ("???"); break;
                    389:        }
                    390:        return 0xdeadbeef;
                    391: }
                    392: 
                    393: void aux_put_movem_regs (int mode, int low, int high)
                    394: {
                    395:        if (!mode) {
                    396:                /* (Ax)+ and control modes */
                    397:                if (low < 8) {
                    398:                        if (low == high) {
                    399:                                output ("d%d", low);
                    400:                                return;
                    401:                        }
                    402:                        if (high >7) {
                    403:                                if (low == 7) output ("d7/");
                    404:                                else output ("d%d-7/", low);
                    405:                        } else {
                    406:                                output ("d%d-%d", low, high);
                    407:                                return;
                    408:                        }
                    409:                }
                    410:                if (high > 7) {
                    411:                        if (low == high) {
                    412:                                output ("a%d", low-8);
                    413:                                return;
                    414:                        }
                    415:                        if (low > 7) {
                    416:                                output ("a%d-%d", low-8, high-8);
                    417:                        } else {
                    418:                                if (high == 8) output ("a0");
                    419:                                else output ("a0-%d", high-8);
                    420:                        }
                    421:                }
                    422:        } else {
                    423:                /* -(Ax) mode */
                    424:                if (high > 7) {
                    425:                        if (low == high) {
                    426:                                output ("d%d", 15-low);
                    427:                                return;
                    428:                        }
                    429:                        if (low > 7) {
                    430:                                output ("d%d-%d", 15-high, 15-low);
                    431:                                return;
                    432:                        } else {
                    433:                                if (high == 8) output ("d7/");
                    434:                                else output ("d%d-7/", 15-high);
                    435:                        }
                    436:                }
                    437:                if (low < 8) {
                    438:                        if (low == high) {
                    439:                                output ("a%d", 7-low);
                    440:                                return;
                    441:                        }
                    442:                        if (high >7) {
                    443:                                if (low == 7) output ("a0");
                    444:                                else output ("a0-%d", 7-low);
                    445:                        } else {
                    446:                                output ("a%d-%d", 7-high, 7-low);
                    447:                        }
                    448:                }
                    449:        }
                    450: }
                    451: 
                    452: void put_movem_regs (int mask, int mode)
                    453: {
                    454:        int start;
                    455:        int pos;
                    456:        int pixie = 0;
                    457: 
                    458:        start = -1;
                    459:        for (pos=0; pos < 16; pos++) {
                    460:                if ((mask & (1<<pos)) && (start == -1)) start = pos;
                    461:                else if ((!(mask & (1<<pos))) && (start != -1)) {
                    462:                        if (pixie) output ("/");
                    463:                        else pixie = 1;
                    464:                        aux_put_movem_regs (mode, start, pos-1);
                    465:                        start = -1;
                    466:                }
                    467:        }
                    468:        if (mask & (1<<15)) {
                    469:                if (pixie) output ("/");
                    470:                else pixie = 1;
                    471:                aux_put_movem_regs (mode, start, pos-1);
                    472:                start = -1;
                    473:        }
                    474: }
                    475: 
                    476: void put_imm (int size)
                    477: {
                    478:        if (size == 0) {
                    479:                rd_byte ();
                    480:                output ("#$%x", (int)rd_byte ());
                    481:        } else if (size == 1) {
                    482:                output ("#$%hx", (int)rd_short ());
                    483:        } else {
                    484:                output ("#$%x", (int)rd_int ());
                    485:        }
                    486: }
                    487: 
                    488: #define is_valid_branch(dest)  (((dest) >= base) && ((dest < end)))
                    489: 
                    490: static void dump_code ()
                    491: {
                    492:        Opcode op;
                    493:        int size;
                    494:        int temp;
                    495:        const char *str;
                    496:        int last_ip;
                    497: 
                    498:        //output ("\topt\te-\r\n");
                    499:        
                    500:        while (buf_pos < end) {
                    501:                if ((guessmode == GUESS_WALK) && (pass == 1)) {
                    502:                        if (labels[buf_pos] & (F_WALKED_CODE | F_CODE_STOP)) {
                    503:                                buf_pos = POP_WS ();
                    504:                                continue;
                    505:                        }
                    506:                }
                    507:                if (labels[buf_pos] & F_LABEL) {
                    508:                        if (guessmode == GUESS_SIMPLE) output ("\r\n* data guess rate %d", probs[buf_pos]);
                    509:                        if (labels[buf_pos] & F_LABEL_MAJOR) {
                    510:                                output ("\r\n\r\n");
                    511:                                output_lab (buf_pos);
                    512:                                output (":\r\n\t\t");
                    513:                        } else {
                    514:                                output ("\r\n\t");
                    515:                                output_lab (buf_pos);
                    516:                                output (":\t");
                    517:                        }
                    518:                } else {
                    519:                        //output ("\r\n_%x:\t\t", buf_pos);
                    520:                        output ("\r\n\t\t");
                    521:                }
                    522:                if (labels[buf_pos] & F_LABEL_TABLE) {
                    523:                        /* contains fixedup label */
                    524:                        temp = rd_int ();
                    525:                        output ("dc.l\t");
                    526:                        output_lab (temp);
                    527:                        if (!(labels[temp] & F_LABEL)) fprintf (stderr, "Error, Label table entry at 0x%x isn't a label address.\n", buf_pos-4);
                    528:                        continue;
                    529:                }
                    530:                if (labels[buf_pos] & F_GUESS_STRING) {
                    531:                        output ("dc.b\t\"");
                    532:                        size = 0;
                    533:                        do {
                    534:                                temp = rd_byte ();
                    535:                                if (temp == '"') output ("%c%c", temp, temp);
                    536:                                else output ("%c", temp);
                    537:                                if (size++ == 70) break;
                    538:                        } while ((labels[buf_pos] & F_GUESS_STRING) && (!(labels[buf_pos] & F_LABEL)));
                    539:                        output ("\"");
                    540:                        continue;
                    541:                }
                    542:                if (labels[buf_pos] & F_GUESS_DATA) {
                    543:                        /* make ds.b if possible */
                    544:                        temp = 0;
                    545:                        last_ip = buf_pos;
                    546:                        while (rd_byte () == 0) {
                    547:                                temp++;
                    548:                                if (labels[buf_pos] & F_LABEL) break;
                    549:                                else if (labels[buf_pos] & F_WALKED_CODE) break;
                    550:                                else if (!(labels[buf_pos] & F_GUESS_DATA)) break;
                    551:                                else if (labels[buf_pos] & F_GUESS_STRING) break;
                    552:                        }
                    553:                        if (temp >= 4) {
                    554:                                output ("ds.b\t%d", temp);
                    555:                                /* stopped because of an end to zeros */
                    556:                                buf_pos--;
                    557:                                if (rd_byte () != 0) buf_pos--;
                    558:                                continue;
                    559:                        }
                    560:                        buf_pos = last_ip;
                    561:                        output ("dc.b\t");
                    562:                        for (temp = 0; temp<16; temp++) {
                    563:                                if (temp) output (",");
                    564:                                output ("$%x", rd_byte ());
                    565:                                if (labels[buf_pos] & F_LABEL) break;
                    566:                                else if (labels[buf_pos] & F_WALKED_CODE) break;
                    567:                                else if (!(labels[buf_pos] & F_GUESS_DATA)) break;
                    568:                                else if (labels[buf_pos] & F_GUESS_STRING) break;
                    569:                        }
                    570:                        continue;
                    571:                }
                    572:                last_ip = buf_pos;
                    573:                op.code = rd_short ();
                    574:                /* ABCD/SBCD */
                    575:                while (op.abcd.OP16 == 16) {
                    576:                        if (op.abcd.OP12 == 12) output ("abcd\t");
                    577:                        else if (op.abcd.OP12 == 8) output ("sbcd\t");
                    578:                        else break;
                    579:                        if (op.abcd.rm) {
                    580:                                output ("-(a%d),-(a%d)", op.abcd.src_reg, op.abcd.dest_reg);
                    581:                        } else {
                    582:                                output ("d%d,d%d", op.abcd.src_reg, op.abcd.dest_reg);
                    583:                        }
                    584:                        goto done;
                    585:                }
                    586:                /* ADD/SUB */
                    587:                while ((op.type2.op == 0xd) || (op.type2.op == 0x9)) {
                    588:                        if (op.type2.op == 0xd) str = "add";
                    589:                        else str = "sub";
                    590:                        if (op.type2.op_mode == 3) {
                    591:                                /* ADDA.W */
                    592:                                if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, 1, -1)) break;
                    593:                                output ("%sa.w\t", str);
                    594:                                put_adrmod (op.type2.ea_mode, op.type2.ea_reg, 1);
                    595:                                output (",a%d", op.type2.reg);
                    596:                        }
                    597:                        else if (op.type2.op_mode == 7) {
                    598:                                /* ADDA.L */
                    599:                                if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, 2, -1)) break;
                    600:                                output ("%sa.l\t", str);
                    601:                                put_adrmod (op.type2.ea_mode, op.type2.ea_reg, 2);
                    602:                                output (",a%d", op.type2.reg);
                    603:                        }
                    604:                        else if (op.type2.op_mode < 3) {
                    605:                                /* dest is reg */
                    606:                                /* no .b size Ax sources */
                    607:                                if ((op.type2.op_mode == 0) && (op.type2.ea_mode == 0x1)) break;
                    608:                                if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode, -1)) break;
                    609:                                output ("%s%s\t", str, size_str[op.type2.op_mode]);
                    610:                                put_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode);
                    611:                                output (",d%d", op.type2.reg);
                    612:                        } else {
                    613:                                /* dest is ea */
                    614:                                if (op.type2.ea_mode == 0x0) break;
                    615:                                if (op.type2.ea_mode == 0x1) break;
                    616:                                if (op.type2.ea_mode == 0x7) {
                    617:                                        if ((op.type2.ea_reg == 2) ||
                    618:                                            (op.type2.ea_reg == 3) ||
                    619:                                            (op.type2.ea_reg == 4)) break;
                    620:                                }
                    621:                                if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode-4, -1)) break;
                    622:                                output ("%s%s\t", str, size_str[op.type2.op_mode-4]);
                    623:                                output ("d%d,", op.type2.reg);
                    624:                                put_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode-4);
                    625:                        }
                    626:                        goto done;
                    627:                }
                    628:                /* ADDI/SUBI */
                    629:                while ((op.addi.OP6 == 6) || (op.addi.OP6 == 4)) {
                    630:                        if (op.addi.size == 3) break;
                    631:                        if (op.addi.dest_mode == 0x1) break;
                    632:                        if (op.addi.dest_mode == 0x7) {
                    633:                                if ((op.addi.dest_reg == 2) ||
                    634:                                    (op.addi.dest_reg == 3) ||
                    635:                                    (op.addi.dest_reg == 4)) break;
                    636:                        }
                    637:                        if (!is_adrmod (op.addi.dest_mode, op.addi.dest_reg, op.addi.size, op.addi.size)) break;
                    638:                        if (op.addi.OP6 == 6) output ("addi%s\t", size_str[op.addi.size]);
                    639:                        else output ("subi%s\t", size_str[op.addi.size]);
                    640:                        put_imm (op.addi.size);
                    641:                        output (",");
                    642:                        put_adrmod (op.addi.dest_mode, op.addi.dest_reg, op.addi.size);
                    643:                        goto done;
                    644:                }
                    645:                /* ADDQ/SUBQ */
                    646:                while (op.addq.op == 0x5) {
                    647:                        if (op.addq.size == 3) break;
                    648:                        /* no immediate or pc relative dest */
                    649:                        if (op.addq.dest_mode == 0x7) {
                    650:                                if (op.addq.dest_reg > 0x1) break;
                    651:                        }
                    652:                        /* no addq.b to address registers */
                    653:                        if ((op.addq.size == 0) && (op.addq.dest_mode == 1)) break;
                    654:                        if (!is_adrmod (op.addq.dest_mode, op.addq.dest_reg, op.addq.size, -1)) break;
                    655:                        if (op.addq.issub) output ("subq%s\t", size_str[op.addq.size]);
                    656:                        else output ("addq%s\t", size_str[op.addq.size]);
                    657:                        output ("#%d,", (op.addq.data == 0 ? 8 : op.addq.data));
                    658:                        put_adrmod (op.addq.dest_mode, op.addq.dest_reg, op.addq.size);
                    659:                        goto done;
                    660:                }
                    661:                /* ADDX/SUBX */
                    662:                while (((op.addx.op == 0xd) || (op.addx.op == 0x9)) && (op.addx.OP1 == 1) && (op.addx.OP0 == 0)) {
                    663:                        if (op.addx.size == 3) break;
                    664:                        if (op.addx.op == 0xd) output ("addx%s\t", size_str[op.addx.size]);
                    665:                        else output ("subx%s\t", size_str[op.addx.size]);
                    666:                        if (op.addx.rm) {
                    667:                                /* memory to memory */
                    668:                                output ("-(a%d),-(a%d)", op.addx.src_reg, op.addx.dest_reg);
                    669:                        } else {
                    670:                                output ("d%d,d%d", op.addx.src_reg, op.addx.dest_reg);
                    671:                        }
                    672: 
                    673:                        goto done;
                    674:                }
                    675:                /* AND/OR */
                    676:                while ((op.type2.op == 0xc) || (op.type2.op == 0x8)) {
                    677:                        if (op.type2.op_mode == 3) break;
                    678:                        if (op.type2.op_mode == 7) break;
                    679:                        if (op.type2.op == 0xc) str = "and";
                    680:                        else str = "or";
                    681:                        if (op.type2.op_mode < 3) {
                    682:                                /* dest is reg */
                    683:                                if (op.type2.ea_mode == 0x1) break;
                    684:                                if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode, -1)) break;
                    685:                                output ("%s%s\t", str, size_str[op.type2.op_mode]);
                    686:                                put_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode);
                    687:                                output (",d%d", op.type2.reg);
                    688:                        } else {
                    689:                                /* dest is ea */
                    690:                                if (op.type2.ea_mode == 0x0) break;
                    691:                                if (op.type2.ea_mode == 0x1) break;
                    692:                                if (op.type2.ea_mode == 0x7) {
                    693:                                        if (op.type2.ea_reg > 1) break;
                    694:                                }
                    695:                                if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode-4, -1)) break;
                    696:                                output ("%s%s\t", str, size_str[op.type2.op_mode-4]);
                    697:                                output ("d%d,", op.type2.reg);
                    698:                                put_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode-4);
                    699:                        }
                    700:                        goto done;
                    701:                }
                    702:                /* ANDI/EORI/ORI */
                    703:                while ((op.type1.op == 0x02) || (op.type1.op == 0xa) || (op.type1.op == 0x0)) {
                    704:                        /* ori.b #0,d0 is 0x0 longword and also a nop. it tends to
                    705:                         * be data rather than code */
                    706:                        if (op.code == 0x0) {
                    707:                                if (rd_short () == 0) {
                    708:                                        buf_pos -= 2;
                    709:                                        labels[buf_pos-2] |= F_DUNNO;
                    710:                                        labels[buf_pos-1] |= F_DUNNO;
                    711:                                        break;
                    712:                                } else {
                    713:                                        buf_pos -= 2;
                    714:                                }
                    715:                        }               
                    716:                        
                    717:                        if (op.type1.size == 3) break;
                    718:                        /* no address reg direct */
                    719:                        if (op.type1.ea_mode == 0x1) break;
                    720:                        /* no immediate or pc relative dest */
                    721:                        if (op.type1.ea_mode == 0x7) {
                    722:                                if (op.type1.ea_reg > 0x1) break;
                    723:                        }
                    724:                        if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size, op.type1.size)) break;
                    725:                        if (op.type1.op == 0x2) output ("andi%s\t", size_str[op.type1.size]);
                    726:                        else if (op.type1.op == 0xa) output ("eori%s\t", size_str[op.type1.size]);
                    727:                        else output ("ori%s\t", size_str[op.type1.size]);
                    728:                        put_imm (op.addi.size);
                    729:                        output (",");
                    730:                        put_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size);
                    731:                        goto done;
                    732:                }
                    733:                /* ANDI to CCR */
                    734:                while (op.code == 0x023c) {
                    735:                        rd_byte ();
                    736:                        output ("andi\t#$%x,ccr", rd_byte ());
                    737:                        goto done;
                    738:                }
                    739:                /* ANDI to SR */
                    740:                while (op.code == 0x027c) {
                    741:                        output ("andi\t#$%hx,sr", rd_short ());
                    742:                        goto done;
                    743:                }
                    744:                /* ASx/LSx reg/imm */
                    745:                while (op.ASx.OP0xe == 0xe) {
                    746:                        if (op.ASx.size == 3) break;
                    747:                        switch (op.ASx.OP0) {
                    748:                                case 0: str = "as"; break;
                    749:                                case 1: str = "ls"; break;
                    750:                                case 2: str = "rox"; break;
                    751:                                default: case 3: str = "ro"; break;
                    752:                        }
                    753:                        if (op.ASx.ir) {
                    754:                                /* data register shift */
                    755:                                output ("%s%c%s\td%d,d%d", str,
                    756:                                                (op.ASx.dr ? 'l' : 'r'),
                    757:                                                size_str[op.ASx.size],
                    758:                                                op.ASx.count_reg, op.ASx.reg);
                    759:                        } else {
                    760:                                /* count shift thingy */
                    761:                                output ("%s%c%s\t#%d,d%d", str,
                    762:                                                (op.ASx.dr ? 'l' : 'r'),
                    763:                                                size_str[op.ASx.size],
                    764:                                                (op.ASx.count_reg == 0 ? 8 : op.ASx.count_reg),
                    765:                                                op.ASx.reg);
                    766:                        }
                    767:                        goto done;
                    768:                }
                    769:                /* ASx/LSx memory shift */
                    770:                while ((op.MemShift.OP3 == 3) && (op.MemShift.OP0x1c == 0x1c)) {
                    771:                        if (op.type1.ea_mode < 0x2) break;
                    772:                        if ((op.type1.ea_mode == 0x7) && (op.type1.ea_reg > 0x1)) break;
                    773:                        if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, 1, -1)) break;
                    774:                        switch (op.MemShift.type) {
                    775:                                case 0: str = "as"; break;
                    776:                                case 1: str = "ls"; break;
                    777:                                case 2: str = "rox"; break;
                    778:                                default: case 3: str = "ro"; break;
                    779:                        }
                    780:                        output ("%s%c.w\t", str, (op.ASx.dr ? 'l' : 'r'));
                    781:                        put_adrmod (op.type1.ea_mode, op.type1.ea_reg, 1);
                    782:                        goto done;
                    783:                }
                    784:                /* Bcc */
                    785:                while (op.Bcc.op == 0x6) {
                    786:                        if (Bcc_str [op.Bcc.cond] == NULL) break;
                    787:                        if (op.bra.displacement) {
                    788:                                temp = buf_pos + op.Bcc.displacement;
                    789:                                if (!is_valid_branch(temp)) break;
                    790:                                output ("b%s.s\t", Bcc_str[op.Bcc.cond]);
                    791:                                output_lab (temp);
                    792:                        } else {
                    793:                                temp = buf_pos;
                    794:                                temp += rd_short ();
                    795:                                if (!is_valid_branch(temp)) break;
                    796:                                output ("b%s.w\t", Bcc_str[op.Bcc.cond]);
                    797:                                output_lab (temp);
                    798:                        }
                    799:                        labels [temp] |= F_LABEL;
                    800:                        if ((guessmode == GUESS_WALK) && (pass == 1)) PUSH_WS (temp);
                    801:                        goto done;
                    802:                }
                    803:                /* BRA */
                    804:                while (op.bra.op == 0x60) {
                    805:                        if (op.bra.displacement) {
                    806:                                temp = buf_pos + op.bra.displacement;
                    807:                                if (!is_valid_branch(temp)) break;
                    808:                                output ("bra.s\t");
                    809:                                output_lab (temp);
                    810:                                labels [temp] |= F_LABEL;
                    811:                        } else {
                    812:                                temp = buf_pos;
                    813:                                temp += rd_short ();
                    814:                                if (!is_valid_branch(temp)) break;
                    815:                                output ("bra.w\t");
                    816:                                output_lab (temp);
                    817:                                labels [temp] |= F_LABEL | F_LABEL_MAJOR;
                    818:                        }
                    819:                        if ((guessmode == GUESS_WALK) && (pass == 1)) buf_pos = temp;
                    820:                        goto done;
                    821:                }
                    822:                /* BSR */
                    823:                while ((op.code & 0xff00) == 0x6100) {
                    824:                        if (op.bra.displacement) {
                    825:                                temp = buf_pos + op.bra.displacement;
                    826:                                if (!is_valid_branch(temp)) break;
                    827:                                output ("bsr.s\t");
                    828:                                output_lab (temp);
                    829:                        } else {
                    830:                                temp = buf_pos;
                    831:                                temp += rd_short ();
                    832:                                if (!is_valid_branch(temp)) break;
                    833:                                output ("bsr.w\t");
                    834:                                output_lab (temp);
                    835:                        }
                    836:                        labels [temp] |= F_LABEL | F_LABEL_MAJOR;
                    837:                        if ((guessmode == GUESS_WALK) && (pass == 1)) PUSH_WS (temp);
                    838:                        goto done;
                    839:                }
                    840:                /* BCHG/BCLR/BSET/BTST (Dn,ea) */
                    841:                while ((op.type2.op == 0) && ((op.type2.op_mode == 0x4) || (op.type2.op_mode == 0x5) || (op.type2.op_mode == 0x6) || (op.type2.op_mode == 0x7))) {
                    842:                        if (op.type2.ea_mode == 0x1) break;
                    843:                        if ((op.type2.op_mode != 0x4) && (op.type2.ea_mode == 0x7)) {
                    844:                                if (op.type2.ea_reg > 1) break;
                    845:                        }
                    846:                        if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, 2, -1)) break;
                    847:                        
                    848:                        if (op.type2.op_mode == 0x4) output ("btst\t");
                    849:                        else if (op.type2.op_mode == 0x5) output ("bchg\t");
                    850:                        else if (op.type2.op_mode == 0x6) output ("bclr\t");
                    851:                        else output ("bset\t");
                    852:                        output ("d%d,", op.type2.reg);
                    853:                        put_adrmod (op.type2.ea_mode, op.type2.ea_reg, 2);
                    854:                        goto done;
                    855:                }
                    856:                /* BCHG/BCLR/BSET (#<data>,ea) */
                    857:                while ((op.type2.op == 0) && (op.type2.reg == 4) &&
                    858:                                ((op.type2.op_mode == 0) || (op.type2.op_mode == 1) || (op.type2.op_mode == 2) || (op.type2.op_mode == 3))) {
                    859:                        if (op.type2.ea_mode == 0x1) break;
                    860:                        if ((op.type2.ea_mode == 0x7) && (op.type2.ea_reg > 1)) break;
                    861:                        if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, 2, 1)) break;
                    862:                        temp = rd_byte ();
                    863:                        if (temp != 0) {
                    864:                                buf_pos--;
                    865:                                break;
                    866:                        }
                    867:                        if (op.type2.op_mode == 0) {
                    868:                                output ("btst\t");
                    869:                        } else if (op.type2.op_mode == 1) {
                    870:                                output ("bchg\t");
                    871:                        } else if (op.type2.op_mode == 2) {
                    872:                                output ("bclr\t");
                    873:                        } else {
                    874:                                output ("bset\t");
                    875:                        }
                    876:                        output ("#$%x,", (int)rd_byte ());
                    877:                        put_adrmod (op.type2.ea_mode, op.type2.ea_reg, 2);
                    878:                        goto done;
                    879:                }
                    880:                /* BKPT */
                    881:                /*while ((op.code & 0xfff8) == 0x4848) {
                    882:                        output ("bkpt\t#%d", op.code & 0x7);
                    883:                        goto done;
                    884:                }*/
                    885:                /* CHK */
                    886:                while ((op.type2.op == 0x4) && (op.type2.op_mode == 0x6)) {
                    887:                        /* no address reg direct */
                    888:                        if (op.type2.ea_mode == 0x1) break;
                    889:                        if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, 1, -1)) break;
                    890:                        
                    891:                        output ("chk\t");
                    892:                        put_adrmod (op.type2.ea_mode, op.type2.ea_reg, 1);
                    893:                        output (",d%d", op.type2.reg);
                    894:                        
                    895:                        goto done;
                    896:                }
                    897:                /* CLR */
                    898:                while (op.type1.op == 0x42) {
                    899:                        if (op.type1.size == 3) break;
                    900:                        /* no address reg direct */
                    901:                        if (op.type1.ea_mode == 0x1) break;
                    902:                        /* no immediate or pc relative dest */
                    903:                        if (op.type1.ea_mode == 0x7) {
                    904:                                if (op.type1.ea_reg > 0x1) break;
                    905:                        }
                    906:                        if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size, -1)) break;
                    907:                        output ("clr%s\t", size_str[op.type1.size]);
                    908:                        put_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size);
                    909:                        goto done;
                    910:                }
                    911:                /* CMP */
                    912:                while (op.type2.op == 11) {
                    913:                        if (op.type2.op_mode > 2) break;
                    914:                        /* no .b size for adr reg direct */
                    915:                        if ((op.type2.op_mode == 0) && (op.type2.ea_mode == 0x1)) break;
                    916:                        if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode, -1)) break;
                    917:                        output ("cmp%s\t", size_str[op.type2.op_mode]);
                    918:                        put_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode);
                    919:                        output (",d%d", op.type2.reg);
                    920:                        goto done;
                    921:                }
                    922:                /* CMPA */
                    923:                while (op.type2.op == 11) {
                    924:                        if ((op.type2.op_mode != 0x3) && (op.type2.op_mode != 0x7)) break;
                    925:                        if (op.type2.op_mode == 0x3) size = 1;
                    926:                        else size = 2;
                    927:                        if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, size, -1)) break;
                    928:                        output ("cmpa%s\t", size_str [size]);
                    929:                        put_adrmod (op.type2.ea_mode, op.type2.ea_reg, size);
                    930:                        output (",a%d", op.type2.reg);
                    931:                        goto done;
                    932:                }
                    933:                /* CMPI */
                    934:                while ((op.type1.op == 0x0c) && (op.type1.size != 0x3)) {
                    935:                        if (op.type1.ea_mode == 0x1) break;
                    936:                        if ((op.type1.ea_mode == 0x7) && (op.type1.ea_reg > 0x1)) break;
                    937:                        if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size, op.type1.size)) break;
                    938:                        output ("cmpi%s\t", size_str [op.type1.size]);
                    939:                        put_imm (op.type1.size);
                    940:                        output (",");
                    941:                        put_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size);
                    942:                        goto done;
                    943:                }
                    944:                /* CMPM */
                    945:                while ((op.cmpm.OP0xb == 0xb) && (op.cmpm.OP2_1 == 0x1) && (op.cmpm.OP1_1 == 0x1)) {
                    946:                        if (op.cmpm.size == 3) break;
                    947:                        output ("cmpm%s\t(a%d)+,(a%d)+", size_str [op.cmpm.size], op.cmpm.src_reg, op.cmpm.dest_reg);
                    948:                        goto done;
                    949:                }
                    950:                /* DBcc */
                    951:                while ((op.DBcc.OP5 == 5) && (op.DBcc.OP25 == 25)) {
                    952:                        if (DBcc_str [op.DBcc.cond] == NULL) break;
                    953:                        temp = buf_pos;
                    954:                        temp += rd_short ();
                    955:                        if (!is_valid_branch (temp)) break;
                    956:                        output ("db%s\td%d,", DBcc_str[op.DBcc.cond],
                    957:                                        op.DBcc.reg);
                    958:                        output_lab (temp);
                    959:                        labels [temp] |= F_LABEL;
                    960:                        if ((guessmode == GUESS_WALK) && (pass == 1)) PUSH_WS (temp);
                    961:                        goto done;
                    962:                }
                    963:                /* DIVS/DIVU */
                    964:                while ((op.type2.op == 0x8) && ((op.type2.op_mode == 0x7) || (op.type2.op_mode == 0x3))) {
                    965:                        if (op.type2.ea_mode == 0x1) break;
                    966:                        if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, 1, -1)) break;
                    967:                        if (op.type2.op_mode == 0x7) output ("divs\t");
                    968:                        else output ("divu\t");
                    969:                        put_adrmod (op.type2.ea_mode, op.type2.ea_reg, 1);
                    970:                        output (",d%d", op.type2.reg);
                    971:                        goto done;
                    972:                }
                    973:                /* EOR */
                    974:                while (op.type2.op == 0xb) {
                    975:                        if ((op.type2.op_mode < 4) || (op.type2.op_mode > 6)) break;
                    976:                        if (op.type2.ea_mode == 0x1) break;
                    977:                        if ((op.type2.ea_mode == 0x7) && (op.type2.ea_reg > 0x1)) break;
                    978:                        size = op.type2.op_mode - 4;
                    979:                        if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, size, -1)) break;
                    980:                        output ("eor%s\t", size_str [size]);
                    981:                        output ("d%d,", op.type2.reg);
                    982:                        put_adrmod (op.type2.ea_mode, op.type2.ea_reg, size);
                    983:                        goto done;
                    984:                }
                    985:                /* EORI to CCR */
                    986:                while (op.code == 0x0a3c) {
                    987:                        rd_byte ();
                    988:                        output ("eori\t#$%x,ccr", rd_byte ());
                    989:                        goto done;
                    990:                }
                    991:                /* EORI to SR */
                    992:                while (op.code == 0x0a7c) {
                    993:                        output ("eori\t#$%hx,sr", rd_short ());
                    994:                        goto done;
                    995:                }
                    996:                /* EXG */
                    997:                while ((op.exg.OP0xc == 0xc) && (op.exg.OP1 == 1)) {
                    998:                        if (op.exg.op_mode == 0x8) {
                    999:                                /* data reg swap */
                   1000:                                output ("exg\td%d,d%d", op.exg.src_reg, op.exg.dest_reg);
                   1001:                        } else if (op.exg.op_mode == 0x9) {
                   1002:                                /* address reg swap */
                   1003:                                output ("exg\ta%d,a%d", op.exg.src_reg, op.exg.dest_reg);
                   1004:                        } else if (op.exg.op_mode == 0x11) {
                   1005:                                /* data & adr reg swap */
                   1006:                                output ("exg\td%d,a%d", op.exg.src_reg, op.exg.dest_reg);
                   1007:                        } else {
                   1008:                                break;
                   1009:                        }
                   1010:                        goto done;
                   1011:                }
                   1012:                /* EXT */
                   1013:                while ((op.code & 0xfe38) == 0x4800) {
                   1014:                        if (op.type2.op_mode == 0x2) {
                   1015:                                output ("ext.w\td%d", op.type2.ea_reg);
                   1016:                        } else if (op.type2.op_mode == 0x3) {
                   1017:                                output ("ext.l\td%d", op.type2.ea_reg);
                   1018:                        } else {
                   1019:                                break;
                   1020:                        }
                   1021:                        goto done;
                   1022:                }
                   1023:                /* HOSTCALL (not 68k) */
                   1024:                while (op.code == 0x000a) {
                   1025:                        output ("hostcall");
                   1026:                        goto done;
                   1027:                }
                   1028:                /* ILLEGAL */
                   1029:                while (op.code == 0x4afc) {
                   1030:                        output ("illegal");
                   1031:                        goto done;
                   1032:                }
                   1033:                /* JMP */
                   1034:                while ((op.code & 0xffc0) == 0x4ec0) {
                   1035:                        if (op.jmp.dest_mode == 0) break;
                   1036:                        if (op.jmp.dest_mode == 1) break;
                   1037:                        if (op.jmp.dest_mode == 3) break;
                   1038:                        if (op.jmp.dest_mode == 4) break;
                   1039:                        if ((op.jmp.dest_mode == 7) &&
                   1040:                            (op.jmp.dest_reg == 4)) break;
                   1041:                        if (!is_adrmod (op.jmp.dest_mode, op.jmp.dest_reg, 2, -1)) break;
                   1042:                        output ("jmp\t");
                   1043:                        temp = put_adrmod (op.jmp.dest_mode, op.jmp.dest_reg, 2);
                   1044:                        if ((guessmode == GUESS_WALK) && (pass == 1)) {
                   1045:                                if (temp != 0xdeadbeef) buf_pos = temp;
                   1046:                                else buf_pos = POP_WS ();
                   1047:                        }
                   1048:                        goto done;
                   1049:                }
                   1050:                /* JSR */
                   1051:                while ((op.code & 0xffc0) == 0x4e80) {
                   1052:                        if (op.type1.ea_mode == 0) break;
                   1053:                        if (op.type1.ea_mode == 1) break;
                   1054:                        if (op.type1.ea_mode == 3) break;
                   1055:                        if (op.type1.ea_mode == 4) break;
                   1056:                        /* no immediate dest */
                   1057:                        if ((op.type1.ea_mode == 7) && (op.type1.ea_reg == 4)) break;
                   1058:                        if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, 2, -1)) break;
                   1059:                        output ("jsr\t");
                   1060:                        temp = put_adrmod (op.type1.ea_mode, op.type1.ea_reg, 2);
                   1061:                        if ((guessmode == GUESS_WALK) && (pass == 1) && (temp != 0xdeadbeef)) {
                   1062:                                PUSH_WS (temp);
                   1063:                        }
                   1064:                        goto done;
                   1065:                }
                   1066:                /* LEA */
                   1067:                while ((op.lea.SEVEN == 7) && (op.lea.FOUR == 4)) {
                   1068:                        if (op.lea.dest_mode == 0) break;
                   1069:                        if (op.lea.dest_mode == 1) break;
                   1070:                        if (op.lea.dest_mode == 3) break;
                   1071:                        if (op.lea.dest_mode == 4) break;
                   1072:                        /* no immediate dest */
                   1073:                        if ((op.lea.dest_mode == 7) && (op.lea.dest_reg == 4)) break;
                   1074:                        if (!is_adrmod (op.lea.dest_mode, op.lea.dest_reg, 2, -1)) break;
                   1075:                        output ("lea\t");
                   1076:                        put_adrmod (op.lea.dest_mode, op.lea.dest_reg, 2);
                   1077:                        output (",a%d", op.lea.reg);
                   1078:                        goto done;
                   1079:                }
                   1080:                /* LINK */
                   1081:                while ((op.code & 0xfff8) == 0x4e50) {
                   1082:                        output ("link\ta%d,", op.type1.ea_reg);
                   1083:                        put_imm (1);
                   1084:                        goto done;
                   1085:                }
                   1086:                /* MOVE/MOVEA */
                   1087:                while (op.move.op == 0) {
                   1088:                        if (op.move.size == 0) break;
                   1089:                        /* byte size and address reg direct is not allowed */
                   1090:                        if ((op.move.size == 1) && (op.move.src_mode == 0x1)) break;
                   1091:                        if ((op.move.size == 1) && (op.move.dest_mode == 0x1)) break;
                   1092:                        if (op.move.dest_mode == 0x7) {
                   1093:                                if (op.move.dest_reg > 1) break;
                   1094:                        }
                   1095:                        size = move_size [op.move.size];
                   1096:                        if (!is_adrmod (op.move.src_mode, op.move.src_reg, size, -1)) break;
                   1097:                        if ((op.move.src_mode == 0x7) && (op.move.src_reg == 0x4)) {
                   1098:                                /* immediate crap in the source so we must skip it */
                   1099:                                if (!is_adrmod (op.move.dest_mode, op.move.dest_reg, size, size)) break;
                   1100:                        } else if ((op.move.src_mode == 0x7) && (op.move.src_reg > 0x1)) {
                   1101:                                if (!is_adrmod (op.move.dest_mode, op.move.dest_reg, size, 1)) break;
                   1102:                        } else if ((op.move.src_mode == 0x7) && (op.move.src_reg == 0x1)) {
                   1103:                                if (!is_adrmod (op.move.dest_mode, op.move.dest_reg, size, 2)) break;
                   1104:                        } else if ((op.move.src_mode == 0x7) && (op.move.src_reg == 0x0)) {
                   1105:                                if (!is_adrmod (op.move.dest_mode, op.move.dest_reg, size, 1)) break;
                   1106:                        } else if ((op.move.src_mode == 0x6) || (op.move.src_mode == 0x5)) {
                   1107:                                /* PC with disp + Dx, (Ax) with disp + Dx */
                   1108:                                if (!is_adrmod (op.move.dest_mode, op.move.dest_reg, size, 1)) break;
                   1109:                        } else {
                   1110:                                if (!is_adrmod (op.move.dest_mode, op.move.dest_reg, size, -1)) break;
                   1111:                        }
                   1112:                        if (op.move.dest_mode == 0x1) {
                   1113:                                output ("movea%s\t", size_str[size]);
                   1114:                        } else {
                   1115:                                output ("move%s\t", size_str[size]);
                   1116:                        }
                   1117:                        
                   1118:                        put_adrmod (op.move.src_mode, op.move.src_reg, size);
                   1119:                        output (",");
                   1120:                        put_adrmod (op.move.dest_mode, op.move.dest_reg, size);
                   1121:                        goto done;
                   1122:                }
                   1123:                /* MOVE to CCR */
                   1124:                while ((op.code & 0xffc0) == 0x44c0) {
                   1125:                        if (op.type1.ea_mode == 0x1) break;
                   1126:                        if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, 1, -1)) break;
                   1127:                        output ("move.w\t");
                   1128:                        put_adrmod (op.type1.ea_mode, op.type1.ea_reg, 1);
                   1129:                        output (",ccr");
                   1130:                        goto done;
                   1131:                }
                   1132:                /* MOVE from SR */
                   1133:                while ((op.code & 0xffc0) == 0x40c0) {
                   1134:                        if (op.type1.ea_mode == 0x1) break;
                   1135:                        if ((op.type1.ea_mode == 0x7) && (op.type1.ea_reg > 0x1)) break;
                   1136:                        if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, 1, -1)) break;
                   1137:                        output ("move.w\tsr,");
                   1138:                        put_adrmod (op.type1.ea_mode, op.type1.ea_reg, 1);
                   1139:                        goto done;
                   1140:                }
                   1141:                /* MOVE to SR */
                   1142:                while ((op.code & 0xffc0) == 0x46c0) {
                   1143:                        if (op.type1.ea_mode == 0x1) break;
                   1144:                        if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, 1, -1)) break;
                   1145:                        output ("move.w\t");
                   1146:                        put_adrmod (op.type1.ea_mode, op.type1.ea_reg, 1);
                   1147:                        output (",sr");
                   1148:                        goto done;
                   1149:                }
                   1150:                /* MOVE USP */
                   1151:                while ((op.code & 0xfff0) == 0x4e60) {
                   1152:                        if (op.addx.rm) {
                   1153:                                /* USP to Ax */
                   1154:                                output ("move.l\tusp,a%d", op.addx.src_reg);
                   1155:                        } else {
                   1156:                                output ("move.l\ta%d,usp", op.addx.src_reg);
                   1157:                        }
                   1158:                        goto done;
                   1159:                }
                   1160:                /* TODO MOVEC */
                   1161:                /* TODO MOVEP */
                   1162:                /* MOVEM */
                   1163:                while ((op.movem.NINE == 9) && (op.movem.ONE == 1)) {
                   1164:                        if (op.movem.dr) {
                   1165:                                /* memory to register */
                   1166:                                if (op.movem.dest_mode < 2) break;
                   1167:                                if (op.movem.dest_mode == 4) break;
                   1168:                                if ((op.movem.dest_mode == 7) && (op.movem.dest_reg == 4)) break;
                   1169:                                if (!is_adrmod (op.movem.dest_mode, op.movem.dest_reg, op.movem.sz+1, 1)) break;
                   1170:                                temp = rd_short ();
                   1171:                                output ("movem%s\t", size_str [op.movem.sz+1]);
                   1172:                                put_adrmod (op.movem.dest_mode, op.movem.dest_reg, op.movem.sz+1);
                   1173:                                output (",");
                   1174:                                put_movem_regs (temp, 0);
                   1175:                        } else {
                   1176:                                /* register to memory */
                   1177:                                if (op.movem.dest_mode < 2) break;
                   1178:                                if (op.movem.dest_mode == 3) break;
                   1179:                                if ((op.movem.dest_mode == 7) && (op.movem.dest_reg > 1)) break;
                   1180:                                if (!is_adrmod (op.movem.dest_mode, op.movem.dest_reg, op.movem.sz+1, 1)) break;
                   1181:                                output ("movem%s\t", size_str [op.movem.sz+1]);
                   1182:                                put_movem_regs (rd_short (), (op.movem.dest_mode == 4));
                   1183:                                output (",");
                   1184:                                put_adrmod (op.movem.dest_mode, op.movem.dest_reg, op.movem.sz+1);
                   1185:                        }
                   1186:                        goto done;
                   1187:                }
                   1188:                /* MOVEQ */
                   1189:                while ((op.moveq.SEVEN == 7) && (op.moveq.ZERO == 0)) {
                   1190:                        output ("moveq\t#%d,d%d", op.moveq.data, op.moveq.reg);
                   1191:                        goto done;
                   1192:                }
                   1193:                /* MULS/MULU */
                   1194:                while ((op.type2.op == 0xc) && ((op.type2.op_mode == 0x7) || (op.type2.op_mode == 0x3))) {
                   1195:                        if (op.type2.ea_mode == 0x1) break;
                   1196:                        if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, 1, -1)) break;
                   1197:                        if (op.type2.op_mode == 0x7) output ("muls\t");
                   1198:                        else output ("mulu\t");
                   1199:                        put_adrmod (op.type2.ea_mode, op.type2.ea_reg, 1);
                   1200:                        output (",d%d", op.type2.reg);
                   1201:                        goto done;
                   1202:                }
                   1203:                /* NBCD */
                   1204:                while ((op.code & 0xffc0) == 0x4800) {
                   1205:                        if (op.type1.ea_mode == 0x1) break;
                   1206:                        if ((op.type1.ea_mode == 0x7) && (op.type1.ea_reg > 1)) break;
                   1207:                        if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, 0, -1)) break;
                   1208:                        output ("nbcd\t");
                   1209:                        put_adrmod (op.type1.ea_mode, op.type1.ea_reg, 0);
                   1210:                        goto done;
                   1211:                }
                   1212:                /* NEG/NEGX/NOT */
                   1213:                while ((op.type1.op == 0x44) || (op.type1.op == 0x40) || (op.type1.op == 0x46)) {
                   1214:                        if (op.type1.size == 3) break;
                   1215:                        if (op.type1.ea_mode == 0x1) break;
                   1216:                        if ((op.type1.ea_mode == 0x7) && (op.type1.ea_reg > 1)) break;
                   1217:                        if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size, -1)) break;
                   1218:                        if (op.type1.op == 0x44) output ("neg%s\t", size_str [op.type1.size]);
                   1219:                        else if (op.type1.op == 0x40) output ("negx%s\t", size_str [op.type1.size]);
                   1220:                        else output ("not%s\t", size_str [op.type1.size]);
                   1221:                        put_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size);
                   1222:                        goto done;
                   1223:                }
                   1224:                /* NOP */
                   1225:                while (op.code == 0x4e71) {
                   1226:                        output ("nop");
                   1227:                        goto done;
                   1228:                }
                   1229:                /* ORI to CCR */
                   1230:                while (op.code == 0x003c) {
                   1231:                        rd_byte ();
                   1232:                        output ("ori\t#$%x,ccr", rd_byte ());
                   1233:                        goto done;
                   1234:                }
                   1235:                /* ORI to SR */
                   1236:                while (op.code == 0x007c) {
                   1237:                        output ("ori\t#$%hx,sr", rd_short ());
                   1238:                        goto done;
                   1239:                }
                   1240:                /* PEA */
                   1241:                while ((op.code & 0xffc0) == 0x4840) {
                   1242:                        if (op.type1.ea_mode < 2) break;
                   1243:                        if (op.type1.ea_mode == 3) break;
                   1244:                        if (op.type1.ea_mode == 4) break;
                   1245:                        if ((op.type1.ea_mode == 7) && (op.type1.ea_reg == 4)) break;
                   1246:                        if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size, -1)) break;
                   1247:                        output ("pea\t");
                   1248:                        put_adrmod (op.type1.ea_mode, op.type1.ea_reg, 2);
                   1249:                        goto done;
                   1250:                }
                   1251:                /* RESET */
                   1252:                while (op.code == 0x4e70) {
                   1253:                        output ("reset");
                   1254:                        goto done;
                   1255:                }
                   1256:                /* RTE */
                   1257:                while (op.code == 0x4e73) {
                   1258:                        output ("rte");
                   1259:                        if ((guessmode == GUESS_WALK) && (pass == 1)) buf_pos = POP_WS ();
                   1260:                        goto done;
                   1261:                }
                   1262:                /* RTR */
                   1263:                while (op.code == 0x4e77) {
                   1264:                        output ("rtr");
                   1265:                        goto done;
                   1266:                }
                   1267:                /* RTS */
                   1268:                while (op.code == 0x4e75) {
                   1269:                        output ("rts");
                   1270:                        if ((guessmode == GUESS_WALK) && (pass == 1)) buf_pos = POP_WS ();
                   1271:                        goto done;
                   1272:                }
                   1273:                /* Scc */
                   1274:                while ((op.code & 0xf0c0) == 0x50c0) {
                   1275:                        if (op.type1.ea_mode == 1) break;
                   1276:                        if ((op.type1.ea_mode == 7) && (op.type1.ea_reg > 1)) break;
                   1277:                        if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, 0, -1)) break;
                   1278:                        output ("s%s\t", Scc_str[op.DBcc.cond]);
                   1279:                        put_adrmod (op.type1.ea_mode, op.type1.ea_reg, 0);
                   1280:                        goto done;
                   1281:                }
                   1282:                /* STOP */
                   1283:                while (op.code == 0x4e72) {
                   1284:                        output ("stop\t");
                   1285:                        put_imm (1);
                   1286:                        goto done;
                   1287:                }
                   1288:                /* SWAP */
                   1289:                while ((op.code & 0xfff8) == 0x4840) {
                   1290:                        output ("swap\td%d", op.code & 0x7);
                   1291:                        goto done;
                   1292:                }
                   1293:                /* TAS */
                   1294:                while ((op.code & 0xffc0) == 0x4ac0) {
                   1295:                        if (op.type1.ea_mode == 0x1) break;
                   1296:                        if ((op.type1.ea_mode == 0x7) && (op.type1.ea_reg > 0x1)) break;
                   1297:                        if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, 0, -1)) break;
                   1298:                        output ("tas\t");
                   1299:                        put_adrmod (op.type1.ea_mode, op.type1.ea_reg, 0);
                   1300:                        goto done;
                   1301:                }
                   1302:                /* TRAP */
                   1303:                while ((op.code & 0xfff0) == 0x4e40) {
                   1304:                        output ("trap\t#%d", op.code & 0xf);
                   1305:                        goto done;
                   1306:                }
                   1307:                /* TRAPV */
                   1308:                while (op.code == 0x4e76) {
                   1309:                        output ("trapv");
                   1310:                        goto done;
                   1311:                }
                   1312:                /* TST */
                   1313:                while (op.type1.op == 0x4a) {
                   1314:                        if (op.type1.size == 3) break;
                   1315:                        /* no address reg direct */
                   1316:                        if (op.type1.ea_mode == 0x1) break;
                   1317:                        /* no immediate or pc relative dest */
                   1318:                        if ((op.type1.ea_mode == 0x7) && (op.type1.ea_reg > 0x1)) break;
                   1319:                        if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size, -1)) break;
                   1320:                        output ("tst%s\t", size_str[op.type1.size]);
                   1321:                        put_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size);
                   1322:                        goto done;
                   1323:                }
                   1324:                /* UNLK */
                   1325:                while ((op.code & 0xfff8) == 0x4e58) {
                   1326:                        output ("unlk\ta%d", op.code & 0x7);
                   1327:                        goto done;
                   1328:                }
                   1329:                /* fuck knows */
                   1330:                output ("dc.w\t$%hx", op.code);
                   1331:                fprintf (stderr, "Eeek. Unknown opcode 0x%hx at 0x%x.\n", op.code, buf_pos-2);
                   1332:                labels[buf_pos-2] |= F_DUNNO;
                   1333:                labels[buf_pos-1] |= F_DUNNO;
                   1334:                if (buf_pos == end) break;
                   1335:                else continue;
                   1336: done:
                   1337:                /* this isn't data */
                   1338:                if ((guessmode == GUESS_WALK) && (pass == 1)) {
                   1339:                        labels[last_ip] |= F_WALKED_CODE;
                   1340:                        labels[last_ip+1] |= F_WALKED_CODE;
                   1341:                }
                   1342:                continue;
                   1343:        }
                   1344:        output ("\r\n");
                   1345: }
                   1346: 
                   1347: /*
                   1348:  * Pass 0 as reloc for first fixup address, otherwise
                   1349:  * pass returned valu. if returned value == 0 you are at the fucking end, man.
                   1350:  */
                   1351: int get_fixup (int reloc)
                   1352: {
                   1353:        int old_bufpos;
                   1354:        int next;
                   1355:        static int reloc_pos;
                   1356: 
                   1357:        old_bufpos = buf_pos;
                   1358:        if (reloc == 0) {
                   1359:                buf_pos = end;
                   1360:                reloc = rd_int ();
                   1361:                reloc_pos = buf_pos;
                   1362:                buf_pos = old_bufpos;
                   1363:                if (reloc == 0) return 0;
                   1364:                else return base + reloc;
                   1365:        } else {
                   1366:                buf_pos = reloc_pos;
                   1367: again:
                   1368:                next = rd_byte ();
                   1369:                if (next == 0) {
                   1370:                        buf_pos = old_bufpos;
                   1371:                        return 0;
                   1372:                }
                   1373:                else if (next == 1) {
                   1374:                        reloc += 254;
                   1375:                        goto again;
                   1376:                }
                   1377:                else reloc += next;
                   1378:                reloc_pos = buf_pos;
                   1379:                buf_pos = old_bufpos;
                   1380:                return reloc;
                   1381:        }
                   1382: }
                   1383: 
                   1384: void do_fixups ()
                   1385: {
                   1386:        int reloc, next;
                   1387:        int pos;
                   1388: 
                   1389:        reloc = get_fixup (0);
                   1390:        fprintf (stderr, "relocs: ");
                   1391:        while (reloc) {
                   1392:                fprintf (stderr, "0x%x ", reloc);
                   1393:                pos = buf_pos;
                   1394:                /* address to be modified */
                   1395:                buf_pos = reloc;
                   1396:                labels [buf_pos] |= F_USELAB;
                   1397:                next = rd_int ();
                   1398:                next += base;
                   1399:                buf_pos -= 4;
                   1400:                wr_int (next);
                   1401:                if (next > end) {
                   1402:                        printf ("Reloc label 0x%x out of range...\n", next);
                   1403:                } else {
                   1404:                        labels [next] |= F_LABEL | F_LABEL_MAJOR;
                   1405:                }
                   1406:                buf_pos = pos;
                   1407: 
                   1408:                reloc = get_fixup (reloc);
                   1409:        }
                   1410:        fprintf (stderr, "\n");
                   1411: }
                   1412: 
                   1413: void guess_datasegs ()
                   1414: {
                   1415:        //int reloc;
                   1416:        int next, dist;
                   1417:        int pos, sec_start, num_dunno, prop;
                   1418: 
                   1419:        if (guessmode == GUESS_WALK) {
                   1420: #if 0
                   1421:                /* 0x4e75 (rts) with label infront is often a function */
                   1422:                for (next = end-3; next >= base; next--) {
                   1423:                        buf_pos = next;
                   1424:                        /* rts */
                   1425:                        if (rd_short () == 0x4e75) {
                   1426:                                /* label after */
                   1427:                                if (!(labels[buf_pos] & F_LABEL)) continue;
                   1428:                                /* zoom to label before this rts */
                   1429:                                for (; next >= base; next--) {
                   1430:                                        if (labels[next] & F_LABEL) break;
                   1431:                                        if (labels[next] & F_WALKED_CODE) break;
                   1432:                                }
                   1433:                                PUSH_WS (end);
                   1434:                                buf_pos = next;
                   1435:                                dump_code ();
                   1436:                        }
                   1437:                }
                   1438:                /* fixup sections ending in 0x4e75 (rts) are probably functions
                   1439:                 * not data */
                   1440:                reloc = get_fixup (0);
                   1441:                while (reloc) {
                   1442:                        /* scan to first label and see if the previous word is
                   1443:                         * an rts */
                   1444:                        for (next = reloc; next < end; next++) {
                   1445:                                if (labels[next] & F_LABEL) break;
                   1446:                        }
                   1447:                        buf_pos = next-2;
                   1448:                        if (rd_short() == 0x4e75) {
                   1449:                                /* grope section as code (find start label) */
                   1450:                                for (next = reloc; next >= base; next--) {
                   1451:                                        if (labels[next] & F_LABEL) break;
                   1452:                                }
                   1453:                                PUSH_WS (end);
                   1454:                                buf_pos = next;
                   1455:                                dump_code ();
                   1456:                        }
                   1457:                        reloc = get_fixup (reloc);
                   1458:                }
                   1459: #endif /* 0 */
                   1460:                /* turn everything not F_WALKED_CODE into F_GUESS_DATA */
                   1461:                for (pos=base; pos<end; pos++) {
                   1462:                        if (!(labels[pos] & F_WALKED_CODE)) {
                   1463:                                labels[pos] |= F_GUESS_DATA;
                   1464:                        }
                   1465:                }
                   1466:                goto skip_simple;
                   1467:        }
                   1468:        /* if there is a good proportion of F_DUNNOs (unknown opcodes) between
                   1469:         * 2 labels then the entire section is probably data */
                   1470:        pos=base;
                   1471:        sec_start=base;
                   1472:        num_dunno=0;
                   1473:        for (;; pos++) {
                   1474:                if ((labels [pos] & F_LABEL) || (pos == end)) {
                   1475:                        /* new section */
                   1476:                        if (pos != base) {
                   1477:                                dist = pos - sec_start;
                   1478:                                /* proportion of dunnos */
                   1479:                                prop = (100*num_dunno)/dist;
                   1480:                                probs[sec_start] = prop;
                   1481:                                //printf ("Section prop %d%% (pos 0x%x to 0x%x)\n", prop, sec_start, pos-1);
                   1482:                                if (prop > 0) {
                   1483:                                        while (sec_start < pos) {
                   1484:                                                labels [sec_start++] |= F_GUESS_DATA;
                   1485:                                        }
                   1486:                                }
                   1487:                        }
                   1488:                        sec_start = pos;
                   1489:                        num_dunno = 0;
                   1490:                }
                   1491:                if (pos >= end) break;
                   1492:                if (labels [pos] & F_DUNNO) {
                   1493:                        num_dunno++;
                   1494:                }
                   1495:        }
                   1496: skip_simple:
                   1497:        /* grope for possible text areas */
                   1498:        for (pos=base, dist=0; pos<end; pos++) {
                   1499:                buf_pos = pos;
                   1500:                next = rd_byte ();
                   1501:                /* labels break runs of ascii characters */
                   1502:                if (labels [pos] & F_LABEL) dist = 0;
                   1503:                if (!(labels [pos] & F_GUESS_DATA)) dist = 0;
                   1504:                if ((next >= ' ') && (next <= 126)) {
                   1505:                        dist++;
                   1506:                } else {
                   1507:                        dist = 0;
                   1508:                }
                   1509:                if (dist == 5) {
                   1510:                        labels [pos-4] |= F_GUESS_STRING;
                   1511:                        labels [pos-3] |= F_GUESS_STRING;
                   1512:                        labels [pos-2] |= F_GUESS_STRING;
                   1513:                        labels [pos-1] |= F_GUESS_STRING;
                   1514:                }
                   1515:                if (dist >= 5) {
                   1516:                        labels [pos] |= F_GUESS_STRING;
                   1517:                }
                   1518:        }
                   1519: }
                   1520: 
                   1521: int main (int argc, char **argv)
                   1522: {
                   1523:        int i, pos, from, to;
                   1524:        FILE *fptr;
                   1525:        
                   1526:        if (argc < 2) {
                   1527:                printf ("Usage: ./thing {-gs|-gw {-codestart addr, addr, ... } {-codestop addr, addr, ... } { -labeltab from,to from2,to2 ... } some.prg\n");
                   1528:                printf (" -gs  Simple data section guessing.\n");
                   1529:                printf (" -gw  'Walking' data section guessing.\n");
                   1530:                printf (" -codestart/stop are for -gw mode, when it fucks up its\n");
                   1531:                printf ("    walk over the code and misses some code or disassembles\n");
                   1532:                printf ("    data.\n");
                   1533:                printf (" -labeltab is for raw reloc thingies. ie dc.l label, which\n");
                   1534:                printf ("    have a fixup and must  be preserved.\n");
                   1535:                exit (0);
                   1536:        }
                   1537: 
                   1538:        if ((fptr = fopen (argv[argc-1], "r"))==NULL) {
                   1539:                fprintf (stderr, "Could not open %s.\n", argv[argc-1]);
                   1540:                exit (0);
                   1541:        }
                   1542:        fseek (fptr, 0, SEEK_END);
                   1543:        end = ftell (fptr);
                   1544:        fseek (fptr, 0, SEEK_SET);
                   1545:        buffer = malloc (end);
                   1546:        fread (buffer, 1, end, fptr);
                   1547:        fclose (fptr);
                   1548: 
                   1549:        buf_pos = 2;
                   1550:        end = base + rd_int ();
                   1551:        
                   1552:        labels = malloc (end*sizeof (short));
                   1553:        memset (labels, 0, end*sizeof (short));
                   1554: 
                   1555:        guessmode = GUESS_NONE;
                   1556:        if (argc > 2) {
                   1557:                if (strcmp (argv[1], "-gs")==0) guessmode = GUESS_SIMPLE;
                   1558:                else if (strcmp (argv[1], "-gw")==0) {
                   1559:                        guessmode = GUESS_WALK;
                   1560:                        PUSH_WS (end);
                   1561:                        i = 2;
                   1562:                        if (strcmp (argv[i], "-codestart")==0) {
                   1563:                                for (i+=1; i<argc-1; i++) {
                   1564:                                        pos = strtol (argv[i], NULL, 0);
                   1565:                                        if (pos == 0) break;
                   1566:                                        PUSH_WS (pos);
                   1567:                                        fprintf (stderr, "Code start 0x%x\n", pos);
                   1568:                                }
                   1569:                        }
                   1570:                        if (strcmp (argv[i], "-codestop")==0) {
                   1571:                                for (i+=1; i<argc-1; i++) {
                   1572:                                        pos = strtol (argv[i], NULL, 0);
                   1573:                                        if (pos == 0) break;
                   1574:                                        labels[pos] |= F_CODE_STOP;
                   1575:                                        fprintf (stderr, "Code stop 0x%x\n", pos);
                   1576:                                }
                   1577:                        }
                   1578:                        if (strcmp (argv[i], "-labeltab")==0) {
                   1579:                                for (i+=1; i<argc-1; i++) {
                   1580:                                        if (sscanf (argv[i], "%x,%x", &from, &to) != 2) {
                   1581:                                                fprintf (stderr, "Malformed -labeltab address.\n");
                   1582:                                                break;
                   1583:                                        } else {
                   1584:                                                fprintf (stderr, "Labeltable 0x%x to 0x%x\n", from, to);
                   1585:                                                for (; from <= to; from++) {
                   1586:                                                        labels[from] |= F_LABEL_TABLE;
                   1587:                                                }
                   1588:                                        }
                   1589:                                }
                   1590:                        }
                   1591:                }
                   1592:        }
                   1593: 
                   1594:        probs = malloc (end);
                   1595:        memset (probs, 0, end);
                   1596:        do_fixups ();
                   1597: 
                   1598:        buf_pos = base;
                   1599:        dump_code ();
                   1600:        
                   1601:        if (guessmode) guess_datasegs ();
                   1602:        pass = 2;
                   1603: 
                   1604:        PUSH_WS (end);
                   1605:        buf_pos = base;
                   1606:        dump_code ();
                   1607:        return 0;
                   1608: }
                   1609: 

unix.superglobalmegacorp.com

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