--- nono/vm/pio.cpp 2026/04/29 17:05:33 1.1.1.15 +++ nono/vm/pio.cpp 2026/04/29 17:06:00 1.1.1.19 @@ -27,8 +27,10 @@ // +------------+ #include "pio.h" +#include "adpcm.h" #include "bitops.h" #include "dipsw.h" +#include "event.h" #include "interrupt.h" #include "lcd.h" #include "mainapp.h" @@ -111,7 +113,7 @@ i8255Device::PokePort(uint32 offset, uin // 共通部分を表示。 // 戻り値は表示を終えた次の行。 int -i8255Device::MonitorUpdateCommon(TextScreen& screen, int y) +i8255Device::MonitorScreenCommon(TextScreen& screen, int y) { // Control = $xx // GroupA (PortA,PortCH) Mode: 0(Basic I/O) @@ -163,6 +165,15 @@ PPIDevice::~PPIDevice() { } +// 初期化 +bool +PPIDevice::Init() +{ + adpcm = GetADPCMDevice(); + + return true; +} + busdata PPIDevice::ReadPort(uint32 offset) { @@ -174,8 +185,8 @@ PPIDevice::ReadPort(uint32 offset) data = 0xff; break; case 2: - putlog(0, "Read $e9a005 PortC (NOT IMPLEMENTED)"); - data = 0xff; + data = GetPC(); + putlog(1, "PortC -> $%02x", data.Data()); break; case 3: putlog(0, "Read $e9a007 Ctrl (NOT IMPLEMENTED)"); @@ -221,22 +232,51 @@ PPIDevice::PeekPort(uint32 offset) return 0xff; } +// PortC 読み込み +uint32 +PPIDevice::GetPC() const +{ + uint32 data = 0; + + // パンの状態はこちらで持っていない。 + if (adpcm->GetPanOutR() == false) { + data |= 0x01; + } + if (adpcm->GetPanOutL() == false) { + data |= 0x02; + } + + // サンプリングレートは書き込み値をこちらでも持っている(ADPCMにもある)。 + data |= adpcm_rate << 2; + + // bit4: PC4 (通常 0) + // bit5: PC5 (通常 0) + // bit6: IOA5 (1=ジョイスティック#1のAが押された状態にする, 0=通常) + // bit6: IOA6 (1=ジョイスティック#1のBが押された状態にする, 0=通常) + + return data; +} + // PortC 書き込み void PPIDevice::SetPC(uint pc, uint val) { switch (pc) { case 0: // ADPCM PAN Left Off - pan_left = !val; + adpcm->SetPanOutL(!val); return; case 1: // ADPCM PAN Right Off - pan_right = !val; + adpcm->SetPanOutR(!val); return; case 2: // ADPCM サンプリングレート - adpcm_rate = (adpcm_rate & 2) | val; + adpcm_rate &= ~1U; + adpcm_rate |= val ? 1U : 0; + adpcm->SetRate(adpcm_rate); return; case 3: // ADPCM サンプリングレート - adpcm_rate = (val << 1) | (adpcm_rate & 1); + adpcm_rate &= ~2U; + adpcm_rate |= val ? 2U : 0; + adpcm->SetRate(adpcm_rate); return; case 4: // ジョイスティック #1 コントロール @@ -332,7 +372,7 @@ PIO0Device::PIO0Device() // PIO0/PIO1 monitor = gMonitorManager->Regist(ID_MONITOR_PIO, this); - monitor->func = ToMonitorCallback(&PIO0Device::MonitorUpdate); + monitor->SetCallback(&PIO0Device::MonitorScreen); monitor->SetSize(76, 15); } @@ -345,10 +385,6 @@ PIO0Device::~PIO0Device() bool PIO0Device::Init() { - if (inherited::Init() == false) { - return false; - } - interrupt = GetInterruptDevice(); pio1 = GetPIO1Device(); @@ -474,7 +510,7 @@ PIO0Device::PeekPort(uint32 offset) // PIO0 が PIO0/PIO1 のモニタ両方を担当する。 void -PIO0Device::MonitorUpdate(Monitor *, TextScreen& screen) +PIO0Device::MonitorScreen(Monitor *, TextScreen& screen) { int y; @@ -482,7 +518,7 @@ PIO0Device::MonitorUpdate(Monitor *, Tex // PIO0 screen.Puts(0, 0, "PIO0 (BaseAddr: $49000000)"); - y = MonitorUpdateCommon(screen, 1); + y = MonitorScreenCommon(screen, 1); // PIO0 固有部 uint32 pa = GetPA(); @@ -516,7 +552,7 @@ PIO0Device::MonitorUpdate(Monitor *, Tex // PIO1 移譲 y++; - pio1->MonitorUpdatePIO1(screen, y); + pio1->MonitorScreenPIO1(screen, y); } // PortA (DIP-SW 1) 読み込み @@ -528,7 +564,7 @@ PIO0Device::GetPA() const data |= ((int)dipsw1[i]) << i; } if (msb_first) { - data = bitrev(data); + data = bitrev8(data); } return data & 0xff; } @@ -542,7 +578,7 @@ PIO0Device::GetPB() const data |= ((int)dipsw2[i]) << i; } if (msb_first) { - data = bitrev(data); + data = bitrev8(data); } return data & 0xff; } @@ -665,10 +701,6 @@ PIO1Device::~PIO1Device() bool PIO1Device::Init() { - if (inherited::Init() == false) { - return false; - } - lcd = GetLCDDevice(); mpu64180 = GetMPU64180Device(); powerdev = GetPowerDevice(); @@ -789,12 +821,12 @@ PIO1Device::PeekPort(uint32 offset) // PIO0 の下請け。 void -PIO1Device::MonitorUpdatePIO1(TextScreen& screen, int y) +PIO1Device::MonitorScreenPIO1(TextScreen& screen, int y) { screen.Puts(0, y++, "PIO1 (BaseAddr: $4d000000)"); // 共通部分 - y = MonitorUpdateCommon(screen, y++); + y = MonitorScreenCommon(screen, y++); // PIO1 固有部 screen.Print(1, y++, "PortA(LCDDATA)=$%02x", lcd->Peek());