Annotation of uae/gencpu.c, revision 1.1

1.1     ! root        1: /* 
        !             2:  * UAE - The Un*x Amiga Emulator
        !             3:  *
        !             4:  * MC68000 emulation generator
        !             5:  *
        !             6:  * This is a fairly stupid program that generates a lot of case labels that 
        !             7:  * can be #included in a switch statement.
        !             8:  * As an alternative, it can generate functions that handle specific
        !             9:  * MC68000 instructions, plus a prototype header file and a function pointer
        !            10:  * array to look up the function for an opcode.
        !            11:  * Error checking is bad, an illegal table68k file will cause the program to
        !            12:  * call abort().
        !            13:  * The generated code is sometimes sub-optimal, an optimizing compiler should 
        !            14:  * take care of this.
        !            15:  * 
        !            16:  * (c) 1995 Bernd Schmidt
        !            17:  * 
        !            18:  */
        !            19: 
        !            20: #include <assert.h>
        !            21: #include <string.h>
        !            22: #include <stdio.h>
        !            23: #include <stdlib.h>
        !            24: #include <ctype.h>
        !            25: 
        !            26: #include "config.h"
        !            27: #include "amiga.h"
        !            28: 
        !            29: typedef enum {
        !            30:   Dreg, Areg, Aind, Aipi, Apdi, Ad16, Ad8r, 
        !            31:   absw, absl, PC16, PC8r, imm, imm0, imm1, imm2, immi, am_unknown, am_illg
        !            32: } amodes;
        !            33: 
        !            34: FILE *tablef;
        !            35: int nextch = 0;
        !            36: 
        !            37: typedef enum {
        !            38:     i_ILLG,
        !            39:     
        !            40:     i_OR, i_AND, i_EOR, i_ORSR, i_ANDSR, i_EORSR, 
        !            41:     i_SUB, i_SUBA, i_SUBX, i_SBCD, 
        !            42:     i_ADD, i_ADDA, i_ADDX, i_ABCD,
        !            43:     i_NEG, i_NEGX, i_NBCD, i_CLR, i_NOT, i_TST, 
        !            44:     i_BTST, i_BCHG, i_BCLR, i_BSET,
        !            45:     i_CMP, i_CMPM, i_CMPA, 
        !            46:     i_MOVEP, i_MOVE, i_MOVEA, i_MVSR2, i_MV2SR, 
        !            47:     i_SWAP, i_EXG, i_EXT, i_MVMEL, i_MVMLE, 
        !            48:     i_TRAP, i_MVR2USP, i_MVUSP2R, i_RESET, i_NOP, i_STOP, i_RTE, i_RTD, 
        !            49:     i_LINK, i_UNLK, 
        !            50:     i_RTS, i_TRAPV, i_RTR, 
        !            51:     i_JSR, i_JMP, i_BSR, i_Bcc,
        !            52:     i_LEA, i_PEA, i_DBcc, i_Scc, 
        !            53:     i_DIVU, i_DIVS, i_MULU, i_MULS, 
        !            54:     i_ASR, i_ASL, i_LSR, i_LSL, i_ROL, i_ROR, i_ROXL, i_ROXR,
        !            55:     i_ASRW, i_ASLW, i_LSRW, i_LSLW, i_ROLW, i_RORW, i_ROXLW, i_ROXRW
        !            56: } instrmnem;
        !            57: 
        !            58: struct mnemolookup {
        !            59:     instrmnem mnemo;
        !            60:     char name[10];
        !            61: } lookuptab[] = {
        !            62:     { i_OR, "OR" },
        !            63:     { i_AND, "AND" }, 
        !            64:     { i_EOR, "EOR" },
        !            65:     { i_ORSR, "ORSR" }, 
        !            66:     { i_ANDSR, "ANDSR" }, 
        !            67:     { i_EORSR, "EORSR" }, 
        !            68:     { i_SUB, "SUB" }, 
        !            69:     { i_SUBA, "SUBA" }, 
        !            70:     { i_SUBX, "SUBX" }, 
        !            71:     { i_SBCD, "SBCD" }, 
        !            72:     { i_ADD, "ADD" }, 
        !            73:     { i_ADDA, "ADDA" }, 
        !            74:     { i_ADDX, "ADDX" }, 
        !            75:     { i_ABCD, "ABCD" },
        !            76:     { i_NEG, "NEG" }, 
        !            77:     { i_NEGX, "NEGX" }, 
        !            78:     { i_NBCD, "NBCD" }, 
        !            79:     { i_CLR, "CLR" }, 
        !            80:     { i_NOT, "NOT" }, 
        !            81:     { i_TST, "TST" }, 
        !            82:     { i_BTST, "BTST" }, 
        !            83:     { i_BCHG, "BCHG" }, 
        !            84:     { i_BCLR, "BCLR" }, 
        !            85:     { i_BSET, "BSET" },
        !            86:     { i_CMP, "CMP" }, 
        !            87:     { i_CMPM, "CMPM" }, 
        !            88:     { i_CMPA, "CMPA" }, 
        !            89:     { i_MOVEP, "MOVEP" },
        !            90:     { i_MOVE, "MOVE" }, 
        !            91:     { i_MOVEA, "MOVEA" },
        !            92:     { i_MVSR2, "MVSR2" },
        !            93:     { i_MV2SR, "MV2SR" }, 
        !            94:     { i_SWAP, "SWAP" },
        !            95:     { i_EXG, "EXG" },
        !            96:     { i_EXT, "EXT" },
        !            97:     { i_MVMEL, "MVMEL" }, 
        !            98:     { i_MVMLE, "MVMLE" }, 
        !            99:     { i_TRAP, "TRAP" },
        !           100:     { i_MVR2USP, "MVR2USP" }, 
        !           101:     { i_MVUSP2R, "MVUSP2R" }, 
        !           102:     { i_RESET, "RESET" },
        !           103:     { i_NOP, "NOP" },
        !           104:     { i_STOP, "STOP" },
        !           105:     { i_RTE, "RTE" },
        !           106:     { i_RTD, "RTD" }, 
        !           107:     { i_LINK, "LINK" },
        !           108:     { i_UNLK, "UNLK" }, 
        !           109:     { i_RTS, "RTS" }, 
        !           110:     { i_TRAPV, "TRAPV" }, 
        !           111:     { i_RTR, "RTR" }, 
        !           112:     { i_JSR, "JSR" },
        !           113:     { i_JMP, "JMP" },
        !           114:     { i_BSR, "BSR" },
        !           115:     { i_Bcc, "Bcc" },
        !           116:     { i_LEA, "LEA" },
        !           117:     { i_PEA, "PEA" },
        !           118:     { i_DBcc, "DBcc" }, 
        !           119:     { i_Scc, "Scc" }, 
        !           120:     { i_DIVU, "DIVU" }, 
        !           121:     { i_DIVS, "DIVS" },
        !           122:     { i_MULU, "MULU" },
        !           123:     { i_MULS, "MULS" }, 
        !           124:     { i_ASR, "ASR" },
        !           125:     { i_ASL, "ASL" },
        !           126:     { i_LSR, "LSR" },
        !           127:     { i_LSL, "LSL" },
        !           128:     { i_ROL, "ROL" },
        !           129:     { i_ROR, "ROR" },
        !           130:     { i_ROXL, "ROXL" },
        !           131:     { i_ROXR, "ROXR" },
        !           132:     { i_ASRW, "ASRW" },
        !           133:     { i_ASLW, "ASLW" },
        !           134:     { i_LSRW, "LSRW" },
        !           135:     { i_LSLW, "LSLW" },
        !           136:     { i_ROLW, "ROLW" },
        !           137:     { i_RORW, "RORW" },
        !           138:     { i_ROXLW, "ROXLW" },
        !           139:     { i_ROXRW, "ROXRW" }
        !           140: };
        !           141: 
        !           142: char patbits[16];
        !           143: char opcstr[256];
        !           144: 
        !           145: UWORD bitmask,bitpattern;
        !           146: 
        !           147: typedef enum {
        !           148:     bit0, bit1, bitc, bitC, bitf, biti, bitI, bitj, bitJ, bits, bitS, bitd, bitD, bitr, bitR, bitz, lastbit
        !           149: } bitvals;
        !           150: 
        !           151: typedef enum {
        !           152:     sz_unknown, sz_byte, sz_word, sz_long
        !           153: } wordsizes;
        !           154: 
        !           155: struct instr {
        !           156:     instrmnem mnemo;
        !           157:     wordsizes size;
        !           158:     amodes dmode, smode;
        !           159:     unsigned char dreg;
        !           160:     unsigned char sreg;
        !           161:     unsigned int suse:1;
        !           162:     unsigned int duse:1;
        !           163:     unsigned int sbtarg:1;
        !           164:     unsigned int generated:1;
        !           165:     unsigned int cc:4;
        !           166:     signed char dpos;
        !           167:     signed char spos;
        !           168:     UWORD handler;
        !           169: } *table;
        !           170: 
        !           171: #ifdef DEBUG
        !           172: static void myabort(void)
        !           173: {
        !           174:     abort();
        !           175: }
        !           176: #else 
        !           177: #define myabort abort
        !           178: #endif
        !           179: static void getnextch(void)
        !           180: {
        !           181:     do {
        !           182:        nextch = fgetc(tablef);
        !           183:        if (nextch == '%') {
        !           184:            do {
        !           185:                nextch = fgetc(tablef);
        !           186:            } while (nextch != EOF && nextch != '\n');  
        !           187:        }
        !           188:     } while (nextch != EOF && isspace(nextch));        
        !           189: }
        !           190: 
        !           191: static void get_bits(void)
        !           192: {
        !           193:     int i;
        !           194:     
        !           195:     bitmask = bitpattern = 0;
        !           196:     for(i=0; i<16; i++) {
        !           197:        bitmask <<= 1;
        !           198:        bitpattern <<= 1;
        !           199:        if (nextch == '0' || nextch == '1') bitmask |= 1;
        !           200:        if (nextch == '1') bitpattern |= 1;
        !           201:        patbits[i] = nextch;
        !           202:        getnextch();
        !           203:     }
        !           204: }
        !           205: 
        !           206: static amodes mode_from_str(char *str)
        !           207: {
        !           208:     if (strncmp(str,"Dreg",4) == 0) return Dreg;
        !           209:     if (strncmp(str,"Areg",4) == 0) return Areg;
        !           210:     if (strncmp(str,"Aind",4) == 0) return Aind;
        !           211:     if (strncmp(str,"Apdi",4) == 0) return Apdi;
        !           212:     if (strncmp(str,"Aipi",4) == 0) return Aipi;
        !           213:     if (strncmp(str,"Ad16",4) == 0) return Ad16;
        !           214:     if (strncmp(str,"Ad8r",4) == 0) return Ad8r;
        !           215:     if (strncmp(str,"absw",4) == 0) return absw;
        !           216:     if (strncmp(str,"absl",4) == 0) return absl;
        !           217:     if (strncmp(str,"PC16",4) == 0) return PC16;
        !           218:     if (strncmp(str,"PC8r",4) == 0) return PC8r;
        !           219:     if (strncmp(str,"Immd",4) == 0) return imm;
        !           220:     myabort();
        !           221: }
        !           222: 
        !           223: static amodes mode_from_mr(int mode, int reg) 
        !           224: {
        !           225:     switch(mode) {
        !           226:      case 0: return Dreg; 
        !           227:      case 1: return Areg;
        !           228:      case 2: return Aind;
        !           229:      case 3: return Aipi;
        !           230:      case 4: return Apdi;
        !           231:      case 5: return Ad16;
        !           232:      case 6: return Ad8r;
        !           233:      case 7: 
        !           234:        switch(reg) {
        !           235:         case 0: return absw;
        !           236:         case 1: return absl;
        !           237:         case 2: return PC16;
        !           238:         case 3: return PC8r;
        !           239:         case 4: return imm;
        !           240:         case 5:
        !           241:         case 6:
        !           242:         case 7: return am_illg;
        !           243:        }
        !           244:     }
        !           245:     myabort();
        !           246: }
        !           247: 
        !           248: static void get_strs(void)
        !           249: {
        !           250:     fgets(opcstr, 250, tablef);
        !           251:     getnextch();
        !           252: }
        !           253: 
        !           254: static void parse_bits(void)
        !           255: {
        !           256:     int find;
        !           257:     long int opc;
        !           258:     
        !           259:     for(opc = 0; opc < 65536; opc ++) {
        !           260:        if ((opc & bitmask) == bitpattern) {
        !           261:            int bitcnt[lastbit];
        !           262:            int bitval[lastbit];
        !           263:            int bitpos[lastbit];
        !           264:            int i,j;
        !           265:            
        !           266:            UWORD msk = 0x8000;
        !           267: 
        !           268:            int pos = 0;
        !           269: 
        !           270:            int mnp = 0;
        !           271:            char mnemonic[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        !           272:            wordsizes sz = sz_unknown;
        !           273:            bool srcgather = false, dstgather = false;
        !           274:            bool usesrc = false, usedst = false;
        !           275:            bool srcbtarg = false;
        !           276:            int srcpos, dstpos;
        !           277:            
        !           278:            amodes srcmode = am_unknown, destmode = am_unknown;
        !           279:            int srcreg, destreg;
        !           280:            
        !           281:            for(i=0; i < lastbit; i++) bitcnt[i] = bitval[i] = 0;
        !           282: 
        !           283:            for(j=0; j < 16; j++, msk >>= 1) {
        !           284:                bitvals currbit;
        !           285:                switch(patbits[j]) {
        !           286:                 case '0': currbit = bit0; break;
        !           287:                 case '1': currbit = bit1; break;
        !           288:                 case 'c': currbit = bitc; break;
        !           289:                 case 'C': currbit = bitC; break;
        !           290:                 case 'f': currbit = bitf; break;
        !           291:                 case 'i': currbit = biti; break;
        !           292:                 case 'I': currbit = bitI; break;
        !           293:                 case 'j': currbit = bitj; break;
        !           294:                 case 'J': currbit = bitJ; break;
        !           295:                 case 's': currbit = bits; break;
        !           296:                 case 'S': currbit = bitS; break;
        !           297:                 case 'd': currbit = bitd; break;
        !           298:                 case 'D': currbit = bitD; break;
        !           299:                 case 'r': currbit = bitr; break;
        !           300:                 case 'R': currbit = bitR; break;
        !           301:                 case 'z': currbit = bitz; break;
        !           302:                 default: myabort();
        !           303:                }
        !           304:                bitpos[currbit] = 15 - j;
        !           305:                bitcnt[currbit]++;
        !           306:                bitval[currbit] = (bitval[currbit] << 1) | ((opc & msk) ? 1 : 0);
        !           307:            }
        !           308:            if (bitval[bitj] == 0) bitval[bitj] = 8;
        !           309:            /* first check whether this one does not match after all */
        !           310:            if (bitval[bitz] == 3) continue; 
        !           311:            if (bitval[bitC] == 1) continue;
        !           312:            if (bitcnt[bitI] && bitval[bitI] == 0) continue;
        !           313: 
        !           314:            /* bitI and bitC get copied to biti and bitc */
        !           315:            if (bitcnt[bitI]) { bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI]; }
        !           316:            if (bitcnt[bitC]) bitval[bitc] = bitval[bitC];
        !           317:            
        !           318:            while (isspace(opcstr[pos]) || opcstr[pos] == ':') pos++;
        !           319:            while (!isspace(opcstr[pos])) {
        !           320:                if (opcstr[pos] == '.') {
        !           321:                    pos++;
        !           322:                    switch(opcstr[pos]) {
        !           323:                        
        !           324:                     case 'B': sz = sz_byte; break;
        !           325:                     case 'W': sz = sz_word; break;
        !           326:                     case 'L': sz = sz_long; break;
        !           327:                     case 'z': 
        !           328:                        switch(bitval[bitz]) {
        !           329:                         case 0: sz = sz_byte; break;
        !           330:                         case 1: sz = sz_word; break;
        !           331:                         case 2: sz = sz_long; break;
        !           332:                         default: myabort();
        !           333:                        }
        !           334:                        break;
        !           335:                     default: myabort();
        !           336:                    }
        !           337:                } else {                    
        !           338:                    mnemonic[mnp] = opcstr[pos];
        !           339:                    if(mnemonic[mnp] == 'f') {
        !           340:                        switch(bitval[bitf]) {
        !           341:                         case 0: mnemonic[mnp] = 'R'; break;
        !           342:                         case 1: mnemonic[mnp] = 'L'; break;
        !           343:                         default: myabort();
        !           344:                        }
        !           345:                    }
        !           346:                    mnp++;
        !           347:                }
        !           348:                pos++;          
        !           349:            }
        !           350:            
        !           351:            /* now, we have read the mnemonic and the size */
        !           352:            while (isspace(opcstr[pos])) pos++;
        !           353:            
        !           354:            /* A goto a day keeps the D******a away. */
        !           355:            if (opcstr[pos] == 0 || opcstr[pos] == ':') goto endofline;
        !           356:            
        !           357:            /* parse the source address */
        !           358:            usesrc = true;
        !           359:            switch(opcstr[pos++]) {
        !           360:             case 'D': 
        !           361:                srcmode = Dreg;
        !           362:                switch (opcstr[pos++]) {
        !           363:                 case 'r': srcreg = bitval[bitr]; srcgather = true; srcpos = bitpos[bitr]; break;
        !           364:                 case 'R': srcreg = bitval[bitR]; srcgather = true; srcpos = bitpos[bitR]; break;
        !           365:                 default: myabort();
        !           366:                }
        !           367:                
        !           368:                break;
        !           369:             case 'A': 
        !           370:                srcmode = Areg;
        !           371:                switch (opcstr[pos++]) {
        !           372:                 case 'r': srcreg = bitval[bitr]; srcgather = true; srcpos = bitpos[bitr]; break;
        !           373:                 case 'R': srcreg = bitval[bitR]; srcgather = true; srcpos = bitpos[bitR]; break;
        !           374:                 default: myabort();
        !           375:                }
        !           376:                switch (opcstr[pos]) {
        !           377:                 case 'p': srcmode = Apdi; pos++; break;
        !           378:                 case 'P': srcmode = Aipi; pos++; break;
        !           379:                }
        !           380:                break;
        !           381:             case '#':
        !           382:                switch(opcstr[pos++]) {
        !           383:                 case 'z': srcmode = imm; break;
        !           384:                 case '0': srcmode = imm0; break;
        !           385:                 case '1': srcmode = imm1; break;
        !           386:                 case '2': srcmode = imm2; break;
        !           387:                 case 'i': srcmode = immi; srcreg = (LONG)(BYTE)bitval[biti]; srcbtarg = true; srcgather = true; srcpos = bitpos[biti]; break;
        !           388:                 case 'j': srcmode = immi; srcreg = bitval[bitj]; break;
        !           389:                 case 'J': srcmode = immi; srcreg = bitval[bitJ]; break;
        !           390:                 default: myabort();
        !           391:                }
        !           392:                break;
        !           393:             case 'd':
        !           394:                srcreg = bitval[bitD];
        !           395:                srcmode = mode_from_mr(bitval[bitd],bitval[bitD]);
        !           396:                if (srcmode == am_illg) continue;
        !           397:                if (srcmode == Areg || srcmode == Dreg || srcmode == Aind 
        !           398:                    || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
        !           399:                    || srcmode == Apdi)
        !           400:                {
        !           401:                    srcgather = true; srcpos = bitpos[bitD];
        !           402:                }
        !           403:                if (opcstr[pos] == '[') {
        !           404:                    pos++;
        !           405:                    if (opcstr[pos] == '!') {
        !           406:                        /* exclusion */
        !           407:                        do {                        
        !           408:                            pos++;
        !           409:                            if (mode_from_str(opcstr+pos) == srcmode) goto nomatch;
        !           410:                            pos += 4;                       
        !           411:                        } while (opcstr[pos] == ',');
        !           412:                        pos++;
        !           413:                    } else {
        !           414:                        if (opcstr[pos+4] == '-') {
        !           415:                            /* replacement */
        !           416:                            if (mode_from_str(opcstr+pos) == srcmode) 
        !           417:                                srcmode = mode_from_str(opcstr+pos+5);
        !           418:                            else
        !           419:                                goto nomatch;
        !           420:                            pos += 10;
        !           421:                        } else {
        !           422:                            /* normal */
        !           423:                            while(mode_from_str(opcstr+pos) != srcmode) {
        !           424:                                pos += 4;
        !           425:                                if (opcstr[pos] == ']') goto nomatch;
        !           426:                                pos++;
        !           427:                            }
        !           428:                            while(opcstr[pos] != ']') pos++;
        !           429:                            pos++;
        !           430:                            break;
        !           431:                        }
        !           432:                    }
        !           433:                }
        !           434:                /* Some addressing modes are invalid as destination */
        !           435:                if (srcmode == imm || srcmode == PC16 || srcmode == PC8r)
        !           436:                    goto nomatch; 
        !           437:                break;
        !           438:             case 's':
        !           439:                srcreg = bitval[bitS];
        !           440:                srcmode = mode_from_mr(bitval[bits],bitval[bitS]);
        !           441:                
        !           442:                if(srcmode == am_illg) continue;                    
        !           443:                if (srcmode == Areg || srcmode == Dreg || srcmode == Aind 
        !           444:                    || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
        !           445:                    || srcmode == Apdi)
        !           446:                {
        !           447:                    srcgather = true; srcpos = bitpos[bitS];
        !           448:                }
        !           449:                if (opcstr[pos] == '[') {
        !           450:                    pos++;
        !           451:                    if (opcstr[pos] == '!') {
        !           452:                        /* exclusion */
        !           453:                        do {                        
        !           454:                            pos++;
        !           455:                            if (mode_from_str(opcstr+pos) == srcmode) goto nomatch;
        !           456:                            pos += 4;                       
        !           457:                        } while (opcstr[pos] == ',');
        !           458:                        pos++;
        !           459:                    } else {
        !           460:                        if (opcstr[pos+4] == '-') {
        !           461:                            /* replacement */
        !           462:                            if (mode_from_str(opcstr+pos) == srcmode) 
        !           463:                                srcmode = mode_from_str(opcstr+pos+5);
        !           464:                            else
        !           465:                                goto nomatch;
        !           466:                            pos += 10;
        !           467:                        } else {
        !           468:                            /* normal */
        !           469:                            while(mode_from_str(opcstr+pos) != srcmode) {
        !           470:                                pos += 4;
        !           471:                                if (opcstr[pos] == ']') goto nomatch;
        !           472:                                pos++;
        !           473:                            }
        !           474:                            while(opcstr[pos] != ']') pos++;
        !           475:                            pos++;
        !           476:                        }
        !           477:                    }
        !           478:                }
        !           479:                break;
        !           480:             default: myabort();
        !           481:            }
        !           482:            /* safety check - might have changed */
        !           483:            if (srcmode != Areg && srcmode != Dreg && srcmode != Aind 
        !           484:                && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi
        !           485:                && srcmode != Apdi && srcmode != immi)
        !           486:            {
        !           487:                srcgather = false;
        !           488:            }
        !           489:            if (srcmode == Areg && sz == sz_byte)
        !           490:                goto nomatch;
        !           491:            
        !           492:            if (opcstr[pos] != ',') goto endofline;
        !           493:            pos++;
        !           494:            
        !           495:            /* parse the destination address */
        !           496:            usedst = true;              
        !           497:            switch(opcstr[pos++]) {
        !           498:             case 'D': 
        !           499:                destmode = Dreg;
        !           500:                switch (opcstr[pos++]) {
        !           501:                 case 'r': destreg = bitval[bitr]; dstgather = true; dstpos = bitpos[bitr]; break;
        !           502:                 case 'R': destreg = bitval[bitR]; dstgather = true; dstpos = bitpos[bitR]; break;
        !           503:                 default: myabort();
        !           504:                }
        !           505:                break;
        !           506:             case 'A': 
        !           507:                destmode = Areg;
        !           508:                switch (opcstr[pos++]) {
        !           509:                 case 'r': destreg = bitval[bitr]; dstgather = true; dstpos = bitpos[bitr]; break;
        !           510:                 case 'R': destreg = bitval[bitR]; dstgather = true; dstpos = bitpos[bitR]; break;
        !           511:                 default: myabort();
        !           512:                }
        !           513:                switch (opcstr[pos]) {
        !           514:                 case 'p': destmode = Apdi; pos++; break;
        !           515:                 case 'P': destmode = Aipi; pos++; break;
        !           516:                }
        !           517:                break;
        !           518:             case '#':
        !           519:                switch(opcstr[pos++]) {
        !           520:                 case 'z': destmode = imm; break;
        !           521:                 case '0': destmode = imm0; break;
        !           522:                 case '1': destmode = imm1; break;
        !           523:                 case '2': destmode = imm2; break;
        !           524:                 case 'i': destmode = immi; destreg = (LONG)(BYTE)bitval[biti]; break;
        !           525:                 case 'j': destmode = immi; destreg = bitval[bitj]; break;
        !           526:                 case 'J': destmode = immi; destreg = bitval[bitJ]; break;
        !           527:                 default: myabort();
        !           528:                }
        !           529:                break;
        !           530:             case 'd':
        !           531:                destreg = bitval[bitD];
        !           532:                destmode = mode_from_mr(bitval[bitd],bitval[bitD]);
        !           533:                if(destmode == am_illg) continue;
        !           534:                if (destmode == Areg || destmode == Dreg || destmode == Aind 
        !           535:                    || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
        !           536:                    || destmode == Apdi)
        !           537:                {
        !           538:                    dstgather = true; dstpos = bitpos[bitD];
        !           539:                }
        !           540:                
        !           541:                if (opcstr[pos] == '[') {
        !           542:                    pos++;
        !           543:                    if (opcstr[pos] == '!') {
        !           544:                        /* exclusion */
        !           545:                        do {                        
        !           546:                            pos++;
        !           547:                            if (mode_from_str(opcstr+pos) == destmode) goto nomatch;
        !           548:                            pos += 4;                       
        !           549:                        } while (opcstr[pos] == ',');
        !           550:                        pos++;
        !           551:                    } else {
        !           552:                        if (opcstr[pos+4] == '-') {
        !           553:                            /* replacement */
        !           554:                            if (mode_from_str(opcstr+pos) == destmode) 
        !           555:                                destmode = mode_from_str(opcstr+pos+5);
        !           556:                            else
        !           557:                                goto nomatch;
        !           558:                            pos += 10;
        !           559:                        } else {
        !           560:                            /* normal */
        !           561:                            while(mode_from_str(opcstr+pos) != destmode) {
        !           562:                                pos += 4;
        !           563:                                if (opcstr[pos] == ']') goto nomatch;
        !           564:                                pos++;
        !           565:                            }
        !           566:                            while(opcstr[pos] != ']') pos++;
        !           567:                            pos++;
        !           568:                            break;
        !           569:                        }
        !           570:                    }
        !           571:                }
        !           572:                /* Some addressing modes are invalid as destination */
        !           573:                if (destmode == imm || destmode == PC16 || destmode == PC8r)
        !           574:                    goto nomatch;
        !           575:                break;
        !           576:             case 's':
        !           577:                destreg = bitval[bitS];
        !           578:                destmode = mode_from_mr(bitval[bits],bitval[bitS]);
        !           579:                
        !           580:                if(destmode == am_illg) continue;                   
        !           581:                if (destmode == Areg || destmode == Dreg || destmode == Aind 
        !           582:                    || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
        !           583:                    || destmode == Apdi)
        !           584:                {
        !           585:                    dstgather = true; dstpos = bitpos[bitS];
        !           586:                }
        !           587:                
        !           588:                if (opcstr[pos] == '[') {
        !           589:                    pos++;
        !           590:                    if (opcstr[pos] == '!') {
        !           591:                        /* exclusion */
        !           592:                        do {                        
        !           593:                            pos++;
        !           594:                            if (mode_from_str(opcstr+pos) == destmode) goto nomatch;
        !           595:                            pos += 4;                       
        !           596:                        } while (opcstr[pos] == ',');
        !           597:                        pos++;
        !           598:                    } else {
        !           599:                        if (opcstr[pos+4] == '-') {
        !           600:                            /* replacement */
        !           601:                            if (mode_from_str(opcstr+pos) == destmode) 
        !           602:                                destmode = mode_from_str(opcstr+pos+5);
        !           603:                            else
        !           604:                                goto nomatch;
        !           605:                            pos += 10;
        !           606:                        } else {
        !           607:                            /* normal */
        !           608:                            while(mode_from_str(opcstr+pos) != destmode) {
        !           609:                                pos += 4;
        !           610:                                if (opcstr[pos] == ']') goto nomatch;
        !           611:                                pos++;
        !           612:                            }
        !           613:                            while(opcstr[pos] != ']') pos++;
        !           614:                            pos++;
        !           615:                        }
        !           616:                    }
        !           617:                }
        !           618:                break;
        !           619:             default: myabort();
        !           620:            }
        !           621:            /* safety check - might have changed */
        !           622:            if (destmode != Areg && destmode != Dreg && destmode != Aind 
        !           623:                && destmode != Ad16 && destmode != Ad8r && destmode != Aipi
        !           624:                && destmode != Apdi)
        !           625:            {
        !           626:                dstgather = false;
        !           627:            }
        !           628:            
        !           629:            if (destmode == Areg && sz == sz_byte)
        !           630:                goto nomatch;
        !           631: #if 0
        !           632:            if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) {
        !           633:                dstgather = false;
        !           634:            }
        !           635: #endif
        !           636: endofline:
        !           637:            /* now, we have a match */
        !           638:            if (table[opc].mnemo != i_ILLG)
        !           639:                fprintf(stderr, "Double match: %x: %s\n", opc, opcstr);
        !           640:            for(find = 0;; find++) {
        !           641:                if (strcmp(mnemonic, lookuptab[find].name) == 0) {
        !           642:                    table[opc].mnemo = lookuptab[find].mnemo;
        !           643:                    break;
        !           644:                }
        !           645:                if (strlen(lookuptab[find].name) == 0) myabort();
        !           646:            }
        !           647:            table[opc].cc = bitval[bitc];
        !           648:            if (table[opc].mnemo == i_BTST
        !           649:                || table[opc].mnemo == i_BSET
        !           650:                || table[opc].mnemo == i_BCLR
        !           651:                || table[opc].mnemo == i_BCHG) 
        !           652:            {
        !           653:                sz = destmode == Dreg ? sz_long : sz_byte;
        !           654:            }
        !           655:            table[opc].generated = false;
        !           656:            table[opc].size = sz;
        !           657:            table[opc].sreg = srcreg;
        !           658:            table[opc].dreg = destreg;
        !           659:            table[opc].smode = srcmode;
        !           660:            table[opc].dmode = destmode;
        !           661:            table[opc].spos = srcgather ? srcpos : -1;
        !           662:            table[opc].dpos = dstgather ? dstpos : -1;
        !           663:            table[opc].suse = usesrc;
        !           664:            table[opc].duse = usedst;
        !           665:            table[opc].sbtarg = srcbtarg;
        !           666: nomatch:
        !           667:            /* FOO! */;
        !           668:        }
        !           669:     }
        !           670: }
        !           671: 
        !           672: static int n_braces = 0;
        !           673: 
        !           674: static void start_brace(void)
        !           675: {
        !           676:     n_braces++;
        !           677:     printf("{");
        !           678: }
        !           679: 
        !           680: static void close_brace(void)
        !           681: {
        !           682:     assert (n_braces > 0);
        !           683:     n_braces--;
        !           684:     printf("}");
        !           685: }
        !           686: 
        !           687: static void finish_braces(void)
        !           688: {
        !           689:     while (n_braces > 0)
        !           690:        close_brace();
        !           691: }
        !           692: 
        !           693: static void pop_braces(int to)
        !           694: {
        !           695:     while (n_braces > to)
        !           696:        close_brace();
        !           697: }
        !           698: 
        !           699: static void genamode(amodes mode, char *reg, wordsizes size, char *name, bool getv, bool movem)
        !           700: {
        !           701:     start_brace ();
        !           702:     switch(mode) {
        !           703:      case Dreg:
        !           704:        if (movem)
        !           705:            abort();
        !           706:        if (getv)
        !           707:            switch(size) {        
        !           708:             case sz_byte:
        !           709:                printf("\tBYTE %s = regs.d[%s];\n", name, reg);
        !           710:                break;
        !           711:             case sz_word:
        !           712:                printf("\tWORD %s = regs.d[%s];\n", name, reg);
        !           713:                break;
        !           714:             case sz_long:
        !           715:                printf("\tLONG %s = regs.d[%s];\n", name, reg);
        !           716:                break;
        !           717:             default: myabort();
        !           718:            }
        !           719:        break;
        !           720:      case Areg:
        !           721:        if (movem)
        !           722:            abort();
        !           723:        if (getv)
        !           724:            switch(size) {        
        !           725:             case sz_word:
        !           726:                printf("\tWORD %s = regs.a[%s];\n", name, reg);
        !           727:                break;
        !           728:             case sz_long:
        !           729:                printf("\tLONG %s = regs.a[%s];\n", name, reg);
        !           730:                break;
        !           731:             default: myabort();
        !           732:            }
        !           733:        break;
        !           734:      case Aind:
        !           735:        printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
        !           736:        if (getv)
        !           737:            switch(size) {        
        !           738:             case sz_byte:
        !           739:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
        !           740:                break;
        !           741:             case sz_word:
        !           742:                printf("\tWORD %s = get_word(%sa);\n", name, name);
        !           743:                break;
        !           744:             case sz_long:
        !           745:                printf("\tLONG %s = get_long(%sa);\n", name, name);
        !           746:                break;
        !           747:             default: myabort();
        !           748:            }
        !           749:        break;
        !           750:      case Aipi:
        !           751:        printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
        !           752:        switch(size) {
        !           753:         case sz_byte:      
        !           754:            if (getv) printf("\tBYTE %s = get_byte(%sa);\n", name, name);
        !           755:            if (!movem) {
        !           756:                start_brace();
        !           757:                printf("\tregs.a[%s] += (%s == 7) ? 2 : 1;\n", reg, reg);
        !           758:            }
        !           759:            break;
        !           760:         case sz_word:
        !           761:            if (getv) printf("\tWORD %s = get_word(%sa);\n", name, name);
        !           762:            if (!movem) {
        !           763:                start_brace();
        !           764:                printf("\tregs.a[%s] += 2;\n", reg);
        !           765:            }
        !           766:            break;
        !           767:         case sz_long:
        !           768:            if (getv) printf("\tLONG %s = get_long(%sa);\n", name, name);
        !           769:            if (!movem) {
        !           770:                start_brace();
        !           771:                printf("\tregs.a[%s] += 4;\n", reg);
        !           772:            }
        !           773:            break;
        !           774:         default: myabort();
        !           775:        }
        !           776:        break;
        !           777:      case Apdi:
        !           778:        switch(size) {    
        !           779:         case sz_byte:
        !           780:            if (!movem) printf("\tregs.a[%s] -= (%s == 7) ? 2 : 1;\n", reg, reg);
        !           781:            start_brace();
        !           782:            printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
        !           783:            if (getv) printf("\tBYTE %s = get_byte(%sa);\n", name, name);
        !           784:            break;
        !           785:         case sz_word:
        !           786:            if (!movem) printf("\tregs.a[%s] -= 2;\n", reg);
        !           787:            start_brace();
        !           788:            printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
        !           789:            if (getv) printf("\tWORD %s = get_word(%sa);\n", name, name);
        !           790:            break;
        !           791:         case sz_long:
        !           792:            if (!movem) printf("\tregs.a[%s] -= 4;\n", reg);
        !           793:            start_brace();
        !           794:            printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
        !           795:            if (getv) printf("\tLONG %s = get_long(%sa);\n", name, name);
        !           796:            break;
        !           797:         default: myabort();
        !           798:        }
        !           799:        break;
        !           800:      case Ad16:
        !           801:        printf("\tCPTR %sa = regs.a[%s] + (LONG)(WORD)nextiword();\n", name, reg);
        !           802:        if (getv) 
        !           803:            switch(size) {        
        !           804:             case sz_byte:
        !           805:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
        !           806:                break;
        !           807:             case sz_word:
        !           808:                printf("\tWORD %s = get_word(%sa);\n", name, name);
        !           809:                break;
        !           810:             case sz_long:
        !           811:                printf("\tLONG %s = get_long(%sa);\n", name, name);
        !           812:                break;
        !           813:             default: myabort();
        !           814:            }
        !           815:        break;
        !           816:      case Ad8r:
        !           817:        printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
        !           818:        printf("\tUWORD %sdp = nextiword();\n", name);
        !           819:        printf("\t%sa += (LONG)(BYTE)(%sdp & 0xFF);\n", name, name);
        !           820:        start_brace();
        !           821:        printf("\tULONG %sdpr = %sdp & 0x8000 ? regs.a[(%sdp & 0x7000) >> 12] : regs.d[(%sdp & 0x7000) >> 12];\n", name, name, name, name);
        !           822:        printf("\tif (!(%sdp & 0x800)) %sdpr = (LONG)(WORD)%sdpr;\n", name, name, name);
        !           823:        printf("\t%sa += %sdpr;\n", name, name);
        !           824:        if (getv) {
        !           825:            start_brace();
        !           826:            switch(size) {        
        !           827:             case sz_byte:
        !           828:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
        !           829:                break;
        !           830:             case sz_word:
        !           831:                printf("\tWORD %s = get_word(%sa);\n", name, name);
        !           832:                break;
        !           833:             case sz_long:
        !           834:                printf("\tLONG %s = get_long(%sa);\n", name, name);
        !           835:                break;
        !           836:             default: myabort();
        !           837:            }
        !           838:        }
        !           839:        break;
        !           840:      case PC16:
        !           841:        printf("\tCPTR %sa = m68k_getpc();\n", name);
        !           842:        printf("\t%sa += (LONG)(WORD)nextiword();\n", name);
        !           843:        if (getv) {
        !           844:            start_brace();
        !           845:            switch(size) {        
        !           846:             case sz_byte:
        !           847:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
        !           848:                break;
        !           849:             case sz_word:
        !           850:                printf("\tWORD %s = get_word(%sa);\n", name, name);
        !           851:                break;
        !           852:             case sz_long:
        !           853:                printf("\tLONG %s = get_long(%sa);\n", name, name);
        !           854:                break;
        !           855:             default: myabort();
        !           856:            }
        !           857:        }
        !           858:        break;
        !           859:      case PC8r:
        !           860:        printf("\tCPTR %sa = m68k_getpc();\n", name);
        !           861:        printf("\tUWORD %sdp = nextiword();\n", name);
        !           862:        printf("\t%sa += (LONG)(BYTE)(%sdp & 0xFF);\n", name, name);
        !           863:        start_brace();
        !           864:        printf("\tULONG %sdpr = %sdp & 0x8000 ? regs.a[(%sdp & 0x7000) >> 12] : regs.d[(%sdp & 0x7000) >> 12];\n", name, name, name, name);
        !           865:        printf("\tif (!(%sdp & 0x800)) %sdpr = (LONG)(WORD)%sdpr;\n", name, name, name);
        !           866:        printf("\t%sa += %sdpr;\n", name, name);
        !           867:        if (getv) {
        !           868:            start_brace();
        !           869:            switch(size) {        
        !           870:             case sz_byte:
        !           871:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
        !           872:                break;
        !           873:             case sz_word:
        !           874:                printf("\tWORD %s = get_word(%sa);\n", name, name);
        !           875:                break;
        !           876:             case sz_long:
        !           877:                printf("\tLONG %s = get_long(%sa);\n", name, name);
        !           878:                break;
        !           879:             default: myabort();
        !           880:            }
        !           881:        }
        !           882:        break;
        !           883:      case absw:
        !           884:        printf("\tCPTR %sa = (LONG)(WORD)nextiword();\n", name);
        !           885:        if (getv) 
        !           886:            switch(size) {        
        !           887:             case sz_byte:
        !           888:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
        !           889:                break;
        !           890:             case sz_word:
        !           891:                printf("\tWORD %s = get_word(%sa);\n", name, name);
        !           892:                break;
        !           893:             case sz_long:
        !           894:                printf("\tLONG %s = get_long(%sa);\n", name, name);
        !           895:                break;
        !           896:             default: myabort();
        !           897:            }
        !           898:        break;
        !           899:      case absl:
        !           900:        printf("\tCPTR %sa = nextilong();\n", name);
        !           901:        if (getv) 
        !           902:            switch(size) {        
        !           903:             case sz_byte:
        !           904:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
        !           905:                break;
        !           906:             case sz_word:
        !           907:                printf("\tWORD %s = get_word(%sa);\n", name, name);
        !           908:                break;
        !           909:             case sz_long:
        !           910:                printf("\tLONG %s = get_long(%sa);\n", name, name);
        !           911:                break;
        !           912:             default: myabort();
        !           913:            }
        !           914:        break;
        !           915:      case imm:
        !           916:        if (getv) 
        !           917:            switch(size) {
        !           918:             case sz_byte:
        !           919:                printf("\tBYTE %s = nextiword();\n", name);
        !           920:                break;
        !           921:             case sz_word:
        !           922:                printf("\tWORD %s = nextiword();\n", name);
        !           923:                break;
        !           924:             case sz_long:
        !           925:                printf("\tLONG %s = nextilong();\n", name);
        !           926:                break;
        !           927:             default: myabort();
        !           928:            }
        !           929:        break;
        !           930:      case imm0:
        !           931:        if (!getv) myabort();
        !           932:        printf("\tBYTE %s = nextiword();\n", name);
        !           933:        break;
        !           934:      case imm1:
        !           935:        if (!getv) myabort();
        !           936:        printf("\tWORD %s = nextiword();\n", name);
        !           937:        break;
        !           938:      case imm2:
        !           939:        if (!getv) myabort();
        !           940:         printf("\tLONG %s = nextilong();\n", name);
        !           941:        break;
        !           942:      case immi:
        !           943:        if (!getv) myabort();
        !           944:        printf("\tULONG %s = %s;\n", name, reg);
        !           945:        break;
        !           946:      default: 
        !           947:        myabort();
        !           948:     }
        !           949: }
        !           950: 
        !           951: static void genastore(char *from, amodes mode, char *reg, wordsizes size, char *to)
        !           952: {
        !           953:     switch(mode) {
        !           954:      case Dreg:
        !           955:        switch(size) {    
        !           956:         case sz_byte:
        !           957:            printf("\tregs.d[%s] &= ~0xff; regs.d[%s] |= (%s) & 0xff;\n", reg, reg, from);
        !           958:            break;
        !           959:         case sz_word:
        !           960:            printf("\tregs.d[%s] &= ~0xffff; regs.d[%s] |= (%s) & 0xffff;\n", reg, reg, from);
        !           961:            break;
        !           962:         case sz_long:
        !           963:            printf("\tregs.d[%s] = (%s);\n", reg, from);
        !           964:            break;
        !           965:         default: myabort();
        !           966:        }
        !           967:        break;
        !           968:      case Areg:
        !           969:        switch(size) {    
        !           970:         case sz_word:
        !           971:            printf("\tregs.a[%s] = (LONG)(WORD)(%s);\n", reg, from);
        !           972:            break;
        !           973:         case sz_long:
        !           974:            printf("\tregs.a[%s] = (%s);\n", reg, from);
        !           975:            break;
        !           976:         default: myabort();
        !           977:        }
        !           978:        break;
        !           979:      case Aind:
        !           980:      case Aipi:
        !           981:      case Apdi:
        !           982:      case Ad16:
        !           983:      case Ad8r:
        !           984:      case absw:
        !           985:      case absl:
        !           986:        switch(size) {
        !           987:         case sz_byte:
        !           988:            printf("\tput_byte(%sa,%s);\n", to, from);
        !           989:            break;
        !           990:         case sz_word:
        !           991:            printf("\tput_word(%sa,%s);\n", to, from);
        !           992:            break;
        !           993:         case sz_long:
        !           994:            printf("\tput_long(%sa,%s);\n", to, from);
        !           995:            break;
        !           996:         default: myabort();
        !           997:        }
        !           998:        break;
        !           999:      case PC16:
        !          1000:      case PC8r:
        !          1001:        switch(size) {
        !          1002:         case sz_byte:
        !          1003:            printf("\tput_byte(%sa,%s);\n", to, from);
        !          1004:            break;
        !          1005:            /* These are only used for byte-sized bit ops */
        !          1006:         default: myabort();
        !          1007:        }
        !          1008:        break;
        !          1009:      case imm:
        !          1010:      case imm0:
        !          1011:      case imm1:
        !          1012:      case imm2:
        !          1013:      case immi:
        !          1014:        myabort();
        !          1015:        break;
        !          1016:      default: 
        !          1017:        myabort();
        !          1018:     }
        !          1019: }
        !          1020: 
        !          1021: static void genmovemel(UWORD opcode)
        !          1022: {
        !          1023:     char getcode[100];
        !          1024:     int size = table[opcode].size == sz_long ? 4 : 2;
        !          1025:     
        !          1026:     if (table[opcode].size == sz_long) {       
        !          1027:        strcpy(getcode, "get_long(srca)");
        !          1028:     } else {       
        !          1029:        strcpy(getcode, "(LONG)(WORD)get_word(srca)");
        !          1030:     }
        !          1031:     
        !          1032:     printf("\tUWORD mask = nextiword(), bitmask = mask;\n");
        !          1033:     genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, true);
        !          1034:     start_brace();
        !          1035:     printf("\tint i, bitcnt = 0;\n");
        !          1036:     printf("\tfor(i=0;i<16;i++) { bitcnt += bitmask & 1; bitmask >>= 1; }\n");
        !          1037:     
        !          1038:     printf("\tfor(i=0;i<8;i++) { if (mask & 1) { regs.d[i] = %s; srca += %d; } mask >>= 1; }\n", getcode, size);
        !          1039:     printf("\tfor(i=0;i<8;i++) { if (mask & 1) { regs.a[i] = %s; srca += %d; } mask >>= 1; }\n", getcode, size);
        !          1040:     
        !          1041:     if (table[opcode].smode == Aipi)
        !          1042:        printf("\tregs.a[srcreg] = srca;\n");
        !          1043: }
        !          1044: 
        !          1045: static void genmovemle(UWORD opcode)
        !          1046: {
        !          1047:     char putcode[100], shiftcode[] = ">>";
        !          1048:     int size = table[opcode].size == sz_long ? 4 : 2;
        !          1049:     int mask = 1;
        !          1050:     if (table[opcode].size == sz_long) {
        !          1051:        strcpy(putcode, "put_long(srca,");
        !          1052:     } else {       
        !          1053:        strcpy(putcode, "put_word(srca,");
        !          1054:     }
        !          1055:     
        !          1056:     printf("\tUWORD mask = nextiword(), bitmask = mask;\n");
        !          1057:     genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, true);
        !          1058:     start_brace();
        !          1059:     printf("\tint i, bitcnt = 0;\n");
        !          1060:     printf("\tULONG rd[8], ra[8];\n");
        !          1061:     printf("\tfor(i=0;i<16;i++) { bitcnt += bitmask & 1; bitmask >>= 1; }\n");
        !          1062:     printf("\tfor(i=0;i<8;i++) { rd[i] = regs.d[i]; ra[i] = regs.a[i]; }\n");
        !          1063:     if (table[opcode].smode == Apdi) {
        !          1064:        printf("\tsrca -= %d*bitcnt;\n", size);
        !          1065:        printf("\tregs.a[srcreg] = srca;\n");
        !          1066:        strcpy(shiftcode, "<<");
        !          1067:        mask = 0x8000;
        !          1068:     }
        !          1069: 
        !          1070:     printf("\tfor(i=0;i<8;i++) { if (mask & %d) { %s rd[i]); srca += %d; } mask %s= 1; }\n", 
        !          1071:           mask, putcode, size, shiftcode);
        !          1072:     printf("\tfor(i=0;i<8;i++) { if (mask & %d) { %s ra[i]); srca += %d; } mask %s= 1; }\n",
        !          1073:           mask, putcode, size, shiftcode);    
        !          1074: }
        !          1075: 
        !          1076: typedef enum {
        !          1077:     flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_zn
        !          1078: } flagtypes;
        !          1079: 
        !          1080: static void genflags(flagtypes type, wordsizes size, char *value, char *src, char *dst)
        !          1081: {
        !          1082:     char vstr[100],sstr[100],dstr[100];
        !          1083:     char usstr[100],udstr[100];
        !          1084:     char unsstr[100],undstr[100];
        !          1085:     ULONG mask;
        !          1086:     switch(size) {
        !          1087:      case sz_byte: mask = 0xFF; break;
        !          1088:      case sz_word: mask = 0xFFFF; break;
        !          1089:      case sz_long: mask = 0xFFFFFFFF; break;
        !          1090:      default: myabort();
        !          1091:     }
        !          1092: #ifndef NO_INLINE_FLAGS
        !          1093:     switch(size) {         
        !          1094:      case sz_byte:
        !          1095:        strcpy(vstr, "((BYTE)(");
        !          1096:        strcpy(usstr, "((UBYTE)(");
        !          1097:        break;
        !          1098:      case sz_word:
        !          1099:        strcpy(vstr, "((WORD)(");
        !          1100:        strcpy(usstr, "((UWORD)(");
        !          1101:        break;
        !          1102:      case sz_long:
        !          1103:        strcpy(vstr, "((LONG)(");
        !          1104:        strcpy(usstr, "((ULONG)(");
        !          1105:        break;
        !          1106:      default:
        !          1107:        myabort();
        !          1108:     }
        !          1109:     strcpy(unsstr, usstr); 
        !          1110: 
        !          1111:     strcpy(sstr, vstr);
        !          1112:     strcpy(dstr, vstr);
        !          1113:     strcat(vstr, value); strcat(vstr,"))");
        !          1114:     strcat(dstr, dst); strcat(dstr,"))");
        !          1115:     strcat(sstr, src); strcat(sstr,"))");
        !          1116:     
        !          1117:     strcpy(udstr, usstr);
        !          1118:     strcat(udstr, dst); strcat(udstr,"))");
        !          1119:     strcat(usstr, src); strcat(usstr,"))");
        !          1120:     
        !          1121:     strcpy(undstr, unsstr);
        !          1122:     strcat(unsstr, "-");
        !          1123:     strcat(undstr, "~");
        !          1124:     strcat(undstr, dst); strcat(undstr,"))");
        !          1125:     strcat(unsstr, src); strcat(unsstr,"))");
        !          1126:     
        !          1127:     switch(type) {
        !          1128:      case flag_logical:
        !          1129:        printf("\tregs.v = regs.c = 0;\n");
        !          1130:        /* fall through */
        !          1131:      case flag_zn:
        !          1132:        switch(size) {
        !          1133:         case sz_byte:
        !          1134:            printf("\tregs.z = %s == 0;\n", vstr);
        !          1135:            printf("\tregs.n = %s < 0;\n", vstr);
        !          1136:            break;
        !          1137:         case sz_word:
        !          1138:            printf("\tregs.z = %s == 0;\n", vstr);
        !          1139:            printf("\tregs.n = %s < 0;\n", vstr);
        !          1140:            break;
        !          1141:         case sz_long:
        !          1142:            printf("\tregs.z = %s == 0;\n", vstr);
        !          1143:            printf("\tregs.n = %s < 0;\n", vstr);
        !          1144:            break;
        !          1145:         default:
        !          1146:            myabort();
        !          1147:        }
        !          1148:        break;
        !          1149:      case flag_add:
        !          1150:        start_brace();
        !          1151:        printf("\tbool flgs = %s < 0;\n", sstr);
        !          1152:        printf("\tbool flgo = %s < 0;\n", dstr);
        !          1153:        printf("\tbool flgn = %s < 0;\n", vstr);
        !          1154:        printf("\tregs.z = %s == 0;\n", vstr);
        !          1155:        printf("\tregs.v = (flgs == flgo) && (flgn != flgo);\n");
        !          1156:        printf("\tregs.c = regs.x = %s < %s;\n", undstr, usstr);
        !          1157:        printf("\tregs.n = flgn != 0;\n");
        !          1158:        break;
        !          1159:      case flag_sub:
        !          1160:        start_brace();
        !          1161:        printf("\tbool flgs = %s < 0;\n", sstr);
        !          1162:        printf("\tbool flgo = %s < 0;\n", dstr);
        !          1163:        printf("\tbool flgn = %s < 0;\n", vstr);
        !          1164:        printf("\tregs.z = %s == 0;\n", vstr);
        !          1165:        printf("\tregs.v = (flgs != flgo) && (flgn != flgo);\n");
        !          1166:        printf("\tregs.c = regs.x = %s > %s;\n", usstr, udstr);
        !          1167:        printf("\tregs.n = flgn != 0;\n");
        !          1168:        break;
        !          1169:      case flag_addx:
        !          1170:        start_brace();
        !          1171:        printf("\tbool flgs = %s < 0;\n", sstr);
        !          1172:        printf("\tbool flgo = %s < 0;\n", dstr);
        !          1173:        printf("\tbool flgn = %s < 0;\n", vstr);
        !          1174:        printf("\tif ((flgs && flgo && !flgn) || (!flgs && !flgo && flgn)) regs.v = 1;\n");
        !          1175:        printf("\tif ((flgs && flgo) || (!flgn && (flgo || flgs))) regs.c = regs.x = 1;\n");
        !          1176:        break;
        !          1177:      case flag_subx:
        !          1178:        start_brace();
        !          1179:        printf("\tbool flgs = %s < 0;\n", sstr);
        !          1180:        printf("\tbool flgo = %s < 0;\n", dstr);
        !          1181:        printf("\tbool flgn = %s < 0;\n", vstr);
        !          1182:        printf("\tif ((!flgs && flgo && !flgn) || (flgs && !flgo && flgn)) regs.v = 1;\n");
        !          1183:        printf("\tif ((flgs && !flgo) || (flgn && (!flgo || flgs))) regs.c = regs.x = 1;\n");
        !          1184:        break;
        !          1185:      case flag_cmp:
        !          1186:        start_brace();
        !          1187:        printf("\tbool flgs = %s < 0;\n", sstr);
        !          1188:        printf("\tbool flgo = %s < 0;\n", dstr);
        !          1189:        printf("\tbool flgn = %s < 0;\n", vstr);
        !          1190:        printf("\tregs.z = %s == 0;\n", vstr);
        !          1191:        printf("\tregs.v = (flgs != flgo) && (flgn != flgo);\n");
        !          1192:        printf("\tregs.c = %s > %s;\n", usstr, udstr);
        !          1193:        printf("\tregs.n = flgn != 0;\n");
        !          1194:        break;
        !          1195:     }
        !          1196: #else
        !          1197:     switch(type) {
        !          1198:      case flag_logical:
        !          1199:        printf("\tsetflags_logical(%s,%s);\n", value, mask);
        !          1200:        break;
        !          1201:      case flag_add:
        !          1202:        printf("\tsetflags_add(%s,%s,%s);\n", src, dest, value);
        !          1203:        break;
        !          1204:      case flag_sub:
        !          1205:        printf("\tsetflags_sub(%s,%s,%s);\n", src, dest, value);
        !          1206:        break;
        !          1207:      case flag_addx:
        !          1208:        printf("\tsetflags_addx(%s,%s,%s);\n", src, dest, value);
        !          1209:        break;
        !          1210:      case flag_subx:
        !          1211:        printf("\tsetflags_subx(%s,%s,%s);\n", src, dest, value);
        !          1212:        break;
        !          1213:      case flag_cmp:
        !          1214:        printf("\tsetflags_cmp(%s,%s,%s);\n", src, dest, value);
        !          1215:        break;
        !          1216:     }
        !          1217: #endif    
        !          1218: }
        !          1219: 
        !          1220: static void gen_opcode(unsigned long int opcode) 
        !          1221: {
        !          1222:     start_brace ();
        !          1223:     switch(table[opcode].mnemo) {
        !          1224:      case i_OR:
        !          1225:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1226:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
        !          1227:        printf("\tsrc |= dst;\n");
        !          1228:        genflags(flag_logical, table[opcode].size, "src", "", "");
        !          1229:        genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
        !          1230:        break;
        !          1231:      case i_AND:
        !          1232:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1233:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
        !          1234:        printf("\tsrc &= dst;\n");
        !          1235:        genflags(flag_logical, table[opcode].size, "src", "", "");
        !          1236:        genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
        !          1237:        break;
        !          1238:      case i_EOR:
        !          1239:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1240:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
        !          1241:        printf("\tsrc ^= dst;\n");
        !          1242:        genflags(flag_logical, table[opcode].size, "src", "", "");
        !          1243:        genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
        !          1244:        break;
        !          1245:      case i_ORSR:
        !          1246:        if (table[opcode].size != sz_byte) {
        !          1247:            printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else\n");
        !          1248:        }
        !          1249:        start_brace ();
        !          1250:        printf("\tMakeSR();\n");
        !          1251:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1252:        if (table[opcode].size == sz_byte) {
        !          1253:            printf("\tsrc &= 0xFF;\n");
        !          1254:        }
        !          1255:        printf("\tregs.sr |= src;\n");
        !          1256:        printf("\tMakeFromSR();\n");
        !          1257:        break;
        !          1258:      case i_ANDSR: 
        !          1259:        if (table[opcode].size != sz_byte) {
        !          1260:            printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else\n");
        !          1261:        }
        !          1262:        start_brace();
        !          1263:        
        !          1264:        printf("\tMakeSR();\n");
        !          1265:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1266:        if (table[opcode].size == sz_byte) {
        !          1267:            printf("\tsrc |= 0xFF00;\n");
        !          1268:        }
        !          1269:        printf("\tregs.sr &= src;\n");
        !          1270:        printf("\tMakeFromSR();\n");
        !          1271:        break;
        !          1272:      case i_EORSR:
        !          1273:        if (table[opcode].size != sz_byte) {
        !          1274:            printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else\n");
        !          1275:        }
        !          1276:        start_brace ();
        !          1277:        printf("\tMakeSR();\n");
        !          1278:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1279:        if (table[opcode].size == sz_byte) {
        !          1280:            printf("\tsrc &= 0xFF;\n");
        !          1281:        }
        !          1282:        printf("\tregs.sr ^= src;\n");
        !          1283:        printf("\tMakeFromSR();\n");
        !          1284:        break;
        !          1285:      case i_SUB: 
        !          1286:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1287:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
        !          1288:        start_brace ();
        !          1289:        printf("\tULONG newv = dst - src;\n");
        !          1290:        genflags(flag_sub, table[opcode].size, "newv", "src", "dst");
        !          1291:        genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
        !          1292:        break;
        !          1293:      case i_SUBA:
        !          1294:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1295:        genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false);
        !          1296:        start_brace ();
        !          1297:        printf("\tULONG newv = dst - src;\n");
        !          1298:        genastore("newv", table[opcode].dmode, "dstreg", sz_long, "dst");
        !          1299:        break;
        !          1300:      case i_SUBX:
        !          1301:        {
        !          1302:            int old_brace_level;
        !          1303:            genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1304:            genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
        !          1305:            start_brace ();
        !          1306:            printf("\tbool xflg = regs.x;\n");
        !          1307:            printf("\tregs.v = regs.c = regs.x = 0;\n");
        !          1308:            start_brace ();
        !          1309:            printf("\tULONG newv = dst - src;\n");
        !          1310:            genflags(flag_subx, table[opcode].size, "newv", "src", "dst");
        !          1311:            /* FIXME: I'm not entirely sure how to handle this */
        !          1312:            printf("\tif (xflg)\n"); 
        !          1313:            old_brace_level = n_braces;
        !          1314:            start_brace ();
        !          1315:            genflags(flag_subx, table[opcode].size, "(newv-1)", "1", "newv");
        !          1316:            printf("\tnewv--;\n");
        !          1317:            pop_braces(old_brace_level);
        !          1318:            
        !          1319:            genflags(flag_zn, table[opcode].size, "newv", "", "");
        !          1320:            genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
        !          1321:        }
        !          1322:        break;
        !          1323:      case i_SBCD:
        !          1324:        /* Let's hope this works... */
        !          1325:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1326:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
        !          1327:        start_brace ();
        !          1328:        printf("\tUWORD newv = dst - src - regs.x;\n");
        !          1329:        printf("\tif ((newv & 0xF) > 9) newv-=6;\n");
        !          1330:        printf("\tregs.c = regs.x = (newv & 0x1F0) > 0x90;\n");
        !          1331:        printf("\tif (regs.c) newv -= 0x60;\n");
        !          1332:        printf("\tif (newv != 0) regs.z = 0;\n");
        !          1333:        genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
        !          1334:        break;
        !          1335:      case i_ADD:
        !          1336:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1337:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
        !          1338:        start_brace ();
        !          1339:        printf("\tULONG newv = dst + src;\n");
        !          1340:        genflags(flag_add, table[opcode].size, "newv", "src", "dst");
        !          1341:        genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
        !          1342:        break;
        !          1343:      case i_ADDA: 
        !          1344:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1345:        genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false);
        !          1346:        start_brace ();
        !          1347:        printf("\tULONG newv = dst + src;\n");
        !          1348:        genastore("newv", table[opcode].dmode, "dstreg", sz_long, "dst");
        !          1349:        break;
        !          1350:      case i_ADDX:
        !          1351:        {
        !          1352:            int old_brace_level;
        !          1353:            genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1354:            genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
        !          1355:            start_brace ();
        !          1356:            printf("\tbool xflg = regs.x;\n");
        !          1357:            printf("\tregs.v = regs.c = regs.x = 0;\n");
        !          1358:            start_brace ();
        !          1359:            printf("\tULONG newv = dst + src;\n");
        !          1360:            genflags(flag_addx, table[opcode].size, "newv", "src", "dst");
        !          1361:            printf("\tif (xflg)\n");
        !          1362:            old_brace_level = n_braces;
        !          1363:            start_brace ();
        !          1364:            genflags(flag_addx, table[opcode].size, "(newv+1)", "newv", "1");
        !          1365:            printf("\tnewv++;\n");
        !          1366:            pop_braces(old_brace_level);
        !          1367:            genflags(flag_zn, table[opcode].size, "newv", "", "");
        !          1368:            genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
        !          1369:        }
        !          1370:        break;
        !          1371:      case i_ABCD:
        !          1372:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1373:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
        !          1374:        start_brace ();
        !          1375:        printf("\tUWORD newv = src + dst + regs.x;\n");
        !          1376:        printf("\tif ((newv & 0xF) > 9) newv+=6;\n");
        !          1377:        printf("\tregs.c = regs.x = (newv & 0x1F0) > 0x90;\n");
        !          1378:        printf("\tif (regs.c) newv += 0x60;\n");
        !          1379:        printf("\tif (newv != 0) regs.z = 0;\n");
        !          1380:        genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
        !          1381:        break;
        !          1382:      case i_NEG:
        !          1383:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1384:        start_brace ();
        !          1385:        printf("\tULONG dst = -src;\n");
        !          1386:        genflags(flag_sub, table[opcode].size, "dst", "src", "0");
        !          1387:        genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src");
        !          1388:        break;
        !          1389:      case i_NEGX:
        !          1390:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1391:        start_brace ();
        !          1392:        printf("\tULONG dst = -src-regs.x;\n");
        !          1393:        genflags(flag_sub, table[opcode].size, "dst", "src", "0");
        !          1394:        genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src");
        !          1395:        break;
        !          1396:      case i_NBCD: 
        !          1397:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1398:        start_brace ();
        !          1399:        printf("\tUWORD newv = - src - regs.x;\n");
        !          1400:        printf("\tif ((newv & 0xF) > 9) newv-=6;\n");
        !          1401:        printf("\tregs.c = regs.x = (newv & 0x1F0) > 0x90;\n");
        !          1402:        printf("\tif (regs.c) newv -= 0x60;\n");
        !          1403:        printf("\tif (newv != 0) regs.z = 0;\n");
        !          1404:        genastore("newv", table[opcode].smode, "srcreg", table[opcode].size, "src");
        !          1405:        break;
        !          1406:      case i_CLR: 
        !          1407:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
        !          1408:        genflags(flag_logical, table[opcode].size, "0", "", "");
        !          1409:        genastore("0",table[opcode].smode, "srcreg", table[opcode].size, "src");
        !          1410:        break;
        !          1411:      case i_NOT: 
        !          1412:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1413:        start_brace ();
        !          1414:        printf("\tULONG dst = ~src;\n");
        !          1415:        genflags(flag_logical, table[opcode].size, "dst", "", "");
        !          1416:        genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src");
        !          1417:        break;
        !          1418:      case i_TST:
        !          1419:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1420:        genflags(flag_logical, table[opcode].size, "src", "", "");
        !          1421:        break;
        !          1422:      case i_BTST:
        !          1423:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1424:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
        !          1425:        if (table[opcode].size == sz_byte)
        !          1426:            printf("\tsrc &= 7;\n");
        !          1427:        else
        !          1428:            printf("\tsrc &= 31;\n");
        !          1429:        printf("\tregs.z = !(dst & (1 << src));\n");
        !          1430:        break;
        !          1431:      case i_BCHG:
        !          1432:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1433:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
        !          1434:        if (table[opcode].size == sz_byte)
        !          1435:            printf("\tsrc &= 7;\n");
        !          1436:        else
        !          1437:            printf("\tsrc &= 31;\n");
        !          1438:        printf("\tregs.z = !(dst & (1 << src));\n");
        !          1439:        printf("\tdst ^= (1 << src);\n");
        !          1440:        genastore("dst", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
        !          1441:        break;
        !          1442:      case i_BCLR:
        !          1443:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1444:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
        !          1445:        if (table[opcode].size == sz_byte)
        !          1446:            printf("\tsrc &= 7;\n");
        !          1447:        else
        !          1448:            printf("\tsrc &= 31;\n");
        !          1449:        printf("\tregs.z = !(dst & (1 << src));\n");
        !          1450:        printf("\tdst &= ~(1 << src);\n");
        !          1451:        genastore("dst", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
        !          1452:        break;
        !          1453:      case i_BSET:
        !          1454:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1455:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
        !          1456:        if (table[opcode].size == sz_byte)
        !          1457:            printf("\tsrc &= 7;\n");
        !          1458:        else
        !          1459:            printf("\tsrc &= 31;\n");
        !          1460:        printf("\tregs.z = !(dst & (1 << src));\n");
        !          1461:        printf("\tdst |= (1 << src);\n");
        !          1462:        genastore("dst", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
        !          1463:        break;
        !          1464:      case i_CMPM:
        !          1465:      case i_CMP:
        !          1466:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1467:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
        !          1468:        start_brace ();
        !          1469:        printf("\tULONG newv = dst - src;\n");
        !          1470:        genflags(flag_cmp, table[opcode].size, "newv", "src", "dst");
        !          1471:        break;
        !          1472:      case i_CMPA: 
        !          1473:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1474:        genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false);
        !          1475:        start_brace ();
        !          1476:        printf("\tULONG newv = dst - src;\n");
        !          1477:        genflags(flag_cmp, sz_long, "newv", "src", "dst");
        !          1478:        break;
        !          1479:      case i_MOVEP: 
        !          1480:        printf("\tfprintf(stderr, \"MOVEP\\n\");\n");
        !          1481:        break;
        !          1482:      case i_MOVE:
        !          1483:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1484:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", false, false);
        !          1485:        genflags(flag_logical, table[opcode].size, "src", "", "");
        !          1486:        genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
        !          1487:        break;
        !          1488:      case i_MOVEA:
        !          1489:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1490:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", false, false);
        !          1491:        genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
        !          1492:        break;
        !          1493:      case i_MVSR2: 
        !          1494:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
        !          1495:        printf("\tMakeSR();\n");
        !          1496:        genastore("regs.sr", table[opcode].smode, "srcreg", table[opcode].size, "src");
        !          1497:        break;
        !          1498:      case i_MV2SR:
        !          1499:        if (table[opcode].size != sz_byte) {
        !          1500:            printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else\n");
        !          1501:        }
        !          1502:        start_brace ();
        !          1503:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1504:        if (table[opcode].size == sz_byte)
        !          1505:            printf("\tMakeSR();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n");
        !          1506:        else {              
        !          1507:            printf("\tregs.sr = src;\n");
        !          1508:        }
        !          1509:        printf("\tMakeFromSR();\n");
        !          1510:        break;
        !          1511:      case i_SWAP: 
        !          1512:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1513:        start_brace ();
        !          1514:        printf("\tULONG dst = ((src >> 16)&0xFFFF) | ((src&0xFFFF)<<16);\n");
        !          1515:        genflags(flag_logical, table[opcode].size, "dst", "", "");
        !          1516:        genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src");
        !          1517:        break;
        !          1518:      case i_EXG:
        !          1519:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1520:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
        !          1521:        genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src");
        !          1522:        genastore("src",table[opcode].dmode, "dstreg", table[opcode].size, "dst");
        !          1523:        break;
        !          1524:      case i_EXT:
        !          1525:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1526:        start_brace ();
        !          1527:        switch(table[opcode].size) {
        !          1528:         case sz_word: printf("\tULONG dst = (LONG)(BYTE)src;\n"); break;
        !          1529:         case sz_long: printf("\tULONG dst = (LONG)(WORD)src;\n"); break;
        !          1530:         default: myabort();
        !          1531:        }
        !          1532:        genflags(flag_logical, table[opcode].size, "dst", "", "");
        !          1533:        genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src");
        !          1534:        break;
        !          1535:      case i_MVMEL:
        !          1536:        genmovemel(opcode);
        !          1537:        break;
        !          1538:      case i_MVMLE:
        !          1539:        genmovemle(opcode);
        !          1540:        break;
        !          1541:      case i_TRAP:
        !          1542:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1543:        printf("\tException(src+32);\n");
        !          1544:        break;
        !          1545:      case i_MVR2USP:
        !          1546:        printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else {\n");
        !          1547:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1548:        printf("\tregs.usp = src;\n");
        !          1549:        printf("\t}\n");
        !          1550:        break;
        !          1551:      case i_MVUSP2R: 
        !          1552:        printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else {\n");
        !          1553:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
        !          1554:        genastore("regs.usp", table[opcode].smode, "srcreg", table[opcode].size, "src");
        !          1555:        printf("\t}\n");
        !          1556:        break;
        !          1557:      case i_RESET:
        !          1558:        printf("\tcustomreset();\n");
        !          1559:        break;
        !          1560:      case i_NOP:
        !          1561:        break;
        !          1562:      case i_STOP:
        !          1563:        printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else {\n");
        !          1564:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1565:        printf("\tregs.sr = src;\n");
        !          1566:        printf("\tMakeFromSR();\n");
        !          1567:        printf("\tm68k_setstopped(1);\n");
        !          1568:        printf("\t}\n");
        !          1569:        break;
        !          1570:      case i_RTE:
        !          1571:        genamode(Aipi, "7", sz_word, "sr", true, false);
        !          1572:        genamode(Aipi, "7", sz_long, "pc", true, false);
        !          1573:        printf("\tregs.sr = sr; m68k_setpc(pc);\n");
        !          1574:        printf("\tMakeFromSR();\n");
        !          1575:        break;
        !          1576:      case i_RTD:
        !          1577:        break;
        !          1578:      case i_LINK:
        !          1579:        genamode(Apdi, "7", sz_long, "old", false, false);
        !          1580:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1581:        genastore("src", Apdi, "7", sz_long, "old");
        !          1582:        genastore("regs.a[7]", table[opcode].smode, "srcreg", table[opcode].size, "src");
        !          1583:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "offs", true, false);
        !          1584:        printf("\tregs.a[7] += offs;\n");
        !          1585:        break;
        !          1586:      case i_UNLK:
        !          1587:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1588:        printf("\tregs.a[7] = src;\n");
        !          1589:        genamode(Aipi, "7", sz_long, "old", true, false);
        !          1590:        genastore("old", table[opcode].smode, "srcreg", table[opcode].size, "src");
        !          1591:        break;
        !          1592:      case i_RTS:
        !          1593:        genamode(Aipi, "7", sz_long, "pc", true, false);
        !          1594:        printf("\tm68k_setpc(pc);\n");
        !          1595:        break;
        !          1596:      case i_TRAPV:
        !          1597:        printf("\tif(regs.v) Exception(7);\n");
        !          1598:        break;
        !          1599:      case i_RTR: 
        !          1600:        printf("\tMakeSR();\n");
        !          1601:        genamode(Aipi, "7", sz_word, "sr", true, false);
        !          1602:        genamode(Aipi, "7", sz_long, "pc", true, false);
        !          1603:        printf("\tregs.sr &= 0xFF00; sr &= 0xFF;\n");
        !          1604:        printf("\tregs.sr |= sr; m68k_setpc(pc);\n");
        !          1605:        printf("\tMakeFromSR();\n");
        !          1606:        break;
        !          1607:      case i_JSR:
        !          1608:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
        !          1609:        genamode(Apdi, "7", sz_long, "sp", false, false);
        !          1610:        genastore("m68k_getpc()", Apdi, "7", sz_long, "sp");
        !          1611:        printf("\tm68k_setpc(srca);\n");
        !          1612:        break;
        !          1613:      case i_JMP: 
        !          1614:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
        !          1615:        printf("\tm68k_setpc(srca);\n");
        !          1616:        break;
        !          1617:      case i_BSR:
        !          1618:        printf("\tchar *oldpcp = (char *)regs.pc_p;\n");
        !          1619:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1620:        genamode(Apdi, "7", sz_long, "sp", false, false);
        !          1621:        genastore("m68k_getpc()", Apdi, "7", sz_long, "sp");
        !          1622:        printf("\tregs.pc_p = (UWORD *)(oldpcp + (LONG)src);\n");
        !          1623:        break;
        !          1624:      case i_Bcc:
        !          1625:        printf("\tchar *oldpcp = (char *)regs.pc_p;\n");
        !          1626:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1627:        printf("\tif (cctrue(%d)) regs.pc_p = (UWORD *)(oldpcp + (LONG)src);\n", table[opcode].cc);
        !          1628:        break;
        !          1629:      case i_LEA:
        !          1630:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
        !          1631:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", false, false);
        !          1632:        genastore("srca", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
        !          1633:        break;
        !          1634:      case i_PEA:
        !          1635:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
        !          1636:        genamode(Apdi, "7", sz_long, "dst", false, false);
        !          1637:        genastore("srca", Apdi, "7", sz_long, "dst");
        !          1638:        break;
        !          1639:      case i_DBcc:
        !          1640:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
        !          1641:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "offs", true, false);
        !          1642:        printf("\tif (!cctrue(%d)) {\n", table[opcode].cc);
        !          1643:        printf("\tif (src--) regs.pc_p = (UWORD *)((char *)regs.pc_p + (LONG)offs - 2);\n");
        !          1644:        genastore("src", table[opcode].smode, "srcreg", table[opcode].size, "src");
        !          1645:        printf("\t}\n");
        !          1646:        break;
        !          1647:      case i_Scc: 
        !          1648:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
        !          1649:        start_brace ();
        !          1650:        printf("\tint val = cctrue(%d) ? 0xff : 0;\n", table[opcode].cc);
        !          1651:        genastore("val",table[opcode].smode, "srcreg", table[opcode].size, "src");
        !          1652:        break;
        !          1653:      case i_DIVU:
        !          1654:        genamode(table[opcode].smode, "srcreg", sz_word, "src", true, false);
        !          1655:        genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false);
        !          1656:        printf("\tif(src != 0){\n");
        !          1657:        printf("\tULONG newv = (ULONG)dst / (UWORD)src;\n");
        !          1658:        printf("\tULONG rem = (ULONG)dst %% (UWORD)src;\n");
        !          1659:        /* The N flag appears to be set each time there is an overflow.
        !          1660:         * Weird. */
        !          1661:        printf("\tif (newv > 0xffff) { regs.v = regs.n = 1; } else\n\t{\n");
        !          1662:        genflags(flag_logical, sz_word, "newv", "", "");
        !          1663:        printf("\tnewv = (newv & 0xffff) | ((ULONG)rem << 16);\n");
        !          1664:        genastore("newv",table[opcode].dmode, "dstreg", sz_long, "dst");
        !          1665:        printf("\t}\n");
        !          1666:        printf("\t}\n");
        !          1667:        break;
        !          1668:      case i_DIVS: 
        !          1669:        genamode(table[opcode].smode, "srcreg", sz_word, "src", true, false);
        !          1670:        genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false);
        !          1671:        printf("\tif(src != 0){\n");
        !          1672:        printf("\tLONG newv = (LONG)dst / (WORD)src;\n");
        !          1673:        printf("\tUWORD rem = (LONG)dst %% (WORD)src;\n");
        !          1674:        printf("\tif ((newv & 0xffff0000) && (newv & 0xffff0000) != 0xffff0000) { regs.v = regs.n = 1; } else\n\t{\n");
        !          1675:        printf("\tif (((WORD)rem < 0) != ((LONG)dst < 0)) rem = -rem;\n");
        !          1676:        genflags(flag_logical, sz_word, "newv", "", "");
        !          1677:        printf("\tnewv = (newv & 0xffff) | ((ULONG)rem << 16);\n");
        !          1678:        genastore("newv",table[opcode].dmode, "dstreg", sz_long, "dst");
        !          1679:        printf("\t}\n");
        !          1680:        printf("\t}\n");
        !          1681:        break;
        !          1682:      case i_MULU: 
        !          1683:        genamode(table[opcode].smode, "srcreg", sz_word, "src", true, false);
        !          1684:        genamode(table[opcode].dmode, "dstreg", sz_word, "dst", true, false);
        !          1685:        start_brace ();
        !          1686:        printf("\tULONG newv = (ULONG)(UWORD)dst * (ULONG)(UWORD)src;\n");
        !          1687:        genflags(flag_logical, sz_long, "newv", "", "");
        !          1688:        genastore("newv",table[opcode].dmode, "dstreg", sz_long, "dst");
        !          1689: #ifdef WANT_SLOW_MULTIPLY
        !          1690:        printf("\tspecialflags |= SPCFLAG_EXTRA_CYCLES;\n");
        !          1691: #endif
        !          1692:        break;
        !          1693:      case i_MULS:
        !          1694:        genamode(table[opcode].smode, "srcreg", sz_word, "src", true, false);
        !          1695:        genamode(table[opcode].dmode, "dstreg", sz_word, "dst", true, false);
        !          1696:        start_brace ();
        !          1697:        printf("\tULONG newv = (LONG)(WORD)dst * (LONG)(WORD)src;\n");
        !          1698:        genflags(flag_logical, sz_long, "newv", "", "");
        !          1699:        genastore("newv",table[opcode].dmode, "dstreg", sz_long, "dst");
        !          1700: #ifdef WANT_SLOW_MULTIPLY
        !          1701:        printf("\tspecialflags |= SPCFLAG_EXTRA_CYCLES;\n");
        !          1702: #endif
        !          1703:        break;
        !          1704:      case i_ASR: 
        !          1705:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
        !          1706:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
        !          1707:        start_brace ();
        !          1708:        switch(table[opcode].size) {
        !          1709:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
        !          1710:         case sz_word: printf("\tUWORD val = data;\n"); break;
        !          1711:         case sz_long: printf("\tULONG val = data;\n"); break;
        !          1712:         default: myabort();
        !          1713:        }
        !          1714:        printf("\tcnt &= 63;\n");
        !          1715:        printf("\tregs.v = 0;\n");
        !          1716:        start_brace ();
        !          1717:        switch(table[opcode].size) {
        !          1718:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
        !          1719:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
        !          1720:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
        !          1721:         default: myabort();
        !          1722:        }
        !          1723:        printf("\tULONG sign = cmask & val;\n");
        !          1724:        printf("\tfor(;cnt;--cnt){\n");
        !          1725:        printf("\tregs.c=regs.x=val&1; val = ((ULONG)val >> 1) | sign;\n");
        !          1726:        printf("\t}\n\tregs.n = sign != 0;\n");
        !          1727:        printf("\tregs.z = val == 0;\n");
        !          1728:        genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
        !          1729:        break;
        !          1730:      case i_ASL:
        !          1731:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
        !          1732:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
        !          1733:        start_brace ();
        !          1734:        switch(table[opcode].size) {
        !          1735:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
        !          1736:         case sz_word: printf("\tUWORD val = data;\n"); break;
        !          1737:         case sz_long: printf("\tULONG val = data;\n"); break;
        !          1738:         default: myabort();
        !          1739:        }
        !          1740:        printf("\tcnt &= 63;\n");
        !          1741:        printf("\tregs.v = 0;\n");
        !          1742:        start_brace ();
        !          1743:        switch(table[opcode].size) {
        !          1744:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
        !          1745:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
        !          1746:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
        !          1747:         default: myabort();
        !          1748:        }
        !          1749:        printf("\tULONG sign = cmask & val;\n");
        !          1750:        printf("\tfor(;cnt;--cnt){\n");
        !          1751:        printf("\tregs.c=regs.x=(val&cmask)!=0; val <<= 1;\n");
        !          1752:        printf("\tif ((val&cmask)!=sign)regs.v=1;\n");
        !          1753:        printf("\t}\n\tregs.n = (val&cmask) != 0;\n");
        !          1754:        printf("\tregs.z = val == 0;\n");
        !          1755:        genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
        !          1756:        break;
        !          1757:      case i_LSR:
        !          1758:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
        !          1759:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
        !          1760:        start_brace ();
        !          1761:        switch(table[opcode].size) {
        !          1762:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
        !          1763:         case sz_word: printf("\tUWORD val = data;\n"); break;
        !          1764:         case sz_long: printf("\tULONG val = data;\n"); break;
        !          1765:         default: myabort();
        !          1766:        }
        !          1767:        printf("\tcnt &= 63;\n");
        !          1768:        start_brace ();
        !          1769:        printf("\tint carry = 0;\n");
        !          1770:        printf("\tfor(;cnt;--cnt){\n");
        !          1771:        printf("\tcarry=val&1; val >>= 1;\n");
        !          1772:        printf("\t}\n");
        !          1773:        genflags(flag_logical, table[opcode].size, "val", "", "");
        !          1774:        printf("regs.c = regs.x = carry!=0;\n");
        !          1775:        genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
        !          1776:        break;
        !          1777:      case i_LSL:
        !          1778:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
        !          1779:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
        !          1780:        start_brace ();
        !          1781:        switch(table[opcode].size) {
        !          1782:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
        !          1783:         case sz_word: printf("\tUWORD val = data;\n"); break;
        !          1784:         case sz_long: printf("\tULONG val = data;\n"); break;
        !          1785:         default: myabort();
        !          1786:        }
        !          1787:        printf("\tcnt &= 63;\n");
        !          1788:        start_brace ();
        !          1789:        printf("\tint carry = 0;\n");
        !          1790:        switch(table[opcode].size) {
        !          1791:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
        !          1792:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
        !          1793:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
        !          1794:         default: myabort();
        !          1795:        }
        !          1796:        printf("\tfor(;cnt;--cnt){\n");
        !          1797:        printf("\tcarry=val&cmask; val <<= 1;\n");
        !          1798:        printf("\t}\n");
        !          1799:        genflags(flag_logical, table[opcode].size, "val", "", "");
        !          1800:        printf("regs.c = regs.x = carry!=0;\n");
        !          1801:        genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
        !          1802:        break;
        !          1803:      case i_ROL:
        !          1804:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
        !          1805:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
        !          1806:        start_brace ();
        !          1807:        switch(table[opcode].size) {
        !          1808:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
        !          1809:         case sz_word: printf("\tUWORD val = data;\n"); break;
        !          1810:         case sz_long: printf("\tULONG val = data;\n"); break;
        !          1811:         default: myabort();
        !          1812:        }
        !          1813:        printf("\tcnt &= 63;\n");
        !          1814:        start_brace ();
        !          1815:        printf("\tint carry = 0;\n");
        !          1816:        switch(table[opcode].size) {
        !          1817:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
        !          1818:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
        !          1819:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
        !          1820:         default: myabort();
        !          1821:        }
        !          1822:        printf("\tfor(;cnt;--cnt){\n");
        !          1823:        printf("\tcarry=val&cmask; val <<= 1;\n");
        !          1824:        printf("\tif(carry)  val |= 1;\n");
        !          1825:        printf("\t}\n");
        !          1826:        genflags(flag_logical, table[opcode].size, "val", "", "");
        !          1827:        printf("regs.c = carry!=0;\n");
        !          1828:        genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
        !          1829:        break;
        !          1830:      case i_ROR:
        !          1831:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
        !          1832:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
        !          1833:        start_brace ();
        !          1834:        switch(table[opcode].size) {
        !          1835:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
        !          1836:         case sz_word: printf("\tUWORD val = data;\n"); break;
        !          1837:         case sz_long: printf("\tULONG val = data;\n"); break;
        !          1838:         default: myabort();
        !          1839:        }
        !          1840:        
        !          1841:        printf("\tcnt &= 63;\n");
        !          1842:        start_brace ();
        !          1843:        printf("\tint carry = 0;\n");
        !          1844:        switch(table[opcode].size) {
        !          1845:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
        !          1846:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
        !          1847:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
        !          1848:         default: myabort();
        !          1849:        }
        !          1850:        printf("\tfor(;cnt;--cnt){\n");
        !          1851:        printf("\tcarry=val&1; val = (ULONG)val >> 1;\n");
        !          1852:        printf("\tif(carry) val |= cmask;\n");
        !          1853:        printf("\t}\n");
        !          1854:        genflags(flag_logical, table[opcode].size, "val", "", "");
        !          1855:        printf("\tregs.c = carry!=0;\n");
        !          1856:        genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
        !          1857:        break;
        !          1858:      case i_ROXL: 
        !          1859:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
        !          1860:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
        !          1861:        start_brace ();
        !          1862:        switch(table[opcode].size) {
        !          1863:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
        !          1864:         case sz_word: printf("\tUWORD val = data;\n"); break;
        !          1865:         case sz_long: printf("\tULONG val = data;\n"); break;
        !          1866:         default: myabort();
        !          1867:        }
        !          1868:        printf("\tcnt &= 63;\n");
        !          1869:        start_brace ();
        !          1870:        printf("\tint carry = 0;\n");
        !          1871:        switch(table[opcode].size) {
        !          1872:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
        !          1873:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
        !          1874:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
        !          1875:         default: myabort();
        !          1876:        }
        !          1877:        printf("\tfor(;cnt;--cnt){\n");
        !          1878:        printf("\tcarry=val&cmask; val <<= 1;\n");
        !          1879:        printf("\tif(regs.x) val |= 1;\n");    
        !          1880:        printf("\tregs.x = carry != 0;\n");
        !          1881:        printf("\t}\n");
        !          1882:        genflags(flag_logical, table[opcode].size, "val", "", "");
        !          1883:        printf("\tregs.x = regs.c = carry!=0;\n");
        !          1884:        genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
        !          1885:        break;
        !          1886:      case i_ROXR:
        !          1887:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
        !          1888:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
        !          1889:        start_brace ();
        !          1890:        switch(table[opcode].size) {
        !          1891:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
        !          1892:         case sz_word: printf("\tUWORD val = data;\n"); break;
        !          1893:         case sz_long: printf("\tULONG val = data;\n"); break;
        !          1894:         default: myabort();
        !          1895:        }
        !          1896:        printf("\tcnt &= 63;\n");
        !          1897:        start_brace ();
        !          1898:        printf("\tint carry = 0;\n");
        !          1899:        switch(table[opcode].size) {
        !          1900:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
        !          1901:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
        !          1902:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
        !          1903:         default: myabort();
        !          1904:        }
        !          1905:        printf("\tfor(;cnt;--cnt){\n");
        !          1906:        printf("\tcarry=val&1; val >>= 1;\n");
        !          1907:        printf("\tif(regs.x) val |= cmask;\n");
        !          1908:        printf("\tregs.x = carry != 0;\n");
        !          1909:        printf("\t}\n");
        !          1910:        genflags(flag_logical, table[opcode].size, "val", "", "");
        !          1911:        printf("\tregs.x = regs.c = carry!=0;\n");
        !          1912:        genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
        !          1913:        break;
        !          1914:      case i_ASRW:
        !          1915:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
        !          1916:        printf("\tregs.v = 0;\n");
        !          1917:        start_brace ();
        !          1918:        switch(table[opcode].size) {
        !          1919:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
        !          1920:         case sz_word: printf("\tUWORD val = data;\n"); break;
        !          1921:         case sz_long: printf("\tULONG val = data;\n"); break;
        !          1922:         default: myabort();
        !          1923:        }
        !          1924:        switch(table[opcode].size) {
        !          1925:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
        !          1926:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
        !          1927:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
        !          1928:         default: myabort();
        !          1929:        }
        !          1930:        printf("\tULONG sign = cmask & val;\n");
        !          1931:        printf("\tregs.c=regs.x=val&1; val = (val >> 1) | sign;\n");
        !          1932:        printf("\tregs.n = sign != 0;\n");
        !          1933:        printf("\tregs.z = val == 0;\n");
        !          1934:        genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
        !          1935:        break;
        !          1936:      case i_ASLW:
        !          1937:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
        !          1938:        printf("\tregs.v = 0;\n");
        !          1939:        start_brace ();
        !          1940:        switch(table[opcode].size) {
        !          1941:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
        !          1942:         case sz_word: printf("\tUWORD val = data;\n"); break;
        !          1943:         case sz_long: printf("\tULONG val = data;\n"); break;
        !          1944:         default: myabort();
        !          1945:        }
        !          1946:        switch(table[opcode].size) {
        !          1947:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
        !          1948:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
        !          1949:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
        !          1950:         default: myabort();
        !          1951:        }
        !          1952:        printf("\tULONG sign = cmask & val;\n");
        !          1953:        printf("\tregs.c=regs.x=(val&cmask)!=0; val <<= 1;\n");
        !          1954:        printf("\tif ((val&cmask)!=sign)regs.v=1;\n");
        !          1955:        printf("\tregs.n = (val&cmask) != 0;\n");
        !          1956:        printf("\tregs.z = val == 0;\n");
        !          1957:        genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
        !          1958:        break;
        !          1959:      case i_LSRW:
        !          1960:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
        !          1961:        start_brace ();
        !          1962:        switch(table[opcode].size) {
        !          1963:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
        !          1964:         case sz_word: printf("\tUWORD val = data;\n"); break;
        !          1965:         case sz_long: printf("\tULONG val = data;\n"); break;
        !          1966:         default: myabort();
        !          1967:        }
        !          1968:        printf("\tint carry = val&1;\n");
        !          1969:        printf("\tcarry=val&1; val >>= 1;\n");
        !          1970:        genflags(flag_logical, table[opcode].size, "val", "", "");
        !          1971:        printf("regs.c = regs.x = carry!=0;\n");
        !          1972:        genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
        !          1973:        break;
        !          1974:      case i_LSLW:
        !          1975:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
        !          1976:        start_brace ();
        !          1977:        switch(table[opcode].size) {
        !          1978:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
        !          1979:         case sz_word: printf("\tUWORD val = data;\n"); break;
        !          1980:         case sz_long: printf("\tULONG val = data;\n"); break;
        !          1981:         default: myabort();
        !          1982:        }
        !          1983:        switch(table[opcode].size) {
        !          1984:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
        !          1985:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
        !          1986:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
        !          1987:         default: myabort();
        !          1988:        }
        !          1989:        printf("\tint carry = val&cmask;\n");
        !          1990:        printf("\tval <<= 1;\n");
        !          1991:        genflags(flag_logical, table[opcode].size, "val", "", "");
        !          1992:        printf("regs.c = regs.x = carry!=0;\n");
        !          1993:        genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
        !          1994:        break;
        !          1995:      case i_ROLW:
        !          1996:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
        !          1997:        start_brace ();
        !          1998:        switch(table[opcode].size) {
        !          1999:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
        !          2000:         case sz_word: printf("\tUWORD val = data;\n"); break;
        !          2001:         case sz_long: printf("\tULONG val = data;\n"); break;
        !          2002:         default: myabort();
        !          2003:        }
        !          2004:        switch(table[opcode].size) {
        !          2005:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
        !          2006:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
        !          2007:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
        !          2008:         default: myabort();
        !          2009:        }
        !          2010:        printf("\tint carry = val&cmask;\n");
        !          2011:        printf("\tval <<= 1;\n");
        !          2012:        printf("\tif(carry)  val |= 1;\n");
        !          2013:        genflags(flag_logical, table[opcode].size, "val", "", "");
        !          2014:        printf("regs.c = carry!=0;\n");
        !          2015:        genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
        !          2016:        break;
        !          2017:      case i_RORW:
        !          2018:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
        !          2019:        start_brace ();
        !          2020:        switch(table[opcode].size) {
        !          2021:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
        !          2022:         case sz_word: printf("\tUWORD val = data;\n"); break;
        !          2023:         case sz_long: printf("\tULONG val = data;\n"); break;
        !          2024:         default: myabort();
        !          2025:        }
        !          2026:        printf("\tint carry = val&1;\n");
        !          2027:        switch(table[opcode].size) {
        !          2028:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
        !          2029:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
        !          2030:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
        !          2031:         default: myabort();
        !          2032:        }
        !          2033:        printf("\tval >>= 1;\n");
        !          2034:        printf("\tif(carry) val |= cmask;\n");
        !          2035:        genflags(flag_logical, table[opcode].size, "val", "", "");
        !          2036:        printf("regs.c = carry!=0;\n");
        !          2037:        genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
        !          2038:        break;
        !          2039:      case i_ROXLW:
        !          2040:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
        !          2041:        start_brace ();
        !          2042:        switch(table[opcode].size) {
        !          2043:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
        !          2044:         case sz_word: printf("\tUWORD val = data;\n"); break;
        !          2045:         case sz_long: printf("\tULONG val = data;\n"); break;
        !          2046:         default: myabort();
        !          2047:        }
        !          2048:        switch(table[opcode].size) {
        !          2049:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
        !          2050:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
        !          2051:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
        !          2052:         default: myabort();
        !          2053:        }
        !          2054:        printf("\tint carry = val&cmask;\n");
        !          2055:        printf("\tval <<= 1;\n");
        !          2056:        printf("\tif(regs.x) val |= 1;\n");
        !          2057:        printf("\tregs.x = carry != 0;\n");
        !          2058:        genflags(flag_logical, table[opcode].size, "val", "", "");
        !          2059:        printf("regs.x = regs.c = carry!=0;\n");
        !          2060:        genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
        !          2061:        break;
        !          2062:      case i_ROXRW:
        !          2063:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
        !          2064:        start_brace ();
        !          2065:        switch(table[opcode].size) {
        !          2066:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
        !          2067:         case sz_word: printf("\tUWORD val = data;\n"); break;
        !          2068:         case sz_long: printf("\tULONG val = data;\n"); break;
        !          2069:         default: myabort();
        !          2070:        }
        !          2071:        printf("\tint carry = val&1;\n");
        !          2072:        switch(table[opcode].size) {
        !          2073:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
        !          2074:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
        !          2075:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
        !          2076:         default: myabort();
        !          2077:        }
        !          2078:        printf("\tval >>= 1;\n");
        !          2079:        printf("\tif(regs.x) val |= cmask;\n");
        !          2080:        printf("\tregs.x = carry != 0;\n");
        !          2081:        genflags(flag_logical, table[opcode].size, "val", "", "");
        !          2082:        printf("regs.x = regs.c = carry!=0;\n");
        !          2083:        genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
        !          2084:        break;
        !          2085:      default:
        !          2086:        myabort();
        !          2087:        break;
        !          2088:     };
        !          2089:     finish_braces ();
        !          2090: }
        !          2091: 
        !          2092: static int mismatch;
        !          2093: 
        !          2094: static void handle_merges(long int opcode)
        !          2095: {
        !          2096:     UWORD smsk; 
        !          2097:     UWORD dmsk;
        !          2098:     int sbitsrc, sbitdst;
        !          2099:     int srcreg, dstreg;
        !          2100:     
        !          2101:     smsk = (table[opcode].sbtarg ? 255 : 7) << table[opcode].spos;
        !          2102:     dmsk = 7 << table[opcode].dpos;
        !          2103:     sbitsrc = table[opcode].spos == -1 ? 0 : 0;
        !          2104:     sbitdst = table[opcode].spos == -1 ? 1 : (table[opcode].sbtarg ? 256 : 8);
        !          2105:     for (srcreg=sbitsrc; srcreg < sbitdst; srcreg++) {
        !          2106:        for (dstreg=0; dstreg < (table[opcode].dpos == -1 ? 1 : 8); dstreg++) {
        !          2107:            UWORD code = opcode;                
        !          2108: 
        !          2109:            if (table[opcode].spos != -1) code &= ~(smsk << table[opcode].spos);
        !          2110:            if (table[opcode].dpos != -1) code &= ~(dmsk << table[opcode].dpos);
        !          2111:            
        !          2112:            if (table[opcode].spos != -1) code |= srcreg << table[opcode].spos;
        !          2113:            if (table[opcode].dpos != -1) code |= dstreg << table[opcode].dpos;
        !          2114:            
        !          2115:            /* Check whether this is in fact the same instruction.
        !          2116:             * The instructions should never differ, except for the
        !          2117:             * Bcc.(BW) case. */
        !          2118:            if (table[code].mnemo != table[opcode].mnemo
        !          2119:                || table[code].size != table[opcode].size
        !          2120:                || table[code].suse != table[opcode].suse
        !          2121:                || table[code].duse != table[opcode].duse) 
        !          2122:            {
        !          2123:                mismatch++; continue;
        !          2124:            }
        !          2125:            if (table[opcode].suse 
        !          2126:                && (table[opcode].spos != table[code].spos
        !          2127:                    || table[opcode].smode != table[code].smode
        !          2128:                    || table[opcode].sbtarg != table[code].sbtarg)) 
        !          2129:            {
        !          2130:                mismatch++; continue;
        !          2131:            }
        !          2132:            if (table[opcode].duse 
        !          2133:                && (table[opcode].dpos != table[code].dpos
        !          2134:                    || table[opcode].dmode != table[code].dmode))
        !          2135:            {
        !          2136:                mismatch++; continue;
        !          2137:            }
        !          2138:            
        !          2139:            table[code].generated = true;
        !          2140:            table[code].handler = opcode;
        !          2141:        }
        !          2142:     }
        !          2143: }
        !          2144:               
        !          2145: static void generate_func(long int from, long int to)
        !          2146: {
        !          2147:     int illg = 0;
        !          2148:     long int opcode;
        !          2149:     UWORD smsk; 
        !          2150:     UWORD dmsk;    
        !          2151:     mismatch = 0;
        !          2152: 
        !          2153:     printf("#include <stdlib.h>\n");
        !          2154:     printf("#include \"config.h\"\n");
        !          2155:     printf("#include \"amiga.h\"\n");
        !          2156:     printf("#include \"options.h\"\n");
        !          2157:     printf("#include \"memory.h\"\n");
        !          2158:     printf("#include \"custom.h\"\n");    
        !          2159:     printf("#include \"newcpu.h\"\n");
        !          2160:     printf("#include \"cputbl.h\"\n");
        !          2161:     for(opcode=from; opcode < to; opcode++) {
        !          2162:        if (table[opcode].mnemo == i_ILLG) {
        !          2163:            illg++;
        !          2164:            continue;
        !          2165:        }
        !          2166:        if (table[opcode].generated) {
        !          2167:            continue;
        !          2168:        }
        !          2169: #ifndef HAVE_ONE_GIG_OF_MEMORY_TO_COMPILE_THIS
        !          2170:     
        !          2171:        handle_merges (opcode);
        !          2172:        
        !          2173:        smsk = (table[opcode].sbtarg ? 255 : 7) << table[opcode].spos;
        !          2174:        dmsk = 7 << table[opcode].dpos;
        !          2175: 
        !          2176:        printf("void op_%lx(UWORD opcode)\n{\n", opcode);
        !          2177:        if (table[opcode].suse
        !          2178:            && table[opcode].smode != imm  && table[opcode].smode != imm0
        !          2179:            && table[opcode].smode != imm1 && table[opcode].smode != imm2
        !          2180:            && table[opcode].smode != absw && table[opcode].smode != absl
        !          2181:            && table[opcode].smode != PC8r && table[opcode].smode != PC16)
        !          2182:        {
        !          2183:            if (table[opcode].spos == -1) {
        !          2184:                printf("\tULONG srcreg = %d;\n", (int)table[opcode].sreg);
        !          2185:            } else {
        !          2186:                printf("\tULONG srcreg = (LONG)(BYTE)((opcode & %d) >> %d);\n", smsk, (int)table[opcode].spos);
        !          2187:            }
        !          2188:        }
        !          2189:        if (table[opcode].duse
        !          2190:            /* Yes, the dmode can be imm, in case of LINK or DBcc */
        !          2191:            && table[opcode].dmode != imm  && table[opcode].dmode != imm0
        !          2192:            && table[opcode].dmode != imm1 && table[opcode].dmode != imm2
        !          2193:            && table[opcode].dmode != absw && table[opcode].dmode != absl) {
        !          2194:            if (table[opcode].dpos == -1) {             
        !          2195:                printf("\tULONG dstreg = %d;\n", (int)table[opcode].dreg);
        !          2196:            } else {
        !          2197:                printf("\tULONG dstreg = (opcode & %d) >> %d;\n", dmsk, (int)table[opcode].dpos);
        !          2198:            }
        !          2199:        }
        !          2200: #else
        !          2201:        printf("void op_%lx(UWORD opcode)\n{\n", opcode);
        !          2202:        if (table[opcode].suse)
        !          2203:            printf("\tULONG srcreg = %d;\n", (int)table[opcode].sreg);
        !          2204:        if (table[opcode].duse)
        !          2205:            printf("\tULONG dstreg = %d;\n", (int)table[opcode].dreg);
        !          2206: #endif
        !          2207:        gen_opcode(opcode);
        !          2208:         printf("}\n");
        !          2209:     }
        !          2210: 
        !          2211:     fprintf (stderr, "%d illegals generated.\n", illg);
        !          2212:     if (mismatch) fprintf(stderr, "%d mismatches.\n", mismatch);
        !          2213: }
        !          2214: 
        !          2215: static void generate_table(void)
        !          2216: {
        !          2217:     int illg = 0;
        !          2218:     long int opcode;
        !          2219:     
        !          2220:     mismatch = 0;
        !          2221:     
        !          2222:     printf("#include <stdlib.h>\n");
        !          2223:     printf("#include \"config.h\"\n");
        !          2224:     printf("#include \"amiga.h\"\n");
        !          2225:     printf("#include \"options.h\"\n");
        !          2226:     printf("#include \"memory.h\"\n");
        !          2227:     printf("#include \"custom.h\"\n");
        !          2228:     printf("#include \"newcpu.h\"\n");
        !          2229:     printf("#include \"cputbl.h\"\n");
        !          2230:     
        !          2231:     printf("cpuop_func *cpufunctbl[65536] = {\n");
        !          2232:     for(opcode=0; opcode < 65536; opcode++) {
        !          2233:        if (table[opcode].mnemo == i_ILLG) {
        !          2234:            printf("op_illg");
        !          2235:            illg++;
        !          2236:            goto loop_end;
        !          2237:        }
        !          2238:        if (table[opcode].generated) {
        !          2239:            printf("op_%x", table[opcode].handler);
        !          2240:            goto loop_end;
        !          2241:        }
        !          2242: #ifndef HAVE_ONE_GIG_OF_MEMORY_TO_COMPILE_THIS
        !          2243:        handle_merges (opcode);
        !          2244: #endif
        !          2245:        printf("op_%lx", opcode);
        !          2246:        
        !          2247:        loop_end:
        !          2248:        if (opcode < 65535) printf(",");
        !          2249:        if ((opcode & 7) == 7) printf("\n");
        !          2250:     }
        !          2251:     printf("\n};\n");
        !          2252:     fprintf (stderr, "%d illegals generated.\n", illg);
        !          2253:     if (mismatch) fprintf(stderr, "%d mismatches.\n", mismatch);
        !          2254: }
        !          2255: 
        !          2256: static void generate_header(void)
        !          2257: {
        !          2258:     int illg = 0;
        !          2259:     long int opcode;
        !          2260:     
        !          2261:     mismatch = 0;
        !          2262:     
        !          2263:     printf("extern void op_illg(UWORD) REGPARAM;\n");
        !          2264:     
        !          2265:     for(opcode=0; opcode < 65536; opcode++) {
        !          2266:        if (table[opcode].mnemo == i_ILLG) {
        !          2267:            illg++;
        !          2268:            continue;
        !          2269:        }
        !          2270:        if (table[opcode].generated) 
        !          2271:            continue;
        !          2272:            
        !          2273: #ifndef HAVE_ONE_GIG_OF_MEMORY_TO_COMPILE_THIS
        !          2274:        handle_merges (opcode);
        !          2275: #endif
        !          2276:        printf("extern cpuop_func op_%lx;\n", opcode);
        !          2277:     }
        !          2278:     
        !          2279:     fprintf (stderr, "%d illegals generated.\n", illg);
        !          2280:     if (mismatch) fprintf(stderr, "%d mismatches.\n", mismatch);
        !          2281: }
        !          2282: 
        !          2283: int main(int argc, char **argv)
        !          2284: {
        !          2285:     long int range = -1;
        !          2286:     char mode = 'n';
        !          2287:     int i;
        !          2288:     
        !          2289:     if (argc == 2)
        !          2290:        mode = *argv[1];
        !          2291: 
        !          2292:     if (argc == 3) {
        !          2293:        range = atoi(argv[2]);
        !          2294:        mode = *argv[1];
        !          2295:     }
        !          2296:     tablef = fopen("table68k","r");
        !          2297:     if (tablef == NULL) {
        !          2298:        fprintf(stderr, "table68k not found\n");
        !          2299:        exit(1);
        !          2300:     }
        !          2301:     table = (struct instr *) malloc (sizeof(struct instr) * 65536);
        !          2302:     for(i = 0; i < 65536; i++) {
        !          2303:        table[i].mnemo = i_ILLG;
        !          2304:     }
        !          2305:     getnextch();
        !          2306:     while (nextch != EOF) {
        !          2307:        get_bits();
        !          2308:        get_strs();
        !          2309:        parse_bits();
        !          2310:     }
        !          2311:     switch(mode) {
        !          2312:      case 'f':
        !          2313:        generate_func(range * 0x1000, (range + 1) * 0x1000);
        !          2314:        break;
        !          2315:      case 'h':
        !          2316:        generate_header();
        !          2317:        break;
        !          2318:      case 't':
        !          2319:        generate_table();
        !          2320:        break;
        !          2321:      default:
        !          2322:        myabort();
        !          2323:     }
        !          2324:     fclose(tablef);
        !          2325:     free(table);
        !          2326:     return 0;
        !          2327: }

unix.superglobalmegacorp.com

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