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