From 3857fede38cf3b1eaca5994b18fdd2f1cae3809a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 19 Jan 2024 16:30:51 +0600 Subject: [PATCH 1/7] DECchip 21040 emulation (only tested on Linux) --- src/include/86box/net_tulip.h | 1 + src/network/net_tulip.c | 315 ++++++++++++++++++++-------------- src/network/network.c | 1 + 3 files changed, 190 insertions(+), 127 deletions(-) diff --git a/src/include/86box/net_tulip.h b/src/include/86box/net_tulip.h index 3e14deeea..2ee7ec3c1 100644 --- a/src/include/86box/net_tulip.h +++ b/src/include/86box/net_tulip.h @@ -1,3 +1,4 @@ extern const device_t dec_tulip_device; extern const device_t dec_tulip_21140_device; extern const device_t dec_tulip_21140_vpc_device; +extern const device_t dec_tulip_21040_device; diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index b74b345bc..c81fbc3f9 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -323,6 +323,9 @@ struct TULIPState { uint32_t mii_word; uint32_t mii_bitcnt; + /* 21040 ROM read address. */ + uint32_t rom_read_addr; + uint32_t current_rx_desc; uint32_t current_tx_desc; @@ -666,6 +669,9 @@ tulip_mii(TULIPState *s) static uint32_t tulip_csr9_read(TULIPState *s) { + if (s->device_info->local == 3) { + return ((uint8_t*)nmc93cxx_eeprom_data(s->eeprom))[s->rom_read_addr++]; + } if (s->csr[9] & CSR9_SR) { if (nmc93cxx_eeprom_read(s->eeprom)) { s->csr[9] |= CSR9_SR_DO; @@ -698,6 +704,10 @@ tulip_read(uint32_t addr, void *opaque) break; case CSR(12): + if (s->device_info->local == 3) { + data = 0; + break; + } /* Fake autocompletion complete until we have PHY emulation */ data = 5 << CSR12_ANS_SHIFT; break; @@ -884,8 +894,10 @@ tulip_reset(void *priv) s->csr[13] = 0xffff0000; s->csr[14] = 0xffffffff; s->csr[15] = 0x8ff00000; - s->subsys_id = eeprom_data[1]; - s->subsys_ven_id = eeprom_data[0]; + if (s->device_info->local != 3) { + s->subsys_id = eeprom_data[1]; + s->subsys_ven_id = eeprom_data[0]; + } } static void @@ -955,12 +967,16 @@ tulip_write(uint32_t addr, uint32_t data, void *opaque) break; case CSR(9): - tulip_csr9_write(s, s->csr[9], data); - /* don't clear MII read data */ - s->csr[9] &= CSR9_MDI; - s->csr[9] |= (data & ~CSR9_MDI); - tulip_mii(s); - s->old_csr9 = s->csr[9]; + if (s->device_info->local != 3) { + tulip_csr9_write(s, s->csr[9], data); + /* don't clear MII read data */ + s->csr[9] &= CSR9_MDI; + s->csr[9] |= (data & ~CSR9_MDI); + tulip_mii(s); + s->old_csr9 = s->csr[9]; + } else { + s->rom_read_addr = 0; + } break; case CSR(10): @@ -978,6 +994,11 @@ tulip_write(uint32_t addr, uint32_t data, void *opaque) case CSR(13): s->csr[13] = data; + if (s->device_info->local == 3 && (data & 0x4)) { + s->csr[13] = 0x8f01; + s->csr[14] = 0xfffd; + s->csr[15] = 0; + } break; case CSR(14): @@ -1141,7 +1162,9 @@ tulip_pci_read(UNUSED(int func), int addr, void *priv) ret = 0x10; break; case 0x02: - if (s->device_info->local) + if (s->device_info->local == 3) + ret = 0x02; + else if (s->device_info->local) ret = 0x09; else ret = 0x19; @@ -1229,6 +1252,7 @@ tulip_pci_read(UNUSED(int func), int addr, void *priv) break; case 0x3E: case 0x3F: + case 0x41: ret = s->pci_conf[addr & 0xff]; break; } @@ -1319,6 +1343,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) return; case 0x3E: case 0x3F: + case 0x41: s->pci_conf[addr & 0xff] = val; return; } @@ -1336,7 +1361,7 @@ nic_init(const device_t *info) if (!s) return NULL; - if (info->local) { + if (info->local && info->local != 3) { s->bios_addr = 0xD0000; s->has_bios = device_get_config_int("bios"); } else { @@ -1349,139 +1374,161 @@ nic_init(const device_t *info) s->device_info = info; - /*Subsystem Vendor ID*/ - s->eeprom_data[0] = info->local ? 0x25 : 0x11; - s->eeprom_data[1] = 0x10; + if (info->local != 3) { + /*Subsystem Vendor ID*/ + s->eeprom_data[0] = info->local ? 0x25 : 0x11; + s->eeprom_data[1] = 0x10; - /*Subsystem ID*/ - s->eeprom_data[2] = info->local ? 0x10 : 0x0a; - s->eeprom_data[3] = info->local ? 0x03 : 0x50; + /*Subsystem ID*/ + s->eeprom_data[2] = info->local ? 0x10 : 0x0a; + s->eeprom_data[3] = info->local ? 0x03 : 0x50; - /*Cardbus CIS Pointer low*/ - s->eeprom_data[4] = 0x00; - s->eeprom_data[5] = 0x00; + /*Cardbus CIS Pointer low*/ + s->eeprom_data[4] = 0x00; + s->eeprom_data[5] = 0x00; - /*Cardbus CIS Pointer high*/ - s->eeprom_data[6] = 0x00; - s->eeprom_data[7] = 0x00; + /*Cardbus CIS Pointer high*/ + s->eeprom_data[6] = 0x00; + s->eeprom_data[7] = 0x00; - /*ID Reserved1*/ - for (int i = 0; i < 7; i++) - s->eeprom_data[8 + i] = 0x00; + /*ID Reserved1*/ + for (int i = 0; i < 7; i++) + s->eeprom_data[8 + i] = 0x00; - /*MiscHwOptions*/ - s->eeprom_data[15] = 0x00; + /*MiscHwOptions*/ + s->eeprom_data[15] = 0x00; - /*ID_BLOCK_CRC*/ - tulip_idblock_crc((uint16_t *) s->eeprom_data); + /*ID_BLOCK_CRC*/ + tulip_idblock_crc((uint16_t *) s->eeprom_data); - /*Func0_HwOptions*/ - s->eeprom_data[17] = 0x00; + /*Func0_HwOptions*/ + s->eeprom_data[17] = 0x00; - /*SROM Format Version 1, compatible with older guests*/ - s->eeprom_data[18] = 0x01; + /*SROM Format Version 1, compatible with older guests*/ + s->eeprom_data[18] = 0x01; - /*Controller Count*/ - s->eeprom_data[19] = 0x01; + /*Controller Count*/ + s->eeprom_data[19] = 0x01; - /*DEC OID*/ - s->eeprom_data[20] = 0x00; - s->eeprom_data[21] = 0x00; - s->eeprom_data[22] = 0xf8; - - if (info->local == 2) { - /* Microsoft VPC DEC Tulip. */ + /*DEC OID*/ s->eeprom_data[20] = 0x00; - s->eeprom_data[21] = 0x03; - s->eeprom_data[22] = 0x0f; - } + s->eeprom_data[21] = 0x00; + s->eeprom_data[22] = 0xf8; - /* See if we have a local MAC address configured. */ - mac = device_get_config_mac("mac", -1); + if (info->local == 2) { + /* Microsoft VPC DEC Tulip. */ + s->eeprom_data[20] = 0x00; + s->eeprom_data[21] = 0x03; + s->eeprom_data[22] = 0x0f; + } - /* Set up our BIA. */ - if (mac & 0xff000000) { - /* Generate new local MAC. */ - s->eeprom_data[23] = random_generate(); - s->eeprom_data[24] = random_generate(); - s->eeprom_data[25] = random_generate(); - mac = (((int) s->eeprom_data[23]) << 16); - mac |= (((int) s->eeprom_data[24]) << 8); - mac |= ((int) s->eeprom_data[25]); - device_set_config_mac("mac", mac); + /* See if we have a local MAC address configured. */ + mac = device_get_config_mac("mac", -1); + + /* Set up our BIA. */ + if (mac & 0xff000000) { + /* Generate new local MAC. */ + s->eeprom_data[23] = random_generate(); + s->eeprom_data[24] = random_generate(); + s->eeprom_data[25] = random_generate(); + mac = (((int) s->eeprom_data[23]) << 16); + mac |= (((int) s->eeprom_data[24]) << 8); + mac |= ((int) s->eeprom_data[25]); + device_set_config_mac("mac", mac); + } else { + s->eeprom_data[23] = (mac >> 16) & 0xff; + s->eeprom_data[24] = (mac >> 8) & 0xff; + s->eeprom_data[25] = (mac & 0xff); + } + + /*Controller_0 Device_Number*/ + s->eeprom_data[26] = 0x00; + + /*Controller_0 Info Leaf_Offset*/ + s->eeprom_data[27] = 0x1e; + s->eeprom_data[28] = 0x00; + + /*Selected Connection Type, Powerup AutoSense and Dynamic AutoSense if the board supports it*/ + s->eeprom_data[30] = 0x00; + s->eeprom_data[31] = 0x08; + + if (info->local) { + /*General Purpose Control*/ + s->eeprom_data[32] = 0xff; + + /*Block Count*/ + s->eeprom_data[33] = 0x01; + + /*Extended Format (first part)*/ + /*Length (0:6) and Format Indicator (7)*/ + s->eeprom_data[34] = 0x81; + + /*Block Type (first part)*/ + s->eeprom_data[35] = 0x01; + + /*Extended Format (second part) - Block Type 0 for 21140*/ + /*Length (0:6) and Format Indicator (7)*/ + s->eeprom_data[36] = 0x85; + + /*Block Type (second part)*/ + s->eeprom_data[37] = 0x00; + + /*Media Code (0:5), EXT (6), Reserved (7)*/ + s->eeprom_data[38] = 0x01; + + /*General Purpose Data*/ + s->eeprom_data[39] = 0x00; + + /*Command*/ + s->eeprom_data[40] = 0x00; + s->eeprom_data[41] = 0x00; + } else { + /*Block Count*/ + s->eeprom_data[32] = 0x01; + + /*Extended Format - Block Type 2 for 21142/21143*/ + /*Length (0:6) and Format Indicator (7)*/ + s->eeprom_data[33] = 0x86; + + /*Block Type*/ + s->eeprom_data[34] = 0x02; + + /*Media Code (0:5), EXT (6), Reserved (7)*/ + s->eeprom_data[35] = 0x01; + + /*General Purpose Control*/ + s->eeprom_data[36] = 0xff; + s->eeprom_data[37] = 0xff; + + /*General Purpose Data*/ + s->eeprom_data[38] = 0x00; + s->eeprom_data[39] = 0x00; + } + + s->eeprom_data[126] = tulip_srom_crc(s->eeprom_data) & 0xff; + s->eeprom_data[127] = tulip_srom_crc(s->eeprom_data) >> 8; } else { - s->eeprom_data[23] = (mac >> 16) & 0xff; - s->eeprom_data[24] = (mac >> 8) & 0xff; - s->eeprom_data[25] = (mac & 0xff); + /* 21040 is supposed to only have MAC address in its serial ROM if Linux is correct. */ + memset(s->eeprom_data, 0, sizeof(s->eeprom_data)); + s->eeprom_data[0] = 0x00; + s->eeprom_data[1] = 0x00; + s->eeprom_data[2] = 0xF8; + if (mac & 0xff000000) { + /* Generate new local MAC. */ + s->eeprom_data[3] = random_generate(); + s->eeprom_data[4] = random_generate(); + s->eeprom_data[5] = random_generate(); + mac = (((int) s->eeprom_data[3]) << 16); + mac |= (((int) s->eeprom_data[4]) << 8); + mac |= ((int) s->eeprom_data[5]); + device_set_config_mac("mac", mac); + } else { + s->eeprom_data[3] = (mac >> 16) & 0xff; + s->eeprom_data[4] = (mac >> 8) & 0xff; + s->eeprom_data[5] = (mac & 0xff); + } } - /*Controller_0 Device_Number*/ - s->eeprom_data[26] = 0x00; - - /*Controller_0 Info Leaf_Offset*/ - s->eeprom_data[27] = 0x1e; - s->eeprom_data[28] = 0x00; - - /*Selected Connection Type, Powerup AutoSense and Dynamic AutoSense if the board supports it*/ - s->eeprom_data[30] = 0x00; - s->eeprom_data[31] = 0x08; - - if (info->local) { - /*General Purpose Control*/ - s->eeprom_data[32] = 0xff; - - /*Block Count*/ - s->eeprom_data[33] = 0x01; - - /*Extended Format (first part)*/ - /*Length (0:6) and Format Indicator (7)*/ - s->eeprom_data[34] = 0x81; - - /*Block Type (first part)*/ - s->eeprom_data[35] = 0x01; - - /*Extended Format (second part) - Block Type 0 for 21140*/ - /*Length (0:6) and Format Indicator (7)*/ - s->eeprom_data[36] = 0x85; - - /*Block Type (second part)*/ - s->eeprom_data[37] = 0x00; - - /*Media Code (0:5), EXT (6), Reserved (7)*/ - s->eeprom_data[38] = 0x01; - - /*General Purpose Data*/ - s->eeprom_data[39] = 0x00; - - /*Command*/ - s->eeprom_data[40] = 0x00; - s->eeprom_data[41] = 0x00; - } else { - /*Block Count*/ - s->eeprom_data[32] = 0x01; - - /*Extended Format - Block Type 2 for 21142/21143*/ - /*Length (0:6) and Format Indicator (7)*/ - s->eeprom_data[33] = 0x86; - - /*Block Type*/ - s->eeprom_data[34] = 0x02; - - /*Media Code (0:5), EXT (6), Reserved (7)*/ - s->eeprom_data[35] = 0x01; - - /*General Purpose Control*/ - s->eeprom_data[36] = 0xff; - s->eeprom_data[37] = 0xff; - - /*General Purpose Data*/ - s->eeprom_data[38] = 0x00; - s->eeprom_data[39] = 0x00; - } - - s->eeprom_data[126] = tulip_srom_crc(s->eeprom_data) & 0xff; - s->eeprom_data[127] = tulip_srom_crc(s->eeprom_data) >> 8; - params.nwords = 64; params.default_content = (uint16_t *) s->eeprom_data; params.filename = filename; @@ -1592,3 +1639,17 @@ const device_t dec_tulip_21140_vpc_device = { .force_redraw = NULL, .config = dec_tulip_21140_config }; + +const device_t dec_tulip_21040_device = { + .name = "DEC DE-435 EtherWorks Turbo (DECchip 21040 \"Tulip\")", + .internal_name = "dec_21040_tulip", + .flags = DEVICE_PCI, + .local = 3, + .init = nic_init, + .close = nic_close, + .reset = tulip_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = dec_tulip_21143_config +}; diff --git a/src/network/network.c b/src/network/network.c index 38af502b2..4d11ba955 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -136,6 +136,7 @@ static const device_t *net_cards[] = { &rtl8139c_plus_device, &dec_tulip_21140_device, &dec_tulip_21140_vpc_device, + &dec_tulip_21040_device, &pcnet_am79c960_vlb_device, NULL }; From 7b387580724ff165486d82430dc997f4e1a8ef2a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 20 Jan 2024 17:06:46 +0600 Subject: [PATCH 2/7] Fix EEPROM reading in DECchip 21040 --- src/network/net_eeprom_nmc93cxx.c | 2 ++ src/network/net_tulip.c | 43 +++++++++++++++++-------------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/network/net_eeprom_nmc93cxx.c b/src/network/net_eeprom_nmc93cxx.c index 1e2fd1645..681263717 100644 --- a/src/network/net_eeprom_nmc93cxx.c +++ b/src/network/net_eeprom_nmc93cxx.c @@ -263,6 +263,8 @@ nmc93cxx_eeprom_close(void *priv) uint16_t * nmc93cxx_eeprom_data(nmc93cxx_eeprom_t *eeprom) { + if (UNLIKELY(!eeprom)) + return NULL; /* Get EEPROM data array. */ return &eeprom->dev.data[0]; } diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index c81fbc3f9..3dab8d915 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -324,7 +324,7 @@ struct TULIPState { uint32_t mii_bitcnt; /* 21040 ROM read address. */ - uint32_t rom_read_addr; + uint8_t rom_read_addr; uint32_t current_rx_desc; uint32_t current_tx_desc; @@ -670,7 +670,7 @@ static uint32_t tulip_csr9_read(TULIPState *s) { if (s->device_info->local == 3) { - return ((uint8_t*)nmc93cxx_eeprom_data(s->eeprom))[s->rom_read_addr++]; + return s->eeprom_data[s->rom_read_addr++]; } if (s->csr[9] & CSR9_SR) { if (nmc93cxx_eeprom_read(s->eeprom)) { @@ -717,7 +717,7 @@ tulip_read(uint32_t addr, void *opaque) data = s->csr[addr >> 3]; break; } - //pclog("[%04X:%08X]: CSR9 read %02x, data = %08x.\n", CS, cpu_state.pc, addr, data); + pclog("[%04X:%08X]: CSR9 read %02x, data = %08x.\n", CS, cpu_state.pc, addr, data); return data; } @@ -906,7 +906,7 @@ tulip_write(uint32_t addr, uint32_t data, void *opaque) TULIPState *s = opaque; addr &= 127; - //pclog("[%04X:%08X]: Tulip Write >> 3: %02x, val=%08x.\n", CS, cpu_state.pc, addr >> 3, data); + pclog("[%04X:%08X]: Tulip Write >> 3: %02x, val=%08x.\n", CS, cpu_state.pc, addr >> 3, data); switch (addr) { case CSR(0): s->csr[0] = data; @@ -1266,11 +1266,11 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { TULIPState *s = (TULIPState *) priv; - //pclog("PCI write=%02x, ret=%02x.\n", addr, val); + pclog("PCI write=%02x, ret=%02x.\n", addr, val); switch (addr) { case 0x04: s->pci_conf[0x04] = val & 0x07; - //pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); + pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); io_removehandler(s->PCIBase, 128, tulip_readb_io, tulip_readw_io, tulip_readl_io, tulip_writeb_io, tulip_writew_io, tulip_writel_io, @@ -1280,7 +1280,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) tulip_readb_io, tulip_readw_io, tulip_readl_io, tulip_writeb_io, tulip_writew_io, tulip_writel_io, priv); - //pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); + pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); mem_mapping_disable(&s->memory); if ((s->MMIOBase != 0) && (val & PCI_COMMAND_MEM)) mem_mapping_set_addr(&s->memory, s->MMIOBase, 128); @@ -1300,7 +1300,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) tulip_pci_bar[0].addr &= 0xffffff80; s->PCIBase = tulip_pci_bar[0].addr; if (s->pci_conf[0x4] & PCI_COMMAND_IO) { - //pclog("PCI write=%02x, base=%04x, io?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_IO); + pclog("PCI write=%02x, base=%04x, io?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_IO); if (s->PCIBase != 0) io_sethandler(s->PCIBase, 128, tulip_readb_io, tulip_readw_io, tulip_readl_io, @@ -1317,7 +1317,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) tulip_pci_bar[1].addr &= 0xffffff80; s->MMIOBase = tulip_pci_bar[1].addr; if (s->pci_conf[0x4] & PCI_COMMAND_MEM) { - //pclog("PCI write=%02x, mmiobase=%08x, mmio?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_MEM); + pclog("PCI write=%02x, mmiobase=%08x, mmio?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_MEM); if (s->MMIOBase != 0) mem_mapping_set_addr(&s->memory, s->MMIOBase, 128); } @@ -1510,6 +1510,9 @@ nic_init(const device_t *info) } else { /* 21040 is supposed to only have MAC address in its serial ROM if Linux is correct. */ memset(s->eeprom_data, 0, sizeof(s->eeprom_data)); + /* See if we have a local MAC address configured. */ + mac = device_get_config_mac("mac", -1); + /*DEC OID*/ s->eeprom_data[0] = 0x00; s->eeprom_data[1] = 0x00; s->eeprom_data[2] = 0xF8; @@ -1529,14 +1532,16 @@ nic_init(const device_t *info) } } - params.nwords = 64; - params.default_content = (uint16_t *) s->eeprom_data; - params.filename = filename; - snprintf(filename, sizeof(filename), "nmc93cxx_eeprom_%s_%d.nvr", info->internal_name, device_get_instance()); - s->eeprom = device_add_parameters(&nmc93cxx_device, ¶ms); - if (!s->eeprom) { - free(s); - return NULL; + if (info->local != 3) { + params.nwords = 64; + params.default_content = (uint16_t *) s->eeprom_data; + params.filename = filename; + snprintf(filename, sizeof(filename), "nmc93cxx_eeprom_%s_%d.nvr", info->internal_name, device_get_instance()); + s->eeprom = device_add_parameters(&nmc93cxx_device, ¶ms); + if (!s->eeprom) { + free(s); + return NULL; + } } tulip_pci_bar[0].addr_regs[0] = 1; @@ -1551,11 +1556,11 @@ nic_init(const device_t *info) tulip_pci_bar[2].addr = 0; mem_mapping_disable(&s->bios_rom.mapping); - eeprom_data = (uint8_t *) &nmc93cxx_eeprom_data(s->eeprom)[0]; + eeprom_data = (info->local == 3) ? s->eeprom_data : (uint8_t *) &nmc93cxx_eeprom_data(s->eeprom)[0]; //pclog("EEPROM Data Format=%02x, Count=%02x, MAC=%02x:%02x:%02x:%02x:%02x:%02x.\n", eeprom_data[0x12], eeprom_data[0x13], eeprom_data[0x14], eeprom_data[0x15], eeprom_data[0x16], eeprom_data[0x17], eeprom_data[0x18], eeprom_data[0x19]); memcpy(s->mii_regs, tulip_mdi_default, sizeof(tulip_mdi_default)); - s->nic = network_attach(s, &eeprom_data[20], tulip_receive, NULL); + s->nic = network_attach(s, &eeprom_data[(info->local == 3) ? 0 : 20], tulip_receive, NULL); pci_add_card(PCI_ADD_NORMAL, tulip_pci_read, tulip_pci_write, s, &s->pci_slot); tulip_reset(s); return s; From 530fafe78a8d9e46cddaf71c7439cbcd51891a35 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 20 Jan 2024 17:27:24 +0100 Subject: [PATCH 3/7] Minor keyboard-related fixes. --- src/86box.c | 3 ++- src/device/kbc_at_dev.c | 8 ++++---- src/device/keyboard_at.c | 21 +++++++++++++++++++-- src/include/86box/keyboard.h | 1 + 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/86box.c b/src/86box.c index f72b066a5..8218c208c 100644 --- a/src/86box.c +++ b/src/86box.c @@ -30,10 +30,10 @@ #include #include #include +#include #ifndef _WIN32 # include -# include #endif #ifdef __APPLE__ # include @@ -1048,6 +1048,7 @@ pc_send_ca(uint16_t sc) keyboard_input(1, 0x1D); /* Ctrl key pressed */ keyboard_input(1, 0x38); /* Alt key pressed */ keyboard_input(1, sc); + usleep(50000); keyboard_input(0, sc); keyboard_input(0, 0x38); /* Alt key released */ keyboard_input(0, 0x1D); /* Ctrl key released */ diff --git a/src/device/kbc_at_dev.c b/src/device/kbc_at_dev.c index 1c1a0e91a..c1041e6e1 100644 --- a/src/device/kbc_at_dev.c +++ b/src/device/kbc_at_dev.c @@ -119,12 +119,13 @@ kbc_at_dev_poll(void *priv) break; case DEV_STATE_MAIN_2: /* Output from scan queue if needed and then return to main loop #1. */ - if (*dev->scan && (dev->port->out_new == -1) && (dev->queue_start != dev->queue_end)) { + if (!dev->ignore && *dev->scan && (dev->port->out_new == -1) && + (dev->queue_start != dev->queue_end)) { kbc_at_dev_log("%s: %02X (DATA) on channel 1\n", dev->name, dev->queue[dev->queue_start]); dev->port->out_new = dev->queue[dev->queue_start]; dev->queue_start = (dev->queue_start + 1) & dev->fifo_mask; } - if (!(*dev->scan) || dev->port->wantcmd) + if (dev->ignore || !(*dev->scan) || dev->port->wantcmd) dev->state = DEV_STATE_MAIN_1; break; case DEV_STATE_MAIN_OUT: @@ -199,8 +200,7 @@ kbc_at_dev_init(uint8_t inst) { atkbc_dev_t *dev; - dev = (atkbc_dev_t *) malloc(sizeof(atkbc_dev_t)); - memset(dev, 0x00, sizeof(atkbc_dev_t)); + dev = (atkbc_dev_t *) calloc(1, sizeof(atkbc_dev_t)); dev->port = kbc_at_ports[inst]; diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index f8eddb931..7accb2fd6 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -523,10 +523,12 @@ static void add_data_kbd(uint16_t val) { atkbc_dev_t *dev = SavedKbd; - uint8_t fake_shift[4]; + uint8_t fake_shift[4] = { 0 }; uint8_t num_lock = 0; uint8_t shift_states = 0; + dev->ignore = 1; + keyboard_get_states(NULL, &num_lock, NULL); shift_states = keyboard_get_shift() & STATE_SHIFT_MASK; @@ -541,12 +543,14 @@ add_data_kbd(uint16_t val) /* Num lock on and no shifts are pressed, send non-inverted fake shift. */ switch (keyboard_mode & 0x02) { case 1: + keyboard_at_log("E0 2A\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0x2a; add_data_vals(dev, fake_shift, 2); break; case 2: + keyboard_at_log("E0 12\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0x12; add_data_vals(dev, fake_shift, 2); @@ -562,12 +566,14 @@ add_data_kbd(uint16_t val) /* Num lock off and left shift pressed. */ switch (keyboard_mode & 0x02) { case 1: + keyboard_at_log("E0 AA\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0xaa; add_data_vals(dev, fake_shift, 2); break; case 2: + keyboard_at_log("E0 F0 12\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0xf0; fake_shift[2] = 0x12; @@ -583,12 +589,14 @@ add_data_kbd(uint16_t val) /* Num lock off and right shift pressed. */ switch (keyboard_mode & 0x02) { case 1: + keyboard_at_log("E0 B6\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0xb6; add_data_vals(dev, fake_shift, 2); break; case 2: + keyboard_at_log("E0 F0 59\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0xf0; fake_shift[2] = 0x59; @@ -614,12 +622,14 @@ add_data_kbd(uint16_t val) /* Num lock on and no shifts are pressed, send non-inverted fake shift. */ switch (keyboard_mode & 0x02) { case 1: + keyboard_at_log("E0 AA\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0xaa; add_data_vals(dev, fake_shift, 2); break; case 2: + keyboard_at_log("E0 F0 12\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0xf0; fake_shift[2] = 0x12; @@ -636,12 +646,14 @@ add_data_kbd(uint16_t val) /* Num lock off and left shift pressed. */ switch (keyboard_mode & 0x02) { case 1: + keyboard_at_log("E0 2A\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0x2a; add_data_vals(dev, fake_shift, 2); break; case 2: + keyboard_at_log("E0 12\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0x12; add_data_vals(dev, fake_shift, 2); @@ -656,12 +668,14 @@ add_data_kbd(uint16_t val) /* Num lock off and right shift pressed. */ switch (keyboard_mode & 0x02) { case 1: + keyboard_at_log("E0 36\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0x36; add_data_vals(dev, fake_shift, 2); break; case 2: + keyboard_at_log("E0 59\n"); fake_shift[0] = 0xe0; fake_shift[1] = 0x59; add_data_vals(dev, fake_shift, 2); @@ -680,6 +694,8 @@ add_data_kbd(uint16_t val) kbc_at_dev_queue_add(dev, val, 1); break; } + + dev->ignore = 0; } void @@ -860,7 +876,8 @@ keyboard_at_write(void *priv) case 0xf5: /* set defaults and disable keyboard */ case 0xf6: /* set defaults */ - keyboard_at_log("%s: set defaults%s\n", (val == 0xf6) ? "" : " and disable keyboard"); + keyboard_at_log("%s: set defaults%s\n", + dev->name, (val == 0xf6) ? "" : " and disable keyboard"); keyboard_scan = !(val & 0x01); keyboard_at_log("%s: val = %02X, keyboard_scan = %i\n", dev->name, val, keyboard_scan); diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index a4b079760..759fad714 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -79,6 +79,7 @@ typedef struct atkbc_dev_t { int y; int z; int b; + int ignore; int *scan; From f59bb3373389d8ce196bed8f5843249a8216d024 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 20 Jan 2024 18:11:21 +0100 Subject: [PATCH 4/7] Added the TriGem Richmond. --- src/chipset/intel_piix.c | 11 +++++++++- src/include/86box/machine.h | 1 + src/machine/m_at_socket7.c | 32 +++++++++++++++++++++++++++++ src/machine/machine_table.c | 40 +++++++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 49d720d8b..1f95c28b3 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -1578,7 +1578,16 @@ piix_init(const device_t *info) dev->acpi = device_add(&acpi_intel_device); acpi_set_slot(dev->acpi, dev->pci_slot); acpi_set_nvr(dev->acpi, dev->nvr); - acpi_set_gpireg2_default(dev->acpi, (dev->type > 4) ? 0xf1 : 0xdd); + /* + TriGem Richmond: + - Bit 5: Manufacturing jumper, must be set; + - Bit 4: CMOS clear jumper, must be clear; + - Bit 0: Password switch, must be clear. + */ + if (!strcmp(machine_get_internal_name(), "richmond")) + acpi_set_gpireg2_default(dev->acpi, 0xee); + else + acpi_set_gpireg2_default(dev->acpi, (dev->type > 4) ? 0xf1 : 0xdd); acpi_set_trap_update(dev->acpi, piix_trap_update, dev); dev->ddma = device_add(&ddma_device); diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index b02b64882..9ca9a84be 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -679,6 +679,7 @@ extern int machine_at_thunderbolt_init(const machine_t *); extern int machine_at_mb540n_init(const machine_t *); extern int machine_at_56a5_init(const machine_t *); extern int machine_at_p5mms98_init(const machine_t *); +extern int machine_at_richmond_init(const machine_t *); extern int machine_at_ficva502_init(const machine_t *); diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index d61e4ba6e..c26ad3889 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1014,6 +1014,38 @@ machine_at_p5mms98_init(const machine_t *model) return ret; } +int +machine_at_richmond_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/richmond/RICHMOND.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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); /* PIIX4 */ + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&i430tx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&it8671f_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + device_add(&lm78_device); /* fans: Thermal, CPU, Chassis; temperature: unused */ + device_add(&lm75_1_4a_device); /* temperature: CPU */ + + return ret; +} + int machine_at_ficva502_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index ac7e767b5..8a8e1b2ff 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -10950,6 +10950,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* [TEST] Has AMIKey 'H' KBC firmware. */ + { + .name = "[i430TX] TriGem Richmond", + .internal_name = "richmond", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_richmond_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 2100, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Apollo VPX */ /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA From 485e73d4da7e2182739fb35ee0edb9da86e786bb Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 21 Jan 2024 01:55:05 +0100 Subject: [PATCH 5/7] Added the Gateway Tomahawk (430TX machine). --- src/acpi.c | 4 ++ src/chipset/intel_4x0.c | 2 + src/include/86box/flash.h | 2 + src/include/86box/machine.h | 1 + src/include/86box/net_pcnet.h | 1 + src/machine/m_at_socket7.c | 44 ++++++++++++++++++++ src/machine/machine_table.c | 41 +++++++++++++++++++ src/mem/sst_flash.c | 75 ++++++++++++++++++++++++++++++----- src/network/net_pcnet.c | 21 +++++++++- 9 files changed, 179 insertions(+), 12 deletions(-) diff --git a/src/acpi.c b/src/acpi.c index 9521d5337..ddd2ffbe7 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -1669,6 +1669,10 @@ acpi_reset(void *priv) acpi_power_on = 0; } + /* The Gateway Tomahawk requires the LID polarity bit to be set. */ + if (!strcmp(machine_get_internal_name(), "tomahawk")) + dev->regs.glbctl |= 0x02000000; + acpi_rtc_status = 0; acpi_update_irq(dev); diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 1e4158b94..a1f923e49 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -1522,6 +1522,8 @@ i4x0_read(int func, int addr, void *priv) with the addition of bits 3 and 0. */ if ((func == 0) && (addr == 0x93) && ((dev->type == INTEL_440FX) || (dev->type == INTEL_440LX) || (dev->type == INTEL_440EX))) ret = (ret & 0xf9) | (pci_read(0x0cf9, NULL) & 0x06); + else if ((func == 0) && (addr == 0x52) && (dev->type == INTEL_430TX) && !strcmp(machine_get_internal_name(), "tomahawk")) + ret = 0xb2; } return ret; diff --git a/src/include/86box/flash.h b/src/include/86box/flash.h index d161d416b..6f0e1ff15 100644 --- a/src/include/86box/flash.h +++ b/src/include/86box/flash.h @@ -60,4 +60,6 @@ extern const device_t sst_flash_49lf080_device; extern const device_t sst_flash_49lf016_device; extern const device_t sst_flash_49lf160_device; +extern const device_t amd_flash_29f020a_device; + #endif /*EMU_FLASH_H*/ diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 9ca9a84be..faed59dae 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -680,6 +680,7 @@ extern int machine_at_mb540n_init(const machine_t *); extern int machine_at_56a5_init(const machine_t *); extern int machine_at_p5mms98_init(const machine_t *); extern int machine_at_richmond_init(const machine_t *); +extern int machine_at_tomahawk_init(const machine_t *); extern int machine_at_ficva502_init(const machine_t *); diff --git a/src/include/86box/net_pcnet.h b/src/include/86box/net_pcnet.h index ccdc7e832..23ee643ed 100644 --- a/src/include/86box/net_pcnet.h +++ b/src/include/86box/net_pcnet.h @@ -36,5 +36,6 @@ extern const device_t pcnet_am79c960_vlb_device; extern const device_t pcnet_am79c961_device; extern const device_t pcnet_am79c970a_device; extern const device_t pcnet_am79c973_device; +extern const device_t pcnet_am79c973_onboard_device; #endif /*NET_PCNET_H*/ diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index c26ad3889..46b95ce76 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -43,6 +43,8 @@ #include <86box/fdc.h> #include <86box/nvr.h> #include <86box/scsi_ncr53c8xx.h> +#include <86box/thread.h> +#include <86box/network.h> int machine_at_acerv35n_init(const machine_t *model) @@ -1046,6 +1048,48 @@ machine_at_richmond_init(const machine_t *model) return ret; } +int +machine_at_tomahawk_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/tomahawk/0AAGT046.ROM", + 0x000c0000, 262144, 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(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); /* PIIX4 */ + pci_register_slot(0x0D, PCI_CARD_VIDEO, 3, 0, 0, 0); + pci_register_slot(0x0E, PCI_CARD_NETWORK, 4, 0, 0, 0); + pci_register_slot(0x06, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x08, PCI_CARD_NORMAL, 3, 4, 1, 2); + device_add(&i430tx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&fdc37c67x_device); + device_add(&amd_flash_29f020a_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + device_add(&lm78_device); /* fans: Thermal, CPU, Chassis; temperature: unused */ + device_add(&lm75_1_4a_device); /* temperature: CPU */ + + if ((gfxcard[0] == VID_INTERNAL) && machine_get_vid_device(machine)) + device_add(machine_get_vid_device(machine)); + + if ((sound_card_current[0] == SOUND_INTERNAL) && machine_get_snd_device(machine)) + device_add(machine_get_snd_device(machine)); + + if ((net_cards_conf[0].device_num == NET_INTERNAL) && machine_get_net_device(machine)) + device_add(machine_get_net_device(machine)); + + return ret; +} + int machine_at_ficva502_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 8a8e1b2ff..7406cce30 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -33,6 +33,7 @@ #include <86box/sound.h> #include <86box/video.h> #include <86box/plat_unused.h> +#include <86box/net_pcnet.h> // Temporarily here till we move everything out into the right files extern const device_t pcjr_device; @@ -10708,6 +10709,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* [TEST] Has AMI Megakey '5' KBC firmware on the SM(S)C FDC37C67x Super I/O chip. */ + { + .name = "[i430TX] Gateway Tomahawk", + .internal_name = "tomahawk", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_tomahawk_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 2100, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_NIC, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &s3_trio64v2_dx_onboard_pci_device, + .snd_device = &cs4236b_device, + .net_device = &pcnet_am79c973_onboard_device + }, #if defined(DEV_BRANCH) && defined(USE_AN430TX) /* This has the Phoenix MultiKey KBC firmware. */ { diff --git a/src/mem/sst_flash.c b/src/mem/sst_flash.c index 472a042d1..cd6ec7cd9 100644 --- a/src/mem/sst_flash.c +++ b/src/mem/sst_flash.c @@ -131,6 +131,9 @@ static char flash_path[1024]; #define W29C020 0x4500 #define W29C040 0x4600 +#define AMD 0x01 /* AMD Manufacturer's ID */ +#define AMD29F020A 0xb000 + #define SIZE_512K 0x010000 #define SIZE_1M 0x020000 #define SIZE_2M 0x040000 @@ -144,12 +147,32 @@ sst_sector_erase(sst_t *dev, uint32_t addr) { uint32_t base = addr & (dev->mask & ~0xfff); - if ((base < 0x2000) && (dev->bbp_first_8k & 0x01)) - return; - else if ((base >= (dev->size - 0x2000)) && (dev->bbp_last_8k & 0x01)) - return; + if (dev->manufacturer == AMD) { + base = addr & biosmask; + + if ((base >= 0x00000) && (base <= 0x0ffff)) + memset(&dev->array[0x00000], 0xff, 65536); + else if ((base >= 0x10000) && (base <= 0x1ffff)) + memset(&dev->array[0x10000], 0xff, 65536); + else if ((base >= 0x20000) && (base <= 0x2ffff)) + memset(&dev->array[0x20000], 0xff, 65536); + else if ((base >= 0x30000) && (base <= 0x37fff)) + memset(&dev->array[0x30000], 0xff, 32768); + else if ((base >= 0x38000) && (base <= 0x39fff)) + memset(&dev->array[0x38000], 0xff, 8192); + else if ((base >= 0x3a000) && (base <= 0x3bfff)) + memset(&dev->array[0x3a000], 0xff, 8192); + else if ((base >= 0x3c000) && (base <= 0x3ffff)) + memset(&dev->array[0x3c000], 0xff, 16384); + } else { + if ((base < 0x2000) && (dev->bbp_first_8k & 0x01)) + return; + else if ((base >= (dev->size - 0x2000)) && (dev->bbp_last_8k & 0x01)) + return; + + memset(&dev->array[base], 0xff, 4096); + } - memset(&dev->array[base], 0xff, 4096); dev->dirty = 1; } @@ -262,10 +285,14 @@ sst_read_id(uint32_t addr, void *priv) { const sst_t *dev = (sst_t *) priv; uint8_t ret = 0x00; + uint32_t mask = 0xffff; - if ((addr & 0xffff) == 0) + if (dev->manufacturer == AMD) + mask >>= 8; + + if ((addr & mask) == 0) ret = dev->manufacturer; - else if ((addr & 0xffff) == 1) + else if ((addr & mask) == 1) ret = dev->id; #ifdef UNKNOWN_FLASH else if ((addr & 0xffff) == 0x100) @@ -278,6 +305,9 @@ sst_read_id(uint32_t addr, void *priv) ret = dev->bbp_first_8k; else if (addr == 0x3fff2) ret = dev->bbp_last_8k; + } else if (dev->manufacturer == AMD) { + if ((addr & mask) == 2) + ret = 0x00; } return ret; @@ -300,6 +330,15 @@ static void sst_write(uint32_t addr, uint8_t val, void *priv) { sst_t *dev = (sst_t *) priv; + uint32_t mask = 0x7fff; + uint32_t addr0 = 0x5555; + uint32_t addr1 = 0x2aaa; + + if (dev->manufacturer == AMD) { + mask >>= 4; + addr0 >>= 4; + addr1 >>= 4; + } switch (dev->command_state) { case 0: @@ -309,7 +348,7 @@ sst_write(uint32_t addr, uint8_t val, void *priv) if (dev->id_mode) dev->id_mode = 0; dev->command_state = 0; - } else if (((addr & 0x7fff) == 0x5555) && (val == 0xaa)) + } else if (((addr & mask) == addr0) && (val == 0xaa)) dev->command_state++; else { if (!dev->is_39 && !dev->sdp && (dev->command_state == 0)) { @@ -326,7 +365,7 @@ sst_write(uint32_t addr, uint8_t val, void *priv) case 1: case 4: /* 2nd and 5th Bus Write Cycle */ - if (((addr & 0x7fff) == 0x2aaa) && (val == 0x55)) + if (((addr & mask) == addr1) && (val == 0x55)) dev->command_state++; else dev->command_state = 0; @@ -337,7 +376,7 @@ sst_write(uint32_t addr, uint8_t val, void *priv) if ((dev->command_state == 5) && (val == SST_SECTOR_ERASE)) { /* Sector erase - can be on any address. */ sst_new_command(dev, addr, val); - } else if ((addr & 0x7fff) == 0x5555) + } else if ((addr & mask) == addr0) sst_new_command(dev, addr, val); else dev->command_state = 0; @@ -481,6 +520,8 @@ sst_init(const device_t *info) dev->id = (info->local >> 8) & 0xff; dev->has_bbp = (dev->manufacturer == WINBOND) && ((info->local & 0xff00) >= W29C020); dev->is_39 = (dev->manufacturer == SST) && ((info->local & 0xff00) >= SST39SF512); + if (dev->manufacturer == AMD) + dev->is_39 = 1; dev->size = info->local & 0xffff0000; if ((dev->size == 0x20000) && (strstr(machine_get_internal_name_ex(machine), "xi8088")) && !xi8088_bios_128kb()) @@ -941,3 +982,17 @@ const device_t sst_flash_49lf160_device = { .force_redraw = NULL, .config = NULL }; + +const device_t amd_flash_29f020a_device = { + .name = "AMD 29F020a Flash BIOS", + .internal_name = "amd_flash_29f020a", + .flags = 0, + .local = AMD | AMD29F020A | SIZE_2M, + .init = sst_init, + .close = sst_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index 02e3d32e7..9ddcfe29d 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -2896,7 +2896,7 @@ pcnet_init(const device_t *info) dev = malloc(sizeof(nic_t)); memset(dev, 0x00, sizeof(nic_t)); dev->name = info->name; - dev->board = info->local; + dev->board = info->local & 0xff; dev->is_pci = !!(info->flags & DEVICE_PCI); dev->is_vlb = !!(info->flags & DEVICE_VLB); @@ -2997,7 +2997,10 @@ pcnet_init(const device_t *info) pcnet_pci_regs[0x04] = 3; /* Add device to the PCI bus, keep its slot number. */ - pci_add_card(PCI_ADD_NORMAL, pcnet_pci_read, pcnet_pci_write, dev, &dev->pci_slot); + if (info->local & 0x0100) + pci_add_card(PCI_ADD_NETWORK, pcnet_pci_read, pcnet_pci_write, dev, &dev->pci_slot); + else + pci_add_card(PCI_ADD_NORMAL, pcnet_pci_read, pcnet_pci_write, dev, &dev->pci_slot); } else if (dev->board == DEV_AM79C961) { dev->dma_channel = -1; @@ -3269,3 +3272,17 @@ const device_t pcnet_am79c973_device = { .force_redraw = NULL, .config = pcnet_pci_config }; + +const device_t pcnet_am79c973_onboard_device = { + .name = "AMD PCnet-FAST III", + .internal_name = "pcnetfast_onboard", + .flags = DEVICE_PCI, + .local = DEV_AM79C973 | 0x0100, + .init = pcnet_init, + .close = pcnet_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = pcnet_pci_config +}; From 0da14beb397efa443bdf454760c6158bcd18a0fc Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 21 Jan 2024 13:28:29 +0600 Subject: [PATCH 6/7] Implement 21040 checksum algorithm --- src/network/net_tulip.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index 3dab8d915..6c01f58ee 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -717,7 +717,7 @@ tulip_read(uint32_t addr, void *opaque) data = s->csr[addr >> 3]; break; } - pclog("[%04X:%08X]: CSR9 read %02x, data = %08x.\n", CS, cpu_state.pc, addr, data); + //pclog("[%04X:%08X]: CSR9 read %02x, data = %08x.\n", CS, cpu_state.pc, addr, data); return data; } @@ -906,7 +906,7 @@ tulip_write(uint32_t addr, uint32_t data, void *opaque) TULIPState *s = opaque; addr &= 127; - pclog("[%04X:%08X]: Tulip Write >> 3: %02x, val=%08x.\n", CS, cpu_state.pc, addr >> 3, data); + //pclog("[%04X:%08X]: Tulip Write >> 3: %02x, val=%08x.\n", CS, cpu_state.pc, addr >> 3, data); switch (addr) { case CSR(0): s->csr[0] = data; @@ -1266,7 +1266,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { TULIPState *s = (TULIPState *) priv; - pclog("PCI write=%02x, ret=%02x.\n", addr, val); + //pclog("PCI write=%02x, ret=%02x.\n", addr, val); switch (addr) { case 0x04: s->pci_conf[0x04] = val & 0x07; @@ -1508,6 +1508,7 @@ nic_init(const device_t *info) s->eeprom_data[126] = tulip_srom_crc(s->eeprom_data) & 0xff; s->eeprom_data[127] = tulip_srom_crc(s->eeprom_data) >> 8; } else { + uint32_t checksum = 0; /* 21040 is supposed to only have MAC address in its serial ROM if Linux is correct. */ memset(s->eeprom_data, 0, sizeof(s->eeprom_data)); /* See if we have a local MAC address configured. */ @@ -1530,6 +1531,31 @@ nic_init(const device_t *info) s->eeprom_data[4] = (mac >> 8) & 0xff; s->eeprom_data[5] = (mac & 0xff); } + + /* Generate checksum. */ + checksum = (s->eeprom_data[0] * 256) | s->eeprom_data[1]; + checksum *= 2; + if (checksum > 65535) + checksum = checksum % 65535; + + /* 2nd pair. */ + checksum += (s->eeprom_data[2] * 256) | s->eeprom_data[3]; + if (checksum > 65535) + checksum = checksum % 65535; + checksum *= 2; + if (checksum > 65535) + checksum = checksum % 65535; + + /* 3rd pair. */ + checksum += (s->eeprom_data[4] * 256) | s->eeprom_data[5]; + if (checksum > 65535) + checksum = checksum % 65535; + + if (checksum >= 65535) + checksum = 0; + + s->eeprom_data[6] = (checksum >> 8) & 0xFF; + s->eeprom_data[7] = checksum & 0xFF; } if (info->local != 3) { From b241817c7b0a8bf35be6fb92b249c4bfbfc4602f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 21 Jan 2024 13:45:36 +0600 Subject: [PATCH 7/7] Disable more logging --- src/network/net_tulip.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index 6c01f58ee..a350d6662 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -1270,7 +1270,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) switch (addr) { case 0x04: s->pci_conf[0x04] = val & 0x07; - pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); + //pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); io_removehandler(s->PCIBase, 128, tulip_readb_io, tulip_readw_io, tulip_readl_io, tulip_writeb_io, tulip_writew_io, tulip_writel_io, @@ -1280,7 +1280,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) tulip_readb_io, tulip_readw_io, tulip_readl_io, tulip_writeb_io, tulip_writew_io, tulip_writel_io, priv); - pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); + //pclog("PCI write cmd: IOBase=%04x, MMIOBase=%08x, val=%02x.\n", s->PCIBase, s->MMIOBase, s->pci_conf[0x04]); mem_mapping_disable(&s->memory); if ((s->MMIOBase != 0) && (val & PCI_COMMAND_MEM)) mem_mapping_set_addr(&s->memory, s->MMIOBase, 128); @@ -1300,7 +1300,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) tulip_pci_bar[0].addr &= 0xffffff80; s->PCIBase = tulip_pci_bar[0].addr; if (s->pci_conf[0x4] & PCI_COMMAND_IO) { - pclog("PCI write=%02x, base=%04x, io?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_IO); + //pclog("PCI write=%02x, base=%04x, io?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_IO); if (s->PCIBase != 0) io_sethandler(s->PCIBase, 128, tulip_readb_io, tulip_readw_io, tulip_readl_io, @@ -1317,7 +1317,7 @@ tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) tulip_pci_bar[1].addr &= 0xffffff80; s->MMIOBase = tulip_pci_bar[1].addr; if (s->pci_conf[0x4] & PCI_COMMAND_MEM) { - pclog("PCI write=%02x, mmiobase=%08x, mmio?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_MEM); + //pclog("PCI write=%02x, mmiobase=%08x, mmio?=%x.\n", addr, s->PCIBase, s->pci_conf[0x4] & PCI_COMMAND_MEM); if (s->MMIOBase != 0) mem_mapping_set_addr(&s->memory, s->MMIOBase, 128); }