|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2017 [email protected] ! 4: // ! 5: ! 6: #pragma once ! 7: ! 8: #include "m68030.h" ! 9: #include "m68030excep.h" ! 10: #include "mpu.h" ! 11: ! 12: // XXX ? ! 13: #define CCR (cpu->reg.ccr) ! 14: ! 15: #define RegIsS (cpu->reg.s) ! 16: ! 17: extern void m68030_restore_reg_pi(m68kcpu *); ! 18: extern void m68030_restore_reg_pd(m68kcpu *); ! 19: extern void m68030_set_sr(m68kcpu *, uint16); ! 20: extern void m68030_exception(m68kcpu *, int); ! 21: extern void m68030_exception_reset(m68kcpu *); ! 22: extern void m68030_exception_interrupt(m68kcpu *, int, int); ! 23: extern void m68030_rte(m68kcpu *); ! 24: extern const char *m68030_get_exception_name(int); ! 25: ! 26: static inline void cpulog(int lv, const char *fmt, ...) __printflike(2, 3); ! 27: static inline void ! 28: cpulog(int lv, const char *fmt, ...) ! 29: { ! 30: if (__predict_false(gMPU->loglevel >= lv)) { ! 31: va_list ap; ! 32: va_start(ap, fmt); ! 33: gMPU->vputlog(fmt, ap); ! 34: va_end(ap); ! 35: } ! 36: } ! 37: ! 38: // ops 用のマクロとか ! 39: ! 40: static inline void ! 41: m68k_add_cycle(m68kcpu *cpu, int cc) ! 42: { ! 43: cpu->cycle_cache += cc; ! 44: } ! 45: ! 46: static inline void ! 47: m68k_add_cycle_nc(m68kcpu *cpu, int cc, int ncc) ! 48: { ! 49: cpu->cycle_cache += cc; ! 50: cpu->cycle_nocache += ncc - cc; ! 51: } ! 52: ! 53: // サイクルを加算する。 ! 54: // キャッシュケース、ノーキャッシュケースで同じ場合用。 ! 55: #define CYCLE(cc) m68k_add_cycle(cpu, (cc)) ! 56: ! 57: // サイクルを加算する。 ! 58: // cc はキャッシュケース、ncc はノーキャッシュケースのサイクル。 ! 59: // ncc は cc からの差分ではなく、ノーキャッシュケースの時のサイクル数 ! 60: // そのものを指定する。(内部で差分をとっている) ! 61: #define CYCLE2(cc, ncc) m68k_add_cycle_nc(cpu, (cc), (ncc)); ! 62: ! 63: // PC を addr に変更する。 ! 64: // addr がメモリからの入力の場合アドレスエラーのチェックが必要なため。 ! 65: static inline void ! 66: m68030_jump(m68kcpu *cpu, uint32 addr) ! 67: { ! 68: // アドレスエラーチェック ! 69: if (__predict_false((addr & 1) != 0)) { ! 70: m68030_exception(cpu, M68K_EXCEP_ADDRERR); ! 71: return; ! 72: } ! 73: ! 74: RegPC = addr; ! 75: ! 76: // ブランチ履歴 ! 77: m68kbrhist *h = &cpu->brhist[cpu->brhist_top]; ! 78: //printf("jump PPC=%x addr=%x h.from=%x to=%x", RegPPC, addr, h->from, h->to); ! 79: if (h->from == RegPPC && h->to == addr) { ! 80: // 前回と同じなら通過回数++ ! 81: h->count++; ! 82: //printf(" ++\n"); ! 83: } else { ! 84: // そうでなければ、新規エントリ ! 85: cpu->brhist_top++; ! 86: //printf(" [%d]\n", cpu->brhist_top); ! 87: h = &cpu->brhist[cpu->brhist_top]; ! 88: h->from = RegPPC; ! 89: h->to = addr; ! 90: h->count = 1; ! 91: } ! 92: } ! 93: ! 94: // -(An) 実行前にレジスタを保存する。 ! 95: // バスエラーからの復帰用。 ! 96: static inline void ! 97: m68030_save_reg_pd(m68kcpu *cpu, int n) ! 98: { ! 99: // 該当ビットのフラグを立てる ! 100: cpu->flag_pd |= (1 << n); ! 101: ! 102: // 保存 ! 103: cpu->save_pd[n] = RegA(n); ! 104: } ! 105: ! 106: // (An)+ 実行前にレジスタを保存する。 ! 107: // バスエラーからの復帰用。 ! 108: static inline void ! 109: m68030_save_reg_pi(m68kcpu *cpu, int n) ! 110: { ! 111: // 該当ビットのフラグを立てる ! 112: cpu->flag_pi |= (1 << n); ! 113: ! 114: // 保存 ! 115: cpu->save_pi[n] = RegA(n); ! 116: } ! 117: ! 118: // cond で示される条件が成立すれば true を返す。 ! 119: static inline bool ! 120: cond_func(m68kcpu *cpu, int cond) ! 121: { ! 122: switch (cond) { ! 123: case 0: // T ! 124: return RegCondT; ! 125: case 1: // F ! 126: return RegCondF; ! 127: case 2: ! 128: return RegCondHI; ! 129: case 3: ! 130: return RegCondLS; ! 131: case 4: ! 132: return RegCondCC; ! 133: case 5: ! 134: return RegCondCS; ! 135: case 6: ! 136: return RegCondNE; ! 137: case 7: ! 138: return RegCondEQ; ! 139: case 8: ! 140: return RegCondVC; ! 141: case 9: ! 142: return RegCondVS; ! 143: case 10: ! 144: return RegCondPL; ! 145: case 11: ! 146: return RegCondMI; ! 147: case 12: ! 148: return RegCondGE; ! 149: case 13: ! 150: return RegCondLT; ! 151: case 14: ! 152: return RegCondGT; ! 153: case 15: ! 154: return RegCondLE; ! 155: } ! 156: __unreachable(); ! 157: } ! 158: ! 159: ! 160: // 副作用のあるマクロ ! 161: // 特権違反例外のスタックに積む PC は違反を起こした命令先頭。 ! 162: #define SUPERVISOR_OP \ ! 163: if (!RegIsS) { \ ! 164: CYCLE2(18, 20); \ ! 165: m68030_exception(cpu, M68K_EXCEP_PRIV); \ ! 166: return; \ ! 167: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.