--- nono/vm/crtc.cpp 2026/04/29 17:05:28 1.1.1.12 +++ nono/vm/crtc.cpp 2026/04/29 17:05:59 1.1.1.16 @@ -20,21 +20,24 @@ // BusIO は使わず自力で処理する。ログの観点からもこのほうが都合がいい。 #include "crtc.h" +#include "event.h" #include "mfp.h" -#include "renderer.h" +#include "monitor.h" #include "scheduler.h" #include "tvram.h" +#include "videoctlr.h" // InsideOut p.135 -const busdata wait = busdata::Wait(9 * 40_nsec); +/*static*/ const busdata +CRTCDevice::wait = busdata::Wait(9 * 40_nsec); // コンストラクタ CRTCDevice::CRTCDevice() : inherited(OBJ_CRTC) { - monitor.func = ToMonitorCallback(&CRTCDevice::MonitorUpdate); - monitor.SetSize(62, 14); - monitor.Regist(ID_MONITOR_CRTC); + monitor = gMonitorManager->Regist(ID_MONITOR_CRTC, this); + monitor->SetCallback(&CRTCDevice::MonitorScreen); + monitor->SetSize(79, 27); } // デストラクタ @@ -46,30 +49,27 @@ CRTCDevice::~CRTCDevice() bool CRTCDevice::Init() { - if (inherited::Init() == false) { - return false; - } - mfp = GetMFPDevice(); - renderer = GetRenderer(); tvram = GetTVRAMDevice(); + videoctlr = GetVideoCtlrDevice(); - hsync_event.func = ToEventCallback(&CRTCDevice::HSyncCallback); - hsync_event.SetName("CRTC H-Sync"); - vdisp_event.func = ToEventCallback(&CRTCDevice::VDispCallback); - vdisp_event.SetName("CRTC V-Disp"); - scheduler->RegistEvent(hsync_event); - scheduler->RegistEvent(vdisp_event); + auto evman = GetEventManager(); + hsync_event = evman->Regist(this, + ToEventCallback(&CRTCDevice::HSyncCallback), + "CRTC H-Sync"); + vdisp_event = evman->Regist(this, + ToEventCallback(&CRTCDevice::VDispCallback), + "CRTC V-Disp"); // ラスターコピーは実際には CRTC の機能ではなく TVRAM (VRAM チップ) の // 機能だが、イベントの時間管理が発生するのは CRTC 側なのでここで管理。 // X68030 搭載の VRAM チップは HM514402A だが、ここでは X68000 XVI 搭載の // HM53461 の値を使用し、これが最小 190nsec * 2 らしいので // とりあえず 400nsec としておく。 - raster_event.func = ToEventCallback(&CRTCDevice::RasterCallback); - raster_event.time = 400_nsec; - raster_event.SetName("CRTC Raster Copy"); - scheduler->RegistEvent(raster_event); + raster_event = evman->Regist(this, + ToEventCallback(&CRTCDevice::RasterCallback), + "CRTC Raster Copy"); + raster_event->time = 400_nsec; return true; } @@ -83,11 +83,11 @@ CRTCDevice::ResetHard(bool poweron) // XXX 適当 // すぐに水平同期と垂直帰線期間を開始する - hsync_event.time = 0; - hsync_event.code = 1; + hsync_state = 1; + hsync_event->time = 0; scheduler->RestartEvent(hsync_event); - vdisp_event.time = 0; - vdisp_event.code = 1; + vdisp_state = 1; + vdisp_event->time = 0; scheduler->RestartEvent(vdisp_event); } @@ -237,8 +237,32 @@ CRTCDevice::Peek2(uint32 addr) const return data; } +// 今の所、標準設定しかサポートしていないので、違う時だけログを出したりする。 +static const uint16 crtc_supported[] = { + 0x0089, // R00 + 0x000e, // R01 + 0x001c, // R02 + 0x007c, // R03 + 0x0237, // R04 + 0x0005, // R05 + 0x0028, // R06 + 0x0228, // R07 + 0, // R08 + 0, // R09 + 0, // R10 + 0, // R11 + 0x0000, // R12 + 0x0000, // R13 + 0x0000, // R14 + 0x0000, // R15 + 0x0000, // R16 + 0x0000, // R17 + 0x0000, // R18 + 0x0000, // R19 +}; + void -CRTCDevice::MonitorUpdate(Monitor *, TextScreen& screen) +CRTCDevice::MonitorScreen(Monitor *, TextScreen& screen) { int y; uint16 val; @@ -259,31 +283,47 @@ CRTCDevice::MonitorUpdate(Monitor *, Tex screen.Print(0, y++, "R10:$%04x (Text ScrollX)", crtc.r[10]); screen.Print(0, y++, "R11:$%04x (Text ScrollY)", crtc.r[11]); + screen.Print(0, y++, "R12:$%04x (Grp. Page0 X)", crtc.r[12]); + screen.Print(0, y++, "R13:$%04x (Grp. Page0 Y)", crtc.r[13]); + screen.Print(0, y++, "R14:$%04x (Grp. Page1 X)", crtc.r[14]); + screen.Print(0, y++, "R15:$%04x (Grp. Page1 Y)", crtc.r[15]); + screen.Print(0, y++, "R16:$%04x (Grp. Page2 X)", crtc.r[16]); + screen.Print(0, y++, "R17:$%04x (Grp. Page2 Y)", crtc.r[17]); + screen.Print(0, y++, "R18:$%04x (Grp. Page3 X)", crtc.r[18]); + screen.Print(0, y++, "R19:$%04x (Grp. Page3 Y)", crtc.r[19]); + + for (uint i = 0; i < countof(crtc_supported); i++) { + if (8 <= i && i < 12) { + continue; + } + if (crtc.r[i] != crtc_supported[i]) { + screen.Print(29, (i < 8 ? i : i - 2), TA::On, + "(not supported value)"); + } + } + + // 3 4 5 6 7 + // 90123456789012345678901234567890123456789012345678 + // SIZ=1024x1024 COL=65536 HF=31kHz VD=undef HD=50MHz val = crtc.r[20]; screen.Print(0, y, "R20:$%04x (Mode)", val); - screen.Print(29, y, TA::OnOff(val & CRTC::R20_MEM), "MEM"); - static const char * const r20col_str[] = { - "16", - "256", - "undef", - "65536", - }; - screen.Print(33, y, "COL=%s", r20col_str[(val >> 8) & 3]); - screen.Print(43, y, TA::OnOff(val & CRTC::R20_HF), "HF"); + screen.Print(29, y, "SIZ=%s", VideoCtlrDevice::siz_str[(val >> 10) & 1]); + screen.Print(43, y, "COL=%s", VideoCtlrDevice::col_str[(val >> 8) & 3]); + screen.Print(53, y, "HF=%ukHz", 15 + (val & 0x10)); static const char * const r20vd_str[] = { "256", "512", "1024", "undef", }; - screen.Print(46, y, "VD=%s", r20vd_str[(val >> 2) & 3]); + screen.Print(62, y, "VD=%s", r20vd_str[(val >> 2) & 3]); static const char * const r20hd_str[] = { "256", "512", "768", "50MHz", }; - screen.Print(55, y, "HD=%s", r20hd_str[val & 3]); + screen.Print(71, y, "HD=%s", r20hd_str[val & 3]); y++; val = crtc.r[21]; @@ -306,6 +346,11 @@ CRTCDevice::MonitorUpdate(Monitor *, Tex val, (val >> 8), (val & 0xff)); screen.Print(0, y++, "R23:$%04x (Text Access Mask)", crtc.r[23]); + + // ビデオコントローラもここに並べたほうが読みやすいか。 + y++; + screen.Puts(0, y++, "