--- nono/vm/mpu88xx0.cpp 2026/04/29 17:04:55 1.1.1.8 +++ nono/vm/mpu88xx0.cpp 2026/04/29 17:04:59 1.1.1.9 @@ -107,6 +107,120 @@ MPU88xx0Device::Interrupt(int level) cpu->Interrupt(level); } +// DOS call エミュレーションのコールバックを指定 +void +MPU88xx0Device::SetFLineCallback(bool (*callback)(m88kcpu *, void *), void *arg) +{ + cpu->SetFLineCallback(callback, arg); +} + +// MPU からのアクセスをエミュレート +uint64 +MPU88xx0Device::Read8(uint32 addr) +{ + return cpu->cmmu[1].load_8(addr); +} + +uint64 +MPU88xx0Device::Read16(uint32 addr) +{ + if ((addr & 1) == 0) { + return cpu->cmmu[1].load_16(addr); + } else { + uint64 h, l; + h = Read8(addr); + if ((int64)h < 0) { + return h; + } + l = Read8(addr + 1); + if ((int64)l < 0) { + return l; + } + return (h << 8) | l; + } +} + +uint64 +MPU88xx0Device::Read32(uint32 addr) +{ + if ((addr & 3) == 0) { + return cpu->cmmu[1].load_32(addr); + } else if ((addr & 1) == 0) { + uint64 h, l; + h = Read16(addr); + if ((int64)h < 0) { + return h; + } + l = Read16(addr + 2); + if ((int64)l < 0) { + return l; + } + return (h << 16) | l; + } else { + uint64 h, m, l; + h = Read8(addr); + if ((int64)h < 0) { + return h; + } + m = Read16(addr + 1); + if ((int64)m < 0) { + return m; + } + l = Read8(addr + 3); + if ((int64)l < 0) { + return l; + } + return (h << 24) | (m << 8) | l; + } +} + +uint64 +MPU88xx0Device::Write8(uint32 addr, uint32 data) +{ + return cpu->cmmu[1].store_8(addr, data & 0xff); +} + +uint64 +MPU88xx0Device::Write16(uint32 addr, uint32 data) +{ + if ((addr & 1) == 0) { + return cpu->cmmu[1].store_16(addr, data & 0xffff); + } else { + uint64 r; + r = Write8(addr, data >> 8); + if ((int64)r < 0) { + return r; + } + return Write8(addr + 1, data); + } +} + +uint64 +MPU88xx0Device::Write32(uint32 addr, uint32 data) +{ + if ((addr & 3) == 0) { + return cpu->cmmu[1].store_32(addr, data); + } else if ((addr & 1) == 0) { + uint64 r; + r = Write16(addr, data >> 16); + if ((int64)r < 0) { + return r; + } + return Write16(addr + 2, data); + } else { + uint64 r; + r = Write8(addr, data >> 24); + if ((int64)r < 0) { + return r; + } + r = Write16(addr + 1, data >> 8); + if ((int64)r < 0) { + return r; + } + return Write8(addr + 3, data); + } +} + // モニター更新 void MPU88xx0Device::MonitorUpdate(Monitor *, TextScreen& screen)