diff --git a/src/chipset/wd76c10.c b/src/chipset/wd76c10.c index d11330c85..ddde7626e 100644 --- a/src/chipset/wd76c10.c +++ b/src/chipset/wd76c10.c @@ -81,7 +81,9 @@ typedef struct { typedef struct { uint8_t ep, p92; + uint8_t addr_sel; + uint8_t addr_regs[8]; uint8_t vbios_states[4]; uint8_t bios_states[8]; uint8_t high_bios_states[8]; @@ -100,6 +102,7 @@ typedef struct }; uint16_t ems_page_regs[40]; + uint16_t lpt_base; int locked; @@ -873,6 +876,92 @@ wd76c10_low_pages_recalc(wd76c10_t *dev) } } +static void +wd73c30_reset(wd76c10_t *dev) +{ + dev->addr_sel = 0x00; + + dev->addr_regs[0x00] = 0x00; + dev->addr_regs[0x01] = 0x00; + dev->addr_regs[0x05] = 0x00; + + serial_set_type(dev->uart[0], SERIAL_16450); + serial_set_type(dev->uart[1], SERIAL_16450); + + serial_set_clock_src(dev->uart[1], 1843200.0); + serial_set_clock_src(dev->uart[0], 1843200.0); + + lpt_set_ext(dev->lpt, 0); +} + +static void +wd76c30_write(uint16_t port, uint8_t val, void *priv) +{ + wd76c10_t *dev = (wd76c10_t *) priv; + + switch (port & 0x0007) { + case 0x0003: + dev->addr_sel = val; + switch (val & 0x60) { + case 0x00: + serial_set_clock_src(dev->uart[1], 1843200.0); + break; + case 0x20: + serial_set_clock_src(dev->uart[1], 3072000.0); + break; + case 0x40: + serial_set_clock_src(dev->uart[1], 6000000.0); /* What is MSTRX1? */ + break; + case 0x60: + serial_set_clock_src(dev->uart[1], 8000000.0); + break; + } + switch (val & 0x18) { + case 0x00: + serial_set_clock_src(dev->uart[0], 1843200.0); + break; + case 0x08: + serial_set_clock_src(dev->uart[0], 3072000.0); + break; + case 0x10: + serial_set_clock_src(dev->uart[0], 6000000.0); /* What is MSTRX1? */ + break; + case 0x18: + serial_set_clock_src(dev->uart[0], 8000000.0); + break; + } + break; + case 0x0007: + dev->addr_regs[dev->addr_sel & 0x07] = val; + switch (dev->addr_sel & 0x07) { + case 0x05: + lpt_set_ext(dev->lpt, !!(val & 0x02)); + serial_set_type(dev->uart[0], (val & 0x01) ? SERIAL_16550 : SERIAL_16450); + serial_set_type(dev->uart[1], (val & 0x01) ? SERIAL_16550 : SERIAL_16450); + break; + } + break; + } +} + +static uint8_t +wd76c30_read(uint16_t port, void *priv) +{ + wd76c10_t *dev = (wd76c10_t *) priv; + uint8_t ret = 0xff; + + switch (port & 0x0007) { + case 0x0003: + ret = dev->addr_sel; + break; + case 0x0007: + ret = dev->addr_regs[dev->addr_sel & 0x07]; + break; + } + + return ret; +} + static void wd76c10_ser_par_cs_recalc(wd76c10_t *dev) { @@ -912,20 +1001,23 @@ wd76c10_ser_par_cs_recalc(wd76c10_t *dev) /* LPT */ lpt_port_remove(dev->lpt); + if (dev->lpt_base != 0x0000) + io_removehandler(dev->lpt_base, 0x0008, wd76c30_read, NULL, NULL, wd76c30_write, NULL, NULL, dev); + dev->lpt_base = 0x0000; switch ((dev->ser_par_cs >> 9) & 0x03) { case 1: - lpt_port_setup(dev->lpt, LPT_MDA_ADDR); - lpt_port_irq(dev->lpt, LPT1_IRQ); + dev->lpt_base = LPT_MDA_ADDR; break; case 2: - lpt_port_setup(dev->lpt, LPT1_ADDR); - lpt_port_irq(dev->lpt, LPT1_IRQ); + dev->lpt_base = LPT1_ADDR; break; case 3: - lpt_port_setup(dev->lpt, LPT2_ADDR); - lpt_port_irq(dev->lpt, LPT1_IRQ); + dev->lpt_base = LPT2_ADDR; break; } + io_sethandler(dev->lpt_base, 0x0008, wd76c30_read, NULL, NULL, wd76c30_write, NULL, NULL, dev); + lpt_port_setup(dev->lpt, dev->lpt_base); + lpt_port_irq(dev->lpt, LPT1_IRQ); } static void @@ -1239,6 +1331,8 @@ wd76c10_reset(void *priv) nvr_lock_set(0x38, 0x08, 0x00, dev->nvr); + wd73c30_reset(dev); + wd76c10_banks_recalc(dev); wd76c10_split_recalc(dev); wd76c10_dis_mem_recalc(dev); diff --git a/src/device/lpt.c b/src/device/lpt.c index c54345856..209ea33f8 100644 --- a/src/device/lpt.c +++ b/src/device/lpt.c @@ -23,6 +23,7 @@ #include <86box/device.h> #include <86box/machine.h> #include <86box/network.h> +#include <86box/plat_fallthrough.h> static int next_inst = 0; int lpt_3bc_used = 0; @@ -378,7 +379,35 @@ lpt_write(const uint16_t port, const uint8_t val, void *priv) } break; - case 0x0400: case 0x0404: + case 0x0404: + if (dev->cfg_regs_enabled) { + switch (dev->eir) { + case 0x00: + dev->ext_regs[0x00] = val & 0x31; + break; + case 0x02: + dev->ext_regs[0x02] = val & 0xd0; + if (dev->ext_regs[0x02] & 0x80) + dev->ecr = dev->ret_ecr; + else switch (dev->ret_ecr & 0xe0) { + case 0x00: case 0x20: + case 0x80: + dev->ecr = (dev->ret_ecr & 0x1f) | 0x60; + break; + } + break; + case 0x04: + dev->ext_regs[0x00] = val & 0x37; + break; + case 0x05: + dev->ext_regs[0x00] = val; + dev->cnfga_readout = (val & 0x80) ? 0x1c : 0x14; + break; + } + break; + } else + fallthrough; + case 0x0400: switch (dev->ecr >> 5) { default: break; @@ -424,10 +453,23 @@ lpt_write(const uint16_t port, const uint8_t val, void *priv) dev->state = LPT_STATE_IDLE; } - dev->ecr = val; + if (dev->ext_regs[0x02] & 0x80) + dev->ecr = val; + else switch (val & 0xe0) { + case 0x00: case 0x20: + case 0x80: + dev->ecr = (val & 0x1f) | 0x60; + break; + } + dev->ret_ecr = val; lpt_ecp_update_irq(dev); break; + case 0x0403: case 0x0407: + if (dev->cfg_regs_enabled) + dev->eir = val & 0x07; + break; + default: break; } @@ -519,6 +561,12 @@ lpt_read_status(lpt_t *dev) return ret; } +uint8_t +lpt_read_ecp_mode(lpt_t *dev) +{ + return ((dev->ret_ecr & 0xe0) == 0x60) ? 0x60 : 0x00; +} + uint8_t lpt_read(const uint16_t port, void *priv) { @@ -567,7 +615,21 @@ lpt_read(const uint16_t port, void *priv) } break; - case 0x0400: case 0x0404: + case 0x0404: + if (dev->cfg_regs_enabled) { + switch (dev->eir) { + default: + ret = 0xff; + break; + case 0x00: case 0x02: + case 0x04: case 0x05: + ret = dev->ext_regs[dev->eir]; + break; + } + break; + } else + fallthrough; + case 0x0400: switch (dev->ecr >> 5) { default: break; @@ -587,7 +649,13 @@ lpt_read(const uint16_t port, void *priv) } break; - case 0x0401: case 0x0405: + case 0x0405: + if (dev->cfg_regs_enabled) { + ret = 0x00; + break; + } else + fallthrough; + case 0x0401: if ((dev->ecr & 0xe0) == 0xe0) { /* CNFGB */ ret = 0x08; @@ -599,11 +667,16 @@ lpt_read(const uint16_t port, void *priv) break; case 0x0402: case 0x0406: - ret = dev->ecr | dev->fifo_stat | (dev->dma_stat & 0x04); + ret = dev->ret_ecr | dev->fifo_stat | (dev->dma_stat & 0x04); ret |= (fifo_get_full(dev->fifo) ? 0x02 : 0x00); ret |= (fifo_get_empty(dev->fifo) ? 0x01 : 0x00); break; + case 0x0403: case 0x0407: + if (dev->cfg_regs_enabled) + ret = dev->eir; + break; + default: break; } @@ -688,6 +761,13 @@ lpt_set_fifo_threshold(lpt_t *dev, const int threshold) fifo_set_trigger_len(dev->fifo, threshold); } +void +lpt_set_cfg_regs_enabled(lpt_t *dev, const uint8_t cfg_regs_enabled) +{ + if (lpt_ports[dev->id].enabled) + dev->cfg_regs_enabled = cfg_regs_enabled; +} + void lpt_set_cnfga_readout(lpt_t *dev, const uint8_t cnfga_readout) { @@ -834,14 +914,21 @@ lpt_reset(void *priv) } } - dev->enable_irq = 0x00; - dev->ext = !!(machine_has_bus(machine, MACHINE_BUS_MCA)); - dev->epp = 0; - dev->ecp = 0; - dev->ecr = 0x15; - dev->dat = 0xff; - dev->fifo_stat = 0x00; - dev->dma_stat = 0x00; + dev->enable_irq = 0x00; + dev->cfg_regs_enabled = 0; + dev->ext = !!(machine_has_bus(machine, MACHINE_BUS_MCA)); + dev->epp = 0; + dev->ecp = 0; + dev->ecr = 0x15; + dev->ret_ecr = 0x15; + dev->dat = 0xff; + dev->fifo_stat = 0x00; + dev->dma_stat = 0x00; + + memset(dev->ext_regs, 0x00, 8); + dev->ext_regs[0x02] = 0x80; + dev->ext_regs[0x04] = 0x07; + dev->cnfga_readout &= 0xf7; } } @@ -869,15 +956,20 @@ lpt_init(const device_t *info) lpt_port_zero(dev); - dev->addr = 0xffff; - dev->irq = 0xff; - dev->dma = 0xff; - dev->enable_irq = 0x00; - dev->ext = 0; - dev->epp = 0; - dev->ecp = 0; - dev->ecr = 0x15; - dev->cnfga_readout = 0x14; + dev->addr = 0xffff; + dev->irq = 0xff; + dev->dma = 0xff; + dev->enable_irq = 0x00; + dev->cfg_regs_enabled = 0; + dev->ext = 0; + dev->epp = 0; + dev->ecp = 0; + dev->ecr = 0x15; + dev->ret_ecr = 0x15; + dev->cnfga_readout = 0x10; + + memset(dev->ext_regs, 0x00, 8); + dev->ext_regs[0x02] = 0x80; if (lpt_ports[dev->id].enabled) { if (info->local & 0xfff00000) { diff --git a/src/device/serial.c b/src/device/serial.c index 8e2071064..ad9abfe5d 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -475,6 +475,12 @@ serial_set_clock_src(serial_t *dev, double clock_src) serial_update_speed(dev); } +void +serial_set_type(serial_t *dev, uint8_t type) +{ + dev->type = type; +} + void serial_write(uint16_t addr, uint8_t val, void *priv) { diff --git a/src/include/86box/lpt.h b/src/include/86box/lpt.h index 4e3adf406..fdf869953 100644 --- a/src/include/86box/lpt.h +++ b/src/include/86box/lpt.h @@ -53,6 +53,7 @@ typedef struct lpt_t { uint8_t epp; uint8_t ecp; uint8_t ecr; + uint8_t ret_ecr; uint8_t in_dat; uint8_t fifo_stat; uint8_t dma_stat; @@ -61,8 +62,11 @@ typedef struct lpt_t { uint8_t strobe; uint8_t lv2; uint8_t cnfga_readout; + uint8_t cfg_regs_enabled; uint8_t inst; - uint8_t pad[5]; + uint8_t eir; + uint8_t pad[2]; + uint8_t ext_regs[8]; uint16_t addr; uint16_t id; uint16_t pad0[2]; @@ -101,6 +105,8 @@ extern uint8_t lpt_read(uint16_t port, void *priv); extern uint8_t lpt_read_port(lpt_t *dev, uint16_t reg); extern uint8_t lpt_read_status(lpt_t *dev); +extern uint8_t lpt_read_ecp_mode(lpt_t *dev); + extern void lpt_irq(void *priv, int raise); extern int lpt_device_get_from_internal_name(const char *str); @@ -125,6 +131,7 @@ extern void lpt_set_ext(lpt_t *dev, uint8_t ext); extern void lpt_set_ecp(lpt_t *dev, uint8_t ecp); extern void lpt_set_epp(lpt_t *dev, uint8_t epp); extern void lpt_set_lv2(lpt_t *dev, uint8_t lv2); +extern void lpt_set_cfg_regs_enabled(lpt_t *dev, uint8_t cfg_regs_enabled); extern void lpt_set_fifo_threshold(lpt_t *dev, int threshold); extern void lpt_set_cnfga_readout(lpt_t *dev, const uint8_t cnfga_readout); extern void lpt_port_setup(lpt_t *dev, uint16_t port); diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 9e14f0656..1eb51bbba 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -164,31 +164,32 @@ enum { MACHINE_TYPE_NONE = 0, - MACHINE_TYPE_8088 = 1, - MACHINE_TYPE_8086 = 2, - MACHINE_TYPE_286 = 3, - MACHINE_TYPE_386SX = 4, - MACHINE_TYPE_486SLC = 5, - MACHINE_TYPE_386DX = 6, - MACHINE_TYPE_386DX_486 = 7, - MACHINE_TYPE_486 = 8, - MACHINE_TYPE_486_S2 = 9, - MACHINE_TYPE_486_S3 = 10, - MACHINE_TYPE_486_S3_PCI = 11, - MACHINE_TYPE_486_MISC = 12, - MACHINE_TYPE_SOCKET4 = 13, - MACHINE_TYPE_SOCKET5 = 14, - MACHINE_TYPE_SOCKET7_3V = 15, - MACHINE_TYPE_SOCKET7 = 16, - MACHINE_TYPE_SOCKETS7 = 17, - MACHINE_TYPE_SOCKET8 = 18, - MACHINE_TYPE_SLOT1 = 19, - MACHINE_TYPE_SLOT1_2 = 20, - MACHINE_TYPE_SLOT1_370 = 21, - MACHINE_TYPE_SLOT2 = 22, - MACHINE_TYPE_SOCKET370 = 23, - MACHINE_TYPE_MISC = 24, - MACHINE_TYPE_MAX = 25 + MACHINE_TYPE_8088, + MACHINE_TYPE_8086, + MACHINE_TYPE_286, + MACHINE_TYPE_386SX, + MACHINE_TYPE_M6117, + MACHINE_TYPE_486SLC, + MACHINE_TYPE_386DX, + MACHINE_TYPE_386DX_486, + MACHINE_TYPE_486, + MACHINE_TYPE_486_S2, + MACHINE_TYPE_486_S3, + MACHINE_TYPE_486_S3_PCI, + MACHINE_TYPE_486_MISC, + MACHINE_TYPE_SOCKET4, + MACHINE_TYPE_SOCKET5, + MACHINE_TYPE_SOCKET7_3V, + MACHINE_TYPE_SOCKET7, + MACHINE_TYPE_SOCKETS7, + MACHINE_TYPE_SOCKET8, + MACHINE_TYPE_SLOT1, + MACHINE_TYPE_SLOT1_2, + MACHINE_TYPE_SLOT1_370, + MACHINE_TYPE_SLOT2, + MACHINE_TYPE_SOCKET370, + MACHINE_TYPE_MISC, + MACHINE_TYPE_MAX }; enum { @@ -440,78 +441,107 @@ extern void machine_at_ibm_common_ide_init(const machine_t *); extern void machine_at_ide_init(const machine_t *); extern void machine_at_ps2_ide_init(const machine_t *); -extern int machine_at_ibm_init(const machine_t *); +extern int machine_at_ibm_init(const machine_t *); // IBM AT with custom BIOS -extern int machine_at_ibmatami_init(const machine_t *); // IBM AT with AMI BIOS -extern int machine_at_ibmatpx_init(const machine_t *); // IBM AT with Phoenix BIOS -extern int machine_at_ibmatquadtel_init(const machine_t *); // IBM AT with Quadtel BIOS +extern int machine_at_ibmatami_init(const machine_t *); // IBM AT with AMI BIOS +extern int machine_at_ibmatpx_init(const machine_t *); // IBM AT with Phoenix BIOS +extern int machine_at_ibmatquadtel_init(const machine_t *); // IBM AT with Quadtel BIOS -extern int machine_at_ibmxt286_init(const machine_t *); +extern int machine_at_ibmxt286_init(const machine_t *); -extern int machine_at_pb286_init(const machine_t *); +extern int machine_at_pb286_init(const machine_t *); -extern int machine_at_siemens_init(const machine_t *); // Siemens PCD-2L. N82330 discrete machine. It segfaults in some places +extern int machine_at_siemens_init(const machine_t *); // Siemens PCD-2L. N82330 discrete machine. It segfaults in some places -extern int machine_at_wellamerastar_init(const machine_t *); // Wells American A*Star with custom award BIOS +/* m_at_286.c */ +/* ISA */ +extern int machine_at_mr286_init(const machine_t *); +extern int machine_at_pc8_init(const machine_t *); +extern int machine_at_m290_init(const machine_t *); -/* m_at_286_386sx.c */ -extern int machine_at_tg286m_init(const machine_t *); -extern int machine_at_ama932j_init(const machine_t *); -extern int machine_at_px286_init(const machine_t *); -extern int machine_at_quadt286_init(const machine_t *); -extern int machine_at_mr286_init(const machine_t *); +/* C&T PC/AT */ +extern int machine_at_dells200_init(const machine_t *); +extern int machine_at_super286c_init(const machine_t *); +extern int machine_at_at122_init(const machine_t *); +extern int machine_at_tuliptc7_init(const machine_t *); -extern int machine_at_pbl300sx_init(const machine_t *); -extern int machine_at_neat_init(const machine_t *); -extern int machine_at_neat_ami_init(const machine_t *); -extern int machine_at_ataripc4_init(const machine_t *); +/* GC103 */ +extern int machine_at_quadt286_init(const machine_t *); +extern void machine_at_headland_common_init(const machine_t *model, int type); +extern int machine_at_tg286m_init(const machine_t *); +/* Wells American A*Star with custom award BIOS. */ +extern int machine_at_wellamerastar_init(const machine_t *); -extern int machine_at_quadt386sx_init(const machine_t *); +/* NEAT */ +extern int machine_at_ataripc4_init(const machine_t *); +extern int machine_at_neat_ami_init(const machine_t *); +extern int machine_at_3302_init(const machine_t *); +extern int machine_at_px286_init(const machine_t *); -extern int machine_at_award286_init(const machine_t *); -extern int machine_at_gdc212m_init(const machine_t *); -extern int machine_at_gw286ct_init(const machine_t *); -extern int machine_at_drsm35286_init(const machine_t *); -extern int machine_at_senor_scat286_init(const machine_t *); -extern int machine_at_super286c_init(const machine_t *); -extern int machine_at_super286tr_init(const machine_t *); -extern int machine_at_spc4200p_init(const machine_t *); -extern int machine_at_spc4216p_init(const machine_t *); -extern int machine_at_spc4620p_init(const machine_t *); -extern int machine_at_kmxc02_init(const machine_t *); -extern int machine_at_deskmaster286_init(const machine_t *); +/* SCAT */ +extern int machine_at_gw286ct_init(const machine_t *); +extern int machine_at_gdc212m_init(const machine_t *); +extern int machine_at_award286_init(const machine_t *); +extern int machine_at_super286tr_init(const machine_t *); +extern int machine_at_drsm35286_init(const machine_t *); +extern int machine_at_deskmaster286_init(const machine_t *); +extern int machine_at_spc4200p_init(const machine_t *); +extern int machine_at_spc4216p_init(const machine_t *); +extern int machine_at_spc4620p_init(const machine_t *); +extern int machine_at_senor_scat286_init(const machine_t *); -extern int machine_at_dells200_init(const machine_t *); -extern int machine_at_at122_init(const machine_t *); -extern int machine_at_tuliptc7_init(const machine_t *); +/* m_at_386sx.c */ +/* ISA */ +extern int machine_at_pc916sx_init(const machine_t *); +extern int machine_at_quadt386sx_init(const machine_t *); -extern int machine_at_pc8_init(const machine_t *); -extern int machine_at_3302_init(const machine_t *); +/* ACC 2036 */ +extern int machine_at_pbl300sx_init(const machine_t *); -extern int machine_at_m290_init(const machine_t *); +/* ALi M1217 */ +extern int machine_at_arb1374_init(const machine_t *); +extern int machine_at_sbc350a_init(const machine_t *); +extern int machine_at_flytech386_init(const machine_t *); +extern int machine_at_325ax_init(const machine_t *); +extern int machine_at_mr1217_init(const machine_t *); -extern int machine_at_shuttle386sx_init(const machine_t *); -extern int machine_at_adi386sx_init(const machine_t *); -extern int machine_at_cmdsl386sx16_init(const machine_t *); -extern int machine_at_cmdsl386sx25_init(const machine_t *); -extern int machine_at_dataexpert386sx_init(const machine_t *); -extern int machine_at_dells333sl_init(const machine_t *); -extern int machine_at_if386sx_init(const machine_t *); -extern int machine_at_spc6033p_init(const machine_t *); -extern int machine_at_wd76c10_init(const machine_t *); -extern int machine_at_arb1374_init(const machine_t *); -extern int machine_at_sbc350a_init(const machine_t *); -extern int machine_at_flytech386_init(const machine_t *); -extern int machine_at_325ax_init(const machine_t *); -extern int machine_at_mr1217_init(const machine_t *); -extern int machine_at_pja511m_init(const machine_t *); -extern int machine_at_prox1332_init(const machine_t *); -extern int machine_at_acer100t_init(const machine_t *); +/* ALi M1409 */ +extern int machine_at_acer100t_init(const machine_t *); -extern int machine_at_awardsx_init(const machine_t *); +/* HT18 */ +extern int machine_at_ama932j_init(const machine_t *); -extern int machine_at_pc916sx_init(const machine_t *); +/* Intel 82335 */ +extern int machine_at_adi386sx_init(const machine_t *); +extern int machine_at_shuttle386sx_init(const machine_t *); + +/* NEAT */ +extern int machine_at_cmdsl386sx16_init(const machine_t *); +extern int machine_at_neat_init(const machine_t *); + +/* NEATsx */ +extern int machine_at_if386sx_init(const machine_t *); + +/* OPTi 291 */ +extern int machine_at_awardsx_init(const machine_t *); + +/* SCAMP */ +extern int machine_at_cmdsl386sx25_init(const machine_t *); +extern int machine_at_dataexpert386sx_init(const machine_t *); +extern int machine_at_dells333sl_init(const machine_t *); +extern int machine_at_spc6033p_init(const machine_t *); + +/* SCATsx */ +extern int machine_at_kmxc02_init(const machine_t *); + +/* WD76C10 */ +extern int machine_at_wd76c10_init(const machine_t *); + +/* m_at_m6117.c */ +/* ALi M6117D */ +extern int machine_at_pja511m_init(const machine_t *); +extern int machine_at_prox1332_init(const machine_t *); /* m_at_386dx_486.c */ /* Note to jriwanek: When merging this into my branch, please make diff --git a/src/include/86box/serial.h b/src/include/86box/serial.h index f35c7e36e..c6389a262 100644 --- a/src/include/86box/serial.h +++ b/src/include/86box/serial.h @@ -135,7 +135,6 @@ extern serial_t *serial_attach_ex_2(int port, serial_attach_ex(port, rcr_callback, dev_write, NULL, NULL, priv); extern void serial_remove(serial_t *dev); -extern void serial_set_type(serial_t *dev, int type); extern void serial_setup(serial_t *dev, uint16_t addr, uint8_t irq); extern void serial_irq(serial_t *dev, uint8_t irq); extern void serial_clear_fifo(serial_t *dev); @@ -143,6 +142,7 @@ extern void serial_write_fifo(serial_t *dev, uint8_t dat); extern void serial_set_next_inst(int ni); extern void serial_standalone_init(void); extern void serial_set_clock_src(serial_t *dev, double clock_src); +extern void serial_set_type(serial_t *dev, uint8_t type); extern void serial_reset_port(serial_t *dev); extern uint8_t serial_read(uint16_t addr, void *priv); extern void serial_device_timeout(void *priv); diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index 941604ddb..b86124273 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -29,36 +29,35 @@ extern const device_t f82c710_device; extern const device_t f82c710_pc5086_device; /* SM(S)C */ -extern const device_t fdc37c651_device; -extern const device_t fdc37c651_ide_device; -extern const device_t fdc37c661_device; -extern const device_t fdc37c661_ide_device; -extern const device_t fdc37c661_ide_sec_device; -extern const device_t fdc37c663_device; -extern const device_t fdc37c663_ide_device; -extern const device_t fdc37c665_device; -extern const device_t fdc37c665_ide_device; -extern const device_t fdc37c665_ide_pri_device; -extern const device_t fdc37c665_ide_sec_device; -extern const device_t fdc37c666_device; +#define FDC37C651 0x00051 +#define FDC37C661 0x00061 +#define FDC37C663 0x00063 +#define FDC37C665 0x00065 +#define FDC37C666 0x00066 + +#define FDC37C6XX_IDE_PRI 0x00100 +#define FDC37C6XX_IDE_SEC 0x00200 + +#define FDC37C6XX_370 0x00400 + +extern const device_t fdc37c6xx_device; extern const device_t fdc37c669_device; -extern const device_t fdc37c669_370_device; -#define FDC37C93X_NORMAL 0x0002 -#define FDC37C93X_FR 0x0003 -#define FDC37C93X_APM 0x0030 -#define FDC37C93X_CHIP_ID 0x00ff +#define FDC37C93X_NORMAL 0x00002 +#define FDC37C93X_FR 0x00003 +#define FDC37C93X_APM 0x00030 +#define FDC37C93X_CHIP_ID 0x000ff -#define FDC37XXX1 0x0100 /* Compaq KBC firmware and configuration registers on GPIO ports. */ -#define FDC37XXX2 0x0200 /* AMI '5' Megakey KBC firmware. */ -#define FDC37XXX3 0x0300 /* IBM KBC firmware. */ -#define FDC37XXX5 0x0500 /* Phoenix Multikey/42 1.38 KBC firmware. */ -#define FDC37XXX7 0x0700 /* Phoenix Multikey/42i 4.16 KBC firmware. */ -#define FDC37XXXX_KBC 0x0f00 +#define FDC37XXX1 0x00100 /* Compaq KBC firmware and configuration registers on GPIO ports. */ +#define FDC37XXX2 0x00200 /* AMI '5' Megakey KBC firmware. */ +#define FDC37XXX3 0x00300 /* IBM KBC firmware. */ +#define FDC37XXX5 0x00500 /* Phoenix Multikey/42 1.38 KBC firmware. */ +#define FDC37XXX7 0x00700 /* Phoenix Multikey/42i 4.16 KBC firmware. */ +#define FDC37XXXX_KBC 0x00f00 -#define FDC37C93X_NO_NVR 0x1000 -#define FDC37XXXX_370 0x2000 +#define FDC37C93X_NO_NVR 0x01000 +#define FDC37XXXX_370 0x02000 extern const device_t fdc37c93x_device; @@ -71,42 +70,52 @@ extern const device_t it8661f_device; extern const device_t it8671f_device; /* Intel */ +#define I82091AA_022 0x00000 /* Default. */ +#define I82091AA_024 0x00008 +#define I82091AA_26E 0x00100 +#define I82091AA_398 0x00108 + +#define I82091AA_IDE_PRI 0x00200 +#define I82091AA_IDE_SEC 0x00400 + extern const device_t i82091aa_device; -extern const device_t i82091aa_26e_device; -extern const device_t i82091aa_398_device; -extern const device_t i82091aa_ide_pri_device; -extern const device_t i82091aa_ide_device; /* National Semiconductors PC87310 / ALi M5105 */ -#define PC87310_IDE 0x0001 -#define PC87310_ALI 0x0002 +#define PCX73XX_IDE 0x00001 + +#define PCX73XX_IDE_PRI PCX73XX_IDE +#define PCX73XX_IDE_SEC 0x00002 + +#define PCX73XX_FDC_ON 0x10000 + +#define PC87310_ALI 0x00004 +#define PC87332 PC87310_ALI extern const device_t pc87310_device; /* National Semiconductors */ -#define PCX7307_PC87307 0x00c0 -#define PCX7307_PC97307 0x00cf +#define PCX7307_PC87307 0x000c0 +#define PCX7307_PC97307 0x000cf -#define PC87309_PC87309 0x00e0 +#define PC87309_PC87309 0x000e0 -#define PCX730X_CHIP_ID 0x00ff +#define PCX730X_CHIP_ID 0x000ff -#define PCX730X_AMI 0x0200 /* AMI '5' Megakey KBC firmware. */ -#define PCX730X_PHOENIX_42 0x0500 /* Phoenix Multikey/42 1.37 KBC firmware. */ -#define PCX730X_PHOENIX_42I 0x0700 /* Phoenix Multikey/42i 4.16 KBC firmware. */ -#define PCX730X_KBC 0x0f00 +#define PCX730X_AMI 0x00200 /* AMI '5' Megakey KBC firmware. */ +#define PCX730X_PHOENIX_42 0x00500 /* Phoenix Multikey/42 1.37 KBC firmware. */ +#define PCX730X_PHOENIX_42I 0x00700 /* Phoenix Multikey/42i 4.16 KBC firmware. */ +#define PCX730X_KBC 0x00f00 -#define PCX730X_15C 0x2000 +#define PCX730X_398 0x00000 +#define PCX730X_26E 0x01000 +#define PCX730X_15C 0x02000 +#define PCX730X_02E 0x03000 +#define PCX730X_BADDR 0x03000 +#define PCX730X_BADDR_SHIFT 12 extern const device_t pc87306_device; -extern const device_t pc87311_device; -extern const device_t pc87311_ide_device; -extern const device_t pc87332_device; -extern const device_t pc87332_398_device; -extern const device_t pc87332_398_ide_device; -extern const device_t pc87332_398_ide_sec_device; -extern const device_t pc87332_398_ide_fdcon_device; +extern const device_t pc873xx_device; /* National Semiconductors PC87307 / PC87309 */ extern const device_t pc87307_device; @@ -114,10 +123,15 @@ extern const device_t pc87307_device; extern const device_t pc87309_device; /* LG Prime */ -extern const device_t prime3b_device; -extern const device_t prime3b_ide_device; -extern const device_t prime3c_device; -extern const device_t prime3c_ide_device; +#define GM82C803A 0x00000 +#define GM82C803B 0x00001 + +#define GM82C803_IDE_PRI 0x00100 +#define GM82C803_IDE_SEC 0x00200 + +extern const device_t gm82c803ab_device; + +extern const device_t gm82c803c_device; /* IBM PS/1 */ extern const device_t ps1_m2133_sio; @@ -128,20 +142,17 @@ extern const device_t sio_detect_device; #endif /* USE_SIO_DETECT */ /* UMC */ -extern const device_t um82c862f_device; -extern const device_t um82c862f_ide_device; -extern const device_t um82c863f_device; -extern const device_t um82c863f_ide_device; -extern const device_t um8663af_device; -extern const device_t um8663af_ide_device; -extern const device_t um8663af_sec_device; -extern const device_t um8663bf_device; -extern const device_t um8663bf_ide_device; -extern const device_t um8663bf_sec_device; +#define UM82C862F 0x00000 +#define UM82C863F 0x0c100 +#define UM8663AF 0x0c300 +#define UM8663BF 0x0c400 + +#define UM866X_IDE_PRI 0x00001 +#define UM866X_IDE_SEC 0x00002 + +extern const device_t um866x_device; extern const device_t um8669f_device; -extern const device_t um8669f_ide_device; -extern const device_t um8669f_ide_sec_device; /* VIA */ extern void vt82c686_sio_write(uint8_t addr, uint8_t val, void *priv); @@ -152,26 +163,43 @@ extern const device_t via_vt82c686_sio_device; extern const device_t vl82c113_device; /* Winbond */ -extern const device_t w83787f_88h_device; -extern const device_t w83787f_device; -extern const device_t w83787f_ide_device; -extern const device_t w83787f_ide_en_device; -extern const device_t w83787f_ide_sec_device; +#define W83777F 0x00007 +#define W83787F 0x00008 +#define W83787IF 0x00009 -extern const device_t w83877f_device; -extern const device_t w83877f_president_device; -extern const device_t w83877tf_device; -extern const device_t w83877tf_acorp_device; +#define W837X7_KEY_88 0x00000 +#define W837X7_KEY_89 0x00020 -#define TYPE_W83977EF 0x52F0 -#define TYPE_W83977F 0x9771 -#define TYPE_W83977TF 0x9773 -#define TYPE_W83977ATF 0x9774 +#define W837X7_IDE_START 0x00040 -extern const device_t w83977f_device; -extern const device_t w83977f_370_device; -extern const device_t w83977tf_device; -extern const device_t w83977ef_device; -extern const device_t w83977ef_370_device; +#define W83XX7_IDE_PRI 0x10000 +#define W83XX7_IDE_SEC 0x20000 + +extern const device_t w837x7_device; + +#define W83877F 0x00a00 +#define W83877TF 0x00c00 +#define W83877_3F0 0x00005 +#define W83877_250 0x00004 + +extern const device_t w83877_device; + +#define W83977F 0x977100 +#define W83977TF 0x977300 +#define W83977EF 0x52f000 +#define W83977_TYPE 0xffff00 +#define W83977_TYPE_SHIFT 8 + +#define W83977_3F0 0x00000 +#define W83977_370 0x00001 + +#define W83977_NO_NVR 0x00002 + +#define W83977_AMI 0x00010 /* AMI 'H' KBC firmware. */ +#define W83977_PHOENIX 0x00020 /* Unknown Phoenix Multikey KBC firmware. */ + +#define W83977_KBC 0x000f0 + +extern const device_t w83977_device; #endif /*EMU_SIO_H*/ diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt index 63f9baf61..ae9d2a1a9 100644 --- a/src/machine/CMakeLists.txt +++ b/src/machine/CMakeLists.txt @@ -42,7 +42,9 @@ add_library(mch OBJECT m_ps2_isa.c m_ps2_mca.c m_at_compaq.c - m_at_286_386sx.c + m_at_286.c + m_at_386sx.c + m_at_m6117.c m_at_386dx_486.c m_at_socket4.c m_at_socket5.c diff --git a/src/machine/m_at_286.c b/src/machine/m_at_286.c new file mode 100644 index 000000000..e13b81853 --- /dev/null +++ b/src/machine/m_at_286.c @@ -0,0 +1,609 @@ +/* + * 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 286 machines. + * + * Authors: Miran Grca, + * EngiNerd + * + * Copyright 2016-2025 Miran Grca. + * Copyright 2020-2025 EngiNerd. + */ +#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/chipset.h> +#include <86box/keyboard.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/fdc_ext.h> +#include <86box/hdc.h> +#include <86box/nvr.h> +#include <86box/port_6x.h> +#define USE_SIO_DETECT +#include <86box/sio.h> +#include <86box/serial.h> +#include <86box/video.h> +#include <86box/vid_cga.h> +#include <86box/flash.h> +#include <86box/machine.h> + +/* ISA */ +int +machine_at_mr286_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/mr286/V000B200-1", + "roms/machines/mr286/V000B200-2", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_ide_init(model); + device_add(&kbc_at_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + +/* + * Current bugs: + * - ctrl-alt-del produces an 8042 error + */ +int +machine_at_pc8_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/pc8/ncr_35117_u127_vers.4-2.bin", + "roms/machines/pc8/ncr_35116_u113_vers.4-2.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&kbc_at_ncr_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + +int +machine_at_m290_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/m290/m290_pep3_1.25.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 6); + device_add(&amstrad_megapc_nvr_device); + + device_add(&olivetti_eva_device); + device_add(&port_6x_olivetti_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&kbc_at_olivetti_device); + + return ret; +} + +/* C&T PC/AT */ +static void +machine_at_ctat_common_init(const machine_t *model) +{ + machine_at_common_init(model); + + device_add(&cs8220_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&kbc_at_phoenix_device); +} + +int +machine_at_dells200_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/dells200/dellL200256_LO_@DIP28.BIN", + "roms/machines/dells200/Dell200256_HI_@DIP28.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_ctat_common_init(model); + + return ret; +} + +int +machine_at_super286c_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/super286c/hyundai_award286.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&kbc_at_ami_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&cs8220_device); + + return ret; +} + +int +machine_at_at122_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/at122/FINAL.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_ctat_common_init(model); + + return ret; +} + +int +machine_at_tuliptc7_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleavedr("roms/machines/tuliptc7/tc7be.bin", + "roms/machines/tuliptc7/tc7bo.bin", + 0x000f8000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_ctat_common_init(model); + + return ret; +} + +int +machine_at_wellamerastar_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/wellamerastar/W_3.031_L.BIN", + "roms/machines/wellamerastar/W_3.031_H.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_ctat_common_init(model); + + return ret; +} + +/* GC103 */ +int +machine_at_quadt286_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/quadt286/QUADT89L.ROM", + "roms/machines/quadt286/QUADT89H.ROM", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&kbc_at_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&headland_gc10x_device); + + return ret; +} + +void +machine_at_headland_common_init(const machine_t *model, int type) +{ + device_add(&kbc_at_ami_device); + + if ((type != 2) && (fdc_current[0] == FDC_INTERNAL)) + device_add(&fdc_at_device); + + if (type == 2) + device_add(&headland_ht18b_device); + else if (type == 1) + device_add(&headland_gc113_device); + else + device_add(&headland_gc10x_device); +} + +int +machine_at_tg286m_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/tg286m/ami.bin", + 0x000f0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_ide_init(model); + + machine_at_headland_common_init(model, 1); + + return ret; +} + +// TODO +// Onboard Paradise PVGA1A-JK VGA Graphics +// Data Technology Corporation DTC7187 RLL Controller (Optional) +int +machine_at_ataripc4_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/ataripc4/AMI_PC4X_1.7_EVEN.BIN", + "roms/machines/ataripc4/AMI_PC4X_1.7_ODD.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&neat_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&kbc_at_ami_device); + + return ret; +} + +int +machine_at_neat_ami_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ami286/AMIC206.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&neat_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&kbc_at_ami_device); + + return ret; +} + +int +machine_at_3302_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/3302/f000-flex_drive_test.bin", + 0x000f0000, 65536, 0); + + if (ret) { + ret &= bios_load_aux_linear("roms/machines/3302/f800-setup_ncr3.5-013190.bin", + 0x000f8000, 32768, 0); + } + + if (bios_only || !ret) + return ret; + + machine_at_common_ide_init(model); + device_add(&neat_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + device_add(&kbc_at_ncr_device); + + return ret; +} + +int +machine_at_px286_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/px286/KENITEC.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&kbc_at_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&neat_device); + + return ret; +} + +/* SCAT */ +static void +machine_at_scat_init(const machine_t *model, int is_v4, int is_ami) +{ + machine_at_common_init(model); + + if (machines[machine].bus_flags & MACHINE_BUS_PS2) { + if (is_ami) + device_add(&kbc_ps2_ami_device); + else + device_add(&kbc_ps2_device); + } else { + if (is_ami) + device_add(&kbc_at_ami_device); + else + device_add(&kbc_at_device); + } + + if (is_v4) + device_add(&scat_4_device); + else + device_add(&scat_device); +} + +int +machine_at_gw286ct_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/gw286ct/2ctc001.bin", + 0x000f0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + device_add(&f82c710_device); + + machine_at_scat_init(model, 1, 0); + + device_add(&ide_isa_device); + + return ret; +} + +int +machine_at_gdc212m_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/gdc212m/gdc212m_72h.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_scat_init(model, 0, 1); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&ide_isa_device); + + return ret; +} + +int +machine_at_award286_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/award286/award.bin", + 0x000f0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_scat_init(model, 0, 1); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&ide_isa_device); + + return ret; +} + +int +machine_at_super286tr_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/super286tr/hyundai_award286.bin", + 0x000f0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_scat_init(model, 0, 1); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + +int +machine_at_drsm35286_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/drsm35286/syab04-665821fb81363428830424.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + device_add(&ide_isa_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C651 | FDC37C6XX_IDE_PRI)); + + machine_at_scat_init(model, 1, 0); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + return ret; +} + +int +machine_at_deskmaster286_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/deskmaster286/SAMSUNG-DESKMASTER-28612-ROM.BIN", + 0x000f0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_scat_init(model, 0, 1); + + device_add(&f82c710_device); + + device_add(&ide_isa_device); + + return ret; +} + +int +machine_at_spc4200p_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/spc4200p/u8.01", + 0x000f0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_scat_init(model, 0, 1); + + device_add(&f82c710_device); + + device_add(&ide_isa_device); + + return ret; +} + +int +machine_at_spc4216p_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/spc4216p/7101.U8", + "roms/machines/spc4216p/AC64.U10", + 0x000f0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_scat_init(model, 1, 1); + + device_add(&f82c710_device); + + return ret; +} + +int +machine_at_spc4620p_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/spc4620p/31005h.u8", + "roms/machines/spc4620p/31005h.u10", + 0x000f0000, 131072, 0x8000); + + if (bios_only || !ret) + return ret; + + if (gfxcard[0] == VID_INTERNAL) + device_add(&ati28800k_spc4620p_device); + + machine_at_scat_init(model, 1, 1); + + device_add(&f82c710_device); + + device_add(&ide_isa_device); + + return ret; +} + +int +machine_at_senor_scat286_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/senor286/AMI-DSC2-1115-061390-K8.rom", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_scat_init(model, 0, 1); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 0fcce36b3..880bb2218 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -423,7 +423,7 @@ machine_at_vect486vl_init(const machine_t *model) // has HDC problems device_add(&vl82c113_device); device_add(&ide_isa_device); - device_add(&fdc37c651_ide_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C651 | FDC37C6XX_IDE_PRI)); return ret; } @@ -453,7 +453,7 @@ machine_at_d824_init(const machine_t *model) device_add(&vl82c113_device); device_add(&ide_isa_device); - device_add(&fdc37c651_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C651); return ret; } @@ -477,7 +477,7 @@ machine_at_tuliptc38_init(const machine_t *model) device_add(&vl82c113_device); device_add(&ide_isa_device); - device_add(&fdc37c651_ide_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C651 | FDC37C6XX_IDE_PRI)); if (gfxcard[0] == VID_INTERNAL) { bios_load_aux_linear("roms/machines/tuliptc38/VBIOS.BIN", @@ -510,7 +510,7 @@ machine_at_martin_init(const machine_t *model) device_add(&vl82c113_device); device_add(&ide_vlb_device); - device_add(&fdc37c651_ide_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C651 | FDC37C6XX_IDE_PRI)); device_add(&intel_flash_bxt_device); @@ -586,7 +586,7 @@ machine_at_decpclpv_init(const machine_t *model) device_add(&kbc_ps2_phoenix_pci_device); device_add(&ide_isa_2ch_device); - device_add(&fdc37c663_ide_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C663 | FDC37C6XX_IDE_PRI)); return ret; } @@ -617,7 +617,7 @@ machine_at_dell466np_init(const machine_t *model) device_add(&kbc_ps2_phoenix_pci_device); device_add(&ide_isa_device); - device_add(&fdc37c661_ide_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C661 | FDC37C6XX_IDE_PRI)); return ret; } @@ -759,7 +759,7 @@ machine_at_c747_init(const machine_t *model) desired behavior: command A9 does absolutely nothing. */ device_add(&kbc_at_siemens_device); - device_add(&um82c862f_ide_device); + device_add_params(&um866x_device, (void *) (UM82C862F | UM866X_IDE_PRI)); return ret; } @@ -921,8 +921,8 @@ machine_at_pb450_init(const machine_t *model) device_add(&opti602_device); device_add(&opti822_device); device_add(&kbc_ps2_phoenix_device); - device_add(&fdc37c665_ide_device); - device_add(&ide_opti611_vlb_sec_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_SEC)); + device_add(&ide_opti611_vlb_device); device_add(&intel_flash_bxt_device); device_add(&phoenix_486_jumper_pci_device); @@ -952,7 +952,7 @@ machine_at_pc330_6573_common_init(const machine_t *model) device_add(&opti802g_device); device_add(&opti822_device); device_add(&kbc_ps2_ami_device); - device_add(&fdc37c665_ide_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_SEC)); device_add(&ide_opti611_vlb_device); device_add(&intel_flash_bxt_device); } @@ -1005,7 +1005,9 @@ machine_at_mvi486_init(const machine_t *model) device_add(&opti498_device); device_add(&kbc_at_device); - device_add(&pc87311_ide_device); + + device_add(&ide_isa_device); + device_add_params(&pc873xx_device, (void *) (PCX73XX_IDE_PRI | PCX730X_398)); return ret; } @@ -1056,7 +1058,7 @@ machine_at_advantage40xxd_init(const machine_t *model) device_add(machine_get_vid_device(machine)); device_add(&kbc_ps2_phoenix_device); - device_add(&um82c863f_ide_device); + device_add_params(&um866x_device, (void *) (UM82C863F | UM866X_IDE_PRI)); device_add(&intel_flash_bxt_device); @@ -1262,7 +1264,7 @@ machine_at_r418_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&kbc_ps2_pci_device); return ret; @@ -1288,7 +1290,7 @@ machine_at_m4li_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&kbc_ps2_pci_device); return ret; @@ -1314,7 +1316,7 @@ machine_at_ls486e_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&kbc_ps2_ami_pci_device); return ret; @@ -1340,7 +1342,7 @@ machine_at_4dps_init(const machine_t *model) pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3); - device_add(&w83787f_device); + device_add_params(&w837x7_device, (void *) (W83787IF | W837X7_KEY_89)); device_add(&kbc_ps2_ami_device); device_add(&intel_flash_bxt_device); @@ -1367,7 +1369,7 @@ machine_at_ms4144_init(const machine_t *model) pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); - device_add(&w83787f_device); + device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_89)); device_add(&kbc_at_ami_device); device_add(&sst_flash_29ee010_device); @@ -1396,11 +1398,11 @@ machine_at_acerp3_init(const machine_t *model) pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); - device_add(&fdc37c665_ide_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_PRI)); device_add(&kbc_ps2_acer_pci_device); - device_add(&ide_cmd640_pci_legacy_only_device); - - if (gfxcard[0] == VID_INTERNAL) + device_add(&ide_cmd640_pci_legacy_only_device); + + if (gfxcard[0] == VID_INTERNAL) device_add(&gd5434_onboard_pci_device); device_add(&intel_flash_bxt_device); @@ -1427,7 +1429,7 @@ machine_at_486sp3c_init(const machine_t *model) pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&kbc_ps2_ami_pci_device); device_add(&intel_flash_bxt_device); @@ -1455,7 +1457,7 @@ machine_at_4saw2_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); - device_add(&w83787f_device); + device_add_params(&w837x7_device, (void *) (W83777F | W837X7_KEY_89)); device_add(&kbc_ps2_pci_device); device_add(&intel_flash_bxt_device); @@ -1488,7 +1490,7 @@ machine_at_alfredo_init(const machine_t *model) pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&kbc_ps2_phoenix_device); device_add(&sio_device); - device_add(&fdc37c663_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C663); device_add(&intel_flash_bxt_ami_device); device_add(&i420tx_device); @@ -1519,7 +1521,7 @@ machine_at_ninja_init(const machine_t *model) device_add(&intel_flash_bxt_ami_device); device_add(&i420ex_device); - device_add(&i82091aa_device); + device_add_params(&i82091aa_device, (void *) I82091AA_022); return ret; } @@ -1548,7 +1550,7 @@ machine_at_bat4ip3e_init(const machine_t *model) device_add(&kbc_ps2_pci_device); device_add(&i420ex_device); device_add(&ide_cmd640_pci_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); return ret; } @@ -1573,7 +1575,7 @@ machine_at_486pi_init(const machine_t *model) pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 1, 2); device_add(&kbc_ps2_ami_pci_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&i420ex_device); return ret; @@ -1598,7 +1600,7 @@ machine_at_sb486p_init(const machine_t *model) pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 2, 1); device_add(&kbc_ps2_ami_pci_device); - device_add(&i82091aa_device); + device_add_params(&i82091aa_device, (void *) I82091AA_022); device_add(&i420ex_device); return ret; @@ -1628,7 +1630,7 @@ machine_at_486sp3_init(const machine_t *model) pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&kbc_at_ami_device); /* Uses the AMIKEY KBC */ device_add(&sio_device); - device_add(&fdc37c663_ide_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C663 | FDC37C6XX_IDE_PRI)); device_add(&sst_flash_29ee010_device); device_add(&i420tx_device); @@ -1657,7 +1659,7 @@ machine_at_amis76_init(const machine_t *model) pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&kbc_ps2_ami_pci_device); device_add(&sio_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&intel_flash_bxt_ami_device); device_add(&i420tx_device); @@ -1750,7 +1752,7 @@ machine_at_486sp3g_init(const machine_t *model) pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&kbc_ps2_ami_pci_device); /* Uses the AMIKEY KBC */ device_add(&sio_zb_device); - device_add(&pc87332_398_ide_device); + device_add_params(&pc873xx_device, (void *) (PC87332 | PCX73XX_IDE_PRI | PCX730X_398)); device_add(&sst_flash_29ee010_device); device_add(&i420zx_device); @@ -1829,7 +1831,7 @@ machine_at_sb486pv_init(const machine_t *model) device_add(&kbc_ps2_ami_pci_device); device_add(&sio_zb_device); device_add(&ide_rz1000_pci_single_channel_device); - device_add(&i82091aa_26e_device); + device_add_params(&i82091aa_device, (void *) I82091AA_26E); if (!strcmp(fn, "roms/machines/sb486pv/amiboot.rom")) device_add(&intel_flash_bxt_device); else @@ -1892,7 +1894,7 @@ machine_at_g486vpa_init(const machine_t *model) device_add(&via_vt82c49x_pci_ide_device); device_add(&via_vt82c505_device); - device_add(&pc87332_398_ide_sec_device); + device_add_params(&pc873xx_device, (void *) (PC87332 | PCX73XX_IDE_SEC | PCX730X_398)); device_add(&kbc_ps2_ami_pci_device); device_add(&sst_flash_29ee010_device); @@ -1921,7 +1923,7 @@ machine_at_486vipio2_init(const machine_t *model) device_add(&via_vt82c49x_pci_ide_device); device_add(&via_vt82c505_device); - device_add(&w83787f_ide_sec_device); + device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_89)); device_add(&kbc_ps2_ami_pci_device); device_add(&sst_flash_29ee010_device); @@ -1948,7 +1950,7 @@ machine_at_abpb4_init(const machine_t *model) pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&ali1489_device); - device_add(&w83787f_device); + device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_89)); device_add(&kbc_at_device); #if 0 device_add(&intel_flash_bxt_device); @@ -1978,7 +1980,7 @@ machine_at_win486pci_init(const machine_t *model) pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&ali1489_device); - device_add(&prime3b_device); + device_add_params(&gm82c803ab_device, (void *) GM82C803B); device_add(&kbc_at_ami_device); return ret; @@ -2005,7 +2007,7 @@ machine_at_ms4145_init(const machine_t *model) pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&ali1489_device); - device_add(&w83787f_device); + device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_89)); device_add(&kbc_at_ami_device); device_add(&sst_flash_29ee010_device); @@ -2037,7 +2039,7 @@ machine_at_sbc490_init(const machine_t *model) device_add(machine_get_vid_device(machine)); device_add(&ali1489_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&kbc_ps2_ami_device); device_add(&sst_flash_29ee010_device); @@ -2062,8 +2064,8 @@ machine_at_tf486_init(const machine_t *model) pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&ali1489_device); - device_add(&w83977ef_device); - device_add(&kbc_at_device); + device_add(&kbc_at_phoenix_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_NO_NVR)); device_add(&sst_flash_29ee010_device); return ret; @@ -2085,7 +2087,7 @@ machine_at_arb1476_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); device_add(&ali1489_device); - device_add(&fdc37c669_device); + device_add_params(&fdc37c669_device, (void *) 0); device_add(&kbc_ps2_device); device_add(&sst_flash_29ee010_device); @@ -2103,14 +2105,13 @@ machine_at_itoxstar_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x1F, PCI_CARD_NORMAL, 1, 2, 3, 4); - device_add(&w83977f_device); - device_add(&kbc_ps2_ami_pci_device); + device_add_params(&w83977_device, (void *) (W83977F | W83977_AMI)); device_add(&stpc_client_device); device_add(&sst_flash_29ee020_device); device_add(&w83781d_device); /* fans: Chassis, CPU, unused; temperatures: Chassis, CPU, unused */ @@ -2132,7 +2133,7 @@ machine_at_arb1423c_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -2140,8 +2141,7 @@ machine_at_arb1423c_init(const machine_t *model) pci_register_slot(0x1F, PCI_CARD_NORMAL, 1, 0, 0, 0); pci_register_slot(0x1E, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x1D, PCI_CARD_NORMAL, 3, 4, 1, 2); - device_add(&w83977f_device); - device_add(&kbc_ps2_ami_pci_device); + device_add_params(&w83977_device, (void *) (W83977F | W83977_AMI)); device_add(&stpc_consumer2_device); device_add(&winbond_flash_w29c020_device); @@ -2159,7 +2159,7 @@ machine_at_arb1479_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -2167,8 +2167,7 @@ machine_at_arb1479_init(const machine_t *model) pci_register_slot(0x1F, PCI_CARD_NORMAL, 1, 0, 0, 0); pci_register_slot(0x1E, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x1D, PCI_CARD_NORMAL, 3, 4, 1, 2); - device_add(&w83977f_device); - device_add(&kbc_ps2_ami_pci_device); + device_add_params(&w83977_device, (void *) (W83977F | W83977_AMI)); device_add(&stpc_consumer2_device); device_add(&winbond_flash_w29c020_device); @@ -2186,13 +2185,12 @@ machine_at_iach488_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&w83977f_device); - device_add(&kbc_ps2_ami_pci_device); + device_add_params(&w83977_device, (void *) (W83977F | W83977_AMI)); device_add(&stpc_consumer2_device); device_add(&sst_flash_29ee020_device); @@ -2210,7 +2208,7 @@ machine_at_pcm9340_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -2218,9 +2216,8 @@ machine_at_pcm9340_init(const machine_t *model) pci_register_slot(0x1D, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x1E, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x1F, PCI_CARD_NORMAL, 2, 3, 4, 1); - device_add_inst(&w83977f_device, 1); - device_add_inst(&w83977f_device, 2); - device_add(&kbc_ps2_ami_pci_device); + device_add_inst_params(&w83977_device, 1, (void *) (W83977F | W83977_AMI)); + device_add_inst_params(&w83977_device, 2, (void *) W83977F); device_add(&stpc_elite_device); device_add(&sst_flash_29ee020_device); @@ -2238,7 +2235,7 @@ machine_at_pcm5330_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -2247,8 +2244,7 @@ machine_at_pcm5330_init(const machine_t *model) pci_register_slot(0x0E, PCI_CARD_SOUTHBRIDGE_USB, 1, 2, 3, 4); pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&stpc_serial_device); - device_add(&w83977f_370_device); - device_add(&kbc_ps2_ami_pci_device); + device_add_params(&w83977_device, (void *) (W83977F | W83977_370 | W83977_AMI)); device_add(&stpc_atlas_device); device_add(&sst_flash_29ee020_device); @@ -2279,7 +2275,7 @@ machine_at_ecs486_init(const machine_t *model) device_add(&umc_hb4_device); device_add(&umc_8886f_device); device_add(&ide_cmd640_pci_legacy_only_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&intel_flash_bxt_device); device_add(&kbc_ps2_ami_device); @@ -2358,9 +2354,9 @@ machine_at_hot433a_init(const machine_t *model) device_add(&umc_hb4_device); device_add(&umc_8886bf_device); if (is_award) - device_add(&um8663af_device); + device_add_params(&um866x_device, (void *) UM8663AF); else - device_add(&um8669f_device); + device_add_params(&um8669f_device, (void *) 0); device_add(&winbond_flash_w29c010_device); if (is_award) device_add(&kbc_ps2_ami_device); @@ -2394,7 +2390,7 @@ machine_at_84xxuuda_init(const machine_t *model) device_add(&umc_hb4_device); device_add(&umc_8886bf_device); - device_add(&um8663bf_device); + device_add_params(&um866x_device, (void *) UM8663BF); device_add(&winbond_flash_w29c010_device); device_add(&kbc_ps2_ami_device); @@ -2425,7 +2421,7 @@ machine_at_pl4600c_init(const machine_t *model) device_add(&umc_hb4_device); device_add(&umc_8886af_device); - device_add(&um8663af_device); + device_add_params(&um866x_device, (void *) UM8663AF); device_add(&sst_flash_29ee010_device); device_add(&kbc_ps2_ami_pci_device); @@ -2496,7 +2492,7 @@ machine_at_actionpc2600_init(const machine_t *model) device_add(&umc_hb4_device); device_add(&umc_8886bf_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&intel_flash_bxt_device); device_add(&kbc_ps2_tg_ami_device); @@ -2528,7 +2524,7 @@ machine_at_actiontower8400_init(const machine_t *model) device_add(&umc_hb4_device); device_add(&umc_8886f_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&ide_cmd640_pci_device); device_add(&intel_flash_bxt_device); // The ActionPC 2600 has this so I'm gonna assume this does too. device_add(&kbc_ps2_ami_pci_device); @@ -2560,7 +2556,7 @@ machine_at_m919_init(const machine_t *model) device_add(&umc_hb4_device); device_add(&umc_8886af_device); /* AF is correct - the BIOS does IDE writes to ports 108h and 109h. */ - device_add(&um8663bf_device); + device_add_params(&um866x_device, (void *) UM8663BF); device_add(&sst_flash_29ee010_device); device_add(&kbc_at_ami_device); @@ -2589,7 +2585,7 @@ machine_at_spc7700plw_init(const machine_t *model) device_add(&umc_hb4_device); device_add(&umc_8886af_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&intel_flash_bxt_device); device_add(&kbc_ps2_ami_device); @@ -2611,7 +2607,7 @@ machine_at_ms4134_init(const machine_t *model) device_add(&ali1429g_device); - device_add(&fdc37c665_ide_pri_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_PRI)); pci_init(FLAG_MECHANISM_1 | FLAG_MECHANISM_2 | PCI_ALWAYS_EXPOSE_DEV0); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -2645,7 +2641,7 @@ machine_at_tg486gp_init(const machine_t *model) device_add(&ali1429g_device); - device_add(&fdc37c665_ide_pri_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_PRI)); pci_init(FLAG_MECHANISM_1 | FLAG_MECHANISM_2 | PCI_ALWAYS_EXPOSE_DEV0); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -2678,7 +2674,7 @@ machine_at_tg486g_init(const machine_t *model) device_add(&amstrad_megapc_nvr_device); device_add(&sis_85c471_device); device_add(&ide_isa_device); - device_add(&fdc37c651_ide_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C651 | FDC37C6XX_IDE_PRI)); device_add(&kbc_ps2_tg_ami_pci_device); if (gfxcard[0] != VID_INTERNAL) { @@ -2705,7 +2701,7 @@ machine_at_dvent4xx_init(const machine_t *model) machine_at_common_init(model); device_add(&sis_85c471_device); device_add(&ide_cmd640_vlb_pri_device); - device_add(&fdc37c665_ide_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_SEC)); device_add(&kbc_ps2_phoenix_device); if (gfxcard[0] == VID_INTERNAL) @@ -2753,7 +2749,7 @@ machine_at_ap4100aa_init(const machine_t *model) device_add(&ali1429g_device); device_add(&kbc_ps2_ami_pci_device); device_add(&ide_vlb_device); - device_add(&um8663bf_device); + device_add_params(&um866x_device, (void *) UM8663BF); return ret; } @@ -2886,7 +2882,7 @@ machine_at_cobalt_init(const machine_t *model) device_add(&opti499_device); device_add(&ide_opti611_vlb_device); device_add(&ide_isa_sec_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&kbc_ps2_ami_device); @@ -2911,7 +2907,7 @@ machine_at_cougar_init(const machine_t *model) device_add(&ide_vlb_device); device_add(&opti499_device); - device_add(&fdc37c665_ide_pri_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_PRI)); device_add(&kbc_at_ami_device); diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_386sx.c similarity index 54% rename from src/machine/m_at_286_386sx.c rename to src/machine/m_at_386sx.c index 8f2c9215f..d52cd6611 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_386sx.c @@ -6,15 +6,13 @@ * * This file is part of the 86Box distribution. * - * Implementation of 286 and 386SX machines. - * - * + * Implementation of 386SX machines. * * Authors: Miran Grca, * EngiNerd * - * Copyright 2016-2019 Miran Grca. - * Copyright 2020 EngiNerd. + * Copyright 2016-2025 Miran Grca. + * Copyright 2020-2025 EngiNerd. */ #include #include @@ -45,104 +43,31 @@ #include <86box/flash.h> #include <86box/machine.h> +/* ISA */ +/* + * Current bugs: + * - soft-reboot after saving CMOS settings/pressing ctrl-alt-del produces an 8042 error + */ int -machine_at_mr286_init(const machine_t *model) +machine_at_pc916sx_init(const machine_t *model) { int ret; - ret = bios_load_interleaved("roms/machines/mr286/V000B200-1", - "roms/machines/mr286/V000B200-2", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_ide_init(model); - device_add(&kbc_at_device); - - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); - - return ret; -} - -static void -machine_at_headland_common_init(const machine_t *model, int type) -{ - device_add(&kbc_at_ami_device); - - if ((type != 2) && (fdc_current[0] == FDC_INTERNAL)) - device_add(&fdc_at_device); - - if (type == 2) - device_add(&headland_ht18b_device); - else if (type == 1) - device_add(&headland_gc113_device); - else - device_add(&headland_gc10x_device); -} - -int -machine_at_tg286m_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/tg286m/ami.bin", - 0x000f0000, 131072, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_ide_init(model); - - machine_at_headland_common_init(model, 1); - - return ret; -} - -int -machine_at_ama932j_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/ama932j/ami.bin", - 0x000f0000, 131072, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_ide_init(model); - - if (gfxcard[0] == VID_INTERNAL) - device_add(&oti067_ama932j_device); - - machine_at_headland_common_init(model, 2); - - device_add_params(&pc87310_device, (void *) (PC87310_ALI)); - - return ret; -} - -int -machine_at_quadt286_init(const machine_t *model) -{ - int ret; - - ret = bios_load_interleaved("roms/machines/quadt286/QUADT89L.ROM", - "roms/machines/quadt286/QUADT89H.ROM", + ret = bios_load_interleaved("roms/machines/pc916sx/ncr_386sx_u46-17_7.3.bin", + "roms/machines/pc916sx/ncr_386sx_u12-19_7.3.bin", 0x000f0000, 65536, 0); if (bios_only || !ret) return ret; machine_at_common_init(model); - device_add(&kbc_at_device); + + device_add(&kbc_at_ncr_device); + mem_remap_top(384); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); - device_add(&headland_gc10x_device); - return ret; } @@ -169,6 +94,7 @@ machine_at_quadt386sx_init(const machine_t *model) return ret; } +/* ACC2036 */ static const device_config_t pbl300sx_config[] = { // clang-format off { @@ -227,7 +153,7 @@ machine_at_pbl300sx_init(const machine_t *model) device_add(&acc2036_device); device_add(&kbc_ps2_phoenix_device); - device_add(&um82c862f_ide_device); + device_add_params(&um866x_device, (void *) (UM82C862F | UM866X_IDE_PRI)); if (gfxcard[0] == VID_INTERNAL) device_add(machine_get_vid_device(machine)); @@ -235,33 +161,13 @@ machine_at_pbl300sx_init(const machine_t *model) return ret; } +/* ALi M1217 */ int -machine_at_neat_init(const machine_t *model) +machine_at_arb1374_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/dtk386/3cto001.bin", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_init(model); - - device_add(&neat_device); - - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); - - return ret; -} - -int -machine_at_neat_ami_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/ami286/AMIC206.BIN", + ret = bios_load_linear("roms/machines/arb1374/1374s.rom", 0x000f0000, 65536, 0); if (bios_only || !ret) @@ -269,290 +175,20 @@ machine_at_neat_ami_init(const machine_t *model) machine_at_common_init(model); - device_add(&neat_device); - - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); - - device_add(&kbc_at_ami_device); - - return ret; -} - -// TODO -// Onboard Paradise PVGA1A-JK VGA Graphics -// Data Technology Corporation DTC7187 RLL Controller (Optional) -int -machine_at_ataripc4_init(const machine_t *model) -{ - int ret; - - ret = bios_load_interleaved("roms/machines/ataripc4/AMI_PC4X_1.7_EVEN.BIN", - "roms/machines/ataripc4/AMI_PC4X_1.7_ODD.BIN", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - - device_add(&neat_device); - - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); - - device_add(&kbc_at_ami_device); - - return ret; -} - -int -machine_at_px286_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/px286/KENITEC.BIN", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - device_add(&kbc_at_device); - - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); - - device_add(&neat_device); - - return ret; -} - -static void -machine_at_ctat_common_init(const machine_t *model) -{ - machine_at_common_init(model); - - device_add(&cs8220_device); - - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); - - device_add(&kbc_at_phoenix_device); -} - -int -machine_at_dells200_init(const machine_t *model) -{ - int ret; - - ret = bios_load_interleaved("roms/machines/dells200/dellL200256_LO_@DIP28.BIN", - "roms/machines/dells200/Dell200256_HI_@DIP28.BIN", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_ctat_common_init(model); - - return ret; -} - -int -machine_at_at122_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/at122/FINAL.BIN", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_ctat_common_init(model); - - return ret; -} - -int -machine_at_tuliptc7_init(const machine_t *model) -{ - int ret; - - ret = bios_load_interleavedr("roms/machines/tuliptc7/tc7be.bin", - "roms/machines/tuliptc7/tc7bo.bin", - 0x000f8000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_ctat_common_init(model); - - return ret; -} - -int -machine_at_wellamerastar_init(const machine_t *model) -{ - int ret; - - ret = bios_load_interleaved("roms/machines/wellamerastar/W_3.031_L.BIN", - "roms/machines/wellamerastar/W_3.031_H.BIN", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_ctat_common_init(model); - - return ret; -} - -static void -machine_at_scat_init(const machine_t *model, int is_v4, int is_ami) -{ - machine_at_common_init(model); - - if (machines[machine].bus_flags & MACHINE_BUS_PS2) { - if (is_ami) - device_add(&kbc_ps2_ami_device); - else - device_add(&kbc_ps2_device); - } else { - if (is_ami) - device_add(&kbc_at_ami_device); - else - device_add(&kbc_at_device); - } - - if (is_v4) - device_add(&scat_4_device); - else - device_add(&scat_device); -} - -static void -machine_at_scatsx_init(const machine_t *model) -{ - machine_at_common_init(model); - - device_add(&kbc_at_ami_device); - - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); - - device_add(&scat_sx_device); -} - -int -machine_at_award286_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/award286/award.bin", - 0x000f0000, 131072, 0); - - if (bios_only || !ret) - return ret; - - machine_at_scat_init(model, 0, 1); - - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); - + device_add(&ali1217_device); device_add(&ide_isa_device); + device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0 | W83XX7_IDE_PRI)); + device_add(&kbc_ps2_ami_device); return ret; } int -machine_at_gdc212m_init(const machine_t *model) +machine_at_sbc350a_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/gdc212m/gdc212m_72h.bin", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_scat_init(model, 0, 1); - - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); - - device_add(&ide_isa_device); - - return ret; -} - -int -machine_at_gw286ct_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/gw286ct/2ctc001.bin", - 0x000f0000, 131072, 0); - - if (bios_only || !ret) - return ret; - - device_add(&f82c710_device); - - machine_at_scat_init(model, 1, 0); - - device_add(&ide_isa_device); - - return ret; -} - -int -machine_at_drsm35286_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/drsm35286/syab04-665821fb81363428830424.bin", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - device_add(&ide_isa_device); - device_add(&fdc37c651_ide_device); - - machine_at_scat_init(model, 1, 0); - - if (gfxcard[0] == VID_INTERNAL) - device_add(machine_get_vid_device(machine)); - - return ret; -} - -int -machine_at_senor_scat286_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/senor286/AMI-DSC2-1115-061390-K8.rom", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_scat_init(model, 0, 1); - - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); - - return ret; -} - -int -machine_at_super286c_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/super286c/hyundai_award286.bin", + ret = bios_load_linear("roms/machines/sbc350a/350a.rom", 0x000f0000, 65536, 0); if (bios_only || !ret) @@ -560,130 +196,147 @@ machine_at_super286c_init(const machine_t *model) machine_at_common_init(model); - device_add(&kbc_at_ami_device); - - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); - - device_add(&cs8220_device); - - return ret; -} - -int -machine_at_super286tr_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/super286tr/hyundai_award286.bin", - 0x000f0000, 131072, 0); - - if (bios_only || !ret) - return ret; - - machine_at_scat_init(model, 0, 1); - - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); - - return ret; -} - -int -machine_at_spc4200p_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/spc4200p/u8.01", - 0x000f0000, 131072, 0); - - if (bios_only || !ret) - return ret; - - machine_at_scat_init(model, 0, 1); - - device_add(&f82c710_device); - + device_add(&ali1217_device); device_add(&ide_isa_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_PRI)); + device_add(&kbc_ps2_ami_device); return ret; } int -machine_at_spc4216p_init(const machine_t *model) +machine_at_flytech386_init(const machine_t *model) { int ret; - ret = bios_load_interleaved("roms/machines/spc4216p/7101.U8", - "roms/machines/spc4216p/AC64.U10", - 0x000f0000, 131072, 0); + ret = bios_load_linear("roms/machines/flytech386/FLYTECH.BIO", + 0x000f0000, 65536, 0); if (bios_only || !ret) return ret; - machine_at_scat_init(model, 1, 1); + machine_at_common_init(model); - device_add(&f82c710_device); - - return ret; -} - -int -machine_at_spc4620p_init(const machine_t *model) -{ - int ret; - - ret = bios_load_interleaved("roms/machines/spc4620p/31005h.u8", - "roms/machines/spc4620p/31005h.u10", - 0x000f0000, 131072, 0x8000); - - if (bios_only || !ret) - return ret; + device_add(&ali1217_device); + device_add(&ide_isa_device); + device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_89 | W83XX7_IDE_PRI | W837X7_IDE_START)); if (gfxcard[0] == VID_INTERNAL) - device_add(&ati28800k_spc4620p_device); + device_add(&tvga8900d_device); - machine_at_scat_init(model, 1, 1); - - device_add(&f82c710_device); - - device_add(&ide_isa_device); + device_add(&kbc_at_ami_device); return ret; } int -machine_at_kmxc02_init(const machine_t *model) +machine_at_325ax_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/kmxc02/3ctm005.bin", - 0x000f0000, 131072, 0); + ret = bios_load_linear("roms/machines/325ax/M27C512.BIN", + 0x000f0000, 65536, 0); if (bios_only || !ret) return ret; - machine_at_scatsx_init(model); + machine_at_common_init(model); + + device_add(&ali1217_device); + device_add(&fdc_at_device); + device_add(&kbc_at_ami_device); return ret; } int -machine_at_deskmaster286_init(const machine_t *model) +machine_at_mr1217_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/deskmaster286/SAMSUNG-DESKMASTER-28612-ROM.BIN", + ret = bios_load_linear("roms/machines/mr1217/mrbios.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&ali1217_device); + device_add(&fdc_at_device); + device_add(&kbc_at_ami_device); + + return ret; +} + +/* ALi M1409 */ +int +machine_at_acer100t_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/acer100t/acer386.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_ps2_ide_init(model); + + device_add(&ali1409_device); + if (gfxcard[0] == VID_INTERNAL) + device_add(&oti077_acer100t_device); + + device_add_params(&pc87310_device, (void *) (PC87310_ALI)); + + return ret; +} + +/* HT18 */ +int +machine_at_ama932j_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ama932j/ami.bin", 0x000f0000, 131072, 0); if (bios_only || !ret) return ret; - machine_at_scat_init(model, 0, 1); + machine_at_common_ide_init(model); - device_add(&f82c710_device); - - device_add(&ide_isa_device); + if (gfxcard[0] == VID_INTERNAL) + device_add(&oti067_ama932j_device); + + machine_at_headland_common_init(model, 2); + + device_add_params(&pc87310_device, (void *) (PC87310_ALI)); + + return ret; +} + +/* Intel 82335 */ +int +machine_at_adi386sx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/adi386sx/3iip001l.bin", + "roms/machines/adi386sx/3iip001h.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + device_add(&amstrad_megapc_nvr_device); /* NVR that is initialized to all 0x00's. */ + + device_add(&intel_82335_device); + device_add(&kbc_at_ami_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); return ret; } @@ -711,54 +364,7 @@ machine_at_shuttle386sx_init(const machine_t *model) return ret; } -int -machine_at_adi386sx_init(const machine_t *model) -{ - int ret; - - ret = bios_load_interleaved("roms/machines/adi386sx/3iip001l.bin", - "roms/machines/adi386sx/3iip001h.bin", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - device_add(&amstrad_megapc_nvr_device); /* NVR that is initialized to all 0x00's. */ - - device_add(&intel_82335_device); - device_add(&kbc_at_ami_device); - - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); - - return ret; -} - -int -machine_at_wd76c10_init(const machine_t *model) -{ - int ret; - - ret = bios_load_interleaved("roms/machines/megapc/41651-bios lo.u18", - "roms/machines/megapc/211253-bios hi.u19", - 0x000f0000, 65536, 0x08000); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - if (gfxcard[0] == VID_INTERNAL) - device_add(¶dise_wd90c11_megapc_device); - - device_add(&kbc_ps2_quadtel_device); - - device_add(&wd76c10_device); - - return ret; -} - +/* NEAT */ int machine_at_cmdsl386sx16_init(const machine_t *model) { @@ -786,6 +392,28 @@ machine_at_cmdsl386sx16_init(const machine_t *model) return ret; } +int +machine_at_neat_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/dtk386/3cto001.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_init(model); + + device_add(&neat_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + +/* NEATsx */ int machine_at_if386sx_init(const machine_t *model) { @@ -819,22 +447,29 @@ machine_at_if386sx_init(const machine_t *model) return ret; } -static void -machine_at_scamp_common_init(const machine_t *model, int is_ps2) +/* OPTi 291 */ +int +machine_at_awardsx_init(const machine_t *model) { - machine_at_common_ide_init(model); + int ret; - if (is_ps2) - device_add(&kbc_ps2_ami_device); - else - device_add(&kbc_at_ami_device); + ret = bios_load_linear("roms/machines/awardsx/Unknown 386SX OPTi291 - Award (original).BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_init(model); + + device_add(&opti291_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); - device_add(&vlsi_scamp_device); + return ret; } +/* SCAMP */ int machine_at_cmdsl386sx25_init(const machine_t *model) { @@ -861,6 +496,38 @@ machine_at_cmdsl386sx25_init(const machine_t *model) return ret; } +static void +machine_at_scamp_common_init(const machine_t *model, int is_ps2) +{ + machine_at_common_ide_init(model); + + if (is_ps2) + device_add(&kbc_ps2_ami_device); + else + device_add(&kbc_at_ami_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&vlsi_scamp_device); +} + +int +machine_at_dataexpert386sx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/dataexpert386sx/5e9f20e5ef967717086346.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_scamp_common_init(model, 0); + + return ret; +} + static const device_config_t dells333sl_config[] = { // clang-format off { @@ -922,7 +589,7 @@ machine_at_dells333sl_init(const machine_t *model) device_add(&ide_isa_device); - device_add(&pc87311_device); + device_add_params(&pc873xx_device, (void *) (PCX73XX_IDE_PRI | PCX730X_26E)); device_add(&vl82c113_device); /* The keyboard controller is part of the VL82c113. */ device_add(&vlsi_scamp_device); @@ -930,22 +597,6 @@ machine_at_dells333sl_init(const machine_t *model) return ret; } -int -machine_at_dataexpert386sx_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/dataexpert386sx/5e9f20e5ef967717086346.BIN", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_scamp_common_init(model, 0); - - return ret; -} - int machine_at_spc6033p_init(const machine_t *model) { @@ -965,301 +616,57 @@ machine_at_spc6033p_init(const machine_t *model) return ret; } -int -machine_at_awardsx_init(const machine_t *model) +/* SCATsx */ +static void +machine_at_scatsx_init(const machine_t *model) { - int ret; - - ret = bios_load_linear("roms/machines/awardsx/Unknown 386SX OPTi291 - Award (original).BIN", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_init(model); - - device_add(&opti291_device); - - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); - - return ret; -} - -int -machine_at_acer100t_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/acer100t/acer386.BIN", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_ps2_ide_init(model); - - device_add(&ali1409_device); - if (gfxcard[0] == VID_INTERNAL) - device_add(&oti077_acer100t_device); - - device_add_params(&pc87310_device, (void *) (PC87310_ALI)); - - return ret; -} - - -int -machine_at_arb1374_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/arb1374/1374s.rom", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - machine_at_common_init(model); - device_add(&ali1217_device); - device_add(&w83787f_ide_en_device); - device_add(&kbc_ps2_ami_device); - - return ret; -} - -int -machine_at_sbc350a_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/sbc350a/350a.rom", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - - device_add(&ali1217_device); - device_add(&ide_isa_device); - device_add(&fdc37c665_ide_pri_device); - device_add(&kbc_ps2_ami_device); - - return ret; -} - -int -machine_at_flytech386_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/flytech386/FLYTECH.BIO", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - - device_add(&ali1217_device); - device_add(&w83787f_ide_en_device); - - if (gfxcard[0] == VID_INTERNAL) - device_add(&tvga8900d_device); - device_add(&kbc_at_ami_device); - return ret; -} - -int -machine_at_325ax_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/325ax/M27C512.BIN", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - - device_add(&ali1217_device); - device_add(&fdc_at_device); - device_add(&kbc_at_ami_device); - - return ret; -} - -int -machine_at_mr1217_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/mr1217/mrbios.BIN", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - - device_add(&ali1217_device); - device_add(&fdc_at_device); - device_add(&kbc_at_ami_device); - - return ret; -} - -int -machine_at_pja511m_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/pja511m/2006915102435734.rom", - 0x000e0000, 131072, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - - device_add_inst(&fdc37c669_device, 1); - device_add_inst(&fdc37c669_device, 2); - device_add(&kbc_ps2_ami_pci_device); - device_add(&ali6117d_device); - device_add(&sst_flash_29ee010_device); - - return ret; -} - -int -machine_at_prox1332_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/prox1332/D30B3AC1.BIN", - 0x000e0000, 131072, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - - device_add(&fdc37c669_device); - device_add(&kbc_ps2_ami_pci_device); - device_add(&ali6117d_device); - device_add(&sst_flash_29ee010_device); - - return ret; -} - -/* - * Current bugs: - * - ctrl-alt-del produces an 8042 error - */ -int -machine_at_pc8_init(const machine_t *model) -{ - int ret; - - ret = bios_load_interleaved("roms/machines/pc8/ncr_35117_u127_vers.4-2.bin", - "roms/machines/pc8/ncr_35116_u113_vers.4-2.bin", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - device_add(&kbc_at_ncr_device); - if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); - return ret; + device_add(&scat_sx_device); } int -machine_at_3302_init(const machine_t *model) +machine_at_kmxc02_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/3302/f000-flex_drive_test.bin", - 0x000f0000, 65536, 0); - - if (ret) { - ret &= bios_load_aux_linear("roms/machines/3302/f800-setup_ncr3.5-013190.bin", - 0x000f8000, 32768, 0); - } + ret = bios_load_linear("roms/machines/kmxc02/3ctm005.bin", + 0x000f0000, 131072, 0); if (bios_only || !ret) return ret; - machine_at_common_ide_init(model); - device_add(&neat_device); + machine_at_scatsx_init(model); - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); + return ret; +} + +/* WD76C10 */ +int +machine_at_wd76c10_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/megapc/41651-bios lo.u18", + "roms/machines/megapc/211253-bios hi.u19", + 0x000f0000, 65536, 0x08000); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); if (gfxcard[0] == VID_INTERNAL) - device_add(machine_get_vid_device(machine)); + device_add(¶dise_wd90c11_megapc_device); - device_add(&kbc_at_ncr_device); - - return ret; -} - -/* - * Current bugs: - * - soft-reboot after saving CMOS settings/pressing ctrl-alt-del produces an 8042 error - */ -int -machine_at_pc916sx_init(const machine_t *model) -{ - int ret; - - ret = bios_load_interleaved("roms/machines/pc916sx/ncr_386sx_u46-17_7.3.bin", - "roms/machines/pc916sx/ncr_386sx_u12-19_7.3.bin", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - - device_add(&kbc_at_ncr_device); - mem_remap_top(384); - - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); - - return ret; -} - -int -machine_at_m290_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/m290/m290_pep3_1.25.bin", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 6); - device_add(&amstrad_megapc_nvr_device); - - device_add(&olivetti_eva_device); - device_add(&port_6x_olivetti_device); - - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); - - device_add(&kbc_at_olivetti_device); + device_add(&kbc_ps2_quadtel_device); + + device_add(&wd76c10_device); return ret; } diff --git a/src/machine/m_at_m6117.c b/src/machine/m_at_m6117.c new file mode 100644 index 000000000..9558dacf3 --- /dev/null +++ b/src/machine/m_at_m6117.c @@ -0,0 +1,88 @@ +/* + * 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 386SX machines. + * + * Authors: Miran Grca, + * EngiNerd + * + * Copyright 2016-2025 Miran Grca. + * Copyright 2020-2025 EngiNerd. + */ +#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/chipset.h> +#include <86box/keyboard.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/fdc_ext.h> +#include <86box/hdc.h> +#include <86box/nvr.h> +#include <86box/port_6x.h> +#define USE_SIO_DETECT +#include <86box/sio.h> +#include <86box/serial.h> +#include <86box/video.h> +#include <86box/vid_cga.h> +#include <86box/flash.h> +#include <86box/machine.h> + +/* ALi M6117D */ +int +machine_at_pja511m_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/pja511m/2006915102435734.rom", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add_inst_params(&fdc37c669_device, 1, (void *) FDC37C6XX_IDE_PRI); + device_add_inst_params(&fdc37c669_device, 2, (void *) 0); + device_add(&kbc_ps2_ami_pci_device); + device_add(&ali6117d_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + +int +machine_at_prox1332_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/prox1332/D30B3AC1.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add_params(&fdc37c669_device, (void *) FDC37C6XX_370); + device_add(&kbc_ps2_ami_pci_device); + device_add(&ali6117d_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} diff --git a/src/machine/m_at_misc.c b/src/machine/m_at_misc.c index b6d16246c..ad26f56e5 100644 --- a/src/machine/m_at_misc.c +++ b/src/machine/m_at_misc.c @@ -65,8 +65,7 @@ machine_at_vpc2007_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&i440bx_no_agp_device); device_add(&piix4e_device); - device_add(&w83977f_370_device); - device_add(&kbc_ps2_ami_pci_device); + device_add_params(&w83977_device, (void *) (W83977F | W83977_370 | W83977_AMI | W83977_NO_NVR)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); /* real VPC provides invalid SPD data */ diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 0bbadca0c..9c4875094 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -110,7 +110,7 @@ machine_at_kn97_init(const machine_t *model) device_add(&i440fx_device); device_add(&piix3_device); device_add(&kbc_ps2_pci_device); - device_add(&w83877f_device); + device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0)); device_add(&intel_flash_bxt_device); device_add(&lm78_device); /* fans: Chassis, CPU, Power; temperature: MB */ for (uint8_t i = 0; i < 3; i++) @@ -142,8 +142,7 @@ machine_at_lx6_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440lx_device); device_add(&piix4e_device); - device_add(&kbc_ps2_ami_pci_device); - device_add(&w83977tf_device); + device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR)); device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); @@ -272,8 +271,7 @@ machine_at_p6i440e2_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440ex_device); device_add(&piix4_device); - device_add(&kbc_ps2_ami_pci_device); - device_add(&w83977tf_device); + device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR)); device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0x03, 256); device_add(&w83781d_device); /* fans: CPU, CHS, PS; temperatures: unused, CPU, System */ @@ -308,8 +306,7 @@ machine_at_p2bls_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); - device_add(&kbc_ps2_ami_pci_device); - device_add(&w83977ef_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); #if 0 device_add(ics9xxx_get(ICS9150_08)); /* setting proper speeds requires some interaction with the AS97127F ASIC */ #endif @@ -345,8 +342,7 @@ machine_at_lgibmx7g_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); - device_add(&kbc_ps2_ami_pci_device); - device_add(&w83977tf_device); + device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR)); device_add(&winbond_flash_w29c020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -378,8 +374,7 @@ machine_at_p3bf_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); - device_add(&kbc_ps2_ami_pci_device); - device_add(&w83977ef_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); device_add(ics9xxx_get(ICS9250_08)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); @@ -415,8 +410,7 @@ machine_at_bf6_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); - device_add(&kbc_ps2_pci_device); - device_add(&w83977ef_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -446,8 +440,7 @@ machine_at_bx6_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); - device_add(&kbc_ps2_pci_device); - device_add(&w83977f_device); + device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR)); device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); @@ -478,8 +471,7 @@ machine_at_ax6bc_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); - device_add(&kbc_ps2_ami_pci_device); - device_add(&w83977tf_device); + device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR)); device_add(&sst_flash_29ee020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); device_add(&gl518sm_2d_device); /* fans: System, CPU; temperature: CPU; no reporting in BIOS */ @@ -510,8 +502,7 @@ machine_at_atc6310bxii_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&slc90e66_device); - device_add(&kbc_ps2_pci_device); - device_add(&w83977ef_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -541,8 +532,7 @@ machine_at_686bx_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); - device_add(&kbc_ps2_ami_pci_device); - device_add(&w83977tf_device); + device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); device_add(&w83781d_device); /* fans: CPU, unused, unused; temperatures: unused, CPU, unused */ @@ -580,8 +570,7 @@ machine_at_p6sba_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); - device_add(&w83977tf_device); - device_add(&kbc_ps2_ami_pci_device); + device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); device_add(&w83781d_device); /* fans: CPU1, CPU2, Thermal Control; temperatures: unused, CPU1, CPU2? */ @@ -653,7 +642,7 @@ machine_at_ficka6130_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&via_apro_device); device_add(&via_vt82c596a_device); - device_add(&w83877tf_device); + device_add_params(&w83877_device, (void *) (W83877TF | W83877_3F0)); device_add(&kbc_ps2_ami_pci_device); device_add(&sst_flash_29ee020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -686,8 +675,7 @@ machine_at_p3v133_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&via_apro133_device); device_add(&via_vt82c596b_device); - device_add(&w83977ef_device); - device_add(&kbc_ps2_ami_pci_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); device_add(ics9xxx_get(ICS9248_39)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 512); @@ -723,8 +711,7 @@ machine_at_p3v4x_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&via_apro133a_device); device_add(&via_vt82c596b_device); - device_add(&w83977ef_device); - device_add(&kbc_ps2_ami_pci_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); device_add(ics9xxx_get(ICS9250_18)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 512); @@ -756,8 +743,7 @@ machine_at_gt694va_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&via_apro133a_device); device_add(&via_vt82c596b_device); - device_add(&w83977ef_device); - device_add(&kbc_ps2_ami_pci_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 1024); device_add(&w83782d_device); /* fans: CPU, unused, unused; temperatures: System, CPU1, unused */ @@ -821,12 +807,11 @@ machine_at_ms6168_common_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440zx_device); device_add(&piix4e_device); - device_add(&w83977ef_device); if (gfxcard[0] == VID_INTERNAL) device_add(&voodoo_3_2000_agp_onboard_8m_device); - device_add(&kbc_ps2_ami_pci_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 256); diff --git a/src/machine/m_at_slot2.c b/src/machine/m_at_slot2.c index b9c556206..461ad925a 100644 --- a/src/machine/m_at_slot2.c +++ b/src/machine/m_at_slot2.c @@ -65,8 +65,7 @@ machine_at_6gxu_init(const machine_t *model) device_add(&i440gx_device); device_add(&piix4e_device); - device_add(&kbc_ps2_pci_device); - device_add(&w83977ef_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 512); device_add(&w83782d_device); /* fans: CPU, Power, System; temperatures: System, CPU, unused */ @@ -102,8 +101,7 @@ machine_at_s2dge_init(const machine_t *model) device_add(&i440gx_device); device_add(&piix4e_device); - device_add(&kbc_ps2_ami_pci_device); - device_add(&w83977tf_device); + device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0xF, 512); device_add(&w83781d_device); /* fans: CPU1, CPU2, Thermal Control; temperatures: unused, CPU1, CPU2? */ diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index fe87564e7..de07d8c41 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -63,8 +63,7 @@ machine_at_s370slm_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440lx_device); device_add(&piix4e_device); - device_add(&w83977tf_device); - device_add(&kbc_ps2_ami_pci_device); + device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); device_add(&w83781d_device); /* fans: CPU, Fan 2, Chassis; temperatures: unused, CPU, unused */ @@ -98,8 +97,7 @@ machine_at_prosignias31x_bx_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); - device_add(&w83977ef_device); - device_add(&kbc_ps2_ami_pci_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); device_add(&winbond_flash_w29c020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); device_add(&gl520sm_2d_device); /* fans: CPU, Chassis; temperature: System */ @@ -139,8 +137,7 @@ machine_at_s1857_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); - device_add(&kbc_ps2_ami_pci_device); - device_add(&w83977ef_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -176,8 +173,7 @@ machine_at_p6bap_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&via_apro133a_device); /* Rebranded as ET82C693A */ device_add(&via_vt82c596b_device); /* Rebranded as ET82C696B */ - device_add(&w83977ef_device); - device_add(&kbc_ps2_ami_pci_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -211,8 +207,7 @@ machine_at_p6bat_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&via_apro133_device); device_add(&via_vt82c596b_device); - device_add(&w83977ef_device); - device_add(&kbc_ps2_ami_pci_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -248,8 +243,7 @@ machine_at_cubx_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); - device_add(&kbc_ps2_ami_pci_device); - device_add(&w83977ef_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); device_add(&ide_cmd648_ter_qua_onboard_device); device_add(ics9xxx_get(ICS9250_08)); device_add(&sst_flash_39sf020_device); @@ -283,8 +277,7 @@ machine_at_atc7020bxii_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&slc90e66_device); - device_add(&kbc_ps2_pci_device); - device_add(&w83977ef_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); @@ -355,8 +348,7 @@ machine_at_ambx133_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); - device_add(&w83977ef_device); - device_add(&kbc_ps2_ami_pci_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); device_add(&gl518sm_2d_device); /* fans: CPUFAN1, CPUFAN2; temperature: CPU */ @@ -391,9 +383,8 @@ machine_at_awo671r_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); - device_add_inst(&w83977ef_device, 1); - device_add_inst(&w83977ef_device, 2); - device_add(&kbc_ps2_pci_device); + device_add_inst_params(&w83977_device, 1, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); + device_add_inst_params(&w83977_device, 2, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); device_add(&sst_flash_39sf020_device); if (gfxcard[0] == VID_INTERNAL) device_add(machine_get_vid_device(machine)); @@ -426,8 +417,7 @@ machine_at_63a1_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440zx_device); device_add(&piix4e_device); - device_add(&w83977tf_device); - device_add(&kbc_ps2_ami_pci_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 256); @@ -457,7 +447,7 @@ machine_at_apas3_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&via_apro_device); device_add(&via_vt82c586b_device); - device_add(&fdc37c669_device); + device_add_params(&fdc37c669_device, (void *) 0); device_add(&kbc_ps2_ami_pci_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index 402489d89..6fd66bae6 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -130,7 +130,7 @@ machine_at_premiere_common_init(const machine_t *model, int pci_switch) device_add(&kbc_ps2_phoenix_device); device_add(&sio_zb_device); device_add(&ide_rz1000_pci_single_channel_device); - device_add(&fdc37c665_ide_sec_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_SEC)); device_add(&intel_flash_bxt_ami_device); } @@ -153,7 +153,7 @@ machine_at_sp4_common_init(const machine_t *model) device_add(&sis_85c50x_device); device_add(&ide_cmd640_pci_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&intel_flash_bxt_device); } @@ -177,7 +177,7 @@ machine_at_excaliburpci_init(const machine_t *model) pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&kbc_ps2_ami_pci_device); device_add(&ide_cmd640_pci_legacy_only_device); @@ -245,7 +245,7 @@ machine_at_dellxp60_init(const machine_t *model) device_add(&i430lx_device); device_add(&kbc_ps2_phoenix_device); device_add(&sio_zb_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&intel_flash_bxt_ami_device); return ret; @@ -276,7 +276,7 @@ machine_at_opti560l_init(const machine_t *model) device_add(&i430lx_device); device_add(&kbc_ps2_phoenix_device); device_add(&sio_zb_device); - device_add(&i82091aa_device); + device_add_params(&i82091aa_device, (void *) I82091AA_022); device_add(&intel_flash_bxt_ami_device); return ret; @@ -308,7 +308,7 @@ machine_at_ambradp60_init(const machine_t *model) pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&kbc_ps2_phoenix_device); device_add(&sio_zb_device); - device_add(&fdc37c665_ide_pri_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_PRI)); device_add(&intel_flash_bxt_ami_device); device_add(&i430lx_device); @@ -341,7 +341,7 @@ machine_at_valuepointp60_init(const machine_t *model) pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&kbc_ps2_ps1_pci_device); device_add(&sio_device); - device_add(&fdc37c665_ide_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_PRI)); device_add(&intel_flash_bxt_ami_device); device_add(&i430lx_device); @@ -441,7 +441,7 @@ machine_at_pb520r_init(const machine_t *model) device_add(&kbc_ps2_pci_device); device_add(&sio_zb_device); - device_add(&i82091aa_ide_device); + device_add_params(&i82091aa_device, (void *) (I82091AA_022 | I82091AA_IDE_PRI)); device_add(&intel_flash_bxt_ami_device); return ret; @@ -471,7 +471,7 @@ machine_at_m5pi_init(const machine_t *model) device_add(&sio_zb_device); device_add(&kbc_ps2_phoenix_device); device_add(&ide_w83769f_pci_single_channel_device); - device_add(&fdc37c665_ide_sec_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_SEC)); device_add(&intel_flash_bxt_ami_device); return ret; @@ -523,7 +523,7 @@ machine_at_excalibur_init(const machine_t *model) device_add(&opti5x7_device); device_add(&ide_opti611_vlb_device); - device_add(&fdc37c661_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C661); device_add(&kbc_ps2_intel_ami_pci_device); return ret; @@ -583,7 +583,7 @@ machine_at_excaliburpci2_init(const machine_t *model) pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&kbc_ps2_ami_pci_device); device_add(&ide_cmd640_pci_legacy_only_device); diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 0088bc188..01812ffe7 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -109,7 +109,7 @@ machine_at_d842_init(const machine_t *model) device_add(&kbc_ps2_pci_device); device_add(&i430nx_device); device_add(&sio_zb_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&intel_flash_bxt_device); return ret; @@ -202,7 +202,7 @@ machine_at_p54np4_init(const machine_t *model) device_add(&i430nx_device); device_add(&sio_zb_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&fdc37c665_ide_pri_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_PRI)); device_add(&intel_flash_bxt_device); return ret; @@ -250,7 +250,7 @@ machine_at_tek932_init(const machine_t *model) device_add(&i430nx_device); device_add(&sio_zb_device); device_add(&ide_vlb_device); - device_add(&fdc37c665_ide_pri_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_PRI)); device_add(&intel_flash_bxt_ami_device); return ret; @@ -279,7 +279,7 @@ machine_at_acerv30_init(const machine_t *model) device_add(&i430fx_device); device_add(&piix_device); device_add(&kbc_ps2_acer_pci_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&sst_flash_29ee010_device); @@ -310,7 +310,7 @@ machine_at_apollo_init(const machine_t *model) device_add(&kbc_ps2_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); - device_add(&pc87332_398_device); + device_add_params(&pc873xx_device, (void *) (PC87332 | PCX730X_398)); device_add(&intel_flash_bxt_device); return ret; @@ -346,7 +346,7 @@ machine_at_optiplexgxl_init(const machine_t *model) device_add(&kbc_ps2_phoenix_pci_device); device_add(&i430fx_device); device_add(&piix_device); - device_add(&pc87332_device); + device_add_params(&pc873xx_device, (void *) (PC87332 | PCX730X_02E)); device_add(&dell_jumper_device); device_add(&intel_flash_bxt_device); @@ -437,7 +437,7 @@ machine_at_powermatev_init(const machine_t *model) device_add(&kbc_ps2_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&intel_flash_bxt_device); return ret; @@ -466,7 +466,7 @@ machine_at_hawk_init(const machine_t *model) device_add(&kbc_ps2_tg_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&intel_flash_bxt_device); return ret; @@ -497,7 +497,7 @@ machine_at_pt2000_init(const machine_t *model) device_add(&kbc_ps2_holtek_device); device_add(&i430fx_device); device_add(&piix_device); - device_add(&pc87332_398_device); + device_add_params(&pc873xx_device, (void *) (PC87332 | PCX730X_398)); device_add(&intel_flash_bxt_device); return ret; @@ -579,7 +579,7 @@ machine_at_ncselp90_init(const machine_t *model) device_add(&sst_flash_29ee010_device); device_add(&kbc_ps2_ami_pci_device); device_add(&ide_opti611_vlb_device); - device_add(&fdc37c665_ide_sec_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_SEC)); device_add(&ide_vlb_2ch_device); return ret; @@ -626,7 +626,7 @@ machine_at_sq588_init(const machine_t *model) device_add(&sis_85c50x_device); device_add(&ide_cmd640_pci_single_channel_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&fdc37c665_ide_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C665 | FDC37C6XX_IDE_SEC)); device_add(&sst_flash_29ee010_device); return ret; @@ -655,7 +655,7 @@ machine_at_p54sps_init(const machine_t *model) device_add(&sis_85c50x_device); device_add(&ide_pci_2ch_device); device_add(&kbc_at_ami_device); - device_add(&w83787f_device); + device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_89)); device_add(&sst_flash_29ee010_device); return ret; @@ -686,7 +686,7 @@ machine_at_ms5109_init(const machine_t *model) device_add(&sis_550x_85c503_device); device_add(&ide_w83769f_pci_device); device_add(&kbc_ps2_ami_device); - device_add(&w83787f_device); + device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_89)); device_add(&sst_flash_29ee010_device); return ret; @@ -720,7 +720,7 @@ machine_at_torino_init(const machine_t *model) device_add(&sis_550x_85c503_device); device_add(&ide_um8673f_device); device_add(&kbc_ps2_tg_ami_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&intel_flash_bxt_ami_device); return ret; @@ -752,7 +752,7 @@ machine_at_hot539_init(const machine_t *model) device_add(&umc_8886af_device); device_add(&sst_flash_29ee010_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&um8663af_device); + device_add_params(&um866x_device, (void *) UM8663AF); return ret; } diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index d5fdc7e0f..18ef41711 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -112,7 +112,7 @@ machine_at_ap5vm_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&ncr53c810_onboard_pci_device); device_add(&intel_flash_bxt_device); @@ -142,7 +142,7 @@ machine_at_p55t2p4_init(const machine_t *model) device_add(&i430hx_device); device_add(&piix3_device); device_add(&kbc_ps2_pci_device); - device_add(&w83877f_device); + device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0)); device_add(&intel_flash_bxt_device); return ret; @@ -384,6 +384,34 @@ machine_at_equium5200_init(const machine_t *model) return ret; } +int +machine_at_p55t2s_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/p55t2s/s6y08t.rom", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&i430hx_device); + device_add(&piix3_device); + device_add_params(&pc87306_device, (void *) PCX730X_AMI); + device_add(&intel_flash_bxt_device); + + return ret; +} + int machine_at_pcv90_init(const machine_t *model) { @@ -458,7 +486,7 @@ machine_at_epc2102_init(const machine_t *model) device_add(&i430hx_device); device_add(&piix3_device); device_add(&kbc_ps2_intel_ami_pci_device); - device_add(&i82091aa_device); + device_add_params(&i82091aa_device, (void *) I82091AA_022); device_add(&sst_flash_39sf010_device); return ret; @@ -487,7 +515,7 @@ machine_at_p55tvp4_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); device_add(&kbc_ps2_ami_pci_device); // It uses the AMIKEY KBC - device_add(&w83877f_device); + device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0)); device_add(&intel_flash_bxt_device); return ret; @@ -514,8 +542,8 @@ machine_at_5ivg_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&kbc_ps2_pci_device); - device_add(&prime3c_device); + device_add(&kbc_ps2_ami_pci_device); + device_add_params(&gm82c803c_device, (void *) 0); device_add(&intel_flash_bxt_device); return ret; @@ -544,7 +572,7 @@ machine_at_8500tvxa_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&um8669f_device); + device_add_params(&um8669f_device, (void *) 0); device_add(&sst_flash_29ee010_device); return ret; @@ -643,6 +671,35 @@ machine_at_dellhannibalp_init(const machine_t *model) return ret; } +int +machine_at_p5vxb_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/p5vxb/P5VXB10.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x05, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x06, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x08, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); + device_add(&i430vx_device); + device_add(&piix3_device); + device_add(&kbc_ps2_ami_pci_device); + device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0)); + device_add(&sst_flash_29ee010_device); + + return ret; +} + int machine_at_p55va_init(const machine_t *model) { @@ -790,7 +847,7 @@ machine_at_mb520n_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&fdc37c669_device); + device_add_params(&fdc37c669_device, (void *) 0); device_add(&intel_flash_bxt_device); return ret; @@ -819,7 +876,7 @@ machine_at_i430vx_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); device_add(&kbc_ps2_pci_device); - device_add(&um8669f_device); + device_add_params(&um8669f_device, (void *) 0); device_add(&intel_flash_bxt_device); return ret; @@ -920,8 +977,7 @@ machine_at_nupro592_init(const machine_t *model) device_add(&i430tx_device); device_add(&piix4_device); - device_add(&kbc_ps2_ami_pci_device); - device_add(&w83977ef_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); device_add(&w83781d_device); /* fans: CPU1, unused, unused; temperatures: System, CPU1, unused */ @@ -958,7 +1014,7 @@ machine_at_tx97_init(const machine_t *model) device_add(&i430tx_device); device_add(&piix4_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&w83877tf_acorp_device); + device_add_params(&w83877_device, (void *) (W83877TF | W83877_3F0)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); device_add(&w83781d_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */ @@ -1073,8 +1129,7 @@ machine_at_ym430tx_init(const machine_t *model) pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&i430tx_device); device_add(&piix4_device); - device_add(&kbc_ps2_pci_device); - device_add(&w83977tf_device); + device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); @@ -1104,7 +1159,7 @@ machine_at_mb540n_init(const machine_t *model) device_add(&i430tx_device); device_add(&piix4_device); device_add(&kbc_ps2_pci_device); - device_add(&um8669f_device); + device_add_params(&um8669f_device, (void *) 0); device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); @@ -1135,7 +1190,7 @@ machine_at_56a5_init(const machine_t *model) device_add(&i430tx_device); device_add(&piix4_device); device_add(&kbc_ps2_pci_device); - device_add(&w83877f_device); + device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0)); device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); @@ -1164,8 +1219,8 @@ machine_at_p5mms98_init(const machine_t *model) pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i430tx_device); device_add(&piix4_device); - device_add(&kbc_ps2_ami_pci_device); - device_add(&w83977tf_device); + /* This actually has the Winbond W83967AF, for which I can not find any datasheet at all. */ + device_add_params(&w83977_device, (void *) (W83977F | W83977_AMI | W83977_NO_NVR)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); device_add(&lm78_device); /* fans: Thermal, CPU, Chassis; temperature: unused */ @@ -1270,7 +1325,7 @@ machine_at_ficva502_init(const machine_t *model) device_add(&via_vpx_device); device_add(&via_vt82c586b_device); device_add(&kbc_ps2_pci_device); - device_add(&fdc37c669_370_device); + device_add_params(&fdc37c669_device, (void *) FDC37C6XX_370); device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0x3, 256); @@ -1302,7 +1357,7 @@ machine_at_ficpa2012_init(const machine_t *model) device_add(&via_vp3_device); device_add(&via_vt82c586b_device); device_add(&kbc_ps2_pci_device); - device_add(&w83877f_device); + device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0)); device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0x7, 512); @@ -1334,7 +1389,7 @@ machine_at_via809ds_init(const machine_t *model) device_add(&via_vp3_device); device_add(&via_vt82c586b_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&fdc37c669_device); + device_add_params(&fdc37c669_device, (void *) 0); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x7, 512); @@ -1364,7 +1419,7 @@ machine_at_r534f_init(const machine_t *model) device_add(&sis_5571_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&w83877f_device); + device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0)); device_add(&sst_flash_29ee010_device); return ret; @@ -1393,7 +1448,7 @@ machine_at_ms5146_init(const machine_t *model) device_add(&sis_5571_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&w83877f_device); + device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0)); device_add(&sst_flash_29ee010_device); return ret; @@ -1422,7 +1477,7 @@ machine_at_cb52xsi_init(const machine_t *model) device_add(&sis_5571_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&fdc37c669_370_device); + device_add_params(&fdc37c669_device, (void *) FDC37C6XX_370); device_add(&sst_flash_29ee010_device); return ret; @@ -1451,7 +1506,7 @@ machine_at_sp97xv_init(const machine_t *model) pci_register_slot(0x13, PCI_CARD_VIDEO, 1, 2, 3, 4); /* On-chip SiS graphics, absent here. */ device_add(&sis_5581_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&w83877f_device); + device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0)); device_add(&sst_flash_29ee010_device); return ret; @@ -1478,7 +1533,7 @@ machine_at_sq578_init(const machine_t *model) pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&sis_5581_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&w83877tf_device); + device_add_params(&w83877_device, (void *) (W83877TF | W83877_3F0)); device_add(&sst_flash_29ee010_device); return ret; @@ -1506,7 +1561,7 @@ machine_at_ms5172_init(const machine_t *model) pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&sis_5591_1997_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&w83877tf_device); + device_add_params(&w83877_device, (void *) (W83877TF | W83877_3F0)); device_add(&sst_flash_29ee010_device); return ret; diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index 706608748..d9933cc08 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -127,7 +127,7 @@ machine_at_p54tp4xe_common_init(const machine_t *model) device_add(&kbc_ps2_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&intel_flash_bxt_device); } @@ -186,7 +186,7 @@ machine_at_exp8551_init(const machine_t *model) device_add(&kbc_ps2_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); - device_add(&w83787f_device); + device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_89)); device_add(&sst_flash_29ee010_device); return ret; @@ -389,7 +389,7 @@ machine_at_ms5119_init(const machine_t *model) device_add(&i430fx_device); device_add(&piix_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&w83787f_device); + device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_89)); device_add(&sst_flash_29ee010_device); return ret; @@ -484,7 +484,7 @@ machine_at_mb500n_init(const machine_t *model) device_add(&kbc_ps2_pci_device); device_add(&i430fx_device); device_add(&piix_no_mirq_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&intel_flash_bxt_device); return ret; @@ -514,7 +514,7 @@ machine_at_fmb_init(const machine_t *model) device_add(&i430fx_device); device_add(&piix_no_mirq_device); device_add(&kbc_at_ami_device); - device_add(&w83787f_device); + device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_89)); device_add(&intel_flash_bxt_device); return ret; @@ -574,7 +574,7 @@ machine_at_ap53_init(const machine_t *model) device_add(&i430hx_device); device_add(&piix3_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&fdc37c669_device); + device_add_params(&fdc37c669_device, (void *) 0); device_add(&intel_flash_bxt_device); return ret; @@ -603,54 +603,12 @@ machine_at_8500tuc_init(const machine_t *model) device_add(&i430hx_device); device_add(&piix3_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&um8669f_device); + device_add_params(&um8669f_device, (void *) 0); device_add(&intel_flash_bxt_device); return ret; } -int -machine_at_d943_init(const machine_t *model) - -{ - int ret = 0; - const char* fn; - - /* No ROMs available */ - if (!device_available(model->device)) - return ret; - - device_context(model->device); - fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); - ret = bios_load_linear(fn, 0x000e0000, 131072, 0); - device_context_restore(); - - machine_at_common_init_ex(model, 2); - device_add(&amstrad_megapc_nvr_device); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); - pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 2, 4, 1); - pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 1, 3, 4); - pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 3, 2, 4); - device_add(&i430hx_device); - device_add(&piix3_device); - device_add(&kbc_ps2_pci_device); - device_add(&fdc37c665_device); - device_add(&intel_flash_bxt_device); - spd_register(SPD_TYPE_EDO, 0x7, 256); - - if (gfxcard[0] == VID_INTERNAL) - device_add(machine_get_vid_device(machine)); - - if (sound_card_current[0] == SOUND_INTERNAL) - machine_snd = device_add(machine_get_snd_device(machine)); - - return ret; -} - static const device_config_t d943_config[] = { // clang-format off { @@ -677,8 +635,6 @@ static const device_config_t d943_config[] = { // clang-format on }; - - const device_t d943_device = { .name = "Siemens-Nixdorf D943", .internal_name = "d943_device", @@ -694,58 +650,43 @@ const device_t d943_device = { }; int -machine_at_p55t2s_init(const machine_t *model) +machine_at_d943_init(const machine_t *model) + { - int ret; + int ret = 0; + const char* fn; - ret = bios_load_linear("roms/machines/p55t2s/s6y08t.rom", - 0x000e0000, 131072, 0); - - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + machine_at_common_init_ex(model, 2); + device_add(&amstrad_megapc_nvr_device); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 2, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 3, 2, 4); device_add(&i430hx_device); device_add(&piix3_device); - device_add_params(&pc87306_device, (void *) PCX730X_AMI); + device_add(&kbc_ps2_pci_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_EDO, 0x7, 256); - return ret; -} + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); -int -machine_at_p5vxb_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/p5vxb/P5VXB10.BIN", - 0x000e0000, 131072, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x05, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x06, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x08, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); - device_add(&i430vx_device); - device_add(&piix3_device); - device_add(&kbc_ps2_ami_pci_device); - device_add(&w83877f_device); - device_add(&sst_flash_29ee010_device); + if (sound_card_current[0] == SOUND_INTERNAL) + machine_snd = device_add(machine_get_snd_device(machine)); return ret; } @@ -851,7 +792,7 @@ machine_at_ap5s_init(const machine_t *model) device_add(&sis_5511_device); device_add(&kbc_ps2_ami_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&sst_flash_29ee010_device); return ret; @@ -880,7 +821,7 @@ machine_at_ms5124_init(const machine_t *model) device_add(&sis_5511_device); device_add(&kbc_ps2_ami_device); - device_add(&w83787f_88h_device); + device_add_params(&w837x7_device, (void *) (W83787F | W837X7_KEY_88)); device_add(&sst_flash_29ee010_device); return ret; @@ -909,7 +850,7 @@ machine_at_amis727_init(const machine_t *model) device_add(&sis_5511_device); device_add(&kbc_ps2_intel_ami_pci_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&intel_flash_bxt_device); return ret; @@ -1014,7 +955,7 @@ machine_at_5sbm2_init(const machine_t *model) device_add(&kbc_at_ami_device); device_add(&sis_550x_device); - device_add(&um8663af_device); + device_add_params(&um866x_device, (void *) UM8663AF); device_add(&sst_flash_29ee010_device); return ret; @@ -1045,7 +986,7 @@ machine_at_pc140_6260_init(const machine_t *model) device_add(&sis_5511_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&fdc37c669_device); + device_add_params(&fdc37c669_device, (void *) 0); device_add(&sst_flash_29ee010_device); return ret; diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index e06356c2c..d9d35b161 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -66,7 +66,7 @@ machine_at_ap61_init(const machine_t *model) device_add(&sio_zb_device); device_add(&ide_cmd646_device); device_add(&kbc_ps2_acer_pci_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&sst_flash_29ee010_device); // device_add(&intel_flash_bxt_device); @@ -101,7 +101,7 @@ machine_at_p6rp4_init(const machine_t *model) device_add(&ide_cmd646_device); /* Input port bit 2 must be 1 or CMOS Setup is disabled. */ device_add(&kbc_ps2_ami_pci_device); - device_add(&fdc37c665_device); + device_add_params(&fdc37c6xx_device, (void *) FDC37C665); device_add(&intel_flash_bxt_device); return ret; @@ -130,7 +130,7 @@ machine_at_686nx_init(const machine_t *model) device_add(&i440fx_device); device_add(&piix3_device); device_add(&kbc_ps2_ami_pci_device); // Uses the AMIKEY keyboard controller - device_add(&um8669f_device); + device_add_params(&um8669f_device, (void *) 0); device_add(&intel_flash_bxt_device); return ret; @@ -159,7 +159,7 @@ machine_at_mb600n_init(const machine_t *model) device_add(&i440fx_device); device_add(&piix3_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&fdc37c669_device); + device_add_params(&fdc37c669_device, (void *) 0); device_add(&intel_flash_bxt_device); return ret; @@ -218,7 +218,7 @@ machine_at_lgibmx61_init(const machine_t *model) device_add(&i440fx_device); device_add(&piix3_device); device_add(&kbc_ps2_ami_device); - device_add(&w83877f_president_device); + device_add_params(&w83877_device, (void *) (W83877F | W83877_250)); device_add(&sst_flash_29ee010_device); return ret; @@ -393,7 +393,7 @@ machine_at_8600ttc_init(const machine_t *model) device_add(&i440fx_device); device_add(&piix3_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&fdc37c669_device); + device_add_params(&fdc37c669_device, (void *) 0); device_add(&intel_flash_bxt_device); return ret; @@ -443,7 +443,7 @@ machine_at_p65up5_common_init(const machine_t *model, const device_t *northbridg device_add(northbridge); device_add(&piix3_ioapic_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&w83877f_device); + device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0)); device_add(&sst_flash_29ee010_device); device_add(&ioapic_device); } diff --git a/src/machine/m_at_sockets7.c b/src/machine/m_at_sockets7.c index 6a867f8f0..28d3033fb 100644 --- a/src/machine/m_at_sockets7.c +++ b/src/machine/m_at_sockets7.c @@ -232,7 +232,7 @@ machine_at_ax59pro_init(const machine_t *model) device_add(&via_mvp3_device); device_add(&via_vt82c586b_device); device_add(&kbc_ps2_pci_device); - device_add(&w83877tf_device); + device_add_params(&w83877_device, (void *) (W83877TF | W83877_250)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -263,7 +263,7 @@ machine_at_mvp3_init(const machine_t *model) device_add(&via_mvp3_device); device_add(&via_vt82c586b_device); device_add(&kbc_ps2_pci_device); - device_add(&w83877tf_acorp_device); + device_add_params(&w83877_device, (void *) (W83877TF | W83877_3F0)); device_add(&sst_flash_39sf010_device); spd_register(SPD_TYPE_SDRAM, 0x3, 256); @@ -365,7 +365,7 @@ machine_at_delhi3_init(const machine_t *model) device_add(&via_mvp3_device); device_add(&via_vt82c596a_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&w83877tf_device); + device_add_params(&w83877_device, (void *) (W83877TF | W83877_250)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x3, 256); @@ -398,7 +398,7 @@ machine_at_5sg100_init(const machine_t *model) pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); device_add(&sis_5591_1997_device); device_add(&kbc_ps2_ami_pci_device); - device_add(&w83877tf_device); + device_add_params(&w83877_device, (void *) (W83877TF | W83877_3F0)); device_add(&sst_flash_29ee010_device); return ret; diff --git a/src/machine/m_ps2_isa.c b/src/machine/m_ps2_isa.c index d7fd2d753..b8114622b 100644 --- a/src/machine/m_ps2_isa.c +++ b/src/machine/m_ps2_isa.c @@ -168,6 +168,7 @@ ps2_isa_setup(int model, int cpu_type) ps2->uart = device_add_inst(&ns16450_device, 1); ps2->lpt = device_add_inst(&lpt_port_device, 1); + lpt_set_ext(ps2->lpt, 1); lpt_port_remove(ps2->lpt); lpt_port_setup(ps2->lpt, LPT_MDA_ADDR); diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index cdb833fd6..42fe64cf8 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -1601,7 +1601,9 @@ machine_ps2_common_init(const machine_t *model) nmi_mask = 0x80; ps2.uart = device_add_inst(&ns16550_device, 1); + ps2.lpt = device_add_inst(&lpt_port_device, 1); + lpt_set_ext(ps2.lpt, 1); ps2.has_e0000_hole = 0; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 110787c04..cf39c7d54 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -81,6 +81,7 @@ const machine_filter_t machine_types[] = { { "[1978] 8086", MACHINE_TYPE_8086 }, { "[1982] 80286", MACHINE_TYPE_286 }, { "[1988] i386SX", MACHINE_TYPE_386SX }, + { "[1988] ALi M6117", MACHINE_TYPE_M6117 }, { "[1992] 486SLC", MACHINE_TYPE_486SLC }, { "[1985] i386DX", MACHINE_TYPE_386DX }, { "[1989] i386DX/i486", MACHINE_TYPE_386DX_486 }, @@ -4158,6 +4159,47 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has IBM AT KBC firmware. */ + { + .name = "[SCAT] Samsung Deskmaster 286", + .internal_name = "deskmaster286", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_SCAT, + .init = machine_at_deskmaster286_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_286, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE, /* Has internal video: C&T VGA 411 */ + .ram = { + .min = 512, + .max = 8192, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has IBM PS/2 Type 1 KBC firmware. */ { .name = "[SCAT] Samsung SPC-4200P", @@ -4281,47 +4323,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has IBM AT KBC firmware. */ - { - .name = "[SCAT] Samsung Deskmaster 286", - .internal_name = "deskmaster286", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_SCAT, - .init = machine_at_deskmaster286_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_286, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE, /* Has internal video: C&T VGA 411 */ - .ram = { - .min = 512, - .max = 8192, - .step = 128 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, { .name = "[SCAT] Senor Science Co. SCAT-286-003", .internal_name = "senorscat286", @@ -4817,7 +4818,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - { + { .name = "[ALi M1409] Acer 100T", .internal_name = "acer100t", .type = MACHINE_TYPE_386SX, @@ -4858,88 +4859,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[ALi M6117] Acrosser PJ-A511M", - .internal_name = "pja511m", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_ALI_M6117, - .init = machine_at_pja511m_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_M6117, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[ALi M6117] Protech ProX-1332", - .internal_name = "prox1332", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_ALI_M6117, - .init = machine_at_prox1332_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_M6117, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, /* Has an AMI KBC firmware, the only photo of this is too low resolution for me to read what's on the KBC chip, so I'm going to assume AMI 'F' based on the other known HT18 AMI BIOS strings. */ @@ -5566,6 +5485,90 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + + /* ALi M6117 machines */ + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[ALi M6117] Acrosser PJ-A511M", + .internal_name = "pja511m", + .type = MACHINE_TYPE_M6117, + .chipset = MACHINE_CHIPSET_ALI_M6117, + .init = machine_at_pja511m_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_M6117, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[ALi M6117] Protech ProX-1332", + .internal_name = "prox1332", + .type = MACHINE_TYPE_M6117, + .chipset = MACHINE_CHIPSET_ALI_M6117, + .init = machine_at_prox1332_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_M6117, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* 486SLC machines */ /* 486SLC machines with just the ISA slot */ @@ -16496,10 +16499,9 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ - -{ + { .name = "[i440BX] ABIT BX6", .internal_name = "bx6", .type = MACHINE_TYPE_SLOT1, @@ -16539,7 +16541,8 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { .name = "[i440BX] ABIT BF6", .internal_name = "bf6", diff --git a/src/sio/CMakeLists.txt b/src/sio/CMakeLists.txt index dd4106fbd..c6e90d320 100644 --- a/src/sio/CMakeLists.txt +++ b/src/sio/CMakeLists.txt @@ -16,29 +16,28 @@ # add_library(sio OBJECT + sio_82091aa.c sio_acc3221.c sio_ali5123.c + sio_gm82c803ab.c + sio_gm82c803c.c sio_f82c606.c sio_f82c710.c - sio_82091aa.c sio_fdc37c6xx.c sio_fdc37c67x.c sio_fdc37c669.c sio_fdc37c93x.c sio_fdc37m60x.c sio_it86x1f.c + sio_pc87310.c + sio_pc873xx.c sio_pc87306.c sio_pc87307.c sio_pc87309.c - sio_pc87310.c - sio_pc87311.c - sio_pc87332.c - sio_prime3b.c - sio_prime3c.c - sio_w83787f.c - sio_w83877f.c - sio_w83977f.c - sio_um8663f.c + sio_w837x7.c + sio_w83877.c + sio_w83977.c + sio_um866x.c sio_um8669f.c sio_vl82c113.c sio_vt82c686.c diff --git a/src/sio/sio_82091aa.c b/src/sio/sio_82091aa.c index 5ef60d20f..283febada 100644 --- a/src/sio/sio_82091aa.c +++ b/src/sio/sio_82091aa.c @@ -57,9 +57,34 @@ static void lpt_handler(i82091aa_t *dev) { uint16_t lpt_port = LPT1_ADDR; + int enable = (dev->regs[0x20] & 0x01); lpt_port_remove(dev->lpt); + lpt_set_fifo_threshold(dev->lpt, (dev->regs[0x20] & 0x80) ? 15 : 8); + + switch (dev->regs[0x20] & 0x60) { + default: + case 0x00: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + case 0x20: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 1); + break; + case 0x40: + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + case 0x60: + enable = 0; + break; + } + switch ((dev->regs[0x20] >> 1) & 0x03) { case 0x00: lpt_port = LPT1_ADDR; @@ -78,7 +103,7 @@ lpt_handler(i82091aa_t *dev) break; } - if ((dev->regs[0x20] & 0x01) && lpt_port) + if (enable && lpt_port) lpt_port_setup(dev->lpt, lpt_port); lpt_port_irq(dev->lpt, (dev->regs[0x20] & 0x08) ? LPT1_IRQ : LPT2_IRQ); @@ -176,7 +201,7 @@ i82091aa_write(uint16_t port, uint8_t val, void *priv) break; case 0x20: *reg = (val & 0xef); - if (valxor & 0x07) + if (valxor & 0xe8) lpt_handler(dev); break; case 0x21: @@ -218,6 +243,8 @@ i82091aa_read(uint16_t port, void *priv) if (index) ret = dev->cur_reg; + else if (dev->cur_reg == 0x20) + ret = dev->regs[dev->cur_reg] | lpt_read_ecp_mode(dev->lpt); else if (dev->cur_reg < 0x51) ret = dev->regs[dev->cur_reg]; @@ -266,6 +293,7 @@ i82091aa_init(const device_t *info) dev->uart[1] = device_add_inst(&ns16550_device, 2); dev->lpt = device_add_inst(&lpt_port_device, 1); + lpt_set_cnfga_readout(dev->lpt, 0x90); dev->has_ide = (info->local >> 9) & 0x03; @@ -288,63 +316,7 @@ const device_t i82091aa_device = { .name = "Intel 82091AA Super I/O", .internal_name = "i82091aa", .flags = 0, - .local = 0x40, - .init = i82091aa_init, - .close = i82091aa_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t i82091aa_26e_device = { - .name = "Intel 82091AA Super I/O (Port 26Eh)", - .internal_name = "i82091aa_26e", - .flags = 0, - .local = 0x140, - .init = i82091aa_init, - .close = i82091aa_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t i82091aa_398_device = { - .name = "Intel 82091AA Super I/O (Port 398h)", - .internal_name = "i82091aa_398", - .flags = 0, - .local = 0x148, - .init = i82091aa_init, - .close = i82091aa_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t i82091aa_ide_pri_device = { - .name = "Intel 82091AA Super I/O (With Primary IDE)", - .internal_name = "i82091aa_ide", - .flags = 0, - .local = 0x240, - .init = i82091aa_init, - .close = i82091aa_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t i82091aa_ide_device = { - .name = "Intel 82091AA Super I/O (With IDE)", - .internal_name = "i82091aa_ide", - .flags = 0, - .local = 0x440, + .local = 0, .init = i82091aa_init, .close = i82091aa_close, .reset = NULL, diff --git a/src/sio/sio_fdc37c669.c b/src/sio/sio_fdc37c669.c index 0f563afa0..d49dd9d30 100644 --- a/src/sio/sio_fdc37c669.c +++ b/src/sio/sio_fdc37c669.c @@ -37,7 +37,10 @@ typedef struct fdc37c669_t { uint8_t id; uint8_t tries; - uint8_t regs[42]; + uint8_t has_ide; + uint8_t dma_map[4]; + uint8_t irq_map[10]; + uint8_t regs[256]; int locked; int rw_locked; int cur_reg; @@ -70,6 +73,7 @@ static void fdc37c669_fdc_handler(fdc37c669_t *dev) { fdc_remove(dev->fdc); + if (dev->regs[0x20] & 0xc0) fdc_set_base(dev->fdc, ((uint16_t) dev->regs[0x20]) << 2); } @@ -82,6 +86,7 @@ fdc37c669_uart_handler(fdc37c669_t *dev, uint8_t uart) uint8_t uart_shift = ((uart ^ 1) << 2); serial_remove(dev->uart[uart]); + if ((dev->regs[0x02] & pwrdn_mask) && (dev->regs[uart_reg] & 0xc0)) serial_setup(dev->uart[0], ((uint16_t) dev->regs[0x24]) << 2, (dev->regs[0x28] >> uart_shift) & 0x0f); @@ -107,10 +112,41 @@ fdc37c669_lpt_handler(fdc37c669_t *dev) uint8_t mask = ~(dev->regs[0x04] & 0x01); lpt_port_remove(dev->lpt); + + if (dev->regs[0x01] & 0x08) { + lpt_set_ext(dev->lpt, 0); + + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + } else { + lpt_set_ext(dev->lpt, 1); + + lpt_set_epp(dev->lpt, dev->regs[0x04] & 0x01); + lpt_set_ecp(dev->lpt, dev->regs[0x04] & 0x02); + } + + lpt_set_fifo_threshold(dev->lpt, dev->regs[0x0a] & 0x0f); + if ((dev->regs[0x01] & 0x04) && (dev->regs[0x23] >= 0x40)) lpt_port_setup(dev->lpt, ((uint16_t) (dev->regs[0x23] & mask)) << 2); } +static void +ide_handler(fdc37c669_t *dev) +{ + if (dev->has_ide > 0) { + int ide_id = dev->has_ide - 1; + + ide_handlers(ide_id, 0); + + ide_set_base_addr(ide_id, 0, ((uint16_t) (dev->regs[0x21] & 0xfc)) << 2); + ide_set_base_addr(ide_id, 1, (((uint16_t) (dev->regs[0x22] & 0xfc)) << 2) | 0x0006); + + if ((dev->regs[0x00] & 0x03) == 0x02) + ide_handlers(ide_id, 1); + } +} + static void fdc37c669_write(uint16_t port, uint8_t val, void *priv) { @@ -139,12 +175,14 @@ fdc37c669_write(uint16_t port, uint8_t val, void *priv) } else if (!dev->rw_locked || (dev->cur_reg > 0x0f)) switch (dev->cur_reg) { case 0x00: dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x74) | (val & 0x8b); - if (!dev->id && (valxor & 8)) + if (!dev->id && (valxor & 0x08)) fdc_set_power_down(dev->fdc, !(val & 0x08)); + if (!dev->id && (valxor & 0x03)) + ide_handler(dev); break; case 0x01: dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x73) | (val & 0x8c); - if (valxor & 0x04) + if (valxor & 0x0c) fdc37c669_lpt_handler(dev); if (valxor & 0x80) dev->rw_locked = !(val & 0x80); @@ -158,6 +196,17 @@ fdc37c669_write(uint16_t port, uint8_t val, void *priv) break; case 0x03: dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x08) | (val & 0xf7); + if ((valxor & 0x60) && (dev->fdc != NULL)) { + fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA); + switch (val & 0x0c) { + case 0x00: + fdc_set_flags(dev->fdc, FDC_FLAG_PS2); + break; + case 0x20: + fdc_set_flags(dev->fdc, FDC_FLAG_PS2_MCA); + break; + } + } if (!dev->id && (valxor & 0x02)) fdc_update_enh_mode(dev->fdc, !!(val & 0x02)); break; @@ -191,6 +240,8 @@ fdc37c669_write(uint16_t port, uint8_t val, void *priv) break; case 0x0a: dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0xf0) | (val & 0x0f); + if (valxor & 0x0f) + fdc37c669_lpt_handler(dev); break; case 0x0b: dev->regs[dev->cur_reg] = val; @@ -223,9 +274,13 @@ fdc37c669_write(uint16_t port, uint8_t val, void *priv) break; case 0x21: dev->regs[dev->cur_reg] = val & 0xfc; + if (!dev->id && (valxor & 0xfc)) + ide_handler(dev); break; case 0x22: dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x03) | (val & 0xfc); + if (!dev->id && (valxor & 0xfc)) + ide_handler(dev); break; case 0x23: dev->regs[dev->cur_reg] = val; @@ -246,6 +301,8 @@ fdc37c669_write(uint16_t port, uint8_t val, void *priv) dev->regs[dev->cur_reg] = val; if (valxor & 0xf0) fdc_set_dma_ch(dev->fdc, val >> 4); + if (valxor & 0x0f) + lpt_port_dma(dev->lpt, val & 0x0f); break; case 0x27: dev->regs[dev->cur_reg] = val; @@ -306,9 +363,13 @@ fdc37c669_reset(void *priv) dev->regs[0x21] = 0x3c; dev->regs[0x22] = 0x3d; - if (dev->id != 1) { + if (!dev->id) { fdc_reset(dev->fdc); + fdc37c669_fdc_handler(dev); + fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA); + + ide_handler(dev); } fdc37c669_uart_handler(dev, 0); @@ -340,17 +401,34 @@ fdc37c669_init(const device_t *info) dev->id = next_id; - if (next_id != 1) - dev->fdc = device_add(&fdc_at_smc_device); + if (next_id != 1) { + dev->fdc = device_add(&fdc_at_smc_device); + dev->has_ide = (info->local >> 8) & 0xff; + } dev->uart[0] = device_add_inst(&ns16550_device, (next_id << 1) + 1); dev->uart[1] = device_add_inst(&ns16550_device, (next_id << 1) + 2); dev->lpt = device_add_inst(&lpt_port_device, next_id + 1); - io_sethandler(info->local ? FDC_SECONDARY_ADDR : (next_id ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR), + io_sethandler((info->local & FDC37C6XX_370) ? FDC_SECONDARY_ADDR : (next_id ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR), 0x0002, fdc37c669_read, NULL, NULL, fdc37c669_write, NULL, NULL, dev); + dev->dma_map[0] = 4; + for (int i = 1; i < 4; i++) + dev->dma_map[i] = i; + + memset(dev->irq_map, 0xff, 16); + dev->irq_map[0] = 0xff; + for (int i = 1; i < 7; i++) + dev->irq_map[i] = i; + dev->irq_map[1] = 5; + dev->irq_map[5] = 7; + dev->irq_map[7] = 0xff; /* Reserved. */ + dev->irq_map[8] = 10; + dev->irq_map[9] = 9; /* This is used by the Acrosser PJ-A511M for IRQ 9. */ + dev->irq_map[11] = 11; /* This is used by the Acrosser PJ-A511M for IRQ 11. */ + fdc37c669_reset(dev); next_id++; @@ -371,17 +449,3 @@ const device_t fdc37c669_device = { .force_redraw = NULL, .config = NULL }; - -const device_t fdc37c669_370_device = { - .name = "SMC FDC37C669 Super I/O (Port 370h)", - .internal_name = "fdc37c669_370", - .flags = 0, - .local = 1, - .init = fdc37c669_init, - .close = fdc37c669_close, - .reset = fdc37c669_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; diff --git a/src/sio/sio_fdc37c67x.c b/src/sio/sio_fdc37c67x.c index c9d0bd149..97e423b17 100644 --- a/src/sio/sio_fdc37c67x.c +++ b/src/sio/sio_fdc37c67x.c @@ -437,7 +437,6 @@ fdc37c67x_write(uint16_t port, uint8_t val, void *priv) fdc_set_flags(dev->fdc, FDC_FLAG_PS2_MCA); break; } - fdc_update_enh_mode(dev->fdc, val & 0x01); } if (valxor & 0x10) fdc_set_swap(dev->fdc, (val & 0x10) >> 4); diff --git a/src/sio/sio_fdc37c6xx.c b/src/sio/sio_fdc37c6xx.c index 3b2a8b942..5d48a73a6 100644 --- a/src/sio/sio_fdc37c6xx.c +++ b/src/sio/sio_fdc37c6xx.c @@ -9,11 +9,9 @@ * Implementation of the SMC FDC37C663 and FDC37C665 Super * I/O Chips. * - * - * * Authors: Miran Grca, * - * Copyright 2016-2020 Miran Grca. + * Copyright 2016-2025 Miran Grca. */ #include #include @@ -113,8 +111,6 @@ lpt_handler(fdc37c6xx_t *dev) uint16_t mask = 0xfffc; uint8_t local_enable = 1; uint8_t lpt_irq = LPT1_IRQ; - /* DMA is guesswork - what channel do boards actually use? */ - uint8_t lpt_dma = 3; uint8_t lpt_ext = !(dev->regs[1] & 0x08); uint8_t lpt_mode = (dev->chip_id >= 0x65) ? (dev->regs[4] & 0x03) : 0x00; @@ -140,9 +136,6 @@ lpt_handler(fdc37c6xx_t *dev) if (lpt_irq > 15) lpt_irq = 0xff; - if (lpt_dma >= 4) - lpt_dma = 0xff; - lpt_port_remove(dev->lpt); lpt_set_fifo_threshold(dev->lpt, dev->regs[0x0a] & 0x0f); if (lpt_ext) switch (lpt_mode) { @@ -192,19 +185,16 @@ fdc_handler(fdc37c6xx_t *dev) static void ide_handler(fdc37c6xx_t *dev) { - /* TODO: Make an ide_disable(channel) and ide_enable(channel) so we can simplify this. */ - if (dev->has_ide == 2) { - ide_sec_disable(); - ide_set_base(1, (dev->regs[0x05] & 0x02) ? 0x170 : 0x1f0); - ide_set_side(1, (dev->regs[0x05] & 0x02) ? 0x376 : 0x3f6); + if (dev->has_ide > 0) { + int ide_id = dev->has_ide - 1; + + ide_handlers(ide_id, 0); + + ide_set_base_addr(ide_id, 0, (dev->regs[0x05] & 0x02) ? 0x0170 : 0x01f0); + ide_set_base_addr(ide_id, 1, (dev->regs[0x05] & 0x02) ? 0x0376 : 0x03f6); + if (dev->regs[0x00] & 0x01) - ide_sec_enable(); - } else if (dev->has_ide == 1) { - ide_pri_disable(); - ide_set_base(0, (dev->regs[0x05] & 0x02) ? 0x170 : 0x1f0); - ide_set_side(0, (dev->regs[0x05] & 0x02) ? 0x376 : 0x3f6); - if (dev->regs[0x00] & 0x01) - ide_pri_enable(); + ide_handlers(ide_id, 1); } } @@ -228,14 +218,14 @@ fdc37c6xx_write(uint16_t port, uint8_t val, void *priv) dev->regs[dev->cur_reg] = val; switch (dev->cur_reg) { - case 0: + case 0x00: if (dev->has_ide && (valxor & 0x01)) ide_handler(dev); if (valxor & 0x10) fdc_handler(dev); break; - case 1: - if (valxor & 3) + case 0x01: + if (valxor & 0x03) lpt_handler(dev); if (valxor & 0x60) { set_com34_addr(dev); @@ -243,23 +233,23 @@ fdc37c6xx_write(uint16_t port, uint8_t val, void *priv) set_serial_addr(dev, 1); } break; - case 2: - if (valxor & 7) + case 0x02: + if (valxor & 0x07) set_serial_addr(dev, 0); if (valxor & 0x70) set_serial_addr(dev, 1); break; - case 3: - if (valxor & 2) - fdc_update_enh_mode(dev->fdc, (dev->regs[3] & 2) ? 1 : 0); + case 0x03: + if (valxor & 0x02) + fdc_update_enh_mode(dev->fdc, !!(dev->regs[0x03] & 0x02)); break; - case 4: + case 0x04: if (valxor & 0x10) set_serial_addr(dev, 0); if (valxor & 0x20) set_serial_addr(dev, 1); break; - case 5: + case 0x05: if (valxor & 0x01) fdc_handler(dev); if (dev->has_ide && (valxor & 0x02)) @@ -285,7 +275,7 @@ fdc37c6xx_read(uint16_t port, void *priv) uint8_t ret = 0xff; if (dev->tries == 2) { - if ((port == 0x3f1) && (dev->cur_reg <= dev->max_reg)) + if ((port == 0x03f1) && (dev->cur_reg <= dev->max_reg)) ret = dev->regs[dev->cur_reg]; } @@ -385,175 +375,23 @@ fdc37c6xx_init(const device_t *info) dev->lpt = device_add_inst(&lpt_port_device, 1); - io_sethandler(FDC_PRIMARY_ADDR, 0x0002, - fdc37c6xx_read, NULL, NULL, fdc37c6xx_write, NULL, NULL, dev); + if (info->local & FDC37C6XX_370) + io_sethandler(FDC_SECONDARY_ADDR, 0x0002, + fdc37c6xx_read, NULL, NULL, fdc37c6xx_write, NULL, NULL, dev); + else + io_sethandler(FDC_PRIMARY_ADDR, 0x0002, + fdc37c6xx_read, NULL, NULL, fdc37c6xx_write, NULL, NULL, dev); fdc37c6xx_reset(dev); return dev; } -/* The three appear to differ only in the chip ID, if I - understood their datasheets correctly. */ -const device_t fdc37c651_device = { - .name = "SMC FDC37C651 Super I/O", - .internal_name = "fdc37c651", +const device_t fdc37c6xx_device = { + .name = "SMC FDC37C6xx Super I/O", + .internal_name = "fdc37c6xx", .flags = 0, - .local = 0x51, - .init = fdc37c6xx_init, - .close = fdc37c6xx_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c651_ide_device = { - .name = "SMC FDC37C651 Super I/O (With IDE)", - .internal_name = "fdc37c651_ide", - .flags = 0, - .local = 0x151, - .init = fdc37c6xx_init, - .close = fdc37c6xx_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c661_device = { - .name = "SMC FDC37C661 Super I/O", - .internal_name = "fdc37c661", - .flags = 0, - .local = 0x61, - .init = fdc37c6xx_init, - .close = fdc37c6xx_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c661_ide_device = { - .name = "SMC FDC37C661 Super I/O (With IDE)", - .internal_name = "fdc37c661_ide", - .flags = 0, - .local = 0x161, - .init = fdc37c6xx_init, - .close = fdc37c6xx_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c661_ide_sec_device = { - .name = "SMC FDC37C661 Super I/O (With Secondary IDE)", - .internal_name = "fdc37c661_ide_sec", - .flags = 0, - .local = 0x261, - .init = fdc37c6xx_init, - .close = fdc37c6xx_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c663_device = { - .name = "SMC FDC37C663 Super I/O", - .internal_name = "fdc37c663", - .flags = 0, - .local = 0x63, - .init = fdc37c6xx_init, - .close = fdc37c6xx_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c663_ide_device = { - .name = "SMC FDC37C663 Super I/O (With IDE)", - .internal_name = "fdc37c663_ide", - .flags = 0, - .local = 0x163, - .init = fdc37c6xx_init, - .close = fdc37c6xx_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c665_device = { - .name = "SMC FDC37C665 Super I/O", - .internal_name = "fdc37c665", - .flags = 0, - .local = 0x65, - .init = fdc37c6xx_init, - .close = fdc37c6xx_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c665_ide_device = { - .name = "SMC FDC37C665 Super I/O (With IDE)", - .internal_name = "fdc37c665_ide", - .flags = 0, - .local = 0x265, - .init = fdc37c6xx_init, - .close = fdc37c6xx_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c665_ide_pri_device = { - .name = "SMC FDC37C665 Super I/O (With Primary IDE)", - .internal_name = "fdc37c665_ide_pri", - .flags = 0, - .local = 0x165, - .init = fdc37c6xx_init, - .close = fdc37c6xx_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c665_ide_sec_device = { - .name = "SMC FDC37C665 Super I/O (With Secondary IDE)", - .internal_name = "fdc37c665_ide_sec", - .flags = 0, - .local = 0x265, - .init = fdc37c6xx_init, - .close = fdc37c6xx_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c666_device = { - .name = "SMC FDC37C666 Super I/O", - .internal_name = "fdc37c666", - .flags = 0, - .local = 0x66, + .local = 0, .init = fdc37c6xx_init, .close = fdc37c6xx_close, .reset = NULL, diff --git a/src/sio/sio_fdc37c93x.c b/src/sio/sio_fdc37c93x.c index 9d0acfae2..85e029fad 100644 --- a/src/sio/sio_fdc37c93x.c +++ b/src/sio/sio_fdc37c93x.c @@ -906,9 +906,11 @@ fdc37c93x_nvr_pri_handler(const fdc37c93x_t *dev) if (dev->chip_id != 0x02) local_enable &= ((dev->ld_regs[6][0xf0] & 0x90) != 0x80); - nvr_at_handler(0, 0x70, dev->nvr); - if (local_enable) - nvr_at_handler(1, 0x70, dev->nvr); + if (dev->has_nvr) { + nvr_at_handler(0, 0x70, dev->nvr); + if (local_enable) + nvr_at_handler(1, 0x70, dev->nvr); + } } static void @@ -926,12 +928,12 @@ fdc37c93x_nvr_sec_handler(fdc37c93x_t *dev) dev->nvr_sec_base = make_port_sec(dev, 6) & 0xfffe; if (dev->nvr_sec_base != old_base) { - if ((old_base > 0x0000) && (old_base <= 0x0ffe)) + if (dev->has_nvr && (old_base > 0x0000) && (old_base <= 0x0ffe)) nvr_at_sec_handler(0, dev->nvr_sec_base, dev->nvr); /* Datasheet erratum: First it says minimum address is 0x0100, but later implies that it's 0x0000 and that default is 0x0070, same as (unrelocatable) primary NVR. */ - if ((dev->nvr_sec_base > 0x0000) && (dev->nvr_sec_base <= 0x0ffe)) + if (dev->has_nvr && (dev->nvr_sec_base > 0x0000) && (dev->nvr_sec_base <= 0x0ffe)) nvr_at_sec_handler(1, dev->nvr_sec_base, dev->nvr); } } @@ -1181,7 +1183,6 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) fdc_set_flags(dev->fdc, FDC_FLAG_PS2_MCA); break; } - fdc_update_enh_mode(dev->fdc, val & 0x01); } if (valxor & 0x10) fdc_set_swap(dev->fdc, (val & 0x10) >> 4); @@ -1365,7 +1366,7 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) else dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x8f; - if (valxor) { + if (dev->has_nvr && valxor) { nvr_lock_set(0x80, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x01), dev->nvr); nvr_lock_set(0xa0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x02), dev->nvr); nvr_lock_set(0xc0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x04), dev->nvr); diff --git a/src/sio/sio_fdc37m60x.c b/src/sio/sio_fdc37m60x.c index 8d18a1192..164db5eac 100644 --- a/src/sio/sio_fdc37m60x.c +++ b/src/sio/sio_fdc37m60x.c @@ -347,7 +347,6 @@ fdc37m60x_write(uint16_t port, uint8_t val, void *priv) fdc_set_flags(dev->fdc, FDC_FLAG_PS2_MCA); break; } - fdc_update_enh_mode(dev->fdc, val & 0x01); } if (valxor & 0x10) fdc_set_swap(dev->fdc, (val & 0x10) >> 4); diff --git a/src/sio/sio_gm82c803ab.c b/src/sio/sio_gm82c803ab.c new file mode 100644 index 000000000..8dca4ae6c --- /dev/null +++ b/src/sio/sio_gm82c803ab.c @@ -0,0 +1,372 @@ +/* + * 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 GoldStar GM82C803 A andB Super I/O + * Chips. + * + * Authors: Miran Grca, + * + * Copyright 2025 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/pci.h> +#include <86box/lpt.h> +#include <86box/serial.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/sio.h> + +typedef struct gm82c803ab_t { + uint8_t type; + uint8_t tries; + uint8_t has_ide; + uint8_t regs[16]; + int cur_reg; + int com3_addr; + int com4_addr; + fdc_t *fdc; + serial_t *uart[2]; + lpt_t *lpt; +} gm82c803ab_t; + +#ifdef ENABLE_GM82C803AB_LOG +int gm82c803ab_do_log = ENABLE_GM82C803AB_LOG; + +static void +gm82c803ab_log(const char *fmt, ...) +{ + va_list ap; + + if (gm82c803ab_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define gm82c803ab_log(fmt, ...) +#endif + +static void +ide_handler(gm82c803ab_t *dev) +{ + if (dev->has_ide > 0) { + int ide_id = dev->has_ide - 1; + + ide_handlers(ide_id, 0); + + ide_set_base_addr(ide_id, 0, (dev->regs[0xa1] & 0x80) ? 0x0170 : 0x01f0); + ide_set_base_addr(ide_id, 1, (dev->regs[0xa1] & 0x80) ? 0x0376 : 0x03f6); + + if (dev->regs[0xa0] & 0x20) + ide_handlers(ide_id, 1); + } +} + +static void +fdc_handler(gm82c803ab_t *dev) +{ + fdc_remove(dev->fdc); + if (dev->regs[0xa0] & 0x10) + fdc_set_base(dev->fdc, (dev->regs[0xa1] & 0x40) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR); +} + +static void +set_com34_addr(gm82c803ab_t *dev) +{ + switch (dev->regs[0xa4] & 0xc0) { + case 0x00: + dev->com3_addr = COM3_ADDR; + dev->com4_addr = COM4_ADDR; + break; + case 0x40: + dev->com3_addr = 0x338; + dev->com4_addr = 0x238; + break; + case 0x80: + dev->com3_addr = COM3_ADDR; + dev->com4_addr = 0x2e0; + break; + case 0xc0: + dev->com3_addr = 0x220; + dev->com4_addr = 0x228; + break; + + default: + break; + } +} + +static void +set_serial_addr(gm82c803ab_t *dev, int port) +{ + uint8_t shift = 2 + (port << 1); + double clock_src = 24000000.0 / 13.0; + + if (dev->regs[0xa4] & (1 << (4 + port))) + clock_src = 24000000.0 / 12.0; + + serial_remove(dev->uart[port]); + if (dev->regs[0xa0] & (0x04 << port)) { + switch ((dev->regs[0xa1] >> shift) & 0x03) { + case 0x00: + serial_setup(dev->uart[port], COM1_ADDR, COM1_IRQ); + break; + case 0x01: + serial_setup(dev->uart[port], COM2_ADDR, COM2_IRQ); + break; + case 0x02: + serial_setup(dev->uart[port], dev->com3_addr, COM3_IRQ); + break; + case 0x03: + serial_setup(dev->uart[port], dev->com4_addr, COM4_IRQ); + break; + + default: + break; + } + } + + serial_set_clock_src(dev->uart[port], clock_src); +} + +static void +lpt_handler(gm82c803ab_t *dev) +{ + uint16_t lpt_port = 0x0000; + uint16_t mask = 0xfffc; + uint8_t local_enable = 1; + uint8_t lpt_irq = LPT1_IRQ; + uint8_t lpt_mode = (dev->regs[0xa0] & 0x03); + + switch (lpt_mode) { + default: + local_enable = 0; + break; + case 0x00: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 1); + break; + case 0x01: + if (dev->type == GM82C803B) { + lpt_set_epp(dev->lpt, !!(dev->regs[0xa5] & 0x20)); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + } else + local_enable = 0; + break; + case 0x02: + if (dev->type == GM82C803B) { + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, !!(dev->regs[0xa5] & 0x20)); + lpt_set_ext(dev->lpt, 0); + } else + local_enable = 0; + break; + } + + switch (dev->regs[0xa1] & 0x03) { + default: + lpt_port = LPT_MDA_ADDR; + lpt_irq = LPT_MDA_IRQ; + break; + case 0x00: + lpt_port = LPT1_ADDR; + lpt_irq = LPT1_IRQ /*LPT2_IRQ*/; + break; + case 0x01: + lpt_port = LPT2_ADDR; + lpt_irq = LPT1_IRQ /*LPT2_IRQ*/; + break; + } + + if (lpt_irq > 15) + lpt_irq = 0xff; + + lpt_port_remove(dev->lpt); + lpt_set_fifo_threshold(dev->lpt, dev->regs[0x0a] & 0x0f); + + if (local_enable && (lpt_port >= 0x0100) && (lpt_port <= (0x0ffc & mask))) + lpt_port_setup(dev->lpt, lpt_port); + + lpt_port_irq(dev->lpt, lpt_irq); +} + +static void +gm82c803ab_write(uint16_t port, uint8_t val, void *priv) +{ + gm82c803ab_t *dev = (gm82c803ab_t *) priv; + uint8_t valxor = 0; + + if (dev->tries == 2) { + if (port == 0x0398) { + if (val == 0xcc) + dev->tries = 0; + else + dev->cur_reg = val; + } else { + if ((dev->cur_reg < 0xa0) || (dev->cur_reg > 0xa5)) + return; + + valxor = val ^ dev->regs[dev->cur_reg]; + dev->regs[dev->cur_reg] = val; + + switch (dev->cur_reg) { + default: + break; + case 0xa0: /* Function Selection Register (FSR) */ + if (valxor & 0x20) + ide_handler(dev); + if (valxor & 0x10) + fdc_handler(dev); + if (valxor & 0x08) + set_serial_addr(dev, 1); + if (valxor & 0x04) + set_serial_addr(dev, 0); + if (valxor & 0x03) + lpt_handler(dev); + break; + case 0xa1: /* Address Selection Register (ASR) */ + if (valxor & 0x80) + ide_handler(dev); + if (valxor & 0x40) + fdc_handler(dev); + if (valxor & 0x30) + set_serial_addr(dev, 1); + if (valxor & 0x0c) + set_serial_addr(dev, 0); + if (valxor & 0x03) + lpt_handler(dev); + break; + case 0xa4: /* Miscellaneous Function Register */ + if (valxor & 0xc0) { + set_com34_addr(dev); + set_serial_addr(dev, 0); + set_serial_addr(dev, 1); + } + if (valxor & 0x20) + set_serial_addr(dev, 1); + if (valxor & 0x10) + set_serial_addr(dev, 0); + if (valxor & 0x01) + fdc_set_swap(dev->fdc, val & 0x01); + break; + case 0xa5: /* ECP Register */ + if (valxor & 0x20) + lpt_handler(dev); + break; + } + } + } else if ((port == 0x0398) && (val == 0x33)) + dev->tries++; +} + +static uint8_t +gm82c803ab_read(uint16_t port, void *priv) +{ + const gm82c803ab_t *dev = (gm82c803ab_t *) priv; + uint8_t ret = 0xff; + + if (dev->tries == 2) { + if ((port == 0x0399) && (dev->cur_reg >= 0xa0) && (dev->cur_reg <= 0xa1)) + ret = dev->regs[dev->cur_reg]; + } + + return ret; +} + +static void +gm82c803ab_reset(gm82c803ab_t *dev) +{ + dev->com3_addr = 0x338; + dev->com4_addr = 0x238; + + serial_remove(dev->uart[0]); + serial_setup(dev->uart[0], COM1_ADDR, COM1_IRQ); + + serial_remove(dev->uart[1]); + serial_setup(dev->uart[1], COM2_ADDR, COM2_IRQ); + + lpt_port_remove(dev->lpt); + lpt_port_setup(dev->lpt, LPT1_ADDR); + + fdc_reset(dev->fdc); + fdc_remove(dev->fdc); + + dev->tries = 0; + memset(dev->regs, 0, 256); + + dev->regs[0xa0] = 0xff; + + set_serial_addr(dev, 0); + set_serial_addr(dev, 1); + + lpt_handler(dev); + + fdc_handler(dev); + + if (dev->has_ide) + ide_handler(dev); +} + +static void +gm82c803ab_close(void *priv) +{ + gm82c803ab_t *dev = (gm82c803ab_t *) priv; + + free(dev); +} + +static void * +gm82c803ab_init(const device_t *info) +{ + gm82c803ab_t *dev = (gm82c803ab_t *) calloc(1, sizeof(gm82c803ab_t)); + + dev->fdc = device_add(&fdc_at_smc_device); + + dev->type = info->local & 0xff; + dev->has_ide = (info->local >> 8) & 0xff; + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + dev->lpt = device_add_inst(&lpt_port_device, 1); + + io_sethandler(0x0398, 0x0002, + gm82c803ab_read, NULL, NULL, gm82c803ab_write, NULL, NULL, dev); + + gm82c803ab_reset(dev); + + return dev; +} + +const device_t gm82c803ab_device = { + .name = "Goldstar GMC82C803A/B", + .internal_name = "gm82c803ab", + .flags = 0, + .local = 0, + .init = gm82c803ab_init, + .close = gm82c803ab_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sio/sio_gm82c803c.c b/src/sio/sio_gm82c803c.c new file mode 100644 index 000000000..eb54b6661 --- /dev/null +++ b/src/sio/sio_gm82c803c.c @@ -0,0 +1,382 @@ +/* + * 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 GoldStar GM82C803C Super I/O Chip. + * + * Authors: Miran Grca, + * + * Copyright 2025 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/pci.h> +#include <86box/lpt.h> +#include <86box/serial.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/sio.h> + +typedef struct gm82c803c_t { + uint8_t tries; + uint8_t has_ide; + uint8_t dma_map[4]; + uint8_t irq_map[10]; + uint8_t regs[16]; + int cur_reg; + fdc_t *fdc; + serial_t *uart[2]; + lpt_t *lpt; +} gm82c803c_t; + +#ifdef ENABLE_GM82C803C_LOG +int gm82c803c_do_log = ENABLE_GM82C803C_LOG; + +static void +gm82c803c_log(const char *fmt, ...) +{ + va_list ap; + + if (gm82c803c_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define gm82c803c_log(fmt, ...) +#endif + +static void +ide_handler(gm82c803c_t *dev) +{ + uint16_t ide_port = 0x0000; + + if (dev->has_ide > 0) { + int ide_id = dev->has_ide - 1; + + ide_handlers(ide_id, 0); + + ide_port = (dev->regs[0xc4] << 2) & 0xfff0; + ide_set_base_addr(ide_id, 0, ide_port); + + ide_port = ((dev->regs[0xc5] << 2) & 0xfff0) | 0x0006; + ide_set_base_addr(ide_id, 1, ide_port); + + if (dev->regs[0xc2] & 0x20) + ide_handlers(ide_id, 1); + } +} + +static void +fdc_handler(gm82c803c_t *dev) +{ + uint16_t fdc_port = 0x0000; + uint8_t fdc_irq = 6; + uint8_t fdc_dma = 2; + + fdc_port = (dev->regs[0xc3] << 2) & 0xfff0; + + fdc_irq = dev->irq_map[dev->regs[0xca] >> 4]; + fdc_dma = dev->dma_map[(dev->regs[0xc9] >> 4) & 0x03]; + + fdc_set_irq(dev->fdc, fdc_irq); + fdc_set_dma_ch(dev->fdc, fdc_dma); + + fdc_remove(dev->fdc); + if (dev->regs[0xc2] & 0x10) + fdc_set_base(dev->fdc, fdc_port); +} + +static void +set_serial_addr(gm82c803c_t *dev, int port) +{ + uint16_t serial_port = 0x0000; + uint8_t serial_irq = COM1_IRQ; + double clock_src = 24000000.0 / 13.0; + + if (dev->regs[0xce] & (1 << (6 + port))) + clock_src = 24000000.0 / 3.0; + else if (dev->regs[0xd1] & (1 << port)) + clock_src = 24000000.0 / 12.0; + + serial_remove(dev->uart[port]); + if (dev->regs[0xc2] & (0x04 << port)) { + serial_port = (dev->regs[0xc7 + port] << 2) & 0xfff8; + serial_irq = dev->irq_map[dev->regs[0xcb] >> ((port ^ 1) * 0xff)]; + + serial_setup(dev->uart[port], serial_port, serial_irq); + } + + serial_set_clock_src(dev->uart[port], clock_src); +} + +static void +lpt_handler(gm82c803c_t *dev) +{ + uint16_t lpt_port = 0x0000; + uint16_t mask = 0xfffc; + uint8_t local_enable = 1; + uint8_t lpt_irq = LPT1_IRQ; + uint8_t lpt_dma = 3; + uint8_t lpt_mode = (dev->regs[0xc2] & 0x03); + + switch (lpt_mode) { + default: + local_enable = 0; + break; + case 0x00: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 1); + break; + case 0x01: + lpt_set_epp(dev->lpt, !!(dev->regs[0xd0] & 0x20)); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + case 0x02: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, !!(dev->regs[0xd0] & 0x20)); + lpt_set_ext(dev->lpt, 0); + break; + } + + lpt_port = ((dev->regs[0xc6] << 2) & 0xfffc) & mask; + + lpt_irq = dev->irq_map[dev->regs[0xca] & 0x0f]; + lpt_dma = dev->dma_map[dev->regs[0xc9] & 0x03]; + + if (lpt_irq > 15) + lpt_irq = 0xff; + + lpt_port_remove(dev->lpt); + lpt_set_fifo_threshold(dev->lpt, dev->regs[0x0a] & 0x0f); + + if (local_enable && (lpt_port >= 0x0100) && (lpt_port <= (0x0ffc & mask))) + lpt_port_setup(dev->lpt, lpt_port); + + lpt_port_irq(dev->lpt, lpt_irq); + lpt_port_dma(dev->lpt, lpt_dma); +} + +static void +gm82c803c_write(uint16_t port, uint8_t val, void *priv) +{ + gm82c803c_t *dev = (gm82c803c_t *) priv; + uint8_t valxor = 0; + + if (dev->tries == 2) { + if (port == 0x0398) { + if (val == 0xcc) + dev->tries = 0; + else + dev->cur_reg = val; + } else { + if ((dev->cur_reg < 0xc2) || (dev->cur_reg > 0xd8)) + return; + + valxor = val ^ dev->regs[dev->cur_reg]; + dev->regs[dev->cur_reg] = val; + + switch (dev->cur_reg) { + default: + break; + case 0xc2: + if (valxor & 0x20) + ide_handler(dev); + if (valxor & 0x10) + fdc_handler(dev); + if (valxor & 0x08) + set_serial_addr(dev, 1); + if (valxor & 0x04) + set_serial_addr(dev, 0); + if (valxor & 0x03) + lpt_handler(dev); + break; + case 0xc3: + if (valxor) + fdc_handler(dev); + break; + case 0xc4: case 0xc5: + if (valxor) + ide_handler(dev); + break; + case 0xc6: + if (valxor) + lpt_handler(dev); + break; + case 0xc7: + if (valxor) + set_serial_addr(dev, 0); + case 0xc8: + if (valxor) + set_serial_addr(dev, 1); + case 0xc9: + if (valxor & 0xf0) + fdc_handler(dev); + if (valxor & 0x0f) + lpt_handler(dev); + break; + case 0xca: + if (valxor & 0xf0) + fdc_handler(dev); + if (valxor & 0x0f) + lpt_handler(dev); + break; + case 0xcb: + if (valxor & 0xf0) + set_serial_addr(dev, 0); + if (valxor & 0x0f) + set_serial_addr(dev, 1); + break; + case 0xce: + if (valxor & 0x80) + set_serial_addr(dev, 1); + if (valxor & 0x40) + set_serial_addr(dev, 0); + break; + case 0xd0: + if (valxor & 0x20) + lpt_handler(dev); + break; + case 0xd1: + if (valxor & 0x02) + set_serial_addr(dev, 1); + if (valxor & 0x01) + set_serial_addr(dev, 0); + break; + + if (valxor & 0x20) + ide_handler(dev); + if (valxor & 0x08) + set_serial_addr(dev, 1); + if (valxor & 0x04) + set_serial_addr(dev, 0); + break; + } + } + } else if ((port == 0x0398) && (val == 0x33)) + dev->tries++; +} + +static uint8_t +gm82c803c_read(uint16_t port, void *priv) +{ + const gm82c803c_t *dev = (gm82c803c_t *) priv; + uint8_t ret = 0xff; + + if (dev->tries == 2) { + if ((port == 0x0399) && (dev->cur_reg >= 0xa0) && (dev->cur_reg <= 0xa1)) + ret = dev->regs[dev->cur_reg]; + } + + return ret; +} + +static void +gm82c803c_reset(gm82c803c_t *dev) +{ + serial_remove(dev->uart[0]); + serial_setup(dev->uart[0], COM1_ADDR, COM1_IRQ); + + serial_remove(dev->uart[1]); + serial_setup(dev->uart[1], COM2_ADDR, COM2_IRQ); + + lpt_port_remove(dev->lpt); + lpt_port_setup(dev->lpt, LPT1_ADDR); + + fdc_reset(dev->fdc); + fdc_remove(dev->fdc); + + dev->tries = 0; + memset(dev->regs, 0, 256); + + dev->regs[0xc0] = 0x3c; + dev->regs[0xc2] = 0x03; + dev->regs[0xc3] = 0x3c; + dev->regs[0xc4] = 0x3c; + dev->regs[0xc5] = 0x3d; + dev->regs[0xd5] = 0x3c; + + set_serial_addr(dev, 0); + set_serial_addr(dev, 1); + + lpt_handler(dev); + + fdc_handler(dev); + + if (dev->has_ide) + ide_handler(dev); +} + +static void +gm82c803c_close(void *priv) +{ + gm82c803c_t *dev = (gm82c803c_t *) priv; + + free(dev); +} + +static void * +gm82c803c_init(const device_t *info) +{ + gm82c803c_t *dev = (gm82c803c_t *) calloc(1, sizeof(gm82c803c_t)); + + dev->fdc = device_add(&fdc_at_smc_device); + + dev->has_ide = (info->local >> 8) & 0xff; + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + dev->lpt = device_add_inst(&lpt_port_device, 1); + + io_sethandler(0x0398, 0x0002, + gm82c803c_read, NULL, NULL, gm82c803c_write, NULL, NULL, dev); + + dev->dma_map[0] = 4; + for (int i = 1; i < 4; i++) + dev->dma_map[i] = i; + + memset(dev->irq_map, 0xff, 16); + dev->irq_map[0] = 0xff; + for (int i = 1; i < 7; i++) + dev->irq_map[i] = i; + dev->irq_map[1] = 5; + dev->irq_map[5] = 7; + dev->irq_map[7] = 0xff; /* Reserved. */ + dev->irq_map[8] = 10; + + gm82c803c_reset(dev); + + return dev; +} + +const device_t gm82c803c_device = { + .name = "Goldstar GM82C803C", + .internal_name = "gm82c803c", + .flags = 0, + .local = 0, + .init = gm82c803c_init, + .close = gm82c803c_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sio/sio_it86x1f.c b/src/sio/sio_it86x1f.c index c11b0e6bd..5d11610ad 100644 --- a/src/sio/sio_it86x1f.c +++ b/src/sio/sio_it86x1f.c @@ -296,6 +296,9 @@ it8661f_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *pri if (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) { it86x1f_log("IT86x1F: LPT enabled at port %04X IRQ %d\n", config->io[0].base, config->irq[0].irq); lpt_port_setup(dev->lpt, config->io[0].base); + + lpt_port_irq(dev->lpt, config->irq[0].irq); + lpt_port_dma(dev->lpt, (config->dma[0].dma == ISAPNP_DMA_DISABLED) ? -1 : config->dma[0].dma); } else { it86x1f_log("IT86x1F: LPT disabled\n"); } @@ -466,6 +469,13 @@ it86x1f_pnp_write_vendor_reg(uint8_t ld, uint8_t reg, uint8_t val, void *priv) case 0x0f0: dev->ldn_regs[ld][reg & 0x0f] = val & 0x0f; fdc_set_swwp(dev->fdc, !!(val & 0x01)); + if (val & 0x02) { + for (int i = 0; i < 4; i++) + fdc_update_drvrate(dev->fdc, i, 1); + } else { + for (int i = 0; i < 4; i++) + fdc_update_drvrate(dev->fdc, i, 0); + } fdc_set_swap(dev->fdc, !!(val & 0x04)); break; @@ -484,6 +494,8 @@ it86x1f_pnp_write_vendor_reg(uint8_t ld, uint8_t reg, uint8_t val, void *priv) case 0x3f0: dev->ldn_regs[ld][reg & 0x0f] = val & 0x07; + lpt_set_epp(dev->lpt, val & 0x01); + lpt_set_ecp(dev->lpt, val & 0x02); break; case 0x4f0: @@ -772,6 +784,9 @@ it86x1f_reset(it86x1f_t *dev) { it86x1f_log("IT86x1F: reset()\n"); + for (int i = 0; i < 4; i++) + fdc_update_drvrate(dev->fdc, i, 0); + fdc_reset(dev->fdc); serial_remove(dev->uart[0]); @@ -780,6 +795,9 @@ it86x1f_reset(it86x1f_t *dev) lpt_port_remove(dev->lpt); + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + isapnp_enable_card(dev->pnp_card, ISAPNP_CARD_DISABLE); dev->locked = 1; @@ -824,6 +842,7 @@ it86x1f_init(UNUSED(const device_t *info)) dev->uart[1] = device_add_inst(&ns16550_device, 2); dev->lpt = device_add_inst(&lpt_port_device, 1); + lpt_set_ext(dev->lpt, 1); dev->gameport = gameport_add(&gameport_sio_device); diff --git a/src/sio/sio_pc87306.c b/src/sio/sio_pc87306.c index 5b55907dd..6cda5bbd1 100644 --- a/src/sio/sio_pc87306.c +++ b/src/sio/sio_pc87306.c @@ -125,13 +125,9 @@ lpt_handler(pc87306_t *dev) uint16_t lptba; uint16_t lpt_port = LPT1_ADDR; uint8_t lpt_irq = LPT2_IRQ; - uint8_t lpt_dma = ((dev->regs[0x18] & 0x06) >> 1); lpt_port_remove(dev->lpt); - if (lpt_dma == 0x00) - lpt_dma = 0xff; - temp = dev->regs[0x01] & 3; lptba = ((uint16_t) dev->regs[0x19]) << 2; @@ -172,8 +168,6 @@ lpt_handler(pc87306_t *dev) lpt_port_setup(dev->lpt, lpt_port); lpt_port_irq(dev->lpt, lpt_irq); - - lpt_port_dma(dev->lpt, lpt_dma); } static void @@ -374,6 +368,8 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) fdc_update_enh_mode(dev->fdc, (val & 4) ? 1 : 0); fdc_update_densel_polarity(dev->fdc, (val & 0x40) ? 1 : 0); } + if (valxor & 0x20) + lpt_set_cnfga_readout(dev->lpt, (val & 0x20) ? 0x18 : 0x10); break; case 0x0f: if (valxor) @@ -470,6 +466,7 @@ pc87306_reset_common(void *priv) 0 = 360 rpm @ 500 kbps for 3.5" 1 = Default, 300 rpm @ 500, 300, 250, 1000 kbps for 3.5" */ + lpt_set_cnfga_readout(dev->lpt, 0x10); lpt_port_remove(dev->lpt); lpt_handler(dev); serial_remove(dev->uart[0x00]); @@ -517,6 +514,7 @@ pc87306_init(UNUSED(const device_t *info)) dev->uart[0x01] = device_add_inst(&ns16550_device, 2); dev->lpt = device_add_inst(&lpt_port_device, 1); + lpt_set_cnfga_readout(dev->lpt, 0x10); dev->nvr = device_add(&at_mb_nvr_device); diff --git a/src/sio/sio_pc87307.c b/src/sio/sio_pc87307.c index 72086fb61..e18d94428 100644 --- a/src/sio/sio_pc87307.c +++ b/src/sio/sio_pc87307.c @@ -267,6 +267,7 @@ fdc_handler(pc87307_t *dev) uint8_t active = (dev->ld_regs[LD_FDC][0x00] & 0x01) && (dev->pm[0x00] & 0x08); uint8_t irq = (dev->ld_regs[LD_FDC][0x40] & 0x0f); + uint8_t dma = (dev->ld_regs[LD_FDC][0x44] & 0x0f); uint16_t addr = ((dev->ld_regs[LD_FDC][0x30] << 8) | dev->ld_regs[LD_FDC][0x31]) & 0xfff8; @@ -274,6 +275,7 @@ fdc_handler(pc87307_t *dev) pc87307_log("Enabling FDC on %04X, IRQ %i...\n", addr, irq); fdc_set_base(dev->fdc, addr); fdc_set_irq(dev->fdc, irq); + fdc_set_dma_ch(dev->fdc, dma); } } @@ -283,16 +285,61 @@ lpt_handler(pc87307_t *dev) uint8_t active = (dev->ld_regs[LD_LPT][0x00] & 0x01) && (dev->pm[0x00] & 0x10); uint8_t irq = (dev->ld_regs[LD_LPT][0x40] & 0x0f); + uint8_t dma = (dev->ld_regs[LD_LPT][0x44] & 0x0f); uint16_t addr = (dev->ld_regs[LD_LPT][0x30] << 8) | dev->ld_regs[LD_LPT][0x31]; + uint8_t mode = (dev->ld_regs[LD_LPT][0xf0] >> 7); + uint16_t mask = 0xfffc; - if (active && (addr <= 0xfffc)) { + if (irq > 15) + irq = 0xff; + + if (dma >= 4) + dma = 0xff; + + lpt_port_remove(dev->lpt); + + switch (mode) { + default: + case 0x00: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + break; + case 0x01: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 1); + break; + case 0x02: case 0x03: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + break; + case 0x04: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + case 0x07: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + } + + lpt_set_cfg_regs_enabled(dev->lpt, !!(dev->ld_regs[LD_LPT][0xf0] & 0x10)); + + if (active && (addr <= (0xfffc & mask))) { pc87307_log("Enabling LPT1 on %04X...\n", addr); - lpt_port_setup(dev->lpt, addr); + lpt_port_setup(dev->lpt, addr & mask); } else lpt_port_setup(dev->lpt, 0xffff); lpt_port_irq(dev->lpt, irq); + lpt_port_dma(dev->lpt, dma); } static void @@ -852,6 +899,7 @@ pc87307_init(const device_t *info) dev->uart[1] = device_add_inst(&ns16550_device, 2); dev->lpt = device_add_inst(&lpt_port_device, 1); + lpt_set_cnfga_readout(dev->lpt, 0x14); switch (info->local & PCX730X_KBC) { default: diff --git a/src/sio/sio_pc87309.c b/src/sio/sio_pc87309.c index 19a18af81..9b50f8181 100644 --- a/src/sio/sio_pc87309.c +++ b/src/sio/sio_pc87309.c @@ -183,6 +183,7 @@ fdc_handler(pc87309_t *dev) uint8_t active = (dev->ld_regs[LD_FDC][0x00] & 0x01) && (dev->pm[0x00] & 0x08); uint8_t irq = (dev->ld_regs[LD_FDC][0x40] & 0x0f); + uint8_t dma = (dev->ld_regs[LD_FDC][0x44] & 0x0f); uint16_t addr = ((dev->ld_regs[LD_FDC][0x30] << 8) | dev->ld_regs[LD_FDC][0x31]) & 0xfff8; @@ -190,6 +191,7 @@ fdc_handler(pc87309_t *dev) pc87309_log("Enabling FDC on %04X, IRQ %i...\n", addr, irq); fdc_set_base(dev->fdc, addr); fdc_set_irq(dev->fdc, irq); + fdc_set_dma_ch(dev->fdc, dma); } } @@ -199,16 +201,61 @@ lpt_handler(pc87309_t *dev) uint8_t active = (dev->ld_regs[LD_LPT][0x00] & 0x01) && (dev->pm[0x00] & 0x10); uint8_t irq = (dev->ld_regs[LD_LPT][0x40] & 0x0f); + uint8_t dma = (dev->ld_regs[LD_LPT][0x44] & 0x0f); uint16_t addr = (dev->ld_regs[LD_LPT][0x30] << 8) | dev->ld_regs[LD_LPT][0x31]; + uint8_t mode = (dev->ld_regs[LD_LPT][0xf0] >> 7); + uint16_t mask = 0xfffc; - if (active && (addr <= 0xfffc)) { + if (irq > 15) + irq = 0xff; + + if (dma >= 4) + dma = 0xff; + + lpt_port_remove(dev->lpt); + + switch (mode) { + default: + case 0x00: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + break; + case 0x01: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 1); + break; + case 0x02: case 0x03: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + break; + case 0x04: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + case 0x07: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + } + + lpt_set_cfg_regs_enabled(dev->lpt, !!(dev->ld_regs[LD_LPT][0xf0] & 0x10)); + + if (active && (addr <= (0xfffc & mask))) { pc87309_log("Enabling LPT1 on %04X...\n", addr); - lpt_port_setup(dev->lpt, addr); + lpt_port_setup(dev->lpt, addr & mask); } else lpt_port_setup(dev->lpt, 0xffff); lpt_port_irq(dev->lpt, irq); + lpt_port_dma(dev->lpt, dma); } static void @@ -687,6 +734,7 @@ pc87309_init(const device_t *info) dev->uart[1] = device_add_inst(&ns16550_device, 2); dev->lpt = device_add_inst(&lpt_port_device, 1); + lpt_set_cnfga_readout(dev->lpt, 0x14); switch (info->local & PCX730X_KBC) { default: diff --git a/src/sio/sio_pc87310.c b/src/sio/sio_pc87310.c index cf6b10bab..b6341abc5 100644 --- a/src/sio/sio_pc87310.c +++ b/src/sio/sio_pc87310.c @@ -85,16 +85,16 @@ lpt_handler(pc87310_t *dev) lpt_port_remove(dev->lpt); switch (temp) { - case 0: + case 0x00: lpt_port = LPT1_ADDR; break; - case 1: + case 0x01: lpt_port = LPT_MDA_ADDR; break; - case 2: + case 0x02: lpt_port = LPT2_ADDR; break; - case 3: + case 0x03: lpt_port = 0x000; lpt_irq = 0xff; break; @@ -195,15 +195,15 @@ pc87310_write(UNUSED(uint16_t port), uint8_t val, void *priv) serial_handler(dev); /* Reconfigure IDE controller. */ - if ((dev->flags & PC87310_IDE) && (valxor & 0x20)) { + if ((dev->flags & PCX73XX_IDE) && (valxor & 0x20)) { pc87310_log("SIO: HDC disabled\n"); ide_pri_disable(); /* Bit 5: 1 = Disable IDE controller. */ if (!(val & 0x20)) { pc87310_log("SIO: HDC enabled\n"); ide_set_base(0, 0x1f0); - ide_set_side(0, 0x3f6); - ide_pri_enable(); + ide_set_side(0, 0x3f6); + ide_pri_enable(); } } @@ -256,7 +256,7 @@ pc87310_reset(pc87310_t *dev) lpt_handler(dev); serial_handler(dev); - if (dev->flags & PC87310_IDE) { + if (dev->flags & PCX73XX_IDE) { ide_pri_disable(); ide_pri_enable(); } @@ -285,17 +285,18 @@ pc87310_init(const device_t *info) dev->uart[1] = device_add_inst(&ns16450_device, 2); dev->lpt = device_add_inst(&lpt_port_device, 1); + lpt_set_ext(dev->lpt, 1); - if (dev->flags & PC87310_IDE) + if (dev->flags & PCX73XX_IDE) device_add((dev->flags & PC87310_ALI) ? &ide_vlb_device : &ide_isa_device); pc87310_reset(dev); - io_sethandler(0x3f3, 0x0001, + io_sethandler(0x03f3, 0x0001, pc87310_read, NULL, NULL, pc87310_write, NULL, NULL, dev); if (dev->flags & PC87310_ALI) - io_sethandler(0x3f1, 0x0001, + io_sethandler(0x03f1, 0x0001, pc87310_read, NULL, NULL, pc87310_write, NULL, NULL, dev); return dev; diff --git a/src/sio/sio_pc87311.c b/src/sio/sio_pc87311.c deleted file mode 100644 index 0b59324d6..000000000 --- a/src/sio/sio_pc87311.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * 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. - * - * Emulation of the National Semiconductor PC87311 Super I/O - * - * - * - * Authors: Tiseno100 - * - * Copyright 2020 Tiseno100 - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/io.h> -#include <86box/timer.h> -#include <86box/device.h> -#include <86box/lpt.h> -#include <86box/serial.h> -#include <86box/hdc.h> -#include <86box/hdc_ide.h> -#include <86box/fdd.h> -#include <86box/fdc.h> -#include <86box/sio.h> -#include <86box/plat_unused.h> - -#define HAS_IDE_FUNCTIONALITY dev->ide_function - -/* Basic Functionalities */ -#define FUNCTION_ENABLE dev->regs[0x00] -#define FUNCTION_ADDRESS dev->regs[0x01] -#define POWER_TEST dev->regs[0x02] - -/* Base Addresses */ -#define LPT_BA (FUNCTION_ADDRESS & 0x03) -#define UART1_BA ((FUNCTION_ADDRESS >> 2) & 0x03) -#define UART2_BA ((FUNCTION_ADDRESS >> 4) & 0x03) -#define COM_BA ((FUNCTION_ADDRESS >> 6) & 0x03) - -#ifdef ENABLE_PC87311_LOG -int pc87311_do_log = ENABLE_PC87311_LOG; - -static void -pc87311_log(const char *fmt, ...) -{ - va_list ap; - - if (pc87311_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define pc87311_log(fmt, ...) -#endif - -typedef struct pc87311_t { - uint8_t index; - uint8_t regs[256]; - uint8_t cfg_lock; - uint8_t ide_function; - uint16_t base; - uint16_t irq; - fdc_t *fdc_controller; - serial_t *uart[2]; - lpt_t *lpt; -} pc87311_t; - -void pc87311_fdc_handler(pc87311_t *dev); -void pc87311_uart_handler(uint8_t num, pc87311_t *dev); -void pc87311_lpt_handler(pc87311_t *dev); -void pc87311_ide_handler(pc87311_t *dev); -void pc87311_enable(pc87311_t *dev); - -static void -pc87311_write(uint16_t addr, uint8_t val, void *priv) -{ - pc87311_t *dev = (pc87311_t *) priv; - - switch (addr) { - case 0x398: - case 0x26e: - dev->index = val; - break; - - case 0x399: - case 0x26f: - switch (dev->index) { - case 0x00: - FUNCTION_ENABLE = val; - break; - case 0x01: - FUNCTION_ADDRESS = val; - break; - case 0x02: - POWER_TEST = val; - break; - - default: - break; - } - break; - - default: - break; - } - - pc87311_enable(dev); -} - -static uint8_t -pc87311_read(UNUSED(uint16_t addr), void *priv) -{ - const pc87311_t *dev = (pc87311_t *) priv; - - return dev->regs[dev->index]; -} - -void -pc87311_fdc_handler(pc87311_t *dev) -{ - fdc_remove(dev->fdc_controller); - fdc_set_base(dev->fdc_controller, (FUNCTION_ENABLE & 0x20) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR); - pc87311_log("PC87311-FDC: BASE %04x\n", (FUNCTION_ENABLE & 0x20) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR); -} - -uint16_t -com3(pc87311_t *dev) -{ - switch (COM_BA) { - case 0: - return COM3_ADDR; - case 1: - return 0x0338; - case 2: - return COM4_ADDR; - case 3: - return 0x0220; - default: - return COM3_ADDR; - } -} - -uint16_t -com4(pc87311_t *dev) -{ - switch (COM_BA) { - case 0: - return COM4_ADDR; - case 1: - return 0x0238; - case 2: - return 0x02e0; - case 3: - return 0x0228; - default: - return COM4_ADDR; - } -} - -void -pc87311_uart_handler(uint8_t num, pc87311_t *dev) -{ - serial_remove(dev->uart[num & 1]); - - switch (!(num & 1) ? UART1_BA : UART2_BA) { - case 0: - dev->base = COM1_ADDR; - dev->irq = COM1_IRQ; - break; - case 1: - dev->base = COM2_ADDR; - dev->irq = COM2_IRQ; - break; - case 2: - dev->base = com3(dev); - dev->irq = COM3_IRQ; - break; - case 3: - dev->base = com4(dev); - dev->irq = COM4_IRQ; - break; - - default: - break; - } - serial_setup(dev->uart[num & 1], dev->base, dev->irq); - pc87311_log("PC87311-UART%01x: BASE %04x IRQ %01x\n", num & 1, dev->base, dev->irq); -} - -void -pc87311_lpt_handler(pc87311_t *dev) -{ - lpt_port_remove(dev->lpt); - switch (LPT_BA) { - case 0: - dev->base = LPT1_ADDR; - dev->irq = (POWER_TEST & 0x08) ? LPT1_IRQ : LPT2_IRQ; - break; - case 1: - dev->base = LPT_MDA_ADDR; - dev->irq = LPT_MDA_IRQ; - break; - case 2: - dev->base = LPT2_ADDR; - dev->irq = LPT2_IRQ; - break; - - default: - break; - } - lpt_port_setup(dev->lpt, dev->base); - lpt_port_irq(dev->lpt, dev->irq); - pc87311_log("PC87311-LPT: BASE %04x IRQ %01x\n", dev->base, dev->irq); -} - -void -pc87311_ide_handler(pc87311_t *dev) -{ - ide_pri_disable(); - ide_sec_disable(); - - ide_set_base(0, 0x1f0); - ide_set_side(0, 0x3f6); - ide_pri_enable(); - - if (FUNCTION_ENABLE & 0x80) { - ide_set_base(1, 0x170); - ide_set_side(1, 0x376); - ide_sec_enable(); - } - pc87311_log("PC87311-IDE: PRI %01x SEC %01x\n", (FUNCTION_ENABLE >> 6) & 1, (FUNCTION_ENABLE >> 7) & 1); -} - -void -pc87311_enable(pc87311_t *dev) -{ - (FUNCTION_ENABLE & 0x01) ? pc87311_lpt_handler(dev) : lpt_port_remove(dev->lpt); - (FUNCTION_ENABLE & 0x02) ? pc87311_uart_handler(0, dev) : serial_remove(dev->uart[0]); - (FUNCTION_ENABLE & 0x04) ? pc87311_uart_handler(1, dev) : serial_remove(dev->uart[1]); - (FUNCTION_ENABLE & 0x08) ? pc87311_fdc_handler(dev) : fdc_remove(dev->fdc_controller); - if (FUNCTION_ENABLE & 0x20) - pc87311_fdc_handler(dev); - if (HAS_IDE_FUNCTIONALITY) { - (FUNCTION_ENABLE & 0x40) ? pc87311_ide_handler(dev) : ide_pri_disable(); - (FUNCTION_ADDRESS & 0x80) ? pc87311_ide_handler(dev) : ide_sec_disable(); - } -} - -static void -pc87311_close(void *priv) -{ - pc87311_t *dev = (pc87311_t *) priv; - - free(dev); -} - -static void * -pc87311_init(const device_t *info) -{ - pc87311_t *dev = (pc87311_t *) calloc(1, sizeof(pc87311_t)); - - /* Avoid conflicting with machines that make no use of the PC87311 Internal IDE */ - HAS_IDE_FUNCTIONALITY = info->local; - - dev->fdc_controller = device_add(&fdc_at_nsc_device); - dev->uart[0] = device_add_inst(&ns16450_device, 1); - dev->uart[1] = device_add_inst(&ns16450_device, 2); - dev->lpt = device_add_inst(&lpt_port_device, 1); - - if (HAS_IDE_FUNCTIONALITY) - device_add(&ide_isa_2ch_device); - - io_sethandler(0x0398, 0x0002, pc87311_read, NULL, NULL, pc87311_write, NULL, NULL, dev); - io_sethandler(0x026e, 0x0002, pc87311_read, NULL, NULL, pc87311_write, NULL, NULL, dev); - - pc87311_enable(dev); - - return dev; -} - -const device_t pc87311_device = { - .name = "National Semiconductor PC87311", - .internal_name = "pc87311", - .flags = 0, - .local = 0, - .init = pc87311_init, - .close = pc87311_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t pc87311_ide_device = { - .name = "National Semiconductor PC87311 with IDE functionality", - .internal_name = "pc87311_ide", - .flags = 0, - .local = 1, - .init = pc87311_init, - .close = pc87311_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; diff --git a/src/sio/sio_pc87332.c b/src/sio/sio_pc873xx.c similarity index 63% rename from src/sio/sio_pc87332.c rename to src/sio/sio_pc873xx.c index 9e57bf74b..bec747ed2 100644 --- a/src/sio/sio_pc87332.c +++ b/src/sio/sio_pc873xx.c @@ -6,9 +6,7 @@ * * This file is part of the 86Box distribution. * - * Emulation of the NatSemi PC87332 Super I/O chip. - * - * + * Emulation of the NatSemi PC87311 and PC87332 Super I/O chips. * * Authors: Miran Grca, * @@ -35,40 +33,50 @@ #include <86box/fdc.h> #include <86box/sio.h> -typedef struct pc87332_t { +typedef struct pc873xx_t { + uint8_t baddr; + uint8_t is_332; uint8_t tries; uint8_t has_ide; uint8_t fdc_on; uint8_t regs[15]; + uint16_t base_addr; int cur_reg; + int max_reg; fdc_t *fdc; serial_t *uart[2]; lpt_t *lpt; -} pc87332_t; +} pc873xx_t; static void -lpt_handler(pc87332_t *dev) +lpt_handler(pc873xx_t *dev) { int temp; uint16_t lpt_port = LPT1_ADDR; - uint8_t lpt_irq = LPT2_IRQ; + uint8_t lpt_irq = LPT2_IRQ; + uint8_t lpt_dma = ((dev->regs[0x18] & 0x06) >> 1); - temp = dev->regs[0x01] & 3; + lpt_port_remove(dev->lpt); + + if (lpt_dma == 0x00) + lpt_dma = 0xff; + + temp = dev->regs[0x01] & 0x03; switch (temp) { - case 0: + case 0x00: lpt_port = LPT1_ADDR; lpt_irq = (dev->regs[0x02] & 0x08) ? LPT1_IRQ : LPT2_IRQ; break; - case 1: + case 0x01: lpt_port = LPT_MDA_ADDR; - lpt_irq = LPT_MDA_IRQ; + lpt_irq = LPT_MDA_IRQ; break; - case 2: + case 0x02: lpt_port = LPT2_ADDR; lpt_irq = LPT2_IRQ; break; - case 3: + case 0x03: lpt_port = 0x000; lpt_irq = 0xff; break; @@ -77,6 +85,15 @@ lpt_handler(pc87332_t *dev) break; } + lpt_set_ext(dev->lpt, !!(dev->regs[0x02] & 0x80)); + + if (dev->is_332) { + lpt_set_epp(dev->lpt, !!(dev->regs[0x04] & 0x01)); + lpt_set_ecp(dev->lpt, !!(dev->regs[0x04] & 0x04)); + + lpt_port_dma(dev->lpt, lpt_dma); + } + if (lpt_port) lpt_port_setup(dev->lpt, lpt_port); @@ -84,7 +101,7 @@ lpt_handler(pc87332_t *dev) } static void -serial_handler(pc87332_t *dev, int uart) +serial_handler(pc873xx_t *dev, int uart) { int temp; @@ -142,7 +159,7 @@ serial_handler(pc87332_t *dev, int uart) } static void -ide_handler(pc87332_t *dev) +ide_handler(pc873xx_t *dev) { /* TODO: Make an ide_disable(channel) and ide_enable(channel) so we can simplify this. */ if (dev->has_ide == 2) { @@ -161,9 +178,9 @@ ide_handler(pc87332_t *dev) } static void -pc87332_write(uint16_t port, uint8_t val, void *priv) +pc873xx_write(uint16_t port, uint8_t val, void *priv) { - pc87332_t *dev = (pc87332_t *) priv; + pc873xx_t *dev = (pc873xx_t *) priv; uint8_t index; uint8_t valxor; @@ -177,7 +194,7 @@ pc87332_write(uint16_t port, uint8_t val, void *priv) if (dev->tries) { valxor = val ^ dev->regs[dev->cur_reg]; dev->tries = 0; - if ((dev->cur_reg <= 14) && (dev->cur_reg != 8)) + if ((dev->cur_reg <= dev->max_reg) && (dev->cur_reg != 8)) dev->regs[dev->cur_reg] = val; else return; @@ -187,69 +204,83 @@ pc87332_write(uint16_t port, uint8_t val, void *priv) } } - switch (dev->cur_reg) { - case 0: - if (valxor & 1) { + if (dev->cur_reg <= dev->max_reg) switch (dev->cur_reg) { + case 0x00: + if (valxor & 0x01) { lpt_port_remove(dev->lpt); - if ((val & 1) && !(dev->regs[2] & 1)) + if ((val & 0x01) && !(dev->regs[0x02] & 0x01)) lpt_handler(dev); } - if (valxor & 2) { + if (valxor & 0x02) { serial_remove(dev->uart[0]); - if ((val & 2) && !(dev->regs[2] & 1)) + if ((val & 0x02) && !(dev->regs[0x02] & 0x01)) serial_handler(dev, 0); } - if (valxor & 4) { + if (valxor & 0x04) { serial_remove(dev->uart[1]); - if ((val & 4) && !(dev->regs[2] & 1)) + if ((val & 0x04) && !(dev->regs[0x02] & 0x01)) serial_handler(dev, 1); } if (valxor & 0x28) { fdc_remove(dev->fdc); - if ((val & 8) && !(dev->regs[2] & 1)) + if ((val & 0x08) && !(dev->regs[0x02] & 0x01)) fdc_set_base(dev->fdc, (val & 0x20) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR); } if (dev->has_ide && (valxor & 0xc0)) ide_handler(dev); break; - case 1: - if (valxor & 3) { + case 0x01: + if (valxor & 0x03) { lpt_port_remove(dev->lpt); - if ((dev->regs[0] & 1) && !(dev->regs[2] & 1)) + if ((dev->regs[0x00] & 0x01) && !(dev->regs[0x02] & 0x01)) lpt_handler(dev); } if (valxor & 0xcc) { serial_remove(dev->uart[0]); - if ((dev->regs[0] & 2) && !(dev->regs[2] & 1)) + if ((dev->regs[0x00] & 0x02) && !(dev->regs[0x02] & 0x01)) serial_handler(dev, 0); } if (valxor & 0xf0) { serial_remove(dev->uart[1]); - if ((dev->regs[0] & 4) && !(dev->regs[2] & 1)) + if ((dev->regs[0x00] & 0x04) && !(dev->regs[0x02] & 0x01)) serial_handler(dev, 1); } break; - case 2: - if (valxor & 1) { + case 0x02: + if (valxor & 0x01) { lpt_port_remove(dev->lpt); serial_remove(dev->uart[0]); serial_remove(dev->uart[1]); fdc_remove(dev->fdc); - if (!(val & 1)) { - if (dev->regs[0] & 1) + if (!(val & 0x01)) { + if (dev->regs[0x00] & 0x01) lpt_handler(dev); - if (dev->regs[0] & 2) + if (dev->regs[0x00] & 0x02) serial_handler(dev, 0); - if (dev->regs[0] & 4) + if (dev->regs[0x00] & 0x04) serial_handler(dev, 1); - if (dev->regs[0] & 8) - fdc_set_base(dev->fdc, (dev->regs[0] & 0x20) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR); + if (dev->regs[0x00] & 0x08) + fdc_set_base(dev->fdc, (dev->regs[0x00] & 0x20) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR); } } - if (valxor & 8) { + if (valxor & 0x88) { lpt_port_remove(dev->lpt); - if ((dev->regs[0] & 1) && !(dev->regs[2] & 1)) + if ((dev->regs[0x00] & 0x01) && !(dev->regs[0x02] & 0x01)) + lpt_handler(dev); + } + break; + case 0x04: + if (valxor & 0x05) { + lpt_port_remove(dev->lpt); + if ((dev->regs[0x00] & 0x01) && !(dev->regs[0x02] & 0x01)) + lpt_handler(dev); + } + break; + case 0x06: + if (valxor & 0x08) { + lpt_port_remove(dev->lpt); + if ((dev->regs[0x00] & 0x01) && !(dev->regs[0x02] & 0x01)) lpt_handler(dev); } break; @@ -260,9 +291,9 @@ pc87332_write(uint16_t port, uint8_t val, void *priv) } uint8_t -pc87332_read(uint16_t port, void *priv) +pc873xx_read(uint16_t port, void *priv) { - pc87332_t *dev = (pc87332_t *) priv; + pc873xx_t *dev = (pc873xx_t *) priv; uint8_t ret = 0xff; uint8_t index; @@ -283,7 +314,7 @@ pc87332_read(uint16_t port, void *priv) } void -pc87332_reset(pc87332_t *dev) +pc873xx_reset(pc873xx_t *dev) { memset(dev->regs, 0, 15); @@ -314,17 +345,17 @@ pc87332_reset(pc87332_t *dev) } static void -pc87332_close(void *priv) +pc873xx_close(void *priv) { - pc87332_t *dev = (pc87332_t *) priv; + pc873xx_t *dev = (pc873xx_t *) priv; free(dev); } static void * -pc87332_init(const device_t *info) +pc873xx_init(const device_t *info) { - pc87332_t *dev = (pc87332_t *) calloc(1, sizeof(pc87332_t)); + pc873xx_t *dev = (pc873xx_t *) calloc(1, sizeof(pc873xx_t)); dev->fdc = device_add(&fdc_at_nsc_device); @@ -333,84 +364,45 @@ pc87332_init(const device_t *info) dev->lpt = device_add_inst(&lpt_port_device, 1); - dev->has_ide = (info->local >> 8) & 0xff; - dev->fdc_on = (info->local >> 16) & 0xff; - pc87332_reset(dev); + dev->is_332 = !!(info->local & PC87332); + dev->max_reg = dev->is_332 ? 0x08 : 0x02; - if ((info->local & 0xff) == 0x01) { - io_sethandler(0x398, 0x0002, - pc87332_read, NULL, NULL, pc87332_write, NULL, NULL, dev); - } else { - io_sethandler(0x02e, 0x0002, - pc87332_read, NULL, NULL, pc87332_write, NULL, NULL, dev); + dev->has_ide = info->local & (PCX73XX_IDE_PRI | PCX73XX_IDE_SEC); + dev->fdc_on = info->local & PCX73XX_FDC_ON; + + dev->baddr = (info->local & PCX730X_BADDR) >> PCX730X_BADDR_SHIFT; + pc873xx_reset(dev); + + switch (dev->baddr) { + default: + case 0x00: + dev->base_addr = 0x0398; + break; + case 0x01: + dev->base_addr = 0x026e; + break; + case 0x02: + dev->base_addr = 0x015c; + break; + case 0x03: + /* Our PC87332 machine use this unless otherwise specified. */ + dev->base_addr = 0x002e; + break; } + io_sethandler(dev->base_addr, 0x0002, + pc873xx_read, NULL, NULL, pc873xx_write, NULL, NULL, dev); + return dev; } -const device_t pc87332_device = { - .name = "National Semiconductor PC87332 Super I/O", - .internal_name = "pc87332", +const device_t pc873xx_device = { + .name = "National Semiconductor PC873xx Super I/O", + .internal_name = "pc873xx", .flags = 0, .local = 0x00, - .init = pc87332_init, - .close = pc87332_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t pc87332_398_device = { - .name = "National Semiconductor PC87332 Super I/O (Port 398h)", - .internal_name = "pc87332_398", - .flags = 0, - .local = 0x01, - .init = pc87332_init, - .close = pc87332_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t pc87332_398_ide_device = { - .name = "National Semiconductor PC87332 Super I/O (Port 398h) (With IDE)", - .internal_name = "pc87332_398_ide", - .flags = 0, - .local = 0x101, - .init = pc87332_init, - .close = pc87332_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t pc87332_398_ide_sec_device = { - .name = "National Semiconductor PC87332 Super I/O (Port 398h) (With Secondary IDE)", - .internal_name = "pc87332_398_ide_sec", - .flags = 0, - .local = 0x201, - .init = pc87332_init, - .close = pc87332_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t pc87332_398_ide_fdcon_device = { - .name = "National Semiconductor PC87332 Super I/O (Port 398h) (With IDE and FDC on)", - .internal_name = "pc87332_398_ide_fdcon", - .flags = 0, - .local = 0x10101, - .init = pc87332_init, - .close = pc87332_close, + .init = pc873xx_init, + .close = pc873xx_close, .reset = NULL, .available = NULL, .speed_changed = NULL, diff --git a/src/sio/sio_prime3b.c b/src/sio/sio_prime3b.c deleted file mode 100644 index 338f8ee90..000000000 --- a/src/sio/sio_prime3b.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * 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. - * - * Emulation of the Goldstar Prime3B Super I/O - * - * - * - * Authors: Tiseno100 - * - * Copyright 2021 Tiseno100 - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/io.h> -#include <86box/timer.h> -#include <86box/device.h> -#include <86box/lpt.h> -#include <86box/serial.h> -#include <86box/hdc.h> -#include <86box/hdc_ide.h> -#include <86box/fdd.h> -#include <86box/fdc.h> -#include <86box/sio.h> -#include <86box/plat_unused.h> - -#define FSR dev->regs[0xa0] -#define ASR dev->regs[0xa1] -#define PDR dev->regs[0xa2] -#define HAS_IDE_FUNCTIONALITY dev->ide_function - -#ifdef ENABLE_PRIME3B_LOG -int prime3b_do_log = ENABLE_PRIME3B_LOG; - -static void -prime3b_log(const char *fmt, ...) -{ - va_list ap; - - if (prime3b_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define prime3b_log(fmt, ...) -#endif - -typedef struct prime3b_t { - uint8_t index; - uint8_t regs[256]; - uint8_t cfg_lock; - uint8_t ide_function; - uint16_t com3_addr; - uint16_t com4_addr; - - fdc_t *fdc_controller; - - serial_t *uart[2]; - lpt_t *lpt; -} prime3b_t; - -void prime3b_fdc_handler(prime3b_t *dev); -void prime3b_uart_handler(uint8_t num, prime3b_t *dev); -void prime3b_lpt_handler(prime3b_t *dev); -void prime3b_ide_handler(prime3b_t *dev); -void prime3b_enable(prime3b_t *dev); -void prime3b_powerdown(prime3b_t *dev); - -static void -prime3b_write(uint16_t addr, uint8_t val, void *priv) -{ - prime3b_t *dev = (prime3b_t *) priv; - - if (addr == 0x398) { - dev->index = val; - - /* Enter/Escape Configuration Mode */ - if (val == 0x33) - dev->cfg_lock = 0; - else if (val == 0xcc) - dev->cfg_lock = 1; - } else if ((addr == 0x399) && !dev->cfg_lock) { - switch (dev->index) { - case 0xa0: /* Function Selection Register (FSR) */ - FSR = val; - prime3b_enable(dev); - break; - case 0xa1: /* Address Selection Register (ASR) */ - ASR = val; - prime3b_enable(dev); - break; - case 0xa2: /* Power Down Register (PDR) */ - dev->regs[0xa2] = val; - break; - case 0xa3: /* Test Mode Register (TMR) */ - dev->regs[0xa3] = val; - break; - case 0xa4: /* Miscellaneous Function Register */ - dev->regs[0xa4] = val; - switch ((dev->regs[0xa4] >> 6) & 3) { - case 0: - dev->com3_addr = COM3_ADDR; - dev->com4_addr = COM4_ADDR; - break; - case 1: - dev->com3_addr = 0x338; - dev->com4_addr = 0x238; - break; - case 2: - dev->com3_addr = COM4_ADDR; - dev->com4_addr = 0x2e0; - break; - case 3: - dev->com3_addr = 0x220; - dev->com4_addr = 0x228; - break; - - default: - break; - } - break; - case 0xa5: /* ECP Register */ - dev->regs[0xa5] = val; - break; - - default: - break; - } - } -} - -static uint8_t -prime3b_read(UNUSED(uint16_t addr), void *priv) -{ - const prime3b_t *dev = (prime3b_t *) priv; - - return dev->regs[dev->index]; -} - -void -prime3b_fdc_handler(prime3b_t *dev) -{ - uint16_t fdc_base = !(ASR & 0x40) ? FDC_PRIMARY_ADDR : FDC_SECONDARY_ADDR; - fdc_remove(dev->fdc_controller); - fdc_set_base(dev->fdc_controller, fdc_base); - prime3b_log("Prime3B-FDC: Enabled with base %03x\n", fdc_base); -} - -void -prime3b_uart_handler(uint8_t num, prime3b_t *dev) -{ - uint16_t uart_base; - if ((ASR >> (3 + 2 * num)) & 1) - uart_base = !((ASR >> (2 + 2 * num)) & 1) ? dev->com3_addr : dev->com4_addr; - else - uart_base = !((ASR >> (2 + 2 * num)) & 1) ? COM1_ADDR : COM2_ADDR; - - serial_remove(dev->uart[num]); - serial_setup(dev->uart[num], uart_base, 4 - num); - prime3b_log("Prime3B-UART%d: Enabled with base %03x\n", num, uart_base); -} - -void -prime3b_lpt_handler(prime3b_t *dev) -{ - uint16_t lpt_base = (ASR & 2) ? LPT_MDA_ADDR : (!(ASR & 1) ? LPT1_ADDR : LPT2_ADDR); - lpt_port_remove(dev->lpt); - lpt_port_setup(dev->lpt, lpt_base); - lpt_port_irq(dev->lpt, LPT1_IRQ); - prime3b_log("Prime3B-LPT: Enabled with base %03x\n", lpt_base); -} - -void -prime3b_ide_handler(prime3b_t *dev) -{ - ide_pri_disable(); - uint16_t ide_base = !(ASR & 0x80) ? 0x1f0 : 0x170; - uint16_t ide_side = ide_base + 0x206; - ide_set_base(0, ide_base); - ide_set_side(0, ide_side); - prime3b_log("Prime3B-IDE: Enabled with base %03x and side %03x\n", ide_base, ide_side); -} - -void -prime3b_enable(prime3b_t *dev) -{ - /* - Simulate a device enable/disable scenario - - Register A0: Function Selection Register (FSR) - Bit 7: Gameport - Bit 6: 4 FDD Enable - Bit 5: IDE - Bit 4: FDC - Bit 3: UART 2 - Bit 2: UART 1 - Bit 1/0: PIO (0/0 Bidirectional , 0/1 ECP, 1/0 EPP, 1/1 Disabled) - - Note: 86Box LPT is simplistic and can't do ECP or EPP. - */ - - !(FSR & 3) ? prime3b_lpt_handler(dev) : lpt_port_remove(dev->lpt); - (FSR & 4) ? prime3b_uart_handler(0, dev) : serial_remove(dev->uart[0]); - (FSR & 8) ? prime3b_uart_handler(1, dev) : serial_remove(dev->uart[1]); - (FSR & 0x10) ? prime3b_fdc_handler(dev) : fdc_remove(dev->fdc_controller); - if (HAS_IDE_FUNCTIONALITY) - (FSR & 0x20) ? prime3b_ide_handler(dev) : ide_pri_disable(); -} - -void -prime3b_powerdown(prime3b_t *dev) -{ - /* Note: It can be done more efficiently for sure */ - uint8_t old_base = PDR; - - if (PDR & 1) - PDR |= 0x1e; - - if (PDR & 0x40) - io_removehandler(0x0398, 0x0002, prime3b_read, NULL, NULL, prime3b_write, NULL, NULL, dev); - - if (PDR & 2) - fdc_remove(dev->fdc_controller); - - if (PDR & 4) - serial_remove(dev->uart[0]); - - if (PDR & 8) - serial_remove(dev->uart[1]); - - if (PDR & 0x10) - lpt_port_remove(dev->lpt); - - if (PDR & 1) - PDR = old_base; -} - -static void -prime3b_close(void *priv) -{ - prime3b_t *dev = (prime3b_t *) priv; - - free(dev); -} - -static void * -prime3b_init(const device_t *info) -{ - prime3b_t *dev = (prime3b_t *) calloc(1, sizeof(prime3b_t)); - - /* Avoid conflicting with machines that make no use of the Prime3B Internal IDE */ - HAS_IDE_FUNCTIONALITY = info->local; - - dev->regs[0xa0] = 3; - - dev->fdc_controller = device_add(&fdc_at_device); - dev->uart[0] = device_add_inst(&ns16550_device, 1); - dev->uart[1] = device_add_inst(&ns16550_device, 2); - dev->lpt = device_add_inst(&lpt_port_device, 1); - if (HAS_IDE_FUNCTIONALITY) - device_add(&ide_isa_device); - - dev->com3_addr = COM3_ADDR; - dev->com4_addr = COM4_ADDR; - fdc_reset(dev->fdc_controller); - - prime3b_enable(dev); - - io_sethandler(0x0398, 0x0002, prime3b_read, NULL, NULL, prime3b_write, NULL, NULL, dev); - - return dev; -} - -const device_t prime3b_device = { - .name = "Goldstar Prime3B", - .internal_name = "prime3b", - .flags = 0, - .local = 0, - .init = prime3b_init, - .close = prime3b_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t prime3b_ide_device = { - .name = "Goldstar Prime3B with IDE functionality", - .internal_name = "prime3b_ide", - .flags = 0, - .local = 1, - .init = prime3b_init, - .close = prime3b_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; diff --git a/src/sio/sio_prime3c.c b/src/sio/sio_prime3c.c deleted file mode 100644 index 3b06d8789..000000000 --- a/src/sio/sio_prime3c.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * 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. - * - * Emulation of the LG Prime3C Super I/O - * - * - * - * Authors: Tiseno100 - * - * Copyright 2020 Tiseno100 - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/io.h> -#include <86box/timer.h> -#include <86box/device.h> -#include <86box/lpt.h> -#include <86box/serial.h> -#include <86box/hdc.h> -#include <86box/hdc_ide.h> -#include <86box/fdd.h> -#include <86box/fdc.h> -#include <86box/sio.h> -#include <86box/plat_unused.h> - -#ifdef ENABLE_PRIME3C_LOG -int prime3c_do_log = ENABLE_PRIME3C_LOG; - -static void -prime3c_log(const char *fmt, ...) -{ - va_list ap; - - if (prime3c_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define prime3c_log(fmt, ...) -#endif - -/* Function Select(Note on prime3c_enable) */ -#define FUNCTION_SELECT dev->regs[0xc2] - -/* Base Address Registers */ -#define FDC_BASE_ADDRESS dev->regs[0xc3] -#define IDE_BASE_ADDRESS dev->regs[0xc4] -#define IDE_SIDE_ADDRESS dev->regs[0xc5] -#define LPT_BASE_ADDRESS dev->regs[0xc6] -#define UART1_BASE_ADDRESS dev->regs[0xc7] -#define UART2_BASE_ADDRESS dev->regs[0xc8] - -/* FDC/LPT Configuration */ -#define FDC_LPT_DMA dev->regs[0xc9] -#define FDC_LPT_IRQ dev->regs[0xca] - -/* UART 1/2 Configuration */ -#define UART_IRQ dev->regs[0xcb] - -/* Miscellaneous Configuration*/ -#define FDC_SWAP (dev->regs[0xd6] & 0x01) - -/* IDE functionality(Note on Init) */ -#define HAS_IDE_FUNCTIONALITY dev->ide_function - -typedef struct prime3c_t { - uint8_t index; - uint8_t regs[256]; - uint8_t cfg_lock; - uint8_t ide_function; - - fdc_t *fdc_controller; - - serial_t *uart[2]; - lpt_t *lpt; -} prime3c_t; - -void prime3c_fdc_handler(prime3c_t *dev); -void prime3c_uart_handler(uint8_t num, prime3c_t *dev); -void prime3c_lpt_handler(prime3c_t *dev); -void prime3c_ide_handler(prime3c_t *dev); -void prime3c_enable(prime3c_t *dev); - -static void -prime3c_write(uint16_t addr, uint8_t val, void *priv) -{ - prime3c_t *dev = (prime3c_t *) priv; - - switch (addr) { - case 0x398: - dev->index = val; - - /* Enter/Escape Configuration Mode */ - if (val == 0x33) - dev->cfg_lock = 0; - else if (val == 0x55) - dev->cfg_lock = 1; - break; - - case 0x399: - if (!dev->cfg_lock) { - switch (dev->index) { - case 0xc2: - FUNCTION_SELECT = val & 0xbf; - prime3c_enable(dev); - break; - - case 0xc3: - FDC_BASE_ADDRESS = val & 0xfc; - prime3c_fdc_handler(dev); - break; - - case 0xc4: - IDE_BASE_ADDRESS = val & 0xfc; - if (HAS_IDE_FUNCTIONALITY) - prime3c_ide_handler(dev); - break; - - case 0xc5: - IDE_SIDE_ADDRESS = (val & 0xfc) | 0x02; - if (HAS_IDE_FUNCTIONALITY) - prime3c_ide_handler(dev); - break; - - case 0xc6: - LPT_BASE_ADDRESS = val; - break; - - case 0xc7: - UART1_BASE_ADDRESS = val & 0xfe; - prime3c_uart_handler(0, dev); - break; - - case 0xc8: - UART2_BASE_ADDRESS = val & 0xfe; - prime3c_uart_handler(1, dev); - break; - - case 0xc9: - FDC_LPT_DMA = val; - prime3c_fdc_handler(dev); - break; - - case 0xca: - FDC_LPT_IRQ = val; - prime3c_fdc_handler(dev); - prime3c_lpt_handler(dev); - break; - - case 0xcb: - UART_IRQ = val; - prime3c_uart_handler(0, dev); - prime3c_uart_handler(1, dev); - break; - - case 0xcd: - case 0xce: - dev->regs[dev->index] = val; - break; - - case 0xcf: - dev->regs[dev->index] = val & 0x3f; - break; - - case 0xd0: - dev->regs[dev->index] = val & 0xfc; - break; - - case 0xd1: - dev->regs[dev->index] = val & 0x3f; - break; - - case 0xd3: - dev->regs[dev->index] = val & 0x7c; - break; - - case 0xd5: - case 0xd6: - case 0xd7: - case 0xd8: - dev->regs[dev->index] = val; - break; - - default: - break; - } - } - break; - - default: - break; - } -} - -static uint8_t -prime3c_read(UNUSED(uint16_t addr), void *priv) -{ - const prime3c_t *dev = (prime3c_t *) priv; - - return dev->regs[dev->index]; -} - -void -prime3c_fdc_handler(prime3c_t *dev) -{ - fdc_remove(dev->fdc_controller); - if (FUNCTION_SELECT & 0x10) { - fdc_set_base(dev->fdc_controller, FDC_BASE_ADDRESS << 2); - fdc_set_irq(dev->fdc_controller, (FDC_LPT_IRQ >> 4) & 0xf); - fdc_set_dma_ch(dev->fdc_controller, (FDC_LPT_DMA >> 4) & 0xf); - fdc_set_swap(dev->fdc_controller, FDC_SWAP); - prime3c_log("Prime3C-FDC: BASE %04x IRQ %01x DMA %01x\n", FDC_BASE_ADDRESS << 2, (FDC_LPT_IRQ >> 4) & 0xf, (FDC_LPT_DMA >> 4) & 0xf); - } -} - -void -prime3c_uart_handler(uint8_t num, prime3c_t *dev) -{ - serial_remove(dev->uart[num & 1]); - if (FUNCTION_SELECT & (!(num & 1) ? 0x04 : 0x08)) { - serial_setup(dev->uart[num & 1], (!(num & 1) ? UART1_BASE_ADDRESS : UART2_BASE_ADDRESS) << 2, (UART_IRQ >> (!(num & 1) ? 4 : 0)) & 0xf); - prime3c_log("Prime3C-UART%01x: BASE %04x IRQ %01x\n", num & 1, (!(num & 1) ? UART1_BASE_ADDRESS : UART2_BASE_ADDRESS) << 2, (UART_IRQ >> (!(num & 1) ? 4 : 0)) & 0xf); - } -} - -void -prime3c_lpt_handler(prime3c_t *dev) -{ - lpt_port_remove(dev->lpt); - - if (!(FUNCTION_SELECT & 0x03)) { - lpt_port_setup(dev->lpt, LPT_BASE_ADDRESS << 2); - lpt_port_irq(dev->lpt, FDC_LPT_IRQ & 0xf); - - prime3c_log("Prime3C-LPT: BASE %04x IRQ %02x\n", LPT_BASE_ADDRESS << 2, FDC_LPT_IRQ & 0xf); - } -} - -void -prime3c_ide_handler(prime3c_t *dev) -{ - ide_pri_disable(); - if (FUNCTION_SELECT & 0x20) { - ide_set_base(0, IDE_BASE_ADDRESS << 2); - ide_set_side(0, IDE_SIDE_ADDRESS << 2); - ide_pri_enable(); - prime3c_log("Prime3C-IDE: BASE %04x SIDE %04x\n", IDE_BASE_ADDRESS << 2, IDE_SIDE_ADDRESS << 2); - } -} - -void -prime3c_enable(prime3c_t *dev) -{ - /* - Simulate a device enable/disable scenario - - Register C2: Function Select - Bit 7: Gameport - Bit 6: Reserved - Bit 5: IDE - Bit 4: FDC - Bit 3: UART 2 - Bit 2: UART 1 - Bit 1/0: PIO (0/0 Unidirectional , 0/1 ECP, 1/0 EPP, 1/1 Disabled) - - Note: 86Box LPT is simplistic and can't do ECP or EPP. - */ - - !(FUNCTION_SELECT & 0x03) ? prime3c_lpt_handler(dev) : lpt_port_remove(dev->lpt); - (FUNCTION_SELECT & 0x04) ? prime3c_uart_handler(0, dev) : serial_remove(dev->uart[0]); - (FUNCTION_SELECT & 0x08) ? prime3c_uart_handler(1, dev) : serial_remove(dev->uart[1]); - (FUNCTION_SELECT & 0x10) ? prime3c_fdc_handler(dev) : fdc_remove(dev->fdc_controller); - if (HAS_IDE_FUNCTIONALITY) - (FUNCTION_SELECT & 0x20) ? prime3c_ide_handler(dev) : ide_pri_disable(); -} - -static void -prime3c_close(void *priv) -{ - prime3c_t *dev = (prime3c_t *) priv; - - free(dev); -} - -static void * -prime3c_init(const device_t *info) -{ - prime3c_t *dev = (prime3c_t *) calloc(1, sizeof(prime3c_t)); - - /* Avoid conflicting with machines that make no use of the Prime3C Internal IDE */ - HAS_IDE_FUNCTIONALITY = info->local; - - dev->regs[0xc0] = 0x3c; - dev->regs[0xc2] = 0x03; - dev->regs[0xc3] = 0x3c; - dev->regs[0xc4] = 0x3c; - dev->regs[0xc5] = 0x3d; - dev->regs[0xd5] = 0x3c; - - dev->fdc_controller = device_add(&fdc_at_device); - dev->uart[0] = device_add_inst(&ns16550_device, 1); - dev->uart[1] = device_add_inst(&ns16550_device, 2); - dev->lpt = device_add_inst(&lpt_port_device, 1); - if (HAS_IDE_FUNCTIONALITY) - device_add(&ide_isa_device); - - prime3c_fdc_handler(dev); - prime3c_uart_handler(0, dev); - prime3c_uart_handler(1, dev); - prime3c_lpt_handler(dev); - if (HAS_IDE_FUNCTIONALITY) - prime3c_ide_handler(dev); - - io_sethandler(0x0398, 0x0002, prime3c_read, NULL, NULL, prime3c_write, NULL, NULL, dev); - - return dev; -} - -const device_t prime3c_device = { - .name = "Goldstar Prime3C", - .internal_name = "prime3c", - .flags = 0, - .local = 0, - .init = prime3c_init, - .close = prime3c_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t prime3c_ide_device = { - .name = "Goldstar Prime3C with IDE functionality", - .internal_name = "prime3c_ide", - .flags = 0, - .local = 1, - .init = prime3c_init, - .close = prime3c_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; diff --git a/src/sio/sio_um8669f.c b/src/sio/sio_um8669f.c index 2ec934465..c42cdd1b6 100644 --- a/src/sio/sio_um8669f.c +++ b/src/sio/sio_um8669f.c @@ -92,7 +92,8 @@ static uint8_t um8669f_pnp_rom[] = { 0x15, 0x41, 0xd0, 0x04, 0x00, 0x01, /* logical device PNP0400, can participate in boot */ 0x22, 0xfa, 0x1f, /* IRQ 1/3/4/5/6/7/8/9/10/11/12 */ - 0x47, 0x00, 0x00, 0x01, 0xf8, 0x03, 0x08, 0x08, /* I/O 0x100-0x3F8, decodes 10-bit, 8-byte alignment, 8 addresses */ + 0x2a, 0x0f, 0x0c, /* DMA 0/1/2/3, compatibility, no count by word, count by byte, is bus master, 8-bit only */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0x0f, 0x08, 0x08, /* I/O 0x100-0x3F8, decodes 16-bit, 8-byte alignment, 8 addresses */ 0x15, 0x41, 0xd0, 0x06, 0x00, 0x01, /* logical device PNP0600, can participate in boot */ 0x22, 0xfa, 0x1f, /* IRQ 1/3/4/5/6/7/8/9/10/11/12 */ @@ -120,7 +121,8 @@ static const isapnp_device_config_t um8669f_pnp_defaults[] = { }, { .activate = 1, .io = { { .base = LPT1_ADDR }, }, - .irq = { { .irq = LPT1_IRQ }, } + .irq = { { .irq = LPT1_IRQ }, }, + .dma = { { .dma = 3 }, } }, { .activate = 0, .io = { { .base = 0x1f0 }, }, @@ -268,6 +270,9 @@ um8669f_write(uint16_t port, uint8_t val, void *priv) if (dev->cur_reg == 0xc1) { um8669f_log("UM8669F: ISAPnP %sabled\n", (val & 0x80) ? "en" : "dis"); isapnp_enable_card(dev->pnp_card, (val & 0x80) ? ISAPNP_CARD_FORCE_CONFIG : ISAPNP_CARD_DISABLE); + } else if (dev->cur_reg == 0xc0) { + lpt_set_epp(dev->lpt, val & 0x08); + lpt_set_ecp(dev->lpt, val & 0x10); } } } @@ -304,6 +309,9 @@ um8669f_reset(um8669f_t *dev) lpt_port_remove(dev->lpt); + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + if (dev->ide < IDE_BUS_MAX) ide_remove_handlers(dev->ide); @@ -341,8 +349,9 @@ um8669f_init(const device_t *info) dev->uart[1] = device_add_inst(&ns16550_device, 2); dev->lpt = device_add_inst(&lpt_port_device, 1); + lpt_set_ext(dev->lpt, 1); - dev->ide = info->local; + dev->ide = (uint8_t) (info->local - 1); if (dev->ide < IDE_BUS_MAX) device_add(&ide_isa_device); @@ -360,20 +369,6 @@ const device_t um8669f_device = { .name = "UMC UM8669F Super I/O", .internal_name = "um8669f", .flags = 0, - .local = 0xff, - .init = um8669f_init, - .close = um8669f_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t um8669f_ide_device = { - .name = "UMC UM8669F Super I/O (With IDE)", - .internal_name = "um8669f_ide", - .flags = 0, .local = 0, .init = um8669f_init, .close = um8669f_close, @@ -383,17 +378,3 @@ const device_t um8669f_ide_device = { .force_redraw = NULL, .config = NULL }; - -const device_t um8669f_ide_sec_device = { - .name = "UMC UM8669F Super I/O (With Secondary IDE)", - .internal_name = "um8669f_ide_sec", - .flags = 0, - .local = 1, - .init = um8669f_init, - .close = um8669f_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; diff --git a/src/sio/sio_um8663f.c b/src/sio/sio_um866x.c similarity index 51% rename from src/sio/sio_um8663f.c rename to src/sio/sio_um866x.c index f51810972..a90bee64d 100644 --- a/src/sio/sio_um8663f.c +++ b/src/sio/sio_um866x.c @@ -6,7 +6,8 @@ * * This file is part of the 86Box distribution. * - * Implementation of the UMC UMF8663F Super I/O chip. + * Implementation of the UMC UM82C862F, UM82C863F, UM86863F, + * and UM8663BF Super I/O chips. * * Authors: Miran Grca, * @@ -35,25 +36,25 @@ #include <86box/random.h> #include <86box/plat_unused.h> -#ifdef ENABLE_UM8663F_LOG -int um8663f_do_log = ENABLE_UM8663F_LOG; +#ifdef ENABLE_UM866X_LOG +int um866x_do_log = ENABLE_UM866X_LOG; static void -um8663f_log(const char *fmt, ...) +um866x_log(const char *fmt, ...) { va_list ap; - if (um8663f_do_log) { + if (um866x_do_log) { va_start(ap, fmt); pclog_ex(fmt, ap); va_end(ap); } } #else -# define um8663f_log(fmt, ...) +# define um866x_log(fmt, ...) #endif -typedef struct um8663f_t { +typedef struct um866x_t { uint8_t max_reg; uint8_t ide; uint8_t locked; @@ -64,10 +65,10 @@ typedef struct um8663f_t { serial_t *uart[2]; lpt_t * lpt; -} um8663f_t; +} um866x_t; static void -um8663f_fdc_handler(um8663f_t *dev) +um866x_fdc_handler(um866x_t *dev) { fdc_remove(dev->fdc); if (dev->regs[0] & 0x01) @@ -75,7 +76,7 @@ um8663f_fdc_handler(um8663f_t *dev) } static void -um8663f_uart_handler(um8663f_t *dev, int port) +um866x_uart_handler(um866x_t *dev, int port) { uint8_t shift = (port + 1); @@ -102,10 +103,32 @@ um8663f_uart_handler(um8663f_t *dev, int port) } static void -um8663f_lpt_handler(um8663f_t *dev) +um866x_lpt_handler(um866x_t *dev) { + int enabled = (dev->regs[0] & 0x08); + lpt_port_remove(dev->lpt); - if (dev->regs[0] & 0x08) { + switch(dev->regs[1] & 0xc0) { + case 0x00: + enabled = 0; + break; + case 0x40: + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + break; + case 0x80: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 1); + break; + case 0xc0: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + } + if (enabled) { switch ((dev->regs[1] >> 3) & 0x01) { case 0x01: lpt_port_setup(dev->lpt, LPT1_ADDR); @@ -123,7 +146,7 @@ um8663f_lpt_handler(um8663f_t *dev) } static void -um8663f_ide_handler(um8663f_t *dev) +um866x_ide_handler(um866x_t *dev) { int board = dev->ide - 1; @@ -137,12 +160,12 @@ um8663f_ide_handler(um8663f_t *dev) } static void -um8663f_write(uint16_t port, uint8_t val, void *priv) +um866x_write(uint16_t port, uint8_t val, void *priv) { - um8663f_t *dev = (um8663f_t *) priv; + um866x_t *dev = (um866x_t *) priv; uint8_t valxor; - um8663f_log("UM8663F: write(%04X, %02X)\n", port, val); + um866x_log("UM866X: write(%04X, %02X)\n", port, val); if (dev->locked) { if ((port == 0x108) && (val == 0xaa)) @@ -160,15 +183,15 @@ um8663f_write(uint16_t port, uint8_t val, void *priv) /* Port enable register. */ case 0x00: if (valxor & 0x10) - um8663f_ide_handler(dev); + um866x_ide_handler(dev); if (valxor & 0x08) - um8663f_lpt_handler(dev); + um866x_lpt_handler(dev); if (valxor & 0x04) - um8663f_uart_handler(dev, 1); + um866x_uart_handler(dev, 1); if (valxor & 0x02) - um8663f_uart_handler(dev, 0); + um866x_uart_handler(dev, 0); if (valxor & 0x01) - um8663f_fdc_handler(dev); + um866x_fdc_handler(dev); break; /* Port configuration register: @@ -184,16 +207,16 @@ um8663f_write(uint16_t port, uint8_t val, void *priv) - Bit 0 = 0 = FDC is 370h, 1 = UART 2 is 3f0h. */ case 0x01: + if (valxor & 0xc8) + um866x_lpt_handler(dev); if (valxor & 0x10) - um8663f_ide_handler(dev); - if (valxor & 0x08) - um8663f_lpt_handler(dev); + um866x_ide_handler(dev); if (valxor & 0x04) - um8663f_uart_handler(dev, 1); + um866x_uart_handler(dev, 1); if (valxor & 0x02) - um8663f_uart_handler(dev, 0); + um866x_uart_handler(dev, 0); if (valxor & 0x01) - um8663f_fdc_handler(dev); + um866x_fdc_handler(dev); break; } } @@ -201,9 +224,9 @@ um8663f_write(uint16_t port, uint8_t val, void *priv) } static uint8_t -um8663f_read(uint16_t port, void *priv) +um866x_read(uint16_t port, void *priv) { - const um8663f_t *dev = (um8663f_t *) priv; + const um866x_t *dev = (um866x_t *) priv; uint8_t ret = 0xff; if (!dev->locked) { @@ -216,15 +239,15 @@ um8663f_read(uint16_t port, void *priv) } } - um8663f_log("UM8663F: read(%04X) = %02X\n", port, ret); + um866x_log("UM866X: read(%04X) = %02X\n", port, ret); return ret; } static void -um8663f_reset(void *priv) +um866x_reset(void *priv) { - um8663f_t *dev = (um8663f_t *) priv; + um866x_t *dev = (um866x_t *) priv; serial_remove(dev->uart[0]); serial_setup(dev->uart[0], COM1_ADDR, COM1_IRQ); @@ -243,27 +266,27 @@ um8663f_reset(void *priv) dev->regs[0x00] = (dev->ide > 0) ? 0x1f : 0x0f; dev->regs[0x01] = (dev->ide == 2) ? 0x0f : 0x1f; - um8663f_fdc_handler(dev); - um8663f_uart_handler(dev, 0); - um8663f_uart_handler(dev, 1); - um8663f_lpt_handler(dev); - um8663f_ide_handler(dev); + um866x_fdc_handler(dev); + um866x_uart_handler(dev, 0); + um866x_uart_handler(dev, 1); + um866x_lpt_handler(dev); + um866x_ide_handler(dev); dev->locked = 1; } static void -um8663f_close(void *priv) +um866x_close(void *priv) { - um8663f_t *dev = (um8663f_t *) priv; + um866x_t *dev = (um866x_t *) priv; free(dev); } static void * -um8663f_init(UNUSED(const device_t *info)) +um866x_init(UNUSED(const device_t *info)) { - um8663f_t *dev = (um8663f_t *) calloc(1, sizeof(um8663f_t)); + um866x_t *dev = (um866x_t *) calloc(1, sizeof(um866x_t)); dev->fdc = device_add(&fdc_at_smc_device); @@ -279,147 +302,21 @@ um8663f_init(UNUSED(const device_t *info)) dev->max_reg = info->local >> 8; if (dev->max_reg != 0x00) - io_sethandler(0x0108, 0x0002, um8663f_read, NULL, NULL, um8663f_write, NULL, NULL, dev); + io_sethandler(0x0108, 0x0002, um866x_read, NULL, NULL, um866x_write, NULL, NULL, dev); - um8663f_reset(dev); + um866x_reset(dev); return dev; } -const device_t um82c862f_device = { - .name = "UMC UM82C862F Super I/O", - .internal_name = "um82c862f", +const device_t um866x_device = { + .name = "UMC UM82C86x/866x Super I/O", + .internal_name = "um866x", .flags = 0, - .local = 0x0000, - .init = um8663f_init, - .close = um8663f_close, - .reset = um8663f_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t um82c862f_ide_device = { - .name = "UMC UM82C862F Super I/O (With IDE)", - .internal_name = "um82c862f_ide", - .flags = 0, - .local = 0x0001, - .init = um8663f_init, - .close = um8663f_close, - .reset = um8663f_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t um82c863f_device = { - .name = "UMC UM82C863F Super I/O", - .internal_name = "um82c863f", - .flags = 0, - .local = 0xc100, - .init = um8663f_init, - .close = um8663f_close, - .reset = um8663f_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t um82c863f_ide_device = { - .name = "UMC UM82C863F Super I/O (With IDE)", - .internal_name = "um82c863f_ide", - .flags = 0, - .local = 0xc101, - .init = um8663f_init, - .close = um8663f_close, - .reset = um8663f_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t um8663af_device = { - .name = "UMC UM8663AF Super I/O", - .internal_name = "um8663af", - .flags = 0, - .local = 0xc300, - .init = um8663f_init, - .close = um8663f_close, - .reset = um8663f_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t um8663af_ide_device = { - .name = "UMC UM8663AF Super I/O (With IDE)", - .internal_name = "um8663af_ide", - .flags = 0, - .local = 0xc301, - .init = um8663f_init, - .close = um8663f_close, - .reset = um8663f_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t um8663af_ide_sec_device = { - .name = "UMC UM8663AF Super I/O (With Secondary IDE)", - .internal_name = "um8663af_ide_sec", - .flags = 0, - .local = 0xc302, - .init = um8663f_init, - .close = um8663f_close, - .reset = um8663f_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t um8663bf_device = { - .name = "UMC UM8663BF Super I/O", - .internal_name = "um8663bf", - .flags = 0, - .local = 0xc400, - .init = um8663f_init, - .close = um8663f_close, - .reset = um8663f_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t um8663bf_ide_device = { - .name = "UMC UM8663BF Super I/O (With IDE)", - .internal_name = "um8663bf_ide", - .flags = 0, - .local = 0xc401, - .init = um8663f_init, - .close = um8663f_close, - .reset = um8663f_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t um8663bf_ide_sec_device = { - .name = "UMC UM8663BF Super I/O (With Secondary IDE)", - .internal_name = "um8663bf_ide_sec", - .flags = 0, - .local = 0xc402, - .init = um8663f_init, - .close = um8663f_close, - .reset = um8663f_reset, + .local = 0, + .init = um866x_init, + .close = um866x_close, + .reset = um866x_reset, .available = NULL, .speed_changed = NULL, .force_redraw = NULL, diff --git a/src/sio/sio_vt82c686.c b/src/sio/sio_vt82c686.c index ec6c5d203..4caffbc00 100644 --- a/src/sio/sio_vt82c686.c +++ b/src/sio/sio_vt82c686.c @@ -86,14 +86,28 @@ vt82c686_lpt_handler(vt82c686_t *dev) lpt_port_remove(dev->lpt); + lpt_set_ext(dev->lpt, !!(dev->regs[0x10] & 0x80)); + + switch (dev->regs[0x10] & 0x03) { + case 0x01: + lpt_set_epp(dev->lpt, !!(dev->regs[0x10] & 0x20)); + lpt_set_ecp(dev->lpt, 1); + break; + case 0x02: + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, !!(dev->regs[0x10] & 0x20)); + break; + } + if (((dev->regs[0x02] & 0x03) != 0x03) && !(dev->regs[0x0f] & 0x11) && (io_base >= 0x100) && (io_base <= io_mask)) lpt_port_setup(dev->lpt, io_base); - if (dev->lpt_irq) { + if (dev->lpt_irq) lpt_port_irq(dev->lpt, dev->lpt_irq); - } else { + else lpt_port_irq(dev->lpt, 0xff); - } + + lpt_port_dma(dev->lpt, dev->lpt_dma); } static void @@ -178,6 +192,7 @@ vt82c686_write(uint16_t port, uint8_t val, void *priv) case 0x10: dev->regs[reg] &= 0xf4; + vt82c686_lpt_handler(dev); break; case 0x11: diff --git a/src/sio/sio_w83787f.c b/src/sio/sio_w83787f.c deleted file mode 100644 index 285d88232..000000000 --- a/src/sio/sio_w83787f.c +++ /dev/null @@ -1,539 +0,0 @@ -/* - * 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. - * - * Emulation of the Winbond W83787F/IF Super I/O Chip. - * - * Winbond W83787F Super I/O Chip - * Used by the Award 430HX - * - * - * - * Authors: Miran Grca, - * Copyright 2020 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/io.h> -#include <86box/timer.h> -#include <86box/mem.h> -#include <86box/lpt.h> -#include <86box/serial.h> -#include <86box/fdd.h> -#include <86box/fdc.h> -#include <86box/hdc.h> -#include <86box/hdc_ide.h> -#include <86box/gameport.h> -#include <86box/sio.h> - -#ifdef ENABLE_W83787_LOG -int w83787_do_log = ENABLE_W83787_LOG; - -static void -w83787_log(const char *fmt, ...) -{ - va_list ap; - - if (w83787_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define w83787_log(fmt, ...) -#endif - -#define FDDA_TYPE (dev->regs[7] & 3) -#define FDDB_TYPE ((dev->regs[7] >> 2) & 3) -#define FDDC_TYPE ((dev->regs[7] >> 4) & 3) -#define FDDD_TYPE ((dev->regs[7] >> 6) & 3) - -#define FD_BOOT (dev->regs[8] & 3) -#define SWWP ((dev->regs[8] >> 4) & 1) -#define DISFDDWR ((dev->regs[8] >> 5) & 1) - -#define EN3MODE ((dev->regs[9] >> 5) & 1) - -#define DRV2EN_NEG (dev->regs[0xB] & 1) /* 0 = drive 2 installed */ -#define INVERTZ ((dev->regs[0xB] >> 1) & 1) /* 0 = invert DENSEL polarity */ -#define IDENT ((dev->regs[0xB] >> 3) & 1) - -#define HEFERE ((dev->regs[0xC] >> 5) & 1) - -#define HAS_IDE_FUNCTIONALITY dev->ide_function - -typedef struct w83787f_t { - uint8_t tries; - uint8_t regs[42]; - uint16_t reg_init; - int locked; - int rw_locked; - int cur_reg; - int key; - int ide_function; - int ide_start; - fdc_t *fdc; - serial_t *uart[2]; - lpt_t *lpt; - void *gameport; -} w83787f_t; - -static void w83787f_write(uint16_t port, uint8_t val, void *priv); -static uint8_t w83787f_read(uint16_t port, void *priv); - -static void -w83787f_remap(w83787f_t *dev) -{ - io_removehandler(0x250, 0x0004, - w83787f_read, NULL, NULL, w83787f_write, NULL, NULL, dev); - io_sethandler(0x250, 0x0004, - w83787f_read, NULL, NULL, w83787f_write, NULL, NULL, dev); - dev->key = 0x88 | HEFERE; -} - -#ifdef FIXME -/* FIXME: Implement EPP (and ECP) parallel port modes. */ -static uint8_t -get_lpt_length(w83787f_t *dev) -{ - uint8_t length = 4; - - if (dev->regs[9] & 0x80) { - if (dev->regs[0] & 0x04) - length = 8; /* EPP mode. */ - if (dev->regs[0] & 0x08) - length |= 0x80; /* ECP mode. */ - } - - return length; -} -#endif - -static void -w83787f_serial_handler(w83787f_t *dev, int uart) -{ - int urs0 = !!(dev->regs[1] & (1 << uart)); - int urs1 = !!(dev->regs[1] & (4 << uart)); - int urs2 = !!(dev->regs[3] & (8 >> uart)); - int urs; - int irq = COM1_IRQ; - uint16_t addr = COM1_ADDR; - uint16_t enable = 1; - - urs = (urs1 << 1) | urs0; - - if (urs2) { - addr = uart ? COM1_ADDR : COM2_ADDR; - irq = uart ? COM1_IRQ : COM2_IRQ; - } else { - switch (urs) { - case 0: - addr = uart ? COM3_ADDR : COM4_ADDR; - irq = uart ? COM3_IRQ : COM4_IRQ; - break; - case 1: - addr = uart ? COM4_ADDR : COM3_ADDR; - irq = uart ? COM4_IRQ : COM3_IRQ; - break; - case 2: - addr = uart ? COM2_ADDR : COM1_ADDR; - irq = uart ? COM2_IRQ : COM1_IRQ; - break; - case 3: - default: - enable = 0; - break; - } - } - - if (dev->regs[4] & (0x20 >> uart)) - enable = 0; - - serial_remove(dev->uart[uart]); - if (enable) - serial_setup(dev->uart[uart], addr, irq); -} - -static void -w83787f_lpt_handler(w83787f_t *dev) -{ - int ptras = (dev->regs[1] >> 4) & 0x03; - int irq = LPT1_IRQ; - uint16_t addr = LPT1_ADDR; - uint16_t enable = 1; - - switch (ptras) { - case 0x00: - addr = LPT_MDA_ADDR; - irq = LPT_MDA_IRQ; - break; - case 0x01: - addr = LPT2_ADDR; - irq = LPT2_IRQ; - break; - case 0x02: - addr = LPT1_ADDR; - irq = LPT1_IRQ; - break; - case 0x03: - default: - enable = 0; - break; - } - - if (dev->regs[4] & 0x80) - enable = 0; - - lpt_port_remove(dev->lpt); - if (enable) { - lpt_port_setup(dev->lpt, addr); - lpt_port_irq(dev->lpt, irq); - } -} - -static void -w83787f_gameport_handler(w83787f_t *dev) -{ - if (!(dev->regs[3] & 0x40) && !(dev->regs[4] & 0x40)) - gameport_remap(dev->gameport, 0x201); - else - gameport_remap(dev->gameport, 0); -} - -static void -w83787f_fdc_handler(w83787f_t *dev) -{ - fdc_remove(dev->fdc); - if (!(dev->regs[0] & 0x20)) - fdc_set_base(dev->fdc, (dev->regs[0] & 0x10) ? FDC_PRIMARY_ADDR : FDC_SECONDARY_ADDR); - fdc_set_power_down(dev->fdc, !!(dev->regs[6] & 0x08)); -} - -static void -w83787f_ide_handler(w83787f_t *dev) -{ - if (dev->ide_function & 0x20) { - ide_sec_disable(); - if (!(dev->regs[0] & 0x80)) { - ide_set_base(1, (dev->regs[0] & 0x40) ? 0x1f0 : 0x170); - ide_set_side(1, (dev->regs[0] & 0x40) ? 0x3f6 : 0x376); - ide_sec_enable(); - } - } else { - ide_pri_disable(); - if (!(dev->regs[0] & 0x80)) { - ide_set_base(0, (dev->regs[0] & 0x40) ? 0x1f0 : 0x170); - ide_set_side(0, (dev->regs[0] & 0x40) ? 0x3f6 : 0x376); - ide_pri_enable(); - } - } -} - -static void -w83787f_write(uint16_t port, uint8_t val, void *priv) -{ - w83787f_t *dev = (w83787f_t *) priv; - uint8_t valxor = 0; - uint8_t max = 0x15; - - if (port == 0x250) { - if (val == dev->key) - dev->locked = 1; - else - dev->locked = 0; - return; - } else if (port == 0x251) { - if (val <= max) - dev->cur_reg = val; - return; - } else { - if (dev->locked) { - if (dev->rw_locked && (dev->cur_reg <= 0x0b)) - return; - if (dev->cur_reg == 6) - val &= 0xFB; - valxor = val ^ dev->regs[dev->cur_reg]; - dev->regs[dev->cur_reg] = val; - } else - return; - } - - switch (dev->cur_reg) { - case 0: - w83787_log("REG 00: %02X\n", val); - if ((valxor & 0xc0) && (HAS_IDE_FUNCTIONALITY)) - w83787f_ide_handler(dev); - if (valxor & 0x30) - w83787f_fdc_handler(dev); - if (valxor & 0x0c) - w83787f_lpt_handler(dev); - break; - case 1: - if (valxor & 0x80) - fdc_set_swap(dev->fdc, (dev->regs[1] & 0x80) ? 1 : 0); - if (valxor & 0x30) - w83787f_lpt_handler(dev); - if (valxor & 0x0a) - w83787f_serial_handler(dev, 1); - if (valxor & 0x05) - w83787f_serial_handler(dev, 0); - break; - case 3: - if (valxor & 0x80) - w83787f_lpt_handler(dev); - if (valxor & 0x40) - w83787f_gameport_handler(dev); - if (valxor & 0x08) - w83787f_serial_handler(dev, 0); - if (valxor & 0x04) - w83787f_serial_handler(dev, 1); - break; - case 4: - if (valxor & 0x10) - w83787f_serial_handler(dev, 1); - if (valxor & 0x20) - w83787f_serial_handler(dev, 0); - if (valxor & 0x80) - w83787f_lpt_handler(dev); - if (valxor & 0x40) - w83787f_gameport_handler(dev); - break; - case 6: - if (valxor & 0x08) - w83787f_fdc_handler(dev); - break; - case 7: - if (valxor & 0x03) - fdc_update_rwc(dev->fdc, 0, FDDA_TYPE); - if (valxor & 0x0c) - fdc_update_rwc(dev->fdc, 1, FDDB_TYPE); - if (valxor & 0x30) - fdc_update_rwc(dev->fdc, 2, FDDC_TYPE); - if (valxor & 0xc0) - fdc_update_rwc(dev->fdc, 3, FDDD_TYPE); - break; - case 8: - if (valxor & 0x03) - fdc_update_boot_drive(dev->fdc, FD_BOOT); - if (valxor & 0x10) - fdc_set_swwp(dev->fdc, SWWP ? 1 : 0); - if (valxor & 0x20) - fdc_set_diswr(dev->fdc, DISFDDWR ? 1 : 0); - break; - case 9: - if (valxor & 0x20) - fdc_update_enh_mode(dev->fdc, EN3MODE ? 1 : 0); - if (valxor & 0x40) - dev->rw_locked = (val & 0x40) ? 1 : 0; - if (valxor & 0x80) - w83787f_lpt_handler(dev); - break; - case 0xB: - w83787_log("Writing %02X to CRB\n", val); - break; - case 0xC: - if (valxor & 0x20) - w83787f_remap(dev); - break; - - default: - break; - } -} - -static uint8_t -w83787f_read(uint16_t port, void *priv) -{ - w83787f_t *dev = (w83787f_t *) priv; - uint8_t ret = 0xff; - - if (dev->locked) { - if (port == 0x251) - ret = dev->cur_reg; - else if (port == 0x252) { - if (dev->cur_reg == 7) - ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2)); - else if (!dev->rw_locked || (dev->cur_reg > 0x0b)) - ret = dev->regs[dev->cur_reg]; - } - } - - return ret; -} - -static void -w83787f_reset(w83787f_t *dev) -{ - uint16_t hefere = dev->reg_init & 0x0100; - - lpt_port_remove(dev->lpt); - lpt_port_setup(dev->lpt, LPT1_ADDR); - lpt_port_irq(dev->lpt, LPT1_IRQ); - - memset(dev->regs, 0, 0x2A); - - if (HAS_IDE_FUNCTIONALITY) { - if (dev->ide_function & 0x20) { - dev->regs[0x00] = 0x90; - ide_sec_disable(); - ide_set_base(1, 0x170); - ide_set_side(1, 0x376); - } else { - dev->regs[0x00] = 0xd0; - ide_pri_disable(); - ide_set_base(0, 0x1f0); - ide_set_side(0, 0x3f6); - } - - if (dev->ide_start) { - dev->regs[0x00] &= 0x7f; - if (dev->ide_function & 0x20) - ide_sec_enable(); - else - ide_pri_enable(); - } - } else - dev->regs[0x00] = 0xd0; - - fdc_reset(dev->fdc); - w83787f_fdc_handler(dev); - - dev->regs[0x01] = 0x2C; - dev->regs[0x03] = 0x70; - dev->regs[0x07] = 0xF5; - dev->regs[0x09] = dev->reg_init & 0xff; - dev->regs[0x0a] = 0x1F; - dev->regs[0x0c] = 0x0C | (hefere >> 3); - dev->regs[0x0d] = 0xA3; - - gameport_remap(dev->gameport, 0); - - serial_setup(dev->uart[0], COM1_ADDR, COM1_IRQ); - serial_setup(dev->uart[1], COM2_ADDR, COM2_IRQ); - - w83787f_lpt_handler(dev); - - dev->key = 0x88 | (hefere >> 8); - - w83787f_remap(dev); - - dev->locked = 0; - dev->rw_locked = 0; -} - -static void -w83787f_close(void *priv) -{ - w83787f_t *dev = (w83787f_t *) priv; - - free(dev); -} - -static void * -w83787f_init(const device_t *info) -{ - w83787f_t *dev = (w83787f_t *) calloc(1, sizeof(w83787f_t)); - - HAS_IDE_FUNCTIONALITY = (info->local & 0x30); - - dev->fdc = device_add(&fdc_at_winbond_device); - - dev->uart[0] = device_add_inst(&ns16550_device, 1); - dev->uart[1] = device_add_inst(&ns16550_device, 2); - - dev->lpt = device_add_inst(&lpt_port_device, 1); - - dev->gameport = gameport_add(&gameport_sio_1io_device); - - if ((dev->ide_function & 0x30) == 0x10) - device_add(&ide_isa_device); - - dev->ide_start = !!(info->local & 0x40); - - dev->reg_init = info->local & 0x010f; - w83787f_reset(dev); - - return dev; -} - -const device_t w83787f_88h_device = { - .name = "Winbond W83787F/IF Super I/O", - .internal_name = "w83787f", - .flags = 0, - .local = 0x0009, - .init = w83787f_init, - .close = w83787f_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t w83787f_device = { - .name = "Winbond W83787F/IF Super I/O", - .internal_name = "w83787f", - .flags = 0, - .local = 0x0109, - .init = w83787f_init, - .close = w83787f_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t w83787f_ide_device = { - .name = "Winbond W83787F/IF Super I/O (With IDE)", - .internal_name = "w83787f_ide", - .flags = 0, - .local = 0x0119, - .init = w83787f_init, - .close = w83787f_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t w83787f_ide_en_device = { - .name = "Winbond W83787F/IF Super I/O (With IDE Enabled)", - .internal_name = "w83787f_ide_en", - .flags = 0, - .local = 0x0159, - .init = w83787f_init, - .close = w83787f_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t w83787f_ide_sec_device = { - .name = "Winbond W83787F/IF Super I/O (With Secondary IDE)", - .internal_name = "w83787f_ide_sec", - .flags = 0, - .local = 0x0139, - .init = w83787f_init, - .close = w83787f_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; diff --git a/src/sio/sio_w837x7.c b/src/sio/sio_w837x7.c new file mode 100644 index 000000000..e670d8454 --- /dev/null +++ b/src/sio/sio_w837x7.c @@ -0,0 +1,475 @@ +/* + * 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. + * + * Emulation of the Winbond W837x7F/IF Super I/O Chip. + * + * Authors: Miran Grca, + * Copyright 2020-2025 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/mem.h> +#include <86box/lpt.h> +#include <86box/serial.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/gameport.h> +#include <86box/sio.h> + +#define FDDA_TYPE (dev->regs[7] & 3) +#define FDDB_TYPE ((dev->regs[7] >> 2) & 3) +#define FDDC_TYPE ((dev->regs[7] >> 4) & 3) +#define FDDD_TYPE ((dev->regs[7] >> 6) & 3) + +#define FD_BOOT (dev->regs[8] & 3) +#define SWWP ((dev->regs[8] >> 4) & 1) +#define DISFDDWR ((dev->regs[8] >> 5) & 1) + +#define EN3MODE ((dev->regs[9] >> 5) & 1) + +#define DRV2EN_NEG (dev->regs[0xB] & 1) /* 0 = drive 2 installed */ +#define INVERTZ ((dev->regs[0xB] >> 1) & 1) /* 0 = invert DENSEL polarity */ +#define IDENT ((dev->regs[0xB] >> 3) & 1) + +#define HEFERE ((dev->regs[0xC] >> 5) & 1) + +typedef struct w837x7_t { + uint8_t tries; + uint8_t has_ide; + uint8_t type; + uint8_t hefere; + uint8_t max_reg; + uint8_t regs[256]; + int locked; + int rw_locked; + int cur_reg; + int key; + int ide_start; + fdc_t *fdc; + serial_t *uart[2]; + lpt_t *lpt; + void *gameport; +} w837x7_t; + +#ifdef ENABLE_W837X7_LOG +int w837x7_do_log = ENABLE_W837X7_LOG; + +static void +w837x7_log(const char *fmt, ...) +{ + va_list ap; + + if (w837x7_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define w837x7_log(fmt, ...) +#endif + +static void +w837x7_serial_handler(w837x7_t *dev, int uart) +{ + int urs0 = !!(dev->regs[0x01] & (0x01 << uart)); + int urs1 = !!(dev->regs[0x01] & (0x04 << uart)); + int urs2 = !!(dev->regs[0x03] & (0x08 >> uart)); + int urs; + int irq = COM1_IRQ; + uint16_t addr = COM1_ADDR; + uint16_t enable = 1; + double clock_src = 24000000.0 / 13.0; + + if (dev->regs[0x03] & (1 << (1 - uart))) + clock_src = 24000000.0 / 12.0; + + urs = (urs1 << 1) | urs0; + + if (urs2) { + addr = uart ? COM1_ADDR : COM2_ADDR; + irq = uart ? COM1_IRQ : COM2_IRQ; + } else { + switch (urs) { + case 0x00: + addr = uart ? COM3_ADDR : COM4_ADDR; + irq = uart ? COM3_IRQ : COM4_IRQ; + break; + case 0x01: + addr = uart ? COM4_ADDR : COM3_ADDR; + irq = uart ? COM4_IRQ : COM3_IRQ; + break; + case 0x02: + addr = uart ? COM2_ADDR : COM1_ADDR; + irq = uart ? COM2_IRQ : COM1_IRQ; + break; + case 0x03: + default: + enable = 0; + break; + } + } + + if (dev->regs[0x04] & (0x20 >> uart)) + enable = 0; + + serial_remove(dev->uart[uart]); + if (enable) + serial_setup(dev->uart[uart], addr, irq); + + serial_set_clock_src(dev->uart[uart], clock_src); +} + +static void +w837x7_lpt_handler(w837x7_t *dev) +{ + int ptras = (dev->regs[1] >> 4) & 0x03; + uint16_t lpt_port = 0x0000; + uint16_t mask = 0xfffc; + uint8_t local_enable = 1; + uint8_t lpt_irq = LPT1_IRQ; + uint8_t lpt_mode = (dev->regs[0x09] & 0x80) | (dev->regs[0x00] & 0x0c); + + switch (ptras) { + case 0x01: + lpt_port = LPT_MDA_ADDR; + lpt_irq = LPT_MDA_IRQ; + break; + case 0x02: + lpt_port = LPT1_ADDR; + lpt_irq = LPT1_IRQ /*LPT2_IRQ*/; + break; + case 0x03: + lpt_port = LPT2_ADDR; + lpt_irq = LPT1_IRQ /*LPT2_IRQ*/; + break; + + default: + local_enable = 0; + break; + } + + if (dev->regs[0x04] & 0x80) + local_enable = 0; + + if (lpt_irq > 15) + lpt_irq = 0xff; + + lpt_port_remove(dev->lpt); + lpt_set_fifo_threshold(dev->lpt, dev->regs[0x05] & 0x0f); + switch (lpt_mode) { + default: + local_enable = 0; + break; + case 0x00: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 1); + break; + case 0x84: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + break; + case 0x88: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + case 0x8c: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + } + + if (local_enable && (lpt_port >= 0x0100) && (lpt_port <= (0x0ffc & mask))) + lpt_port_setup(dev->lpt, lpt_port); + + lpt_port_irq(dev->lpt, lpt_irq); +} + +static void +w837x7_gameport_handler(w837x7_t *dev) +{ + if (!(dev->regs[3] & 0x40) && !(dev->regs[4] & 0x40)) + gameport_remap(dev->gameport, 0x201); + else + gameport_remap(dev->gameport, 0); +} + +static void +w837x7_fdc_handler(w837x7_t *dev) +{ + fdc_remove(dev->fdc); + if (!(dev->regs[0] & 0x20)) + fdc_set_base(dev->fdc, (dev->regs[0] & 0x10) ? FDC_PRIMARY_ADDR : FDC_SECONDARY_ADDR); + fdc_set_power_down(dev->fdc, !!(dev->regs[6] & 0x08)); +} + +static void +w837x7_ide_handler(w837x7_t *dev) +{ + if (dev->has_ide > 0) { + int ide_id = dev->has_ide - 1; + + ide_handlers(ide_id, 0); + + ide_set_base_addr(ide_id, 0, (dev->regs[0x00] & 0x40) ? 0x0170 : 0x01f0); + ide_set_base_addr(ide_id, 1, (dev->regs[0x00] & 0x40) ? 0x0376 : 0x03f6); + + if (!(dev->regs[0x00] & 0x80)) + ide_handlers(ide_id, 1); + } +} + +static void +w837x7_write(uint16_t port, uint8_t val, void *priv) +{ + w837x7_t *dev = (w837x7_t *) priv; + uint8_t valxor = 0; + + if (port == 0x0250) { + if (val == dev->key) + dev->locked = 1; + else + dev->locked = 0; + return; + } else if (port == 0x0251) { + dev->cur_reg = val; + return; + } else { + if (dev->locked) { + if (dev->rw_locked && (dev->cur_reg <= 0x0b)) + return; + valxor = val ^ dev->regs[dev->cur_reg]; + dev->regs[dev->cur_reg] = val; + } else + return; + } + + if (dev->cur_reg <= dev->max_reg) switch (dev->cur_reg) { + case 0x00: + w837x7_log("REG 00: %02X\n", val); + if (valxor & 0xc0) + w837x7_ide_handler(dev); + if (valxor & 0x30) + w837x7_fdc_handler(dev); + if (valxor & 0x0c) + w837x7_lpt_handler(dev); + break; + case 0x01: + if (valxor & 0x80) + fdc_set_swap(dev->fdc, (dev->regs[1] & 0x80) ? 1 : 0); + if (valxor & 0x30) + w837x7_lpt_handler(dev); + if (valxor & 0x0a) + w837x7_serial_handler(dev, 1); + if (valxor & 0x05) + w837x7_serial_handler(dev, 0); + break; + case 0x03: + if (valxor & 0x80) + w837x7_lpt_handler(dev); + if (valxor & 0x40) + w837x7_gameport_handler(dev); + if (valxor & 0x0a) + w837x7_serial_handler(dev, 0); + if (valxor & 0x05) + w837x7_serial_handler(dev, 1); + break; + case 0x04: + if (valxor & 0x10) + w837x7_serial_handler(dev, 1); + if (valxor & 0x20) + w837x7_serial_handler(dev, 0); + if (valxor & 0x80) + w837x7_lpt_handler(dev); + if (valxor & 0x40) + w837x7_gameport_handler(dev); + break; + case 0x05: + if (valxor & 0x0f) + w837x7_lpt_handler(dev); + break; + case 0x06: + if (valxor & 0x08) + w837x7_fdc_handler(dev); + break; + case 0x07: + if (valxor & 0x03) + fdc_update_rwc(dev->fdc, 0, FDDA_TYPE); + if (valxor & 0x0c) + fdc_update_rwc(dev->fdc, 1, FDDB_TYPE); + if (valxor & 0x30) + fdc_update_rwc(dev->fdc, 2, FDDC_TYPE); + if (valxor & 0xc0) + fdc_update_rwc(dev->fdc, 3, FDDD_TYPE); + break; + case 0x08: + if (valxor & 0x03) + fdc_update_boot_drive(dev->fdc, FD_BOOT); + if (valxor & 0x10) + fdc_set_swwp(dev->fdc, SWWP ? 1 : 0); + if (valxor & 0x20) + fdc_set_diswr(dev->fdc, DISFDDWR ? 1 : 0); + break; + case 0x09: + if (valxor & 0x20) + fdc_update_enh_mode(dev->fdc, EN3MODE ? 1 : 0); + if (valxor & 0x40) + dev->rw_locked = (val & 0x40) ? 1 : 0; + if (valxor & 0x80) + w837x7_lpt_handler(dev); + break; + case 0x0b: + if ((valxor & 0x0c) && (dev->type == W83777F)) { + fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA); + switch (val & 0x0c) { + case 0x00: + fdc_set_flags(dev->fdc, FDC_FLAG_PS2); + break; + case 0x04: + fdc_set_flags(dev->fdc, FDC_FLAG_PS2_MCA); + break; + } + } + break; + case 0x0c: + if (dev->type == W83787IF) + dev->key = 0x88 | HEFERE; + break; + + default: + break; + } +} + +static uint8_t +w837x7_read(uint16_t port, void *priv) +{ + w837x7_t *dev = (w837x7_t *) priv; + uint8_t ret = 0xff; + + if (dev->locked) { + if (port == 0x0251) + ret = dev->cur_reg; + else if (port == 0x0252) { + if (dev->cur_reg == 7) + ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2)); + else if (!dev->rw_locked || (dev->cur_reg > 0x0b)) + ret = dev->regs[dev->cur_reg]; + } + } + + return ret; +} + +static void +w837x7_reset(w837x7_t *dev) +{ + memset(dev->regs, 0x00, dev->max_reg + 1); + + if (dev->has_ide == 0x02) + dev->regs[0x00] = 0x90; + else if (dev->has_ide == 0x01) + dev->regs[0x00] = 0xd0; + + if (dev->ide_start) + dev->regs[0x00] &= 0x7f; + + dev->regs[0x01] = 0x2c; + dev->regs[0x03] = 0x30; + dev->regs[0x09] = dev->type; + dev->regs[0x0a] = 0x1f; + + if (dev->type == W83787IF) { + dev->regs[0x0c] = 0x0c | dev->hefere; + dev->regs[0x0d] = 0x03; + } else + dev->regs[0x0c] = dev->hefere; + + dev->key = 0x88 | HEFERE; + + fdc_reset(dev->fdc); + fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA); + + w837x7_fdc_handler(dev); + + w837x7_lpt_handler(dev); + w837x7_serial_handler(dev, 0); + w837x7_serial_handler(dev, 0); + w837x7_gameport_handler(dev); + w837x7_ide_handler(dev); + + dev->locked = 0; + dev->rw_locked = 0; +} + +static void +w837x7_close(void *priv) +{ + w837x7_t *dev = (w837x7_t *) priv; + + free(dev); +} + +static void * +w837x7_init(const device_t *info) +{ + w837x7_t *dev = (w837x7_t *) calloc(1, sizeof(w837x7_t)); + + dev->type = info->local & 0x0f; + dev->hefere = info->local & W837X7_KEY_89; + dev->max_reg = (dev->type == W83787IF) ? 0x15 : ((dev->type == W83787F) ? 0x0a : 0x0b); + dev->has_ide = (info->local >> 16) & 0xff; + dev->ide_start = !!(info->local & W837X7_IDE_START); + + dev->fdc = device_add(&fdc_at_winbond_device); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + dev->lpt = device_add_inst(&lpt_port_device, 1); + + dev->gameport = gameport_add(&gameport_sio_1io_device); + + w837x7_reset(dev); + + io_sethandler(0x250, 0x0004, + w837x7_read, NULL, NULL, w837x7_write, NULL, NULL, dev); + + return dev; +} + +const device_t w837x7_device = { + .name = "Winbond W837x7 Super I/O", + .internal_name = "w837x7", + .flags = 0, + .local = 0, + .init = w837x7_init, + .close = w837x7_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sio/sio_w83877f.c b/src/sio/sio_w83877.c similarity index 50% rename from src/sio/sio_w83877f.c rename to src/sio/sio_w83877.c index ef5ccc284..419abb9f6 100644 --- a/src/sio/sio_w83877f.c +++ b/src/sio/sio_w83877.c @@ -6,15 +6,10 @@ * * This file is part of the 86Box distribution. * - * Emulation of the Winbond W83877F Super I/O Chip. - * - * Winbond W83877F Super I/O Chip - * Used by the Award 430HX - * - * + * Emulation of the Winbond W83877 family of Super I/O Chips. * * Authors: Miran Grca, - * Copyright 2016-2020 Miran Grca. + * Copyright 2016-2025 Miran Grca. */ #include #include @@ -30,35 +25,41 @@ #include <86box/rom.h> #include <86box/lpt.h> #include <86box/serial.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/machine.h> #include <86box/sio.h> -#define FDDA_TYPE (dev->regs[7] & 3) -#define FDDB_TYPE ((dev->regs[7] >> 2) & 3) -#define FDDC_TYPE ((dev->regs[7] >> 4) & 3) -#define FDDD_TYPE ((dev->regs[7] >> 6) & 3) +#define FDDA_TYPE (dev->regs[0x07] & 3) +#define FDDB_TYPE ((dev->regs[0x07] >> 2) & 3) +#define FDDC_TYPE ((dev->regs[0x07] >> 4) & 3) +#define FDDD_TYPE ((dev->regs[0x07] >> 6) & 3) -#define FD_BOOT (dev->regs[8] & 3) -#define SWWP ((dev->regs[8] >> 4) & 1) -#define DISFDDWR ((dev->regs[8] >> 5) & 1) +#define FD_BOOT (dev->regs[0x08] & 3) +#define SWWP ((dev->regs[0x08] >> 4) & 1) +#define DISFDDWR ((dev->regs[0x08] >> 5) & 1) -#define EN3MODE ((dev->regs[9] >> 5) & 1) +#define EN3MODE ((dev->regs[0x09] >> 5) & 1) -#define DRV2EN_NEG (dev->regs[0xB] & 1) /* 0 = drive 2 installed */ -#define INVERTZ ((dev->regs[0xB] >> 1) & 1) /* 0 = invert DENSEL polarity */ -#define IDENT ((dev->regs[0xB] >> 3) & 1) +#define DRV2EN_NEG (dev->regs[0x0b] & 1) /* 0 = drive 2 installed */ +#define INVERTZ ((dev->regs[0x0b] >> 1) & 1) /* 0 = invert DENSEL polarity */ +#define IDENT ((dev->regs[0x0b] >> 3) & 1) -#define HEFERE ((dev->regs[0xC] >> 5) & 1) +#define HEFERE ((dev->regs[0x0c] >> 5) & 1) #define HEFRAS (dev->regs[0x16] & 1) #define PRTIQS (dev->regs[0x27] & 0x0f) #define ECPIRQ ((dev->regs[0x27] >> 5) & 0x07) -typedef struct w83877f_t { +typedef struct w83877_t { uint8_t tries; - uint8_t regs[42]; + uint8_t has_ide; + uint8_t dma_map[4]; + uint8_t irq_map[10]; + uint8_t regs[256]; uint16_t reg_init; int locked; int rw_locked; @@ -69,36 +70,36 @@ typedef struct w83877f_t { fdc_t *fdc; serial_t *uart[2]; lpt_t *lpt; -} w83877f_t; +} w83877_t; -static void w83877f_write(uint16_t port, uint8_t val, void *priv); -static uint8_t w83877f_read(uint16_t port, void *priv); +static void w83877_write(uint16_t port, uint8_t val, void *priv); +static uint8_t w83877_read(uint16_t port, void *priv); static void -w83877f_remap(w83877f_t *dev) +w83877_remap(w83877_t *dev) { uint8_t hefras = HEFRAS; io_removehandler(0x250, 0x0003, - w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev); + w83877_read, NULL, NULL, w83877_write, NULL, NULL, dev); io_removehandler(FDC_PRIMARY_ADDR, 0x0002, - w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev); + w83877_read, NULL, NULL, w83877_write, NULL, NULL, dev); dev->base_address = (hefras ? FDC_PRIMARY_ADDR : 0x250); io_sethandler(dev->base_address, hefras ? 0x0002 : 0x0003, - w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev); + w83877_read, NULL, NULL, w83877_write, NULL, NULL, dev); dev->key_times = hefras + 1; dev->key = (hefras ? 0x86 : 0x88) | HEFERE; } static uint8_t -get_lpt_length(w83877f_t *dev) +get_lpt_length(w83877_t *dev) { uint8_t length = 4; - if (dev->regs[9] & 0x80) { - if (dev->regs[0] & 0x04) + if (dev->regs[0x09] & 0x80) { + if (dev->regs[0x00] & 0x04) length = 8; /* EPP mode. */ - if (dev->regs[0] & 0x08) + if (dev->regs[0x00] & 0x08) length |= 0x80; /* ECP mode. */ } @@ -106,7 +107,7 @@ get_lpt_length(w83877f_t *dev) } static uint16_t -make_port(w83877f_t *dev, uint8_t reg) +make_port(w83877_t *dev, uint8_t reg) { uint16_t p = 0; uint8_t l; @@ -114,34 +115,31 @@ make_port(w83877f_t *dev, uint8_t reg) switch (reg) { case 0x20: p = ((uint16_t) (dev->regs[reg] & 0xfc)) << 2; - p &= 0xFF0; - if ((p < 0x100) || (p > 0x3F0)) - p = 0x3F0; + p &= 0x0ff0; + if ((p < 0x0100) || (p > 0x03f0)) + p = 0x03f0; break; case 0x23: l = get_lpt_length(dev); p = ((uint16_t) (dev->regs[reg] & 0xff)) << 2; /* 8 ports in EPP mode, 4 in non-EPP mode. */ if ((l & 0x0f) == 8) - p &= 0x3F8; + p &= 0x03f8; else - p &= 0x3FC; - if ((p < 0x100) || (p > 0x3FF)) + p &= 0x03fc; + if ((p < 0x0100) || (p > 0x03ff)) p = LPT1_ADDR; - /* In ECP mode, A10 is active. */ - if (l & 0x80) - p |= 0x400; break; case 0x24: p = ((uint16_t) (dev->regs[reg] & 0xfe)) << 2; - p &= 0xFF8; - if ((p < 0x100) || (p > 0x3F8)) + p &= 0x0ff8; + if ((p < 0x0100) || (p > 0x03f8)) p = COM1_ADDR; break; case 0x25: p = ((uint16_t) (dev->regs[reg] & 0xfe)) << 2; - p &= 0xFF8; - if ((p < 0x100) || (p > 0x3F8)) + p &= 0x0ff8; + if ((p < 0x0100) || (p > 0x03f8)) p = COM2_ADDR; break; @@ -153,35 +151,60 @@ make_port(w83877f_t *dev, uint8_t reg) } static void -w83877f_fdc_handler(w83877f_t *dev) +w83877_ide_handler(w83877_t *dev) +{ + uint16_t ide_port = 0x0000; + + if (dev->has_ide > 0) { + int ide_id = dev->has_ide - 1; + + ide_handlers(ide_id, 0); + + ide_port = (dev->regs[0x21] << 2) & 0xfff0; + ide_set_base_addr(ide_id, 0, ide_port); + + ide_port = ((dev->regs[0x22] << 2) & 0xfff0) | 0x0006; + ide_set_base_addr(ide_id, 1, ide_port); + + if (!(dev->regs[0x06] & 0x04)) + ide_handlers(ide_id, 1); + } +} + +static void +w83877_fdc_handler(w83877_t *dev) { fdc_remove(dev->fdc); - if (dev->regs[0x20] & 0xc0) + if (!(dev->regs[0x06] & 0x08) && (dev->regs[0x20] & 0xc0)) fdc_set_base(dev->fdc, make_port(dev, 0x20)); - fdc_set_power_down(dev->fdc, !!(dev->regs[6] & 0x08)); + fdc_set_irq(dev->fdc, dev->irq_map[dev->regs[0x29] >> 4]); + fdc_set_dma_ch(dev->fdc, dev->dma_map[(dev->regs[0x26] >> 4) & 0x03]); + fdc_set_power_down(dev->fdc, !!(dev->regs[0x06] & 0x08)); } static void -w83877f_lpt_handler(w83877f_t *dev) +w83877_lpt_handler(w83877_t *dev) { - uint8_t lpt_irq; - uint8_t lpt_irqs[8] = { 0, 7, 9, 10, 11, 14, 15, 5 }; + const uint8_t lpt_irq = dev->irq_map[PRTIQS]; lpt_port_remove(dev->lpt); - if (!(dev->regs[4] & 0x80) && (dev->regs[0x23] & 0xc0)) + + lpt_set_ext(dev->lpt, 1); + + lpt_set_epp(dev->lpt, (dev->regs[0x09] & 0x80) && (dev->regs[0x00] & 0x04)); + lpt_set_ecp(dev->lpt, (dev->regs[0x09] & 0x80) && (dev->regs[0x00] & 0x08)); + + lpt_set_fifo_threshold(dev->lpt, dev->regs[0x05] & 0x0f); + + if (!(dev->regs[0x04] & 0x80) && (dev->regs[0x23] & 0xc0)) lpt_port_setup(dev->lpt, make_port(dev, 0x23)); - lpt_irq = 0xff; - - lpt_irq = lpt_irqs[ECPIRQ]; - if (lpt_irq == 0) - lpt_irq = PRTIQS; - lpt_port_irq(dev->lpt, lpt_irq); + lpt_port_dma(dev->lpt, dev->dma_map[dev->regs[0x26] & 0x03]); } static void -w83877f_serial_handler(w83877f_t *dev, int uart) +w83877_serial_handler(w83877_t *dev, int uart) { int reg_mask = uart ? 0x10 : 0x20; int reg_id = uart ? 0x25 : 0x24; @@ -191,7 +214,7 @@ w83877f_serial_handler(w83877f_t *dev, int uart) serial_remove(dev->uart[uart]); if (!(dev->regs[4] & reg_mask) && (dev->regs[reg_id] & 0xc0)) - serial_setup(dev->uart[uart], make_port(dev, reg_id), (dev->regs[0x28] & irq_mask) >> irq_shift); + serial_setup(dev->uart[uart], make_port(dev, reg_id), dev->irq_map[(dev->regs[0x28] & irq_mask) >> irq_shift]); if (dev->regs[0x19] & (0x02 >> uart)) { clock_src = 14769000.0; @@ -205,21 +228,19 @@ w83877f_serial_handler(w83877f_t *dev, int uart) } static void -w83877f_write(uint16_t port, uint8_t val, void *priv) +w83877_write(uint16_t port, uint8_t val, void *priv) { - w83877f_t *dev = (w83877f_t *) priv; + w83877_t *dev = (w83877_t *) priv; uint8_t valxor = 0; - uint8_t max = 0x2A; - if (port == 0x250) { + if (port == 0x0250) { if (val == dev->key) dev->locked = 1; else dev->locked = 0; return; - } else if (port == 0x251) { - if (val <= max) - dev->cur_reg = val; + } else if (port == 0x0251) { + dev->cur_reg = val; return; } else if (port == FDC_PRIMARY_ADDR) { if ((val == dev->key) && !dev->locked) { @@ -235,8 +256,8 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) } } else { if (dev->locked) { - if (val < max) - dev->cur_reg = val; + dev->cur_reg = val; + if (val == 0xaa) dev->locked = 0; } else { @@ -245,16 +266,10 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) } } return; - } else if ((port == 0x252) || (port == 0x3f1)) { + } else if ((port == 0x0252) || (port == 0x03f1)) { if (dev->locked) { if (dev->rw_locked) return; - if ((dev->cur_reg >= 0x26) && (dev->cur_reg <= 0x27)) - return; - if (dev->cur_reg == 0x29) - return; - if (dev->cur_reg == 6) - val &= 0xFB; valxor = val ^ dev->regs[dev->cur_reg]; dev->regs[dev->cur_reg] = val; } else @@ -262,33 +277,39 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) } switch (dev->cur_reg) { - case 0: + case 0x00: if (valxor & 0x0c) - w83877f_lpt_handler(dev); + w83877_lpt_handler(dev); break; - case 1: + case 0x01: if (valxor & 0x80) - fdc_set_swap(dev->fdc, (dev->regs[1] & 0x80) ? 1 : 0); + fdc_set_swap(dev->fdc, (dev->regs[0x01] & 0x80) ? 1 : 0); break; - case 3: + case 0x03: if (valxor & 0x02) - w83877f_serial_handler(dev, 0); + w83877_serial_handler(dev, 0); if (valxor & 0x01) - w83877f_serial_handler(dev, 1); + w83877_serial_handler(dev, 1); break; - case 4: + case 0x04: if (valxor & 0x10) - w83877f_serial_handler(dev, 1); + w83877_serial_handler(dev, 1); if (valxor & 0x20) - w83877f_serial_handler(dev, 0); + w83877_serial_handler(dev, 0); if (valxor & 0x80) - w83877f_lpt_handler(dev); + w83877_lpt_handler(dev); break; - case 6: + case 0x05: + if (valxor & 0x0f) + w83877_lpt_handler(dev); + break; + case 0x06: if (valxor & 0x08) - w83877f_fdc_handler(dev); + w83877_fdc_handler(dev); + if (valxor & 0x04) + w83877_ide_handler(dev); break; - case 7: + case 0x07: if (valxor & 0x03) fdc_update_rwc(dev->fdc, 0, FDDA_TYPE); if (valxor & 0x0c) @@ -298,7 +319,7 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) if (valxor & 0xc0) fdc_update_rwc(dev->fdc, 3, FDDD_TYPE); break; - case 8: + case 0x08: if (valxor & 0x03) fdc_update_boot_drive(dev->fdc, FD_BOOT); if (valxor & 0x10) @@ -306,66 +327,106 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) if (valxor & 0x20) fdc_set_diswr(dev->fdc, DISFDDWR ? 1 : 0); break; - case 9: + case 0x09: if (valxor & 0x20) fdc_update_enh_mode(dev->fdc, EN3MODE ? 1 : 0); if (valxor & 0x40) dev->rw_locked = (val & 0x40) ? 1 : 0; if (valxor & 0x80) - w83877f_lpt_handler(dev); + w83877_lpt_handler(dev); break; - case 0xB: - if (valxor & 1) - fdc_update_drv2en(dev->fdc, DRV2EN_NEG ? 0 : 1); - if (valxor & 2) + case 0x0b: + if (valxor & 0x0c) { + fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA); + switch (val & 0x0c) { + case 0x00: + fdc_set_flags(dev->fdc, FDC_FLAG_PS2); + break; + case 0x04: + fdc_set_flags(dev->fdc, FDC_FLAG_PS2_MCA); + break; + } + } + if (valxor & 0x02) fdc_update_densel_polarity(dev->fdc, INVERTZ ? 1 : 0); + if (valxor & 0x01) + fdc_update_drv2en(dev->fdc, DRV2EN_NEG ? 0 : 1); break; - case 0xC: + case 0x0c: if (valxor & 0x20) - w83877f_remap(dev); + w83877_remap(dev); break; case 0x16: - if (valxor & 1) - w83877f_remap(dev); + if (valxor & 0x02) { + dev->regs[0x1e] = (val & 0x02) ? 0x81 : 0x00; + dev->regs[0x20] = (val & 0x02) ? 0xfc : 0x00; + dev->regs[0x21] = (val & 0x02) ? 0x7c : 0x00; + dev->regs[0x22] = (val & 0x02) ? 0xfd : 0x00; + dev->regs[0x23] = (val & 0x02) ? 0xde : 0x00; + dev->regs[0x24] = (val & 0x02) ? 0xfe : 0x00; + dev->regs[0x25] = (val & 0x02) ? 0xbe : 0x00; + dev->regs[0x26] = (val & 0x02) ? 0x23 : 0x00; + dev->regs[0x27] = (val & 0x02) ? 0x65 : 0x00; + dev->regs[0x28] = (val & 0x02) ? 0x43 : 0x00; + dev->regs[0x29] = (val & 0x02) ? 0x62 : 0x00; + w83877_fdc_handler(dev); + w83877_lpt_handler(dev); + w83877_serial_handler(dev, 0); + w83877_serial_handler(dev, 1); + } + if (valxor & 0x01) + w83877_remap(dev); break; case 0x19: if (valxor & 0x02) - w83877f_serial_handler(dev, 0); + w83877_serial_handler(dev, 0); if (valxor & 0x01) - w83877f_serial_handler(dev, 1); + w83877_serial_handler(dev, 1); break; case 0x20: if (valxor) - w83877f_fdc_handler(dev); + w83877_fdc_handler(dev); + break; + case 0x21: case 0x22: + if (valxor) + w83877_ide_handler(dev); break; case 0x23: if (valxor) - w83877f_lpt_handler(dev); + w83877_lpt_handler(dev); break; case 0x24: if (valxor & 0xfe) - w83877f_serial_handler(dev, 0); + w83877_serial_handler(dev, 0); break; case 0x25: if (valxor & 0xfe) - w83877f_serial_handler(dev, 1); + w83877_serial_handler(dev, 1); + break; + case 0x26: + if (valxor & 0x0f) + w83877_lpt_handler(dev); break; case 0x27: if (valxor & 0xef) - w83877f_lpt_handler(dev); + w83877_lpt_handler(dev); break; case 0x28: - if (valxor & 0xf) { + if (valxor & 0x0f) { if ((dev->regs[0x28] & 0x0f) == 0) dev->regs[0x28] |= 0x03; - w83877f_serial_handler(dev, 1); + w83877_serial_handler(dev, 1); } if (valxor & 0xf0) { if ((dev->regs[0x28] & 0xf0) == 0) dev->regs[0x28] |= 0x40; - w83877f_serial_handler(dev, 0); + w83877_serial_handler(dev, 0); } break; + case 0x29: + if (valxor & 0xf0) + w83877_fdc_handler(dev); + break; default: break; @@ -373,9 +434,9 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) } static uint8_t -w83877f_read(uint16_t port, void *priv) +w83877_read(uint16_t port, void *priv) { - w83877f_t *dev = (w83877f_t *) priv; + w83877_t *dev = (w83877_t *) priv; uint8_t ret = 0xff; if (dev->locked) { @@ -393,7 +454,7 @@ w83877f_read(uint16_t port, void *priv) } static void -w83877f_reset(w83877f_t *dev) +w83877_reset(w83877_t *dev) { fdc_reset(dev->fdc); @@ -405,47 +466,40 @@ w83877f_reset(w83877f_t *dev) dev->regs[0x0c] = 0x28; dev->regs[0x0d] = 0xA3; dev->regs[0x16] = dev->reg_init & 0xff; - dev->regs[0x1e] = 0x81; - dev->regs[0x20] = (FDC_PRIMARY_ADDR >> 2) & 0xfc; - dev->regs[0x21] = (0x1f0 >> 2) & 0xfc; - dev->regs[0x22] = ((0x3f6 >> 2) & 0xfc) | 1; - dev->regs[0x23] = (LPT1_ADDR >> 2); - dev->regs[0x24] = (COM1_ADDR >> 2) & 0xfe; - dev->regs[0x25] = (COM2_ADDR >> 2) & 0xfe; - dev->regs[0x26] = (2 << 4) | 4; - dev->regs[0x27] = (2 << 4) | 5; - dev->regs[0x28] = (4 << 4) | 3; - dev->regs[0x29] = 0x62; - w83877f_fdc_handler(dev); + w83877_fdc_handler(dev); + fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA); - w83877f_lpt_handler(dev); + w83877_lpt_handler(dev); - w83877f_serial_handler(dev, 0); - w83877f_serial_handler(dev, 1); + w83877_serial_handler(dev, 0); + w83877_serial_handler(dev, 1); + + if (dev->has_ide) + w83877_ide_handler(dev); dev->base_address = FDC_PRIMARY_ADDR; dev->key = 0x89; dev->key_times = 1; - w83877f_remap(dev); + w83877_remap(dev); dev->locked = 0; dev->rw_locked = 0; } static void -w83877f_close(void *priv) +w83877_close(void *priv) { - w83877f_t *dev = (w83877f_t *) priv; + w83877_t *dev = (w83877_t *) priv; free(dev); } static void * -w83877f_init(const device_t *info) +w83877_init(const device_t *info) { - w83877f_t *dev = (w83877f_t *) calloc(1, sizeof(w83877f_t)); + w83877_t *dev = (w83877_t *) calloc(1, sizeof(w83877_t)); dev->fdc = device_add(&fdc_at_winbond_device); @@ -456,60 +510,40 @@ w83877f_init(const device_t *info) dev->reg_init = info->local; - w83877f_reset(dev); + dev->has_ide = (info->local >> 16) & 0xff; + + if (!strcmp(machine_get_internal_name(), "ficpa2012")) { + dev->dma_map[0] = 4; + dev->dma_map[1] = 3; + dev->dma_map[2] = 1; + dev->dma_map[3] = 2; + } else { + dev->dma_map[0] = 4; + for (int i = 1; i < 4; i++) + dev->dma_map[i] = i; + } + + memset(dev->irq_map, 0xff, 16); + dev->irq_map[0] = 0xff; + for (int i = 1; i < 7; i++) + dev->irq_map[i] = i; + dev->irq_map[1] = 5; + dev->irq_map[5] = 7; + dev->irq_map[7] = 9; /* Guesswork, I can't find a single BIOS that lets me assign IRQ_G to something. */ + dev->irq_map[8] = 10; + + w83877_reset(dev); return dev; } -const device_t w83877f_device = { +const device_t w83877_device = { .name = "Winbond W83877F Super I/O", - .internal_name = "w83877f", + .internal_name = "w83877", .flags = 0, - .local = 0x0a05, - .init = w83877f_init, - .close = w83877f_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t w83877f_president_device = { - .name = "Winbond W83877F Super I/O (President)", - .internal_name = "w83877f_president", - .flags = 0, - .local = 0x0a04, - .init = w83877f_init, - .close = w83877f_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t w83877tf_device = { - .name = "Winbond W83877TF Super I/O", - .internal_name = "w83877tf", - .flags = 0, - .local = 0x0c04, - .init = w83877f_init, - .close = w83877f_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t w83877tf_acorp_device = { - .name = "Winbond W83877TF Super I/O", - .internal_name = "w83877tf_acorp", - .flags = 0, - .local = 0x0c05, - .init = w83877f_init, - .close = w83877f_close, + .local = 0, + .init = w83877_init, + .close = w83877_close, .reset = NULL, .available = NULL, .speed_changed = NULL, diff --git a/src/sio/sio_w83977.c b/src/sio/sio_w83977.c new file mode 100644 index 000000000..62d456aff --- /dev/null +++ b/src/sio/sio_w83977.c @@ -0,0 +1,1340 @@ +/* + * 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 Winbond W83977 Super I/O Chips. + * + * Authors: Miran Grca, + * + * Copyright 2025 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/lpt.h> +#include <86box/serial.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/keyboard.h> +#include <86box/machine.h> +#include <86box/nvr.h> +#include <86box/apm.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/video.h> +#include <86box/sio.h> +#include "cpu.h" + +typedef struct w83977_gpio_t { + uint8_t id; + uint8_t reg; + uint8_t pulldn; + uint8_t pad; + + uint8_t alt[4]; + + uint16_t base; + + void * parent; +} w83977_gpio_t; + +typedef struct w83977_t { + uint8_t id; + uint8_t hefras; + uint8_t has_nvr; + uint8_t tries; + uint8_t lockreg; + uint8_t gpio_reg; + uint8_t regs[48]; + uint8_t ld_regs[11][256]; + uint16_t kbc_type; + uint16_t superio_base; + uint16_t fdc_base; + uint16_t lpt_base; + uint16_t nvr_base; + uint16_t kbc_base[2]; + uint16_t gpio_base; /* Set to EA */ + uint16_t uart_base[2]; + int locked; + int cur_reg; + uint32_t type; + w83977_gpio_t gpio[3]; + fdc_t *fdc; + nvr_t *nvr; + void *kbc; + serial_t *uart[2]; + lpt_t *lpt; +} w83977_t; + +static int next_id = 0; + +static void w83977_write(uint16_t port, uint8_t val, void *priv); +static uint8_t w83977_read(uint16_t port, void *priv); + +static uint16_t +make_port(const w83977_t *dev, const uint8_t ld) +{ + const uint16_t r0 = dev->ld_regs[ld][0x60]; + const uint16_t r1 = dev->ld_regs[ld][0x61]; + + const uint16_t p = (r0 << 8) + r1; + + return p; +} + +static uint16_t +make_port_sec(const w83977_t *dev, const uint8_t ld) +{ + const uint16_t r0 = dev->ld_regs[ld][0x62]; + const uint16_t r1 = dev->ld_regs[ld][0x63]; + + const uint16_t p = (r0 << 8) + r1; + + return p; +} + +static __inline uint8_t +w83977_do_read_gp(w83977_gpio_t *dev, int reg, int bit) +{ + return dev->reg & dev->pulldn & (1 << bit); +} + +static __inline uint8_t +w83977_do_read_alt(const w83977_gpio_t *dev, int alt, int reg, int bit) +{ + return dev->alt[alt] & (1 << bit); +} + +static uint8_t +w83977_read_gp(const w83977_gpio_t *dev, int bit) +{ + uint8_t reg = dev->id; + w83977_t *sio = (w83977_t *) dev->parent; + uint8_t gp_func_reg = sio->ld_regs[0x07 + reg - 1][0xe0 + ((((reg - 1) << 3) + bit) & 0x0f)]; + uint8_t gp_func; + uint8_t ret = 1 << bit; + + if (gp_func_reg & 0x01) switch (reg) { + default: + /* Do nothing, this GP does not exist. */ + break; + case 1: + switch (bit) { + default: + gp_func = (gp_func_reg >> 3) & 0x03; + if (gp_func == 0x00) + ret = w83977_do_read_gp((w83977_gpio_t *) dev, reg - 1, bit); + else + ret = w83977_do_read_alt(dev, gp_func - 1, reg - 1, bit); + break; + case 0: case 1: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x00) + ret = w83977_do_read_gp((w83977_gpio_t *) dev, reg - 1, bit); + else + ret = w83977_do_read_alt(dev, 0, reg - 1, bit); + break; + case 4: + gp_func = (gp_func_reg >> 3) & 0x03; + if (gp_func == 0x00) + ret = w83977_do_read_gp((w83977_gpio_t *) dev, reg - 1, bit); + else if (gp_func == 0x02) + ret = kbc_at_read_p(sio->kbc, 1, 0x80) ? (1 << bit) : 0x00; + else + ret = w83977_do_read_alt(dev, gp_func - 1, reg - 1, bit); + break; + } + break; + case 2: + switch (bit) { + default: + break; + case 0: + gp_func = (gp_func_reg >> 3) & 0x03; + if (gp_func == 0x00) + ret = w83977_do_read_gp((w83977_gpio_t *) dev, reg - 1, bit); + else if (gp_func == 0x02) + ret = kbc_at_read_p(sio->kbc, 2, 0x01) ? (1 << bit) : 0x00; + else + ret = w83977_do_read_alt(dev, gp_func - 1, reg - 1, bit); + break; + case 1 ... 4: + gp_func = (gp_func_reg >> 3) & 0x03; + if (gp_func == 0x00) + ret = w83977_do_read_gp((w83977_gpio_t *) dev, reg - 1, bit); + else if (gp_func == 0x02) + ret = kbc_at_read_p(sio->kbc, 1, 1 << (bit + 2)) ? (1 << bit) : 0x00; + else + ret = w83977_do_read_alt(dev, gp_func - 1, reg - 1, bit); + break; + case 5: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x00) + ret = w83977_do_read_gp((w83977_gpio_t *) dev, reg, bit); + else + ret = kbc_at_read_p(sio->kbc, 2, 0x02) ? (1 << bit) : 0x00; + break; + case 6: case 7: + /* Do nothing, these bits do not exist. */ + break; + } + break; + case 3: + if (sio->type == W83977TF) switch (bit) { + default: + break; + case 0 ... 4: + gp_func = (gp_func_reg >> 3) & 0x03; + if (gp_func == 0x00) + ret = w83977_do_read_gp((w83977_gpio_t *) dev, reg - 1, bit); + else + ret = w83977_do_read_alt(dev, gp_func - 1, reg - 1, bit); + break; + case 5 ... 7: + /* Do nothing, these bits have no function. */ + break; + } + break; + } + + if (gp_func_reg & 0x02) + ret ^= (1 << bit); + + return ret; +} + +static __inline void +w83977_do_write_gp(w83977_gpio_t *dev, int reg, int bit, int set) +{ + dev->reg = (dev->reg & ~(1 << bit)) | (set << bit); +} + +static __inline void +w83977_do_write_alt(w83977_gpio_t *dev, int alt, int reg, int bit, int set) +{ + dev->alt[alt] = (dev->alt[alt] & ~(1 << bit)) | (set << bit); +} + +static void +w83977_write_gp(w83977_gpio_t *dev, int bit, int set) +{ + uint8_t reg = dev->id; + w83977_t *sio = (w83977_t *) dev->parent; + uint8_t gp_func_reg = sio->ld_regs[0x07 + reg - 1][0xe0 + ((((reg - 1) << 3) + bit) & 0x0f)]; + uint8_t gp_func; + + if (gp_func_reg & 0x02) + set = !set; + + if (!(gp_func_reg & 0x01)) switch (reg) { + default: + /* Do nothing, this GP does not exist. */ + break; + case 1: + switch (bit) { + default: + gp_func = (gp_func_reg >> 3) & 0x03; + if (gp_func == 0x00) + w83977_do_write_gp(dev, reg - 1, bit, set); + else + w83977_do_write_alt(dev, gp_func - 1, reg - 1, bit, set); + break; + case 0: case 1: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x00) + w83977_do_write_gp(dev, reg - 1, bit, set); + else + w83977_do_write_alt(dev, 0, reg - 1, bit, set); + break; + case 4: + gp_func = (gp_func_reg >> 3) & 0x03; + if (gp_func == 0x00) + w83977_do_write_gp(dev, reg - 1, bit, set); + else if (gp_func == 0x02) + kbc_at_write_p(sio->kbc, 1, 0x7f, set << 7); + else + w83977_do_write_alt(dev, gp_func - 1, reg - 1, bit, set); + break; + } + break; + case 2: + switch (bit) { + default: + break; + case 0: + gp_func = (gp_func_reg >> 3) & 0x03; + if (gp_func == 0x00) + w83977_do_write_gp(dev, reg - 1, bit, set); + else if (gp_func == 0x02) + kbc_at_write_p(sio->kbc, 2, 0xfe, set); + else + w83977_do_write_alt(dev, gp_func - 1, reg - 1, bit, set); + break; + case 1 ... 4: + gp_func = (gp_func_reg >> 3) & 0x03; + if (gp_func == 0x00) + w83977_do_write_gp(dev, reg - 1, bit, set); + else if (gp_func == 0x02) + kbc_at_write_p(sio->kbc, 1, ~(1 << (bit + 2)), set << (bit + 2)); + else + w83977_do_write_alt(dev, gp_func - 1, reg - 1, bit, set); + break; + case 5: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x00) + w83977_do_write_gp(dev, reg - 1, bit, set); + else + kbc_at_write_p(sio->kbc, 2, 0xfd, set << 1); + break; + case 6: case 7: + /* Do nothing, these bits do not exist. */ + break; + } + break; + case 3: + if (sio->type == W83977TF) switch (bit) { + default: + break; + case 0 ... 4: + gp_func = (gp_func_reg >> 3) & 0x03; + if (gp_func == 0x00) + w83977_do_write_gp(dev, reg - 1, bit, set); + else + w83977_do_write_alt(dev, gp_func - 1, reg - 1, bit, set); + break; + case 5 ... 7: + /* Do nothing, these bits have no function. */ + break; + } + break; + } +} + +static uint8_t +w83977_gpio_read(uint16_t port, void *priv) +{ + const w83977_gpio_t *dev = (w83977_gpio_t *) priv; + uint8_t ret = 0x00; + + for (uint8_t i = 0; i < 8; i++) + ret |= w83977_read_gp(dev, i); + + return ret; +} + +static void +w83977_gpio_write(uint16_t port, uint8_t val, void *priv) +{ + w83977_gpio_t *dev = (w83977_gpio_t *) priv; + + for (uint8_t i = 0; i < 8; i++) + w83977_write_gp(dev, i, val & (1 << i)); +} + +static void +w83977_superio_handler(w83977_t *dev) +{ + if (dev->superio_base != 0x0000) + io_removehandler(dev->superio_base, 0x0002, + w83977_read, NULL, NULL, w83977_write, NULL, NULL, dev); + + dev->superio_base = (dev->regs[0x26] & 0x40) ? 0x0370 : 0x03f0; + + io_sethandler(dev->superio_base, 0x0002, + w83977_read, NULL, NULL, w83977_write, NULL, NULL, dev); +} + +static void +w83977_fdc_handler(w83977_t *dev) +{ + const uint8_t global_enable = !!(dev->regs[0x22] & (1 << 0)); + const uint8_t local_enable = !!dev->ld_regs[0][0x30]; + const uint16_t old_base = dev->fdc_base; + + dev->fdc_base = 0x0000; + + if (global_enable && local_enable) + dev->fdc_base = make_port(dev, 0) & 0xfff8; + + if (dev->fdc_base != old_base) { + if ((dev->id != 1) && (old_base >= 0x0100) && (old_base <= 0x0ff8)) + fdc_remove(dev->fdc); + + if ((dev->id != 1) && (dev->fdc_base >= 0x0100) && (dev->fdc_base <= 0x0ff8)) + fdc_set_base(dev->fdc, dev->fdc_base); + } +} + +static void +w83977_lpt_handler(w83977_t *dev) +{ + uint16_t ld_port = 0x0000; + uint16_t mask = 0xfffc; + uint8_t global_enable = !!(dev->regs[0x22] & (1 << 3)); + uint8_t local_enable = !!dev->ld_regs[1][0x30]; + uint8_t lpt_irq = dev->ld_regs[1][0x70]; + uint8_t lpt_dma = dev->ld_regs[1][0x74]; + uint8_t lpt_mode = dev->ld_regs[1][0xf0] & 0x07; + + if (lpt_irq > 15) + lpt_irq = 0xff; + + if (lpt_dma >= 4) + lpt_dma = 0xff; + + lpt_port_remove(dev->lpt); + lpt_set_fifo_threshold(dev->lpt, (dev->ld_regs[1][0xf0] & 0x78) >> 3); + switch (lpt_mode) { + default: + case 0x04: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + break; + case 0x00: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 1); + break; + case 0x01: case 0x05: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + break; + case 0x02: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + case 0x03: case 0x07: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + } + if (global_enable && local_enable) { + ld_port = (make_port(dev, 1) & 0xfffc) & mask; + if ((ld_port >= 0x0100) && (ld_port <= (0x0ffc & mask))) + lpt_port_setup(dev->lpt, ld_port); + } + lpt_port_irq(dev->lpt, lpt_irq); + lpt_port_dma(dev->lpt, lpt_dma); +} + +static void +w83977_serial_handler(w83977_t *dev, const int uart) +{ + const uint8_t uart_no = 2 + uart; + const uint8_t global_enable = !!(dev->regs[0x22] & (1 << uart_no)); + const uint8_t local_enable = !!dev->ld_regs[uart_no][0x30]; + const uint16_t old_base = dev->uart_base[uart]; + double clock_src = 24000000.0 / 13.0; + + dev->uart_base[uart] = 0x0000; + + if (global_enable && local_enable) + dev->uart_base[uart] = make_port(dev, uart_no) & 0xfff8; + + if (dev->uart_base[uart] != old_base) { + if ((old_base >= 0x0100) && (old_base <= 0x0ff8)) + serial_remove(dev->uart[uart]); + + if ((dev->uart_base[uart] >= 0x0100) && (dev->uart_base[uart] <= 0x0ff8)) + serial_setup(dev->uart[uart], dev->uart_base[uart], dev->ld_regs[uart_no][0x70]); + } + + switch (dev->ld_regs[uart_no][0xf0] & 0x03) { + case 0x00: + clock_src = 24000000.0 / 13.0; + break; + case 0x01: + clock_src = 24000000.0 / 12.0; + break; + case 0x02: + clock_src = 24000000.0 / 1.0; + break; + case 0x03: + clock_src = 24000000.0 / 1.625; + break; + + default: + break; + } + + serial_set_clock_src(dev->uart[uart], clock_src); + + serial_irq(dev->uart[uart], dev->ld_regs[uart_no][0x70]); +} + +static void +w83977_nvr_handler(w83977_t *dev) +{ + uint8_t local_enable = !!dev->ld_regs[6][0x30]; + const uint16_t old_base = dev->nvr_base; + + local_enable &= (((dev->ld_regs[6][0xf0] & 0xe0) == 0x80) || + ((dev->ld_regs[6][0xf0] & 0xe0) == 0xe0)); + + dev->nvr_base = 0x0000; + + if (local_enable) + dev->nvr_base = make_port(dev, 6) & 0xfffe; + + if (dev->nvr_base != old_base) { + if ((dev->id != 1) && dev->has_nvr && (old_base > 0x0000) && (old_base <= 0x0ffe)) + nvr_at_handler(0, dev->nvr_base, dev->nvr); + + if ((dev->id != 1) && dev->has_nvr && (dev->nvr_base > 0x0000) && (dev->nvr_base <= 0x0ffe)) + nvr_at_handler(1, dev->nvr_base, dev->nvr); + } +} + +static void +w83977_kbc_handler(w83977_t *dev) +{ + const uint8_t local_enable = !!dev->ld_regs[5][0x30]; + const uint16_t old_base = dev->kbc_base[0]; + const uint16_t old_base2 = dev->kbc_base[1]; + + dev->kbc_base[0] = dev->kbc_base[1] = 0x0000; + + if (local_enable) { + dev->kbc_base[0] = make_port(dev, 5); + dev->kbc_base[1] = make_port_sec(dev, 5); + } + + if (dev->kbc_base[0] != old_base) { + if ((dev->id != 1) && (dev->kbc != NULL) && (old_base >= 0x0100) && (old_base <= 0x0ff8)) + kbc_at_port_handler(0, 0, old_base, dev->kbc); + + if ((dev->id != 1) && (dev->kbc != NULL) && (dev->kbc_base[0] >= 0x0100) && (dev->kbc_base[0] <= 0x0ff8)) + kbc_at_port_handler(0, 1, dev->kbc_base[0], dev->kbc); + } + + if (dev->kbc_base[1] != old_base2) { + if ((dev->id != 1) && (dev->kbc != NULL) && (old_base2 >= 0x0100) && (old_base2 <= 0x0ff8)) + kbc_at_port_handler(1, 0, old_base2, dev->kbc); + + if ((dev->id != 1) && (dev->kbc != NULL) && (dev->kbc_base[1] >= 0x0100) && (dev->kbc_base[1] <= 0x0ff8)) + kbc_at_port_handler(1, 1, dev->kbc_base[1], dev->kbc); + } + + if ((dev->id != 1) && (dev->kbc != NULL)) { + kbc_at_set_irq(0, dev->ld_regs[5][0x70], dev->kbc); + kbc_at_set_irq(1, dev->ld_regs[5][0x72], dev->kbc); + } +} + +static void +w83977_gpio_handler(w83977_t *dev, const int gpio) +{ + const uint8_t gpio_no = 7 + gpio; + const uint8_t local_enable = !!dev->ld_regs[gpio_no][0x30]; + const uint16_t old_base = dev->gpio[gpio].base; + + dev->gpio[gpio].base = 0x0000; + + if (local_enable) + dev->gpio[gpio].base = make_port(dev, gpio_no) & 0xfff8; + + if (dev->gpio[gpio].base != old_base) { + if ((old_base >= 0x0100) && (old_base <= 0x0ff8)) + io_removehandler(old_base, 0x0002, + w83977_gpio_read, NULL, NULL, w83977_gpio_write, NULL, NULL, dev); + + if ((dev->gpio[gpio].base >= 0x0100) && (dev->gpio[gpio].base <= 0x0ff8)) + io_sethandler(dev->gpio[gpio].base, 0x0002, + w83977_gpio_read, NULL, NULL, w83977_gpio_write, NULL, NULL, dev); + } +} + +static void +w83977_state_change(w83977_t *dev, const uint8_t locked) +{ + dev->locked = locked; + + if (dev->id != 1) + fdc_3f1_enable(dev->fdc, !locked); +} + +static void +w83977_write(uint16_t port, uint8_t val, void *priv) +{ + w83977_t *dev = (w83977_t *) priv; + uint8_t index = !(port & 1); + uint8_t valxor; + + if (index) { + if ((val == 0x87) && !dev->locked) { + if (dev->tries) { + w83977_state_change(dev, 1); + dev->tries = 0; + } else + dev->tries++; + } else if (dev->locked) { + if (val == 0xaa) + w83977_state_change(dev, 0); + else + dev->cur_reg = val; + } else if (dev->tries) + dev->tries = 0; + } else if (dev->locked && !dev->lockreg) { + if (dev->cur_reg < 0x30) { + valxor = val ^ dev->regs[dev->cur_reg]; + + switch (dev->cur_reg) { + case 0x02: + dev->regs[dev->cur_reg] = val; + if (val == 0x02) + w83977_state_change(dev, 0); + break; + case 0x07: + case 0x2c ... 0x2f: + dev->regs[dev->cur_reg] = val; + break; + case 0x22: + if (dev->type == W83977F) + dev->regs[dev->cur_reg] = val & 0x3d; + else + dev->regs[dev->cur_reg] = val & 0x39; + + if (valxor & 0x01) + w83977_fdc_handler(dev); + if (valxor & 0x08) + w83977_lpt_handler(dev); + if (valxor & 0x10) + w83977_serial_handler(dev, 0); + if (valxor & 0x20) + w83977_serial_handler(dev, 1); + break; + case 0x23: + if (dev->type == W83977F) + dev->regs[dev->cur_reg] = val & 0x3f; + else + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0xfe) | (val & 0x01); + break; + case 0x24: + if (dev->type == W83977F) + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x04) | (val & 0xf3); + else + dev->regs[dev->cur_reg] = (dev->regs[dev->cur_reg] & 0x04) | (val & 0xc1); + break; + case 0x25: + if (dev->type == W83977F) + dev->regs[dev->cur_reg] = val & 0x3d; + else + dev->regs[dev->cur_reg] = val & 0x39; + break; + case 0x26: + if (dev->type == W83977F) + dev->regs[dev->cur_reg] = val; + else + dev->regs[dev->cur_reg] = val & 0xef; + dev->lockreg = !!(val & 0x20); + w83977_superio_handler(dev); + break; + case 0x28: + dev->regs[dev->cur_reg] = val & 0x17; + break; + case 0x2a: + if (dev->type == W83977TF) + dev->regs[dev->cur_reg] = val & 0xf3; + else + dev->regs[dev->cur_reg] = val; + break; + case 0x2b: + if (dev->type == W83977TF) + dev->regs[dev->cur_reg] = val & 0xf9; + else + dev->regs[dev->cur_reg] = val; + break; + + default: + break; + } + } else { + valxor = val ^ dev->ld_regs[dev->regs[7]][dev->cur_reg]; + + if (dev->regs[7] <= 0x0a) switch (dev->regs[7]) { + case 0x00: /* FDD */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + case 0x74: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x01; + if (valxor) + w83977_fdc_handler(dev); + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((valxor & 0x01) && (val & 0x01)) { + uint8_t reg_f2 = dev->ld_regs[dev->regs[7]][0xf2]; + + fdc_update_rwc(dev->fdc, 3, (reg_f2 & 0xc0) >> 6); + fdc_update_rwc(dev->fdc, 2, (reg_f2 & 0x30) >> 4); + fdc_update_rwc(dev->fdc, 1, (reg_f2 & 0x0c) >> 2); + fdc_update_rwc(dev->fdc, 0, (reg_f2 & 0x03)); + } else { + fdc_update_rwc(dev->fdc, 3, 0x00); + fdc_update_rwc(dev->fdc, 2, 0x00); + fdc_update_rwc(dev->fdc, 1, 0x00); + fdc_update_rwc(dev->fdc, 0, 0x00); + } + if (valxor & 0x0c) { + fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA); + switch (val & 0x0c) { + case 0x00: + fdc_set_flags(dev->fdc, FDC_FLAG_PS2); + break; + case 0x04: + fdc_set_flags(dev->fdc, FDC_FLAG_PS2_MCA); + break; + } + } + if (valxor & 0x10) + fdc_set_swap(dev->fdc, (val & 0x10) >> 4); + break; + case 0xf1: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor & 0x01) + fdc_set_swwp(dev->fdc, !!(val & 0x01)); + if (valxor & 0x02) + fdc_set_diswr(dev->fdc, !!(val & 0x02)); + if (valxor & 0x0c) + fdc_update_densel_force(dev->fdc, (val & 0xc) >> 2); + break; + case 0xf2: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (dev->ld_regs[dev->regs[7]][0xf0] & 0x01) { + if (valxor & 0xc0) + fdc_update_rwc(dev->fdc, 3, (val & 0xc0) >> 6); + if (valxor & 0x30) + fdc_update_rwc(dev->fdc, 2, (val & 0x30) >> 4); + if (valxor & 0x0c) + fdc_update_rwc(dev->fdc, 1, (val & 0x0c) >> 2); + if (valxor & 0x03) + fdc_update_rwc(dev->fdc, 0, (val & 0x03)); + } + break; + case 0xf4 ... 0xf7: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x5b; + + if (valxor & 0x18) + fdc_update_drvrate(dev->fdc, dev->cur_reg - 0xf4, + (val & 0x18) >> 3); + break; + } + break; + case 0x01: /* Parallel Port */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + case 0x74: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x08; + if (valxor) + w83977_lpt_handler(dev); + break; + /* + Bits 2:0: Mode: + - 000: Bi-directional (SPP); + - 001: EPP-1.9 and SPP; + - 010: ECP; + - 011: ECP and EPP-1.9; + - 100: Printer Mode (Default); + - 101: EPP-1.7 and SPP; + - 110: ECP and EPP-1.7. + Bits 6:3: ECP FIFO Threshold. + */ + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + if (valxor) + w83977_lpt_handler(dev); + break; + } + break; + case 0x02: /* Serial port 1 */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x10; + if (valxor) + w83977_serial_handler(dev, 0); + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x03; + + if (valxor & 0x03) + w83977_serial_handler(dev, 0); + break; + } + break; + case 0x03: /* Serial port 2 */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + case 0x74: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x20; + if (valxor) + w83977_serial_handler(dev, 1); + break; + case 0xf0: + if (dev->type == W83977F) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x03; + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x0f; + + if (valxor & 0x03) + w83977_serial_handler(dev, 1); + break; + case 0xf1: + if (dev->type != W83977F) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x7f; + break; + } + break; + case 0x04: /* Real Time Clock */ + if (dev->type == W83977F) switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor) + w83977_nvr_handler(dev); + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->id != 1) && dev->has_nvr && valxor) { + nvr_lock_set(0x80, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x01), dev->nvr); + nvr_lock_set(0xa0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x02), dev->nvr); + nvr_lock_set(0xc0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x04), dev->nvr); + nvr_lock_set(0xe0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x08), dev->nvr); + + nvr_bank_set(0, val >> 6, dev->nvr); + } + break; + } + break; + case 0x05: /* KBC */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x62: case 0x63: + case 0x70: case 0x72: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor) + w83977_kbc_handler(dev); + break; + case 0xf0: + if (dev->type == W83977F) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xc7; + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x83; + if (valxor & 0x01) + kbc_at_set_fast_reset(val & 0x01); + break; + } + break; + case 0x06: /* IR */ + if (dev->type == W83977F) switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + case 0x74: case 0x75: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x0f; + break; + } + break; + case 0x07: /* GP I/O Port I */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x62: case 0x63: + case 0x64: case 0x65: + case 0x70: case 0x72: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor) + w83977_gpio_handler(dev, 0); + break; + case 0xe0 ... 0xe7: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x1b; + break; + case 0xf1: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x03; + break; + } + break; + case 0x08: /* GP I/O Port II */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: case 0x72: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor) + w83977_gpio_handler(dev, 0); + break; + case 0xe8 ... 0xed: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x1f; + break; + case 0xee: + if (dev->type == W83977TF) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x1f; + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x08; + break; + case 0xf2: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + case 0xf3: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x0e; + break; + case 0xf4: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x0f; + break; + } + break; + case 0x09: /* GP I/O Port III */ + if (dev->type == W83977TF) switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x62: case 0x63: + case 0x64: case 0x65: + case 0x70: case 0x72: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor) + w83977_gpio_handler(dev, 0); + break; + case 0xe0 ... 0xe7: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x1b; + break; + case 0xf1: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x07; + break; + } + break; + case 0x0a: /* ACPI */ + if (dev->type != W83977F) switch (dev->cur_reg) { + case 0x30: + case 0x70: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + case 0x60: case 0x61: + case 0x62: case 0x63: + case 0x64: case 0x65: + if (dev->type == W83977TF) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + case 0xe0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xf7; + break; + case 0xe1: case 0xe2: + case 0xfe: case 0xff: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + case 0xe4: + if (dev->type == W83977EF) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xf0; + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + case 0xe5: + if (dev->type == W83977EF) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x7f; + break; + case 0xe7: + if (dev->type == W83977EF) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x03; + break; + case 0xf0: + if (dev->type == W83977EF) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xcf; + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x8f; + break; + case 0xf1: + if (dev->type == W83977EF) + dev->ld_regs[dev->regs[7]][dev->cur_reg] &= ~(val & 0xcf); + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] &= ~(val & 0x0f); + break; + case 0xf2: + if (dev->type != W83977EF) + dev->ld_regs[dev->regs[7]][dev->cur_reg] &= ~(val & 0x0f); + break; + case 0xf3: + if (dev->type == W83977EF) + dev->ld_regs[dev->regs[7]][dev->cur_reg] &= ~(val & 0x7f); + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] &= ~(val & 0x3f); + break; + case 0xf4: + if (dev->type == W83977EF) + dev->ld_regs[dev->regs[7]][dev->cur_reg] &= ~(val & 0x17); + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x0f; + break; + case 0xf5: + if (dev->type != W83977EF) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x0f; + break; + case 0xf6: + if (dev->type == W83977EF) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x7f; + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x3f; + break; + case 0xf7: + if (dev->type == W83977EF) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x17; + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x01; + break; + case 0xf9: + if (dev->type == W83977EF) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x07; + break; + } + break; + } + } + } +} + +static uint8_t +w83977_read(uint16_t port, void *priv) +{ + w83977_t *dev = (w83977_t *) priv; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t ret = 0xff; + + if (dev->locked) { + if (index) + ret = dev->cur_reg; + else { + if (dev->cur_reg < 0x30) { + if (dev->cur_reg == 0x20) + ret = dev->type >> (W83977_TYPE_SHIFT + 8); + else if (dev->cur_reg == 0x21) + ret = (dev->type >> W83977_TYPE_SHIFT) & 0xff; + else + ret = dev->regs[dev->cur_reg]; + } else if ((dev->regs[7] == 0x0a) && (dev->cur_reg == 0xe3)) { + ret = dev->ld_regs[dev->regs[7]][dev->cur_reg]; + if (dev->type == W83977EF) + dev->ld_regs[dev->regs[7]][dev->cur_reg] &= ~0x17; + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] &= ~0x07; + } else if (dev->regs[7] <= 0x0a) { + if ((dev->regs[7] == 0x00) && (dev->cur_reg == 0xf2)) + ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2) | + (fdc_get_rwc(dev->fdc, 2) << 4) | (fdc_get_rwc(dev->fdc, 3) << 6)); + else + ret = dev->ld_regs[dev->regs[7]][dev->cur_reg]; + } + } + } + + return ret; +} + +static void +w83977_reset(void *priv) +{ + w83977_t *dev = (w83977_t *) priv; + + dev->lockreg = 0; + + memset(dev->regs, 0x00, sizeof(dev->regs)); + + dev->regs[0x03] = 0x03; + dev->regs[0x20] = dev->type >> (W83977_TYPE_SHIFT + 8); + dev->regs[0x21] = (dev->type >> W83977_TYPE_SHIFT) & 0xff; + dev->regs[0x22] = 0xff; + dev->regs[0x23] = (dev->type != W83977F) ? 0xfe : 0x00; + dev->regs[0x24] = 0x80; + dev->regs[0x26] = dev->hefras << 6; + + for (uint8_t i = 0; i <= 0x0a; i++) + memset(dev->ld_regs[i], 0x00, 256); + + /* Logical device 0: FDD */ + dev->ld_regs[0x00][0x30] = 0x01; + dev->ld_regs[0x00][0x60] = 0x03; + dev->ld_regs[0x00][0x61] = (dev->id == 1) ? 0x70 : 0xf0; + dev->ld_regs[0x00][0x70] = 0x06; + if (dev->type == W83977F) + dev->ld_regs[0x00][0x71] = 0x02; + dev->ld_regs[0x00][0x74] = 0x02; + dev->ld_regs[0x00][0xf0] = 0x0e; + dev->ld_regs[0x00][0xf2] = 0xff; + + /* Logical device 1: Parallel Port */ + dev->ld_regs[0x01][0x30] = 0x01; + dev->ld_regs[0x01][0x60] = (dev->id == 1) ? 0x02 : 0x03; + dev->ld_regs[0x01][0x61] = 0x78; + dev->ld_regs[0x01][0x70] = (dev->id == 1) ? 0x05 : 0x07; + if (dev->type == W83977F) + dev->ld_regs[0x01][0x71] = 0x02; + dev->ld_regs[0x01][0x74] = 0x04; + dev->ld_regs[0x01][0xf0] = 0x3f; + + /* Logical device 2: Serial Port 1 */ + dev->ld_regs[0x02][0x30] = 0x01; + dev->ld_regs[0x02][0x60] = 0x03; + dev->ld_regs[0x02][0x61] = (dev->id == 1) ? 0xe8 : 0xf8; + dev->ld_regs[0x02][0x70] = 0x04; + if (dev->type == W83977F) + dev->ld_regs[0x02][0x71] = 0x02; + serial_irq(dev->uart[0], dev->ld_regs[2][0x70]); + + /* Logical device 3: Serial Port 2 */ + dev->ld_regs[0x03][0x30] = 0x01; + dev->ld_regs[0x03][0x60] = 0x02; + dev->ld_regs[0x03][0x61] = (dev->id == 1) ? 0xe8 : 0xf8; + dev->ld_regs[0x03][0x70] = 0x03; + if (dev->type == W83977F) + dev->ld_regs[0x03][0x71] = 0x02; + dev->ld_regs[0x03][0x74] = 0x04; + serial_irq(dev->uart[1], dev->ld_regs[3][0x70]); + + if (dev->type == W83977F) { + /* Logical device 4: Real Time Clock */ + dev->ld_regs[0x04][0x30] = 0x01; + dev->ld_regs[0x04][0x61] = 0x70; + dev->ld_regs[0x04][0x70] = 0x08; + } + + /* Logical device 5: KBC */ + dev->ld_regs[0x05][0x30] = 0x01; + dev->ld_regs[0x05][0x61] = 0x60; + dev->ld_regs[0x05][0x63] = 0x64; + dev->ld_regs[0x05][0x70] = 0x01; + if (dev->type == W83977F) + dev->ld_regs[0x05][0x71] = 0x02; + dev->ld_regs[0x05][0x72] = 0x0c; + if (dev->type == W83977F) + dev->ld_regs[0x05][0x73] = 0x02; + if (dev->type == W83977F) + dev->ld_regs[0x05][0xf0] = 0x40; + else + dev->ld_regs[0x05][0xf0] = 0x83; + + if (dev->type == W83977F) { + /* Logical device 6: IR */ + dev->ld_regs[0x06][0x71] = 0x02; + dev->ld_regs[0x06][0x74] = 0x04; + } + + /* Logical device 7: GP I/O Port I */ + if (dev->type == W83977F) + dev->ld_regs[0x07][0x71] = 0x02; + dev->ld_regs[0x07][0xe0] = 0x01; + dev->ld_regs[0x07][0xe1] = 0x01; + dev->ld_regs[0x07][0xe2] = 0x01; + dev->ld_regs[0x07][0xe3] = 0x01; + dev->ld_regs[0x07][0xe4] = 0x01; + dev->ld_regs[0x07][0xe5] = 0x01; + dev->ld_regs[0x07][0xe6] = 0x01; + dev->ld_regs[0x07][0xe7] = 0x01; + + /* Logical device 8: GP I/O Port II */ + if (dev->type == W83977F) + dev->ld_regs[0x08][0x71] = 0x02; + dev->ld_regs[0x08][0xe8] = 0x01; + dev->ld_regs[0x08][0xe9] = 0x01; + dev->ld_regs[0x08][0xea] = 0x01; + dev->ld_regs[0x08][0xeb] = 0x01; + dev->ld_regs[0x08][0xec] = 0x01; + dev->ld_regs[0x08][0xed] = 0x01; + if (dev->type == W83977TF) + dev->ld_regs[0x08][0xee] = 0x01; + + if (dev->type == W83977TF) { + /* Logical device 9: GP I/O Port III */ + dev->ld_regs[0x09][0xe0] = 0x01; + dev->ld_regs[0x09][0xe1] = 0x01; + dev->ld_regs[0x09][0xe2] = 0x01; + dev->ld_regs[0x09][0xe3] = 0x01; + dev->ld_regs[0x09][0xe4] = 0x01; + dev->ld_regs[0x09][0xe5] = 0x01; + dev->ld_regs[0x09][0xe6] = 0x01; + dev->ld_regs[0x09][0xe7] = 0x01; + } + + /* Logical device A: ACPI - not on W83977F */ + if (dev->type == W83977EF) + dev->ld_regs[0x0a][0xe3] = 0x10; + + w83977_lpt_handler(dev); + w83977_serial_handler(dev, 0); + w83977_serial_handler(dev, 1); + + /* W83977EF has ACPI but no ACPI I/O ports. */ + + if (dev->id != 1) { + fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA); + fdc_reset(dev->fdc); + + w83977_fdc_handler(dev); + + if ((dev->type == W83977F) && dev->has_nvr) { + w83977_nvr_handler(dev); + nvr_bank_set(0, 0, dev->nvr); + + nvr_lock_set(0x80, 0x20, 0, dev->nvr); + nvr_lock_set(0xa0, 0x20, 0, dev->nvr); + nvr_lock_set(0xc0, 0x20, 0, dev->nvr); + nvr_lock_set(0xe0, 0x20, 0, dev->nvr); + } + + w83977_kbc_handler(dev); + } + + w83977_superio_handler(dev); + + for (int i = 0; i < 3; i++) { + dev->gpio[i].reg = 0xff; + dev->gpio[i].pulldn = 0xff; + + w83977_gpio_handler(dev, i); + } + + dev->locked = 0; +} + +static void +w83977_close(void *priv) +{ + w83977_t *dev = (w83977_t *) priv; + + next_id = 0; + + free(dev); +} + +static void * +w83977_init(const device_t *info) +{ + w83977_t *dev = (w83977_t *) calloc(1, sizeof(w83977_t)); + + dev->hefras = info->local & W83977_370; + + dev->id = next_id; + + if (next_id == 1) + dev->hefras ^= W83977_370; + else + dev->fdc = device_add(&fdc_at_smc_device); + + dev->uart[0] = device_add_inst(&ns16550_device, (next_id << 1) + 1); + dev->uart[1] = device_add_inst(&ns16550_device, (next_id << 1) + 2); + + dev->lpt = device_add_inst(&lpt_port_device, next_id + 1); + + dev->type = info->local & W83977_TYPE; + + dev->kbc_type = info->local & W83977_KBC; + + dev->has_nvr = !(info->local & W83977_NO_NVR); + + if (dev->has_nvr && (dev->id != 1)) { + dev->nvr = device_add(&amstrad_megapc_nvr_device); + + nvr_bank_set(0, 0, dev->nvr); + } + + switch (dev->kbc_type) { + case W83977_AMI: + dev->kbc = device_add(&kbc_ps2_ami_pci_device); + break; + case W83977_PHOENIX: + dev->kbc = device_add(&kbc_ps2_phoenix_device); + break; + } + + /* Set the defaults here so the ports can be removed by w83977_reset(). */ + dev->fdc_base = (dev->id == 1) ? 0x0000 : 0x03f0; + dev->lpt_base = (dev->id == 1) ? 0x0278 : 0x0378; + dev->uart_base[0] = (dev->id == 1) ? 0x03e8 : 0x03f8; + dev->uart_base[1] = (dev->id == 1) ? 0x02e8 : 0x02f8; + dev->nvr_base = (dev->id == 1) ? 0x0000 : 0x0070; + dev->kbc_base[0] = (dev->id == 1) ? 0x0000 : 0x0060; + dev->kbc_base[1] = (dev->id == 1) ? 0x0000 : 0x0064; + + for (int i = 0; i < 3; i++) { + dev->gpio[i].id = i + 1; + + dev->gpio[i].reg = 0xff; + dev->gpio[i].pulldn = 0xff; + + for (int j = 0; j < 4; j++) + dev->gpio[i].alt[j] = 0xff; + + dev->gpio[i].parent = dev; + } + + w83977_reset(dev); + + next_id++; + + return dev; +} + +const device_t w83977_device = { + .name = "SMC FDC37C93x Super I/O", + .internal_name = "w83977", + .flags = 0, + .local = 0, + .init = w83977_init, + .close = w83977_close, + .reset = w83977_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sio/sio_w83977f.c b/src/sio/sio_w83977f.c deleted file mode 100644 index 3b03dfc4d..000000000 --- a/src/sio/sio_w83977f.c +++ /dev/null @@ -1,680 +0,0 @@ -/* - * 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. - * - * Emulation of the Winbond W83977F Super I/O Chip. - * - * Winbond W83977F Super I/O Chip - * Used by the Award 430TX - * - * - * - * Authors: Miran Grca, - * Copyright 2016-2020 Miran Grca. - */ -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/io.h> -#include <86box/timer.h> -#include <86box/pci.h> -#include <86box/mem.h> -#include <86box/rom.h> -#include <86box/lpt.h> -#include <86box/serial.h> -#include <86box/fdd.h> -#include <86box/fdc.h> -#include <86box/sio.h> - -#define HEFRAS (dev->regs[0x26] & 0x40) - -typedef struct w83977f_t { - uint8_t id; - uint8_t tries; - uint8_t regs[48]; - uint8_t dev_regs[256][208]; - int locked; - int rw_locked; - int cur_reg; - int base_address; - int type; - int hefras; - fdc_t *fdc; - lpt_t *lpt; - serial_t *uart[2]; -} w83977f_t; - -static int next_id = 0; - -static void w83977f_write(uint16_t port, uint8_t val, void *priv); -static uint8_t w83977f_read(uint16_t port, void *priv); - -static void -w83977f_remap(w83977f_t *dev) -{ - io_removehandler(FDC_PRIMARY_ADDR, 0x0002, - w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev); - io_removehandler(FDC_SECONDARY_ADDR, 0x0002, - w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev); - - dev->base_address = (HEFRAS ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR); - - io_sethandler(dev->base_address, 0x0002, - w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev); -} - -static uint8_t -get_lpt_length(w83977f_t *dev) -{ - uint8_t length = 4; - - if (((dev->dev_regs[1][0xc0] & 0x07) != 0x00) && ((dev->dev_regs[1][0xc0] & 0x07) != 0x02) && ((dev->dev_regs[1][0xc0] & 0x07) != 0x04)) - length = 8; - - return length; -} - -static void -w83977f_fdc_handler(w83977f_t *dev) -{ - uint16_t io_base = (dev->dev_regs[0][0x30] << 8) | dev->dev_regs[0][0x31]; - - if (dev->id == 1) - return; - - fdc_remove(dev->fdc); - - if ((dev->dev_regs[0][0x00] & 0x01) && (dev->regs[0x22] & 0x01) && (io_base >= 0x100) && (io_base <= 0xff8)) - fdc_set_base(dev->fdc, io_base); - - fdc_set_irq(dev->fdc, dev->dev_regs[0][0x40] & 0x0f); -} - -static void -w83977f_lpt_handler(w83977f_t *dev) -{ - uint16_t io_mask; - uint16_t io_base = (dev->dev_regs[1][0x30] << 8) | dev->dev_regs[1][0x31]; - int io_len = get_lpt_length(dev); - io_base &= (0xff8 | io_len); - io_mask = 0xffc; - if (io_len == 8) - io_mask = 0xff8; - - lpt_port_remove(dev->lpt); - - if ((dev->dev_regs[1][0x00] & 0x01) && (dev->regs[0x22] & 0x08) && (io_base >= 0x100) && (io_base <= io_mask)) - lpt_port_setup(dev->lpt, io_base); - - lpt_port_irq(dev->lpt, dev->dev_regs[1][0x40] & 0x0f); -} - -static void -w83977f_serial_handler(w83977f_t *dev, int uart) -{ - uint16_t io_base = (dev->dev_regs[2 + uart][0x30] << 8) | dev->dev_regs[2 + uart][0x31]; - double clock_src = 24000000.0 / 13.0; - - serial_remove(dev->uart[uart]); - - if ((dev->dev_regs[2 + uart][0x00] & 0x01) && (dev->regs[0x22] & (0x10 << uart)) && (io_base >= 0x100) && (io_base <= 0xff8)) - serial_setup(dev->uart[uart], io_base, dev->dev_regs[2 + uart][0x40] & 0x0f); - - switch (dev->dev_regs[2 + uart][0xc0] & 0x03) { - case 0x00: - clock_src = 24000000.0 / 13.0; - break; - case 0x01: - clock_src = 24000000.0 / 12.0; - break; - case 0x02: - clock_src = 24000000.0 / 1.0; - break; - case 0x03: - clock_src = 24000000.0 / 1.625; - break; - - default: - break; - } - - serial_set_clock_src(dev->uart[uart], clock_src); -} - -static void -w83977f_write(uint16_t port, uint8_t val, void *priv) -{ - w83977f_t *dev = (w83977f_t *) priv; - uint8_t index = (port & 1) ? 0 : 1; - uint8_t valxor = 0; - uint8_t ld = dev->regs[7]; - - if (index) { - if ((val == 0x87) && !dev->locked) { - if (dev->tries) { - dev->locked = 1; - dev->tries = 0; - } else - dev->tries++; - } else { - if (dev->locked) { - if (val == 0xaa) - dev->locked = 0; - else - dev->cur_reg = val; - } else { - if (dev->tries) - dev->tries = 0; - } - } - return; - } else { - if (dev->locked) { - if (dev->rw_locked) - return; - if (dev->cur_reg >= 0x30) { - valxor = val ^ dev->dev_regs[ld][dev->cur_reg - 0x30]; - dev->dev_regs[ld][dev->cur_reg - 0x30] = val; - } else { - valxor = val ^ dev->regs[dev->cur_reg]; - dev->regs[dev->cur_reg] = val; - } - } else - return; - } - - switch (dev->cur_reg) { - case 0x02: -#if 0 - if (valxor & 0x02) - softresetx86(); -#endif - break; - case 0x22: - if (valxor & 0x20) - w83977f_serial_handler(dev, 1); - if (valxor & 0x10) - w83977f_serial_handler(dev, 0); - if (valxor & 0x08) - w83977f_lpt_handler(dev); - if (valxor & 0x01) - w83977f_fdc_handler(dev); - break; - case 0x26: - if (valxor & 0x40) - w83977f_remap(dev); - if (valxor & 0x20) - dev->rw_locked = (val & 0x20) ? 1 : 0; - break; - case 0x30: - if (valxor & 0x01) - switch (ld) { - case 0x00: - w83977f_fdc_handler(dev); - break; - case 0x01: - w83977f_lpt_handler(dev); - break; - case 0x02: - case 0x03: - w83977f_serial_handler(dev, ld - 2); - break; - - default: - break; - } - break; - case 0x60: - case 0x61: - if (valxor & 0xff) - switch (ld) { - case 0x00: - w83977f_fdc_handler(dev); - break; - case 0x01: - w83977f_lpt_handler(dev); - break; - case 0x02: - case 0x03: - w83977f_serial_handler(dev, ld - 2); - break; - - default: - break; - } - break; - case 0x70: - if (valxor & 0x0f) - switch (ld) { - case 0x00: - w83977f_fdc_handler(dev); - break; - case 0x01: - w83977f_lpt_handler(dev); - break; - case 0x02: - case 0x03: - w83977f_serial_handler(dev, ld - 2); - break; - - default: - break; - } - break; - case 0xf0: - switch (ld) { - case 0x00: - if (dev->id == 1) - break; - - if (!dev->id && (valxor & 0x20)) - fdc_update_drv2en(dev->fdc, (val & 0x20) ? 0 : 1); - if (!dev->id && (valxor & 0x10)) - fdc_set_swap(dev->fdc, (val & 0x10) ? 1 : 0); - if (!dev->id && (valxor & 0x01)) - fdc_update_enh_mode(dev->fdc, (val & 0x01) ? 1 : 0); - break; - case 0x01: - if (valxor & 0x07) - w83977f_lpt_handler(dev); - break; - case 0x02: - case 0x03: - if (valxor & 0x03) - w83977f_serial_handler(dev, ld - 2); - break; - - default: - break; - } - break; - case 0xf1: - switch (ld) { - case 0x00: - if (dev->id == 1) - break; - - if (!dev->id && (valxor & 0xc0)) - fdc_update_boot_drive(dev->fdc, (val & 0xc0) >> 6); - if (!dev->id && (valxor & 0x0c)) - fdc_update_densel_force(dev->fdc, (val & 0x0c) >> 2); - if (!dev->id && (valxor & 0x02)) - fdc_set_diswr(dev->fdc, (val & 0x02) ? 1 : 0); - if (!dev->id && (valxor & 0x01)) - fdc_set_swwp(dev->fdc, (val & 0x01) ? 1 : 0); - break; - - default: - break; - } - break; - case 0xf2: - switch (ld) { - case 0x00: - if (dev->id == 1) - break; - - if (!dev->id && (valxor & 0xc0)) - fdc_update_rwc(dev->fdc, 3, (val & 0xc0) >> 6); - if (!dev->id && (valxor & 0x30)) - fdc_update_rwc(dev->fdc, 2, (val & 0x30) >> 4); - if (!dev->id && (valxor & 0x0c)) - fdc_update_rwc(dev->fdc, 1, (val & 0x0c) >> 2); - if (!dev->id && (valxor & 0x03)) - fdc_update_rwc(dev->fdc, 0, val & 0x03); - break; - - default: - break; - } - break; - case 0xf4: - case 0xf5: - case 0xf6: - case 0xf7: - switch (ld) { - case 0x00: - if (dev->id == 1) - break; - - if (!dev->id && (valxor & 0x18)) - fdc_update_drvrate(dev->fdc, dev->cur_reg & 0x03, (val & 0x18) >> 3); - break; - - default: - break; - } - break; - - default: - break; - } -} - -static uint8_t -w83977f_read(uint16_t port, void *priv) -{ - w83977f_t *dev = (w83977f_t *) priv; - uint8_t ret = 0xff; - uint8_t index = (port & 1) ? 0 : 1; - uint8_t ld = dev->regs[7]; - - if (dev->locked) { - if (index) - ret = dev->cur_reg; - else { - if (!dev->rw_locked) { - if (!dev->id && ((dev->cur_reg == 0xf2) && (ld == 0x00))) - ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2) | (fdc_get_rwc(dev->fdc, 2) << 4) | (fdc_get_rwc(dev->fdc, 3) << 6)); - else if (dev->cur_reg >= 0x30) - ret = dev->dev_regs[ld][dev->cur_reg - 0x30]; - else - ret = dev->regs[dev->cur_reg]; - } - } - } - - return ret; -} - -static void -w83977f_reset(w83977f_t *dev) -{ - memset(dev->regs, 0, 48); - for (uint16_t i = 0; i < 256; i++) - memset(dev->dev_regs[i], 0, 208); - - if (dev->type < 2) { - dev->regs[0x20] = 0x97; - dev->regs[0x21] = dev->type ? 0x73 : 0x71; - } else { - dev->regs[0x20] = 0x52; - dev->regs[0x21] = 0xf0; - } - dev->regs[0x22] = 0xff; - dev->regs[0x24] = dev->type ? 0x84 : 0xa4; - dev->regs[0x26] = dev->hefras; - - /* WARNING: Array elements are register - 0x30. */ - /* Logical Device 0 (FDC) */ - dev->dev_regs[0][0x00] = 0x01; - if (!dev->type) - dev->dev_regs[0][0x01] = 0x02; - if (next_id == 1) { - dev->dev_regs[0][0x30] = 0x03; - dev->dev_regs[0][0x31] = 0x70; - } else { - dev->dev_regs[0][0x30] = 0x03; - dev->dev_regs[0][0x31] = 0xf0; - } - dev->dev_regs[0][0x40] = 0x06; - if (!dev->type) - dev->dev_regs[0][0x41] = 0x02; /* Read-only */ - dev->dev_regs[0][0x44] = 0x02; - dev->dev_regs[0][0xc0] = 0x0e; - - /* Logical Device 1 (Parallel Port) */ - dev->dev_regs[1][0x00] = 0x01; - if (!dev->type) - dev->dev_regs[1][0x01] = 0x02; - if (next_id == 1) { - dev->dev_regs[1][0x30] = 0x02; - dev->dev_regs[1][0x31] = 0x78; - dev->dev_regs[1][0x40] = 0x05; - } else { - dev->dev_regs[1][0x30] = 0x03; - dev->dev_regs[1][0x31] = 0x78; - dev->dev_regs[1][0x40] = 0x07; - } - if (!dev->type) - dev->dev_regs[1][0x41] = 0x01 /*0x02*/; /* Read-only */ - dev->dev_regs[1][0x44] = 0x04; - dev->dev_regs[1][0xc0] = 0x3c; /* The datasheet says default is 3f, but also default is printer mode. */ - - /* Logical Device 2 (UART A) */ - dev->dev_regs[2][0x00] = 0x01; - if (!dev->type) - dev->dev_regs[2][0x01] = 0x02; - if (next_id == 1) { - dev->dev_regs[2][0x30] = 0x03; - dev->dev_regs[2][0x31] = 0xe8; - } else { - dev->dev_regs[2][0x30] = 0x03; - dev->dev_regs[2][0x31] = 0xf8; - } - dev->dev_regs[2][0x40] = 0x04; - if (!dev->type) - dev->dev_regs[2][0x41] = 0x02; /* Read-only */ - - /* Logical Device 3 (UART B) */ - dev->dev_regs[3][0x00] = 0x01; - if (!dev->type) - dev->dev_regs[3][0x01] = 0x02; - if (next_id == 1) { - dev->dev_regs[3][0x30] = 0x02; - dev->dev_regs[3][0x31] = 0xe8; - } else { - dev->dev_regs[3][0x30] = 0x02; - dev->dev_regs[3][0x31] = 0xf8; - } - dev->dev_regs[3][0x40] = 0x03; - if (!dev->type) - dev->dev_regs[3][0x41] = 0x02; /* Read-only */ - - /* Logical Device 4 (RTC) */ - if (!dev->type) { - dev->dev_regs[4][0x00] = 0x01; - dev->dev_regs[4][0x01] = 0x02; - dev->dev_regs[4][0x30] = 0x00; - dev->dev_regs[4][0x31] = 0x70; - dev->dev_regs[4][0x40] = 0x08; - dev->dev_regs[4][0x41] = 0x02; /* Read-only */ - } - - /* Logical Device 5 (KBC) */ - dev->dev_regs[5][0x00] = 0x01; - if (!dev->type) - dev->dev_regs[5][0x01] = 0x02; - dev->dev_regs[5][0x30] = 0x00; - dev->dev_regs[5][0x31] = 0x60; - dev->dev_regs[5][0x32] = 0x00; - dev->dev_regs[5][0x33] = 0x64; - dev->dev_regs[5][0x40] = 0x01; - if (!dev->type) - dev->dev_regs[5][0x41] = 0x02; /* Read-only */ - dev->dev_regs[5][0x42] = 0x0c; - if (!dev->type) - dev->dev_regs[5][0x43] = 0x02; /* Read-only? */ - dev->dev_regs[5][0xc0] = dev->type ? 0x83 : 0x40; - - /* Logical Device 6 (IR) = UART C */ - if (!dev->type) { - dev->dev_regs[6][0x01] = 0x02; - dev->dev_regs[6][0x41] = 0x02; /* Read-only */ - dev->dev_regs[6][0x44] = 0x04; - dev->dev_regs[6][0x45] = 0x04; - } - - /* Logical Device 7 (Auxiliary I/O Part I) */ - if (!dev->type) - dev->dev_regs[7][0x01] = 0x02; - if (!dev->type) - dev->dev_regs[7][0x41] = 0x02; /* Read-only */ - if (!dev->type) - dev->dev_regs[7][0x43] = 0x02; /* Read-only? */ - dev->dev_regs[7][0xb0] = 0x01; - dev->dev_regs[7][0xb1] = 0x01; - dev->dev_regs[7][0xb2] = 0x01; - dev->dev_regs[7][0xb3] = 0x01; - dev->dev_regs[7][0xb4] = 0x01; - dev->dev_regs[7][0xb5] = 0x01; - dev->dev_regs[7][0xb6] = 0x01; - if (dev->type) - dev->dev_regs[7][0xb7] = 0x01; - - /* Logical Device 8 (Auxiliary I/O Part II) */ - if (!dev->type) - dev->dev_regs[8][0x01] = 0x02; - if (!dev->type) - dev->dev_regs[8][0x41] = 0x02; /* Read-only */ - if (!dev->type) - dev->dev_regs[8][0x43] = 0x02; /* Read-only? */ - dev->dev_regs[8][0xb8] = 0x01; - dev->dev_regs[8][0xb9] = 0x01; - dev->dev_regs[8][0xba] = 0x01; - dev->dev_regs[8][0xbb] = 0x01; - dev->dev_regs[8][0xbc] = 0x01; - dev->dev_regs[8][0xbd] = 0x01; - dev->dev_regs[8][0xbe] = 0x01; - dev->dev_regs[8][0xbf] = 0x01; - - /* Logical Device 9 (Auxiliary I/O Part III) */ - if (dev->type) { - dev->dev_regs[9][0xb0] = 0x01; - dev->dev_regs[9][0xb1] = 0x01; - dev->dev_regs[9][0xb2] = 0x01; - dev->dev_regs[9][0xb3] = 0x01; - dev->dev_regs[9][0xb4] = 0x01; - dev->dev_regs[9][0xb5] = 0x01; - dev->dev_regs[9][0xb6] = 0x01; - dev->dev_regs[9][0xb7] = 0x01; - - dev->dev_regs[10][0xc0] = 0x8f; - } - - if (dev->id == 1) { - serial_setup(dev->uart[0], COM3_ADDR, COM3_IRQ); - serial_setup(dev->uart[1], COM4_ADDR, COM4_IRQ); - } else { - fdc_reset(dev->fdc); - - serial_setup(dev->uart[0], COM1_ADDR, COM1_IRQ); - serial_setup(dev->uart[1], COM2_ADDR, COM2_IRQ); - - w83977f_fdc_handler(dev); - } - - w83977f_lpt_handler(dev); - w83977f_serial_handler(dev, 0); - w83977f_serial_handler(dev, 1); - - w83977f_remap(dev); - - dev->locked = 0; - dev->rw_locked = 0; -} - -static void -w83977f_close(void *priv) -{ - w83977f_t *dev = (w83977f_t *) priv; - - next_id = 0; - - free(dev); -} - -static void * -w83977f_init(const device_t *info) -{ - w83977f_t *dev = (w83977f_t *) calloc(1, sizeof(w83977f_t)); - - dev->type = info->local & 0x0f; - dev->hefras = info->local & 0x40; - - dev->id = next_id; - - if (next_id == 1) - dev->hefras ^= 0x40; - else - dev->fdc = device_add(&fdc_at_smc_device); - - dev->uart[0] = device_add_inst(&ns16550_device, (next_id << 1) + 1); - dev->uart[1] = device_add_inst(&ns16550_device, (next_id << 1) + 2); - - dev->lpt = device_add_inst(&lpt_port_device, next_id + 1); - - w83977f_reset(dev); - - next_id++; - - return dev; -} - -const device_t w83977f_device = { - .name = "Winbond W83977F Super I/O", - .internal_name = "w83977f", - .flags = 0, - .local = 0, - .init = w83977f_init, - .close = w83977f_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t w83977f_370_device = { - .name = "Winbond W83977F Super I/O (Port 370h)", - .internal_name = "w83977f_370", - .flags = 0, - .local = 0x40, - .init = w83977f_init, - .close = w83977f_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t w83977tf_device = { - .name = "Winbond W83977TF Super I/O", - .internal_name = "w83977tf", - .flags = 0, - .local = 1, - .init = w83977f_init, - .close = w83977f_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t w83977ef_device = { - .name = "Winbond W83977TF Super I/O", - .internal_name = "w83977ef", - .flags = 0, - .local = 2, - .init = w83977f_init, - .close = w83977f_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t w83977ef_370_device = { - .name = "Winbond W83977TF Super I/O (Port 370h)", - .internal_name = "w83977ef_370", - .flags = 0, - .local = 0x42, - .init = w83977f_init, - .close = w83977f_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -};