--- nono/m680x0/m68030ops.cpp 2026/04/29 17:04:28 1.1 +++ nono/m680x0/m68030ops.cpp 2026/04/29 17:05:19 1.1.1.6 @@ -1,21 +1,66 @@ // // nono -// Copyright (C) 2017 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // +#include "mpu680x0.h" +#include "m68030acc.h" +#include "m68030bitfield.h" + +#define OP_DEF(name) void __CONCAT(MPU680x0Device::op_,name)() +#define OP_FUNC(name) __CONCAT(op_,name)() + +#define CCR reg.ccr +#define ACC (*(m68030acc*)®.ccr) + +#define RegIRX ((ir >> 9) & 7) +#define RegIRY (ir & 7) +#define RegDX reg.D[RegIRX] +#define RegAX reg.A[RegIRX] +#define RegDY reg.D[RegIRY] +#define RegAY reg.A[RegIRY] + +// 副作用のあるマクロ +// 特権違反例外のスタックに積む PC は違反を起こした命令先頭。 +#define SUPERVISOR_OP do { \ + if (!IsSuper()) { \ + CYCLE2(18, 20); \ + Exception(M68K::EXCEP_PRIV); \ + return; \ + } \ +} while (0) + +// FPU 命令の FSAVE/FRESTORE 以外のグループ全員で実行開始時に必要な処理 +inline void +MPU680x0Device::fpu_op_start() +{ + fpu_dirty = true; + + // 現在の FPCR/FPSR を fe 構造体にコピー。 + // + // fe.fe_{fpcr,fpsr} のほうはこの fpe 用の内部ワークなので破壊してよい。 + // 命令実行の結果、FPSR レジスタの値を更新する際は fpu_upd_fpsr() を + // 呼ぶこと。これを使わず独自に更新する場合は fe.fe_fpframe->fpf_fpsr + // (こっちがレジスタ値) と fe.fe_fpsr (FPE 用) を同時に更新すること。 + // FPCR のほうは FMOVE-to-FPCR 命令以外で変更されることはないはず。 + fe.fe_fpcr = RegFPCR; + fe.fe_fpsr = RegFPSR; +} + // %0000_000000_mmmrrr ORI.B #, // %0000_000000_111100 ORI.B #,CCR OP_DEF(ori_b) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; - uint32 src = m68030_fetch_16(cpu) & 0xff; + uint32 src = fetch_16() & 0xff; if (n < 8) { // ORI.B #,Dn CYCLE(2); - uint32 dst = (RegD(n) & 0xff) | src; - acc_move_8(cpu, dst); - RegD(n) = (RegD(n) & 0xffffff00) | dst; + uint32 dst = (reg.D[n] & 0xff) | src; + ACC.move_8(dst); + reg.D[n] = (reg.D[n] & 0xffffff00) | dst; } else if (n == 0b111100) { // ORI.B #,SR CYCLE2(12, 14); @@ -23,11 +68,11 @@ OP_DEF(ori_b) } else { // ORI.B #, CYCLE2(3, 4); - uint32 ea = cea_data_8(cpu); - uint32 dst = m68030_read_8(cpu, ea); + uint32 ea = cea_data_8(); + uint32 dst = read_8(ea); dst |= src; - acc_move_8(cpu, dst); - m68030_write_8(cpu, ea, dst); + ACC.move_8(dst); + write_8(ea, dst); } } @@ -35,85 +80,85 @@ OP_DEF(ori_b) // %0000_000001_111100 ORI.W #,SR OP_DEF(ori_w) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // ORI.W #,Dn CYCLE(2); - uint32 src = m68030_fetch_16(cpu); - uint32 dst = (RegD(n) & 0xffff) | src; - acc_move_16(cpu, dst); - RegD(n) = (RegD(n) & 0xffff0000) | dst; + uint32 src = fetch_16(); + uint32 dst = (reg.D[n] & 0xffff) | src; + ACC.move_16(dst); + reg.D[n] = (reg.D[n] & 0xffff0000) | dst; } else if (n == 0b111100) { // ORI.W #,SR SUPERVISOR_OP; CYCLE2(12, 14); - uint32 src = m68030_fetch_16(cpu); - m68030_set_sr(cpu, RegSR | src); + uint32 src = fetch_16(); + SetSR(GetSR() | src); } else { // ORI.W #, CYCLE2(3, 4); - uint32 src = m68030_fetch_16(cpu); - uint32 ea = cea_data_16(cpu); - uint32 dst = m68030_read_16(cpu, ea); + uint32 src = fetch_16(); + uint32 ea = cea_data_16(); + uint32 dst = read_16(ea); dst |= src; - acc_move_16(cpu, dst); - m68030_write_16(cpu, ea, dst); + ACC.move_16(dst); + write_16(ea, dst); } } // %0000_000010_mmmrrr ORI.L #, OP_DEF(ori_l) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; - uint32 src = m68030_fetch_32(cpu); + uint32 src = fetch_32(); if (n < 8) { // ORI.L #,Dn CYCLE(2); - RegD(n) |= src; - acc_move_32(cpu, RegD(n)); + reg.D[n] |= src; + ACC.move_32(reg.D[n]); } else { // ORI.L #, CYCLE2(3, 4); - uint32 ea = cea_data_32(cpu); - uint32 dst = m68030_read_32(cpu, ea); + uint32 ea = cea_data_32(); + uint32 dst = read_32(ea); dst |= src; - acc_move_32(cpu, dst); - m68030_write_32(cpu, ea, dst); + ACC.move_32(dst); + write_32(ea, dst); } } // %0000_000011_mmmrrr CMP2/CHK2.B ,Rn OP_DEF(cmp2chk2_b) { - RegIR2 = m68030_fetch_16(cpu); + ir2 = fetch_16(); uint32 compare; - uint32 ea = cea_ctrl(cpu); + uint32 ea = cea_ctrl(); uint32 lower; uint32 upper; - if ((RegIR2 & 0x8000) == 0) { + if ((ir2 & 0x8000) == 0) { // compare が Dn - compare = (int32)(int8)(RegR(RegIR2 >> 12) & 0xff); + compare = (int32)(int8)(reg.R[ir2 >> 12] & 0xff); } else { // compare が An - compare = RegR(RegIR2 >> 12); + compare = reg.R[ir2 >> 12]; } // 本当は PC 相対ならプログラム空間アクセス、 // それ以外はデータ空間アクセスだが、ここでは区別しない。 - lower = (int32)(int8)m68030_read_8(cpu, ea); - upper = (int32)(int8)m68030_read_8(cpu, ea + 1); + lower = (int32)(int8)read_8(ea); + upper = (int32)(int8)read_8(ea + 1); - acc_chk2cmp2_32(cpu, compare, lower, upper); + ACC.chk2cmp2_32(compare, lower, upper); // サイクル数はこれは実際には全部最大値 - if ((RegIR2 & 0x0800)) { + if ((ir2 & 0x0800)) { // CHK2 で条件を満たしていれば例外 - if (RegCondCS) { + if (reg.ccr.CondCS()) { CYCLE2(40, 42); - m68030_exception(cpu, M68K_EXCEP_CHK); + Exception(M68K::EXCEP_CHK); } else { CYCLE(18); } @@ -126,12 +171,12 @@ OP_DEF(cmp2chk2_b) // MOVEP.[WL] (d,Ay),Dx と // MOVEP.[WL] Dx,(d,Ay) の共通部分。 void -ops_movep(m68kcpu *cpu) +MPU680x0Device::ops_movep() { - uint32 disp = (int32)(int16)m68030_fetch_16(cpu); + uint32 disp = (int32)(int16)fetch_16(); uint32 ea = RegAY + disp; - bool size_long = ((RegIR & 0x40) != 0); - bool reg2mem = ((RegIR & 0x80) != 0); + bool size_long = ((ir & 0x40) != 0); + bool reg2mem = ((ir & 0x80) != 0); CYCLE(14); @@ -139,30 +184,30 @@ ops_movep(m68kcpu *cpu) // Dx -> memory uint32 dx = RegDX; if (size_long) { - m68030_write_8(cpu, ea, (dx >> 24)); + write_8(ea, (dx >> 24)); ea += 2; - m68030_write_8(cpu, ea, (dx >> 16) & 0xff); + write_8(ea, (dx >> 16) & 0xff); ea += 2; } - m68030_write_8(cpu, ea, (dx >> 8) & 0xff); + write_8(ea, (dx >> 8) & 0xff); ea += 2; - m68030_write_8(cpu, ea, (dx & 0xff)); + write_8(ea, (dx & 0xff)); } else { // memory -> Dx uint32 dx = 0; if (size_long) { - dx = m68030_read_8(cpu, ea); + dx = read_8(ea); dx <<= 8; ea += 2; - dx |= m68030_read_8(cpu, ea); + dx |= read_8(ea); dx <<= 8; ea += 2; } // word - dx |= m68030_read_8(cpu, ea); + dx |= read_8(ea); dx <<= 8; ea += 2; - dx |= m68030_read_8(cpu, ea); + dx |= read_8(ea); if (size_long) { RegDX = dx; @@ -177,22 +222,22 @@ ops_movep(m68kcpu *cpu) // %0000_xxx100_mmmrrr BTST.B Dx, OP_DEF(btst_dn_ea) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // BTST.L Dx,Dy CYCLE(4); uint bit = (RegDX & 31); - acc_btst(cpu, RegDY, bit); + ACC.btst(RegDY, bit); } else if (n < 16) { // MOVEP.W (d,Ay),Dx - ops_movep(cpu); + ops_movep(); } else { // BTST.B Dx, CYCLE(4); uint bit = (RegDX & 7); - uint32 data = fea_data_8(cpu); - acc_btst(cpu, data, bit); + uint32 data = fea_data_8(); + ACC.btst(data, bit); } } @@ -201,24 +246,24 @@ OP_DEF(btst_dn_ea) // %0000_xxx101_mmmrrr BCHG.B Dx, OP_DEF(bchg_dn_ea) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // BCHG.L Dx,Dy CYCLE(6); uint bit = (RegDX & 31); - RegDY = acc_bchg(cpu, RegDY, bit); + RegDY = ACC.bchg(RegDY, bit); } else if (n < 16) { // MOVEP.L (d,Ay),Dx - ops_movep(cpu); + ops_movep(); } else { // BCHG.B Dx, CYCLE(6); uint bit = (RegDX & 7); - uint32 ea = cea_data_8(cpu); - uint32 data = m68030_read_8(cpu, ea); - data = acc_bchg(cpu, data, bit); - m68030_write_8(cpu, ea, data); + uint32 ea = cea_data_8(); + uint32 data = read_8(ea); + data = ACC.bchg(data, bit); + write_8(ea, data); } } @@ -227,24 +272,24 @@ OP_DEF(bchg_dn_ea) // %0000_xxx110_mmmrrr BCLR.B Dx, OP_DEF(bclr_dn_ea) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // BCLR.L Dx,Dy CYCLE(6); uint bit = (RegDX & 31); - RegDY = acc_bclr(cpu, RegDY, bit); + RegDY = ACC.bclr(RegDY, bit); } else if (n < 16) { // MOVEP.W Dx,(d,Ay) - ops_movep(cpu); + ops_movep(); } else { // BCLR.B Dx, CYCLE(6); uint bit = (RegDX & 7); - uint32 ea = cea_data_8(cpu); - uint32 data = m68030_read_8(cpu, ea); - data = acc_bclr(cpu, data, bit); - m68030_write_8(cpu, ea, data); + uint32 ea = cea_data_8(); + uint32 data = read_8(ea); + data = ACC.bclr(data, bit); + write_8(ea, data); } } @@ -253,24 +298,24 @@ OP_DEF(bclr_dn_ea) // %0000_xxx111_mmmrrr BSET.B Dx, OP_DEF(bset_dn_ea) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // BSET.L Dx,Dy CYCLE(6); uint bit = (RegDX & 31); - RegDY = acc_bset(cpu, RegDY, bit); + RegDY = ACC.bset(RegDY, bit); } else if (n < 16) { // MOVEP.L Dx,(d,Ay) - ops_movep(cpu); + ops_movep(); } else { // BSET.B Dx, CYCLE(6); uint bit = (RegDX & 7); - uint32 ea = cea_data_8(cpu); - uint32 data = m68030_read_8(cpu, ea); - data = acc_bset(cpu, data, bit); - m68030_write_8(cpu, ea, data); + uint32 ea = cea_data_8(); + uint32 data = read_8(ea); + data = ACC.bset(data, bit); + write_8(ea, data); } } @@ -278,16 +323,16 @@ OP_DEF(bset_dn_ea) // %0000_001000_111100 ANDI.B #,CCR OP_DEF(andi_b) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; - uint32 src = m68030_fetch_16(cpu) & 0xff; + uint32 src = fetch_16() & 0xff; if (n < 8) { // ANDI.B #,Dn CYCLE(2); - uint32 dst = RegD(n) & 0xff; + uint32 dst = reg.D[n] & 0xff; dst &= src; - acc_move_8(cpu, dst); - RegD(n) = (RegD(n) & 0xffffff00) | dst; + ACC.move_8(dst); + reg.D[n] = (reg.D[n] & 0xffffff00) | dst; } else if (n == 0b111100) { // ANDI.B #,CCR CYCLE2(12, 14); @@ -295,11 +340,11 @@ OP_DEF(andi_b) } else { // ANDI.B #, CYCLE2(3, 4); - uint32 ea = cea_data_8(cpu); - uint32 dst = m68030_read_8(cpu, ea); + uint32 ea = cea_data_8(); + uint32 dst = read_8(ea); dst &= src; - acc_move_8(cpu, dst); - m68030_write_8(cpu, ea, dst); + ACC.move_8(dst); + write_8(ea, dst); } } @@ -307,86 +352,86 @@ OP_DEF(andi_b) // %0000_001001_111100 ANDI.W #,SR OP_DEF(andi_w) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // ANDI.W #,Dn CYCLE(2); - uint32 src = m68030_fetch_16(cpu); - uint32 dst = RegD(n) & 0xffff; + uint32 src = fetch_16(); + uint32 dst = reg.D[n] & 0xffff; dst &= src; - acc_move_16(cpu, dst); - RegD(n) = (RegD(n) & 0xffff0000) | dst; + ACC.move_16(dst); + reg.D[n] = (reg.D[n] & 0xffff0000) | dst; } else if (n == 0b111100) { // ANDI.W #,SR SUPERVISOR_OP; CYCLE2(12, 14); - uint32 src = m68030_fetch_16(cpu); - m68030_set_sr(cpu, RegSR & src); + uint32 src = fetch_16(); + SetSR(GetSR() & src); } else { // ANDI.W #, CYCLE2(3, 4); - uint32 src = m68030_fetch_16(cpu); - uint32 ea = cea_data_16(cpu); - uint32 dst = m68030_read_16(cpu, ea); + uint32 src = fetch_16(); + uint32 ea = cea_data_16(); + uint32 dst = read_16(ea); dst &= src; - acc_move_16(cpu, dst); - m68030_write_16(cpu, ea, dst); + ACC.move_16(dst); + write_16(ea, dst); } } // %0000_001010_mmmrrr ANDI.L #, OP_DEF(andi_l) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; - uint32 src = m68030_fetch_32(cpu); + uint32 src = fetch_32(); if (n < 8) { // ANDI.L #,Dn CYCLE(2); - RegD(n) &= src; - acc_move_32(cpu, RegD(n)); + reg.D[n] &= src; + ACC.move_32(reg.D[n]); } else { // ANDI.L #, CYCLE2(3, 4); - uint32 ea = cea_data_32(cpu); - uint32 dst = m68030_read_32(cpu, ea); + uint32 ea = cea_data_32(); + uint32 dst = read_32(ea); dst &= src; - acc_move_32(cpu, dst); - m68030_write_32(cpu, ea, dst); + ACC.move_32(dst); + write_32(ea, dst); } } // %0000_001011_mmmrrr CMP2/CHK2.W ,Rn OP_DEF(cmp2chk2_w) { - RegIR2 = m68030_fetch_16(cpu); + ir2 = fetch_16(); uint32 compare; - uint32 ea = cea_ctrl(cpu); + uint32 ea = cea_ctrl(); uint32 lower; uint32 upper; - if ((RegIR2 & 0x8000) == 0) { + if ((ir2 & 0x8000) == 0) { // compare が Dn - compare = (int32)(int16)(RegR(RegIR2 >> 12) & 0xffff); + compare = (int32)(int16)(reg.R[ir2 >> 12] & 0xffff); } else { // compare が An - compare = RegR(RegIR2 >> 12); + compare = reg.R[ir2 >> 12]; } // 本当は PC 相対ならプログラム空間アクセス、 // それ以外はデータ空間アクセスだが、ここでは区別しない。 - lower = (int32)(int16)m68030_read_16(cpu, ea); - upper = (int32)(int16)m68030_read_16(cpu, ea + 2); + lower = (int32)(int16)read_16(ea); + upper = (int32)(int16)read_16(ea + 2); - acc_chk2cmp2_32(cpu, compare, lower, upper); + ACC.chk2cmp2_32(compare, lower, upper); // サイクル数はこれは実際には全部最大値 - if ((RegIR2 & 0x0800)) { + if ((ir2 & 0x0800)) { // CHK2 で条件を満たしていれば例外 - if (RegCondCS) { + if (reg.ccr.CondCS()) { CYCLE2(40, 42); - m68030_exception(cpu, M68K_EXCEP_CHK); + Exception(M68K::EXCEP_CHK); } else { CYCLE(18); } @@ -399,89 +444,89 @@ OP_DEF(cmp2chk2_w) // %0000_010000_mmmrrr SUBI.B #, OP_DEF(subi_b) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; - uint32 src = m68030_fetch_16(cpu) & 0xff; + uint32 src = fetch_16() & 0xff; if (n < 8) { // SUBI.B #,Dn CYCLE(2); - uint32 dst = RegD(n) & 0xff; - dst = acc_sub_8(cpu, src, dst); - RegD(n) = (RegD(n) & 0xffffff00) | dst; + uint32 dst = reg.D[n] & 0xff; + dst = ACC.sub_8(src, dst); + reg.D[n] = (reg.D[n] & 0xffffff00) | dst; } else { // SUBI.B #, CYCLE2(3, 4); - uint32 ea = cea_data_8(cpu); - uint32 dst = m68030_read_8(cpu, ea); - dst = acc_sub_8(cpu, src, dst); - m68030_write_8(cpu, ea, dst); + uint32 ea = cea_data_8(); + uint32 dst = read_8(ea); + dst = ACC.sub_8(src, dst); + write_8(ea, dst); } } // %0000_010001_mmmrrr SUBI.W #, OP_DEF(subi_w) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; - uint32 src = m68030_fetch_16(cpu); + uint32 src = fetch_16(); if (n < 8) { // SUBI.W #,Dn CYCLE(2); - uint32 dst = RegD(n) & 0xffff; - dst = acc_sub_16(cpu, src, dst); - RegD(n) = (RegD(n) & 0xffff0000) | dst; + uint32 dst = reg.D[n] & 0xffff; + dst = ACC.sub_16(src, dst); + reg.D[n] = (reg.D[n] & 0xffff0000) | dst; } else { // SUBI.W #, CYCLE2(3, 4); - uint32 ea = cea_data_16(cpu); - uint32 dst = m68030_read_16(cpu, ea); - dst = acc_sub_16(cpu, src, dst); - m68030_write_16(cpu, ea, dst); + uint32 ea = cea_data_16(); + uint32 dst = read_16(ea); + dst = ACC.sub_16(src, dst); + write_16(ea, dst); } } // %0000_010010_mmmrrr SUBI.L #, OP_DEF(subi_l) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; - uint32 src = m68030_fetch_32(cpu); + uint32 src = fetch_32(); if (n < 8) { // SUBI.L #,Dn CYCLE(2); - RegD(n) = acc_sub_32(cpu, src, RegD(n)); + reg.D[n] = ACC.sub_32(src, reg.D[n]); } else { // SUBI.L #, CYCLE2(3, 4); - uint32 ea = cea_data_32(cpu); - uint32 dst = m68030_read_32(cpu, ea); - dst = acc_sub_32(cpu, src, dst); - m68030_write_32(cpu, ea, dst); + uint32 ea = cea_data_32(); + uint32 dst = read_32(ea); + dst = ACC.sub_32(src, dst); + write_32(ea, dst); } } // %0000_010011_mmmrrr CMP2/CHK2.L ,Rn OP_DEF(cmp2chk2_l) { - RegIR2 = m68030_fetch_16(cpu); - uint32 compare = RegR(RegIR2 >> 12); - uint32 ea = cea_ctrl(cpu); + ir2 = fetch_16(); + uint32 compare = reg.R[ir2 >> 12]; + uint32 ea = cea_ctrl(); uint32 lower; uint32 upper; // 本当は PC 相対ならプログラム空間アクセス、 // それ以外はデータ空間アクセスだが、ここでは区別しない。 - lower = m68030_read_32(cpu, ea); - upper = m68030_read_32(cpu, ea + 4); + lower = read_32(ea); + upper = read_32(ea + 4); - acc_chk2cmp2_32(cpu, compare, lower, upper); + ACC.chk2cmp2_32(compare, lower, upper); // サイクル数はこれは実際には全部最大値 - if ((RegIR2 & 0x0800)) { + if ((ir2 & 0x0800)) { // CHK2 で条件を満たしていれば例外 - if (RegCondCS) { + if (reg.ccr.CondCS()) { CYCLE2(40, 42); - m68030_exception(cpu, M68K_EXCEP_CHK); + Exception(M68K::EXCEP_CHK); } else { CYCLE(18); } @@ -494,87 +539,94 @@ OP_DEF(cmp2chk2_l) // %0000_011000_mmmrrr ADDI.B #, OP_DEF(addi_b) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; - uint32 src = m68030_fetch_16(cpu) & 0xff; + uint32 src = fetch_16() & 0xff; if (n < 8) { // ADDI.B #,Dn CYCLE(2); - uint32 dst = RegD(n) & 0xff; - dst = acc_add_8(cpu, src, dst); - RegD(n) = (RegD(n) & 0xffffff00) | dst; + uint32 dst = reg.D[n] & 0xff; + dst = ACC.add_8(src, dst); + reg.D[n] = (reg.D[n] & 0xffffff00) | dst; } else { // ADDI.B #, CYCLE2(3, 4); - uint32 ea = cea_data_8(cpu); - uint32 dst = m68030_read_8(cpu, ea); - dst = acc_add_8(cpu, src, dst); - m68030_write_8(cpu, ea, dst); + uint32 ea = cea_data_8(); + uint32 dst = read_8(ea); + dst = ACC.add_8(src, dst); + write_8(ea, dst); } } // %0000_011001_mmmrrr ADDI.W #, OP_DEF(addi_w) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; - uint32 src = m68030_fetch_16(cpu); + uint32 src = fetch_16(); if (n < 8) { // ADDI.W #,Dn CYCLE(2); - uint32 dst = RegD(n) & 0xffff; - dst = acc_add_16(cpu, src, dst); - RegD(n) = (RegD(n) & 0xffff0000) | dst; + uint32 dst = reg.D[n] & 0xffff; + dst = ACC.add_16(src, dst); + reg.D[n] = (reg.D[n] & 0xffff0000) | dst; } else { // ADDI.W #, CYCLE2(3, 4); - uint32 ea = cea_data_16(cpu); - uint32 dst = m68030_read_16(cpu, ea); - dst = acc_add_16(cpu, src, dst); - m68030_write_16(cpu, ea, dst); + uint32 ea = cea_data_16(); + uint32 dst = read_16(ea); + dst = ACC.add_16(src, dst); + write_16(ea, dst); } } // %0000_011010_mmmrrr ADDI.L #, OP_DEF(addi_l) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; - uint32 src = m68030_fetch_32(cpu); + uint32 src = fetch_32(); if (n < 8) { // ADDI.L #,Dn CYCLE(2); - RegD(n) = acc_add_32(cpu, src, RegD(n)); + reg.D[n] = ACC.add_32(src, reg.D[n]); } else { // ADDI.L #, CYCLE2(3, 4); - uint32 ea = cea_data_32(cpu); - uint32 dst = m68030_read_32(cpu, ea); - dst = acc_add_32(cpu, src, dst); - m68030_write_32(cpu, ea, dst); + uint32 ea = cea_data_32(); + uint32 dst = read_32(ea); + dst = ACC.add_32(src, dst); + write_32(ea, dst); } } +// %0000_011011_00nnnn RTM Rn +// %0000_011011_mmmrrr CALLM #, +OP_DEF(callm) +{ + op_illegal(); +} + // %0000_100000_000yyy BTST.L #,Dy // %0000_100000_mmmrrr BTST.B #, OP_DEF(btst_imm_ea) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // BTST.L #,Dy CYCLE(4); - uint bit = m68030_fetch_16(cpu) & 31; - acc_btst(cpu, RegDY, bit); + uint bit = fetch_16() & 31; + ACC.btst(RegDY, bit); } else if (n == 0x3c) { // BTST.B #, には #imm はない - op_illegal(cpu); + op_illegal(); } else { // BTST.B #, CYCLE(4); - uint bit = m68030_fetch_16(cpu) & 7; - uint32 data = fea_data_8(cpu); - acc_btst(cpu, data, bit); + uint bit = fetch_16() & 7; + uint32 data = fea_data_8(); + ACC.btst(data, bit); } } @@ -582,24 +634,24 @@ OP_DEF(btst_imm_ea) // %0000_100001_mmmrrr BCHG.B #, OP_DEF(bchg_imm_ea) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // BCHG.L #,Dy CYCLE(6); - uint bit = m68030_fetch_16(cpu) & 31; - RegDY = acc_bchg(cpu, RegDY, bit); + uint bit = fetch_16() & 31; + RegDY = ACC.bchg(RegDY, bit); } else if (n == 0x3c) { // BCHG.B #, には #imm はない - op_illegal(cpu); + op_illegal(); } else { // BCHG.B #, CYCLE(6); - uint bit = m68030_fetch_16(cpu) & 7; - uint32 ea = cea_data_8(cpu); - uint32 data = m68030_read_8(cpu, ea); - data = acc_bchg(cpu, data, bit); - m68030_write_8(cpu, ea, data); + uint bit = fetch_16() & 7; + uint32 ea = cea_data_8(); + uint32 data = read_8(ea); + data = ACC.bchg(data, bit); + write_8(ea, data); } } @@ -607,24 +659,24 @@ OP_DEF(bchg_imm_ea) // %0000_100010_mmmrrr BCLR.B #, OP_DEF(bclr_imm_ea) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // BCLR.L #,Dy CYCLE(6); - uint bit = m68030_fetch_16(cpu) & 31; - RegDY = acc_bclr(cpu, RegDY, bit); + uint bit = fetch_16() & 31; + RegDY = ACC.bclr(RegDY, bit); } else if (n == 0x3c) { // BCLR.B #, には #imm はない - op_illegal(cpu); + op_illegal(); } else { // BCLR.B #, CYCLE(6); - uint bit = m68030_fetch_16(cpu) & 7; - uint32 ea = cea_data_8(cpu); - uint32 data = m68030_read_8(cpu, ea); - data = acc_bclr(cpu, data, bit); - m68030_write_8(cpu, ea, data); + uint bit = fetch_16() & 7; + uint32 ea = cea_data_8(); + uint32 data = read_8(ea); + data = ACC.bclr(data, bit); + write_8(ea, data); } } @@ -632,24 +684,24 @@ OP_DEF(bclr_imm_ea) // %0000_100011_mmmrrr BSET.B #, OP_DEF(bset_imm_ea) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // BSET.L #,Dy CYCLE(6); - uint bit = m68030_fetch_16(cpu) & 31; - RegDY = acc_bset(cpu, RegDY, bit); + uint bit = fetch_16() & 31; + RegDY = ACC.bset(RegDY, bit); } else if (n == 0x3c) { // BSET.B #, には #imm はない - op_illegal(cpu); + op_illegal(); } else { // BSET.B #, CYCLE(6); - uint bit = m68030_fetch_16(cpu) & 7; - uint32 ea = cea_data_8(cpu); - uint32 data = m68030_read_8(cpu, ea); - data = acc_bset(cpu, data, bit); - m68030_write_8(cpu, ea, data); + uint bit = fetch_16() & 7; + uint32 ea = cea_data_8(); + uint32 data = read_8(ea); + data = ACC.bset(data, bit); + write_8(ea, data); } } @@ -657,15 +709,15 @@ OP_DEF(bset_imm_ea) // %0000_101000_111100 EORI.B #,CCR OP_DEF(eori_b) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; - uint32 src = m68030_fetch_16(cpu) & 0xff; + uint32 src = fetch_16() & 0xff; if (n < 8) { // EORI.B #,Dn CYCLE(2); - uint32 dst = (RegD(n) & 0xff) ^ src; - acc_move_8(cpu, dst); - RegD(n) = (RegD(n) & 0xffffff00) | dst; + uint32 dst = (reg.D[n] & 0xff) ^ src; + ACC.move_8(dst); + reg.D[n] = (reg.D[n] & 0xffffff00) | dst; } else if (n == 0b111100) { // EORI.B #,SR CYCLE2(12, 14); @@ -673,11 +725,11 @@ OP_DEF(eori_b) } else { // EORI.B #, CYCLE2(3, 4); - uint32 ea = cea_data_8(cpu); - uint32 dst = m68030_read_8(cpu, ea); + uint32 ea = cea_data_8(); + uint32 dst = read_8(ea); dst ^= src; - acc_move_8(cpu, dst); - m68030_write_8(cpu, ea, dst); + ACC.move_8(dst); + write_8(ea, dst); } } @@ -685,184 +737,184 @@ OP_DEF(eori_b) // %0000_101001_111100 EORI.W #,SR OP_DEF(eori_w) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // EORI.W #,Dn CYCLE(2); - uint32 src = m68030_fetch_16(cpu); - uint32 dst = (RegD(n) & 0xffff) ^ src; - acc_move_16(cpu, dst); - RegD(n) = (RegD(n) & 0xffff0000) | dst; + uint32 src = fetch_16(); + uint32 dst = (reg.D[n] & 0xffff) ^ src; + ACC.move_16(dst); + reg.D[n] = (reg.D[n] & 0xffff0000) | dst; } else if (n == 0b111100) { // EORI.W #,SR SUPERVISOR_OP; CYCLE2(12, 14); - uint32 src = m68030_fetch_16(cpu); - m68030_set_sr(cpu, RegSR ^ src); + uint32 src = fetch_16(); + SetSR(GetSR() ^ src); } else { // EORI.W #, CYCLE2(3, 4); - uint32 src = m68030_fetch_16(cpu); - uint32 ea = cea_data_16(cpu); - uint32 dst = m68030_read_16(cpu, ea); + uint32 src = fetch_16(); + uint32 ea = cea_data_16(); + uint32 dst = read_16(ea); dst ^= src; - acc_move_16(cpu, dst); - m68030_write_16(cpu, ea, dst); + ACC.move_16(dst); + write_16(ea, dst); } } // %0000_101010_mmmrrr EORI.L #, OP_DEF(eori_l) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; - uint32 src = m68030_fetch_32(cpu); + uint32 src = fetch_32(); if (n < 8) { // EORI.L #,Dn CYCLE(2); - RegD(n) ^= src; - acc_move_32(cpu, RegD(n)); + reg.D[n] ^= src; + ACC.move_32(reg.D[n]); } else { // EORI.L #, CYCLE2(3, 4); - uint32 ea = cea_data_32(cpu); - uint32 dst = m68030_read_32(cpu, ea); + uint32 ea = cea_data_32(); + uint32 dst = read_32(ea); dst ^= src; - acc_move_32(cpu, dst); - m68030_write_32(cpu, ea, dst); + ACC.move_32(dst); + write_32(ea, dst); } } // %0000_101011_mmmrrr CAS.B Dc,Du, OP_DEF(cas_b) { - RegIR2 = m68030_fetch_16(cpu); - uint c = RegIR2 & 7; - uint u = (RegIR2 >> 6) & 7; - uint32 dc = RegD(c) & 0xff; - uint32 du = RegD(u) & 0xff; - uint ea = cea_data_8(cpu); - uint32 dst = m68030_read_8(cpu, ea); + ir2 = fetch_16(); + uint c = ir2 & 7; + uint u = (ir2 >> 6) & 7; + uint32 dc = reg.D[c] & 0xff; + uint32 du = reg.D[u] & 0xff; + uint ea = cea_data_8(); + uint32 dst = read_8(ea); - acc_cmp_8(cpu, dc, dst); + ACC.cmp_8(dc, dst); if (CCR.IsZ()) { // 等しければ、Du -> dst CYCLE(13); - m68030_write_8(cpu, ea, du); + write_8(ea, du); } else { // そうでなければ、dst -> Dc CYCLE(11); - RegD(c) = (RegD(c) & 0xffffff00) | dst; + reg.D[c] = (reg.D[c] & 0xffffff00) | dst; } } // %0000_110000_mmmrrr CMPI.B #, OP_DEF(cmpi_b) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; // CMPI はデータアドレッシングだが #imm がないことに注意 if (n == 0x3c) { - op_illegal(cpu); + op_illegal(); return; } CYCLE(2); - uint32 src = m68030_fetch_16(cpu) & 0xff; - uint32 dst = fea_data_8(cpu); - acc_cmp_8(cpu, src, dst); + uint32 src = fetch_16() & 0xff; + uint32 dst = fea_data_8(); + ACC.cmp_8(src, dst); } // %0000_110001_mmmrrr CMPI.W #, OP_DEF(cmpi_w) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; // CMPI はデータアドレッシングだが #imm がないことに注意 if (n == 0x3c) { - op_illegal(cpu); + op_illegal(); return; } CYCLE(2); - uint32 src = m68030_fetch_16(cpu); - uint32 dst = fea_data_16(cpu); - acc_cmp_16(cpu, src, dst); + uint32 src = fetch_16(); + uint32 dst = fea_data_16(); + ACC.cmp_16(src, dst); } // %0000_110010_mmmrrr CMPI.L #, OP_DEF(cmpi_l) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; // CMPI はデータアドレッシングだが #imm がないことに注意 if (n == 0x3c) { - op_illegal(cpu); + op_illegal(); return; } CYCLE(2); - uint32 src = m68030_fetch_32(cpu); - uint32 dst = fea_data_32(cpu); - acc_cmp_32(cpu, src, dst); + uint32 src = fetch_32(); + uint32 dst = fea_data_32(); + ACC.cmp_32(src, dst); } // %0000_110011_mmmrrr CAS.W Dc,Du, // %0000_110011_111100 CAS2.W Dc1:Dc2,Du1:Du2,(Rn1):(Rn2) OP_DEF(cas_w) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n == 0x3c) { // CAS2.W Dc1:Dc2,Du1:Du2,(Rn1):(Rn2) - RegIR2 = m68030_fetch_16(cpu); - uint32 ir3 = m68030_fetch_16(cpu); - uint c1 = RegIR2 & 7; - uint u1 = (RegIR2 >> 6) & 7; - uint r1 = RegIR2 >> 12; + ir2 = fetch_16(); + uint32 ir3 = fetch_16(); + uint c1 = ir2 & 7; + uint u1 = (ir2 >> 6) & 7; + uint r1 = ir2 >> 12; uint c2 = ir3 & 7; uint u2 = (ir3 >> 6) & 7; uint r2 = ir3 >> 12; - uint32 dc1 = RegD(c1) & 0xffff; - uint32 du1 = RegD(u1) & 0xffff; - uint32 ea1 = RegR(r1); - uint32 dc2 = RegD(c2) & 0xffff; - uint32 du2 = RegD(u2) & 0xffff; - uint32 ea2 = RegR(r2); - - uint32 dst1 = m68030_read_16(cpu, ea1); - uint32 dst2 = m68030_read_16(cpu, ea2); - acc_cmp_16(cpu, dc1, dst1); + uint32 dc1 = reg.D[c1] & 0xffff; + uint32 du1 = reg.D[u1] & 0xffff; + uint32 ea1 = reg.R[r1]; + uint32 dc2 = reg.D[c2] & 0xffff; + uint32 du2 = reg.D[u2] & 0xffff; + uint32 ea2 = reg.R[r2]; + + uint32 dst1 = read_16(ea1); + uint32 dst2 = read_16(ea2); + ACC.cmp_16(dc1, dst1); if (CCR.IsZ()) { - acc_cmp_16(cpu, dc2, dst2); + ACC.cmp_16(dc2, dst2); if (CCR.IsZ()) { // 更新オペランド -> デスティネーション CYCLE2(0, 2); // これは成功時の追加分 - m68030_write_16(cpu, ea1, du1); - m68030_write_16(cpu, ea2, du2); + write_16(ea1, du1); + write_16(ea2, du2); } } // デスティネーション -> 比較オペランド CYCLE(24); // 本当はこれは最大値 - RegD(c1) = (RegD(c1) & 0xffff0000) | dst1; - RegD(c2) = (RegD(c2) & 0xffff0000) | dst2; + reg.D[c1] = (reg.D[c1] & 0xffff0000) | dst1; + reg.D[c2] = (reg.D[c2] & 0xffff0000) | dst2; } else { // CAS.W Dc,Du, - RegIR2 = m68030_fetch_16(cpu); - uint c = RegIR2 & 7; - uint u = (RegIR2 >> 6) & 7; - uint32 dc = RegD(c) & 0xffff; - uint32 du = RegD(u) & 0xffff; - uint ea = cea_data_16(cpu); - uint32 dst = m68030_read_16(cpu, ea); + ir2 = fetch_16(); + uint c = ir2 & 7; + uint u = (ir2 >> 6) & 7; + uint32 dc = reg.D[c] & 0xffff; + uint32 du = reg.D[u] & 0xffff; + uint ea = cea_data_16(); + uint32 dst = read_16(ea); - acc_cmp_16(cpu, dc, dst); + ACC.cmp_16(dc, dst); if (CCR.IsZ()) { // 等しければ、Du -> dst CYCLE(13); - m68030_write_16(cpu, ea, du); + write_16(ea, du); } else { // そうでなければ、dst -> Dc CYCLE(11); - RegD(c) = (RegD(c) & 0xffff0000) | dst; + reg.D[c] = (reg.D[c] & 0xffff0000) | dst; } } } @@ -873,31 +925,31 @@ OP_DEF(moves_b) { SUPERVISOR_OP; - RegIR2 = m68030_fetch_16(cpu); - uint n = RegIR2 >> 12; + ir2 = fetch_16(); + uint n = ir2 >> 12; uint ea; uint32 data; - if ((RegIR & 0x3f) < 16) { - op_illegal(cpu); + if ((ir & 0x3f) < 16) { + op_illegal(); return; } - ea = cea_data_8(cpu); - if ((RegIR2 & 0x0800) == 0) { + ea = cea_data_8(); + if ((ir2 & 0x0800) == 0) { // ,Rn CYCLE(7); - data = m68030_read_8_fc(cpu, ea); + data = read_8_fc(ea); if (n < 8) { // Dn - RegD(n) = (RegD(n) & 0xffffff00) | data; + reg.D[n] = (reg.D[n] & 0xffffff00) | data; } else { // An - RegR(n) = (int32)(int8)data; + reg.R[n] = (int32)(int8)data; } } else { // Rn, CYCLE2(5, 6); - data = RegR(n) & 0xff; - m68030_write_8_fc(cpu, ea, data); + data = reg.R[n] & 0xff; + write_8_fc(ea, data); } } @@ -907,31 +959,31 @@ OP_DEF(moves_w) { SUPERVISOR_OP; - RegIR2 = m68030_fetch_16(cpu); - uint n = RegIR2 >> 12; + ir2 = fetch_16(); + uint n = ir2 >> 12; uint ea; uint32 data; - if ((RegIR & 0x3f) < 16) { - op_illegal(cpu); + if ((ir & 0x3f) < 16) { + op_illegal(); return; } - ea = cea_data_16(cpu); - if ((RegIR2 & 0x0800) == 0) { + ea = cea_data_16(); + if ((ir2 & 0x0800) == 0) { // ,Rn CYCLE(7); - data = m68030_read_16_fc(cpu, ea); + data = read_16_fc(ea); if (n < 8) { // Dn - RegD(n) = (RegD(n) & 0xffff0000) | data; + reg.D[n] = (reg.D[n] & 0xffff0000) | data; } else { // An - RegR(n) = (int32)(int16)data; + reg.R[n] = (int32)(int16)data; } } else { // Rn, CYCLE2(5, 6); - data = RegR(n) & 0xffff; - m68030_write_16_fc(cpu, ea, data); + data = reg.R[n] & 0xffff; + write_16_fc(ea, data); } } @@ -941,27 +993,27 @@ OP_DEF(moves_l) { SUPERVISOR_OP; - RegIR2 = m68030_fetch_16(cpu); - uint n = RegIR2 >> 12; + ir2 = fetch_16(); + uint n = ir2 >> 12; uint ea; uint32 data; - if ((RegIR & 0x3f) < 16) { - op_illegal(cpu); + if ((ir & 0x3f) < 16) { + op_illegal(); return; } - ea = cea_data_32(cpu); - if ((RegIR2 & 0x0800) == 0) { + ea = cea_data_32(); + if ((ir2 & 0x0800) == 0) { // ,Rn CYCLE(7); - data = m68030_read_32_fc(cpu, ea); - RegR(n) = data; + data = read_32_fc(ea); + reg.R[n] = data; } else { // Rn, CYCLE2(5, 6); - data = RegR(n); - m68030_write_32_fc(cpu, ea, data); + data = reg.R[n]; + write_32_fc(ea, data); } } @@ -969,60 +1021,60 @@ OP_DEF(moves_l) // %0000_111011_111100 CAS2.L Dc1:Dc2,Du1:Du2,(Rn1):(Rn2) OP_DEF(cas_l) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n == 0x3c) { // CAS2.L Dc1:Dc2,Du1:Du2,(Rn1):(Rn2) - RegIR2 = m68030_fetch_16(cpu); - uint32 ir3 = m68030_fetch_16(cpu); - uint c1 = RegIR2 & 7; - uint u1 = (RegIR2 >> 6) & 7; - uint r1 = RegIR2 >> 12; + ir2 = fetch_16(); + uint32 ir3 = fetch_16(); + uint c1 = ir2 & 7; + uint u1 = (ir2 >> 6) & 7; + uint r1 = ir2 >> 12; uint c2 = ir3 & 7; uint u2 = (ir3 >> 6) & 7; uint r2 = ir3 >> 12; - uint32 dc1 = RegD(c1); - uint32 du1 = RegD(u1); - uint32 ea1 = RegR(r1); - uint32 dc2 = RegD(c2); - uint32 du2 = RegD(u2); - uint32 ea2 = RegR(r2); - - uint32 dst1 = m68030_read_32(cpu, ea1); - uint32 dst2 = m68030_read_32(cpu, ea2); - acc_cmp_32(cpu, dc1, dst1); + uint32 dc1 = reg.D[c1]; + uint32 du1 = reg.D[u1]; + uint32 ea1 = reg.R[r1]; + uint32 dc2 = reg.D[c2]; + uint32 du2 = reg.D[u2]; + uint32 ea2 = reg.R[r2]; + + uint32 dst1 = read_32(ea1); + uint32 dst2 = read_32(ea2); + ACC.cmp_32(dc1, dst1); if (CCR.IsZ()) { - acc_cmp_32(cpu, dc2, dst2); + ACC.cmp_32(dc2, dst2); if (CCR.IsZ()) { // 更新オペランド -> デスティネーション CYCLE2(0, 2); // これは成功時の追加分 - m68030_write_32(cpu, ea1, du1); - m68030_write_32(cpu, ea2, du2); + write_32(ea1, du1); + write_32(ea2, du2); } } // デスティネーション -> 比較オペランド CYCLE(24); // 本当はこれは最大値 - RegD(c1) = dst1; - RegD(c2) = dst2; + reg.D[c1] = dst1; + reg.D[c2] = dst2; } else { // CAS.L Dc,Du, - RegIR2 = m68030_fetch_16(cpu); - uint c = RegIR2 & 7; - uint u = (RegIR2 >> 6) & 7; - uint32 dc = RegD(c); - uint32 du = RegD(u); - uint ea = cea_data_32(cpu); - uint32 dst = m68030_read_32(cpu, ea); + ir2 = fetch_16(); + uint c = ir2 & 7; + uint u = (ir2 >> 6) & 7; + uint32 dc = reg.D[c]; + uint32 du = reg.D[u]; + uint ea = cea_data_32(); + uint32 dst = read_32(ea); - acc_cmp_32(cpu, dc, dst); + ACC.cmp_32(dc, dst); if (CCR.IsZ()) { // 等しければ、Du -> dst CYCLE(13); - m68030_write_32(cpu, ea, du); + write_32(ea, du); } else { // そうでなければ、dst -> Dc CYCLE(11); - RegD(c) = dst; + reg.D[c] = dst; } } } @@ -1031,8 +1083,8 @@ OP_DEF(cas_l) OP_DEF(move_b_ea_dn) { CYCLE(2); - uint32 data = fea_all_8(cpu); - acc_move_8(cpu, data); + uint32 data = fea_all_8(); + ACC.move_8(data); RegDX = (RegDX & 0xffffff00) | data; } @@ -1041,10 +1093,10 @@ OP_DEF(move_b_ea_anin) { // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5) CYCLE2(4, 5); - uint32 data = fea_all_8(cpu); - uint32 ea = cea_anin(cpu, RegIRX); - acc_move_8(cpu, data); - m68030_write_8(cpu, ea, data); + uint32 data = fea_all_8(); + uint32 ea = cea_anin(RegIRX); + ACC.move_8(data); + write_8(ea, data); } // %0001_xxx011_mmmrrr MOVE.B ,(Ax)+ @@ -1052,10 +1104,10 @@ OP_DEF(move_b_ea_anpi) { // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5) CYCLE2(4, 5); - uint32 data = fea_all_8(cpu); - uint32 ea = cea_anpi_8(cpu, RegIRX); - acc_move_8(cpu, data); - m68030_write_8(cpu, ea, data); + uint32 data = fea_all_8(); + uint32 ea = cea_anpi_8(RegIRX); + ACC.move_8(data); + write_8(ea, data); } // %0001_xxx100_mmmrrr MOVE.B ,-(Ax) @@ -1063,20 +1115,20 @@ OP_DEF(move_b_ea_anpd) { // 実際にはソースがレジスタなら (4, 4)、メモリなら (4, 5) CYCLE2(4, 5); - uint32 data = fea_all_8(cpu); - uint32 ea = cea_anpd_8(cpu, RegIRX); - acc_move_8(cpu, data); - m68030_write_8(cpu, ea, data); + uint32 data = fea_all_8(); + uint32 ea = cea_anpd_8(RegIRX); + ACC.move_8(data); + write_8(ea, data); } // %0001_xxx101_mmmrrr MOVE.B ,d16(Ax) OP_DEF(move_b_ea_andi) { CYCLE2(4, 5); - uint32 data = fea_all_8(cpu); - uint32 ea = cea_andi(cpu, RegIRX); - acc_move_8(cpu, data); - m68030_write_8(cpu, ea, data); + uint32 data = fea_all_8(); + uint32 ea = cea_andi(RegIRX); + ACC.move_8(data); + write_8(ea, data); } // %0001_xxx110_mmmrrr MOVE.B ,(Ax,IX) @@ -1084,38 +1136,38 @@ OP_DEF(move_b_ea_anix) { // XXX 実際にはdstのフォーマットによって(8,9)-(20,23) CYCLE2(16, 18); - uint32 data = fea_all_8(cpu); - uint32 ea = cea_anix(cpu, RegIRX); - acc_move_8(cpu, data); - m68030_write_8(cpu, ea, data); + uint32 data = fea_all_8(); + uint32 ea = cea_anix(RegIRX); + ACC.move_8(data); + write_8(ea, data); } // %0001_000111_mmmrrr MOVE.B ,Abs.W OP_DEF(move_b_ea_absw) { CYCLE2(4, 5); - uint32 data = fea_all_8(cpu); - uint32 ea = cea_absw(cpu); - acc_move_8(cpu, data); - m68030_write_8(cpu, ea, data); + uint32 data = fea_all_8(); + uint32 ea = cea_absw(); + ACC.move_8(data); + write_8(ea, data); } // %0001_001111_mmmrrr MOVE.B ,Abs.L OP_DEF(move_b_ea_absl) { CYCLE2(6, 7); - uint32 data = fea_all_8(cpu); - uint32 ea = cea_absl(cpu); - acc_move_8(cpu, data); - m68030_write_8(cpu, ea, data); + uint32 data = fea_all_8(); + uint32 ea = cea_absl(); + ACC.move_8(data); + write_8(ea, data); } // %0010_xxx000_mmmrrr MOVE.L ,Dx OP_DEF(move_l_ea_dn) { CYCLE(2); - uint32 data = fea_all_32(cpu); - acc_move_32(cpu, data); + uint32 data = fea_all_32(); + ACC.move_32(data); RegDX = data; } @@ -1123,7 +1175,7 @@ OP_DEF(move_l_ea_dn) OP_DEF(movea_l) { CYCLE(2); - uint32 data = fea_all_32(cpu); + uint32 data = fea_all_32(); RegAX = data; } @@ -1132,10 +1184,10 @@ OP_DEF(move_l_ea_anin) { // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5) CYCLE2(4, 5); - uint32 data = fea_all_32(cpu); - uint32 ea = cea_anin(cpu, RegIRX); - acc_move_32(cpu, data); - m68030_write_32(cpu, ea, data); + uint32 data = fea_all_32(); + uint32 ea = cea_anin(RegIRX); + ACC.move_32(data); + write_32(ea, data); } // %0010_xxx011_mmmrrr MOVE.L ,(Ax)+ @@ -1143,10 +1195,10 @@ OP_DEF(move_l_ea_anpi) { // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5) CYCLE2(4, 5); - uint32 data = fea_all_32(cpu); - uint32 ea = cea_anpi_32(cpu, RegIRX); - acc_move_32(cpu, data); - m68030_write_32(cpu, ea, data); + uint32 data = fea_all_32(); + uint32 ea = cea_anpi_32(RegIRX); + ACC.move_32(data); + write_32(ea, data); } // %0010_xxx100_mmmrrr MOVE.L ,-(Ax) @@ -1154,20 +1206,20 @@ OP_DEF(move_l_ea_anpd) { // 実際にはソースがレジスタなら (4, 4)、メモリなら (4, 5) CYCLE2(4, 5); - uint32 data = fea_all_32(cpu); - uint32 ea = cea_anpd_32(cpu, RegIRX); - acc_move_32(cpu, data); - m68030_write_32(cpu, ea, data); + uint32 data = fea_all_32(); + uint32 ea = cea_anpd_32(RegIRX); + ACC.move_32(data); + write_32(ea, data); } // %0010_xxx101_mmmrrr MOVE.L ,d16(Ax) OP_DEF(move_l_ea_andi) { CYCLE2(4, 5); - uint32 data = fea_all_32(cpu); - uint32 ea = cea_andi(cpu, RegIRX); - acc_move_32(cpu, data); - m68030_write_32(cpu, ea, data); + uint32 data = fea_all_32(); + uint32 ea = cea_andi(RegIRX); + ACC.move_32(data); + write_32(ea, data); } // %0010_xxx110_mmmrrr MOVE.L ,(Ax,IX) @@ -1175,38 +1227,38 @@ OP_DEF(move_l_ea_anix) { // XXX 実際にはdstのフォーマットによって(8,9)-(20,23) CYCLE2(16, 18); - uint32 data = fea_all_32(cpu); - uint32 ea = cea_anix(cpu, RegIRX); - acc_move_32(cpu, data); - m68030_write_32(cpu, ea, data); + uint32 data = fea_all_32(); + uint32 ea = cea_anix(RegIRX); + ACC.move_32(data); + write_32(ea, data); } // %0010_000111_mmmrrr MOVE.L ,Abs.W OP_DEF(move_l_ea_absw) { CYCLE2(4, 5); - uint32 data = fea_all_32(cpu); - uint32 ea = cea_absw(cpu); - acc_move_32(cpu, data); - m68030_write_32(cpu, ea, data); + uint32 data = fea_all_32(); + uint32 ea = cea_absw(); + ACC.move_32(data); + write_32(ea, data); } // %0010_001111_mmmrrr MOVE.L ,Abs.L OP_DEF(move_l_ea_absl) { CYCLE2(6, 7); - uint32 data = fea_all_32(cpu); - uint32 ea = cea_absl(cpu); - acc_move_32(cpu, data); - m68030_write_32(cpu, ea, data); + uint32 data = fea_all_32(); + uint32 ea = cea_absl(); + ACC.move_32(data); + write_32(ea, data); } // %0011_xxx000_mmmrrr MOVE.W ,Dx OP_DEF(move_w_ea_dn) { CYCLE(2); - uint32 data = fea_all_16(cpu); - acc_move_16(cpu, data); + uint32 data = fea_all_16(); + ACC.move_16(data); RegDX = (RegDX & 0xffff0000) | data; } @@ -1214,7 +1266,7 @@ OP_DEF(move_w_ea_dn) OP_DEF(movea_w) { CYCLE(2); - uint32 data = (int32)(int16)fea_all_16(cpu); + uint32 data = (int32)(int16)fea_all_16(); RegAX = data; } @@ -1223,10 +1275,10 @@ OP_DEF(move_w_ea_anin) { // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5) CYCLE2(4, 5); - uint32 data = fea_all_16(cpu); - uint32 ea = cea_anin(cpu, RegIRX); - acc_move_16(cpu, data); - m68030_write_16(cpu, ea, data); + uint32 data = fea_all_16(); + uint32 ea = cea_anin(RegIRX); + ACC.move_16(data); + write_16(ea, data); } // %0011_xxx011_mmmrrr MOVE.W ,(Ax)+ @@ -1234,10 +1286,10 @@ OP_DEF(move_w_ea_anpi) { // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5) CYCLE2(4, 5); - uint32 data = fea_all_16(cpu); - uint32 ea = cea_anpi_16(cpu, RegIRX); - acc_move_16(cpu, data); - m68030_write_16(cpu, ea, data); + uint32 data = fea_all_16(); + uint32 ea = cea_anpi_16(RegIRX); + ACC.move_16(data); + write_16(ea, data); } // %0011_xxx100_mmmrrr MOVE.W ,-(Ax) @@ -1245,20 +1297,20 @@ OP_DEF(move_w_ea_anpd) { // 実際にはソースがレジスタなら (4, 4)、メモリなら (4, 5) CYCLE2(4, 5); - uint32 data = fea_all_16(cpu); - uint32 ea = cea_anpd_16(cpu, RegIRX); - acc_move_16(cpu, data); - m68030_write_16(cpu, ea, data); + uint32 data = fea_all_16(); + uint32 ea = cea_anpd_16(RegIRX); + ACC.move_16(data); + write_16(ea, data); } // %0011_xxx101_mmmrrr MOVE.W ,d16(Ax) OP_DEF(move_w_ea_andi) { CYCLE2(4, 5); - uint32 data = fea_all_16(cpu); - uint32 ea = cea_andi(cpu, RegIRX); - acc_move_16(cpu, data); - m68030_write_16(cpu, ea, data); + uint32 data = fea_all_16(); + uint32 ea = cea_andi(RegIRX); + ACC.move_16(data); + write_16(ea, data); } // %0011_xxx110_mmmrrr MOVE.W ,(Ax,IX) @@ -1266,96 +1318,96 @@ OP_DEF(move_w_ea_anix) { // XXX 実際にはdstのフォーマットによって(8,9)-(20,23) CYCLE2(16, 18); - uint32 data = fea_all_16(cpu); - uint32 ea = cea_anix(cpu, RegIRX); - acc_move_16(cpu, data); - m68030_write_16(cpu, ea, data); + uint32 data = fea_all_16(); + uint32 ea = cea_anix(RegIRX); + ACC.move_16(data); + write_16(ea, data); } // %0011_000111_mmmrrr MOVE.W ,Abs.W OP_DEF(move_w_ea_absw) { CYCLE2(4, 5); - uint32 data = fea_all_16(cpu); - uint32 ea = cea_absw(cpu); - acc_move_16(cpu, data); - m68030_write_16(cpu, ea, data); + uint32 data = fea_all_16(); + uint32 ea = cea_absw(); + ACC.move_16(data); + write_16(ea, data); } // %0011_001111_mmmrrr MOVE.W ,Abs.L OP_DEF(move_w_ea_absl) { CYCLE2(6, 7); - uint32 data = fea_all_16(cpu); - uint32 ea = cea_absl(cpu); - acc_move_16(cpu, data); - m68030_write_16(cpu, ea, data); + uint32 data = fea_all_16(); + uint32 ea = cea_absl(); + ACC.move_16(data); + write_16(ea, data); } // %0100_000000_mmmrrr NEGX.B OP_DEF(negx_b) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // NEGX.B Dn CYCLE(2); - uint32 data = RegD(n) & 0xff; - data = acc_subx_8(cpu, data, 0); - RegD(n) = (RegD(n) & 0xffffff00) | data; + uint32 data = reg.D[n] & 0xff; + data = ACC.subx_8(data, 0); + reg.D[n] = (reg.D[n] & 0xffffff00) | data; } else if (n < 16) { - op_illegal(cpu); + op_illegal(); } else { // NEGX.B CYCLE2(3, 4); - uint32 ea = cea_data_8(cpu); - uint32 data = m68030_read_8(cpu, ea); - data = acc_subx_8(cpu, data, 0); - m68030_write_8(cpu, ea, data); + uint32 ea = cea_data_8(); + uint32 data = read_8(ea); + data = ACC.subx_8(data, 0); + write_8(ea, data); } } // %0100_000001_mmmrrr NEGX.W OP_DEF(negx_w) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // NEGX.W Dn CYCLE(2); - uint32 data = RegD(n) & 0xffff; - data = acc_subx_16(cpu, data, 0); - RegD(n) = (RegD(n) & 0xffff0000) | data; + uint32 data = reg.D[n] & 0xffff; + data = ACC.subx_16(data, 0); + reg.D[n] = (reg.D[n] & 0xffff0000) | data; } else if (n < 16) { - op_illegal(cpu); + op_illegal(); } else { // NEGX.W CYCLE2(3, 4); - uint32 ea = cea_data_16(cpu); - uint32 data = m68030_read_16(cpu, ea); - data = acc_subx_16(cpu, data, 0); - m68030_write_16(cpu, ea, data); + uint32 ea = cea_data_16(); + uint32 data = read_16(ea); + data = ACC.subx_16(data, 0); + write_16(ea, data); } } // %0100_000010_mmmrrr NEGX.L OP_DEF(negx_l) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // NEGX.L Dn CYCLE(2); - RegD(n) = acc_subx_32(cpu, RegD(n), 0); + reg.D[n] = ACC.subx_32(reg.D[n], 0); } else if (n < 16) { - op_illegal(cpu); + op_illegal(); } else { // NEGX.L CYCLE2(3, 4); - uint32 ea = cea_data_32(cpu); - uint32 data = m68030_read_32(cpu, ea); - data = acc_subx_32(cpu, data, 0); - m68030_write_32(cpu, ea, data); + uint32 ea = cea_data_32(); + uint32 data = read_32(ea); + data = ACC.subx_32(data, 0); + write_32(ea, data); } } @@ -1364,16 +1416,16 @@ OP_DEF(move_sr_ea) { SUPERVISOR_OP; - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // MOVE.W SR,Dn CYCLE(4); - RegD(n) = (RegD(n) & 0xffff0000) | RegSR; + reg.D[n] = (reg.D[n] & 0xffff0000) | GetSR(); } else { // MOVE.W SR, CYCLE2(4, 5); - uint32 ea = cea_data_16(cpu); - m68030_write_16(cpu, ea, RegSR); + uint32 ea = cea_data_16(); + write_16(ea, GetSR()); } } @@ -1381,20 +1433,20 @@ OP_DEF(move_sr_ea) OP_DEF(chk_l) { uint32 dst = RegDX; - acc_move_32(cpu, dst); + ACC.move_32(dst); if (CCR.IsN()) { // これは最大値で次の条件式が成立した時の値なので、 // 実際にはこれより小さい確定した値のはずだけど。 CYCLE2(28, 30); - m68030_exception(cpu, M68K_EXCEP_CHK); + Exception(M68K::EXCEP_CHK); return; } // 本当はこうじゃないけど、とりあえず - uint32 src = fea_data_32(cpu); + uint32 src = fea_data_32(); if ((int32)dst > (int32)src) { CYCLE2(28, 30); - CCR.ClrN(); - m68030_exception(cpu, M68K_EXCEP_CHK); + CCR.SetN(false); + Exception(M68K::EXCEP_CHK); return; } CYCLE(8); @@ -1404,20 +1456,20 @@ OP_DEF(chk_l) OP_DEF(chk_w) { uint32 dst = RegDX & 0xffff; - acc_move_16(cpu, dst); + ACC.move_16(dst); if (CCR.IsN()) { // これは最大値で次の条件式が成立した時の値なので、 // 実際にはこれより小さい確定した値のはずだけど。 CYCLE2(28, 30); - m68030_exception(cpu, M68K_EXCEP_CHK); + Exception(M68K::EXCEP_CHK); return; } // 本当はこうじゃないけど、とりあえず - uint32 src = fea_data_16(cpu); + uint32 src = fea_data_16(); if ((int16)dst > (int16)src) { CYCLE2(28, 30); - CCR.ClrN(); - m68030_exception(cpu, M68K_EXCEP_CHK); + CCR.SetN(false); + Exception(M68K::EXCEP_CHK); return; } CYCLE(8); @@ -1427,174 +1479,174 @@ OP_DEF(chk_w) // %0100_100111_000yyy EXTB.L Dy OP_DEF(lea) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // EXTB.L Dy CYCLE(4); RegDY = (int32)(int8)(RegDY & 0xff); - acc_move_32(cpu, RegDY); + ACC.move_32(RegDY); } else { // LEA.L ,Ax CYCLE(2); - RegAX = cea_ctrl(cpu); + RegAX = cea_ctrl(); } } // %0100_001000_mmmrrr CLR.B OP_DEF(clr_b) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // CLR.B Dn CYCLE(2); RegDY &= 0xffffff00; - acc_move_8(cpu, 0); + ACC.move_8(0); } else { // CLR.B CYCLE2(3, 4); - uint32 ea = cea_data_8(cpu); - acc_move_8(cpu, 0); - m68030_write_8(cpu, ea, 0); + uint32 ea = cea_data_8(); + ACC.move_8(0); + write_8(ea, 0); } } // %0100_001001_mmmrrr CLR.W OP_DEF(clr_w) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // CLR.W Dn CYCLE(2); RegDY &= 0xffff0000; - acc_move_16(cpu, 0); + ACC.move_16(0); } else { // CLR.W CYCLE2(3, 4); - uint32 ea = cea_data_16(cpu); - acc_move_16(cpu, 0); - m68030_write_16(cpu, ea, 0); + uint32 ea = cea_data_16(); + ACC.move_16(0); + write_16(ea, 0); } } // %0100_001010_mmmrrr CLR.L OP_DEF(clr_l) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // CLR.L Dn CYCLE(2); RegDY = 0; - acc_move_32(cpu, 0); + ACC.move_32(0); } else { // CLR.L CYCLE2(3, 4); - uint32 ea = cea_data_32(cpu); - acc_move_32(cpu, 0); - m68030_write_32(cpu, ea, 0); + uint32 ea = cea_data_32(); + ACC.move_32(0); + write_32(ea, 0); } } // %0100_001011_mmmrrr MOVE.W CCR, OP_DEF(move_ccr_ea) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; // 転送は16ビットで行われ、上位バイトと未実装ビットは %0 になる。 if (n < 8) { // MOVE.W CCR,Dn CYCLE(4); - RegD(n) = (RegD(n) & 0xffff0000) | CCR.Get(); + reg.D[n] = (reg.D[n] & 0xffff0000) | CCR.Get(); } else if (n < 16) { // MOVE.W CCR,An はない - op_illegal(cpu); + op_illegal(); } else { // MOVE.W CCR, CYCLE2(4, 5); - uint32 ea = cea_data_16(cpu); - m68030_write_16(cpu, ea, CCR.Get()); + uint32 ea = cea_data_16(); + write_16(ea, CCR.Get()); } } // %0100_010000_mmmrrr NEG.B OP_DEF(neg_b) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // NEG.B Dn CYCLE(2); - uint32 data = acc_sub_8(cpu, RegD(n) & 0xff, 0); - RegD(n) = (RegD(n) & 0xffffff00) | data; + uint32 data = ACC.sub_8(reg.D[n] & 0xff, 0); + reg.D[n] = (reg.D[n] & 0xffffff00) | data; } else { // NEG.B CYCLE2(3, 4); - uint32 ea = cea_data_8(cpu); - uint32 data = m68030_read_8(cpu, ea); - data = acc_sub_8(cpu, data, 0); - m68030_write_8(cpu, ea, data); + uint32 ea = cea_data_8(); + uint32 data = read_8(ea); + data = ACC.sub_8(data, 0); + write_8(ea, data); } } // %0100_010001_mmmrrr NEG.W OP_DEF(neg_w) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // NEG.W Dn CYCLE(2); - uint32 data = acc_sub_16(cpu, RegD(n) & 0xffff, 0); - RegD(n) = (RegD(n) & 0xffff0000) | data; + uint32 data = ACC.sub_16(reg.D[n] & 0xffff, 0); + reg.D[n] = (reg.D[n] & 0xffff0000) | data; } else { // NEG.W CYCLE2(3, 4); - uint32 ea = cea_data_16(cpu); - uint32 data = m68030_read_16(cpu, ea); - data = acc_sub_16(cpu, data, 0); - m68030_write_16(cpu, ea, data); + uint32 ea = cea_data_16(); + uint32 data = read_16(ea); + data = ACC.sub_16(data, 0); + write_16(ea, data); } } // %0100_010010_mmmrrr NEG.L OP_DEF(neg_l) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // NEG.L Dn CYCLE(2); - RegD(n) = acc_sub_32(cpu, RegD(n), 0); + reg.D[n] = ACC.sub_32(reg.D[n], 0); } else { // NEG.L CYCLE2(3, 4); - uint32 ea = cea_data_32(cpu); - uint32 data = m68030_read_32(cpu, ea); - data = acc_sub_32(cpu, data, 0); - m68030_write_32(cpu, ea, data); + uint32 ea = cea_data_32(); + uint32 data = read_32(ea); + data = ACC.sub_32(data, 0); + write_32(ea, data); } } // %0100_010011_mmmrrr MOVE.W ,CCR OP_DEF(move_ea_ccr) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // MOVE.W Dn,CCR CYCLE(4); - uint32 data = RegD(n) & 0xff; + uint32 data = reg.D[n] & 0xff; CCR.Set(data); } else if (n < 16) { // MOVE.W An,CCR はない - op_illegal(cpu); + op_illegal(); } else { // MOVE.W ,CCR CYCLE(4); - uint32 data = fea_data_16(cpu); + uint32 data = fea_data_16(); CCR.Set(data); } } @@ -1602,65 +1654,65 @@ OP_DEF(move_ea_ccr) // %0100_011000_mmmrrr NOT.B OP_DEF(not_b) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // NOT.B Dn CYCLE(2); - uint32 data = (~RegD(n)) & 0xff; - acc_move_8(cpu, data); - RegD(n) = (RegD(n) & 0xffffff00) | data; + uint32 data = (~reg.D[n]) & 0xff; + ACC.move_8(data); + reg.D[n] = (reg.D[n] & 0xffffff00) | data; } else { // NOT.B CYCLE2(3, 4); - uint32 ea = cea_data_8(cpu); - uint32 data = m68030_read_8(cpu, ea); + uint32 ea = cea_data_8(); + uint32 data = read_8(ea); data = (~data) & 0xff; - acc_move_8(cpu, data); - m68030_write_8(cpu, ea, data); + ACC.move_8(data); + write_8(ea, data); } } // %0100_011001_mmmrrr NOT.W OP_DEF(not_w) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // NOT.W Dn CYCLE(2); - uint32 data = (~RegD(n)) & 0xffff; - acc_move_16(cpu, data); - RegD(n) = (RegD(n) & 0xffff0000) | data; + uint32 data = (~reg.D[n]) & 0xffff; + ACC.move_16(data); + reg.D[n] = (reg.D[n] & 0xffff0000) | data; } else { // NOT.W CYCLE2(3, 4); - uint32 ea = cea_data_16(cpu); - uint32 data = m68030_read_16(cpu, ea); + uint32 ea = cea_data_16(); + uint32 data = read_16(ea); data = (~data) & 0xffff; - acc_move_16(cpu, data); - m68030_write_16(cpu, ea, data); + ACC.move_16(data); + write_16(ea, data); } } // %0100_011010_mmmrrr NOT.L OP_DEF(not_l) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // NOT.L Dn CYCLE(2); - RegD(n) = ~RegD(n); - acc_move_32(cpu, RegD(n)); + reg.D[n] = ~reg.D[n]; + ACC.move_32(reg.D[n]); } else { // NOT.L CYCLE2(3, 4); - uint32 ea = cea_data_32(cpu); - uint32 data = m68030_read_32(cpu, ea); + uint32 ea = cea_data_32(); + uint32 data = read_32(ea); data = ~data; - acc_move_32(cpu, data); - m68030_write_32(cpu, ea, data); + ACC.move_32(data); + write_32(ea, data); } } @@ -1668,52 +1720,52 @@ OP_DEF(not_l) OP_DEF(move_ea_sr) { CYCLE2(8, 10); - uint16 data = fea_data_16(cpu); - m68030_set_sr(cpu, data); + uint16 data = fea_data_16(); + SetSR(data); } // %0100_100000_mmmrrr NBCD.B // %0100_100000_001yyy LINK.L Ay,# OP_DEF(nbcd) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; int32 imm; if (n < 8) { // NBCD.B Dn CYCLE(6); uint32 dst = RegDY & 0xff; - dst = acc_sbcd_8(cpu, dst, 0); + dst = ACC.sbcd_8(dst, 0); RegDY = (RegDY & 0xffffff00) | dst; } else if (n == 0x0e) { // LINK.L A6,# CYCLE2(6, 7); // レジスタやスタックを変更する前にフェッチしないと、 // ページフォルトで再実行できなくなる - imm = m68030_fetch_32(cpu); + imm = fetch_32(); // ページフォルトに備えて保存する - m68030_save_reg_pd(cpu, 7); - m68030_push_32(cpu, RegA(6)); - RegA(6) = RegA(7); - RegA(7) += imm; + save_reg_pd(7); + push_32(reg.A[6]); + reg.A[6] = reg.A[7]; + reg.A[7] += imm; } else if (n < 16) { // LINK.L An,# CYCLE2(6, 7); // レジスタやスタックを変更する前にフェッチしないと、 // ページフォルトで再実行できなくなる - imm = m68030_fetch_32(cpu); + imm = fetch_32(); // ページフォルトに備えて保存する - m68030_save_reg_pd(cpu, 7); - m68030_push_32(cpu, RegAY); - RegAY = RegA(7); - RegA(7) += imm; + save_reg_pd(7); + push_32(RegAY); + RegAY = reg.A[7]; + reg.A[7] += imm; } else { // NBCD.B CYCLE(6); - uint32 ea = cea_data_8(cpu); - uint32 dst = m68030_read_8(cpu, ea); - dst = acc_sbcd_8(cpu, dst, 0); - m68030_write_8(cpu, ea, dst); + uint32 ea = cea_data_8(); + uint32 dst = read_8(ea); + dst = ACC.sbcd_8(dst, 0); + write_8(ea, dst); } } @@ -1722,33 +1774,34 @@ OP_DEF(nbcd) // %0100_100001_mmmrrr PEA.L OP_DEF(pea) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // SWAP.W Dy CYCLE(4); - RegD(n) = (RegD(n) << 16) | (RegD(n) >> 16); - acc_move_32(cpu, RegD(n)); + reg.D[n] = (reg.D[n] << 16) | (reg.D[n] >> 16); + ACC.move_32(reg.D[n]); } else if (n < 16) { // BKPT # // ブレークポイント・アクノリッジサイクルに応答するデバイスはないので // 常に不当命令にする。 CYCLE(9); // ? - op_illegal(cpu); + op_illegal(); } else { // PEA.L CYCLE(4); - uint32 ea = cea_ctrl(cpu); + uint32 ea = cea_ctrl(); // ページフォルトに備えて保存する - m68030_save_reg_pd(cpu, 7); - m68030_push_32(cpu, ea); + save_reg_pd(7); + push_32(ea); } } // MOVEM.[WL] , の共通部分。 // bytesize は1レジスタ分のサイズ、.Wなら2、.Lなら4。 -template void -ops_movem_list_ea(m68kcpu *cpu) +// 本当はテンプレートにしたい。 +void +MPU680x0Device::ops_movem_list_ea(int bytesize) { uint32 ea; int regcount; @@ -1760,35 +1813,35 @@ ops_movem_list_ea(m68kcpu *cpu) | INVALID(1) // An | INVALID(3) // (An)+ | 0x3fL; // (PC)... - if ((int64)(valid << (RegIR & 0x3f)) < 0) { - op_illegal(cpu); + if ((int64)(valid << (ir & 0x3f)) < 0) { + op_illegal(); return; } // 第2ワードは EA が正当な場合のみ EA より先にフェッチ - RegIR2 = m68030_fetch_16(cpu); + ir2 = fetch_16(); // EA 取得。MOVEM だけ別対応 // | M -WXZ | MOVEM list, // だが、不当 EA はすでに弾いてあるので cea_data でいい if (bytesize == 2) { - ea = cea_data_16(cpu); + ea = cea_data_16(); } else { - ea = cea_data_32(cpu); + ea = cea_data_32(); } regcount = 0; - uint list = RegIR2; - if (eamode(RegIR) == 4/*-(An)*/) { + uint list = ir2; + if (eamode(ir) == 4/*-(An)*/) { // -(An) の場合 reglist の格納順が逆(転送順は LSB から) // bit15 bit0 // D0 D1 D2 D3 D4 D5 D6 D7 A0 A1 A2 A3 A4 A5 A6 A7 while (list) { int ctz = __builtin_ctz(list); if (bytesize == 2) { - m68030_write_16(cpu, ea, RegR(15 - ctz) & 0xffff); + write_16(ea, reg.R[15 - ctz] & 0xffff); } else { - m68030_write_32(cpu, ea, RegR(15 - ctz)); + write_32(ea, reg.R[15 - ctz]); } ea -= bytesize; regcount++; @@ -1804,9 +1857,9 @@ ops_movem_list_ea(m68kcpu *cpu) while (list) { int ctz = __builtin_ctz(list); if (bytesize == 2) { - m68030_write_16(cpu, ea, RegR(ctz) & 0xffff); + write_16(ea, reg.R[ctz] & 0xffff); } else { - m68030_write_32(cpu, ea, RegR(ctz)); + write_32(ea, reg.R[ctz]); } ea += bytesize; regcount++; @@ -1822,17 +1875,17 @@ ops_movem_list_ea(m68kcpu *cpu) // %0100_100010_mmmrrr MOVEM.W , OP_DEF(movem_w_mem) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // EXT.W Dy CYCLE(4); uint16 data = (int16)(int8)(RegDY & 0xff); - acc_move_16(cpu, data); + ACC.move_16(data); RegDY = (RegDY & 0xffff0000) | data; } else { // MOVEM.W , - ops_movem_list_ea<2>(cpu); + ops_movem_list_ea(2); } } @@ -1840,16 +1893,16 @@ OP_DEF(movem_w_mem) // %0100_100011_mmmrrr MOVEM.L , OP_DEF(movem_l_mem) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // EXT.L Dy CYCLE(4); RegDY = (int32)(int16)(RegDY & 0x0000ffff); - acc_move_32(cpu, RegDY); + ACC.move_32(RegDY); } else { // MOVEM.L , - ops_movem_list_ea<4>(cpu); + ops_movem_list_ea(4); } } @@ -1857,50 +1910,50 @@ OP_DEF(movem_l_mem) OP_DEF(tst_b) { CYCLE(2); - uint32 data = fea_all_8(cpu); - acc_move_8(cpu, data); + uint32 data = fea_all_8(); + ACC.move_8(data); } // %0100_101001_mmmrrr TST.W OP_DEF(tst_w) { CYCLE(2); - uint32 data = fea_all_16(cpu); - acc_move_16(cpu, data); + uint32 data = fea_all_16(); + ACC.move_16(data); } // %0100_101010_mmmrrr TST.L OP_DEF(tst_l) { CYCLE(2); - uint32 data = fea_all_32(cpu); - acc_move_32(cpu, data); + uint32 data = fea_all_32(); + ACC.move_32(data); } // %0100_101011_mmmrrr TAS.B // %0100_101011_111100 ILLEGAL OP_DEF(tas) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; if (n < 8) { // TAS.B Dn // リード・モディファイ・ライトという概念はない CYCLE(4); - uint32 data = RegD(n); - acc_move_8(cpu, data); - RegD(n) |= 0x80; + uint32 data = reg.D[n]; + ACC.move_8(data); + reg.D[n] |= 0x80; } else if (n == 0x3c) { // ILLEGAL - op_illegal(cpu); + op_illegal(); } else { // TAS.B // リード・モディファイ・ライトという概念はない CYCLE(12); - uint32 ea = cea_data_8(cpu); - uint32 data = m68030_read_8(cpu, ea); - acc_move_8(cpu, data); - m68030_write_8(cpu, ea, (data | 0x80)); + uint32 ea = cea_data_8(); + uint32 data = read_8(ea); + ACC.move_8(data); + write_8(ea, (data | 0x80)); } } @@ -1913,51 +1966,51 @@ OP_DEF(mul) // | |+------------ %1:64bit, %0:32bit // | +------------- %1:MULS, %0:MULU // +---------------- Dl - RegIR2 = m68030_fetch_16(cpu); - int h = RegIR2 & 7; - int l = (RegIR2 >> 12) & 7; + ir2 = fetch_16(); + int h = ir2 & 7; + int l = (ir2 >> 12) & 7; CYCLE(44); // XXX これは本当は最大値だけど - switch ((RegIR2 >> 10) & 3) { + switch ((ir2 >> 10) & 3) { case 0: { // MULU.L ,Dl - uint32 src = fea_data_32(cpu); - uint32 dst = RegD(l); - RegD(l) = acc_mulu_32(cpu, src, dst); + uint32 src = fea_data_32(); + uint32 dst = reg.D[l]; + reg.D[l] = ACC.mulu_32(src, dst); break; } case 1: { // MULU.L ,Dh:Dl - uint32 src = fea_data_32(cpu); - uint32 dst = RegD(l); - uint64 res = acc_mulu_64(cpu, src, dst); + uint32 src = fea_data_32(); + uint32 dst = reg.D[l]; + uint64 res = ACC.mulu_64(src, dst); // h == l の時は未定義なので考えない。 - RegD(h) = res >> 32; - RegD(l) = res; + reg.D[h] = res >> 32; + reg.D[l] = res; break; } case 2: { // MULS.L ,Dl - uint32 src = fea_data_32(cpu); - uint32 dst = RegD(l); - RegD(l) = acc_muls_32(cpu, src, dst); + uint32 src = fea_data_32(); + uint32 dst = reg.D[l]; + reg.D[l] = ACC.muls_32(src, dst); break; } case 3: { // MULS.L ,Dh:Dl - uint32 src = fea_data_32(cpu); - uint32 dst = RegD(l); - uint64 res = acc_muls_64(cpu, src, dst); + uint32 src = fea_data_32(); + uint32 dst = reg.D[l]; + uint64 res = ACC.muls_64(src, dst); // h == l の時は未定義なので考えない。 - RegD(h) = res >> 32; - RegD(l) = res; + reg.D[h] = res >> 32; + reg.D[l] = res; break; } @@ -1966,6 +2019,178 @@ OP_DEF(mul) } } +// DIVU.L ,Dq +// DIVUL.L ,Dr:Dq +void +MPU680x0Device::ops_divu_32_32(int r, int q) +{ + CYCLE(78); // XXX これは本当は最大値だけど + + uint32 src = fea_data_32(); + uint32 dst = reg.D[q]; + + if (src == 0) { + // ゼロ除算の場合、 + // X は変化しない + // C は常にクリア + // N,Z,V は未定義 + CCR.SetC(false); + Exception(M68K::EXCEP_ZERODIV); + return; + } + uint32 quo = dst / src; + uint32 rem = dst % src; + // このケースでオーバーフローは起きないはず + + // 正常の場合、 + // X は変化しない + // V, C はクリア + // N, Z は quo の結果。 + // r == q の場合 quo が残るので、rem を先に書く + reg.D[r] = rem; + reg.D[q] = quo; + ACC.move_32(quo); +} + +// DIVU.L ,Dr:Dq +void +MPU680x0Device::ops_divu_64_32(int r, int q) +{ + CYCLE(78); // XXX これは本当は最大値だけど + + uint32 src = fea_data_32(); + uint64 dst = (((uint64)reg.D[r]) << 32) | reg.D[q]; + + if (src == 0) { + // ゼロ除算の場合、 + // X は変化しない + // C は常にクリア + // N,Z,V は未定義 + CCR.SetC(false); + Exception(M68K::EXCEP_ZERODIV); + return; + } + uint64 q64 = dst / src; + if (q64 > 0xffffffffUL) { + // オーバーフローの場合、 + // X は変化しない + // N,Z は未定義 + // V はセット + // C は常にクリア + CCR.SetV(true); + CCR.SetC(false); + return; + } + uint32 quo = q64; + uint32 rem = dst % src; + + // 正常の場合、 + // X は変化しない + // V, C はクリア + // N, Z は quo の結果。 + // r == q の場合 quo が残るので、rem を先に書く + reg.D[r] = rem; + reg.D[q] = quo; + ACC.move_32(quo); +} + +// DIVS.L ,Dq +// DIVSL.L ,Dr:Dq +void +MPU680x0Device::ops_divs_32_32(int r, int q) +{ + CYCLE(90); // XXX これは本当は最大値だけど + + uint32 src = fea_data_32(); + uint32 dst = reg.D[q]; + + if (src == 0) { + // ゼロ除算の場合、 + // X は変化しない + // C は常にクリア + // N,Z,V は未定義 + CCR.SetC(false); + Exception(M68K::EXCEP_ZERODIV); + return; + } + + // ホストでオーバーフローが起きるのはこのケースのみ + if (dst == INT32_MIN && src == -1) { + // オーバーフローの場合、 + // X は変化しない + // N,Z は未定義 + // V はセット + // C は常にクリア + CCR.SetV(true); + CCR.SetC(false); + return; + } + + uint32 quo = (int32)dst / (int32)src; + uint32 rem = (int32)dst % (int32)src; + // ここでオーバーフローは起きない + + // 正常の場合、 + // X は変化しない + // V, C はクリア + // N, Z は quo の結果。 + // r == q の場合 quo が残るので、rem を先に書く + reg.D[r] = rem; + reg.D[q] = quo; + ACC.move_32(quo); +} + +// DIVSL.L +void +MPU680x0Device::ops_divs_64_32(int r, int q) +{ + CYCLE(90); // XXX これは本当は最大値だけど + + uint32 src = fea_data_32(); + uint64 dst = (((uint64)reg.D[r]) << 32) | reg.D[q]; + + if (src == 0) { + // ゼロ除算の場合、 + // X は変化しない + // C は常にクリア + // N,Z,V は未定義 + CCR.SetC(false); + Exception(M68K::EXCEP_ZERODIV); + return; + } + + // ホストでオーバーフローが起きるのはこのケースのみ + if (dst == INT64_MIN && src == -1) { + // オーバーフローの場合、 + // X は変化しない + // N,Z は未定義 + // V はセット + // C は常にクリア + CCR.SetV(true); + CCR.SetC(false); + return; + } + + int64 sq64 = (int64)dst / (int32)src; + if ((int32)sq64 != sq64) { + // オーバーフロー + CCR.SetV(true); + CCR.SetC(false); + return; + } + uint32 quo = (uint32)sq64; + uint32 rem = (int64)dst % (int32)src; + + // 正常の場合、 + // X は変化しない + // V, C はクリア + // N, Z は quo の結果。 + // r == q の場合 quo が残るので、rem を先に書く + reg.D[r] = rem; + reg.D[q] = quo; + ACC.move_32(quo); +} + // %0100_110001_mmmrrr DIVU.L ,Dq // %0100_110001_mmmrrr DIVU.L ,Dr:Dq // %0100_110001_mmmrrr DIVUL.L ,Dr:Dq @@ -1980,128 +2205,78 @@ OP_DEF(div) // | |+------------ %1:64bit, %0:32bit // | +------------- %1:DIVS, %0:DIVU // +---------------- Dq - RegIR2 = m68030_fetch_16(cpu); - int r = RegIR2 & 7; - int q = (RegIR2 >> 12) & 7; + ir2 = fetch_16(); + int r = ir2 & 7; + int q = (ir2 >> 12) & 7; - switch ((RegIR2 >> 10) & 3) { + switch ((ir2 >> 10) & 3) { case 0: - { - // DIVU.L ,Dq - // DIVUL.L ,Dr:Dq - CYCLE(78); // XXX これは本当は最大値だけど - uint32 src = fea_data_32(cpu); - uint32 dst = RegD(q); - uint32 quo; - uint32 rem; - if (acc_divu_32_32(cpu, src, dst, &quo, &rem)) { - // r == q の場合 quo が残るので、rem を先に書く - RegD(r) = rem; - RegD(q) = quo; - } + ops_divu_32_32(r, q); break; - } - - case 1: // DIVU.L ,Dr:Dq - { - CYCLE(78); // XXX これは本当は最大値だけど - uint32 src = fea_data_32(cpu); - uint64 dst = (((uint64)RegD(r)) << 32) | RegD(q); - uint32 quo; - uint32 rem; - if (acc_divu_64_32(cpu, src, dst, &quo, &rem)) { - RegD(r) = rem; - RegD(q) = quo; - } + case 1: + ops_divu_64_32(r, q); break; - } - case 2: - { - // DIVS.L ,Dq - // DIVSL.L ,Dr:Dq - CYCLE(90); // XXX これは本当は最大値だけど - uint32 src = fea_data_32(cpu); - uint32 dst = RegD(q); - uint32 quo; - uint32 rem; - if (acc_divs_32_32(cpu, src, dst, &quo, &rem)) { - // r == q の場合 quo が残るので、rem を先に書く - RegD(r) = rem; - RegD(q) = quo; - } + ops_divs_32_32(r, q); break; - } - - case 3: // DIVSL.L - { - CYCLE(90); // XXX これは本当は最大値だけど - uint32 src = fea_data_32(cpu); - uint64 dst = (((uint64)RegD(r)) << 32) | RegD(q); - uint32 quo; - uint32 rem; - if (acc_divs_64_32(cpu, src, dst, &quo, &rem)) { - RegD(r) = rem; - RegD(q) = quo; - } + case 3: + ops_divs_64_32(r, q); break; - } - default: __unreachable(); } } -template void -ops_movem_ea_list(m68kcpu *cpu) +void +MPU680x0Device::ops_movem_ea_list(int bytesize) { uint32 ea; int regcount; bool anpi = false; - RegIR2 = m68030_fetch_16(cpu); + ir2 = fetch_16(); // EA 取得。MOVEM だけ別対応 // | M+ WXZP | MOVEM ,list - switch (eamode(RegIR)) { + switch (eamode(ir)) { case 2: // (An) - ea = cea_anin(cpu, eanum(RegIR)); + ea = cea_anin(eanum(ir)); break; case 3: // (An)+ if (bytesize == 2) { - ea = cea_anpi_16(cpu, eanum(RegIR)); + ea = cea_anpi_16(eanum(ir)); } else { - ea = cea_anpi_32(cpu, eanum(RegIR)); + ea = cea_anpi_32(eanum(ir)); } anpi = true; break; case 5: // d16(An) - ea = cea_andi(cpu, eanum(RegIR)); + ea = cea_andi(eanum(ir)); break; case 6: // (An,IX) - ea = cea_anix(cpu, eanum(RegIR)); + ea = cea_anix(eanum(ir)); break; case 7: - switch (eanum(RegIR)) { + switch (eanum(ir)) { case 0: // Abs.W - ea = cea_absw(cpu); + ea = cea_absw(); break; case 1: // Abs.L - ea = cea_absl(cpu); + ea = cea_absl(); break; case 2: // d16(PC) - ea = cea_pcdi(cpu); + ea = cea_pcdi(); break; case 3: // (PC,IX) - ea = cea_pcix(cpu); + ea = cea_pcix(); break; default: - op_illegal(cpu); + op_illegal(); return; } break; default: - op_illegal(cpu); + op_illegal(); return; } @@ -2109,18 +2284,18 @@ ops_movem_ea_list(m68kcpu *cpu) // レジスタはデータレジスタIX も含めて全部保存しておく必要がある。 regcount = 0; - uint list = RegIR2; + uint list = ir2; while (list) { uint32 data; if (bytesize == 2) { - data = (int32)(int16)m68030_read_16(cpu, ea); + data = (int32)(int16)read_16(ea); } else { - data = m68030_read_32(cpu, ea); + data = read_32(ea); } ea += bytesize; regcount++; int ctz = __builtin_ctz(list); - RegR(ctz) = data; + reg.R[ctz] = data; // clear LSB bits list &= ((~1U) << ctz); } @@ -2135,127 +2310,118 @@ ops_movem_ea_list(m68kcpu *cpu) // %0100_110010_mmmrrr MOVEM.W , OP_DEF(movem_w) { - ops_movem_ea_list<2>(cpu); + ops_movem_ea_list(2); } // %0100_110011_mmmrrr MOVEM.L , OP_DEF(movem_l) { - ops_movem_ea_list<4>(cpu); -} - -void -ops_rte(m68kcpu *cpu) -{ - SUPERVISOR_OP; - - // subr.cpp - m68030_rte(cpu); + ops_movem_ea_list(4); } // MOVEC.L Rc,Rn void -ops_movec_rc_rn(m68kcpu *cpu) +MPU680x0Device::ops_movec_rc_rn() { SUPERVISOR_OP; CYCLE(6); - RegIR2 = m68030_fetch_16(cpu); - int n = RegIR2 >> 12; - int c = RegIR2 & 0xfff; + ir2 = fetch_16(); + int n = ir2 >> 12; + int c = ir2 & 0xfff; switch (c) { case 0x000: - RegR(n) = RegSFC; + reg.R[n] = reg.sfc; return; case 0x001: - RegR(n) = RegDFC; + reg.R[n] = reg.dfc; return; case 0x002: - RegR(n) = RegCACR; + reg.R[n] = reg.cacr; return; case 0x800: - RegR(n) = RegUSP; + reg.R[n] = reg.usp; return; case 0x801: - RegR(n) = RegVBR; + reg.R[n] = reg.vbr; return; case 0x802: - RegR(n) = RegCAAR; + reg.R[n] = reg.caar; return; case 0x803: - if (cpu->reg.m) { - RegR(n) = RegA(7); + if (reg.m) { + reg.R[n] = reg.A[7]; } else { - RegR(n) = RegMSP; + reg.R[n] = reg.msp; } return; case 0x804: - if (cpu->reg.m) { - RegR(n) = RegISP; + if (reg.m) { + reg.R[n] = reg.isp; } else { - RegR(n) = RegA(7); + reg.R[n] = reg.A[7]; } return; default: break; } - op_illegal(cpu); + op_illegal(); } // MOVEC.L Rn,Rc void -ops_movec_rn_rc(m68kcpu *cpu) +MPU680x0Device::ops_movec_rn_rc() { SUPERVISOR_OP; - RegIR2 = m68030_fetch_16(cpu); - int n = RegIR2 >> 12; - int c = RegIR2 & 0xfff; + ir2 = fetch_16(); + int n = ir2 >> 12; + int c = ir2 & 0xfff; switch (c) { case 0x000: CYCLE(12); - RegSFC = RegR(n); + reg.sfc = reg.R[n]; return; case 0x001: CYCLE(12); - RegDFC = RegR(n); + reg.dfc = reg.R[n]; return; case 0x002: CYCLE(12); - RegCACR = RegR(n); + reg.cacr = reg.R[n]; return; case 0x800: CYCLE(6); - RegUSP = RegR(n); + reg.usp = reg.R[n]; return; case 0x801: CYCLE(6); - RegVBR = RegR(n); + reg.vbr = reg.R[n]; return; case 0x802: CYCLE(6); - RegCAAR = RegR(n); + reg.caar = reg.R[n]; return; case 0x803: CYCLE(6); - if (cpu->reg.m) { - RegA(7) = RegR(n); + if (reg.m) { + reg.A[7] = reg.R[n]; } else { - RegMSP = RegR(n); + reg.msp = reg.R[n]; } return; case 0x804: CYCLE(6); - if (cpu->reg.m) { - RegISP = RegR(n); + if (reg.m) { + reg.isp = reg.R[n]; } else { - RegA(7) = RegR(n); + reg.A[7] = reg.R[n]; } return; default: break; } - op_illegal(cpu); + op_illegal(); } // %0100_111001_00nnnn TRAP # @@ -2275,14 +2441,20 @@ ops_movec_rn_rc(m68kcpu *cpu) // %0100_111001_111011 MOVEC.L Rn,Rc OP_DEF(trap) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; int32 imm; switch (n) { - case 0x00 ... 0x0f:// TRAP # + case 0x00 ... 0x0e:// TRAP # CYCLE2(18, 20); // TRAP#N 例外 - m68030_exception(cpu, M68K_EXCEP_TRAP0 + n); + Exception(M68K::EXCEP_TRAP0 + n); + return; + + case 0x0f: // TRAP #15 + CYCLE2(18, 20); + // TRAP#15 例外 (IOCS コール表示のためこれだけ別処理) + ExceptionTrap15(); return; case 0x10: @@ -2295,22 +2467,22 @@ OP_DEF(trap) CYCLE2(4, 5); // レジスタやスタックを変更する前にフェッチとセーブをしないと、 // ページフォルトで再実行できなくなる - imm = (int32)(int16)m68030_fetch_16(cpu); - m68030_save_reg_pd(cpu, 7); - m68030_push_32(cpu, RegAY); - RegAY = RegA(7); - RegA(7) += imm; + imm = (int32)(int16)fetch_16(); + save_reg_pd(7); + push_32(RegAY); + RegAY = reg.A[7]; + reg.A[7] += imm; return; case 0x16: // LINK.W A6,# // LINK はほぼ A6 なのでこいつだけ展開してみる CYCLE2(4, 5); // レジスタやスタックを変更する前にフェッチとセーブをしないと、 // ページフォルトで再実行できなくなる - imm = (int32)(int16)m68030_fetch_16(cpu); - m68030_save_reg_pd(cpu, 7); - m68030_push_32(cpu, RegA(6)); - RegA(6) = RegA(7); - RegA(7) += imm; + imm = (int32)(int16)fetch_16(); + save_reg_pd(7); + push_32(reg.A[6]); + reg.A[6] = reg.A[7]; + reg.A[7] += imm; return; case 0x18: @@ -2322,17 +2494,17 @@ OP_DEF(trap) case 0x1f: // UNLK Ay CYCLE(5); // ページフォルトに備えて保存する - m68030_save_reg_pi(cpu, 7); - RegA(7) = RegAY; - RegAY = m68030_pop_32(cpu); + save_reg_pi(7); + reg.A[7] = RegAY; + RegAY = pop_32(); return; case 0x1e: // UNLK A6 // UNLK はほぼ A6 なのでこいつだけ展開してみる CYCLE(5); // ページフォルトに備えて保存する - m68030_save_reg_pi(cpu, 7); - RegA(7) = RegA(6); - RegA(6) = m68030_pop_32(cpu); + save_reg_pi(7); + reg.A[7] = reg.A[6]; + reg.A[6] = pop_32(); return; case 0x20: @@ -2345,7 +2517,7 @@ OP_DEF(trap) case 0x27: // MOVE.L Ay,USP SUPERVISOR_OP; CYCLE(4); - RegUSP = RegAY; + reg.usp = RegAY; return; case 0x28: @@ -2358,12 +2530,12 @@ OP_DEF(trap) case 0x2f: // MOVE.L USP,Ay SUPERVISOR_OP; CYCLE(4); - RegAY = RegUSP; + RegAY = reg.usp; return; case 0x30: // RESET CYCLE(518); - m68030_reset_inst(cpu); + ops_reset(); return; case 0x31: // NOP @@ -2372,41 +2544,38 @@ OP_DEF(trap) return; case 0x32: // STOP # - { SUPERVISOR_OP; CYCLE(8); - uint32 data = m68030_fetch_16(cpu); - m68030_set_sr(cpu, data); - cpu->atomic_reqflag |= CPU_REQ_RELEASE | CPU_REQ_STOP; + ops_stop(); return; - } case 0x33: // RTE - ops_rte(cpu); + SUPERVISOR_OP; + ops_rte(); return; case 0x34: // RTD # { CYCLE2(10, 12); // ページフォルトに備えて保存する - m68030_save_reg_pi(cpu, 7); - uint32 disp = m68030_fetch_16(cpu); - m68030_jump(cpu, m68030_pop_32(cpu)); - RegA(7) += (int32)(int16)disp; + save_reg_pi(7); + uint32 disp = fetch_16(); + Jump(pop_32()); + reg.A[7] += (int32)(int16)disp; return; } case 0x35: // RTS CYCLE2(9, 11); // ページフォルトに備えて保存する - m68030_save_reg_pi(cpu, 7); - m68030_jump(cpu, m68030_pop_32(cpu)); + save_reg_pi(7); + Jump(pop_32()); return; case 0x36: // TRAPV if (CCR.IsV()) { CYCLE2(22, 24); - m68030_exception(cpu, M68K_EXCEP_TRAPV); + Exception(M68K::EXCEP_TRAPV); } else { CYCLE(4); } @@ -2415,21 +2584,21 @@ OP_DEF(trap) case 0x37: // RTR CYCLE2(12, 14); // ページフォルトに備えて保存する - m68030_save_reg_pi(cpu, 7); - CCR.Set(m68030_pop_16(cpu)); - m68030_jump(cpu, m68030_pop_32(cpu)); + save_reg_pi(7); + CCR.Set(pop_16()); + Jump(pop_32()); return; case 0x3a: // MOVEC.L Rc,Rn - ops_movec_rc_rn(cpu); + ops_movec_rc_rn(); return; case 0x3b: // MOVEC.L Rn,Rc - ops_movec_rn_rc(cpu); + ops_movec_rn_rc(); return; default: - op_illegal(cpu); + op_illegal(); return; } } @@ -2438,11 +2607,11 @@ OP_DEF(trap) OP_DEF(jsr) { CYCLE2(4, 7); - uint32 ea = cea_ctrl(cpu); + uint32 ea = cea_ctrl(); // ページフォルトに備えて保存する - m68030_save_reg_pd(cpu, 7); - m68030_push_32(cpu, RegPC); - m68030_jump(cpu, ea); + save_reg_pd(7); + push_32(reg.pc); + Jump(ea); } // %0100_111011_mmmrrr JMP @@ -2450,29 +2619,29 @@ OP_DEF(jmp) { CYCLE2(4, 6); // 実際には CEA ではなく JEA の実行時間を足すんだがまあいいか - uint32 ea = cea_ctrl(cpu); - m68030_jump(cpu, ea); + uint32 ea = cea_ctrl(); + Jump(ea); } // %0101_qqq000_mmmrrr ADDQ.B #qqq, OP_DEF(addq_b) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; uint32 src = RegIRX; src = (src == 0) ? 8 : src; if (n < 8) { // ADDQ.B #qqq,Dn CYCLE(2); - uint32 data = acc_add_8(cpu, src, RegD(n) & 0xff); - RegD(n) = (RegD(n) & 0xffffff00) | data; + uint32 data = ACC.add_8(src, reg.D[n] & 0xff); + reg.D[n] = (reg.D[n] & 0xffffff00) | data; } else { // ADDQ.B #qqq, CYCLE2(3, 4); - uint32 ea = cea_data_8(cpu); - uint32 data = m68030_read_8(cpu, ea); - data = acc_add_8(cpu, src, data); - m68030_write_8(cpu, ea, data); + uint32 ea = cea_data_8(); + uint32 data = read_8(ea); + data = ACC.add_8(src, data); + write_8(ea, data); } } @@ -2480,27 +2649,27 @@ OP_DEF(addq_b) // %0101_qqq001_001yyy ADDQ.W #qqq,Ay (.Lと等価) OP_DEF(addq_w) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; uint32 src = RegIRX; src = (src == 0) ? 8 : src; if (n < 8) { // ADDQ.W #qqq,Dn CYCLE(2); - uint32 data = acc_add_16(cpu, src, RegD(n) & 0xffff); - RegD(n) = (RegD(n) & 0xffff0000) | data; + uint32 data = ACC.add_16(src, reg.D[n] & 0xffff); + reg.D[n] = (reg.D[n] & 0xffff0000) | data; } else if (n < 16) { // ADDQ.W #qqq,An は ADDQ.L と等価 // フラグは変化しない CYCLE(2); - RegR(n) += src; + reg.R[n] += src; } else { // ADDQ.W #qqq, CYCLE2(3, 4); - uint32 ea = cea_data_16(cpu); - uint32 data = m68030_read_16(cpu, ea); - data = acc_add_16(cpu, src, data); - m68030_write_16(cpu, ea, data); + uint32 ea = cea_data_16(); + uint32 data = read_16(ea); + data = ACC.add_16(src, data); + write_16(ea, data); } } @@ -2508,54 +2677,59 @@ OP_DEF(addq_w) // %0101_qqq010_001yyy ADDQ.L #qqq,Ay OP_DEF(addq_l) { - uint n = RegIR & 0x3f; + uint n = ir & 0x3f; uint32 src = RegIRX; src = (src == 0) ? 8 : src; if (n < 8) { // ADDQ.L #qqq,Dn CYCLE(2); - RegD(n) = acc_add_32(cpu, src, RegD(n)); + reg.D[n] = ACC.add_32(src, reg.D[n]); } else if (n < 16) { // ADDQ.L #qqq,An // フラグは変化しない CYCLE(2); - RegR(n) += src; + reg.R[n] += src; } else { // ADDQ.L #qqq, CYCLE2(3, 4); - uint32 ea = cea_data_32(cpu); - uint32 data = m68030_read_32(cpu, ea); - data = acc_add_32(cpu, src, data); - m68030_write_32(cpu, ea, data); + uint32 ea = cea_data_32(); + uint32 data = read_32(ea); + data = ACC.add_32(src, data); + write_32(ea, data); } } // TRAPcc の共通部分。 -templatevoid -ops_trapcc(m68kcpu *cpu) +void +MPU680x0Device::ops_trapcc(uint cond) { // 条件成立すれば例外。成立しなければ何もしない。 // いずれの場合もオペランドありの形態なら事前に読み飛ばしておくこと。 - if (cond_func(cpu, cond)) { + if (CCR.Cond(cond)) { CYCLE2(22, 24); - m68030_exception(cpu, M68K_EXCEP_TRAPV); + Exception(M68K::EXCEP_TRAPV); } else { // サイクルを消費するだけ CYCLE(4); } } -// Scc ブロックの共通部分。 -template void -ops_scc(m68kcpu *cpu) +// %0101_cccc11_mmmrrr Scc.B +// %0101_cccc11_001yyy DBcc.W Dy,