--- nono/vm/iocon.cpp 2026/04/29 17:04:28 1.1 +++ nono/vm/iocon.cpp 2026/04/29 17:04:32 1.1.1.2 @@ -6,7 +6,7 @@ #include "iocon.h" #include "mpu.h" -IOConDevice *gIOCon; +std::unique_ptr gIOCon; IOConDevice::IOConDevice() { @@ -20,12 +20,24 @@ IOConDevice::~IOConDevice() { } +inline uint64 +IOConDevice::Decoder(uint32 addr) const +{ + // 折り返しは? + addr -= baseaddr; + + // 偶数アドレスはバスエラー + if ((addr & 1) == 0) + return (uint64)-1; + + return addr >> 1; +} + uint64 IOConDevice::Read8(uint32 addr) { - uint32 offset = addr - baseaddr; - switch (offset) { - case 1: // $E9C001 割り込みステータス + switch (Decoder(addr)) { + case 0: // $E9C001 割り込みステータス return (fdc_int ? 0x80 : 0) | (fdd_int ? 0x40 : 0) | (prt_int ? 0x20 : 0) @@ -34,7 +46,7 @@ IOConDevice::Read8(uint32 addr) | (fdc_en ? 0x04 : 0) | (fdd_en ? 0x02 : 0) | (prt_en ? 0x01 : 0); - case 3: // $E9C003 割り込みベクタ + case 1: // $E9C003 割り込みベクタ return vector; break; } @@ -50,9 +62,8 @@ IOConDevice::Read16(uint32 addr) uint64 IOConDevice::Write8(uint32 addr, uint32 data) { - uint32 offset = addr - baseaddr; - switch (offset) { - case 1: // $E9C001 割り込みマスク + switch (Decoder(addr)) { + case 0: // $E9C001 割り込みマスク hdd_en = (data & 0x08); fdc_en = (data & 0x04); fdd_en = (data & 0x02); @@ -60,7 +71,7 @@ IOConDevice::Write8(uint32 addr, uint32 putlog(1, "割り込みマスク設定 HDD=%d FDC=%d FDD=%d PRT=%d", hdd_en, fdc_en, fdd_en, prt_en); return 0; - case 3: // $E9C003 割り込みベクタ + case 1: // $E9C003 割り込みベクタ vector = data & 0xfc; putlog(1, "割り込みベクタ設定 $%02x", vector); return 0; @@ -79,9 +90,8 @@ IOConDevice::Write16(uint32 addr, uint32 uint64 IOConDevice::Peek8(uint32 addr) { - uint32 offset = addr - baseaddr; - switch (offset) { - case 1: + switch (Decoder(addr)) { + case 0: return (fdc_int ? 0x80 : 0) | (fdd_int ? 0x40 : 0) | (prt_int ? 0x20 : 0) @@ -91,7 +101,7 @@ IOConDevice::Peek8(uint32 addr) | (fdd_en ? 0x02 : 0) | (prt_en ? 0x01 : 0); - case 3: + case 1: return vector; default: @@ -106,7 +116,7 @@ IOConDevice::IntFDC() fdc_int = true; if (fdc_en) { putlog(1, "FDC からの割り込み要求"); - gMPU->Interrupt(1, vector + 0); + gMPU680x0->Interrupt(1, vector + 0); } else { putlog(2, "FDC からの割り込み要求(マスク)"); }