|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2018 [email protected] ! 4: // ! 5: ! 6: #include "header.h" ! 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: // ! 27: // F E D C B A 9 8 7 6 5 4 3 2 1 0 ! 28: // +----------+-----------+--------+--------+ ! 29: // | DA n n n WL SCALE 0 <---- disp ----> | ! 30: // +----------+-----------+--------+--------+ ! 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: // ! 49: // F E D C B A 9 8 7 6 5 4 3 2 1 0 ! 50: // +----------+-----------+----------+--------+ ! 51: // | DA n n n WL SCALE 1 BS IS BDSZ 0 I/IS | ! 52: // +----------+-----------+----------+--------+ ! 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.