--- nono/m680x0/m68030bus.cpp 2026/04/29 17:04:34 1.1.1.3 +++ nono/m680x0/m68030bus.cpp 2026/04/29 17:05:15 1.1.1.4 @@ -6,424 +6,192 @@ // 論理アクセス -// -// 1回の(アラインド)物理アクセスを担当するマクロ。 -// これらは続く _mmu テンプレートで使用する。 -// goto を含むことに注意。gcc 拡張式(?)に注意。 -// mmu_translate_* は fetch, read, write の3種だが、vm_phys_ は -// read, write しかないことに注意。物理バスに FC0 と FC1、つまりプログラム -// 空間かどうかの情報は出していないため。 -// - -#define FETCH(size) ({ \ - cpu->bus.paddr = cpu->bus.laddr; \ - if (use_mmu && m68030_mmu_translate_fetch(cpu) == false) \ - goto buserr; \ - uint64 data_ = vm_phys_read_##size(cpu->bus.paddr); \ - if ((int64)data_ < 0) \ - goto buserr; \ - data_; /* これが戻り値 */ \ -}) - -#define READ(size) ({ \ - cpu->bus.paddr = cpu->bus.laddr; \ - if (use_mmu && m68030_mmu_translate_read(cpu) == false) \ - goto buserr; \ - uint64 data_ = vm_phys_read_##size(cpu->bus.paddr); \ - if ((int64)data_ < 0) \ - goto buserr; \ - data_; /* これが戻り値 */ \ -}) - -#define WRITE(size, data) ({ \ - cpu->bus.paddr = cpu->bus.laddr; \ - if (use_mmu && m68030_mmu_translate_write(cpu) == false) \ - goto buserr; \ - int64 berr_ = vm_phys_write_##size(cpu->bus.paddr, (data)); \ - if (berr_ < 0) \ - goto buserr; \ - 0; /* 戻り値不要だけど一応 */ \ -}) +#include "mpu680x0.h" // バスエラー時に SSW をセットする。 -// m68030_*_NN_mmu() 関数の下請け。 -static inline void -SET_SSW(m68kcpu *cpu, bool use_mmu, uint size) +// {fetch,read,write}_NN_mmu() 関数の下請け。 +void +m68kbus::SET_SSW(bool use_mmu, uint size) { // サイズを設定 - cpu->bus.ssw &= ~SSW_SIZE_MASK; - cpu->bus.ssw |= size; + ssw &= ~M68K::SSW_SIZE_MASK; + ssw |= size; if (use_mmu) { // データアクセスなら再試行のため DataFault ビットをセット。 // 命令アクセスなら RB をセット。 - if ((cpu->bus.ssw & FC_DATA)) { - cpu->bus.ssw |= SSW_DF; + if ((ssw & M68K::FC_DATA)) { + ssw |= M68K::SSW_DF; } else { - cpu->bus.ssw |= SSW_RB; + ssw |= M68K::SSW_RB; } } } -// -// MMU を考慮した下請けテンプレート。 -// 1回分のミスアラインドありのアクセスを担当。 -// - -template uint32 -m68030_fetch_16_mmu(m68kcpu *cpu) -{ - uint64 data; - - data = FETCH(16); - // XXX バスエラー時に PC をインクリメントするタイミングは? - RegPC += 2; - - return data; - - buserr: - SET_SSW(cpu, use_mmu, SSW_SIZE_WORD); - throw M68K_EXCEP_BUSERR; -} - -template uint32 -m68030_fetch_32_mmu(m68kcpu *cpu) -{ - uint64 data; - - if ((cpu->bus.laddr & 3) == 0) { - data = FETCH(32); - } else { - uint64 h, l; - - h = FETCH(16); - cpu->bus.laddr += 2; - - l = FETCH(16); - data = (h << 16) | l; - } - // XXX バスエラー時に PC をインクリメントするタイミングは? - RegPC += 4; - return data; - - buserr: - SET_SSW(cpu, use_mmu, SSW_SIZE_LONG); - throw M68K_EXCEP_BUSERR; -} - -template uint32 -m68030_read_8_mmu(m68kcpu *cpu) -{ - uint64 data; - - data = READ(8); - - if (1) - cpulog(2, "m68030_read_8 %08X -> %02X", cpu->bus.laddr, (uint32)data); - return data; - - buserr: - SET_SSW(cpu, use_mmu, SSW_SIZE_BYTE); - throw M68K_EXCEP_BUSERR; -} - -template uint32 -m68030_read_16_mmu(m68kcpu *cpu) -{ - uint64 data; - - if ((cpu->bus.laddr & 1) == 0) { - data = READ(16); - } else { - uint64 h, l; - - h = READ(8); - cpu->bus.laddr += 1; - - l = READ(8); - data = (h << 8) | l; - } - - if (1) - cpulog(2, "m68030_read_16 %08X -> %04X", cpu->bus.laddr, (uint32)data); - return data; - - buserr: - SET_SSW(cpu, use_mmu, SSW_SIZE_WORD); - throw M68K_EXCEP_BUSERR; -} - -template uint32 -m68030_read_32_mmu(m68kcpu *cpu) -{ - uint64 data; - - if ((cpu->bus.laddr & 3) == 0) { - data = READ(32); - } else if ((cpu->bus.laddr & 1) == 0) { - uint64 h, l; - - h = READ(16); - cpu->bus.laddr += 2; - - l = READ(16); - data = (h << 16) | l; - } else { - uint64 h, m, l; - - h = READ(8); - cpu->bus.laddr += 1; - - m = READ(16); - cpu->bus.laddr += 2; - - l = READ(8); - data = (h << 24) | (m << 8) | l; - } - - if (1) - cpulog(2, "m68030_read_32 %08X -> %08X", cpu->bus.laddr, (uint32)data); - return data; - - buserr: - SET_SSW(cpu, use_mmu, SSW_SIZE_LONG); - throw M68K_EXCEP_BUSERR; -} - -template void -m68030_write_8_mmu(m68kcpu *cpu) -{ - uint32 data = cpu->bus.data; - - if (1) - cpulog(2, "m68030_write_8 %08X <- %02X", cpu->bus.laddr, data); - - WRITE(8, data); - return; - - buserr: - SET_SSW(cpu, use_mmu, SSW_SIZE_BYTE); - throw M68K_EXCEP_BUSERR; -} - -template void -m68030_write_16_mmu(m68kcpu *cpu) -{ - uint32 data = cpu->bus.data; - - if (1) - cpulog(2, "m68030_write_16 %08X <- %04X", cpu->bus.laddr, data); - - if ((cpu->bus.laddr & 1) == 0) { - WRITE(16, data); - } else { - WRITE(8, data >> 8); - - cpu->bus.laddr += 1; - WRITE(8, data & 0xff); - } - return; - - buserr: - SET_SSW(cpu, use_mmu, SSW_SIZE_WORD); - throw M68K_EXCEP_BUSERR; -} - -template void -m68030_write_32_mmu(m68kcpu *cpu) -{ - uint32 data = cpu->bus.data; - - if (1) - cpulog(2, "m68030_write_32 %08X <- %08X", cpu->bus.laddr, data); - - if ((cpu->bus.laddr & 3) == 0) { - WRITE(32, data); - } else if ((cpu->bus.laddr & 1) == 0) { - WRITE(16, data >> 16); - - cpu->bus.laddr += 2; - WRITE(16, data & 0xffff); - } else { - WRITE(8, data >> 24); - - cpu->bus.laddr += 1; - WRITE(16, (data >> 8) & 0xffff); - - cpu->bus.laddr += 2; - WRITE(8, data & 0xff); - } - return; - - buserr: - SET_SSW(cpu, use_mmu, SSW_SIZE_LONG); - throw M68K_EXCEP_BUSERR; -} - -// m68030_{fetch,read,write}_NN() と m68030_{read,write}_NN_fc() の共通部分。 +// {fetch,read,write}_NN() と {read,write}_NN_fc() の共通部分。 // fetch には FC 指定版はないので分ける必要は本来ないけど対称性のため。 -// cpu->bus に必要な情報はセットされている。 +// bus に必要な情報はセットされている。 // _bus 接尾辞はバスアクセスというより bus 構造体を使ったアクセスという感じ。 -static inline uint32 -m68030_fetch_16_bus(m68kcpu *cpu) +inline uint32 +MPU680x0Device::fetch_16_bus() { - if (cpu->mmu_enable) { - return m68030_fetch_16_mmu(cpu); + if (mmu_enable) { + return fetch_16_mmu(); } else { - return m68030_fetch_16_mmu(cpu); + return fetch_16_mmu(); } } -static inline uint32 -m68030_fetch_32_bus(m68kcpu *cpu) +inline uint32 +MPU680x0Device::fetch_32_bus() { - if (cpu->mmu_enable) { - return m68030_fetch_32_mmu(cpu); + if (mmu_enable) { + return fetch_32_mmu(); } else { - return m68030_fetch_32_mmu(cpu); + return fetch_32_mmu(); } } -static uint32 -m68030_read_8_bus(m68kcpu *cpu) +inline uint32 +MPU680x0Device::read_8_bus() { -if(1)cpulog(2, "%s $%08x", __func__, cpu->bus.laddr); - if (cpu->mmu_enable) { - return m68030_read_8_mmu(cpu); +if(1)putlog(2, "%s $%08x", __func__, bus.laddr); + if (mmu_enable) { + return read_8_mmu(); } else { - return m68030_read_8_mmu(cpu); + return read_8_mmu(); } } -static uint32 -m68030_read_16_bus(m68kcpu *cpu) +inline uint32 +MPU680x0Device::read_16_bus() { -if(1)cpulog(2, "%s $%08x", __func__, cpu->bus.laddr); - if (cpu->mmu_enable) { - return m68030_read_16_mmu(cpu); +if(1)putlog(2, "%s $%08x", __func__, bus.laddr); + if (mmu_enable) { + return read_16_mmu(); } else { - return m68030_read_16_mmu(cpu); + return read_16_mmu(); } } -static uint32 -m68030_read_32_bus(m68kcpu *cpu) +inline uint32 +MPU680x0Device::read_32_bus() { -if(1)cpulog(2, "%s $%08x", __func__, cpu->bus.laddr); - if (cpu->mmu_enable) { - return m68030_read_32_mmu(cpu); +if(1)putlog(2, "%s $%08x", __func__, bus.laddr); + if (mmu_enable) { + return read_32_mmu(); } else { - return m68030_read_32_mmu(cpu); + return read_32_mmu(); } } -static void -m68030_write_8_bus(m68kcpu *cpu) +inline void +MPU680x0Device::write_8_bus() { -if(1)cpulog(2, "%s $%08x", __func__, cpu->bus.laddr); - if (cpu->mmu_enable) { - m68030_write_8_mmu(cpu); +if(1)putlog(2, "%s $%08x", __func__, bus.laddr); + if (mmu_enable) { + write_8_mmu(); } else { - m68030_write_8_mmu(cpu); + write_8_mmu(); } } -static void -m68030_write_16_bus(m68kcpu *cpu) +inline void +MPU680x0Device::write_16_bus() { -if(1)cpulog(2, "%s $%08x", __func__, cpu->bus.laddr); - if (cpu->mmu_enable) { - m68030_write_16_mmu(cpu); +if(1)putlog(2, "%s $%08x", __func__, bus.laddr); + if (mmu_enable) { + write_16_mmu(); } else { - m68030_write_16_mmu(cpu); + write_16_mmu(); } } -static void -m68030_write_32_bus(m68kcpu *cpu) +inline void +MPU680x0Device::write_32_bus() { -if(1)cpulog(2, "%s $%08x", __func__, cpu->bus.laddr); - if (cpu->mmu_enable) { - m68030_write_32_mmu(cpu); +if(1)putlog(2, "%s $%08x", __func__, bus.laddr); + if (mmu_enable) { + write_32_mmu(); } else { - m68030_write_32_mmu(cpu); + write_32_mmu(); } } // // CPU 内部からのメモリアクセスは常にこの8つ (またはこれを呼び出すヘルパー // 関数) を呼ぶこと。 -// uint32 m68030_fetch_{16,32}(cpu) -// uint32 m68030_read_{8,16,32}(cpu, laddr) -// void m68030_write_{8,16,32}(cpu, laddr, data) +// uint32 fetch_{16,32}() +// uint32 read_{8,16,32}(laddr) +// void write_{8,16,32}(laddr, data) // uint32 -m68030_fetch_16(m68kcpu *cpu) +MPU680x0Device::fetch_16() { - cpu->bus.ssw = SSW_BUS_R | cpu->bus.fc2 | FC_PROG; - cpu->bus.laddr = RegPC; - return m68030_fetch_16_bus(cpu); + bus.ssw = M68K::SSW_BUS_R | bus.fc2 | M68K::FC_PROG; + bus.laddr = reg.pc; + return fetch_16_bus(); } uint32 -m68030_fetch_32(m68kcpu *cpu) +MPU680x0Device::fetch_32() { - cpu->bus.ssw = SSW_BUS_R | cpu->bus.fc2 | FC_PROG; - cpu->bus.laddr = RegPC; - return m68030_fetch_32_bus(cpu); + bus.ssw = M68K::SSW_BUS_R | bus.fc2 | M68K::FC_PROG; + bus.laddr = reg.pc; + return fetch_32_bus(); } uint32 -m68030_read_8(m68kcpu *cpu, uint32 addr) +MPU680x0Device::read_8(uint32 addr) { - cpu->bus.ssw = SSW_BUS_R | cpu->bus.fc2 | FC_DATA; - cpu->bus.laddr = addr; - return m68030_read_8_bus(cpu); + bus.ssw = M68K::SSW_BUS_R | bus.fc2 | M68K::FC_DATA; + bus.laddr = addr; + return read_8_bus(); } uint32 -m68030_read_16(m68kcpu *cpu, uint32 addr) +MPU680x0Device::read_16(uint32 addr) { - cpu->bus.ssw = SSW_BUS_R | cpu->bus.fc2 | FC_DATA; - cpu->bus.laddr = addr; - return m68030_read_16_bus(cpu); + bus.ssw = M68K::SSW_BUS_R | bus.fc2 | M68K::FC_DATA; + bus.laddr = addr; + return read_16_bus(); } uint32 -m68030_read_32(m68kcpu *cpu, uint32 addr) +MPU680x0Device::read_32(uint32 addr) { - cpu->bus.ssw = SSW_BUS_R | cpu->bus.fc2 | FC_DATA; - cpu->bus.laddr = addr; - return m68030_read_32_bus(cpu); + bus.ssw = M68K::SSW_BUS_R | bus.fc2 | M68K::FC_DATA; + bus.laddr = addr; + return read_32_bus(); } void -m68030_write_8(m68kcpu *cpu, uint32 addr, uint32 data) +MPU680x0Device::write_8(uint32 addr, uint32 data) { - cpu->bus.ssw = SSW_BUS_W | cpu->bus.fc2 | FC_DATA; - cpu->bus.laddr = addr; - cpu->bus.data = data; - m68030_write_8_bus(cpu); + bus.ssw = M68K::SSW_BUS_W | bus.fc2 | M68K::FC_DATA; + bus.laddr = addr; + bus.data = data; + write_8_bus(); } void -m68030_write_16(m68kcpu *cpu, uint32 addr, uint32 data) +MPU680x0Device::write_16(uint32 addr, uint32 data) { - cpu->bus.ssw = SSW_BUS_W | cpu->bus.fc2 | FC_DATA; - cpu->bus.laddr = addr; - cpu->bus.data = data; - m68030_write_16_bus(cpu); + bus.ssw = M68K::SSW_BUS_W | bus.fc2 | M68K::FC_DATA; + bus.laddr = addr; + bus.data = data; + write_16_bus(); } void -m68030_write_32(m68kcpu *cpu, uint32 addr, uint32 data) +MPU680x0Device::write_32(uint32 addr, uint32 data) { - cpu->bus.ssw = SSW_BUS_W | cpu->bus.fc2 | FC_DATA; - cpu->bus.laddr = addr; - cpu->bus.data = data; - m68030_write_32_bus(cpu); + bus.ssw = M68K::SSW_BUS_W | bus.fc2 | M68K::FC_DATA; + bus.laddr = addr; + bus.data = data; + write_32_bus(); } // @@ -433,52 +201,52 @@ m68030_write_32(m68kcpu *cpu, uint32 add // uint32 -m68030_read_8_fc(m68kcpu *cpu, uint32 addr) +MPU680x0Device::read_8_fc(uint32 addr) { - cpu->bus.ssw = SSW_BUS_R | RegSFC; - cpu->bus.laddr = addr; - return m68030_read_8_bus(cpu); + bus.ssw = M68K::SSW_BUS_R | reg.sfc; + bus.laddr = addr; + return read_8_bus(); } uint32 -m68030_read_16_fc(m68kcpu *cpu, uint32 addr) +MPU680x0Device::read_16_fc(uint32 addr) { - cpu->bus.ssw = SSW_BUS_R | RegSFC; - cpu->bus.laddr = addr; - return m68030_read_16_bus(cpu); + bus.ssw = M68K::SSW_BUS_R | reg.sfc; + bus.laddr = addr; + return read_16_bus(); } uint32 -m68030_read_32_fc(m68kcpu *cpu, uint32 addr) +MPU680x0Device::read_32_fc(uint32 addr) { - cpu->bus.ssw = SSW_BUS_R | RegSFC; - cpu->bus.laddr = addr; - return m68030_read_32_bus(cpu); + bus.ssw = M68K::SSW_BUS_R | reg.sfc; + bus.laddr = addr; + return read_32_bus(); } void -m68030_write_8_fc(m68kcpu *cpu, uint32 addr, uint32 data) +MPU680x0Device::write_8_fc(uint32 addr, uint32 data) { - cpu->bus.ssw = SSW_BUS_W | RegDFC; - cpu->bus.laddr = addr; - cpu->bus.data = data; - m68030_write_8_bus(cpu); + bus.ssw = M68K::SSW_BUS_W | reg.dfc; + bus.laddr = addr; + bus.data = data; + write_8_bus(); } void -m68030_write_16_fc(m68kcpu *cpu, uint32 addr, uint32 data) +MPU680x0Device::write_16_fc(uint32 addr, uint32 data) { - cpu->bus.ssw = SSW_BUS_W | RegDFC; - cpu->bus.laddr = addr; - cpu->bus.data = data; - m68030_write_16_bus(cpu); + bus.ssw = M68K::SSW_BUS_W | reg.dfc; + bus.laddr = addr; + bus.data = data; + write_16_bus(); } void -m68030_write_32_fc(m68kcpu *cpu, uint32 addr, uint32 data) +MPU680x0Device::write_32_fc(uint32 addr, uint32 data) { - cpu->bus.ssw = SSW_BUS_W | RegDFC; - cpu->bus.laddr = addr; - cpu->bus.data = data; - m68030_write_32_bus(cpu); + bus.ssw = M68K::SSW_BUS_W | reg.dfc; + bus.laddr = addr; + bus.data = data; + write_32_bus(); }