Annotation of nono/m680x0/m68030ea.cpp, revision 1.1.1.5

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

unix.superglobalmegacorp.com

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