From b20e72f37f7f4627d7f184e33aa25ec2bef03163 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 9 Sep 2021 15:39:26 +0200 Subject: [PATCH] Add a Victor V86P disk driver This emulates a JVC-branded controller/drive pair, using RLL encoding, connected via a small connector electrically compatible with ST-506. The controller is ST-506 compatible with an extra command for self-power-off. The option ROM is made by SMS. Commented disassembly is available for study [1]. The disk is a 3.5" 20MiB "made by Victor", labeled JD3824T100 on the outer protective casing, JD3824T00-1 on the actual drive. It's 615/2/34 physically, pretends to be a 614/4/17 so that it's type 3 compatible. [1] https://archive.org/details/v86p-hd --- src/disk/hdc.c | 1 + src/disk/hdc_st506_xt.c | 76 +++++++++++++++++++++++++++++++++++++++++ src/include/86box/hdc.h | 1 + 3 files changed, 78 insertions(+) diff --git a/src/disk/hdc.c b/src/disk/hdc.c index 0f2bc8599..1df1cd39b 100644 --- a/src/disk/hdc.c +++ b/src/disk/hdc.c @@ -115,6 +115,7 @@ static const struct { { &st506_xt_wd1002a_27x_device }, { &st506_xt_wd1004_27x_device }, { &st506_xt_wd1004a_27x_device }, + { &st506_xt_victor_v86p_device }, { &esdi_at_wd1007vse1_device }, { &ide_isa_device }, { &ide_isa_2ch_device }, diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index cedeb1220..ddf137f9c 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -99,6 +99,7 @@ #define WD1002A_27X_BIOS_FILE "roms/hdd/st506/wd1002a_27x-62-000094-032.bin" #define WD1004_27X_BIOS_FILE "roms/hdd/st506/western_digital_WD1004A-27X.bin" #define WD1004A_27X_BIOS_FILE "roms/hdd/st506/western_digital_WD1004A-27X.bin" +#define VICTOR_V86P_BIOS_FILE "roms/machines/v86p/2793VG.10010688.rom" #define ST506_TIME (250 * TIMER_USEC) #define ST506_TIME_MS (1000 * TIMER_USEC) @@ -182,6 +183,7 @@ #define CMD_WRITE_BUFFER 0x0f #define CMD_ALT_TRACK 0x11 #define CMD_INQUIRY_ST11 0x12 /* ST-11 BIOS */ +#define CMD_V86P_POWEROFF 0x1a /* Victor V86P */ #define CMD_RAM_DIAGNOSTIC 0xe0 /* reserved 0xe1 */ /* reserved 0xe2 */ @@ -819,6 +821,29 @@ st506_callback(void *priv) /* For a 615/4/26 we get 666/2/31 geometry. */ st506_xt_log("ST506: drive%i: cyls=%i, heads=%i\n", dev->drive_sel, drive->cfg_cyl, drive->cfg_hpc); + if (dev->type == 23 && drive->cfg_hpc == 2) { + /* + * On Victor V86P, there's a disagreement between + * the physical geometry, what the controller + * pretends it to be, and what the BIOS uses. + * + * The disk physically has 2/34 heads/sectors per + * track, but it is treated as 4/17 in order to + * look like a regular type 3 drive (see [1], + * line 1859). The controller accepts the 4/17 + * geometry, so this should not really matter. + * + * However, the BIOS issues SPECIFY (see [1], + * line 2089) with head count of two. Let's + * hardwire the correct number instead, just like + * the real hardware seems to. + * + * [1] https://archive.org/download/v86p-hd/V86P-HD.TXT + */ + drive->cfg_hpc = 4; + st506_xt_log("ST506: drive%i: corrected to heads=%i\n", + dev->drive_sel, drive->cfg_hpc); + } st506_complete(dev); break; } @@ -949,6 +974,34 @@ st506_callback(void *priv) } break; + case CMD_V86P_POWEROFF: + if (dev->type == 23) { + /* + * Main BIOS (not the option ROM on disk) issues this. + * Not much we can do, since we don't have a physical disk + * to spin down, but handle this anyways so that we log + * something more reasonable than "unknown command". + * + * Entirely undocumented, but this is what's been observed: + * BIOS setting | Command sent + * 1 minutes | 1a 00 00 0c 02 00 + * 2 minutes | 1a 00 00 18 02 00 + * 3 minutes | 1a 00 00 24 02 00 + * 4 minutes | 1a 00 00 30 02 00 + * 5 minutes | 1a 00 00 3c 02 00 + * off | 1a 00 00 00 02 00 + */ + if (dev->command[3]) + st506_xt_log("ST506: Auto power-off in %d seconds (type=%i)\n", + dev->command[3] * 5, dev->type); + else + st506_xt_log("ST506: Auto power-off disabled (type=%i)\n", dev->type); + } else { + st506_error(dev, ERR_BAD_COMMAND); + } + st506_complete(dev); + break; + case CMD_RAM_DIAGNOSTIC: #ifdef ENABLE_ST506_XT_LOG st506_xt_log("ST506: RAM_DIAG\n"); @@ -1485,6 +1538,9 @@ st506_init(const device_t *info) dev->switches |= 0x40; dev->bios_addr = device_get_config_hex20("bios_addr"); break; + case 23: /* Victor V86P (RLL) */ + fn = VICTOR_V86P_BIOS_FILE; + break; } /* Load the ROM BIOS. */ @@ -1605,6 +1661,12 @@ wd1004a_27x_available(void) return (rom_present(WD1004A_27X_BIOS_FILE)); } +static int +victor_v86p_available(void) +{ + return (rom_present(VICTOR_V86P_BIOS_FILE)); +} + // clang-format off static const device_config_t dtc_config[] = { { @@ -2036,3 +2098,17 @@ const device_t st506_xt_wd1004a_27x_device = { .force_redraw = NULL, .config = wd_rll_config }; + +const device_t st506_xt_victor_v86p_device = { + .name = "Victor V86P RLL Fixed Disk Adapter", + .internal_name = "st506_xt_victor_v86p", + .flags = DEVICE_ISA, + .local = (HDD_BUS_MFM << 8) | 23, + .init = st506_init, + .close = st506_close, + .reset = NULL, + { .available = victor_v86p_available }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index 0c20aaa32..bde423337 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -40,6 +40,7 @@ extern const device_t st506_at_wd1003_device; /* st506_at_wd1003 */ extern const device_t st506_xt_wd1004a_wx1_device; /* st506_xt_wd1004a_wx1 */ extern const device_t st506_xt_wd1004_27x_device; /* st506_xt_wd1004_27x */ extern const device_t st506_xt_wd1004a_27x_device; /* st506_xt_wd1004a_27x */ +extern const device_t st506_xt_victor_v86p_device; /* st506_xt_victor_v86p */ extern const device_t esdi_at_wd1007vse1_device; /* esdi_at */ extern const device_t esdi_ps2_device; /* esdi_mca */