From 002bc92cad875ea6b838623438740a2a00899676 Mon Sep 17 00:00:00 2001 From: Szymon Rakowski <4791668+s-rakowski@users.noreply.github.com> Date: Sat, 9 May 2026 18:44:30 +0200 Subject: [PATCH 1/2] Add Quirks flag for PC-9801-55 --- lib/SCSI2SD/include/scsi2sd.h | 3 ++- lib/SCSI2SD/src/firmware/mode.c | 34 ++++++++++++++++++++++++++++----- src/BlueSCSI.cpp | 2 ++ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/lib/SCSI2SD/include/scsi2sd.h b/lib/SCSI2SD/include/scsi2sd.h index d1d39f28..858531db 100755 --- a/lib/SCSI2SD/include/scsi2sd.h +++ b/lib/SCSI2SD/include/scsi2sd.h @@ -92,7 +92,8 @@ typedef enum S2S_CFG_QUIRKS_XEBEC = 4, S2S_CFG_QUIRKS_VMS = 8, S2S_CFG_QUIRKS_X68000 = 16, - S2S_CFG_QUIRKS_EWSD = 32 + S2S_CFG_QUIRKS_EWSD = 32, + S2S_CFG_QUIRKS_PC98_55 = 64 } S2S_CFG_QUIRKS; typedef enum diff --git a/lib/SCSI2SD/src/firmware/mode.c b/lib/SCSI2SD/src/firmware/mode.c index 0cac7275..d5d88546 100755 --- a/lib/SCSI2SD/src/firmware/mode.c +++ b/lib/SCSI2SD/src/firmware/mode.c @@ -402,6 +402,14 @@ static void doModeSense( } } + // The PC-9801-55 SCSI-1 controller, and its derivatives will + // ask for all pages (0x3F), expecting only those pages back: + // 0x01 - Read-write error recovery page + // 0x03 - Format device page + // 0x04 - Rigid disk geometry page + // This quirk is expected to be used with SCSI-1 mode only + uint8_t oldNecHddMode = scsiDev.target->cfg->quirks == S2S_CFG_QUIRKS_PC98_55; + ////////////// Block Descriptor //////////////////////////////////// if (!dbd) @@ -410,9 +418,15 @@ static void doModeSense( // Number of blocks // Zero == all remaining blocks shall have the medium // characteristics specified. - scsiDev.data[idx++] = 0; - scsiDev.data[idx++] = 0; - scsiDev.data[idx++] = 0; + uint32_t blocks = 0; + if (oldNecHddMode) + { + // NEC PC-9801-55 needs explicit block count + blocks = scsiDev.target->cfg->scsiSectors; + } + scsiDev.data[idx++] = (blocks >> 16) & 0xFF; + scsiDev.data[idx++] = (blocks >> 8) & 0xFF; + scsiDev.data[idx++] = blocks & 0xFF; scsiDev.data[idx++] = 0; // reserved @@ -440,7 +454,7 @@ static void doModeSense( } } - if (pageCode == 0x02 || pageCode == 0x3F) + if (!oldNecHddMode && (pageCode == 0x02 || pageCode == 0x3F)) { pageFound = 1; if ((scsiDev.compatMode >= COMPAT_SCSI2)) @@ -462,6 +476,16 @@ static void doModeSense( pageIn(pc, idx, FormatDevicePage, sizeof(FormatDevicePage)); if (pc != 0x01) { + if (oldNecHddMode) + { + // This mimics ArdSCSino-stm32 behavior, + // setting "Tracks per zone" to heads per cylinder value + // If left as 0, PC-9801FA doesn't detect the drive properly + scsiDev.data[idx+2] = 0x00; + scsiDev.data[idx+3] = scsiDev.target->cfg->headsPerCylinder; + // Interleave field + scsiDev.data[idx+15] = 0x00; + } uint16_t sectorsPerTrack = scsiDev.target->cfg->sectorsPerTrack; scsiDev.data[idx+10] = sectorsPerTrack >> 8; scsiDev.data[idx+11] = sectorsPerTrack & 0xFF; @@ -627,7 +651,7 @@ static void doModeSense( } // SCSI 2 standard says page 0 is always last. - if (pageCode == 0x00 || pageCode == 0x3F) + if (!oldNecHddMode && (pageCode == 0x00 || pageCode == 0x3F)) { pageFound = 1; pageIn(pc, idx, OperatingPage, sizeof(OperatingPage)); diff --git a/src/BlueSCSI.cpp b/src/BlueSCSI.cpp index 828df74f..9f55667c 100644 --- a/src/BlueSCSI.cpp +++ b/src/BlueSCSI.cpp @@ -260,6 +260,8 @@ static const char * quirksToChar(int quirks) { switch (quirks) { + case S2S_CFG_QUIRKS_PC98_55: + return "PC-9801-55"; case S2S_CFG_QUIRKS_APPLE: return "Apple"; case S2S_CFG_QUIRKS_OMTI: From 4747366703715bf3889a8cf1a329eaade2e2bd05 Mon Sep 17 00:00:00 2001 From: Szymon Rakowski <4791668+s-rakowski@users.noreply.github.com> Date: Sat, 9 May 2026 19:24:54 +0200 Subject: [PATCH 2/2] Add PC-9801-55 system preset --- src/BlueSCSI_settings.cpp | 21 +++++++++++++++++++-- src/BlueSCSI_settings.h | 1 + 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/BlueSCSI_settings.cpp b/src/BlueSCSI_settings.cpp index 5ec06827..340fa370 100644 --- a/src/BlueSCSI_settings.cpp +++ b/src/BlueSCSI_settings.cpp @@ -36,7 +36,7 @@ // SCSI system and device settings BlueSCSISettings g_scsi_settings; -const char *systemPresetName[] = {"", "Mac", "MacPlus", "MPC3000", "MegaSTE", "X68000", "X68000-SCSI", "X68000-SASI", "NeXT", "Generic"}; +const char *systemPresetName[] = {"", "Mac", "MacPlus", "MPC3000", "MegaSTE", "X68000", "X68000-SCSI", "X68000-SASI", "NeXT", "PC-9801-55", "Generic"}; const char *devicePresetName[] = {"", "ST32430N"}; // must be in the same order as bluescsi_speed_grade_t in BlueSCSI_settings.h @@ -539,6 +539,14 @@ scsi_system_settings_t *BlueSCSISettings::initSystem(const char *presetName) cfgSys.enableParity = false; cfgSys.maxSyncSpeed = 5; } + else if (strequals(systemPresetName[SYS_PRESET_PC_9801_55], presetName)) + { + m_sysPreset = SYS_PRESET_PC_9801_55; + cfgSys.quirks = S2S_CFG_QUIRKS_PC98_55; + cfgSys.enableSCSI2 = false; + cfgDev.sectorsPerTrack = 25; + cfgDev.headsPerCylinder = 8; + } else if (strequals(systemPresetName[SYS_PRESET_NeXT], presetName)) { m_sysPreset = SYS_PRESET_NeXT; @@ -558,7 +566,16 @@ scsi_system_settings_t *BlueSCSISettings::initSystem(const char *presetName) } // Clear SCSI device strings - memset(cfgDev.vendor, 0, sizeof(cfgDev.vendor)); + if (m_sysPreset == SYS_PRESET_PC_9801_55) + { + // Controller requires that Vendor starts with "NEC" + const char *necVendor = "NECBLUE"; + strncpy(cfgDev.vendor, necVendor, sizeof(cfgDev.vendor)); + } + else + { + memset(cfgDev.vendor, 0, sizeof(cfgDev.vendor)); + } memset(cfgDev.prodId, 0, sizeof(cfgDev.prodId)); memset(cfgDev.revision, 0, sizeof(cfgDev.revision)); memset(cfgDev.serial, 0, sizeof(cfgDev.serial)); diff --git a/src/BlueSCSI_settings.h b/src/BlueSCSI_settings.h index 8b7e11d2..bab498ff 100644 --- a/src/BlueSCSI_settings.h +++ b/src/BlueSCSI_settings.h @@ -62,6 +62,7 @@ typedef enum SYS_PRESET_X68000_SCSI, SYS_PRESET_X68000_SASI, SYS_PRESET_NeXT, + SYS_PRESET_PC_9801_55, SYS_PRESET_GENERIC, } scsi_system_preset_t;