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