|
|
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: #include "m68030core.h"
8: #include "m68030bus.h"
9: #include "m68030ea.h"
10: #include "m68030fpu.h"
11:
12: //
13: // EA の拡張ワード
14: //
15:
16: uint32
17: internal_ea_ix(m68kcpu *cpu, uint32 anpc)
18: {
19: uint16 ext = m68030_fetch_16(cpu);
20: int rn = (ext >> 12) & 15;
21: bool idx_long = (ext & 0x0800);
22: int scale = (ext >> 9) & 3;
23:
24: if ((ext & 0x0100) == 0) {
25: // Brief extension
26: //
1.1.1.3 ! root 27: // F E D C B A 9 8 7 6 5 4 3 2 1 0
! 28: // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
! 29: // | DA| n | WL| SCALE | 0 | disp |
! 30: // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1.1 root 31: //
32: // WL: インデックスレジスタ(Rn)のサイズ 1=.L 0=.W
33: // SCALE: スケールファクタ %00=*1 %01=*2 %10=*4 %11=*8
34:
35: CYCLE(4);
36: int32 disp = (int32)(int8)(ext & 0xff);
37: uint32 idx;
38:
39: if (idx_long) {
40: idx = RegR(rn);
41: } else {
42: idx = (int32)(int16)(RegR(rn) & 0xffff);
43: }
44: idx <<= scale;
45: return anpc + (int32)idx + disp;
46: } else {
47: // Full extension
48: //
1.1.1.3 ! root 49: // F E D C B A 9 8 7 6 5 4 3 2 1 0
! 50: // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
! 51: // | DA| n | WL| SCALE | 1 | BS| IS| BDSZ | 0 | I/IS |
! 52: // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1.1 root 53: //
54: // BS=1: ベースレジスタ・サプレス
55: // IS=1: インデックスオペランド・サプレス
56: // BDSZ: ベースディスプレースメントのサイズ %01=null %10=.W %11=.L
57: // I/IS: モード
58:
59: // クロックは概略値なので完全に正確ではないがまず基本は以下の2通り。
60: // メモリ間接なし (6, 6)
61: // メモリ間接あり (10, 10)
62: // これを元に必要に応じて以下をそれぞれ加算する。
63: // bd16 (+2, +3)
64: // bd32 (メモリ間接なし) (+4, +6)
65: // bd32 (メモリ間接あり) (+6, +6)
66: // outer (W/L 不問) (+2, +3)
67: // ただしここでは実行順の都合で bd32 はいずれも (+4, +6) とした。
68:
69: bool bs = (ext & 0x0080);
70: bool is = (ext & 0x0040);
71: int bdsize = (ext >> 4) & 3;
72: int iis = (ext & 7);
73:
74: // ベースレジスタ
75: if (bs) {
76: anpc = 0;
77: }
78:
79: // ベース・ディスプレースメント
80: uint32 base = 0;
81: switch (bdsize) {
82: case 0: // 予約
83: // XXX 未定義命令列になるんだろうか?
84: PANIC("BDSIZE==0 not impl");
85: case 1: // ベースはヌル
86: break;
87: case 2: // ベース.W
88: base = (int32)(int16)m68030_fetch_16(cpu);
89: CYCLE2(2, 3);
90: break;
91: case 3: // ベース.L
92: base = m68030_fetch_32(cpu);
93: CYCLE2(4, 6);
94: break;
95: default:
96: __unreachable();
97: }
98:
99: uint32 outer;
100: if (is == 0) {
101: // インデックス
102: uint32 idx = 0;
103: if (idx_long) {
104: idx = RegR(rn);
105: } else {
106: idx = (int32)(int16)(RegR(rn) & 0xffff);
107: }
108: idx <<= scale;
109:
110: switch (iis) {
111: case 0: // no memory indirection
112: CYCLE(6);
113: return anpc + base + idx;
114:
115: case 1: // indirect pre-index with null outer
116: CYCLE(10);
117: return m68030_read_32(cpu, anpc + base + idx);
118: case 2: // indirect pre-index with word outer
119: CYCLE2(10+2, 10+3);
120: outer = (int32)(int16)m68030_fetch_16(cpu);
121: return m68030_read_32(cpu, anpc + base + idx) + outer;
122: case 3: // indirect pre-index with long outer
123: CYCLE2(10+2, 10+3);
124: outer = m68030_fetch_32(cpu);
125: return m68030_read_32(cpu, anpc + base + idx) + outer;
126:
127: case 4:
128: PANIC("iis==4 reserved");
129:
130: case 5: // indirect post-index with null outer
131: CYCLE(10);
132: return m68030_read_32(cpu, anpc + base) + idx;
133: case 6: // indirect post-index with word outer
134: CYCLE2(10+2, 10+3);
135: outer = (int32)(int16)m68030_fetch_16(cpu);
136: return m68030_read_32(cpu, anpc + base) + idx + outer;
137: case 7: // indirect post-index with long outer
138: CYCLE2(10+2, 10+3);
139: outer = m68030_fetch_32(cpu);
140: return m68030_read_32(cpu, anpc + base) + idx + outer;
141: default:
142: __unreachable();
143: }
144: } else {
145: switch (iis) {
146: case 0: // no memory indirection
147: CYCLE(6);
148: return anpc + base;
149:
150: case 1: // memory indirect with null outer
151: CYCLE(10);
152: return m68030_read_32(cpu, anpc + base);
153: case 2: // memory indirect with word outer
154: CYCLE2(10+2, 10+3);
155: outer = (int32)(int16)m68030_fetch_16(cpu);
156: return m68030_read_32(cpu, anpc + base) + outer;
157: case 3: // memory indirect with long outer
158: CYCLE2(10+2, 10+3);
159: outer = m68030_fetch_32(cpu);
160: return m68030_read_32(cpu, anpc + base) + outer;
161: default:
162: PANIC("is==1 && iis>3 reserved");
163: }
164: }
165: }
166: }
167:
168: //
169: // Calc EA
170: //
171:
172: uint32
173: cea_ctrl(m68kcpu *cpu)
174: {
175: switch (eamode(RegIR)) {
176: case 2: // (An)
177: return cea_anin(cpu, eanum(RegIR));
178: case 5: // d16(An)
179: return cea_andi(cpu, eanum(RegIR));
180: case 6: // (An,IX)
181: return cea_anix(cpu, eanum(RegIR));
182: case 7:
183: switch (eanum(RegIR)) {
184: case 0: // Abs.W
185: return cea_absw(cpu);
186: case 1: // Abs.L
187: return cea_absl(cpu);
188: case 2: // d16(PC)
189: return cea_pcdi(cpu);
190: case 3: // (PC,IX)
191: return cea_pcix(cpu);
192: default:
193: break;
194: }
195: break;
196: }
197: // 不当命令
198: throw M68K_EXCEP_ILLEGAL;
199: }
200:
201: uint32
202: cea_data_8(m68kcpu *cpu)
203: {
204: switch (eamode(RegIR)) {
205: case 2: // (An)
206: return cea_anin(cpu, eanum(RegIR));
207: case 3: // (An)+
208: return cea_anpi_8(cpu, eanum(RegIR));
209: case 4: // -(An)
210: return cea_anpd_8(cpu, eanum(RegIR));
211: case 5: // d16(An)
212: return cea_andi(cpu, eanum(RegIR));
213: case 6: // (An,IX)
214: return cea_anix(cpu, eanum(RegIR));
215: case 7:
216: switch (eanum(RegIR)) {
217: case 0: // Abs.W
218: return cea_absw(cpu);
219: case 1: // Abs.L
220: return cea_absl(cpu);
221: default:
222: break;
223: }
224: break;
225: }
226: // 不当命令
227: throw M68K_EXCEP_ILLEGAL;
228: }
229:
230: uint32
231: cea_data_16(m68kcpu *cpu)
232: {
233: switch (eamode(RegIR)) {
234: case 2: // (An)
235: return cea_anin(cpu, eanum(RegIR));
236: case 3: // (An)+
237: return cea_anpi_16(cpu, eanum(RegIR));
238: case 4: // -(An)
239: return cea_anpd_16(cpu, eanum(RegIR));
240: case 5: // d16(An)
241: return cea_andi(cpu, eanum(RegIR));
242: case 6: // (An,IX)
243: return cea_anix(cpu, eanum(RegIR));
244: case 7:
245: switch (eanum(RegIR)) {
246: case 0: // Abs.W
247: return cea_absw(cpu);
248: case 1: // Abs.L
249: return cea_absl(cpu);
250: default:
251: break;
252: }
253: break;
254: }
255: // 不当命令
256: throw M68K_EXCEP_ILLEGAL;
257: }
258:
259: uint32
260: cea_data_32(m68kcpu *cpu)
261: {
262: switch (eamode(RegIR)) {
263: case 2: // (An)
264: return cea_anin(cpu, eanum(RegIR));
265: case 3: // (An)+
266: return cea_anpi_32(cpu, eanum(RegIR));
267: case 4: // -(An)
268: return cea_anpd_32(cpu, eanum(RegIR));
269: case 5: // d16(An)
270: return cea_andi(cpu, eanum(RegIR));
271: case 6: // (An,IX)
272: return cea_anix(cpu, eanum(RegIR));
273: case 7:
274: switch (eanum(RegIR)) {
275: case 0: // Abs.W
276: return cea_absw(cpu);
277: case 1: // Abs.L
278: return cea_absl(cpu);
279: default:
280: break;
281: }
282: break;
283: }
284: // 不当命令
285: throw M68K_EXCEP_ILLEGAL;
286: }
287:
288: // MMU からの呼び出し用。
289: uint32
290: cea_copro(m68kcpu *cpu)
291: {
292: switch (eamode(RegIR)) {
293: case 2: // (An)
294: CYCLE(4);
295: return internal_ea_anin(cpu, eanum(RegIR));
296: case 5: // d16(An)
297: CYCLE(4);
298: return internal_ea_andi(cpu, eanum(RegIR));
299: case 6: // (An,IX)
300: CYCLE(4);
301: return internal_ea_anix(cpu, eanum(RegIR));
302: case 7:
303: switch (eanum(RegIR)) {
304: case 0: // Abs.W
305: CYCLE(4);
306: return internal_ea_absw(cpu);
307: case 1: // Abs.L
308: CYCLE(6);
309: return internal_ea_absl(cpu);
310: default:
311: break;
312: }
313: break;
314: }
315: // 不当命令
316: throw M68K_EXCEP_ILLEGAL;
317: }
318:
319: //
320: // Fetch EA
321: //
322:
323: uint32
324: fea_data_8(m68kcpu *cpu)
325: {
326: uint32 ea;
327:
328: switch (eamode(RegIR)) {
329: case 0: // Dn
330: return RegD(eanum(RegIR)) & 0xff;
331: case 2: // (An)
332: ea = fea_anin(cpu);
333: return m68030_read_8(cpu, ea);
334: case 3: // (An)+
335: ea = fea_anpi_8(cpu);
336: return m68030_read_8(cpu, ea);
337: case 4: // -(An)
338: ea = fea_anpd_8(cpu);
339: return m68030_read_8(cpu, ea);
340: case 5: // d16(An)
341: ea = fea_andi(cpu);
342: return m68030_read_8(cpu, ea);
343: case 6: // (An,IX)
344: ea = fea_anix(cpu);
345: return m68030_read_8(cpu, ea);
346: case 7:
347: switch (eanum(RegIR)) {
348: case 0: // Abs.W
349: ea = fea_absw(cpu);
350: return m68030_read_8(cpu, ea);
351: case 1: // Abs.L
352: ea = fea_absl(cpu);
353: return m68030_read_8(cpu, ea);
354: case 2: // d16(PC)
355: ea = fea_pcdi(cpu);
356: return m68030_read_8(cpu, ea);
357: case 3: // (PC,IX)
358: ea = fea_pcix(cpu);
359: return m68030_read_8(cpu, ea);
360: case 4: // #imm
361: fea_imm_16(cpu);
362: return m68030_fetch_16(cpu) & 0xff;
363: default:
364: break;
365: }
366: break;
367: default:
368: break;
369: }
370: // 不当命令
371: throw M68K_EXCEP_ILLEGAL;
372: }
373:
374: uint32
375: fea_data_16(m68kcpu *cpu)
376: {
377: uint32 ea;
378:
379: switch (eamode(RegIR)) {
380: case 0: // Dn
381: return RegD(eanum(RegIR)) & 0xffff;
382: case 2: // (An)
383: ea = fea_anin(cpu);
384: return m68030_read_16(cpu, ea);
385: case 3: // (An)+
386: ea = fea_anpi_16(cpu);
387: return m68030_read_16(cpu, ea);
388: case 4: // -(An)
389: ea = fea_anpd_16(cpu);
390: return m68030_read_16(cpu, ea);
391: case 5: // d16(An)
392: ea = fea_andi(cpu);
393: return m68030_read_16(cpu, ea);
394: case 6: // (An,IX)
395: ea = fea_anix(cpu);
396: return m68030_read_16(cpu, ea);
397: case 7:
398: switch (eanum(RegIR)) {
399: case 0: // Abs.W
400: ea = fea_absw(cpu);
401: return m68030_read_16(cpu, ea);
402: case 1: // Abs.L
403: ea = fea_absl(cpu);
404: return m68030_read_16(cpu, ea);
405: case 2: // d16(PC)
406: ea = fea_pcdi(cpu);
407: return m68030_read_16(cpu, ea);
408: case 3: // (PC,IX)
409: ea = fea_pcix(cpu);
410: return m68030_read_16(cpu, ea);
411: case 4: // #imm
412: fea_imm_16(cpu);
413: return m68030_fetch_16(cpu);
414: default:
415: break;
416: }
417: break;
418: default:
419: break;
420: }
421: // 不当命令
422: throw M68K_EXCEP_ILLEGAL;
423: }
424:
425: uint32
426: fea_data_32(m68kcpu *cpu)
427: {
428: uint32 ea;
429:
430: switch (eamode(RegIR)) {
431: case 0: // Dn
432: return RegD(eanum(RegIR));
433: case 2: // (An)
434: ea = fea_anin(cpu);
435: return m68030_read_32(cpu, ea);
436: case 3: // (An)+
437: ea = fea_anpi_32(cpu);
438: return m68030_read_32(cpu, ea);
439: case 4: // -(An)
440: ea = fea_anpd_32(cpu);
441: return m68030_read_32(cpu, ea);
442: case 5: // d16(An)
443: ea = fea_andi(cpu);
444: return m68030_read_32(cpu, ea);
445: case 6: // (An,IX)
446: ea = fea_anix(cpu);
447: return m68030_read_32(cpu, ea);
448: case 7:
449: switch (eanum(RegIR)) {
450: case 0: // Abs.W
451: ea = fea_absw(cpu);
452: return m68030_read_32(cpu, ea);
453: case 1: // Abs.L
454: ea = fea_absl(cpu);
455: return m68030_read_32(cpu, ea);
456: case 2: // d16(PC)
457: ea = fea_pcdi(cpu);
458: return m68030_read_32(cpu, ea);
459: case 3: // (PC,IX)
460: ea = fea_pcix(cpu);
461: return m68030_read_32(cpu, ea);
462: case 4: // #imm
463: fea_imm_32(cpu);
464: return m68030_fetch_32(cpu);
465: default:
466: break;
467: }
468: break;
469: default:
470: break;
471: }
472: // 不当命令
473: throw M68K_EXCEP_ILLEGAL;
474: }
475:
476: uint32
477: fea_all_8(m68kcpu *cpu)
478: {
479: uint32 ea;
480:
481: switch (eamode(RegIR)) {
482: case 0: // Dn
483: return RegD(eanum(RegIR)) & 0xff;
484: case 1: // An
485: // An.B は不当命令
486: break;
487: case 2: // (An)
488: ea = fea_anin(cpu);
489: return m68030_read_8(cpu, ea);
490: case 3: // (An)+
491: ea = fea_anpi_8(cpu);
492: return m68030_read_8(cpu, ea);
493: case 4: // -(An)
494: ea = fea_anpd_8(cpu);
495: return m68030_read_8(cpu, ea);
496: case 5: // d16(An)
497: ea = fea_andi(cpu);
498: return m68030_read_8(cpu, ea);
499: case 6: // (An,IX)
500: ea = fea_anix(cpu);
501: return m68030_read_8(cpu, ea);
502: case 7:
503: switch (eanum(RegIR)) {
504: case 0: // Abs.W
505: ea = fea_absw(cpu);
506: return m68030_read_8(cpu, ea);
507: case 1: // Abs.L
508: ea = fea_absl(cpu);
509: return m68030_read_8(cpu, ea);
510: case 2: // d16(PC)
511: ea = fea_pcdi(cpu);
512: return m68030_read_8(cpu, ea);
513: case 3: // (PC,IX)
514: ea = fea_pcix(cpu);
515: return m68030_read_8(cpu, ea);
516: case 4: // #imm
517: fea_imm_16(cpu);
518: return m68030_fetch_16(cpu) & 0xff;
519: default:
520: break;
521: }
522: break;
523: default:
524: break;
525: }
526: // 不当命令
527: throw M68K_EXCEP_ILLEGAL;
528: }
529:
530: uint32
531: fea_all_16(m68kcpu *cpu)
532: {
533: uint32 ea;
534:
535: switch (eamode(RegIR)) {
536: case 0: // Dn
537: case 1: // An
538: return RegR(RegIR & 15) & 0xffff;
539: case 2: // (An)
540: ea = fea_anin(cpu);
541: return m68030_read_16(cpu, ea);
542: case 3: // (An)+
543: ea = fea_anpi_16(cpu);
544: return m68030_read_16(cpu, ea);
545: case 4: // -(An)
546: ea = fea_anpd_16(cpu);
547: return m68030_read_16(cpu, ea);
548: case 5: // d16(An)
549: ea = fea_andi(cpu);
550: return m68030_read_16(cpu, ea);
551: case 6: // (An,IX)
552: ea = fea_anix(cpu);
553: return m68030_read_16(cpu, ea);
554: case 7:
555: switch (eanum(RegIR)) {
556: case 0: // Abs.W
557: ea = fea_absw(cpu);
558: return m68030_read_16(cpu, ea);
559: case 1: // Abs.L
560: ea = fea_absl(cpu);
561: return m68030_read_16(cpu, ea);
562: case 2: // d16(PC)
563: ea = fea_pcdi(cpu);
564: return m68030_read_16(cpu, ea);
565: case 3: // (PC,IX)
566: ea = fea_pcix(cpu);
567: return m68030_read_16(cpu, ea);
568: case 4: // #imm
569: fea_imm_16(cpu);
570: return m68030_fetch_16(cpu);
571: default:
572: break;
573: }
574: break;
575: default:
576: break;
577: }
578: // 不当命令
579: throw M68K_EXCEP_ILLEGAL;
580: }
581:
582: uint32
583: fea_all_32(m68kcpu *cpu)
584: {
585: uint32 ea;
586:
587: switch (eamode(RegIR)) {
588: case 0: // Dn
589: case 1: // An
590: return RegR(RegIR & 15);
591: case 2: // (An)
592: ea = fea_anin(cpu);
593: return m68030_read_32(cpu, ea);
594: case 3: // (An)+
595: ea = fea_anpi_32(cpu);
596: return m68030_read_32(cpu, ea);
597: case 4: // -(An)
598: ea = fea_anpd_32(cpu);
599: return m68030_read_32(cpu, ea);
600: case 5: // d16(An)
601: ea = fea_andi(cpu);
602: return m68030_read_32(cpu, ea);
603: case 6: // (An,IX)
604: ea = fea_anix(cpu);
605: return m68030_read_32(cpu, ea);
606: case 7:
607: switch (eanum(RegIR)) {
608: case 0: // Abs.W
609: ea = fea_absw(cpu);
610: return m68030_read_32(cpu, ea);
611: case 1: // Abs.L
612: ea = fea_absl(cpu);
613: return m68030_read_32(cpu, ea);
614: case 2: // d16(PC)
615: ea = fea_pcdi(cpu);
616: return m68030_read_32(cpu, ea);
617: case 3: // (PC,IX)
618: ea = fea_pcix(cpu);
619: return m68030_read_32(cpu, ea);
620: case 4: // #imm
621: fea_imm_32(cpu);
622: return m68030_fetch_32(cpu);
623: default:
624: break;
625: }
626: break;
627: default:
628: break;
629: }
630: // 不当命令
631: throw M68K_EXCEP_ILLEGAL;
632: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.