--- nono/m680x0/m68030fpu.cpp 2026/04/29 17:05:08 1.1.1.3 +++ nono/m680x0/m68030fpu.cpp 2026/04/29 17:05:15 1.1.1.5 @@ -4,29 +4,23 @@ // Licensed under nono-license.txt // -#include "m68030core.h" -#include "m68030bus.h" -#include "m68030ea.h" -#include "m68030excep.h" -#include "m68030fpu.h" - -static void fgen(m68kcpu *); -static void fpu_op_fmovecr(m68kcpu *); +#include "mpu680x0.h" // リセット用のレジスタ初期値 -static struct fpframe initial_fpframe; +/*static*/ struct fpframe +MPU680x0Device::initial_fpframe; // 初期化 void -fpu_init(m68kcpu *cpu) +MPU680x0Device::fpu_init() { int i; uint32_t *p; // XXX cpu の初期化のところと見直してマージするとか - memset(&cpu->fe, 0, sizeof(cpu->fe)); - memset(&cpu->reg.fpframe, 0, sizeof(cpu->reg.fpframe)); - cpu->fe.fe_fpframe = &cpu->reg.fpframe; + memset(&fe, 0, sizeof(fe)); + memset(®.fpframe, 0, sizeof(reg.fpframe)); + fe.fe_fpframe = ®.fpframe; // FRESTORE によるリセット用に FP レジスタの初期値を用意しておく memset(&initial_fpframe, 0, sizeof(initial_fpframe)); @@ -40,13 +34,13 @@ fpu_init(m68kcpu *cpu) // FPU をリセットする。 // MPU リセット時と、NULL フレームのリストア時に呼ばれる。 -static void -fpu_reset(m68kcpu *cpu) +void +MPU680x0Device::fpu_reset() { // 高速化のため、あらかじめ用意しておいたイメージをコピーする - memcpy(&cpu->reg.fpframe, &initial_fpframe, sizeof(initial_fpframe)); + memcpy(®.fpframe, &initial_fpframe, sizeof(initial_fpframe)); - cpu->fpu_dirty = false; + fpu_dirty = false; } // FPU からの呼び出し用。 @@ -59,55 +53,55 @@ fpu_reset(m68kcpu *cpu) // 事前に弾くこと。いずれも消費クロック数は 0 なので問題ない。 // またそれ以外のすべてのアドレッシングモードで反応するため、命令ごとに // 対応していないアドレッシングモードは事前に弾くこと。 -static inline uint32 -cea_fpu(m68kcpu *cpu, int bytes) +inline uint32 +MPU680x0Device::cea_fpu(int bytes) { int n; - switch (eamode(RegIR)) { + switch (eamode(ir)) { case 0: // Dn case 1: // An break; case 2: // (An) - return cea_anin(cpu, eanum(RegIR)); + return cea_anin(eanum(ir)); case 3: // (An)+ CYCLE(6); - n = eanum(RegIR); - m68030_save_reg_pi(cpu, n); + n = eanum(ir); + save_reg_pi(n); if (bytes == 1) { - return internal_ea_anpi_8(cpu, n); + return internal_ea_anpi_8(n); } else { // _anpi_{16,32} のマクロは用意されてるけど、これと同じなので - RegA(n) += bytes; - return RegA(n) - bytes; + reg.A[n] += bytes; + return reg.A[n] - bytes; } break; case 4: // -(An) CYCLE(6); - n = eanum(RegIR); - m68030_save_reg_pd(cpu, n); + n = eanum(ir); + save_reg_pd(n); if (bytes == 1) { - return internal_ea_anpd_8(cpu, n); + return internal_ea_anpd_8(n); } else { // _anpd_{16,32} のマクロは用意されてるけど、これと同じなので - RegA(n) -= bytes; - return RegA(n); + reg.A[n] -= bytes; + return reg.A[n]; } break; case 5: // d16(An) - return cea_andi(cpu, eanum(RegIR)); + return cea_andi(eanum(ir)); case 6: // (An,IX) - return cea_anix(cpu, eanum(RegIR)); + return cea_anix(eanum(ir)); case 7: - switch (eanum(RegIR)) { + switch (eanum(ir)) { case 0: // Abs.W - return cea_absw(cpu); + return cea_absw(); case 1: // Abs.L - return cea_absl(cpu); + return cea_absl(); case 2: // d16(PC) - return cea_pcdi(cpu); + return cea_pcdi(); case 3: // (PC,IX) - return cea_pcix(cpu); + return cea_pcix(); case 4: // #imm break; default: @@ -116,51 +110,50 @@ cea_fpu(m68kcpu *cpu, int bytes) break; } // 不当命令 - throw M68K_EXCEP_ILLEGAL; + throw M68K::EXCEP_ILLEGAL; } // メモリから 64ビット値を読み込む -static void -m68030_read_64(m68kcpu *cpu, uint32 addr, uint32 *data) +void +MPU680x0Device::read_64(uint32 addr, uint32 *data) { - data[0] = m68030_read_32(cpu, addr); - data[1] = m68030_read_32(cpu, addr + 4); + data[0] = read_32(addr); + data[1] = read_32(addr + 4); } // メモリから 96ビット値を読み込む -static void -m68030_read_96(m68kcpu *cpu, uint32 addr, uint32 *data) +void +MPU680x0Device::read_96(uint32 addr, uint32 *data) { - data[0] = m68030_read_32(cpu, addr); - data[1] = m68030_read_32(cpu, addr + 4); - data[2] = m68030_read_32(cpu, addr + 8); + data[0] = read_32(addr); + data[1] = read_32(addr + 4); + data[2] = read_32(addr + 8); } // 64ビット値(.D)をメモリに書き込む -static void -m68030_write_64(m68kcpu *cpu, int32 addr, const uint32 *data) +void +MPU680x0Device::write_64(uint32 addr, const uint32 *data) { - m68030_write_32(cpu, addr, data[0]); - m68030_write_32(cpu, addr + 4, data[1]); + write_32(addr, data[0]); + write_32(addr + 4, data[1]); } // 96ビット値(.D)をメモリに書き込む -static void -m68030_write_96(m68kcpu *cpu, int32 addr, const uint32 *data) +void +MPU680x0Device::write_96(uint32 addr, const uint32 *data) { - m68030_write_32(cpu, addr, data[0]); - m68030_write_32(cpu, addr + 4, data[1]); - m68030_write_32(cpu, addr + 8, data[2]); + write_32(addr, data[0]); + write_32(addr + 4, data[1]); + write_32(addr + 8, data[2]); } // ソースを読み込む。 // 不当命令パターンなら false を返す。 // size_id は SIZE_*。 -static bool -readSRC(m68kcpu *cpu, int size_id, struct fpn *fpn) +bool +MPU680x0Device::readSRC(int size_id, struct fpn *fpn) { - struct fpemu *fe = &cpu->fe; - uint mr = RegIR & 0x3f; + uint mr = ir & 0x3f; uint32 ea; uint32 data[3]; @@ -185,14 +178,14 @@ readSRC(m68kcpu *cpu, int size_id, struc if (mr < 8) { // Dn switch (size_id) { case SIZE_B: - data[0] = (int32)(int8)RegD(mr); + data[0] = (int32)(int8)reg.D[mr]; break; case SIZE_W: - data[0] = (int32)(int16)RegD(mr); + data[0] = (int32)(int16)reg.D[mr]; break; case SIZE_L: case SIZE_S: - data[0] = RegD(mr); + data[0] = reg.D[mr]; break; default: return false; @@ -202,24 +195,24 @@ readSRC(m68kcpu *cpu, int size_id, struc } else if (mr == 0x3c) { // #imm switch (size_id) { case SIZE_B: - data[0] = m68030_fetch_16(cpu) & 0xff; + data[0] = fetch_16() & 0xff; break; case SIZE_W: - data[0] = m68030_fetch_16(cpu); + data[0] = fetch_16(); break; case SIZE_L: case SIZE_S: - data[0] = m68030_fetch_32(cpu); + data[0] = fetch_32(); break; case SIZE_D: - data[0] = m68030_fetch_32(cpu); - data[1] = m68030_fetch_32(cpu); + data[0] = fetch_32(); + data[1] = fetch_32(); break; case SIZE_X: case SIZE_P: - data[0] = m68030_fetch_32(cpu); - data[1] = m68030_fetch_32(cpu); - data[2] = m68030_fetch_32(cpu); + data[0] = fetch_32(); + data[1] = fetch_32(); + data[2] = fetch_32(); break; default: return false; @@ -228,26 +221,26 @@ readSRC(m68kcpu *cpu, int size_id, struc // それ以外は EA を求めてからメモリから読み込む switch (size_id) { case SIZE_B: - ea = cea_fpu(cpu, 1); - data[0] = (int32)(int8)m68030_read_8(cpu, ea); + ea = cea_fpu(1); + data[0] = (int32)(int8)read_8(ea); break; case SIZE_W: - ea = cea_fpu(cpu, 2); - data[0] = (int32)(int16)m68030_read_16(cpu, ea); + ea = cea_fpu(2); + data[0] = (int32)(int16)read_16(ea); break; case SIZE_L: case SIZE_S: - ea = cea_fpu(cpu, 4); - data[0] = m68030_read_32(cpu, ea); + ea = cea_fpu(4); + data[0] = read_32(ea); break; case SIZE_D: - ea = cea_fpu(cpu, 8); - m68030_read_64(cpu, ea, data); + ea = cea_fpu(8); + read_64(ea, data); break; case SIZE_X: case SIZE_P: - ea = cea_fpu(cpu, 12); - m68030_read_96(cpu, ea, data); + ea = cea_fpu(12); + read_96(ea, data); break; default: return false; @@ -260,23 +253,23 @@ readSRC(m68kcpu *cpu, int size_id, struc case SIZE_W: case SIZE_L: CYCLE(+27); - fpu_explode(fe, fpn, FTYPE_LNG, data); + fpu_explode(&fe, fpn, FTYPE_LNG, data); break; case SIZE_S: CYCLE(+19); - fpu_explode(fe, fpn, FTYPE_SNG, data); + fpu_explode(&fe, fpn, FTYPE_SNG, data); break; case SIZE_D: CYCLE(+25); - fpu_explode(fe, fpn, FTYPE_DBL, data); + fpu_explode(&fe, fpn, FTYPE_DBL, data); break; case SIZE_X: CYCLE(+23); - fpu_explode(fe, fpn, FTYPE_EXT, data); + fpu_explode(&fe, fpn, FTYPE_EXT, data); break; case SIZE_P: CYCLE(+837); - fpu_explode(fe, fpn, FTYPE_BCD, data); + fpu_explode(&fe, fpn, FTYPE_BCD, data); break; } @@ -285,243 +278,240 @@ readSRC(m68kcpu *cpu, int size_id, struc // FPU 不当命令 (1ワード目で確定) void -fpu_op_illg(m68kcpu *cpu) +MPU680x0Device::fpu_op_illg() { - cpulog(1, "FPU 不当命令 %04X", RegIR); - m68030_exception(cpu, M68K_EXCEP_FLINE); + putlog(1, "FPU illegal instruction %04X", ir); + Exception(M68K::EXCEP_FLINE); } // FPU 不当命令 (2ワード目で確定) -static void -fpu_op_illg2(m68kcpu *cpu) +void +MPU680x0Device::fpu_op_illg2() { - cpulog(1, "FPU 不当命令 %04X %04X", RegIR, RegIR2); - m68030_exception(cpu, M68K_EXCEP_FLINE); + putlog(1, "FPU illegal instruction %04X %04X", ir, ir2); + Exception(M68K::EXCEP_FLINE); } // R/M=0 (レジスタ-レジスタ演算) void -fpu_op_fgen_reg(m68kcpu *cpu) +MPU680x0Device::fpu_op_fgen_reg() { - struct fpemu *fe = &cpu->fe; - uint srcnum = (RegIR2 >> 10) & 7; - uint dstnum = (RegIR2 >> 7) & 7; - - fpu_explode(fe, &fe->fe_f2, FTYPE_EXT, &RegFP(srcnum * 3)); - fpu_explode(fe, &fe->fe_f1, FTYPE_EXT, &RegFP(dstnum * 3)); - fgen(cpu); + uint srcnum = (ir2 >> 10) & 7; + uint dstnum = (ir2 >> 7) & 7; + + fpu_explode(&fe, &fe.fe_f2, FTYPE_EXT, &RegFP(srcnum * 3)); + fpu_explode(&fe, &fe.fe_f1, FTYPE_EXT, &RegFP(dstnum * 3)); + fgen(); } // R/M=1 (メモリ-レジスタ演算) void -fpu_op_fgen_mem(m68kcpu *cpu) +MPU680x0Device::fpu_op_fgen_mem() { - struct fpemu *fe = &cpu->fe; - uint size_id = (RegIR2 >> 10) & 7; - uint dstnum = (RegIR2 >> 7) & 7; + uint size_id = (ir2 >> 10) & 7; + uint dstnum = (ir2 >> 7) & 7; // source specifier はオペランドサイズ if (size_id == 7) { // こんなところに FMOVECR - fpu_op_fmovecr(cpu); + fpu_op_fmovecr(); return; } // 第1ワードの EA がソース EA - if (!readSRC(cpu, size_id, &fe->fe_f2)) { - fpu_op_illg2(cpu); + if (!readSRC(size_id, &fe.fe_f2)) { + fpu_op_illg2(); return; } - fpu_explode(fe, &fe->fe_f1, FTYPE_EXT, &RegFP(dstnum * 3)); - fgen(cpu); + fpu_explode(&fe, &fe.fe_f1, FTYPE_EXT, &RegFP(dstnum * 3)); + fgen(); } // 一般算術演算 -static void -fgen(m68kcpu *cpu) +void +MPU680x0Device::fgen() { - struct fpemu *fe = &cpu->fe; - uint opmode = RegIR2 & 0x3f; - uint dstnum = (RegIR2 >> 7) & 7; + uint opmode = ir2 & 0x3f; + uint dstnum = (ir2 >> 7) & 7; bool discard_result = false; struct fpn *res = NULL; // shutup gcc switch (opmode) { case 0x00: // FMOVE CYCLE(33); - res = &fe->fe_f2; - fpu_round_prec(fe, res); + res = &fe.fe_f2; + fpu_round_prec(&fe, res); break; case 0x01: // FINT CYCLE(55); - res = fpu_int(fe); + res = fpu_int(&fe); break; case 0x02: // FSINH CYCLE(687); - res = fpu_sinh(fe); - fpu_round_prec(fe, res); + res = fpu_sinh(&fe); + fpu_round_prec(&fe, res); break; case 0x03: // FINTRZ CYCLE(55); - res = fpu_intrz(fe); + res = fpu_intrz(&fe); break; case 0x04: // FSQRT CYCLE(107); - res = fpu_sqrt(fe); - fpu_round_prec(fe, res); + res = fpu_sqrt(&fe); + fpu_round_prec(&fe, res); break; case 0x06: // FLOGNP1 CYCLE(571); - res = fpu_lognp1(fe); - fpu_round_prec(fe, res); + res = fpu_lognp1(&fe); + fpu_round_prec(&fe, res); break; case 0x08: // FETOXM1 CYCLE(545); - res = fpu_etoxm1(fe); - fpu_round_prec(fe, res); + res = fpu_etoxm1(&fe); + fpu_round_prec(&fe, res); break; case 0x09: // FTANH CYCLE(661); - res = fpu_tanh(fe); - fpu_round_prec(fe, res); + res = fpu_tanh(&fe); + fpu_round_prec(&fe, res); break; case 0x0a: // FATAN CYCLE(403); - res = fpu_atan(fe); - fpu_round_prec(fe, res); + res = fpu_atan(&fe); + fpu_round_prec(&fe, res); break; case 0x0c: // FASIN CYCLE(581); - res = fpu_asin(fe); - fpu_round_prec(fe, res); + res = fpu_asin(&fe); + fpu_round_prec(&fe, res); break; case 0x0d: // FATANH CYCLE(693); - res = fpu_atanh(fe); - fpu_round_prec(fe, res); + res = fpu_atanh(&fe); + fpu_round_prec(&fe, res); break; case 0x0e: // FSIN CYCLE(391); - res = fpu_sin(fe); - fpu_round_prec(fe, res); + res = fpu_sin(&fe); + fpu_round_prec(&fe, res); break; case 0x0f: // FTAN CYCLE(473); - res = fpu_tan(fe); - fpu_round_prec(fe, res); + res = fpu_tan(&fe); + fpu_round_prec(&fe, res); break; case 0x10: // FETOX CYCLE(497); - res = fpu_etox(fe); - fpu_round_prec(fe, res); + res = fpu_etox(&fe); + fpu_round_prec(&fe, res); break; case 0x11: // FTWOTOX CYCLE(567); - res = fpu_twotox(fe); - fpu_round_prec(fe, res); + res = fpu_twotox(&fe); + fpu_round_prec(&fe, res); break; case 0x12: // FTENTOX CYCLE(567); - res = fpu_tentox(fe); - fpu_round_prec(fe, res); + res = fpu_tentox(&fe); + fpu_round_prec(&fe, res); break; case 0x14: // FLOGN CYCLE(525); - res = fpu_logn(fe); - fpu_round_prec(fe, res); + res = fpu_logn(&fe); + fpu_round_prec(&fe, res); break; case 0x15: // FLOG10 CYCLE(581); - res = fpu_log10(fe); - fpu_round_prec(fe, res); + res = fpu_log10(&fe); + fpu_round_prec(&fe, res); break; case 0x16: // FLOG2 CYCLE(581); - res = fpu_log2(fe); - fpu_round_prec(fe, res); + res = fpu_log2(&fe); + fpu_round_prec(&fe, res); break; case 0x18: // FABS CYCLE(35); - fe->fe_f2.fp_sign = 0; - res = &fe->fe_f2; - fpu_round_prec(fe, res); + fe.fe_f2.fp_sign = 0; + res = &fe.fe_f2; + fpu_round_prec(&fe, res); break; case 0x19: // FCOSH CYCLE(607); - res = fpu_cosh(fe); - fpu_round_prec(fe, res); + res = fpu_cosh(&fe); + fpu_round_prec(&fe, res); break; case 0x1a: // FNEG CYCLE(35); - res = &fe->fe_f2; + res = &fe.fe_f2; if (!ISNAN(res)) { res->fp_sign = !res->fp_sign; - fpu_round_prec(fe, res); + fpu_round_prec(&fe, res); } break; case 0x1c: // FACOS CYCLE(625); - res = fpu_acos(fe); - fpu_round_prec(fe, res); + res = fpu_acos(&fe); + fpu_round_prec(&fe, res); break; case 0x1d: // FCOS CYCLE(391); - res = fpu_cos(fe); - fpu_round_prec(fe, res); + res = fpu_cos(&fe); + fpu_round_prec(&fe, res); break; case 0x1e: // FGETEXP CYCLE(45); - res = fpu_getexp(fe); - fpu_round_prec(fe, res); + res = fpu_getexp(&fe); + fpu_round_prec(&fe, res); break; case 0x1f: // FGETMAN CYCLE(31); - res = fpu_getman(fe); - fpu_round_prec(fe, res); + res = fpu_getman(&fe); + fpu_round_prec(&fe, res); break; case 0x20: // FDIV CYCLE(103); - res = fpu_div(fe); - fpu_round_prec(fe, res); + res = fpu_div(&fe); + fpu_round_prec(&fe, res); break; case 0x21: // FMOD CYCLE(67); - res = fpu_mod(fe); - fpu_round_prec(fe, res); + res = fpu_mod(&fe); + fpu_round_prec(&fe, res); break; case 0x22: // FADD CYCLE(51); - res = fpu_add(fe); - fpu_round_prec(fe, res); + res = fpu_add(&fe); + fpu_round_prec(&fe, res); break; case 0x23: // FMUL CYCLE(71); - res = fpu_mul(fe); - fpu_round_prec(fe, res); + res = fpu_mul(&fe); + fpu_round_prec(&fe, res); break; case 0x24: // FSGLDIV CYCLE(69); - res = fpu_sgldiv(fe); + res = fpu_sgldiv(&fe); break; case 0x25: // FREM CYCLE(67); - res = fpu_rem(fe); - fpu_round_prec(fe, res); + res = fpu_rem(&fe); + fpu_round_prec(&fe, res); break; case 0x26: // FSCALE // こいつだけ形式が違う。 // 結果は dst に直接格納済み、FPSR も演算済み。 CYCLE(41); - fpu_emul_fscale(fe, RegIR2); + fpu_emul_fscale(&fe, ir2); return; case 0x27: // FSGLMUL CYCLE(59); - res = fpu_sglmul(fe); + res = fpu_sglmul(&fe); break; case 0x28: // FSUB CYCLE(51); - res = fpu_sub(fe); - fpu_round_prec(fe, res); + res = fpu_sub(&fe); + fpu_round_prec(&fe, res); break; case 0x30: case 0x31: @@ -532,207 +522,200 @@ fgen(m68kcpu *cpu) case 0x36: case 0x37: // FSINCOS CYCLE(451); - res = fpu_sincos(fe, opmode & 7); - fpu_round_prec(fe, res); + res = fpu_sincos(&fe, opmode & 7); + fpu_round_prec(&fe, res); break; case 0x38: // FCMP CYCLE(33); - res = fpu_cmp(fe); + res = fpu_cmp(&fe); discard_result = 1; break; case 0x3a: // FTST CYCLE(33); - res = &fe->fe_f2; + res = &fe.fe_f2; discard_result = 1; break; default: // 不当命令 - fpu_op_illg2(cpu); + fpu_op_illg2(); return; } assert(res); if (!discard_result) { - fpu_implode(fe, res, FTYPE_EXT, &RegFP(dstnum * 3)); + fpu_implode(&fe, res, FTYPE_EXT, &RegFP(dstnum * 3)); } - fpu_upd_fpsr(fe, res); - fpu_upd_excp(fe); + fpu_upd_fpsr(&fe, res); + fpu_upd_excp(&fe); } // FMOVECR void -fpu_op_fmovecr(m68kcpu *cpu) +MPU680x0Device::fpu_op_fmovecr() { CYCLE(29); - struct fpemu *fe = &cpu->fe; - uint offset = (RegIR2 & 0x7f); - uint dstnum = (RegIR2 >> 7) & 7; - - fpu_const(&fe->fe_f3, offset); - fpu_implode(fe, &fe->fe_f3, FTYPE_EXT, &RegFP(dstnum * 3)); - fpu_upd_fpsr(fe, &fe->fe_f3); - fpu_upd_excp(fe); + uint offset = (ir2 & 0x7f); + uint dstnum = (ir2 >> 7) & 7; + + fpu_const(&fe.fe_f3, offset); + fpu_implode(&fe, &fe.fe_f3, FTYPE_EXT, &RegFP(dstnum * 3)); + fpu_upd_fpsr(&fe, &fe.fe_f3); + fpu_upd_excp(&fe); } // FMOVE.B FPn, // cf. 68000PRM.pdf p378 (5-76) void -fpu_op_fmove_b_mem(m68kcpu *cpu) +MPU680x0Device::fpu_op_fmove_b_mem() { - struct fpemu *fe = &cpu->fe; - uint mr = RegIR & 0x3f; - uint srcnum = (RegIR2 >> 7) & 7; + uint mr = ir & 0x3f; + uint srcnum = (ir2 >> 7) & 7; uint32 ea; uint32 data; - fpu_explode(fe, &fe->fe_f3, FTYPE_EXT, &RegFP(srcnum * 3)); - fpu_implode(fe, &fe->fe_f3, FTYPE_LNG, &data); + fpu_explode(&fe, &fe.fe_f3, FTYPE_EXT, &RegFP(srcnum * 3)); + fpu_implode(&fe, &fe.fe_f3, FTYPE_LNG, &data); if ((int32)data < INT8_MIN || (int32)data > INT8_MAX) { RegFPSR |= FPSR_OPERR | FPSR_AIOP; } if (mr < 8) { // Dn CYCLE(100-2); - RegD(mr) &= 0xffffff00; - RegD(mr) |= (uint8)data; + reg.D[mr] &= 0xffffff00; + reg.D[mr] |= (uint8)data; } else { CYCLE(100); - ea = cea_fpu(cpu, 1); - m68030_write_8(cpu, ea, (uint8)data); + ea = cea_fpu(1); + write_8(ea, (uint8)data); } } // FMOVE.W FPn, // cf. 68000PRM.pdf p378 (5-76) void -fpu_op_fmove_w_mem(m68kcpu *cpu) +MPU680x0Device::fpu_op_fmove_w_mem() { - struct fpemu *fe = &cpu->fe; - uint mr = RegIR & 0x3f; - uint srcnum = (RegIR2 >> 7) & 7; + uint mr = ir & 0x3f; + uint srcnum = (ir2 >> 7) & 7; uint32 ea; uint32 data; - fpu_explode(fe, &fe->fe_f3, FTYPE_EXT, &RegFP(srcnum * 3)); - fpu_implode(fe, &fe->fe_f3, FTYPE_LNG, &data); + fpu_explode(&fe, &fe.fe_f3, FTYPE_EXT, &RegFP(srcnum * 3)); + fpu_implode(&fe, &fe.fe_f3, FTYPE_LNG, &data); if ((int32)data < INT16_MIN || (int32)data > INT16_MAX) { RegFPSR |= FPSR_OPERR | FPSR_AIOP; } if (mr < 8) { // Dn CYCLE(100-2); - RegD(mr) &= 0xffff0000; - RegD(mr) |= (uint16)data; + reg.D[mr] &= 0xffff0000; + reg.D[mr] |= (uint16)data; } else { CYCLE(100); - ea = cea_fpu(cpu, 2); - m68030_write_16(cpu, ea, (uint16)data); + ea = cea_fpu(2); + write_16(ea, (uint16)data); } } // FMOVE.L FPn, // cf. 68000PRM.pdf p378 (5-76) void -fpu_op_fmove_l_mem(m68kcpu *cpu) +MPU680x0Device::fpu_op_fmove_l_mem() { - struct fpemu *fe = &cpu->fe; - uint mr = RegIR & 0x3f; - uint srcnum = (RegIR2 >> 7) & 7; + uint mr = ir & 0x3f; + uint srcnum = (ir2 >> 7) & 7; uint32 ea; uint32 data; - fpu_explode(fe, &fe->fe_f3, FTYPE_EXT, &RegFP(srcnum * 3)); - fpu_implode(fe, &fe->fe_f3, FTYPE_LNG, &data); + fpu_explode(&fe, &fe.fe_f3, FTYPE_EXT, &RegFP(srcnum * 3)); + fpu_implode(&fe, &fe.fe_f3, FTYPE_LNG, &data); // XXX オーバーフローチェック if (mr < 8) { // Dn CYCLE(100-2); - RegD(mr) = data; + reg.D[mr] = data; } else { CYCLE(100); - ea = cea_fpu(cpu, 4); - m68030_write_32(cpu, ea, data); + ea = cea_fpu(4); + write_32(ea, data); } } // FMOVE.S FPn, // cf. 68000PRM.pdf p378 (5-76) void -fpu_op_fmove_s_mem(m68kcpu *cpu) +MPU680x0Device::fpu_op_fmove_s_mem() { - struct fpemu *fe = &cpu->fe; - uint mr = RegIR & 0x3f; - uint srcnum = (RegIR2 >> 7) & 7; + uint mr = ir & 0x3f; + uint srcnum = (ir2 >> 7) & 7; uint32 ea; uint32 data; - fpu_explode(fe, &fe->fe_f3, FTYPE_EXT, &RegFP(srcnum * 3)); - fpu_implode(fe, &fe->fe_f3, FTYPE_SNG, &data); + fpu_explode(&fe, &fe.fe_f3, FTYPE_EXT, &RegFP(srcnum * 3)); + fpu_implode(&fe, &fe.fe_f3, FTYPE_SNG, &data); if (mr < 8) { // Dn CYCLE(80-2); - RegD(mr) = data; + reg.D[mr] = data; } else { CYCLE(80); - ea = cea_fpu(cpu, 4); - m68030_write_32(cpu, ea, data); + ea = cea_fpu(4); + write_32(ea, data); } } // FMOVE.D FPn, // cf. 68000PRM.pdf p378 (5-76) void -fpu_op_fmove_d_mem(m68kcpu *cpu) +MPU680x0Device::fpu_op_fmove_d_mem() { CYCLE(86); - struct fpemu *fe = &cpu->fe; - uint srcnum = (RegIR2 >> 7) & 7; + uint srcnum = (ir2 >> 7) & 7; uint32 ea; uint32 data[2]; - fpu_explode(fe, &fe->fe_f3, FTYPE_EXT, &RegFP(srcnum * 3)); - fpu_implode(fe, &fe->fe_f3, FTYPE_DBL, data); + fpu_explode(&fe, &fe.fe_f3, FTYPE_EXT, &RegFP(srcnum * 3)); + fpu_implode(&fe, &fe.fe_f3, FTYPE_DBL, data); - ea = cea_fpu(cpu, 8); - m68030_write_64(cpu, ea, data); + ea = cea_fpu(8); + write_64(ea, data); } // FMOVE.X FPn, // cf. 68000PRM.pdf p378 (5-76) void -fpu_op_fmove_x_mem(m68kcpu *cpu) +MPU680x0Device::fpu_op_fmove_x_mem() { CYCLE(72); - uint srcnum = (RegIR2 >> 7) & 7; + uint srcnum = (ir2 >> 7) & 7; uint32 ea; - ea = cea_fpu(cpu, 12); - m68030_write_96(cpu, ea, &RegFP(srcnum * 3)); + ea = cea_fpu(12); + write_96(ea, &RegFP(srcnum * 3)); } // FMOVE.P FPn, // cf. 68000PRM.pdf p378 (5-76) void -fpu_op_fmove_p_mem(m68kcpu *cpu) +MPU680x0Device::fpu_op_fmove_p_mem() { - struct fpemu *fe = &cpu->fe; - uint srcnum = (RegIR2 >> 7) & 7; + uint srcnum = (ir2 >> 7) & 7; uint32 ea; uint32 data[3]; uint32 k; - if ((RegIR2 & 0x1000)) { + if ((ir2 & 0x1000)) { // dynamic k-factor CYCLE(1996+14); - k = RegD((RegIR2 >> 4) & 7); + k = reg.D[(ir2 >> 4) & 7]; } else { // static k-factor CYCLE(1996); - k = RegIR2; + k = ir2; } // k は7ビット符号付き数 k &= 0x7f; @@ -740,11 +723,11 @@ fpu_op_fmove_p_mem(m68kcpu *cpu) k = (int32)(int8)(k | 0x80); } - fpu_explode(fe, &fe->fe_f3, FTYPE_EXT, &RegFP(srcnum * 3)); - fpu_ftop(fe, &fe->fe_f3, data, k); + fpu_explode(&fe, &fe.fe_f3, FTYPE_EXT, &RegFP(srcnum * 3)); + fpu_ftop(&fe, &fe.fe_f3, data, k); - ea = cea_fpu(cpu, 12); - m68030_write_96(cpu, ea, data); + ea = cea_fpu(12); + write_96(ea, data); } // FMOVEM.L , @@ -752,10 +735,10 @@ fpu_op_fmove_p_mem(m68kcpu *cpu) // D=0: to FPctl // RRR: register list void -fpu_op_fmovem_ea2ctl(m68kcpu *cpu) +MPU680x0Device::fpu_op_fmovem_ea2ctl() { - uint mr = RegIR & 0x3f; - uint reglist = (RegIR2 >> 10) & 7; + uint mr = ir & 0x3f; + uint reglist = (ir2 >> 10) & 7; int count; uint32 ea; uint32 src[3]; @@ -781,19 +764,19 @@ fpu_op_fmovem_ea2ctl(m68kcpu *cpu) CYCLE2(28, 31); // 対データレジスタは転送数 1 のみ有効 if (count > 1) { - fpu_op_illg2(cpu); + fpu_op_illg2(); return; } - src[0] = RegR(mr); + src[0] = reg.R[mr]; } else if (mr < 16) { // An CYCLE2(28, 31); // 対アドレスレジスタは FPIAR のみ有効 if (reglist != 1) { - fpu_op_illg2(cpu); + fpu_op_illg2(); return; } - src[0] = RegR(mr); + src[0] = reg.R[mr]; } else if (mr < 0x3c) { // 対メモリ CYCLE2(28, 30); @@ -803,9 +786,9 @@ fpu_op_fmovem_ea2ctl(m68kcpu *cpu) // -(An) の時も先にレジスタ数分一気に減算して、そこからプラス方向に // 読み込んでいくので、ロジックは全部同じになる。 // (68000PRM.pdf p393) - ea = cea_fpu(cpu, count * 4); + ea = cea_fpu(count * 4); for (i = 0; i < count; i++) { - src[i] = m68030_read_32(cpu, ea); + src[i] = read_32(ea); ea += 4; } @@ -814,21 +797,21 @@ fpu_op_fmovem_ea2ctl(m68kcpu *cpu) CYCLE(count * 6); for (i = 0; i < count; i++) { - src[i] = m68030_fetch_32(cpu); + src[i] = fetch_32(); } } else { - fpu_op_illg2(cpu); + fpu_op_illg2(); return; } // 該当レジスタへ読み込み i = 0; if ((reglist & 4)) { - RegFPCR = src[i++] & M68K_FPCR_MASK; + RegFPCR = src[i++] & M68K::FPCR_MASK; } if ((reglist & 2)) { - RegFPSR = src[i++] & M68K_FPSR_MASK; + RegFPSR = src[i++] & M68K::FPSR_MASK; } if ((reglist & 1)) { RegFPIAR = src[i++]; @@ -840,10 +823,10 @@ fpu_op_fmovem_ea2ctl(m68kcpu *cpu) // D=1: FPctl to // RRR: register list void -fpu_op_fmovem_ctl2ea(m68kcpu *cpu) +MPU680x0Device::fpu_op_fmovem_ctl2ea() { - uint mr = RegIR & 0x3f; - uint reglist = (RegIR2 >> 10) & 7; + uint mr = ir & 0x3f; + uint reglist = (ir2 >> 10) & 7; int count; uint32 ea; @@ -862,18 +845,18 @@ fpu_op_fmovem_ctl2ea(m68kcpu *cpu) CYCLE2(31, 34); // 対データレジスタは転送数は 1 のみ有効 if (count > 1) { - fpu_op_illg2(cpu); + fpu_op_illg2(); return; } if ((reglist & 4)) { - RegR(mr) = RegFPCR; + reg.R[mr] = RegFPCR; } if ((reglist & 2)) { - RegR(mr) = RegFPSR; + reg.R[mr] = RegFPSR; } if ((reglist & 1)) { - RegR(mr) = RegFPIAR; + reg.R[mr] = RegFPIAR; } return; } @@ -881,14 +864,14 @@ fpu_op_fmovem_ctl2ea(m68kcpu *cpu) CYCLE2(31, 34); // 対アドレスレジスタは FPIAR のみ有効 if (reglist != 1) { - fpu_op_illg2(cpu); + fpu_op_illg2(); return; } - RegR(mr) = RegFPIAR; + reg.R[mr] = RegFPIAR; return; } if (mr >= 0x3a) { // #imm, d16(PC), (PC,IX) - fpu_op_illg2(cpu); + fpu_op_illg2(); return; } @@ -897,18 +880,18 @@ fpu_op_fmovem_ctl2ea(m68kcpu *cpu) CYCLE(count * 6); // EA を取得して... - ea = cea_fpu(cpu, count * 4); + ea = cea_fpu(count * 4); // 該当レジスタをメモリへ書き出し if ((reglist & 4)) { - m68030_write_32(cpu, ea, RegFPCR); + write_32(ea, RegFPCR); ea += 4; } if ((reglist & 2)) { - m68030_write_32(cpu, ea, RegFPSR); + write_32(ea, RegFPSR); ea += 4; } if ((reglist & 1)) { - m68030_write_32(cpu, ea, RegFPIAR); + write_32(ea, RegFPIAR); ea += 4; } } @@ -918,12 +901,12 @@ fpu_op_fmovem_ctl2ea(m68kcpu *cpu) // 1111 ccc 000 mmmrrr | 11D MM000 RRRRRRRR // D=0: to FPn void -fpu_op_fmovem_ea2reg(m68kcpu *cpu) +MPU680x0Device::fpu_op_fmovem_ea2reg() { - uint mr = RegIR & 0x3f; - bool predec = !(RegIR2 & 0x1000); - bool dynamic = (RegIR2 & 0x0800); - uint8 reglist = RegIR2 & 0xff; + uint mr = ir & 0x3f; + bool predec = !(ir2 & 0x1000); + bool dynamic = (ir2 & 0x0800); + uint8 reglist = ir2 & 0xff; int i; uint32 ea; @@ -938,7 +921,7 @@ fpu_op_fmovem_ea2reg(m68kcpu *cpu) case 0x20 ... 0x27: // -(An) case 0x3c: // #imm case 0x3d ... 0x3f: - fpu_op_illg2(cpu); + fpu_op_illg2(); return; } @@ -947,7 +930,7 @@ fpu_op_fmovem_ea2reg(m68kcpu *cpu) // ビットは無視、Dn の上位ビットも無視。 // ついでにここでベースクロックを記録 if (dynamic) { - reglist = RegD((reglist >> 4) & 7); + reglist = reg.D[(reglist >> 4) & 7]; CYCLE2(49, 52); } else { CYCLE2(35, 38); @@ -955,13 +938,13 @@ fpu_op_fmovem_ea2reg(m68kcpu *cpu) // EA は最初に一度取得しておいて... int count = __builtin_popcount(reglist); - ea = cea_fpu(cpu, 12 * count); + ea = cea_fpu(12 * count); if (predec) { // predec ならビット7から FP7..FP0 で、bit7 側から順に転送。 for (i = 7; reglist; reglist <<=1, i--) { if ((int8)reglist < 0) { - m68030_read_96(cpu, ea, &RegFP(i * 3)); + read_96(ea, &RegFP(i * 3)); ea += 12; } } @@ -969,7 +952,7 @@ fpu_op_fmovem_ea2reg(m68kcpu *cpu) // ctrl/postinc ならビット7から FP0..FP7 で、bit7 側から順に転送。 for (i = 0; reglist; reglist <<= 1, i++) { if ((int8)reglist < 0) { - m68030_read_96(cpu, ea, &RegFP(i * 3)); + read_96(ea, &RegFP(i * 3)); ea += 12; } } @@ -982,13 +965,13 @@ fpu_op_fmovem_ea2reg(m68kcpu *cpu) // 1111 ccc 000 mmmrrr | 11D MM000 RRRRRRRR // D=1: FPn to void -fpu_op_fmovem_reg2ea(m68kcpu *cpu) +MPU680x0Device::fpu_op_fmovem_reg2ea() { - uint mr = RegIR & 0x3f; + uint mr = ir & 0x3f; bool anpd = false; // 第1ワード EA が -(An) か - bool predec = !(RegIR2 & 0x1000); // 第2ワードの mode が predec か - bool dynamic = (RegIR2 & 0x0800); - uint8 reglist = RegIR2 & 0xff; + bool predec = !(ir2 & 0x1000); // 第2ワードの mode が predec か + bool dynamic = (ir2 & 0x0800); + uint8 reglist = ir2 & 0xff; int i; uint32 ea; @@ -1006,7 +989,7 @@ fpu_op_fmovem_reg2ea(m68kcpu *cpu) case 0x3b: // (PC,IX) case 0x3c: // #imm case 0x3d ... 0x3f: - fpu_op_illg2(cpu); + fpu_op_illg2(); return; case 0x20 ... 0x27: // -(An) anpd = true; @@ -1018,7 +1001,7 @@ fpu_op_fmovem_reg2ea(m68kcpu *cpu) // ビットは無視、Dn の上位ビットも無視。 // ついでにここでベースクロックを記録 if (dynamic) { - reglist = RegD((reglist >> 4) & 7); + reglist = reg.D[(reglist >> 4) & 7]; CYCLE2(51, 54); } else { CYCLE2(37, 40); @@ -1038,35 +1021,35 @@ fpu_op_fmovem_reg2ea(m68kcpu *cpu) // なので、例外的である FMOVEM は仕方がない。 if (anpd) { CYCLE(6); - uint n = eanum(RegIR); - m68030_save_reg_pd(cpu, n); + uint n = eanum(ir); + save_reg_pd(n); if (predec) { // predec ならビット7から FP7..FP0 で、bit7 側から順に転送。 for (i = 7; reglist; reglist <<= 1, i--) { if ((int8)reglist < 0) { - RegA(n) -= 12; - m68030_write_96(cpu, RegA(n), &RegFP(i * 3)); + reg.A[n] -= 12; + write_96(reg.A[n], &RegFP(i * 3)); } } } else { // ctrl/postinc ならビット7から FP0..FP7 で、bit7 側から順に転送。 for (i = 0; reglist; reglist <<= 1, i++) { if ((int8)reglist < 0) { - RegA(n) -= 12; - m68030_write_96(cpu, RegA(n), &RegFP(i * 3)); + reg.A[n] -= 12; + write_96(reg.A[n], &RegFP(i * 3)); } } } } else { // -(An) 以外は EA を最初に一度計算しておく方法が使える - ea = cea_fpu(cpu, 12 * count); + ea = cea_fpu(12 * count); if (predec) { // predec ならビット7から FP7..FP0 で、bit7 側から順に転送。 for (i = 7; reglist; reglist <<= 1, i--) { if ((int8)reglist < 0) { - m68030_write_96(cpu, ea, &RegFP(i * 3)); + write_96(ea, &RegFP(i * 3)); ea += 12; } } @@ -1074,7 +1057,7 @@ fpu_op_fmovem_reg2ea(m68kcpu *cpu) // ctrl/postinc ならビット7から FP0..FP7 で、bit7 側から順に転送。 for (i = 0; reglist; reglist <<= 1, i++) { if ((int8)reglist < 0) { - m68030_write_96(cpu, ea, &RegFP(i * 3)); + write_96(ea, &RegFP(i * 3)); ea += 12; } } @@ -1086,13 +1069,12 @@ fpu_op_fmovem_reg2ea(m68kcpu *cpu) // FScc.B // 1111 ccc 001 mmmrrr | 0000 000 000 CCCCCC void -fpu_op_fscc(m68kcpu *cpu) +MPU680x0Device::fpu_op_fscc() { - struct fpemu *fe = &cpu->fe; - uint mr = RegIR & 0x3f; - uint mm = eamode(RegIR); - uint rr = eanum(RegIR); - uint cond = RegIR2 & 0x3f; + uint mr = ir & 0x3f; + uint mm = eamode(ir); + uint rr = eanum(ir); + uint cond = ir2 & 0x3f; int data; uint32 ea; @@ -1103,17 +1085,17 @@ fpu_op_fscc(m68kcpu *cpu) // FScc.B 20 23 if (cond > 0x1f) { - fpu_op_illg2(cpu); + fpu_op_illg2(); return; } - data = (test_cc(fe, cond) == -1) ? 0xff : 0x00; + data = (test_cc(&fe, cond) == -1) ? 0xff : 0x00; switch (mm) { case 0: // Dn CYCLE2(18, 21); - RegD(rr) &= 0xffffff00; - RegD(rr) |= data; + reg.D[rr] &= 0xffffff00; + reg.D[rr] |= data; return; case 3: // (An)+ @@ -1129,7 +1111,7 @@ fpu_op_fscc(m68kcpu *cpu) case 7: if (mr == 0x38 || mr == 0x39) { // Abs.W, Abs.L } else { - fpu_op_illg2(cpu); + fpu_op_illg2(); return; } FALLTHROUGH; @@ -1138,109 +1120,105 @@ fpu_op_fscc(m68kcpu *cpu) break; } - ea = cea_fpu(cpu, 1); - m68030_write_8(cpu, ea, data); + ea = cea_fpu(1); + write_8(ea, data); } // FDBcc Dn,