|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2017 [email protected]
4: //
5: // EA
6: //
7:
8: #pragma once
9:
10: // EA は大別して5種類。
11: //
12: // |d m rxwp | 制御 CalcCtrl サイズ不問
13: // |dam+-rxw | 可変 CalcData B/W/L
14: // | m rxwp | MMU CalcMMU サイズ不問
15: // |dam+-rxwpi| FPU CalcFPU B/W/L/S/D/X/P
16: // |d m+-rxwpi| データ FetchData B/W/L
17: // |dam+-rxwpi| All FetchAll B/W/L
18: //
19: // CalcCtrl はユーザーズマニュアルで「制御(Control)」と呼ばれている
20: // グループで、デスティネーション側のため EA の計算のみ。
21: // また (An)+/-(An) を含まないため、サイズに関係なく1種類だけでよい。
22: //
23: // CalcData はユーザーズマニュアルで「可変」と呼ばれているグループで、
24: // デスティネーション側のため EA の計算のみ。B/W/L
25: //
26: // CalcMMU は対 MMU 用に勝手に用意したもの。
27: //
28: // CalcFPU は対 FPU 用。ソースであっても CalcFPU を使用する。
29: // サイズは B/W/L/S/D/X/P。
30: // フェッチサイクルは別途存在するはずだが不詳。
31: //
32: // FetchData はユーザーズマニュアルで「データ(Data)」と呼ばれている
33: // グループで、ソース側のため EA 計算および値の取得。B/W/L
34: //
35: // FetchAll はユーザーズマニュアルのここには記載がないグループで、
36: // ソース側のため EA 計算および値の取得。B/W/L
37: //
38: // CalcCtrl、CalcData でアドレッシングモードに D や A が含まれている場合は
39: // その命令のデスティネーションに Dn、An が指定できるという意味であり、
40: // EA 処理であるここには関係ない。
41: // EA 計算より前に呼出側で条件分けして処理すること。
42: //
43: // CalcCtrl、CalcData と FetchData には (*) 印の例外があるので留意。
44: //
45: // (CalcCtrl)
46: // | m rxwp | CMP2/CHK2
47: // | m rxwp | JMP/JSR
48: // | m rxwp | LEA/PEA
49: // |d m rxwp | BFEXT*/BFFFO/BFTST
50: // |d m rxw | (*) BFCHG/BFCLR/BFINS/BFSET <ea>{#o:#w}
51: //
52: // (CalcData)
53: // | m+-rxw | ADD/SUB/CMP Dx,<ea>
54: // | m+-rxw | CAS/TAS <ea>
55: // | m+-rxw | MOVES <ea>,Rn
56: // | m+-rxw | shift/rotate.W <ea>
57: // | m+-rxw | BCHG/BCLR/BSET src,<ea>
58: // |d m+-rxw | ADDI/SUBI Dx,<ea>
59: // |d m+-rwx | NBCD <ea>
60: // |d m+-rxw | AND/OR/EOR Dx,<ea>
61: // |d m+-rxw | CLR/NEG/NEGX/NOT/TST/Scc <ea>
62: // |d m+-rxw | MOVE CCR/SR,<ea>
63: // |dam+-rxw | ADDQ/SUBQ #qqq,<ea>
64: // |dam+-rxw | (*) MOVE の dst 側。EA の分類的には CalcData だが、
65: // 下位6ビットの IR ではないので、cea_data_NN() ではなく
66: // 各々 cea_XXXX() のほうを個別に呼ぶこと。
67: //
68: // (CalcMMU)
69: // | m rxw | MMU
70: //
71: // (CalcFPU)
72: // |d m+-rxw | FScc.B <ea>
73: // |dam+-rxw | FMOVE.f FPn,<ea>
74: // |dam+-rxw | FMOVE.L ctl,<ea>
75: // |dam+-rxw | FMOVEM.L ctl,<ea>
76: // |d m+-rxwpi| Fgen <ea>,FPn
77: // |d m+-rxwpi| FMOVE.f <ea>,FPn
78: // |dam+-rwxpi| FMOVE.L <ea>,ctl
79: // |dam+-rxwpi| FMOVEM.L <ea>,ctl
80: // 実際にどのアドレッシングモードが有効かどうかは極力個別の命令内で判断する?
81: // ここは実行サイクル数的な分類。
82: //
83: // (FetchData)
84: // |d m+-rxwpi| AND/OR/CHK <ea>,Dn
85: // |d m+-rxwpi| MOVE.B <ea>,dst
86: // |d m+-rxwpi| MOVE <ea>,CCR/SR
87: // |d m+-rxwpi| MUL*/DIV* <ea>,Dn
88: // |d m+-rxwp | (*) TST.B <ea>
89: // |d m+-rxwp | (*) CMPI #<data>,<ea>
90: // | m+-rxwp | (*) BTST.B #<data>,<ea>
91: // | m+-rxwpi| (*) BTST.B Dx,<ea>
92: //
93: // (FetchAll)
94: // |dam+-rxwpi| ADD/SUB/CMP <ea>,Dn
95: // |dam+-rxwpi| MOVEA/ADDA/SUBA/CMPA <ea>,An
96: // |dam+-rxwpi| TST.WL <ea>
97: // |dam+-rxwpi| MOVE.WL <ea>,dst
98: //
99: // (たぶん別対応)
100: // | m -rxw | MOVEM list,<ea>
101: // | m -rxw | FMOVEM.X reg,<ea>
102: // | m -rxw | FSAVE <ea>
103: // | m+ rxwp | MOVEM <ea>,list
104: // | m+ rxwp | FMOVEM.X <ea>,reg
105: // | m+ rxwp | FRESTORE <ea>
106:
107: extern uint32 internal_ea_ix(m68kcpu *cpu, uint32 anpc);
108:
109: extern uint32 cea_ctrl(m68kcpu *);
110: extern uint32 cea_data_8(m68kcpu *);
111: extern uint32 cea_data_16(m68kcpu *);
112: extern uint32 cea_data_32(m68kcpu *);
113: extern uint32 cea_copro(m68kcpu *);
114: extern uint32 fea_data_8(m68kcpu *);
115: extern uint32 fea_data_16(m68kcpu *);
116: extern uint32 fea_data_32(m68kcpu *);
117: extern uint32 fea_all_8(m68kcpu *);
118: extern uint32 fea_all_16(m68kcpu *);
119: extern uint32 fea_all_32(m68kcpu *);
120:
121: // mmmrrr のうち mmm の部分を取り出す
122: #define eamode(x) (((x) >> 3) & 7)
123:
124: // mmmrrr のうち rrr の部分を取り出す
125: #define eanum(x) ((x) & 7)
126:
127: //
128: // EA を計算だけするマクロ
129: // MOVE の DST 側からも呼ばれる
130: //
131:
132: // (An)
133: static inline uint32 internal_ea_anin(m68kcpu *cpu, int n)
134: {
135: return RegA(n);
136: }
137:
138: // (An)+ .B
139: static inline uint32 internal_ea_anpi_8(m68kcpu *cpu, int n)
140: {
141: m68030_save_reg_pi(cpu, n);
142: if (n == 7) {
143: RegA(n) += 2;
144: return RegA(n) - 2;
145: } else {
146: RegA(n) += 1;
147: return RegA(n) - 1;
148: }
149: }
150:
151: // (An)+ .W
152: static inline uint32 internal_ea_anpi_16(m68kcpu *cpu, int n)
153: {
154: m68030_save_reg_pi(cpu, n);
155: RegA(n) += 2;
156: return RegA(n) - 2;
157: }
158:
159: // (An)+ .L
160: static inline uint32 internal_ea_anpi_32(m68kcpu *cpu, int n)
161: {
162: m68030_save_reg_pi(cpu, n);
163: RegA(n) += 4;
164: return RegA(n) - 4;
165: }
166:
167: // -(An) .B
168: static inline uint32 internal_ea_anpd_8(m68kcpu *cpu, int n)
169: {
170: m68030_save_reg_pd(cpu, n);
171: if (n == 7) {
172: RegA(n) -= 2;
173: } else {
174: RegA(n) -= 1;
175: }
176: return RegA(n);
177: }
178:
179: // -(An) .W
180: static inline uint32 internal_ea_anpd_16(m68kcpu *cpu, int n)
181: {
182: m68030_save_reg_pd(cpu, n);
183: RegA(n) -= 2;
184: return RegA(n);
185: }
186:
187: // -(An) .L
188: static inline uint32 internal_ea_anpd_32(m68kcpu *cpu, int n)
189: {
190: m68030_save_reg_pd(cpu, n);
191: RegA(n) -= 4;
192: return RegA(n);
193: }
194:
195: // d16(An)
196: static inline uint32 internal_ea_andi(m68kcpu *cpu, int n)
197: {
198: int32 disp = (int32)(int16)m68030_fetch_16(cpu);
199: return RegA(n) + disp;
200: }
201:
202: // (An,IX)
203: static inline uint32 internal_ea_anix(m68kcpu *cpu, int n)
204: {
205: return internal_ea_ix(cpu, RegA(n));
206: }
207:
208: // Abs.W
209: static inline uint32 internal_ea_absw(m68kcpu *cpu)
210: {
211: return (int32)(int16)m68030_fetch_16(cpu);
212: }
213:
214: // Abs.L
215: static inline uint32 internal_ea_absl(m68kcpu *cpu)
216: {
217: return m68030_fetch_32(cpu);
218: }
219:
220: // d16(PC)
221: static inline uint32 internal_ea_pcdi(m68kcpu *cpu)
222: {
223: int32 pc = RegPC;
224: int32 disp = (int32)(int16)m68030_fetch_16(cpu);
225: return pc + disp;
226: }
227:
228: // (PC,IX)
229: static inline uint32 internal_ea_pcix(m68kcpu *cpu)
230: {
231: return internal_ea_ix(cpu, RegPC);
232: }
233:
234: //
235: // Calc EA
236: //
237:
238: static inline uint32
239: cea_anin(m68kcpu *cpu, int n)
240: {
241: CYCLE(2);
242: return internal_ea_anin(cpu, n);
243: }
244:
245: static inline uint32
246: cea_anpi_8(m68kcpu *cpu, int n)
247: {
248: CYCLE(2);
249: return internal_ea_anpi_8(cpu, n);
250: }
251:
252: static inline uint32
253: cea_anpi_16(m68kcpu *cpu, int n)
254: {
255: CYCLE(2);
256: return internal_ea_anpi_16(cpu, n);
257: }
258:
259: static inline uint32
260: cea_anpi_32(m68kcpu *cpu, int n)
261: {
262: CYCLE(2);
263: return internal_ea_anpi_32(cpu, n);
264: }
265:
266: static inline uint32
267: cea_anpd_8(m68kcpu *cpu, int n)
268: {
269: CYCLE(2);
270: return internal_ea_anpd_8(cpu, n);
271: }
272:
273: static inline uint32
274: cea_anpd_16(m68kcpu *cpu, int n)
275: {
276: CYCLE(2);
277: return internal_ea_anpd_16(cpu, n);
278: }
279:
280: static inline uint32
281: cea_anpd_32(m68kcpu *cpu, int n)
282: {
283: CYCLE(2);
284: return internal_ea_anpd_32(cpu, n);
285: }
286:
287: static inline uint32
288: cea_andi(m68kcpu *cpu, int n)
289: {
290: CYCLE(2);
291: return internal_ea_andi(cpu, n);
292: }
293:
294: static inline uint32
295: cea_anix(m68kcpu *cpu, int n)
296: {
297: CYCLE(10); // XXX 4,4-18,20
298: return internal_ea_anix(cpu, n);
299: }
300:
301: static inline uint32
302: cea_absw(m68kcpu *cpu)
303: {
304: CYCLE(2);
305: return internal_ea_absw(cpu);
306: }
307:
308: static inline uint32
309: cea_absl(m68kcpu *cpu)
310: {
311: CYCLE(4);
312: return internal_ea_absl(cpu);
313: }
314:
315: static inline uint32
316: cea_pcdi(m68kcpu *cpu)
317: {
318: CYCLE(2);
319: return internal_ea_pcdi(cpu);
320: }
321:
322: static inline uint32
323: cea_pcix(m68kcpu *cpu)
324: {
325: CYCLE(10); // XXX 4,4-18,20
326: return internal_ea_pcix(cpu);
327: }
328:
329: //
330: // Fetch EA
331: //
332:
333: static inline uint32
334: fea_anin(m68kcpu *cpu)
335: {
336: CYCLE(3);
337: return internal_ea_anin(cpu, eanum(RegIR));
338: }
339:
340: static inline uint32
341: fea_anpi_8(m68kcpu *cpu)
342: {
343: CYCLE(3);
344: return internal_ea_anpi_8(cpu, eanum(RegIR));
345: }
346:
347: static inline uint32
348: fea_anpi_16(m68kcpu *cpu)
349: {
350: CYCLE(3);
351: return internal_ea_anpi_16(cpu, eanum(RegIR));
352: }
353:
354: static inline uint32
355: fea_anpi_32(m68kcpu *cpu)
356: {
357: CYCLE(3);
358: return internal_ea_anpi_32(cpu, eanum(RegIR));
359: }
360:
361: static inline uint32
362: fea_anpd_8(m68kcpu *cpu)
363: {
364: CYCLE(4);
365: return internal_ea_anpd_8(cpu, eanum(RegIR));
366: }
367:
368: static inline uint32
369: fea_anpd_16(m68kcpu *cpu)
370: {
371: CYCLE(4);
372: return internal_ea_anpd_16(cpu, eanum(RegIR));
373: }
374:
375: static inline uint32
376: fea_anpd_32(m68kcpu *cpu)
377: {
378: CYCLE(4);
379: return internal_ea_anpd_32(cpu, eanum(RegIR));
380: }
381:
382: static inline uint32
383: fea_andi(m68kcpu *cpu)
384: {
385: CYCLE(4);
386: return internal_ea_andi(cpu, eanum(RegIR));
387: }
388:
389: static inline uint32
390: fea_anix(m68kcpu *cpu)
391: {
392: CYCLE2(12, 14); // XXX 6,6-18,21
393: return internal_ea_anix(cpu, eanum(RegIR));
394: }
395:
396: static inline uint32
397: fea_absw(m68kcpu *cpu)
398: {
399: CYCLE(4);
400: return internal_ea_absw(cpu);
401: }
402:
403: static inline uint32
404: fea_absl(m68kcpu *cpu)
405: {
406: CYCLE2(4, 5);
407: return internal_ea_absl(cpu);
408: }
409:
410: static inline uint32
411: fea_pcdi(m68kcpu *cpu)
412: {
413: CYCLE(4);
414: return internal_ea_pcdi(cpu);
415: }
416:
417: static inline uint32
418: fea_pcix(m68kcpu *cpu)
419: {
420: CYCLE2(12, 14); // XXX 6,6-18,21
421: return internal_ea_pcix(cpu);
422: }
423:
424: static inline void
425: fea_imm_16(m68kcpu *cpu)
426: {
427: CYCLE(2);
428: }
429:
430: static inline void
431: fea_imm_32(m68kcpu *cpu)
432: {
433: CYCLE(4);
434: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.