--- nono/vm/pio.cpp 2026/04/29 17:05:18 1.1.1.12 +++ nono/vm/pio.cpp 2026/04/29 17:05:25 1.1.1.13 @@ -143,6 +143,9 @@ i8255Device::MonitorUpdateCommon(TextScr // X68k PPI // +// InsideOut p.135 +static const busdata ppi_wait = busdata::Wait(19 * 40_nsec); + // コンストラクタ PPIDevice::PPIDevice() : inherited(OBJ_PPI) @@ -154,31 +157,35 @@ PPIDevice::~PPIDevice() { } -uint64 +busdata PPIDevice::Read(uint32 offset) { - mpu->AddCycle(19); // InsideOut p.135 + busdata data; switch (offset) { case 0: case 1: - return 0xff; + data = 0xff; + break; case 2: putlog(0, "Read $e9a005 PortC (NOT IMPLEMENTED)"); - return 0xff; + data = 0xff; + break; case 3: putlog(0, "Read $e9a007 Ctrl (NOT IMPLEMENTED)"); - return 0xff; + data = 0xff; + break; default: VMPANIC("corrupted offset=%d", offset); } + + data |= ppi_wait; + return data; } -uint64 +busdata PPIDevice::Write(uint32 offset, uint32 data) { - mpu->AddCycle(19); // InsideOut p.135 - switch (offset) { case 0: case 1: @@ -195,10 +202,10 @@ PPIDevice::Write(uint32 offset, uint32 d default: VMPANIC("corrupted offset=%d", offset); } - return 0; + return ppi_wait; } -uint64 +busdata PPIDevice::Peek(uint32 offset) { // XXX @@ -359,7 +366,7 @@ PIO0Device::ResetHard(bool poweron) } } -uint64 +busdata PIO0Device::Read(uint32 offset) { uint32 data; @@ -374,7 +381,7 @@ PIO0Device::Read(uint32 offset) ChangeInterrupt(); putlog(1, "DIP-SW1 -> $%02x", data); - return data; + break; case 1: // PortB @@ -385,49 +392,55 @@ PIO0Device::Read(uint32 offset) ChangeInterrupt(); putlog(1, "DIP-SW2 -> $%02x", data); - return data; + break; case 2: // PortC data = GetPC(); putlog(1, "PortC -> $%02x", data); - return data; + break; case 3: data = ReadCtrl(); putlog(1, "Ctrl -> $%02x", data); - return data; + break; default: VMPANIC("corrupted offset=%d", offset); } + + // XXX wait? + return data; } -uint64 +busdata PIO0Device::Write(uint32 offset, uint32 data) { switch (offset) { case 0: // PIO0 PortA: DIPSW1 (入力のみ) case 1: // PIO0 PortB: DIPSW2 (入力のみ) - return 0; + break; case 2: // PIO0 PortC: ホスト割り込み制御 for (int i = 0; i < 8; i++) { SetPC(i, data & 1); data >>= 1; } - return 0; + break; case 3: // コントロール WriteCtrl(data); - return 0; + break; default: VMPANIC("corrupted offset=%d", offset); } + + // XXX wait? + return 0; } -uint64 +busdata PIO0Device::Peek(uint32 offset) { switch (offset) { @@ -664,7 +677,7 @@ PIO1Device::ResetHard(bool poweron) powerdev->SetSystemPowerOn(false); } -uint64 +busdata PIO1Device::Read(uint32 offset) { uint32 data; @@ -672,11 +685,13 @@ PIO1Device::Read(uint32 offset) switch (offset) { case 0: // PIO1 PortA: LCD データ - return lcd->Read(); + data = lcd->Read(); + break; case 1: // PIO1 PortB: 無効 - return 0xff; + data = 0xff; + break; case 2: // PortC @@ -685,49 +700,55 @@ PIO1Device::Read(uint32 offset) // 残りのビットは %1 だろうか? data |= 0x0d; putlog(1, "PortC -> $%02x", data); - return data; + break; case 3: data = ReadCtrl(); putlog(1, "Ctrl -> $%02x", data); - return data; + break; default: VMPANIC("corrupted offset=%d", offset); } + + // XXX wait? + return data; } -uint64 +busdata PIO1Device::Write(uint32 offset, uint32 data) { switch (offset) { case 0: // PIO1 PortA: LCD データ lcd->Write(data); - return 0; + break; case 1: // PIO1 PortB: XP の INT0 をアサート // データ不問でアサートする。 putlog(1, "Assert XP INT0"); mpu64180->AssertINT0(); - return 0; + break; case 2: // PIO1 PortC: LCD/パワーオフ制御 for (int i = 0; i < 8; i++) { SetPC(i, data & 1); data >>= 1; } - return 0; + break; case 3: // コントロール WriteCtrl(data); - return 0; + break; default: VMPANIC("corrupted offset=%d", offset); } + + // XXX wait? + return 0; } -uint64 +busdata PIO1Device::Peek(uint32 offset) { switch (offset) {