diff --git a/src/chipset/ali1489.c b/src/chipset/ali1489.c index 822ab7baf..3550f1da6 100644 --- a/src/chipset/ali1489.c +++ b/src/chipset/ali1489.c @@ -41,7 +41,8 @@ #include <86box/chipset.h> -#define DEFINE_SHADOW_PROCEDURE (((dev->regs[0x14] & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x14] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)) +#define DEFINE_SHADOW_PROCEDURE (((dev->regs[0x14] & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | \ + ((dev->regs[0x14] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)) #define DISABLED_SHADOW (MEM_READ_EXTANY | MEM_WRITE_EXTANY) #ifdef ENABLE_ALI1489_LOG @@ -64,19 +65,14 @@ ali1489_log(const char *fmt, ...) typedef struct ali1489_t { uint8_t index; - uint8_t ide_index; - uint8_t ide_chip_id; uint8_t pci_slot; uint8_t regs[256]; uint8_t pci_conf[256]; - uint8_t ide_regs[256]; port_92_t *port_92; smram_t *smram; } ali1489_t; -static void ali1489_ide_handler(ali1489_t *dev); - static void ali1489_shadow_recalc(ali1489_t *dev) { @@ -85,7 +81,8 @@ ali1489_shadow_recalc(ali1489_t *dev) for (uint8_t i = 0; i < 8; i++) { if (dev->regs[0x13] & (1 << i)) { ali1489_log("%06Xh-%06Xh region shadow enabled: read = %i, write = %i\n", - 0xc0000 + (i << 14), 0xc3fff + (i << 14), !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20)); + 0xc0000 + (i << 14), 0xc3fff + (i << 14), + !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20)); mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, DEFINE_SHADOW_PROCEDURE); } else { ali1489_log("%06Xh-%06Xh region shadow disabled\n", 0xc0000 + (i << 14), 0xc3fff + (i << 14)); @@ -96,7 +93,8 @@ ali1489_shadow_recalc(ali1489_t *dev) for (uint8_t i = 0; i < 4; i++) { if (dev->regs[0x14] & (1 << i)) { ali1489_log("%06Xh-%06Xh region shadow enabled: read = %i, write = %i\n", - 0xe0000 + (i << 15), 0xe7fff + (i << 15), !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20)); + 0xe0000 + (i << 15), 0xe7fff + (i << 15), + !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20)); mem_set_mem_state_both(0xe0000 + (i << 15), 0x8000, DEFINE_SHADOW_PROCEDURE); shadowbios |= !!(dev->regs[0x14] & 0x10); shadowbios_write |= !!(dev->regs[0x14] & 0x20); @@ -142,25 +140,9 @@ ali1489_smram_recalc(ali1489_t *dev) static void ali1489_defaults(ali1489_t *dev) { - memset(dev->ide_regs, 0x00, 256); memset(dev->pci_conf, 0x00, 256); memset(dev->regs, 0x00, 256); - ide_pri_disable(); - ide_sec_disable(); - - /* IDE registers */ - dev->ide_regs[0x00] = 0x57; - dev->ide_regs[0x01] = 0x02; - dev->ide_regs[0x08] = 0xff; - dev->ide_regs[0x09] = 0x41; - dev->ide_regs[0x0c] = 0x02; - dev->ide_regs[0x0e] = 0x02; - dev->ide_regs[0x10] = 0x02; - dev->ide_regs[0x12] = 0x02; - dev->ide_regs[0x34] = 0xff; - dev->ide_regs[0x35] = 0x01; - /* PCI registers */ dev->pci_conf[0x00] = 0xb9; dev->pci_conf[0x01] = 0x10; @@ -203,8 +185,6 @@ ali1489_defaults(ali1489_t *dev) pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - - ali1489_ide_handler(dev); } static void @@ -385,7 +365,8 @@ ali1489_write(uint16_t addr, uint8_t val, void *priv) break; case 0x44: /* PCI INTx Sensitivity Register */ - /* TODO: When doing the IRQ and PCI IRQ rewrite, bits 0 to 3 toggle edge/level output. */ + /* TODO: When doing the IRQ and PCI IRQ rewrite, + bits 0 to 3 toggle edge/level output. */ dev->regs[dev->index] = val; break; default: @@ -464,121 +445,6 @@ ali1489_pci_read(UNUSED(int func), int addr, void *priv) return ret; } -static void -ali1489_ide_handler(ali1489_t *dev) -{ - ide_pri_disable(); - ide_sec_disable(); - if (dev->ide_regs[0x01] & 0x01) { - ide_pri_enable(); - if (!(dev->ide_regs[0x35] & 0x40)) - ide_sec_enable(); - } -} - -static void -ali1489_ide_write(uint16_t addr, uint8_t val, void *priv) -{ - ali1489_t *dev = (ali1489_t *) priv; - - switch (addr) { - case 0xf4: /* Usually it writes 30h here */ - dev->ide_chip_id = val; - break; - - case 0xf8: - dev->ide_index = val; - break; - - case 0xfc: - if (dev->ide_chip_id != 0x30) - break; - - switch (dev->ide_index) { - case 0x01: /* IDE Configuration Register */ - dev->ide_regs[dev->ide_index] = val & 0x8f; - ali1489_ide_handler(dev); - break; - case 0x02: /* DBA Data Byte Cative Count for IDE-1 */ - case 0x03: /* D0RA Disk 0 Read Active Count for IDE-1 */ - case 0x04: /* D0WA Disk 0 Write Active Count for IDE-1 */ - case 0x05: /* D1RA Disk 1 Read Active Count for IDE-1 */ - case 0x06: /* D1WA Disk 1 Write Active Count for IDE-1 */ - case 0x25: /* DBR Data Byte Recovery Count for IDE-1 */ - case 0x26: /* D0RR Disk 0 Read Byte Recovery Count for IDE-1 */ - case 0x27: /* D0WR Disk 0 Write Byte Recovery Count for IDE-1 */ - case 0x28: /* D1RR Disk 1 Read Byte Recovery Count for IDE-1 */ - case 0x29: /* D1WR Disk 1 Write Byte Recovery Count for IDE-1 */ - case 0x2a: /* DBA Data Byte Cative Count for IDE-2 */ - case 0x2b: /* D0RA Disk 0 Read Active Count for IDE-2 */ - case 0x2c: /* D0WA Disk 0 Write Active Count for IDE-2 */ - case 0x2d: /* D1RA Disk 1 Read Active Count for IDE-2 */ - case 0x2e: /* D1WA Disk 1 Write Active Count for IDE-2 */ - case 0x2f: /* DBR Data Byte Recovery Count for IDE-2 */ - case 0x30: /* D0RR Disk 0 Read Byte Recovery Count for IDE-2 */ - case 0x31: /* D0WR Disk 0 Write Byte Recovery Count for IDE-2 */ - case 0x32: /* D1RR Disk 1 Read Byte Recovery Count for IDE-2 */ - case 0x33: /* D1WR Disk 1 Write Byte Recovery Count for IDE-2 */ - dev->ide_regs[dev->ide_index] = val & 0x1f; - break; - case 0x07: /* Buffer Mode Register 1 */ - dev->ide_regs[dev->ide_index] = val; - break; - case 0x09: /* IDEPE1 IDE Port Enable Register 1 */ - dev->ide_regs[dev->ide_index] = val & 0xc3; - break; - case 0x0a: /* Buffer Mode Register 2 */ - dev->ide_regs[dev->ide_index] = val & 0x4f; - break; - case 0x0b: /* IDE Channel 1 Disk 0 Sector Byte Count Register 1 */ - case 0x0d: /* IDE Channel 1 Disk 1 Sector Byte Count Register 1 */ - case 0x0f: /* IDE Channel 2 Disk 0 Sector Byte Count Register 1 */ - case 0x11: /* IDE Channel 2 Disk 1 Sector Byte Count Register 1 */ - dev->ide_regs[dev->ide_index] = val & 0x03; - break; - case 0x0c: /* IDE Channel 1 Disk 0 Sector Byte Count Register 2 */ - case 0x0e: /* IDE Channel 1 Disk 1 Sector Byte Count Register 2 */ - case 0x10: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */ - case 0x12: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */ - dev->ide_regs[dev->ide_index] = val & 0x1f; - break; - case 0x35: /* IDEPE3 IDE Port Enable Register 3 */ - dev->ide_regs[dev->ide_index] = val; - ali1489_ide_handler(dev); - break; - - default: - break; - } - break; - - default: - break; - } -} - -static uint8_t -ali1489_ide_read(uint16_t addr, void *priv) -{ - const ali1489_t *dev = (ali1489_t *) priv; - uint8_t ret = 0xff; - - switch (addr) { - case 0xf4: - ret = dev->ide_chip_id; - break; - case 0xfc: - ret = dev->ide_regs[dev->ide_index]; - ali1489_log("M1489-IDE: dev->regs[%02x] (%02x)\n", dev->ide_index, ret); - break; - - default: - break; - } - - return ret; -} - static void ali1489_reset(void *priv) { @@ -612,19 +478,10 @@ ali1489_init(UNUSED(const device_t *info)) 23h Data Port */ io_sethandler(0x0022, 0x0002, ali1489_read, NULL, NULL, ali1489_write, NULL, NULL, dev); - /* M1489 IDE controller - F4h Chip ID we write always 30h onto it - F8h Index Port - FCh Data Port - */ - io_sethandler(0x0f4, 0x0001, ali1489_ide_read, NULL, NULL, ali1489_ide_write, NULL, NULL, dev); - io_sethandler(0x0f8, 0x0001, ali1489_ide_read, NULL, NULL, ali1489_ide_write, NULL, NULL, dev); - io_sethandler(0x0fc, 0x0001, ali1489_ide_read, NULL, NULL, ali1489_ide_write, NULL, NULL, dev); - /* Dummy M1489 PCI device */ pci_add_card(PCI_ADD_NORTHBRIDGE, ali1489_pci_read, ali1489_pci_write, dev, &dev->pci_slot); - device_add(&ide_pci_2ch_device); + device_add(&ide_ali1489_device); dev->port_92 = device_add(&port_92_pci_device); dev->smram = smram_add(); diff --git a/src/disk/CMakeLists.txt b/src/disk/CMakeLists.txt index 7771a0b72..00da385d4 100644 --- a/src/disk/CMakeLists.txt +++ b/src/disk/CMakeLists.txt @@ -15,7 +15,8 @@ add_library(hdd OBJECT hdd.c hdd_image.c hdd_table.c hdc.c hdc_st506_xt.c hdc_st506_at.c hdc_xta.c hdc_esdi_at.c hdc_esdi_mca.c hdc_xtide.c - hdc_ide.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_cmd646.c hdc_ide_sff8038i.c) + hdc_ide.c hdc_ide_ali5213.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_cmd646.c + hdc_ide_sff8038i.c) add_library(zip OBJECT zip.c) diff --git a/src/disk/hdc_ide_ali5213.c b/src/disk/hdc_ide_ali5213.c new file mode 100644 index 000000000..eee3844c4 --- /dev/null +++ b/src/disk/hdc_ide_ali5213.c @@ -0,0 +1,267 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the ALi M1489 chipset. + * + * + * + * Authors: Tiseno100, + * Miran Grca, + * + * Copyright 2020-2021 Tiseno100. + * Copyright 2020-2021 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> + +#include <86box/hdc_ide.h> +#include <86box/hdc.h> +#include <86box/mem.h> +#include <86box/nmi.h> +#include <86box/pic.h> +#include <86box/pci.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/smram.h> + +#include <86box/chipset.h> + +#ifdef ENABLE_ALI5213_LOG +int ali5213_do_log = ENABLE_ALI5213_LOG; + +static void +ali5213_log(const char *fmt, ...) +{ + va_list ap; + + if (ali5213_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define ali5213_log(fmt, ...) +#endif + +typedef struct ali5213_t { + uint8_t index; + uint8_t chip_id; + + uint8_t regs[256]; +} ali5213_t; + +static void +ali5213_ide_handler(ali5213_t *dev) +{ + ide_pri_disable(); + ide_sec_disable(); + if (dev->regs[0x01] & 0x01) { + ide_pri_enable(); + if (!(dev->regs[0x35] & 0x40)) + ide_sec_enable(); + } +} + +static void +ali5213_write(uint16_t addr, uint8_t val, void *priv) +{ + ali5213_t *dev = (ali5213_t *) priv; + + ali5213_log("[%04X:%08X] [W] %02X = %02X (%i)\n", CS, cpu_state.pc, port, val, dev->tries); + + switch (addr) { + case 0xf4: /* Usually it writes 30h here */ + dev->chip_id = val; + break; + + case 0xf8: + dev->index = val; + break; + + case 0xfc: + if (dev->chip_id != 0x30) + break; + + switch (dev->index) { + case 0x01: /* IDE Configuration Register */ + dev->regs[dev->index] = val & 0x8f; + ali5213_ide_handler(dev); + break; + case 0x02: /* DBA Data Byte Cative Count for IDE-1 */ + case 0x03: /* D0RA Disk 0 Read Active Count for IDE-1 */ + case 0x04: /* D0WA Disk 0 Write Active Count for IDE-1 */ + case 0x05: /* D1RA Disk 1 Read Active Count for IDE-1 */ + case 0x06: /* D1WA Disk 1 Write Active Count for IDE-1 */ + case 0x25: /* DBR Data Byte Recovery Count for IDE-1 */ + case 0x26: /* D0RR Disk 0 Read Byte Recovery Count for IDE-1 */ + case 0x27: /* D0WR Disk 0 Write Byte Recovery Count for IDE-1 */ + case 0x28: /* D1RR Disk 1 Read Byte Recovery Count for IDE-1 */ + case 0x29: /* D1WR Disk 1 Write Byte Recovery Count for IDE-1 */ + case 0x2a: /* DBA Data Byte Cative Count for IDE-2 */ + case 0x2b: /* D0RA Disk 0 Read Active Count for IDE-2 */ + case 0x2c: /* D0WA Disk 0 Write Active Count for IDE-2 */ + case 0x2d: /* D1RA Disk 1 Read Active Count for IDE-2 */ + case 0x2e: /* D1WA Disk 1 Write Active Count for IDE-2 */ + case 0x2f: /* DBR Data Byte Recovery Count for IDE-2 */ + case 0x30: /* D0RR Disk 0 Read Byte Recovery Count for IDE-2 */ + case 0x31: /* D0WR Disk 0 Write Byte Recovery Count for IDE-2 */ + case 0x32: /* D1RR Disk 1 Read Byte Recovery Count for IDE-2 */ + case 0x33: /* D1WR Disk 1 Write Byte Recovery Count for IDE-2 */ + dev->regs[dev->index] = val & 0x1f; + break; + case 0x07: /* Buffer Mode Register 1 */ + dev->regs[dev->index] = val; + break; + case 0x09: /* IDEPE1 IDE Port Enable Register 1 */ + dev->regs[dev->index] = val & 0xc3; + break; + case 0x0a: /* Buffer Mode Register 2 */ + dev->regs[dev->index] = val & 0x4f; + break; + case 0x0b: /* IDE Channel 1 Disk 0 Sector Byte Count Register 1 */ + case 0x0d: /* IDE Channel 1 Disk 1 Sector Byte Count Register 1 */ + case 0x0f: /* IDE Channel 2 Disk 0 Sector Byte Count Register 1 */ + case 0x11: /* IDE Channel 2 Disk 1 Sector Byte Count Register 1 */ + dev->regs[dev->index] = val & 0x03; + break; + case 0x0c: /* IDE Channel 1 Disk 0 Sector Byte Count Register 2 */ + case 0x0e: /* IDE Channel 1 Disk 1 Sector Byte Count Register 2 */ + case 0x10: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */ + case 0x12: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */ + dev->regs[dev->index] = val & 0x1f; + break; + case 0x35: /* IDEPE3 IDE Port Enable Register 3 */ + dev->regs[dev->index] = val; + ali5213_ide_handler(dev); + break; + + default: + break; + } + break; + + default: + break; + } +} + +static uint8_t +ali5213_read(uint16_t addr, void *priv) +{ + const ali5213_t *dev = (ali5213_t *) priv; + uint8_t ret = 0xff; + + switch (addr) { + case 0xf4: + ret = dev->chip_id; + break; + case 0xfc: + ret = dev->regs[dev->index]; + break; + + default: + break; + } + + ali5213_log("[%04X:%08X] [R] %02X = %02X\n", CS, cpu_state.pc, port, ret); + + return ret; +} + +static void +ali5213_reset(void *priv) +{ + ali5213_t *dev = (ali5213_t *) priv; + + memset(dev->regs, 0x00, 256); + + ide_pri_disable(); + ide_sec_disable(); + + /* IDE registers */ + dev->regs[0x00] = 0x57; + dev->regs[0x01] = 0x02; + dev->regs[0x08] = 0xff; + dev->regs[0x09] = 0x41; + dev->regs[0x0c] = 0x02; + dev->regs[0x0e] = 0x02; + dev->regs[0x10] = 0x02; + dev->regs[0x12] = 0x02; + dev->regs[0x34] = 0xff; + dev->regs[0x35] = 0x01; + + ali5213_ide_handler(dev); +} + +static void +ali5213_close(void *priv) +{ + ali5213_t *dev = (ali5213_t *) priv; + + free(dev); +} + +static void * +ali5213_init(UNUSED(const device_t *info)) +{ + ali5213_t *dev = (ali5213_t *) calloc(1, sizeof(ali5213_t)); + + /* M5213/M1489 IDE controller + F4h Chip ID we write always 30h onto it + F8h Index Port + FCh Data Port + */ + io_sethandler(0x0f4, 0x0001, ali5213_read, NULL, NULL, ali5213_write, NULL, NULL, dev); + io_sethandler(0x0f8, 0x0001, ali5213_read, NULL, NULL, ali5213_write, NULL, NULL, dev); + io_sethandler(0x0fc, 0x0001, ali5213_read, NULL, NULL, ali5213_write, NULL, NULL, dev); + + device_add(info->local ? &ide_pci_2ch_device : &ide_vlb_2ch_device); + + ali5213_reset(dev); + + return dev; +} + +const device_t ide_ali1489_device = { + .name = "ALi M1489 IDE", + .internal_name = "ali1489_ide", + .flags = 0, + .local = 1, + .init = ali5213_init, + .close = ali5213_close, + .reset = ali5213_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_ali5213_device = { + .name = "ALi M5213", + .internal_name = "ali5213", + .flags = 0, + .local = 0, + .init = ali5213_init, + .close = ali5213_close, + .reset = ali5213_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index 8ede3e786..b0e775886 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -60,6 +60,9 @@ extern const device_t ide_vlb_2ch_device; /* vlb_ide_2ch */ extern const device_t ide_pci_device; /* pci_ide */ extern const device_t ide_pci_2ch_device; /* pci_ide_2ch */ +extern const device_t ide_ali1489_device; /* ALi M1489 */ +extern const device_t ide_ali5213_device; /* ALi M5213 */ + extern const device_t ide_cmd640_vlb_device; /* CMD PCI-640B VLB */ extern const device_t ide_cmd640_vlb_178_device; /* CMD PCI-640B VLB (Port 178h) */ extern const device_t ide_cmd640_vlb_pri_device; /* CMD PCI-640B VLB (Only primary channel) */ diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index a695073e2..2f92676c9 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -381,9 +381,9 @@ machine_at_acera1g_init(const machine_t *model) device_add(&gd5428_onboard_device); device_add(&keyboard_ps2_acer_pci_device); - device_add(&ide_vlb_2ch_device); device_add(&ali5105_device); + device_add(&ide_ali5213_device); return ret; } diff --git a/src/sio/sio_pc87310.c b/src/sio/sio_pc87310.c index f9626214c..075b819ff 100644 --- a/src/sio/sio_pc87310.c +++ b/src/sio/sio_pc87310.c @@ -244,7 +244,6 @@ pc87310_read(UNUSED(uint16_t port), void *priv) ret = dev->regs[idx]; pc87310_log("[%04X:%08X] [R] %02X = %02X\n", CS, cpu_state.pc, port, ret); - pc87310_log("SIO: read %01X\n", ret); return ret; }