|
|
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: //
1.1.1.2 ! root 6:
1.1 root 7: // EA
8:
9: #pragma once
10:
11: // EA は大別して5種類。
12: //
13: // |d m rxwp | 制御 CalcCtrl サイズ不問
14: // |dam+-rxw | 可変 CalcData B/W/L
15: // | m rxwp | MMU CalcMMU サイズ不問
16: // |dam+-rxwpi| FPU CalcFPU B/W/L/S/D/X/P
17: // |d m+-rxwpi| データ FetchData B/W/L
18: // |dam+-rxwpi| All FetchAll B/W/L
19: //
20: // CalcCtrl はユーザーズマニュアルで「制御(Control)」と呼ばれている
21: // グループで、デスティネーション側のため EA の計算のみ。
22: // また (An)+/-(An) を含まないため、サイズに関係なく1種類だけでよい。
23: //
24: // CalcData はユーザーズマニュアルで「可変」と呼ばれているグループで、
25: // デスティネーション側のため EA の計算のみ。B/W/L
26: //
27: // CalcMMU は対 MMU 用に勝手に用意したもの。
28: //
29: // CalcFPU は対 FPU 用。ソースであっても CalcFPU を使用する。
30: // サイズは B/W/L/S/D/X/P。
31: // フェッチサイクルは別途存在するはずだが不詳。
32: //
33: // FetchData はユーザーズマニュアルで「データ(Data)」と呼ばれている
34: // グループで、ソース側のため EA 計算および値の取得。B/W/L
35: //
36: // FetchAll はユーザーズマニュアルのここには記載がないグループで、
37: // ソース側のため EA 計算および値の取得。B/W/L
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: extern uint32 internal_ea_ix(m68kcpu *cpu, uint32 anpc);
109:
110: extern uint32 cea_ctrl(m68kcpu *);
111: extern uint32 cea_data_8(m68kcpu *);
112: extern uint32 cea_data_16(m68kcpu *);
113: extern uint32 cea_data_32(m68kcpu *);
114: extern uint32 cea_copro(m68kcpu *);
115: extern uint32 fea_data_8(m68kcpu *);
116: extern uint32 fea_data_16(m68kcpu *);
117: extern uint32 fea_data_32(m68kcpu *);
118: extern uint32 fea_all_8(m68kcpu *);
119: extern uint32 fea_all_16(m68kcpu *);
120: extern uint32 fea_all_32(m68kcpu *);
121:
122: // mmmrrr のうち mmm の部分を取り出す
123: #define eamode(x) (((x) >> 3) & 7)
124:
125: // mmmrrr のうち rrr の部分を取り出す
126: #define eanum(x) ((x) & 7)
127:
128: //
129: // EA を計算だけするマクロ
130: // MOVE の DST 側からも呼ばれる
131: //
132:
133: // (An)
134: static inline uint32 internal_ea_anin(m68kcpu *cpu, int n)
135: {
136: return RegA(n);
137: }
138:
139: // (An)+ .B
140: static inline uint32 internal_ea_anpi_8(m68kcpu *cpu, int n)
141: {
142: m68030_save_reg_pi(cpu, n);
143: if (n == 7) {
144: RegA(n) += 2;
145: return RegA(n) - 2;
146: } else {
147: RegA(n) += 1;
148: return RegA(n) - 1;
149: }
150: }
151:
152: // (An)+ .W
153: static inline uint32 internal_ea_anpi_16(m68kcpu *cpu, int n)
154: {
155: m68030_save_reg_pi(cpu, n);
156: RegA(n) += 2;
157: return RegA(n) - 2;
158: }
159:
160: // (An)+ .L
161: static inline uint32 internal_ea_anpi_32(m68kcpu *cpu, int n)
162: {
163: m68030_save_reg_pi(cpu, n);
164: RegA(n) += 4;
165: return RegA(n) - 4;
166: }
167:
168: // -(An) .B
169: static inline uint32 internal_ea_anpd_8(m68kcpu *cpu, int n)
170: {
171: m68030_save_reg_pd(cpu, n);
172: if (n == 7) {
173: RegA(n) -= 2;
174: } else {
175: RegA(n) -= 1;
176: }
177: return RegA(n);
178: }
179:
180: // -(An) .W
181: static inline uint32 internal_ea_anpd_16(m68kcpu *cpu, int n)
182: {
183: m68030_save_reg_pd(cpu, n);
184: RegA(n) -= 2;
185: return RegA(n);
186: }
187:
188: // -(An) .L
189: static inline uint32 internal_ea_anpd_32(m68kcpu *cpu, int n)
190: {
191: m68030_save_reg_pd(cpu, n);
192: RegA(n) -= 4;
193: return RegA(n);
194: }
195:
196: // d16(An)
197: static inline uint32 internal_ea_andi(m68kcpu *cpu, int n)
198: {
199: int32 disp = (int32)(int16)m68030_fetch_16(cpu);
200: return RegA(n) + disp;
201: }
202:
203: // (An,IX)
204: static inline uint32 internal_ea_anix(m68kcpu *cpu, int n)
205: {
206: return internal_ea_ix(cpu, RegA(n));
207: }
208:
209: // Abs.W
210: static inline uint32 internal_ea_absw(m68kcpu *cpu)
211: {
212: return (int32)(int16)m68030_fetch_16(cpu);
213: }
214:
215: // Abs.L
216: static inline uint32 internal_ea_absl(m68kcpu *cpu)
217: {
218: return m68030_fetch_32(cpu);
219: }
220:
221: // d16(PC)
222: static inline uint32 internal_ea_pcdi(m68kcpu *cpu)
223: {
224: int32 pc = RegPC;
225: int32 disp = (int32)(int16)m68030_fetch_16(cpu);
226: return pc + disp;
227: }
228:
229: // (PC,IX)
230: static inline uint32 internal_ea_pcix(m68kcpu *cpu)
231: {
232: return internal_ea_ix(cpu, RegPC);
233: }
234:
235: //
236: // Calc EA
237: //
238:
239: static inline uint32
240: cea_anin(m68kcpu *cpu, int n)
241: {
242: CYCLE(2);
243: return internal_ea_anin(cpu, n);
244: }
245:
246: static inline uint32
247: cea_anpi_8(m68kcpu *cpu, int n)
248: {
249: CYCLE(2);
250: return internal_ea_anpi_8(cpu, n);
251: }
252:
253: static inline uint32
254: cea_anpi_16(m68kcpu *cpu, int n)
255: {
256: CYCLE(2);
257: return internal_ea_anpi_16(cpu, n);
258: }
259:
260: static inline uint32
261: cea_anpi_32(m68kcpu *cpu, int n)
262: {
263: CYCLE(2);
264: return internal_ea_anpi_32(cpu, n);
265: }
266:
267: static inline uint32
268: cea_anpd_8(m68kcpu *cpu, int n)
269: {
270: CYCLE(2);
271: return internal_ea_anpd_8(cpu, n);
272: }
273:
274: static inline uint32
275: cea_anpd_16(m68kcpu *cpu, int n)
276: {
277: CYCLE(2);
278: return internal_ea_anpd_16(cpu, n);
279: }
280:
281: static inline uint32
282: cea_anpd_32(m68kcpu *cpu, int n)
283: {
284: CYCLE(2);
285: return internal_ea_anpd_32(cpu, n);
286: }
287:
288: static inline uint32
289: cea_andi(m68kcpu *cpu, int n)
290: {
291: CYCLE(2);
292: return internal_ea_andi(cpu, n);
293: }
294:
295: static inline uint32
296: cea_anix(m68kcpu *cpu, int n)
297: {
298: CYCLE(10); // XXX 4,4-18,20
299: return internal_ea_anix(cpu, n);
300: }
301:
302: static inline uint32
303: cea_absw(m68kcpu *cpu)
304: {
305: CYCLE(2);
306: return internal_ea_absw(cpu);
307: }
308:
309: static inline uint32
310: cea_absl(m68kcpu *cpu)
311: {
312: CYCLE(4);
313: return internal_ea_absl(cpu);
314: }
315:
316: static inline uint32
317: cea_pcdi(m68kcpu *cpu)
318: {
319: CYCLE(2);
320: return internal_ea_pcdi(cpu);
321: }
322:
323: static inline uint32
324: cea_pcix(m68kcpu *cpu)
325: {
326: CYCLE(10); // XXX 4,4-18,20
327: return internal_ea_pcix(cpu);
328: }
329:
330: //
331: // Fetch EA
332: //
333:
334: static inline uint32
335: fea_anin(m68kcpu *cpu)
336: {
337: CYCLE(3);
338: return internal_ea_anin(cpu, eanum(RegIR));
339: }
340:
341: static inline uint32
342: fea_anpi_8(m68kcpu *cpu)
343: {
344: CYCLE(3);
345: return internal_ea_anpi_8(cpu, eanum(RegIR));
346: }
347:
348: static inline uint32
349: fea_anpi_16(m68kcpu *cpu)
350: {
351: CYCLE(3);
352: return internal_ea_anpi_16(cpu, eanum(RegIR));
353: }
354:
355: static inline uint32
356: fea_anpi_32(m68kcpu *cpu)
357: {
358: CYCLE(3);
359: return internal_ea_anpi_32(cpu, eanum(RegIR));
360: }
361:
362: static inline uint32
363: fea_anpd_8(m68kcpu *cpu)
364: {
365: CYCLE(4);
366: return internal_ea_anpd_8(cpu, eanum(RegIR));
367: }
368:
369: static inline uint32
370: fea_anpd_16(m68kcpu *cpu)
371: {
372: CYCLE(4);
373: return internal_ea_anpd_16(cpu, eanum(RegIR));
374: }
375:
376: static inline uint32
377: fea_anpd_32(m68kcpu *cpu)
378: {
379: CYCLE(4);
380: return internal_ea_anpd_32(cpu, eanum(RegIR));
381: }
382:
383: static inline uint32
384: fea_andi(m68kcpu *cpu)
385: {
386: CYCLE(4);
387: return internal_ea_andi(cpu, eanum(RegIR));
388: }
389:
390: static inline uint32
391: fea_anix(m68kcpu *cpu)
392: {
393: CYCLE2(12, 14); // XXX 6,6-18,21
394: return internal_ea_anix(cpu, eanum(RegIR));
395: }
396:
397: static inline uint32
398: fea_absw(m68kcpu *cpu)
399: {
400: CYCLE(4);
401: return internal_ea_absw(cpu);
402: }
403:
404: static inline uint32
405: fea_absl(m68kcpu *cpu)
406: {
407: CYCLE2(4, 5);
408: return internal_ea_absl(cpu);
409: }
410:
411: static inline uint32
412: fea_pcdi(m68kcpu *cpu)
413: {
414: CYCLE(4);
415: return internal_ea_pcdi(cpu);
416: }
417:
418: static inline uint32
419: fea_pcix(m68kcpu *cpu)
420: {
421: CYCLE2(12, 14); // XXX 6,6-18,21
422: return internal_ea_pcix(cpu);
423: }
424:
425: static inline void
426: fea_imm_16(m68kcpu *cpu)
427: {
428: CYCLE(2);
429: }
430:
431: static inline void
432: fea_imm_32(m68kcpu *cpu)
433: {
434: CYCLE(4);
435: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.