--- nono/vm/pedec.cpp 2026/04/29 17:05:10 1.1.1.5 +++ nono/vm/pedec.cpp 2026/04/29 17:06:00 1.1.1.13 @@ -21,27 +21,54 @@ // +--| PEDECDevice | (X68030 の Lv1 担当コントローラ) // | +-------------+ // | -// +-- SysCtlrDevice (LUNA88K の割り込みコントローラ) +// +-- SysCtlrDevice (LUNA-88K の割り込みコントローラ) #include "pedec.h" #include "fdc.h" +#include "fdd.h" +#include "mainapp.h" #include "spc.h" -// グローバル参照用 -PEDECDevice *gPEDEC; - // コンストラクタ PEDECDevice::PEDECDevice() - : inherited("PEDEC") + : inherited(OBJ_PEDEC) { - devaddr = baseaddr; - devlen = 0x2000; } // デストラクタ PEDECDevice::~PEDECDevice() { - gPEDEC = NULL; +} + +// 初期化 +bool +PEDECDevice::Init() +{ + interrupt = GetInterruptDevice(); + + // 検索順 + RegistINT(IntmapSPC, "SPC", GetSPCDevice()); + RegistINT(IntmapFDC, "FDC", GetFDCDevice()); + RegistINT(IntmapHDD, "HDD", NULL); + RegistINT(IntmapPRT, "PRT", NULL); + // FDD は4本を共有しているのでいろいろ特別扱い。 + RegistINT(IntmapFDD0, "FDD0", gMainApp.FindObject(OBJ_FDD(0))); + RegistINT(IntmapFDD1, "FDD1", gMainApp.FindObject(OBJ_FDD(1))); + RegistINT(IntmapFDD2, "FDD2", gMainApp.FindObject(OBJ_FDD(2))); + RegistINT(IntmapFDD3, "FDD3", gMainApp.FindObject(OBJ_FDD(3))); + // 名前表示用 + RegistINT(IntmapFDD, "FDD", NULL); + + // 表示順 + disp_list = { + IntmapSPC, + IntmapFDC, + IntmapFDD, + IntmapHDD, + IntmapPRT, + }; + + return true; } // リセット @@ -50,56 +77,71 @@ PEDECDevice::ResetHard(bool poweron) { inherited::ResetHard(poweron); - intmap_enabled = IntmapSPC; + intmap_enable = IntmapSPC; + ChangeInterrupt(); + // XXX vector } -uint64 -PEDECDevice::Read(uint32 offset) +busdata +PEDECDevice::ReadPort(uint32 offset) { + busdata data; + switch (offset) { case 0: // $E9C001 割り込みステータス - return GetStat(); + data = GetStat(); + break; case 1: // $E9C003 割り込みベクタ // 書き込み専用 - return 0xff; + data = 0xff; + break; default: - return 0xff; + data = 0xff; + break; } + + // XXX wait? + data |= BusData::Size1; + return data; } -uint64 -PEDECDevice::Write(uint32 offset, uint32 data) +busdata +PEDECDevice::WritePort(uint32 offset, uint32 data) { switch (offset) { case 0: // $E9C001 割り込みマスク - intmap_enabled = IntmapSPC; - intmap_enabled |= (data & 0x08) ? IntmapHDD : 0; - intmap_enabled |= (data & 0x04) ? IntmapFDC : 0; - intmap_enabled |= (data & 0x02) ? IntmapFDD : 0; - intmap_enabled |= (data & 0x01) ? IntmapPRT : 0; - - putlog(1, "割り込みマスク設定 HDD=%d FDC=%d FDD=%d PRT=%d", - ((intmap_enabled & IntmapHDD) ? 1 : 0), - ((intmap_enabled & IntmapFDC) ? 1 : 0), - ((intmap_enabled & IntmapFDD) ? 1 : 0), - ((intmap_enabled & IntmapPRT) ? 1 : 0)); - return 0; + intmap_enable = IntmapSPC; + intmap_enable |= (data & 0x08) ? IntmapHDD : 0; + intmap_enable |= (data & 0x04) ? IntmapFDC : 0; + intmap_enable |= (data & 0x02) ? IntmapFDD : 0; + intmap_enable |= (data & 0x01) ? IntmapPRT : 0; + + putlog(1, "Set Interrupt Mask HDD=%u FDC=%u FDD=%u PRT=%u", + ((intmap_enable & IntmapHDD) ? 1 : 0), + ((intmap_enable & IntmapFDC) ? 1 : 0), + ((intmap_enable & IntmapFDD) ? 1 : 0), + ((intmap_enable & IntmapPRT) ? 1 : 0)); + break; case 1: // $E9C003 割り込みベクタ vector = data & 0xfc; - putlog(1, "割り込みベクタ設定 $%02x", vector); - return 0; + putlog(1, "Set Interrupt Vector $%02x", vector); + break; default: - return 0; + break; } + + // XXX wait? + busdata r = BusData::Size1; + return r; } -uint64 -PEDECDevice::Peek(uint32 offset) +busdata +PEDECDevice::PeekPort(uint32 offset) { switch (offset) { case 0: @@ -114,29 +156,27 @@ PEDECDevice::Peek(uint32 offset) } } -void -PEDECDevice::MonitorUpdate(TextScreen& screen, uint intr_level, int y) +bool +PEDECDevice::PokePort(uint32 offset, uint32 data) { - struct { - const char *name; - uint32 map; - } table[] = { - { "SPC", IntmapSPC }, - { "FDC", IntmapFDC }, - { "FDD", IntmapFDD }, - { "HDD", IntmapHDD }, - { "PRT", IntmapPRT }, - }; + return false; +} - for (int i = 0; i < countof(table); i++) { - uint32 map = table[i].map; +void +PEDECDevice::MonitorScreen(TextScreen& screen, uint intr_level, int y) +{ + for (uint32 map : disp_list) { int clz = __builtin_clz(map); - screen.Puts(3, y, TA::OnOff(intmap & map), table[i].name); - screen.Print(8, y, "%11" PRIu64, counter[clz]); - - if (intr_level >= 1 || (intmap_enabled & map) == 0) { - screen.Puts(21, y, "Mask"); + screen.Puts(4, y, TA::OnOff(intmap_status & map), GetIntName(map)); + if (intr_level >= 1 || (intmap_enable & map) == 0) { + screen.Puts(11, y, "Mask"); + } + uint64 cnt = counter[clz]; + if (__predict_false(map == IntmapFDD)) { + // FDD は4つの和 + cnt += counter[clz + 1] + counter[clz + 2] + counter[clz + 3]; } + screen.Print(15, y, "%26s", format_number(cnt).c_str()); y++; } } @@ -147,14 +187,14 @@ uint32 PEDECDevice::GetStat() const { uint32 data = 0; - data |= (intmap & IntmapFDC) ? 0x80 : 0; - data |= (intmap & IntmapFDD) ? 0x40 : 0; - data |= (intmap & IntmapPRT) ? 0x20 : 0; - data |= (intmap & IntmapHDD) ? 0x10 : 0; - data |= (intmap_enabled & IntmapHDD) ? 0x08 : 0; - data |= (intmap_enabled & IntmapFDC) ? 0x04 : 0; - data |= (intmap_enabled & IntmapFDD) ? 0x02 : 0; - data |= (intmap_enabled & IntmapPRT) ? 0x01 : 0; + data |= (intmap_status & IntmapFDC) ? 0x80 : 0; + data |= (intmap_status & IntmapFDD) ? 0x40 : 0; + data |= (intmap_status & IntmapPRT) ? 0x20 : 0; + data |= (intmap_status & IntmapHDD) ? 0x10 : 0; + data |= (intmap_enable & IntmapHDD) ? 0x08 : 0; + data |= (intmap_enable & IntmapFDC) ? 0x04 : 0; + data |= (intmap_enable & IntmapFDD) ? 0x02 : 0; + data |= (intmap_enable & IntmapPRT) ? 0x01 : 0; return data; } @@ -164,22 +204,22 @@ PEDECDevice::ChangeInterrupt() { #if 0 // こんなログ出したいかも // ログ表示のためだけ - if ((intmap_enabled & IntmapFDC)) { + if ((intmap_enable & IntmapFDC)) { putlog(1, "FDC からの割り込み要求"); } else { putlog(2, "FDC からの割り込み要求(マスク)"); } #endif - uint32 stat = (intmap & intmap_enabled); - gInterrupt->ChangeINT(this, stat); + uint32 stat = (intmap_status & intmap_enable); + interrupt->ChangeINT(this, stat); } // 割り込みアクノリッジ -int +busdata PEDECDevice::InterruptAcknowledge(int lv) { - uint32 stat = (intmap & intmap_enabled); + uint32 stat = (intmap_status & intmap_enable); // SPC と I/O コントローラ担当の4本どっちが優先かは分からないので // SPC を優先しておくのでいいだろう。 @@ -190,20 +230,9 @@ PEDECDevice::InterruptAcknowledge(int lv if ((stat & IntmapFDC)) { return vector + 0; + } else if ((stat & IntmapFDD)) { + return vector + 1; } else { - VMPANIC("Unknown interrupt acknowledge"); - } -} - -// デバイスから Intmap 値を引く -uint32 -PEDECDevice::GetIntmap(Device *source) const -{ - if (__predict_true(source == gSPC)) { - return IntmapSPC; - } - if (__predict_true(source == gFDC)) { - return IntmapFDC; + return BusData::BusErr; } - VMPANIC("Unsupported interrupt device"); }