Annotation of nono/m680x0/m680x0ea.cpp, revision 1.1.1.2

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: // EA は大別して6種類。
                      8: //
                      9: // |d m  rxwp |        制御  CalcCtrl                サイズ不問
                     10: // |dam+-rxw  |        可変  CalcData                B/W/L
                     11: // |  m  rxwp |        MMU             CalcMMU                 サイズ不問
                     12: // |dam+-rxwpi|        FPU             CalcFPU                 B/W/L/S/D/X/P
                     13: // |d m+-rxwpi|        データ       FetchData               B/W/L
                     14: // |dam+-rxwpi|        All             FetchAll                B/W/L
                     15: //
                     16: // CalcCtrl はユーザーズマニュアルで「制御(Control)」と呼ばれている
                     17: // グループで、デスティネーション側のため EA の計算のみ。
                     18: // また (An)+/-(An) を含まないため、サイズに関係なく1種類だけでよい。
                     19: //
                     20: // CalcData はユーザーズマニュアルで「可変」と呼ばれているグループで、
                     21: // デスティネーション側のため EA の計算のみ。サイズは B/W/L。
                     22: // (An)+/-(An) ならレジスタを保存する。
                     23: //
                     24: // CalcMMU は対 68030 MMU 命令用に勝手に用意したもの。
                     25: //
                     26: // CalcFPU は対 FPU 用。ソースであっても CalcFPU を使用する。
                     27: // サイズは B/W/L/S/D/X/P。
                     28: // (An)+/-(An) ならレジスタを保存する。
                     29: // フェッチサイクルは別途存在するはずだが不詳。
                     30: //
                     31: // FetchData はユーザーズマニュアルで「データ(Data)」と呼ばれている
                     32: // グループで、ソース側のため EA 計算および値の取得。サイズは B/W/L。
                     33: // (An)+/-(An) ならレジスタを保存する。
                     34: //
                     35: // FetchAll はユーザーズマニュアルのここには記載がないグループで、
                     36: // ソース側のため EA 計算および値の取得。サイズは B/W/L。
                     37: // (An)+/-(An) ならレジスタを保存する。
                     38: //
                     39: // CalcCtrl、CalcData でアドレッシングモードに D や A が含まれている場合は
                     40: // その命令のデスティネーションに Dn、An が指定できるという意味であり、
                     41: // EA 処理であるここには関係ない。
                     42: // EA 計算より前に呼出側で条件分けして処理すること。
                     43: //
                     44: // CalcCtrl、CalcData と FetchData には (*) 印の例外があるので留意。
                     45: //
                     46: // (CalcCtrl)
                     47: // |  m  rxwp | CMP2/CHK2
                     48: // |  m  rxwp | JMP/JSR
                     49: // |  m  rxwp | LEA/PEA
                     50: // |d m  rxwp | BFEXT*/BFFFO/BFTST
                     51: // |d m  rxw  | (*) BFCHG/BFCLR/BFINS/BFSET <ea>{#o:#w}
                     52: //
                     53: // (CalcData)
                     54: // |  m+-rxw  | ADD/SUB/CMP Dx,<ea>
                     55: // |  m+-rxw  | CAS/TAS <ea>
                     56: // |  m+-rxw  | MOVES <ea>,Rn
                     57: // |  m+-rxw  | shift/rotate.W <ea>
                     58: // |  m+-rxw  | BCHG/BCLR/BSET src,<ea>
                     59: // |d m+-rxw  | ADDI/SUBI Dx,<ea>
                     60: // |d m+-rxw  | NBCD <ea>
                     61: // |d m+-rxw  | AND/OR/EOR Dx,<ea>
                     62: // |d m+-rxw  | CLR/NEG/NEGX/NOT/TST/Scc <ea>
                     63: // |d m+-rxw  | MOVE CCR/SR,<ea>
                     64: // |dam+-rxw  | ADDQ/SUBQ #qqq,<ea>
                     65: // |dam+-rxw  | (*) MOVE の dst 側。EA の分類的には CalcData だが、
                     66: //              下位6ビットの IR ではないので、cea_data_NN() ではなく
                     67: //              各々 cea_XXXX() のほうを個別に呼ぶこと。
                     68: //
                     69: // (CalcMMU)
                     70: // |  m  rxw  | MMU
                     71: //
                     72: // (CalcFPU)
                     73: // |d m+-rxw  | FScc.B <ea>
                     74: // |dam+-rxw  | FMOVE.f FPn,<ea>
                     75: // |dam+-rxw  | FMOVE.L ctl,<ea>
                     76: // |dam+-rxw  | FMOVEM.L ctl,<ea>
                     77: // |d m+-rxwpi| Fgen <ea>,FPn
                     78: // |d m+-rxwpi| FMOVE.f <ea>,FPn
                     79: // |dam+-rxwpi| FMOVE.L <ea>,ctl
                     80: // |dam+-rxwpi| FMOVEM.L <ea>,ctl
                     81: // 実際にどのアドレッシングモードが有効かどうかは極力個別の命令内で判断する?
                     82: // ここは実行サイクル数的な分類。
                     83: //
                     84: // (FetchData)
                     85: // |d m+-rxwpi| AND/OR/CHK <ea>,Dn
                     86: // |d m+-rxwpi| MOVE.B <ea>,dst
                     87: // |d m+-rxwpi| MOVE <ea>,CCR/SR
                     88: // |d m+-rxwpi| MUL*/DIV* <ea>,Dn
                     89: // |d m+-rxwp | (*) TST.B <ea>
                     90: // |d m+-rxwp | (*) CMPI #<data>,<ea>
                     91: // |  m+-rxwp | (*) BTST.B #<data>,<ea>
                     92: // |  m+-rxwpi| (*) BTST.B Dx,<ea>
                     93: //
                     94: // (FetchAll)
                     95: // |dam+-rxwpi| ADD/SUB/CMP <ea>,Dn
                     96: // |dam+-rxwpi| MOVEA/ADDA/SUBA/CMPA <ea>,An
                     97: // |dam+-rxwpi| TST.WL <ea>
                     98: // |dam+-rxwpi| MOVE.WL <ea>,dst
                     99: //
                    100: // (たぶん別対応)
                    101: // |  m -rxw  | MOVEM list,<ea>
                    102: // |  m -rxw  | FMOVEM.X reg,<ea>
                    103: // |  m -rxw  | FSAVE <ea>
                    104: // |  m+ rxwp | MOVEM <ea>,list
                    105: // |  m+ rxwp | FMOVEM.X <ea>,reg
                    106: // |  m+ rxwp | FRESTORE <ea>
                    107: 
                    108: #include "mpu680x0.h"
1.1.1.2 ! root      109: #include "m680x0cycle.h"
1.1       root      110: 
                    111: //
                    112: // Calc EA
                    113: //
                    114: 
                    115: // 個別 EA は (An)+/-(An) でもレジスタを保存しない。
                    116: // 自動的に保存する cea_data() 等を介さずこれらを呼ぶ時は
                    117: // レジスタ保存のタイミングや回数に注意すること。
                    118: 
                    119: uint32
                    120: MPU680x0Device::cea_anin(uint n)
                    121: {
1.1.1.2 ! root      122:        CYCLE3(cea_anin);
1.1       root      123:        return internal_ea_anin(n);
                    124: }
                    125: 
                    126: uint32
                    127: MPU680x0Device::cea_anpi_1(uint n)
                    128: {
1.1.1.2 ! root      129:        CYCLE3(cea_anpi);
1.1       root      130:        return internal_ea_anpi_1(n);
                    131: }
                    132: 
                    133: uint32
                    134: MPU680x0Device::cea_anpi_2(uint n)
                    135: {
1.1.1.2 ! root      136:        CYCLE3(cea_anpi);
1.1       root      137:        return internal_ea_anpi_2(n);
                    138: }
                    139: 
                    140: uint32
                    141: MPU680x0Device::cea_anpi_4(uint n)
                    142: {
1.1.1.2 ! root      143:        CYCLE3(cea_anpi);
1.1       root      144:        return internal_ea_anpi_4(n);
                    145: }
                    146: 
                    147: uint32
                    148: MPU680x0Device::cea_anpd_1(uint n)
                    149: {
1.1.1.2 ! root      150:        CYCLE3(cea_anpd);
1.1       root      151:        return internal_ea_anpd_1(n);
                    152: }
                    153: 
                    154: uint32
                    155: MPU680x0Device::cea_anpd_2(uint n)
                    156: {
1.1.1.2 ! root      157:        CYCLE3(cea_anpd);
1.1       root      158:        return internal_ea_anpd_2(n);
                    159: }
                    160: 
                    161: uint32
                    162: MPU680x0Device::cea_anpd_4(uint n)
                    163: {
1.1.1.2 ! root      164:        CYCLE3(cea_anpd);
1.1       root      165:        return internal_ea_anpd_4(n);
                    166: }
                    167: 
                    168: uint32
                    169: MPU680x0Device::cea_andi(uint n)
                    170: {
1.1.1.2 ! root      171:        CYCLE3(cea_andi);
1.1       root      172:        return internal_ea_andi(n);
                    173: }
                    174: 
                    175: uint32
                    176: MPU680x0Device::cea_anix(uint n)
                    177: {
1.1.1.2 ! root      178:        // CYCLE は呼び出し先で加算。
1.1       root      179:        return internal_ea_anix(n);
                    180: }
                    181: 
                    182: uint32
                    183: MPU680x0Device::cea_absw()
                    184: {
1.1.1.2 ! root      185:        CYCLE3(cea_absw);
1.1       root      186:        return internal_ea_absw();
                    187: }
                    188: 
                    189: uint32
                    190: MPU680x0Device::cea_absl()
                    191: {
1.1.1.2 ! root      192:        CYCLE3(cea_absl);
1.1       root      193:        return internal_ea_absl();
                    194: }
                    195: 
                    196: uint32
                    197: MPU680x0Device::cea_pcdi()
                    198: {
1.1.1.2 ! root      199:        CYCLE3(cea_andi);
1.1       root      200:        return internal_ea_pcdi();
                    201: }
                    202: 
                    203: uint32
                    204: MPU680x0Device::cea_pcix()
                    205: {
1.1.1.2 ! root      206:        // CYCLE は呼び出し先で加算。
1.1       root      207:        return internal_ea_pcix();
                    208: }
                    209: 
                    210: //
                    211: // Fetch EA
                    212: //
                    213: 
                    214: inline uint32
                    215: MPU680x0Device::fea_anin()
                    216: {
1.1.1.2 ! root      217:        CYCLE3(fea_anin);
1.1       root      218:        return internal_ea_anin(eanum(ir));
                    219: }
                    220: 
                    221: inline uint32
                    222: MPU680x0Device::fea_anpi_1()
                    223: {
1.1.1.2 ! root      224:        CYCLE3(fea_anpi);
1.1       root      225:        return internal_ea_anpi_1(eanum(ir));
                    226: }
                    227: 
                    228: inline uint32
                    229: MPU680x0Device::fea_anpi_2()
                    230: {
1.1.1.2 ! root      231:        CYCLE3(fea_anpi);
1.1       root      232:        return internal_ea_anpi_2(eanum(ir));
                    233: }
                    234: 
                    235: inline uint32
                    236: MPU680x0Device::fea_anpi_4()
                    237: {
1.1.1.2 ! root      238:        CYCLE3(fea_anpi);
1.1       root      239:        return internal_ea_anpi_4(eanum(ir));
                    240: }
                    241: 
                    242: inline uint32
                    243: MPU680x0Device::fea_anpd_1()
                    244: {
1.1.1.2 ! root      245:        CYCLE3(fea_anpd);
1.1       root      246:        return internal_ea_anpd_1(eanum(ir));
                    247: }
                    248: 
                    249: inline uint32
                    250: MPU680x0Device::fea_anpd_2()
                    251: {
1.1.1.2 ! root      252:        CYCLE3(fea_anpd);
1.1       root      253:        return internal_ea_anpd_2(eanum(ir));
                    254: }
                    255: 
                    256: inline uint32
                    257: MPU680x0Device::fea_anpd_4()
                    258: {
1.1.1.2 ! root      259:        CYCLE3(fea_anpd);
1.1       root      260:        return internal_ea_anpd_4(eanum(ir));
                    261: }
                    262: 
                    263: inline uint32
                    264: MPU680x0Device::fea_andi()
                    265: {
1.1.1.2 ! root      266:        CYCLE3(fea_andi);
1.1       root      267:        return internal_ea_andi(eanum(ir));
                    268: }
                    269: 
                    270: inline uint32
                    271: MPU680x0Device::fea_anix()
                    272: {
1.1.1.2 ! root      273:        // CYCLE は呼び出し先で加算。
1.1       root      274:        return internal_ea_anix(eanum(ir));
                    275: }
                    276: 
                    277: inline uint32
                    278: MPU680x0Device::fea_absw()
                    279: {
1.1.1.2 ! root      280:        CYCLE3(fea_absw);
1.1       root      281:        return internal_ea_absw();
                    282: }
                    283: 
                    284: inline uint32
                    285: MPU680x0Device::fea_absl()
                    286: {
1.1.1.2 ! root      287:        CYCLE3(fea_absl);
1.1       root      288:        return internal_ea_absl();
                    289: }
                    290: 
                    291: inline uint32
                    292: MPU680x0Device::fea_pcdi()
                    293: {
1.1.1.2 ! root      294:        CYCLE3(fea_andi);
1.1       root      295:        return internal_ea_pcdi();
                    296: }
                    297: 
                    298: inline uint32
                    299: MPU680x0Device::fea_pcix()
                    300: {
1.1.1.2 ! root      301:        // CYCLE は呼び出し先で加算。
1.1       root      302:        return internal_ea_pcix();
                    303: }
                    304: 
                    305: inline void
                    306: MPU680x0Device::fea_imm_2()
                    307: {
1.1.1.2 ! root      308:        CYCLE3(fea_immw);
1.1       root      309: }
                    310: 
                    311: inline void
                    312: MPU680x0Device::fea_imm_4()
                    313: {
1.1.1.2 ! root      314:        CYCLE3(fea_imml);
1.1       root      315: }
                    316: 
                    317: //
                    318: // EA の拡張ワード
                    319: //
                    320: 
1.1.1.2 ! root      321: // 所要サイクルについて。
        !           322: // 本来 internal_ea_*() はサイクルを加算しないが、ea_ix は展開してみないと
        !           323: // 分からないのでここで加算する。CEA と FEA の両方から呼ばれて本来なら
        !           324: // サイクル数が異なるのだが、実際にサイクル数が異なるのは No Cache Case 側
        !           325: // だけなので、簡略化のため FEA (の NCC) のことは忘れる。
        !           326: //
        !           327: // サイクルは、メモリ間接かどうか、ベースディスプレースメント(bd) のサイズ、
        !           328: // アウターディスプレースメント(od) のサイズ、の3つのパラメータで決まる。
        !           329: //
        !           330: // 間接      bd              od              CEA               bd加算分  od加算分
        !           331: // ----        ----    ----    ----
        !           332: // n   -               -               (6,6)
        !           333: // n   16              -               (8,9)   = (6,6)   + (2,3)
        !           334: // n   32              -               (12,12) = (6,6)   + (6,6)
        !           335: // y   -               -               (10,10)
        !           336: // y   -               16/32   (12,13) = (10,10)           + (2,3)
        !           337: // y   16              -               (12,13) = (10,10) + (2,3)
        !           338: // y   16              16/32   (14,16) = (10,10) + (2,3)   + (2,3)
        !           339: // y   32              -               (16,17) = (10,10) + (6,7)※1
        !           340: // y   32              16/32   (18,20) = (10,10) + (6,7)※1+ (2,3)
        !           341: //
        !           342: // ※1: 簡略化のためここの (6,7) は (6,6) として扱う。
        !           343: //
        !           344: // FEA はだいたいこんな感じになるが、実装はしない。
        !           345: //
        !           346: // 間接      bd              od              FEA               bd加算分  od加算分
        !           347: // ----        ----    ----    ----
        !           348: // n   -               -               (6,7)
        !           349: // n   16              -               (8,10)  = (6,7)   + (2,3)
        !           350: // n   32              -               (12,13) = (6,7)   + (6,6)
        !           351: // y   -               -               (10,10)
        !           352: // y   -               16              (12,13) = (10,10)         + (2,3)
        !           353: // y   -               32              (12,14) = (10,10)         + (2,4)
        !           354: // y   16              -               (12,13)
        !           355: // y   16              16              (14,16) = (10,10) + (2,3) + (2,3)
        !           356: // y   16              32              (14,17) = (10,10) + (2,3) + (2,4)
        !           357: // y   32              -               (16,17) = (10,10) + (6,7)
        !           358: // y   32              16              (18,20) = (10,10) + (6,7) + (2,3)
        !           359: // y   32              32              (18,21) = (10,10) + (6,7) + (2,4)
1.1       root      360: uint32
                    361: MPU680x0Device::internal_ea_ix(uint32 anpc)
                    362: {
                    363:        uint16 ext = fetch_2();
                    364:        uint rn = (ext >> 12) & 15;
                    365:        bool idx_long = (ext & 0x0800);
                    366:        uint scale = (ext >> 9) & 3;
                    367: 
                    368:        if ((ext & 0x0100) == 0) {
                    369:                // Brief extension
                    370:                //
                    371:                //   F   E   D   C   B   A   9   8   7   6   5   4   3   2   1   0
                    372:                // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
                    373:                // | DA|     n     | WL| SCALE | 0 |             disp              |
                    374:                // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
                    375:                //
                    376:                // WL: インデックスレジスタ(Rn)のサイズ 1=.L 0=.W
                    377:                // SCALE: スケールファクタ %00=*1 %01=*2 %10=*4 %11=*8
                    378: 
1.1.1.2 ! root      379:                CYCLE3(cea_anix_brief);
1.1       root      380:                int32 disp = (int32)(int8)(ext & 0xff);
                    381:                uint32 idx;
                    382: 
                    383:                if (idx_long) {
                    384:                        idx = reg.R[rn];
                    385:                } else {
                    386:                        idx = (int32)(int16)(reg.R[rn] & 0xffff);
                    387:                }
                    388:                idx <<= scale;
                    389:                return anpc + (int32)idx + disp;
                    390:        } else {
                    391:                // Full extension
                    392:                //
                    393:                //   F   E   D   C   B   A   9   8   7   6   5   4   3   2   1   0
                    394:                // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
                    395:                // | DA|     n     | WL| SCALE | 1 | BS| IS|  BDSZ | 0 |   I/IS    |
                    396:                // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
                    397:                //
                    398:                // BS=1: ベースレジスタ・サプレス
                    399:                // IS=1: インデックスオペランド・サプレス
                    400:                // BDSZ: ベースディスプレースメントのサイズ %01=null %10=.W %11=.L
                    401:                // I/IS: モード
                    402: 
                    403:                bool bs = (ext & 0x0080);
                    404:                bool is = (ext & 0x0040);
                    405:                uint bdsize = (ext >> 4) & 3;
                    406:                uint iis = (ext & 7);
                    407: 
                    408:                // ベースレジスタ
                    409:                if (bs) {
                    410:                        anpc = 0;
                    411:                }
                    412: 
                    413:                // ベース・ディスプレースメント
                    414:                uint32 base = 0;
                    415:                switch (bdsize) {
                    416:                 case 0:        // 予約
                    417:                        throw M68K::EXCEP_ILLEGAL;
                    418:                 case 1:        // ベースはヌル
                    419:                        break;
                    420:                 case 2:        // ベース.W
                    421:                        base = (int32)(int16)fetch_2();
1.1.1.2 ! root      422:                        CYCLE3(cea_anix_bd2);
1.1       root      423:                        break;
                    424:                 case 3:        // ベース.L
                    425:                        base = fetch_4();
1.1.1.2 ! root      426:                        CYCLE3(cea_anix_bd4);
1.1       root      427:                        break;
                    428:                 default:
                    429:                        __unreachable();
                    430:                }
                    431: 
                    432:                uint32 outer;
                    433:                if (is == 0) {
                    434:                        // インデックス
                    435:                        uint32 idx = 0;
                    436:                        if (idx_long) {
                    437:                                idx = reg.R[rn];
                    438:                        } else {
                    439:                                idx = (int32)(int16)(reg.R[rn] & 0xffff);
                    440:                        }
                    441:                        idx <<= scale;
                    442: 
                    443:                        switch (iis) {
                    444:                         case 0:        // no memory indirection
1.1.1.2 ! root      445:                                CYCLE3(cea_anix_direct);
1.1       root      446:                                return anpc + base + idx;
                    447: 
                    448:                         case 1:        // indirect pre-index with null outer
1.1.1.2 ! root      449:                                CYCLE3(cea_anix_indir);
1.1       root      450:                                return read_4(anpc + base + idx);
                    451:                         case 2:        // indirect pre-index with word outer
1.1.1.2 ! root      452:                                CYCLE3(cea_anix_indir_od);
1.1       root      453:                                outer = (int32)(int16)fetch_2();
                    454:                                return read_4(anpc + base + idx) + outer;
                    455:                         case 3:        // indirect pre-index with long outer
1.1.1.2 ! root      456:                                CYCLE3(cea_anix_indir_od);
1.1       root      457:                                outer = fetch_4();
                    458:                                return read_4(anpc + base + idx) + outer;
                    459: 
                    460:                         case 4:
                    461:                                throw M68K::EXCEP_ILLEGAL;
                    462: 
                    463:                         case 5:        // indirect post-index with null outer
1.1.1.2 ! root      464:                                CYCLE3(cea_anix_indir);
1.1       root      465:                                return read_4(anpc + base) + idx;
                    466:                         case 6:        // indirect post-index with word outer
1.1.1.2 ! root      467:                                CYCLE3(cea_anix_indir_od);
1.1       root      468:                                outer = (int32)(int16)fetch_2();
                    469:                                return read_4(anpc + base) + idx + outer;
                    470:                         case 7:        // indirect post-index with long outer
1.1.1.2 ! root      471:                                CYCLE3(cea_anix_indir_od);
1.1       root      472:                                outer = fetch_4();
                    473:                                return read_4(anpc + base) + idx + outer;
                    474:                         default:
                    475:                                __unreachable();
                    476:                        }
                    477:                } else {
                    478:                        switch (iis) {
                    479:                         case 0:        // no memory indirection
1.1.1.2 ! root      480:                                CYCLE3(cea_anix_direct);
1.1       root      481:                                return anpc + base;
                    482: 
                    483:                         case 1:        // memory indirect with null outer
1.1.1.2 ! root      484:                                CYCLE3(cea_anix_indir);
1.1       root      485:                                return read_4(anpc + base);
                    486:                         case 2:        // memory indirect with word outer
1.1.1.2 ! root      487:                                CYCLE3(cea_anix_indir_od);
1.1       root      488:                                outer = (int32)(int16)fetch_2();
                    489:                                return read_4(anpc + base) + outer;
                    490:                         case 3:        // memory indirect with long outer
1.1.1.2 ! root      491:                                CYCLE3(cea_anix_indir_od);
1.1       root      492:                                outer = fetch_4();
                    493:                                return read_4(anpc + base) + outer;
                    494:                         default:
                    495:                                throw M68K::EXCEP_ILLEGAL;
                    496:                        }
                    497:                }
                    498:        }
                    499: }
                    500: 
                    501: //
                    502: // Calc EA
                    503: //
                    504: 
                    505: uint32
                    506: MPU680x0Device::cea_ctrl()
                    507: {
                    508:        switch (eamode(ir)) {
                    509:         case 2:        // (An)
                    510:                return cea_anin(eanum(ir));
                    511:         case 5:        // d16(An)
                    512:                return cea_andi(eanum(ir));
                    513:         case 6:        // (An,IX)
                    514:                return cea_anix(eanum(ir));
                    515:         case 7:
                    516:                switch (eanum(ir)) {
                    517:                 case 0:        // Abs.W
                    518:                        return cea_absw();
                    519:                 case 1:        // Abs.L
                    520:                        return cea_absl();
                    521:                 case 2:        // d16(PC)
                    522:                        return cea_pcdi();
                    523:                 case 3:        // (PC,IX)
                    524:                        return cea_pcix();
                    525:                 default:
                    526:                        break;
                    527:                }
                    528:                break;
                    529:        }
                    530:        // 不当命令
                    531:        throw M68K::EXCEP_ILLEGAL;
                    532: }
                    533: 
                    534: uint32
                    535: MPU680x0Device::cea_data_1()
                    536: {
                    537:        switch (eamode(ir)) {
                    538:         case 2:        // (An)
                    539:                return cea_anin(eanum(ir));
                    540:         case 3:        // (An)+
                    541:                save_reg_pi(eanum(ir));
                    542:                return cea_anpi_1(eanum(ir));
                    543:         case 4:        // -(An)
                    544:                save_reg_pd(eanum(ir));
                    545:                return cea_anpd_1(eanum(ir));
                    546:         case 5:        // d16(An)
                    547:                return cea_andi(eanum(ir));
                    548:         case 6:        // (An,IX)
                    549:                return cea_anix(eanum(ir));
                    550:         case 7:
                    551:                switch (eanum(ir)) {
                    552:                 case 0:        // Abs.W
                    553:                        return cea_absw();
                    554:                 case 1:        // Abs.L
                    555:                        return cea_absl();
                    556:                 default:
                    557:                        break;
                    558:                }
                    559:                break;
                    560:        }
                    561:        // 不当命令
                    562:        throw M68K::EXCEP_ILLEGAL;
                    563: }
                    564: 
                    565: uint32
                    566: MPU680x0Device::cea_data_2()
                    567: {
                    568:        switch (eamode(ir)) {
                    569:         case 2:        // (An)
                    570:                return cea_anin(eanum(ir));
                    571:         case 3:        // (An)+
                    572:                save_reg_pi(eanum(ir));
                    573:                return cea_anpi_2(eanum(ir));
                    574:         case 4:        // -(An)
                    575:                save_reg_pd(eanum(ir));
                    576:                return cea_anpd_2(eanum(ir));
                    577:         case 5:        // d16(An)
                    578:                return cea_andi(eanum(ir));
                    579:         case 6:        // (An,IX)
                    580:                return cea_anix(eanum(ir));
                    581:         case 7:
                    582:                switch (eanum(ir)) {
                    583:                 case 0:        // Abs.W
                    584:                        return cea_absw();
                    585:                 case 1:        // Abs.L
                    586:                        return cea_absl();
                    587:                 default:
                    588:                        break;
                    589:                }
                    590:                break;
                    591:        }
                    592:        // 不当命令
                    593:        throw M68K::EXCEP_ILLEGAL;
                    594: }
                    595: 
                    596: uint32
                    597: MPU680x0Device::cea_data_4()
                    598: {
                    599:        switch (eamode(ir)) {
                    600:         case 2:        // (An)
                    601:                return cea_anin(eanum(ir));
                    602:         case 3:        // (An)+
                    603:                save_reg_pi(eanum(ir));
                    604:                return cea_anpi_4(eanum(ir));
                    605:         case 4:        // -(An)
                    606:                save_reg_pd(eanum(ir));
                    607:                return cea_anpd_4(eanum(ir));
                    608:         case 5:        // d16(An)
                    609:                return cea_andi(eanum(ir));
                    610:         case 6:        // (An,IX)
                    611:                return cea_anix(eanum(ir));
                    612:         case 7:
                    613:                switch (eanum(ir)) {
                    614:                 case 0:        // Abs.W
                    615:                        return cea_absw();
                    616:                 case 1:        // Abs.L
                    617:                        return cea_absl();
                    618:                 default:
                    619:                        break;
                    620:                }
                    621:                break;
                    622:        }
                    623:        // 不当命令
                    624:        throw M68K::EXCEP_ILLEGAL;
                    625: }
                    626: 
                    627: // MMU からの呼び出し用。
                    628: uint32
                    629: MPU680x0Device::cea_copro()
                    630: {
                    631:        switch (eamode(ir)) {
                    632:         case 2:        // (An)
                    633:                CYCLE(4);
                    634:                return internal_ea_anin(eanum(ir));
                    635:         case 5:        // d16(An)
                    636:                CYCLE(4);
                    637:                return internal_ea_andi(eanum(ir));
                    638:         case 6:        // (An,IX)
                    639:                CYCLE(4);
                    640:                return internal_ea_anix(eanum(ir));
                    641:         case 7:
                    642:                switch (eanum(ir)) {
                    643:                 case 0:        // Abs.W
                    644:                        CYCLE(4);
                    645:                        return internal_ea_absw();
                    646:                 case 1:        // Abs.L
                    647:                        CYCLE(6);
                    648:                        return internal_ea_absl();
                    649:                 default:
                    650:                        break;
                    651:                }
                    652:                break;
                    653:        }
                    654:        // 不当命令
                    655:        throw M68K::EXCEP_ILLEGAL;
                    656: }
                    657: 
                    658: //
                    659: // Fetch EA
                    660: //
                    661: 
                    662: uint32
                    663: MPU680x0Device::fea_data_1()
                    664: {
                    665:        uint32 ea;
                    666: 
                    667:        switch (eamode(ir)) {
                    668:         case 0:        // Dn
                    669:                return reg.D[eanum(ir)] & 0xff;
                    670:         case 2:        // (An)
                    671:                ea = fea_anin();
                    672:                return read_1(ea);
                    673:         case 3:        // (An)+
                    674:                save_reg_pi(eanum(ir));
                    675:                ea = fea_anpi_1();
                    676:                return read_1(ea);
                    677:         case 4:        // -(An)
                    678:                save_reg_pd(eanum(ir));
                    679:                ea = fea_anpd_1();
                    680:                return read_1(ea);
                    681:         case 5:        // d16(An)
                    682:                ea = fea_andi();
                    683:                return read_1(ea);
                    684:         case 6:        // (An,IX)
                    685:                ea = fea_anix();
                    686:                return read_1(ea);
                    687:         case 7:
                    688:                switch (eanum(ir)) {
                    689:                 case 0:        // Abs.W
                    690:                        ea = fea_absw();
                    691:                        return read_1(ea);
                    692:                 case 1:        // Abs.L
                    693:                        ea = fea_absl();
                    694:                        return read_1(ea);
                    695:                 case 2:        // d16(PC)
                    696:                        ea = fea_pcdi();
                    697:                        return read_1(ea);
                    698:                 case 3:        // (PC,IX)
                    699:                        ea = fea_pcix();
                    700:                        return read_1(ea);
                    701:                 case 4:        // #imm
                    702:                        fea_imm_2();
                    703:                        return fetch_2() & 0xff;
                    704:                 default:
                    705:                        break;
                    706:                }
                    707:                break;
                    708:         default:
                    709:                break;
                    710:        }
                    711:        // 不当命令
                    712:        throw M68K::EXCEP_ILLEGAL;
                    713: }
                    714: 
                    715: uint32
                    716: MPU680x0Device::fea_data_2()
                    717: {
                    718:        uint32 ea;
                    719: 
                    720:        switch (eamode(ir)) {
                    721:         case 0:        // Dn
                    722:                return reg.D[eanum(ir)] & 0xffff;
                    723:         case 2:        // (An)
                    724:                ea = fea_anin();
                    725:                return read_2(ea);
                    726:         case 3:        // (An)+
                    727:                save_reg_pi(eanum(ir));
                    728:                ea = fea_anpi_2();
                    729:                return read_2(ea);
                    730:         case 4:        // -(An)
                    731:                save_reg_pd(eanum(ir));
                    732:                ea = fea_anpd_2();
                    733:                return read_2(ea);
                    734:         case 5:        // d16(An)
                    735:                ea = fea_andi();
                    736:                return read_2(ea);
                    737:         case 6:        // (An,IX)
                    738:                ea = fea_anix();
                    739:                return read_2(ea);
                    740:         case 7:
                    741:                switch (eanum(ir)) {
                    742:                 case 0:        // Abs.W
                    743:                        ea = fea_absw();
                    744:                        return read_2(ea);
                    745:                 case 1:        // Abs.L
                    746:                        ea = fea_absl();
                    747:                        return read_2(ea);
                    748:                 case 2:        // d16(PC)
                    749:                        ea = fea_pcdi();
                    750:                        return read_2(ea);
                    751:                 case 3:        // (PC,IX)
                    752:                        ea = fea_pcix();
                    753:                        return read_2(ea);
                    754:                 case 4:        // #imm
                    755:                        fea_imm_2();
                    756:                        return fetch_2();
                    757:                 default:
                    758:                        break;
                    759:                }
                    760:                break;
                    761:         default:
                    762:                break;
                    763:        }
                    764:        // 不当命令
                    765:        throw M68K::EXCEP_ILLEGAL;
                    766: }
                    767: 
                    768: uint32
                    769: MPU680x0Device::fea_data_4()
                    770: {
                    771:        uint32 ea;
                    772: 
                    773:        switch (eamode(ir)) {
                    774:         case 0:        // Dn
                    775:                return reg.D[eanum(ir)];
                    776:         case 2:        // (An)
                    777:                ea = fea_anin();
                    778:                return read_4(ea);
                    779:         case 3:        // (An)+
                    780:                save_reg_pi(eanum(ir));
                    781:                ea = fea_anpi_4();
                    782:                return read_4(ea);
                    783:         case 4:        // -(An)
                    784:                save_reg_pd(eanum(ir));
                    785:                ea = fea_anpd_4();
                    786:                return read_4(ea);
                    787:         case 5:        // d16(An)
                    788:                ea = fea_andi();
                    789:                return read_4(ea);
                    790:         case 6:        // (An,IX)
                    791:                ea = fea_anix();
                    792:                return read_4(ea);
                    793:         case 7:
                    794:                switch (eanum(ir)) {
                    795:                 case 0:        // Abs.W
                    796:                        ea = fea_absw();
                    797:                        return read_4(ea);
                    798:                 case 1:        // Abs.L
                    799:                        ea = fea_absl();
                    800:                        return read_4(ea);
                    801:                 case 2:        // d16(PC)
                    802:                        ea = fea_pcdi();
                    803:                        return read_4(ea);
                    804:                 case 3:        // (PC,IX)
                    805:                        ea = fea_pcix();
                    806:                        return read_4(ea);
                    807:                 case 4:        // #imm
                    808:                        fea_imm_4();
                    809:                        return fetch_4();
                    810:                 default:
                    811:                        break;
                    812:                }
                    813:                break;
                    814:         default:
                    815:                break;
                    816:        }
                    817:        // 不当命令
                    818:        throw M68K::EXCEP_ILLEGAL;
                    819: }
                    820: 
                    821: uint32
                    822: MPU680x0Device::fea_all_1()
                    823: {
                    824:        uint32 ea;
                    825: 
                    826:        switch (eamode(ir)) {
                    827:         case 0:        // Dn
                    828:                return reg.D[eanum(ir)] & 0xff;
                    829:         case 1:        // An
                    830:                // An.B は不当命令
                    831:                break;
                    832:         case 2:        // (An)
                    833:                ea = fea_anin();
                    834:                return read_1(ea);
                    835:         case 3:        // (An)+
                    836:                save_reg_pi(eanum(ir));
                    837:                ea = fea_anpi_1();
                    838:                return read_1(ea);
                    839:         case 4:        // -(An)
                    840:                save_reg_pd(eanum(ir));
                    841:                ea = fea_anpd_1();
                    842:                return read_1(ea);
                    843:         case 5:        // d16(An)
                    844:                ea = fea_andi();
                    845:                return read_1(ea);
                    846:         case 6:        // (An,IX)
                    847:                ea = fea_anix();
                    848:                return read_1(ea);
                    849:         case 7:
                    850:                switch (eanum(ir)) {
                    851:                 case 0:        // Abs.W
                    852:                        ea = fea_absw();
                    853:                        return read_1(ea);
                    854:                 case 1:        // Abs.L
                    855:                        ea = fea_absl();
                    856:                        return read_1(ea);
                    857:                 case 2:        // d16(PC)
                    858:                        ea = fea_pcdi();
                    859:                        return read_1(ea);
                    860:                 case 3:        // (PC,IX)
                    861:                        ea = fea_pcix();
                    862:                        return read_1(ea);
                    863:                 case 4:        // #imm
                    864:                        fea_imm_2();
                    865:                        return fetch_2() & 0xff;
                    866:                 default:
                    867:                        break;
                    868:                }
                    869:                break;
                    870:         default:
                    871:                break;
                    872:        }
                    873:        // 不当命令
                    874:        throw M68K::EXCEP_ILLEGAL;
                    875: }
                    876: 
                    877: uint32
                    878: MPU680x0Device::fea_all_2()
                    879: {
                    880:        uint32 ea;
                    881: 
                    882:        switch (eamode(ir)) {
                    883:         case 0:        // Dn
                    884:         case 1:        // An
                    885:                return reg.R[ir & 15] & 0xffff;
                    886:         case 2:        // (An)
                    887:                ea = fea_anin();
                    888:                return read_2(ea);
                    889:         case 3:        // (An)+
                    890:                save_reg_pi(eanum(ir));
                    891:                ea = fea_anpi_2();
                    892:                return read_2(ea);
                    893:         case 4:        // -(An)
                    894:                save_reg_pd(eanum(ir));
                    895:                ea = fea_anpd_2();
                    896:                return read_2(ea);
                    897:         case 5:        // d16(An)
                    898:                ea = fea_andi();
                    899:                return read_2(ea);
                    900:         case 6:        // (An,IX)
                    901:                ea = fea_anix();
                    902:                return read_2(ea);
                    903:         case 7:
                    904:                switch (eanum(ir)) {
                    905:                 case 0:        // Abs.W
                    906:                        ea = fea_absw();
                    907:                        return read_2(ea);
                    908:                 case 1:        // Abs.L
                    909:                        ea = fea_absl();
                    910:                        return read_2(ea);
                    911:                 case 2:        // d16(PC)
                    912:                        ea = fea_pcdi();
                    913:                        return read_2(ea);
                    914:                 case 3:        // (PC,IX)
                    915:                        ea = fea_pcix();
                    916:                        return read_2(ea);
                    917:                 case 4:        // #imm
                    918:                        fea_imm_2();
                    919:                        return fetch_2();
                    920:                 default:
                    921:                        break;
                    922:                }
                    923:                break;
                    924:         default:
                    925:                break;
                    926:        }
                    927:        // 不当命令
                    928:        throw M68K::EXCEP_ILLEGAL;
                    929: }
                    930: 
                    931: uint32
                    932: MPU680x0Device::fea_all_4()
                    933: {
                    934:        uint32 ea;
                    935: 
                    936:        switch (eamode(ir)) {
                    937:         case 0:        // Dn
                    938:         case 1:        // An
                    939:                return reg.R[ir & 15];
                    940:         case 2:        // (An)
                    941:                ea = fea_anin();
                    942:                return read_4(ea);
                    943:         case 3:        // (An)+
                    944:                save_reg_pi(eanum(ir));
                    945:                ea = fea_anpi_4();
                    946:                return read_4(ea);
                    947:         case 4:        // -(An)
                    948:                save_reg_pd(eanum(ir));
                    949:                ea = fea_anpd_4();
                    950:                return read_4(ea);
                    951:         case 5:        // d16(An)
                    952:                ea = fea_andi();
                    953:                return read_4(ea);
                    954:         case 6:        // (An,IX)
                    955:                ea = fea_anix();
                    956:                return read_4(ea);
                    957:         case 7:
                    958:                switch (eanum(ir)) {
                    959:                 case 0:        // Abs.W
                    960:                        ea = fea_absw();
                    961:                        return read_4(ea);
                    962:                 case 1:        // Abs.L
                    963:                        ea = fea_absl();
                    964:                        return read_4(ea);
                    965:                 case 2:        // d16(PC)
                    966:                        ea = fea_pcdi();
                    967:                        return read_4(ea);
                    968:                 case 3:        // (PC,IX)
                    969:                        ea = fea_pcix();
                    970:                        return read_4(ea);
                    971:                 case 4:        // #imm
                    972:                        fea_imm_4();
                    973:                        return fetch_4();
                    974:                 default:
                    975:                        break;
                    976:                }
                    977:                break;
                    978:         default:
                    979:                break;
                    980:        }
                    981:        // 不当命令
                    982:        throw M68K::EXCEP_ILLEGAL;
                    983: }

unix.superglobalmegacorp.com

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