diff --git a/src/disk/hdc.c b/src/disk/hdc.c index ce5d2e257..4523132aa 100644 --- a/src/disk/hdc.c +++ b/src/disk/hdc.c @@ -92,6 +92,7 @@ static const struct { /* PCI */ { &ide_cmd646_ter_qua_device }, { &ide_cmd648_ter_qua_device }, + { &ide_cmd649_ter_qua_device }, { &ide_pci_device }, { &ide_pci_2ch_device }, { NULL } diff --git a/src/disk/hdc_ide_cmd646.c b/src/disk/hdc_ide_cmd646.c index b2e80f2fd..052871a7d 100644 --- a/src/disk/hdc_ide_cmd646.c +++ b/src/disk/hdc_ide_cmd646.c @@ -42,15 +42,18 @@ #include "cpu.h" #include "x86.h" -#define CMD_TYPE_646 0x000000 -#define CMD_TYPE_648 0x100000 +#define CMD_TYPE_646 0x0000000 +#define CMD_TYPE_648 0x0100000 +#define CMD_TYPE_649 0x0200000 -#define CMD648_JP7 0x200000 /* Reload subsystem ID on reset. */ -#define CMD648_RAID 0x400000 +#define CMD648_JP7 0x0400000 /* Reload subsystem ID on reset. */ +#define CMD648_RAID 0x0800000 -#define CMD64X_ONBOARD 0x800000 +#define CMD64X_ONBOARD 0x1000000 -#define CMD648_BIOS_FILE "roms/hdd/ide/648_1910.bin" +#define CMD648_BIOS_FILE "roms/hdd/ide/648_1910.bin" +#define CMD649_REV_1914_BIOS_FILE "roms/hdd/ide/649_1914.bin" +#define CMD649_REV_2301_BIOS_FILE "roms/hdd/ide/649_2301.bin" typedef struct cmd646_t { uint8_t vlb_idx; @@ -62,6 +65,8 @@ typedef struct cmd646_t { uint32_t local; uint32_t rom_addr; + uint32_t rom_addr_size; + uint32_t rom_addr_mask; int irq_pin; int has_bios; @@ -228,10 +233,16 @@ cmd646_bm_write(uint16_t port, uint8_t val, void *priv) dev->regs[0x57] &= ~0x10; ret &= 0x03; break; + case 0x0003: + dev->regs[0x73] = val; + break; case 0x0009: dev->regs[(port & 0x000f) | 0x70] = (dev->regs[(port & 0x000f) | 0x70] & 0x0f) | (val & 0xf0); ret &= 0x03; break; + case 0x000b: + dev->regs[0x7b] = val; + break; } return ret; @@ -250,9 +261,15 @@ cmd646_bm_read(uint16_t port, uint8_t val, void *priv) case 0x0002: case 0x000a: ret |= 0x08; break; + case 0x0003: + ret = dev->regs[0x73]; + break; case 0x0009: ret = dev->regs[(port & 0x000f) | 0x70]; break; + case 0x000b: + ret = dev->regs[0x7b]; + break; } return ret; @@ -264,13 +281,13 @@ cmd646_bios_handler(cmd646_t *dev) if ((dev->local & CMD_TYPE_648) && dev->has_bios) { uint32_t *addr = (uint32_t *) &(dev->regs[0x30]); - *addr &= 0xffffc001; + *addr &= (~dev->rom_addr_mask) | 0x00000001; dev->rom_addr = *addr & 0xfffffff0; cmd646_log("ROM address now: %08X\n", dev->rom_addr); if ((dev->regs[0x04] & 0x02) && (*addr & 0x00000001)) - mem_mapping_set_addr(&dev->bios_rom.mapping, dev->rom_addr, 0x00004000); + mem_mapping_set_addr(&dev->bios_rom.mapping, dev->rom_addr, dev->rom_addr_size); else mem_mapping_disable(&dev->bios_rom.mapping); } @@ -300,8 +317,15 @@ cmd646_pci_write(int func, int addr, uint8_t val, void *priv) cmd646_bios_handler(dev); break; + case 0x05: + if (dev->local & CMD_TYPE_648) + dev->regs[addr] = (dev->regs[addr] & 0x7e) | (val & 0x01); + break; case 0x07: - dev->regs[addr] &= ~(val & 0xb1); + if (dev->local & CMD_TYPE_648) + dev->regs[addr] = ((dev->regs[addr] & ~(val & 0xb9)) & 0xbf) | (val & 0x40); + else + dev->regs[addr] &= ~(val & 0xb1); break; case 0x09: if (!(dev->local & CMD_TYPE_648) || @@ -409,7 +433,7 @@ cmd646_pci_write(int func, int addr, uint8_t val, void *priv) dev->regs[addr] = val; break; case 0x59: - if (!(dev->local & CMD_TYPE_648)) + if ((dev->local & CMD_TYPE_649) || !(dev->local & CMD_TYPE_648)) dev->regs[addr] = val; break; case 0x53: @@ -529,21 +553,25 @@ cmd646_reset(void *priv) dev->regs[0x00] = 0x95; /* CMD */ dev->regs[0x01] = 0x10; - if (dev->local & CMD_TYPE_648) + if (dev->local & CMD_TYPE_649) + dev->regs[0x02] = 0x49; /* PCI-0649 */ + else if (dev->local & CMD_TYPE_648) dev->regs[0x02] = 0x48; /* PCI-0648 */ else dev->regs[0x02] = 0x46; /* PCI-0646 */ dev->regs[0x03] = 0x06; dev->regs[0x04] = 0x00; - dev->regs[0x06] = 0x80; dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */ if ((dev->local & CMD_TYPE_648) && (dev->local & CMD648_RAID)) { + dev->regs[0x06] = 0x90; + dev->regs[0x08] = 0x02; dev->regs[0x09] = 0x00; /* Programming interface */ dev->regs[0x0a] = 0x04; /* RAID controller */ dev->regs[0x50] = 0x40; /* Enable Base address register R/W; If 0, they return 0 and are read-only 8 */ } else { + dev->regs[0x06] = 0x80; dev->regs[0x09] = dev->local; /* Programming interface */ dev->regs[0x0a] = 0x01; /* IDE controller */ } @@ -578,12 +606,20 @@ cmd646_reset(void *priv) if (!dev->single_channel) dev->regs[0x51] = 0x08; + dev->regs[0x57] = 0x0c; + if (dev->local & CMD_TYPE_648) { dev->regs[0x34] = 0x60; dev->regs[0x4f] = (dev->local & CMD648_JP7) ? 0x02 : 0x00; dev->regs[0x51] |= 0x04; + if (dev->local & CMD_TYPE_649) { + dev->regs[0x57] |= 0x80; + dev->regs[0x59] = 0x40; + } else + dev->regs[0x57] |= 0xc0; + dev->regs[0x60] = 0x01; dev->regs[0x62] = 0x21; dev->regs[0x63] = 0x06; @@ -597,8 +633,6 @@ cmd646_reset(void *priv) } else dev->regs[0x59] = 0x40; - dev->regs[0x57] = 0x0c; - dev->irq_pin = PCI_INTA; if ((dev->local & CMD_TYPE_648) && (dev->local & CMD648_RAID)) @@ -670,8 +704,24 @@ cmd646_init(const device_t *info) dev->has_bios = device_get_config_int("bios"); if (dev->has_bios) { - rom_init(&dev->bios_rom, CMD648_BIOS_FILE, - 0x000c8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + char *fn = NULL; + + if (dev->local & CMD_TYPE_649) { + const char *bios_rev = (char *) device_get_config_bios("bios_rev"); + fn = (char *) device_get_bios_file(info, bios_rev, 0); + + dev->rom_addr_size = device_get_bios_file_size(info, bios_rev); + } else { + fn = CMD648_BIOS_FILE; + + dev->rom_addr_size = 0x00004000; + } + + dev->rom_addr_mask = dev->rom_addr_size - 1; + + rom_init(&dev->bios_rom, fn, + 0x000d0000, dev->rom_addr_size, dev->rom_addr_mask, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&dev->bios_rom.mapping); } } @@ -701,11 +751,57 @@ static const device_config_t cmd648_config[] = { }; // clang-format on +static const device_config_t cmd649_config[] = { + { + .name = "bios", + .description = "Enable BIOS", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "bios_rev", + .description = "BIOS Revision", + .type = CONFIG_BIOS, + .default_string = "rev_2301", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .bios = { + { + .name = "Revision 1.9.14", + .internal_name = "rev_1914", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 16384, + .files = { CMD649_REV_2301_BIOS_FILE, "" } + }, + { + .name = "Revision 2.3.01", + .internal_name = "rev_2301", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 65536, + .files = { CMD649_REV_2301_BIOS_FILE, "" } + }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + const device_t ide_cmd646_device = { .name = "CMD PCI-0646", .internal_name = "ide_cmd646", .flags = DEVICE_PCI, - .local = 0x8a | CMD64X_ONBOARD, + .local = 0x000008a | CMD64X_ONBOARD, .init = cmd646_init, .close = cmd646_close, .reset = cmd646_reset, @@ -719,7 +815,7 @@ const device_t ide_cmd646_legacy_only_device = { .name = "CMD PCI-0646 (Legacy Mode Only)", .internal_name = "ide_cmd646_legacy_only", .flags = DEVICE_PCI, - .local = 0x80 | CMD64X_ONBOARD, + .local = 0x0000080 | CMD64X_ONBOARD, .init = cmd646_init, .close = cmd646_close, .reset = cmd646_reset, @@ -733,7 +829,7 @@ const device_t ide_cmd646_single_channel_device = { .name = "CMD PCI-0646 (Single Channel)", .internal_name = "ide_cmd646_single_channel", .flags = DEVICE_PCI, - .local = 0x2008a | CMD64X_ONBOARD, + .local = 0x002008a | CMD64X_ONBOARD, .init = cmd646_init, .close = cmd646_close, .reset = cmd646_reset, @@ -747,7 +843,7 @@ const device_t ide_cmd646_ter_qua_device = { .name = "CMD PCI-0646 (Tertiary and Quaternary)", .internal_name = "ide_cmd646_ter_qua", .flags = DEVICE_PCI, - .local = 0x8008f, + .local = 0x008008f, .init = cmd646_init, .close = cmd646_close, .reset = cmd646_reset, @@ -761,7 +857,7 @@ const device_t ide_cmd648_ter_qua_device = { .name = "CMD PCI-0648 (Tertiary and Quaternary)", .internal_name = "ide_cmd648_ter_qua", .flags = DEVICE_PCI, - .local = 0x78008f, + .local = 0x0d8008f, .init = cmd646_init, .close = cmd646_close, .reset = cmd646_reset, @@ -775,7 +871,7 @@ const device_t ide_cmd648_ter_qua_onboard_device = { .name = "CMD PCI-0648 (Tertiary and Quaternary) On-Board", .internal_name = "ide_cmd648_ter_qua_onboard", .flags = DEVICE_PCI, - .local = 0x78008f | CMD64X_ONBOARD, + .local = 0x0d8008f | CMD64X_ONBOARD, .init = cmd646_init, .close = cmd646_close, .reset = cmd646_reset, @@ -784,3 +880,17 @@ const device_t ide_cmd648_ter_qua_onboard_device = { .force_redraw = NULL, .config = NULL }; + +const device_t ide_cmd649_ter_qua_device = { + .name = "CMD PCI-0649 (Tertiary and Quaternary)", + .internal_name = "ide_cmd649_ter_qua", + .flags = DEVICE_PCI, + .local = 0x0f8008f, + .init = cmd646_init, + .close = cmd646_close, + .reset = cmd646_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = cmd649_config +}; diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index 90ff6e2bc..f0cf64361 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -81,6 +81,7 @@ extern const device_t ide_cmd646_single_channel_device; /* CMD PCI-646 ( extern const device_t ide_cmd646_ter_qua_device; /* CMD PCI-646 (Tertiary and quaternary channels) */ extern const device_t ide_cmd648_ter_qua_device; /* CMD PCI-648 (Tertiary and quaternary channels) */ extern const device_t ide_cmd648_ter_qua_onboard_device; /* CMD PCI-648 (Tertiary and quaternary channels, on-board) */ +extern const device_t ide_cmd649_ter_qua_device; /* CMD PCI-649 (Tertiary and quaternary channels) */ extern const device_t ide_opti611_vlb_device; /* OPTi 82c611/611A VLB */ extern const device_t ide_opti611_vlb_sec_device; /* OPTi 82c611/611A VLB (Secondary channel) */