diff --git a/src/86box.c b/src/86box.c index 763d41cd3..00fc3222c 100644 --- a/src/86box.c +++ b/src/86box.c @@ -749,6 +749,26 @@ pc_init_modules(void) wchar_t temp[512]; char tempc[512]; + c = m = 0; + while (machine_get_internal_name_ex(c) != NULL) { + m = machine_available(c); + if (!m) + pclog("Missing machine: %s\n", machine_getname_ex(c)); + c++; + } + + c = m = 0; + while (video_get_internal_name(c) != NULL) { + memset(tempc, 0, sizeof(tempc)); + device_get_name(video_card_getdevice(c), 0, tempc); + if ((c > 1) && !(tempc[0])) + break; + m = video_card_available(c); + if (!m) + pclog("Missing video card: %s\n", tempc); + c++; + } + pc_log("Scanning for ROM images:\n"); c = m = 0; while (machine_get_internal_name_ex(m) != NULL) { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3e82eabe0..ec001a963 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,8 +31,8 @@ set_source_files_properties(${APP_ICON_MACOSX} PROPERTIES # WIN32 marks us as a GUI app on Windows # MACOSX_BUNDLE prepares a macOS application bundle including with the app icon -add_executable(86Box WIN32 MACOSX_BUNDLE 86box.c config.c random.c timer.c io.c acpi.c apm.c - dma.c ddma.c nmi.c pic.c pit.c port_92.c ppi.c pci.c mca.c usb.c +add_executable(86Box WIN32 MACOSX_BUNDLE 86box.c config.c log.c random.c timer.c io.c acpi.c apm.c + dma.c ddma.c nmi.c pic.c pit.c port_6x.c port_92.c ppi.c pci.c mca.c usb.c device.c nvr.c nvr_at.c nvr_ps2.c ${APP_ICON_MACOSX}) if(NEW_DYNAREC) diff --git a/src/acpi.c b/src/acpi.c index 9b0ba6734..0b9676c81 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -72,11 +72,15 @@ acpi_update_irq(acpi_t *dev) if (sci_level) { if (dev->irq_mode == 1) pci_set_irq(dev->slot, dev->irq_pin); + else if (dev->irq_mode == 2) + pci_set_mirq(5, dev->mirq_is_level); else pci_set_mirq(0xf0 | dev->irq_line, 1); } else { if (dev->irq_mode == 1) pci_clear_irq(dev->slot, dev->irq_pin); + else if (dev->irq_mode == 2) + pci_clear_mirq(5, dev->mirq_is_level); else pci_clear_mirq(0xf0 | dev->irq_line, 1); } @@ -84,20 +88,29 @@ acpi_update_irq(acpi_t *dev) void -acpi_raise_smi(acpi_t *dev) +acpi_raise_smi(void *priv, int do_smi) { + acpi_t *dev = (acpi_t *) priv; + if (dev->regs.glbctl & 0x01) { if ((dev->vendor == VEN_VIA) || (dev->vendor == VEN_VIA_596B)) { - if ((!dev->regs.smi_lock || !dev->regs.smi_active)) { - smi_line = 1; + if ((!dev->regs.smi_lock || !dev->regs.smi_active)) { + if (do_smi) + smi_line = 1; dev->regs.smi_active = 1; } } else if ((dev->vendor == VEN_INTEL) || (dev->vendor == VEN_ALI)) { - smi_line = 1; + if (do_smi) + smi_line = 1; /* Clear bit 16 of GLBCTL. */ - dev->regs.glbctl &= ~0x00010000; - } else if (dev->vendor == VEN_SMC) - smi_line = 1; + if (dev->vendor == VEN_INTEL) + dev->regs.glbctl &= ~0x00010000; + else + dev->regs.ali_soft_smi = 1; + } else if (dev->vendor == VEN_SMC) { + if (do_smi) + smi_line = 1; + } } } @@ -159,8 +172,7 @@ acpi_reg_read_ali(int size, uint16_t addr, void *p) shift16 = (addr & 1) << 3; shift32 = (addr & 3) << 3; - switch(addr) - { + switch(addr) { case 0x10: case 0x11: case 0x12: case 0x13: /* PCNTRL - Processor Control Register (IO) */ ret = (dev->regs.pcntrl >> shift16) & 0xff; @@ -175,39 +187,33 @@ acpi_reg_read_ali(int size, uint16_t addr, void *p) break; case 0x18: case 0x19: /* GPE0_STS - General Purpose Event0 Status Register */ - ret = (dev->regs.gpsts >> shift16) & 0xff; - break; + ret = (dev->regs.gpsts >> shift16) & 0xff; + break; case 0x1a: case 0x1b: /* GPE0_EN - General Purpose Event0 Enable Register */ - ret = (dev->regs.gpen >> shift16) & 0xff; - break; + ret = (dev->regs.gpen >> shift16) & 0xff; + break; case 0x1d: case 0x1c: /* GPE1_STS - General Purpose Event1 Status Register */ - ret = (dev->regs.gpsts >> shift16) & 0xff; - break; + ret = (dev->regs.gpsts1 >> shift16) & 0xff; + break; case 0x1f: case 0x1e: /* GPE1_EN - General Purpose Event1 Enable Register */ - ret = (dev->regs.gpen1 >> shift16) & 0xff; - break; - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: + ret = (dev->regs.gpen1 >> shift16) & 0xff; + break; + case 0x20 ... 0x27: /* GPE1_CTL - General Purpose Event1 Control Register */ - ret = (dev->regs.gpcntrl >> shift32) & 0xff; - break; + ret = (dev->regs.gpcntrl >> shift32) & 0xff; + break; case 0x30: /* PM2_CNTRL - Power Management 2 Control Register( */ - ret = dev->regs.pmcntrl; - break; + ret = dev->regs.pmcntrl; + break; default: ret = acpi_reg_read_common_regs(size, addr, p); break; - } + } + #ifdef ENABLE_ACPI_LOG if (size != 1) acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret); @@ -291,6 +297,7 @@ acpi_reg_read_intel(int size, uint16_t addr, void *p) return ret; } + static uint32_t acpi_reg_read_sis(int size, uint16_t addr, void *p) { @@ -714,44 +721,37 @@ acpi_reg_write_ali(int size, uint16_t addr, uint8_t val, void *p) break; case 0x18: case 0x19: /* GPE0_STS - General Purpose Event0 Status Register */ - dev->regs.gpsts &= ~((val << shift16) & 0x0d07); - break; + dev->regs.gpsts &= ~((val << shift16) & 0x0d07); + break; case 0x1a: case 0x1b: /* GPE0_EN - General Purpose Event0 Enable Register */ - dev->regs.gpen = ((dev->regs.gpen & ~(0xff << shift16)) | (val << shift16)) & 0x0d07; - break; + dev->regs.gpen = ((dev->regs.gpen & ~(0xff << shift16)) | (val << shift16)) & 0x0d07; + break; case 0x1d: case 0x1c: /* GPE1_STS - General Purpose Event1 Status Register */ - dev->regs.gpsts &= ~((val << shift16) & 0x0c01); - break; + dev->regs.gpsts1 &= ~((val << shift16) & 0x0c01); + break; case 0x1f: case 0x1e: /* GPE1_EN - General Purpose Event1 Enable Register */ - dev->regs.gpen = ((dev->regs.gpen & ~(0xff << shift16)) | (val << shift16)) & 0x0c01; - break; - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: + dev->regs.gpen1 = ((dev->regs.gpen & ~(0xff << shift16)) | (val << shift16)) & 0x0c01; + break; + case 0x20 ... 0x27: /* GPE1_CTL - General Purpose Event1 Control Register */ - dev->regs.gpcntrl = ((dev->regs.gpcntrl & ~(0xff << shift32)) | (val << shift32)) & 0x00000001; - break; + dev->regs.gpcntrl = ((dev->regs.gpcntrl & ~(0xff << shift32)) | (val << shift32)) & 0x00000001; + break; case 0x30: /* PM2_CNTRL - Power Management 2 Control Register( */ - dev->regs.pmcntrl = val & 1; - break; + dev->regs.pmcntrl = val & 1; + break; default: acpi_reg_write_common_regs(size, addr, val, p); /* Setting GBL_RLS also sets BIOS_STS and generates SMI. */ if ((addr == 0x00) && !(dev->regs.pmsts & 0x20)) - dev->regs.glbctl &= ~0x0002; + dev->regs.gpcntrl &= ~0x0002; else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) { - dev->regs.glbsts |= 0x01; - if (dev->regs.glben & 0x02) - acpi_raise_smi(dev); + dev->regs.gpsts1 |= 0x01; + if (dev->regs.gpen1 & 0x01) + acpi_raise_smi(dev, 1); } } } @@ -829,7 +829,7 @@ acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p) else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) { dev->regs.glbsts |= 0x01; if (dev->regs.glben & 0x02) - acpi_raise_smi(dev); + acpi_raise_smi(dev, 1); } break; } @@ -978,7 +978,7 @@ acpi_reg_write_via_common(int size, uint16_t addr, uint8_t val, void *p) dev->regs.smicmd = val & 0xff; dev->regs.glbsts |= 0x40; if (dev->regs.glben & 0x40) - acpi_raise_smi(dev); + acpi_raise_smi(dev, 1); } break; case 0x38: case 0x39: case 0x3a: case 0x3b: @@ -993,7 +993,7 @@ acpi_reg_write_via_common(int size, uint16_t addr, uint8_t val, void *p) else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) { dev->regs.glbsts |= 0x20; if (dev->regs.glben & 0x20) - acpi_raise_smi(dev); + acpi_raise_smi(dev, 1); } break; } @@ -1125,7 +1125,7 @@ acpi_reg_write_smc(int size, uint16_t addr, uint8_t val, void *p) else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) { dev->regs.glbsts |= 0x01; if (dev->regs.glben & 0x01) - acpi_raise_smi(dev); + acpi_raise_smi(dev, 1); } } @@ -1554,6 +1554,13 @@ acpi_set_irq_line(acpi_t *dev, int irq_line) } +void +acpi_set_mirq_is_level(acpi_t *dev, int mirq_is_level) +{ + dev->mirq_is_level = mirq_is_level; +} + + void acpi_set_gpireg2_default(acpi_t *dev, uint8_t gpireg2_default) { @@ -1577,6 +1584,20 @@ acpi_set_trap_update(acpi_t *dev, void (*update)(void *priv), void *priv) } +uint8_t +acpi_ali_soft_smi_status_read(acpi_t *dev) +{ + return dev->regs.ali_soft_smi = 1; +} + + +void +acpi_ali_soft_smi_status_write(acpi_t *dev, uint8_t soft_smi) +{ + dev->regs.ali_soft_smi = soft_smi; +} + + static void acpi_apm_out(uint16_t port, uint8_t val, void *p) { @@ -1586,15 +1607,25 @@ acpi_apm_out(uint16_t port, uint8_t val, void *p) port &= 0x0001; - if (port == 0x0000) { - dev->apm->cmd = val; - if (dev->apm->do_smi) { - if ((dev->vendor == VEN_INTEL) || (dev->vendor == VEN_ALI)) + if (dev->vendor == VEN_ALI) { + if (port == 0x0001) { + acpi_log("ALi SOFT SMI# status set (%i)\n", dev->apm->do_smi); + dev->apm->cmd = val; + // acpi_raise_smi(dev, dev->apm->do_smi); + if (dev->apm->do_smi) + smi_line = 1; + dev->regs.ali_soft_smi = 1; + } else if (port == 0x0003) + dev->apm->stat = val; + } else { + if (port == 0x0000) { + dev->apm->cmd = val; + if (dev->vendor == VEN_INTEL) dev->regs.glbsts |= 0x20; - acpi_raise_smi(dev); - } - } else - dev->apm->stat = val; + acpi_raise_smi(dev, dev->apm->do_smi); + } else + dev->apm->stat = val; + } } @@ -1606,10 +1637,17 @@ acpi_apm_in(uint16_t port, void *p) port &= 0x0001; - if (port == 0x0000) - ret = dev->apm->cmd; - else - ret = dev->apm->stat; + if (dev->vendor == VEN_ALI) { + if (port == 0x0001) + ret = dev->apm->cmd; + else if (port == 0x0003) + ret = dev->apm->stat; + } else { + if (port == 0x0000) + ret = dev->apm->cmd; + else + ret = dev->apm->stat; + } acpi_log("[%04X:%08X] APM read: %04X = %02X\n", CS, cpu_state.pc, port, ret); @@ -1705,8 +1743,14 @@ acpi_init(const device_t *info) dev->irq_line = 9; if ((dev->vendor == VEN_INTEL) || (dev->vendor == VEN_ALI)) { + if (dev->vendor == VEN_ALI) + dev->irq_mode = 2; dev->apm = device_add(&apm_pci_acpi_device); - io_sethandler(0x00b2, 0x0002, acpi_apm_in, NULL, NULL, acpi_apm_out, NULL, NULL, dev); + if (dev->vendor == VEN_ALI) { + acpi_log("Setting I/O handler at port B1\n"); + io_sethandler(0x00b1, 0x0003, acpi_apm_in, NULL, NULL, acpi_apm_out, NULL, NULL, dev); + } else + io_sethandler(0x00b2, 0x0002, acpi_apm_in, NULL, NULL, acpi_apm_out, NULL, NULL, dev); } else if (dev->vendor == VEN_VIA) { dev->i2c = i2c_gpio_init("smbus_vt82c586b"); i2c_smbus = i2c_gpio_get_bus(dev->i2c); diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt index f506ecc42..ce5bded9a 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -13,28 +13,13 @@ # Copyright 2020,2021 David Hrdlička. # -add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1217.c ali1429.c ali1489.c et6000.c headland.c - intel_82335.c cs4031.c intel_420ex.c intel_4x0.c intel_sio.c intel_piix.c ../ioapic.c - neat.c opti283.c opti291.c opti495.c opti822.c opti895.c opti5x7.c scamp.c scat.c - sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c - umc_8886.c umc_8890.c umc_hb4.c - via_vt82c49x.c via_vt82c505.c sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c - gc100.c stpc.c - via_apollo.c via_pipc.c wd76c10.c - vl82c480.c) - -if(I450KX) - target_sources(chipset PRIVATE intel_i450kx.c) -endif() - -if(M154X) - target_sources(chipset PRIVATE ali1531.c) - target_sources(chipset PRIVATE ali1543.c) -endif() - -if(M6117) - target_sources(chipset PRIVATE ali6117.c) -endif() +add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1489.c ali1531.c ali1541.c ali1543.c + ali1621.c ali6117.c headland.c intel_82335.c contaq_82c59x.c cs4031.c intel_420ex.c + intel_4x0.c intel_i450kx.c intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c + opti495.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c + sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c sis_85c310.c + sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c umc_hb4.c via_apollo.c + via_pipc.c vl82c480.c wd76c10.c) if(OLIVETTI) target_sources(chipset PRIVATE olivetti_eva.c) diff --git a/src/chipset/ali1217.c b/src/chipset/ali1217.c deleted file mode 100644 index ab05ac0a0..000000000 --- a/src/chipset/ali1217.c +++ /dev/null @@ -1,145 +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. - * - * Implementation of the ALi M1217 chipset. - * - * Note: This chipset has no datasheet, everything were done via - * reverse engineering the BIOS of various machines using it. - * - * Authors: Tiseno100 - * - * Copyright 2021 Tiseno100 - * - */ - -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include "cpu.h" -#include <86box/timer.h> -#include <86box/io.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/port_92.h> -#include <86box/chipset.h> - - -#ifdef ENABLE_ALI1217_LOG -int ali1217_do_log = ENABLE_ALI1217_LOG; -static void -ali1217_log(const char *fmt, ...) -{ - va_list ap; - - if (ali1217_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -#define ali1217_log(fmt, ...) -#endif - -typedef struct -{ - uint8_t index, regs[256]; - int cfg_locked; -} ali1217_t; - -static void ali1217_shadow_recalc(int reg_15, ali1217_t *dev) -{ - for (uint8_t i = 0; i < 4; i++) - mem_set_mem_state_both((reg_15 ? 0xe0000 : 0xc0000) + (i << 15), 0x8000, ((dev->regs[0x14 + reg_15] & (1 << (i * 2))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x14 + reg_15] & (1 << ((i * 2) + 1))) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); - - flushmmucache_nopc(); -} - -static void -ali1217_write(uint16_t addr, uint8_t val, void *priv) -{ - ali1217_t *dev = (ali1217_t *)priv; - - switch (addr) - { - case 0x22: - dev->index = val; - break; - case 0x23: - if (dev->index != 0x13) - ali1217_log("ALi M1217: dev->regs[%02x] = %02x\n", dev->index, val); - else - dev->cfg_locked = !(val == 0xc5); - - if (!dev->cfg_locked) - { - dev->regs[dev->index] = val; - - if ((dev->index == 0x14) || (dev->index == 0x15)) - ali1217_shadow_recalc(dev->index & 1, dev); - } - break; - } -} - -static uint8_t -ali1217_read(uint16_t addr, void *priv) -{ - ali1217_t *dev = (ali1217_t *)priv; - - return (addr == 0x23) ? dev->regs[dev->index] : 0xff; -} - -static void -ali1217_close(void *priv) -{ - ali1217_t *dev = (ali1217_t *)priv; - - free(dev); -} - -static void * -ali1217_init(const device_t *info) -{ - ali1217_t *dev = (ali1217_t *)malloc(sizeof(ali1217_t)); - memset(dev, 0, sizeof(ali1217_t)); - - device_add(&port_92_device); - - dev->cfg_locked = 1; - - /* - - ALi M1217 Ports - - 22h Index Port - 23h Data Port - - */ - io_sethandler(0x0022, 0x0002, ali1217_read, NULL, NULL, ali1217_write, NULL, NULL, dev); - - return dev; -} - -const device_t ali1217_device = { - "ALi M1217", - 0, - 0, - ali1217_init, - ali1217_close, - NULL, - {NULL}, - NULL, - NULL, - NULL}; diff --git a/src/chipset/ali1429.c b/src/chipset/ali1429.c index 08cc6ff14..b96ec7896 100644 --- a/src/chipset/ali1429.c +++ b/src/chipset/ali1429.c @@ -8,15 +8,71 @@ * * Implementation of the ALi M1429 chipset. * - * Note: This chipset has no datasheet, everything were done via - * reverse engineering the BIOS of various machines using it. + * Note: This chipset has no datasheet, everything were done via + * reverse engineering the BIOS of various machines using it. * - * Authors: Tiseno100 - * - * Copyright 2020 Tiseno100 + * Authors: Tiseno100, + * Miran Grca, * + * Copyright 2020,2021 Tiseno100. + * Copyright 2021,2021 Miran Grca. */ +/* + ALi M1429/M1429G Configuration Registers + + Notes: Incorporated sometimes with a M1435 PCI-to-VLB Bridge + M1429G is just a 1429 with Green Functionality + SMM in it's entirety needs more research + + Warning: Register documentation may be inaccurate! + + Register 03h: Write C5h to unlock the configuration registers + + Register 10h & 11h: DRAM Bank Configuration + + Register 12h: + Bit 2: Memory Remapping Enable (128KB) + + Register 13h: + Bit 7: Shadow RAM Enable for F8000-FFFFF + Bit 6: Shadow RAM Enable for F0000-F7FFF + Bit 5: Shadow RAM Enable for E8000-FFFFF + Bit 4: Shadow RAM Enable for E0000-F7FFF + Bit 3: Shadow RAM Enable for D8000-FFFFF + Bit 2: Shadow RAM Enable for D0000-F7FFF + Bit 1: Shadow RAM Enable for C8000-FFFFF + Bit 0: Shadow RAM Enable for C0000-F7FFF + + Register 14h: + Bit 1: Shadow RAM Write for Enabled Segments + Bit 0: Shadow RAM Read for Enabled Segments + + Register 18h: + Bit 6-5-4 (Cache Size) + 0 0 0 32KB + 0 0 1 128KB + 0 1 0 256KB + 0 1 1 512KB + 1 0 0 64KB + 1 0 1 256KB + 1 1 0 512KB + 1 1 1 1MB + + Bit 1: L2 Cache Enable + + Register 20h: + Bits 2-1-0: Bus Clock Speed + 0 0 0: 7.1519Mhz (ATCLK2) + 0 0 1: CLK2IN/4 + 0 1 0: CLK2IN/5 + 0 1 1: CLK2IN/6 + 1 0 0: CLK2IN/8 + 1 0 1: CLK2IN/10 + 1 1 0: CLK2IN/12 + +*/ + #include #include #include @@ -38,17 +94,19 @@ #include <86box/smram.h> #include <86box/chipset.h> -#define disabled_shadow (MEM_READ_EXTANY | MEM_WRITE_EXTANY) +#define GREEN dev->is_g /* Is G Variant */ + #ifdef ENABLE_ALI1429_LOG int ali1429_do_log = ENABLE_ALI1429_LOG; + + static void ali1429_log(const char *fmt, ...) { va_list ap; - if (ali1429_do_log) - { + if (ali1429_do_log) { va_start(ap, fmt); pclog_ex(fmt, ap); va_end(ap); @@ -58,17 +116,17 @@ ali1429_log(const char *fmt, ...) #define ali1429_log(fmt, ...) #endif + typedef struct { - uint8_t index, cfg_locked, - regs[256]; - - smram_t *smram; + uint8_t is_g, index, cfg_locked, reg_57h, + regs[90]; } ali1429_t; -static void ali1429_shadow_recalc(ali1429_t *dev) -{ +static void +ali1429_shadow_recalc(ali1429_t *dev) +{ uint32_t base, i, can_write, can_read; shadowbios = (dev->regs[0x13] & 0x40) && (dev->regs[0x14] & 0x01); @@ -77,66 +135,150 @@ static void ali1429_shadow_recalc(ali1429_t *dev) can_write = (dev->regs[0x14] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; can_read = (dev->regs[0x14] & 0x01) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - for (i = 0; i < 8; i++) - { + for (i = 0; i < 8; i++) { base = 0xc0000 + (i << 15); if (dev->regs[0x13] & (1 << i)) mem_set_mem_state_both(base, 0x8000, can_read | can_write); else - mem_set_mem_state_both(base, 0x8000, disabled_shadow); + mem_set_mem_state_both(base, 0x8000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); } - flushmmucache(); + flushmmucache_nopc(); } + static void ali1429_write(uint16_t addr, uint8_t val, void *priv) { ali1429_t *dev = (ali1429_t *)priv; - switch (addr) - { - case 0x22: - dev->index = val; - break; + switch (addr) { + case 0x22: + dev->index = val; + break; - case 0x23: - if (dev->index != 0x03) - ali1429_log("M1429: dev->regs[%02x] = %02x\n", dev->index, val); + case 0x23: +#ifdef ENABLE_ALI1429_LOG + if (dev->index != 0x03) + ali1429_log("M1429: dev->regs[%02x] = %02x\n", dev->index, val); +#endif - if (dev->index == 0x03) - dev->cfg_locked = !(val == 0xc5); + if (dev->index == 0x03) + dev->cfg_locked = !(val == 0xc5); - if (!dev->cfg_locked) - { - dev->regs[dev->index] = val; + if (!dev->cfg_locked) { + /* Common M1429 Registers */ + switch (dev->index) { + case 0x10: case 0x11: + dev->regs[dev->index] = val; + break; - switch (dev->index) - { - case 0x13: - case 0x14: - ali1429_shadow_recalc(dev); - break; + case 0x12: + dev->regs[dev->index] = val; + if(val & 4) + mem_remap_top(128); + else + mem_remap_top(0); + break; - case 0x18: - cpu_cache_ext_enabled = !!(val & 2); - cpu_update_waitstates(); - break; - } - } + case 0x13: case 0x14: + dev->regs[dev->index] = val; + ali1429_shadow_recalc(dev); + break; - break; + case 0x15: case 0x16: + case 0x17: + dev->regs[dev->index] = val; + break; + + case 0x18: + dev->regs[dev->index] = (val & 0x8f) | 0x20; + cpu_cache_ext_enabled = !!(val & 2); + cpu_update_waitstates(); + break; + + case 0x19: case 0x1a: + case 0x1e: + dev->regs[dev->index] = val; + break; + + case 0x20: + dev->regs[dev->index] = val; + + switch(val & 7) { + case 0: case 7: /* Illegal */ + cpu_set_isa_speed(7159091); + break; + + case 1: + cpu_set_isa_speed(cpu_busspeed / 4); + break; + + case 2: + cpu_set_isa_speed(cpu_busspeed / 5); + break; + + case 3: + cpu_set_isa_speed(cpu_busspeed / 6); + break; + + case 4: + cpu_set_isa_speed(cpu_busspeed / 8); + break; + + case 5: + cpu_set_isa_speed(cpu_busspeed / 10); + break; + + case 6: + cpu_set_isa_speed(cpu_busspeed / 12); + break; + } + break; + + case 0x21 ... 0x27: + dev->regs[dev->index] = val; + break; + } + + /* M1429G Only Registers */ + if (GREEN) { + switch (dev->index) { + case 0x30 ... 0x41: + case 0x43: case 0x45: + case 0x4a: + dev->regs[dev->index] = val; + break; + + case 0x57: + dev->reg_57h = val; + break; + } + } + } + break; } } + static uint8_t ali1429_read(uint16_t addr, void *priv) { ali1429_t *dev = (ali1429_t *)priv; - return (addr == 0x23) ? dev->regs[dev->index] : 0xff; + uint8_t ret = 0xff; + + if ((addr == 0x23) && (dev->index >= 0x10) && (dev->index <= 0x4a)) + ret = dev->regs[dev->index]; + else if ((addr == 0x23) && (dev->index == 0x57)) + ret = dev->reg_57h; + else if (addr == 0x22) + ret = dev->index; + + return ret; } + static void ali1429_close(void *priv) { @@ -145,24 +287,53 @@ ali1429_close(void *priv) free(dev); } + +static void +ali1429_defaults(ali1429_t *dev) +{ + /* M1429 Defaults */ + dev->regs[0x10] = 0xf0; + dev->regs[0x11] = 0xff; + dev->regs[0x12] = 0x10; + dev->regs[0x14] = 0x48; + dev->regs[0x15] = 0x40; + dev->regs[0x17] = 0x7a; + dev->regs[0x1a] = 0x80; + dev->regs[0x22] = 0x80; + dev->regs[0x23] = 0x57; + dev->regs[0x25] = 0xc0; + dev->regs[0x27] = 0x30; + + /* M1429G Default Registers */ + if (GREEN) { + dev->regs[0x31] = 0x88; + dev->regs[0x32] = 0xc0; + dev->regs[0x38] = 0xe5; + dev->regs[0x40] = 0xe3; + dev->regs[0x41] = 2; + dev->regs[0x45] = 0x80; + } +} + + static void * ali1429_init(const device_t *info) { ali1429_t *dev = (ali1429_t *)malloc(sizeof(ali1429_t)); memset(dev, 0, sizeof(ali1429_t)); - /* - M1429 Ports: - 22h Index Port - 23h Data Port + dev->cfg_locked = 1; + GREEN = info->local; + + /* M1429 Ports: + 22h Index Port + 23h Data Port */ io_sethandler(0x0022, 0x0002, ali1429_read, NULL, NULL, ali1429_write, NULL, NULL, dev); - dev->cfg_locked = 1; - - device_add(&apm_device); device_add(&port_92_device); - /* dev->smram = smram_add(); */ + + ali1429_defaults(dev); return dev; } @@ -171,10 +342,16 @@ const device_t ali1429_device = { "ALi M1429", 0, 0, - ali1429_init, - ali1429_close, - NULL, - {NULL}, - NULL, - NULL, - NULL}; + ali1429_init, ali1429_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + +const device_t ali1429g_device = { + "ALi M1429G", + 0, + 1, + ali1429_init, ali1429_close, NULL, + { NULL }, NULL, NULL, + NULL +}; diff --git a/src/chipset/ali1531.c b/src/chipset/ali1531.c index c29d831fc..59080144f 100644 --- a/src/chipset/ali1531.c +++ b/src/chipset/ali1531.c @@ -34,6 +34,7 @@ #include <86box/chipset.h> + typedef struct ali1531_t { uint8_t pci_conf[256]; @@ -41,201 +42,270 @@ typedef struct ali1531_t smram_t *smram; } ali1531_t; -void ali1531_shadow_recalc(int cur_reg, ali1531_t *dev) -{ - for (uint32_t i = 0; i < 8; i++) - mem_set_mem_state_both(0xc0000 + ((cur_reg & 1) << 17) + (i << 14), 0x4000, (((dev->pci_conf[0x4c + (cur_reg & 1)] >> i) & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | (((dev->pci_conf[0x4e + (cur_reg & 1)] >> i) & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); - flushmmucache_nopc(); +#ifdef ENABLE_ALI1531_LOG +int ali1531_do_log = ENABLE_ALI1531_LOG; +static void +ali1531_log(const char *fmt, ...) +{ + va_list ap; + + if (ali1531_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } } +#else +#define ali1531_log(fmt, ...) +#endif -void ali1531_smm_recalc(uint8_t smm_state, ali1531_t *dev) + +static void +ali1531_smram_recalc(uint8_t val, ali1531_t *dev) { - smram_disable_all(); - if (dev->pci_conf[0x48] & 1) - { - switch (smm_state) - { - case 0: - smram_enable(dev->smram, 0xd0000, 0xb0000, 0x10000, 0, 1); - smram_map(1, 0xd0000, 0x10000, 1); - break; - case 1: - smram_enable(dev->smram, 0xd0000, 0xb0000, 0x10000, 1, 1); - smram_map(1, 0xd0000, 0x10000, 1); - break; - case 2: - smram_enable(dev->smram, 0xa0000, 0xa0000, 0x20000, 0, 1); - smram_map(1, 0xa0000, 0x20000, (dev->pci_conf[0x48] & 0x10) ? 2 : 1); - break; - case 3: - smram_enable(dev->smram, 0xa0000, 0xa0000, 0x20000, 1, 1); - smram_map(1, 0xa0000, 0x20000, (dev->pci_conf[0x48] & 0x10) ? 2 : 1); - break; - case 4: - smram_enable(dev->smram, 0x30000, 0xb0000, 0x10000, 0, 1); - smram_map(1, 0x30000, 0x10000, 1); - break; - case 5: - smram_enable(dev->smram, 0x30000, 0xb0000, 0x10000, 1, 1); - smram_map(1, 0x30000, 0x10000, 1); - break; - } + if (val & 1) { + switch (val & 0x0c) { + case 0x00: + ali1531_log("SMRAM: D0000 -> B0000 (%i)\n", val & 2); + smram_enable(dev->smram, 0xd0000, 0xb0000, 0x10000, val & 2, 1); + if (val & 0x10) + mem_set_mem_state_smram_ex(1, 0xd0000, 0x10000, 0x02); + break; + case 0x04: + ali1531_log("SMRAM: A0000 -> A0000 (%i)\n", val & 2); + smram_enable(dev->smram, 0xa0000, 0xa0000, 0x20000, val & 2, 1); + if (val & 0x10) + mem_set_mem_state_smram_ex(1, 0xa0000, 0x20000, 0x02); + break; + case 0x08: + ali1531_log("SMRAM: 30000 -> B0000 (%i)\n", val & 2); + smram_enable(dev->smram, 0x30000, 0xb0000, 0x10000, val & 2, 1); + if (val & 0x10) + mem_set_mem_state_smram_ex(1, 0x30000, 0x10000, 0x02); + break; + } } flushmmucache_nopc(); } + +static void +ali1531_shadow_recalc(int cur_reg, ali1531_t *dev) +{ + int i, bit, r_reg, w_reg; + uint32_t base, flags = 0; + + shadowbios = shadowbios_write = 0; + + for (i = 0; i < 16; i++) { + base = 0x000c0000 + (i << 14); + bit = i & 7; + r_reg = 0x4c + (i >> 3); + w_reg = 0x4e + (i >> 3); + + flags = (dev->pci_conf[r_reg] & (1 << bit)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + flags |= ((dev->pci_conf[w_reg] & (1 << bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY); + + if (base >= 0x000e0000) { + if (dev->pci_conf[r_reg] & (1 << bit)) + shadowbios |= 1; + if (dev->pci_conf[w_reg] & (1 << bit)) + shadowbios_write |= 1; + } + + ali1531_log("%08X-%08X shadow: R%c, W%c\n", base, base + 0x00003fff, + (dev->pci_conf[r_reg] & (1 << bit)) ? 'I' : 'E', (dev->pci_conf[w_reg] & (1 << bit)) ? 'I' : 'E'); + mem_set_mem_state_both(base, 0x00004000, flags); + } + + flushmmucache_nopc(); +} + + static void ali1531_write(int func, int addr, uint8_t val, void *priv) { ali1531_t *dev = (ali1531_t *)priv; - switch (addr) - { - case 0x05: - dev->pci_conf[addr] = val & 1; - break; + switch (addr) { + case 0x04: + dev->pci_conf[addr] = val; + break; + case 0x05: + dev->pci_conf[addr] = val & 0x01; + break; - case 0x07: - dev->pci_conf[addr] = val & 0xfe; - break; + case 0x07: + dev->pci_conf[addr] &= ~(val & 0xf8); + break; - case 0x0d: - dev->pci_conf[addr] = val & 0xf8; - break; + case 0x0d: + dev->pci_conf[addr] = val & 0xf8; + break; - case 0x40: - dev->pci_conf[addr] = val & 0xf1; - break; + case 0x2c: /* Subsystem Vendor ID */ + case 0x2d: + case 0x2e: + case 0x2f: + if (dev->pci_conf[0x70] & 0x08) + dev->pci_conf[addr] = val; + break; - case 0x41: - dev->pci_conf[addr] = val & 0xdf; - break; + case 0x40: + dev->pci_conf[addr] = val & 0xf1; + break; - case 0x42: /* L2 Cache */ - dev->pci_conf[addr] = val & 0xf7; - cpu_cache_ext_enabled = !!(val & 1); - cpu_update_waitstates(); - break; + case 0x41: + dev->pci_conf[addr] = (val & 0xd6) | 0x08; + break; - case 0x43: /* L1 Cache */ - dev->pci_conf[addr] = val; - cpu_cache_int_enabled = !!(val & 1); - cpu_update_waitstates(); - break; + case 0x42: /* L2 Cache */ + dev->pci_conf[addr] = val & 0xf7; + cpu_cache_ext_enabled = !!(val & 1); + cpu_update_waitstates(); + break; - case 0x47: - dev->pci_conf[addr] = val & 0xfc; + case 0x43: /* L1 Cache */ + dev->pci_conf[addr] = val; + cpu_cache_int_enabled = !!(val & 1); + cpu_update_waitstates(); + break; - if (mem_size > 0xe00000) - mem_set_mem_state_both(0xe00000, 0x100000, !(val & 0x20) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); + case 0x44: + dev->pci_conf[addr] = val; + break; + case 0x45: + dev->pci_conf[addr] = val; + break; - if (mem_size > 0xf00000) - mem_set_mem_state_both(0xf00000, 0x100000, !(val & 0x10) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); + case 0x46: + dev->pci_conf[addr] = val; + break; - mem_set_mem_state_both(0xa0000, 0x20000, (val & 8) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); - mem_set_mem_state_both(0x80000, 0x20000, (val & 4) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); - break; + case 0x47: + dev->pci_conf[addr] = val & 0xfc; - case 0x48: /* SMRAM */ - dev->pci_conf[addr] = val; - ali1531_smm_recalc((val >> 1) & 7, dev); - break; + if (mem_size > 0xe00000) + mem_set_mem_state_both(0xe00000, 0x100000, (val & 0x20) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL)); - case 0x49: - dev->pci_conf[addr] = val & 0x73; - break; + if (mem_size > 0xf00000) + mem_set_mem_state_both(0xf00000, 0x100000, (val & 0x10) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL)); - case 0x4c: /* Shadow RAM */ - case 0x4d: - case 0x4e: - case 0x4f: - dev->pci_conf[addr] = val; - ali1531_shadow_recalc(addr, dev); - break; + mem_set_mem_state_both(0xa0000, 0x20000, (val & 8) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); + mem_set_mem_state_both(0x80000, 0x20000, (val & 4) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL)); - case 0x57: /* H2PO */ - dev->pci_conf[addr] = val & 0x60; - if (!(val & 0x20)) - outb(0x92, 0x01); - break; + flushmmucache_nopc(); + break; - case 0x58: - dev->pci_conf[addr] = val & 0x83; - break; + case 0x48: /* SMRAM */ + dev->pci_conf[addr] = val; + ali1531_smram_recalc(val, dev); + break; - case 0x5b: - dev->pci_conf[addr] = val & 0x4f; - break; + case 0x49: + dev->pci_conf[addr] = val & 0x73; + break; - case 0x5d: - dev->pci_conf[addr] = val & 0x53; - break; + case 0x4a: + dev->pci_conf[addr] = val; + break; - case 0x5f: - dev->pci_conf[addr] = val & 0x7f; - break; + case 0x4c ... 0x4f: /* Shadow RAM */ + dev->pci_conf[addr] = val; + ali1531_shadow_recalc(val, dev); + break; - case 0x60: /* DRB's */ - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - case 0x68: - case 0x69: - case 0x6a: - case 0x6b: - case 0x6c: - case 0x6d: - case 0x6e: - case 0x6f: - dev->pci_conf[addr] = val; - spd_write_drbs(dev->pci_conf, 0x60, 0x6f, 1); - break; + case 0x50: case 0x51: case 0x52: case 0x54: + case 0x55: case 0x56: + dev->pci_conf[addr] = val; + break; - case 0x72: - dev->pci_conf[addr] = val & 0xf; - break; + case 0x57: /* H2PO */ + dev->pci_conf[addr] = val & 0x60; + /* Find where the Shut-down Special cycle is initiated. */ + // if (!(val & 0x20)) + // outb(0x92, 0x01); + break; - case 0x74: - dev->pci_conf[addr] = val & 0x2b; - break; + case 0x58: + dev->pci_conf[addr] = val & 0x86; + break; - case 0x80: - dev->pci_conf[addr] = val & 0x84; - break; + case 0x59: case 0x5a: + case 0x5c: + dev->pci_conf[addr] = val; + break; - case 0x81: - dev->pci_conf[addr] = val & 0x81; - break; + case 0x5b: + dev->pci_conf[addr] = val & 0x4f; + break; - case 0x83: - dev->pci_conf[addr] = val & 0x10; - break; + case 0x5d: + dev->pci_conf[addr] = val & 0x53; + break; - default: - dev->pci_conf[addr] = val; - break; + case 0x5f: + dev->pci_conf[addr] = val & 0x7f; + break; + + case 0x60 ... 0x6f: /* DRB's */ + dev->pci_conf[addr] = val; + spd_write_drbs_interleaved(dev->pci_conf, 0x60, 0x6f, 1); + break; + + case 0x70: case 0x71: + dev->pci_conf[addr] = val; + break; + + case 0x72: + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x74: + dev->pci_conf[addr] = val & 0x2b; + break; + + case 0x76: case 0x77: + dev->pci_conf[addr] = val; + break; + + case 0x80: + dev->pci_conf[addr] = val & 0x84; + break; + + case 0x81: + dev->pci_conf[addr] = val & 0x81; + break; + + case 0x83: + dev->pci_conf[addr] = val & 0x10; + break; } } + static uint8_t ali1531_read(int func, int addr, void *priv) { ali1531_t *dev = (ali1531_t *)priv; - return dev->pci_conf[addr]; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + return ret; } + static void ali1531_reset(void *priv) { ali1531_t *dev = (ali1531_t *)priv; + int i; /* Default Registers */ dev->pci_conf[0x00] = 0xb9; @@ -267,11 +337,20 @@ ali1531_reset(void *priv) ali1531_write(0, 0x42, 0x00, dev); ali1531_write(0, 0x43, 0x00, dev); + ali1531_write(0, 0x47, 0x00, dev); - ali1531_write(0, 0x60, 0x08, dev); - ali1531_write(0, 0x61, 0x40, dev); + ali1531_write(0, 0x48, 0x00, dev); + + for (i = 0; i < 4; i++) + ali1531_write(0, 0x4c + i, 0x00, dev); + + for (i = 0; i < 16; i += 2) { + ali1531_write(0, 0x60 + i, 0x08, dev); + ali1531_write(0, 0x61 + i, 0x40, dev); + } } + static void ali1531_close(void *priv) { @@ -281,6 +360,7 @@ ali1531_close(void *priv) free(dev); } + static void * ali1531_init(const device_t *info) { @@ -296,6 +376,7 @@ ali1531_init(const device_t *info) return dev; } + const device_t ali1531_device = { "ALi M1531 CPU-to-PCI Bridge", DEVICE_PCI, @@ -306,4 +387,5 @@ const device_t ali1531_device = { {NULL}, NULL, NULL, - NULL}; + NULL +}; diff --git a/src/chipset/ali1541.c b/src/chipset/ali1541.c new file mode 100644 index 000000000..16587b3fc --- /dev/null +++ b/src/chipset/ali1541.c @@ -0,0 +1,656 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the ALi M1541/2 CPU-to-PCI Bridge. + * + * Authors: Miran Grca, + * + * Copyright 2021 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/timer.h> + +#include <86box/device.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/smram.h> +#include <86box/spd.h> + +#include <86box/chipset.h> + + +typedef struct ali1541_t +{ + uint8_t pci_conf[256]; + + smram_t * smram; + void * agp_bridge; +} ali1541_t; + + +#ifdef ENABLE_ALI1541_LOG +int ali1541_do_log = ENABLE_ALI1541_LOG; +static void +ali1541_log(const char *fmt, ...) +{ + va_list ap; + + if (ali1541_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define ali1541_log(fmt, ...) +#endif + + +static void +ali1541_smram_recalc(uint8_t val, ali1541_t *dev) +{ + smram_disable_all(); + + if (val & 1) { + switch (val & 0x0c) { + case 0x00: + ali1541_log("SMRAM: D0000 -> B0000 (%i)\n", val & 2); + smram_enable(dev->smram, 0xd0000, 0xb0000, 0x10000, val & 2, 1); + if (val & 0x10) + mem_set_mem_state_smram_ex(1, 0xd0000, 0x10000, 0x02); + break; + case 0x04: + ali1541_log("SMRAM: A0000 -> A0000 (%i)\n", val & 2); + smram_enable(dev->smram, 0xa0000, 0xa0000, 0x20000, val & 2, 1); + if (val & 0x10) + mem_set_mem_state_smram_ex(1, 0xa0000, 0x20000, 0x02); + break; + case 0x08: + ali1541_log("SMRAM: 30000 -> B0000 (%i)\n", val & 2); + smram_enable(dev->smram, 0x30000, 0xb0000, 0x10000, val & 2, 1); + if (val & 0x10) + mem_set_mem_state_smram_ex(1, 0x30000, 0x10000, 0x02); + break; + } + } + + flushmmucache_nopc(); +} + + +static void +ali1541_shadow_recalc(int cur_reg, ali1541_t *dev) +{ + int i, bit, r_reg, w_reg; + uint32_t base, flags = 0; + + shadowbios = shadowbios_write = 0; + + for (i = 0; i < 16; i++) { + base = 0x000c0000 + (i << 14); + bit = i & 7; + r_reg = 0x56 + (i >> 3); + w_reg = 0x58 + (i >> 3); + + flags = (dev->pci_conf[r_reg] & (1 << bit)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + flags |= ((dev->pci_conf[w_reg] & (1 << bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY); + + if (base >= 0x000e0000) { + if (dev->pci_conf[r_reg] & (1 << bit)) + shadowbios |= 1; + if (dev->pci_conf[w_reg] & (1 << bit)) + shadowbios_write |= 1; + } + + ali1541_log("%08X-%08X shadow: R%c, W%c\n", base, base + 0x00003fff, + (dev->pci_conf[r_reg] & (1 << bit)) ? 'I' : 'E', (dev->pci_conf[w_reg] & (1 << bit)) ? 'I' : 'E'); + mem_set_mem_state_both(base, 0x00004000, flags); + } + + flushmmucache_nopc(); +} + + +static void +ali1541_mask_bar(ali1541_t *dev) +{ + uint32_t bar, mask; + + switch (dev->pci_conf[0xbc] & 0x0f) { + case 0x00: + default: + mask = 0x00000000; + break; + case 0x01: + mask = 0xfff00000; + break; + case 0x02: + mask = 0xffe00000; + break; + case 0x03: + mask = 0xffc00000; + break; + case 0x04: + mask = 0xff800000; + break; + case 0x06: + mask = 0xff000000; + break; + case 0x07: + mask = 0xfe000000; + break; + case 0x08: + mask = 0xfc000000; + break; + case 0x09: + mask = 0xf8000000; + break; + case 0x0a: + mask = 0xf0000000; + break; + } + + bar = ((dev->pci_conf[0x13] << 24) | (dev->pci_conf[0x12] << 16)) & mask; + dev->pci_conf[0x12] = (bar >> 16) & 0xff; + dev->pci_conf[0x13] = (bar >> 24) & 0xff; +} + + +static void +ali1541_write(int func, int addr, uint8_t val, void *priv) +{ + ali1541_t *dev = (ali1541_t *)priv; + + switch (addr) { + case 0x04: + dev->pci_conf[addr] = val; + break; + case 0x05: + dev->pci_conf[addr] = val & 0x01; + break; + + case 0x07: + dev->pci_conf[addr] &= ~(val & 0xf8); + break; + + case 0x0d: + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x12: + dev->pci_conf[0x12] = (val & 0xc0); + ali1541_mask_bar(dev); + break; + case 0x13: + dev->pci_conf[0x13] = val; + ali1541_mask_bar(dev); + break; + + case 0x2c: /* Subsystem Vendor ID */ + case 0x2d: + case 0x2e: + case 0x2f: + if (dev->pci_conf[0x90] & 0x01) + dev->pci_conf[addr] = val; + break; + + case 0x34: + if (dev->pci_conf[0x90] & 0x02) + dev->pci_conf[addr] = val; + break; + + case 0x40: + dev->pci_conf[addr] = val & 0x7f; + break; + + case 0x41: + dev->pci_conf[addr] = val & 0x7f; + break; + + case 0x42: /* L2 Cache */ + dev->pci_conf[addr] = val; + cpu_cache_ext_enabled = !!(val & 1); + cpu_update_waitstates(); + break; + + case 0x43: /* PLCTL-Pipe Line Control */ + dev->pci_conf[addr] = val & 0xf7; + break; + + case 0x44: + dev->pci_conf[addr] = val; + break; + case 0x45: + dev->pci_conf[addr] = val; + break; + case 0x46: + dev->pci_conf[addr] = val & 0xf0; + break; + case 0x47: + dev->pci_conf[addr] = val; + break; + + case 0x48: + dev->pci_conf[addr] = val; + break; + case 0x49: + dev->pci_conf[addr] = val; + break; + + case 0x4a: + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x4b: + dev->pci_conf[addr] = val; + break; + + case 0x4c: + dev->pci_conf[addr] = val; + break; + case 0x4d: + dev->pci_conf[addr] = val; + break; + + case 0x4e: + dev->pci_conf[addr] = val; + break; + case 0x4f: + dev->pci_conf[addr] = val; + break; + + case 0x50: + dev->pci_conf[addr] = val & 0x71; + break; + + case 0x51: + dev->pci_conf[addr] = val; + break; + + case 0x52: + dev->pci_conf[addr] = val; + break; + + case 0x53: + dev->pci_conf[addr] = val; + break; + + case 0x54: + dev->pci_conf[addr] = val & 0x3c; + + if (mem_size > 0xe00000) + mem_set_mem_state_both(0xe00000, 0x100000, (val & 0x20) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL)); + + if (mem_size > 0xf00000) + mem_set_mem_state_both(0xf00000, 0x100000, (val & 0x10) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL)); + + mem_set_mem_state_both(0xa0000, 0x20000, (val & 8) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); + mem_set_mem_state_both(0x80000, 0x20000, (val & 4) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL)); + + flushmmucache_nopc(); + break; + + case 0x55: /* SMRAM */ + dev->pci_conf[addr] = val & 0x1f; + ali1541_smram_recalc(val, dev); + break; + + case 0x56 ... 0x59: /* Shadow RAM */ + dev->pci_conf[addr] = val; + ali1541_shadow_recalc(val, dev); + break; + + case 0x5a: case 0x5b: + dev->pci_conf[addr] = val; + break; + + case 0x5c: + dev->pci_conf[addr] = val; + break; + + case 0x5d: + dev->pci_conf[addr] = val & 0x17; + break; + + case 0x5e: + dev->pci_conf[addr] = val; + break; + + case 0x5f: + dev->pci_conf[addr] = val & 0xc1; + break; + + case 0x60 ... 0x6f: /* DRB's */ + dev->pci_conf[addr] = val; + spd_write_drbs_interleaved(dev->pci_conf, 0x60, 0x6f, 1); + break; + + case 0x70: + dev->pci_conf[addr] = val; + break; + + case 0x71: + dev->pci_conf[addr] = val; + break; + + case 0x72: + dev->pci_conf[addr] = val & 0xc7; + break; + + case 0x73: + dev->pci_conf[addr] = val & 0x1f; + break; + + case 0x84: case 0x85: + dev->pci_conf[addr] = val; + break; + + case 0x86: + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x87: /* H2PO */ + dev->pci_conf[addr] = val; + /* Find where the Shut-down Special cycle is initiated. */ + // if (!(val & 0x20)) + // outb(0x92, 0x01); + break; + + case 0x88: + dev->pci_conf[addr] = val; + break; + + case 0x89: + dev->pci_conf[addr] = val; + break; + + case 0x8a: + dev->pci_conf[addr] = val; + break; + + case 0x8b: + dev->pci_conf[addr] = val & 0x3f; + break; + + case 0x8c: + dev->pci_conf[addr] = val; + break; + + case 0x8d: + dev->pci_conf[addr] = val; + break; + + case 0x8e: + dev->pci_conf[addr] = val; + break; + + case 0x8f: + dev->pci_conf[addr] = val; + break; + + case 0x90: + dev->pci_conf[addr] = val; + pci_bridge_set_ctl(dev->agp_bridge, val); + break; + + case 0x91: + dev->pci_conf[addr] = val; + break; + + case 0xb4: + if (dev->pci_conf[0x90] & 0x01) + dev->pci_conf[addr] = val & 0x03; + break; + case 0xb5: + if (dev->pci_conf[0x90] & 0x01) + dev->pci_conf[addr] = val & 0x02; + break; + case 0xb7: + if (dev->pci_conf[0x90] & 0x01) + dev->pci_conf[addr] = val; + break; + + case 0xb8: + dev->pci_conf[addr] = val & 0x03; + break; + case 0xb9: + dev->pci_conf[addr] = val & 0x03; + break; + case 0xbb: + dev->pci_conf[addr] = val; + break; + + case 0xbc: + dev->pci_conf[addr] = val & 0x0f; + ali1541_mask_bar(dev); + break; + case 0xbd: + dev->pci_conf[addr] = val & 0xf0; + break; + case 0xbe: case 0xbf: + dev->pci_conf[addr] = val; + break; + + case 0xc0: + dev->pci_conf[addr] = val & 0x90; + break; + case 0xc1: case 0xc2: + case 0xc3: + dev->pci_conf[addr] = val; + break; + + case 0xc8: case 0xc9: + dev->pci_conf[addr] = val; + break; + + case 0xd1: + dev->pci_conf[addr] = val & 0xf1; + break; + case 0xd2: case 0xd3: + dev->pci_conf[addr] = val; + break; + + case 0xe0: case 0xe1: + if (dev->pci_conf[0x90] & 0x20) + dev->pci_conf[addr] = val; + break; + case 0xe2: + if (dev->pci_conf[0x90] & 0x20) + dev->pci_conf[addr] = val & 0x3f; + break; + case 0xe3: + if (dev->pci_conf[0x90] & 0x20) + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0xe4: + if (dev->pci_conf[0x90] & 0x20) + dev->pci_conf[addr] = val & 0x03; + break; + case 0xe5: + if (dev->pci_conf[0x90] & 0x20) + dev->pci_conf[addr] = val; + break; + + case 0xe6: + if (dev->pci_conf[0x90] & 0x20) + dev->pci_conf[addr] = val & 0xc0; + break; + + case 0xe7: + if (dev->pci_conf[0x90] & 0x20) + dev->pci_conf[addr] = val; + break; + + case 0xe8: case 0xe9: + if (dev->pci_conf[0x90] & 0x04) + dev->pci_conf[addr] = val; + break; + + case 0xea: + dev->pci_conf[addr] = val & 0xcf; + break; + + case 0xeb: + dev->pci_conf[addr] = val & 0xcf; + break; + + case 0xec: + dev->pci_conf[addr] = val & 0x3f; + break; + + case 0xed: + dev->pci_conf[addr] = val; + break; + + case 0xee: + dev->pci_conf[addr] = val & 0x3e; + break; + case 0xef: + dev->pci_conf[addr] = val; + break; + + case 0xf3: + dev->pci_conf[addr] = val & 0x08; + break; + + case 0xf5: + dev->pci_conf[addr] = val; + break; + + case 0xf6: + dev->pci_conf[addr] = val; + break; + + case 0xf7: + dev->pci_conf[addr] = val & 0x43; + break; + } +} + + +static uint8_t +ali1541_read(int func, int addr, void *priv) +{ + ali1541_t *dev = (ali1541_t *)priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + return ret; +} + + +static void +ali1541_reset(void *priv) +{ + ali1541_t *dev = (ali1541_t *)priv; + int i; + + /* Default Registers */ + dev->pci_conf[0x00] = 0xb9; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x41; + dev->pci_conf[0x03] = 0x15; + dev->pci_conf[0x04] = 0x06; + dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = 0x10; + dev->pci_conf[0x07] = 0x04; + dev->pci_conf[0x08] = 0x00; + dev->pci_conf[0x09] = 0x00; + dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x0c] = 0x00; + dev->pci_conf[0x0d] = 0x20; + dev->pci_conf[0x0e] = 0x00; + dev->pci_conf[0x0f] = 0x00; + dev->pci_conf[0x2c] = 0xb9; + dev->pci_conf[0x2d] = 0x10; + dev->pci_conf[0x2e] = 0x41; + dev->pci_conf[0x2f] = 0x15; + dev->pci_conf[0x34] = 0xb0; + dev->pci_conf[0x89] = 0x20; + dev->pci_conf[0x8a] = 0x20; + dev->pci_conf[0x91] = 0x13; + dev->pci_conf[0xb0] = 0x02; + dev->pci_conf[0xb1] = 0xe0; + dev->pci_conf[0xb2] = 0x10; + dev->pci_conf[0xb4] = 0x03; + dev->pci_conf[0xb5] = 0x02; + dev->pci_conf[0xb7] = 0x1c; + dev->pci_conf[0xc8] = 0xbf; + dev->pci_conf[0xc9] = 0x0a; + dev->pci_conf[0xe0] = 0x01; + + cpu_cache_int_enabled = 1; + ali1541_write(0, 0x42, 0x00, dev); + + ali1541_write(0, 0x54, 0x00, dev); + ali1541_write(0, 0x55, 0x00, dev); + + for (i = 0; i < 4; i++) + ali1541_write(0, 0x56 + i, 0x00, dev); + + ali1541_write(0, 0x60 + i, 0x07, dev); + ali1541_write(0, 0x61 + i, 0x40, dev); + for (i = 0; i < 14; i += 2) { + ali1541_write(0, 0x62 + i, 0x00, dev); + ali1541_write(0, 0x63 + i, 0x00, dev); + } +} + + +static void +ali1541_close(void *priv) +{ + ali1541_t *dev = (ali1541_t *)priv; + + smram_del(dev->smram); + free(dev); +} + + +static void * +ali1541_init(const device_t *info) +{ + ali1541_t *dev = (ali1541_t *)malloc(sizeof(ali1541_t)); + memset(dev, 0, sizeof(ali1541_t)); + + pci_add_card(PCI_ADD_NORTHBRIDGE, ali1541_read, ali1541_write, dev); + + dev->smram = smram_add(); + + ali1541_reset(dev); + + dev->agp_bridge = device_add(&ali5243_agp_device); + + return dev; +} + + +const device_t ali1541_device = { + "ALi M1541 CPU-to-PCI Bridge", + DEVICE_PCI, + 0, + ali1541_init, + ali1541_close, + ali1541_reset, + {NULL}, + NULL, + NULL, + NULL +}; diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index 158d42ba4..5e43ec9fd 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -34,19 +34,56 @@ #include <86box/fdc.h> #include <86box/hdc_ide.h> #include <86box/hdc_ide_sff8038i.h> +#include <86box/keyboard.h> #include <86box/lpt.h> #include <86box/mem.h> #include <86box/nvr.h> #include <86box/pci.h> +#include <86box/pic.h> #include <86box/port_92.h> #include <86box/serial.h> -#include <86box/smbus_piix4.h> +#include <86box/smbus.h> #include <86box/usb.h> #include <86box/acpi.h> #include <86box/chipset.h> + +typedef struct ali1543_t +{ + uint8_t pci_conf[256], pmu_conf[256], usb_conf[256], ide_conf[256], + sio_regs[256], device_regs[8][256], sio_index, in_configuration_mode, + pci_slot, ide_slot, usb_slot, pmu_slot, usb_dev_enable, ide_dev_enable, + pmu_dev_enable, type; + + apm_t * apm; + acpi_t * acpi; + ddma_t * ddma; + fdc_t * fdc_controller; + nvr_t * nvr; + port_92_t * port_92; + serial_t * uart[2]; + sff8038i_t * ide_controller[2]; + smbus_ali7101_t * smbus; + usb_t * usb; + +} ali1543_t; + +/* + Notes: + - Power Managment isn't functioning properly + - IDE isn't functioning properly + - 1543C differences have to be examined + - Some Chipset functionality might be missing + - Device numbers and types might be incorrect + - Code quality is abysmal and needs lot's of cleanup. +*/ + +int ali1533_irq_routing[16] = { PCI_IRQ_DISABLED, 9, 3, 10, 4, 5, 7, 6, + 1, 11, PCI_IRQ_DISABLED, 12, PCI_IRQ_DISABLED, 14, PCI_IRQ_DISABLED, 15 }; + + #ifdef ENABLE_ALI1543_LOG int ali1543_do_log = ENABLE_ALI1543_LOG; static void @@ -65,200 +102,337 @@ ali1543_log(const char *fmt, ...) #define ali1543_log(fmt, ...) #endif -typedef struct ali1543_t + +static void +ali1533_ddma_handler(ali1543_t *dev) { - uint8_t pci_conf[256], pmu_conf[256], usb_conf[256], ide_conf[256], - sio_regs[256], device_regs[8][256], sio_index, in_configuration_mode, - pci_slot, ide_slot, usb_slot, pmu_slot; - - apm_t *apm; - acpi_t *acpi; - ddma_t *ddma; - fdc_t *fdc_controller; - nvr_t *nvr; - port_92_t *port_92; - serial_t *uart[2]; - sff8038i_t *ide_controller[2]; - smbus_piix4_t *smbus; - usb_t *usb; - -} ali1543_t; - -/* - - Notes: - - Power Managment isn't functioning properly - - IDE isn't functioning properly - - 1543C differences have to be examined - - Some Chipset functionality might be missing - - Device numbers and types might be incorrect - - Code quality is abysmal and needs lot's of cleanup. - -*/ - -int ali1533_irq_routing[15] = {9, 3, 0x0a, 4, 5, 7, 6, 1, 0x0b, 0, 0x0c, 0, 0x0e, 0, 0x0f}; - -void ali1533_ddma_handler(ali1543_t *dev) -{ - for (uint8_t i = 0; i < 8; i++) - { - if (i != 4) - ddma_update_io_mapping(dev->ddma, i & 7, dev->pci_conf[0x73] & 0xf, dev->pci_conf[0x73] & 0xf0, dev->pci_conf[0x45] & 2); - } + /* TODO: Find any documentation that actually explains the ALi southbridge DDMA mapping. */ } -void ali5229_ide_handler(ali1543_t *dev); + +static void ali5229_ide_handler(ali1543_t *dev); +static void ali5229_ide_irq_handler(ali1543_t *dev); + +static void ali5229_write(int func, int addr, uint8_t val, void *priv); + +static void ali7101_write(int func, int addr, uint8_t val, void *priv); +static uint8_t ali7101_read(int func, int addr, void *priv); + static void ali1533_write(int func, int addr, uint8_t val, void *priv) { ali1543_t *dev = (ali1543_t *)priv; + int irq; ali1543_log("M1533: dev->pci_conf[%02x] = %02x\n", addr, val); - switch (addr) - { - case 0x04: - if (dev->pci_conf[0x5f] & 8) - dev->pci_conf[addr] = val; - break; - case 0x2c: /* Subsystem Vendor ID */ - case 0x2d: - case 0x2e: - case 0x2f: - if (dev->pci_conf[0x74] & 0x40) - dev->pci_conf[addr] = val; - break; + if (func > 0) + return; - case 0x40: - dev->pci_conf[addr] = val & 0x7f; - break; + switch (addr) { + case 0x04: /* Command Register */ + if (dev->type == 1) { + if (dev->pci_conf[0x5f] & 0x08) + dev->pci_conf[0x04] = val & 0x0f; + else + dev->pci_conf[0x04] = val; + } else { + if (!(dev->pci_conf[0x5f] & 0x08)) + dev->pci_conf[0x04] = val; + } + break; + case 0x05: /* Command Register */ + if (!(dev->pci_conf[0x5f] & 0x08)) + dev->pci_conf[0x04] = val & 0x03; + break; - case 0x42: /* ISA Bus Speed */ - dev->pci_conf[addr] = val & 0xcf; - switch(val & 7) - { - case 0: - cpu_set_isa_speed(7159091); - break; - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - cpu_set_isa_pci_div(val & 7); - break; - } + case 0x07: /* Status Byte */ + dev->pci_conf[addr] &= ~(val & 0x30); + break; - break; + case 0x2c: /* Subsystem Vendor ID */ + case 0x2d: + case 0x2e: + case 0x2f: + if (!(dev->pci_conf[0x74] & 0x40)) + dev->pci_conf[addr] = val; + break; - case 0x43: - dev->pci_conf[addr] = val; - if (val & 0x80) - port_92_add(dev->port_92); - else - port_92_remove(dev->port_92); - break; + case 0x40: + dev->pci_conf[addr] = val & 0x7f; + break; - case 0x44: /* Set IRQ Line for Primary IDE if it's on native mode */ - dev->pci_conf[addr] = 0xdf; - if (dev->ide_conf[0x09] & 1) - sff_set_irq_line(dev->ide_controller[0], ((val & 0x0f) == 0) ? ali1533_irq_routing[(val & 0x0f) - 1] : PCI_IRQ_DISABLED); - break; + case 0x41: + /* TODO: Bit 7 selects keyboard controller type: + 0 = AT, 1 = PS/2 */ + keyboard_at_set_mouse_scan((val & 0x40) ? 1 : 0); + dev->pci_conf[addr] = val & 0xbf; + break; - case 0x45: /* DDMA Enable */ - dev->pci_conf[addr] = 0xcf; - ali1533_ddma_handler(dev); - break; + case 0x42: /* ISA Bus Speed */ + dev->pci_conf[addr] = val & 0xcf; + switch (val & 7) { + case 0: + cpu_set_isa_speed(7159091); + break; + case 1: case 2: case 3: case 4: + case 5: case 6: + cpu_set_isa_pci_div((val & 7) + 1); + break; + } + break; - case 0x48: /* PCI IRQ Routing */ - case 0x49: - dev->pci_conf[addr] = val; - pci_set_irq_routing(((addr & 1) * 2) + 2, (((val >> 4) & 0x0f) == 0) ? ali1533_irq_routing[((val >> 4) & 0x0f) - 1] : PCI_IRQ_DISABLED); - pci_set_irq_routing(((addr & 1) * 2) + 1, ((val & 0x0f) == 0) ? ali1533_irq_routing[(val & 0x0f) - 1] : PCI_IRQ_DISABLED); - break; + case 0x43: + dev->pci_conf[addr] = val; + if (val & 0x80) + port_92_add(dev->port_92); + else + port_92_remove(dev->port_92); + break; - case 0x53: /* USB Enable */ - dev->pci_conf[addr] = val & 0xe7; - ohci_update_mem_mapping(dev->usb, 0x11, 0x12, 0x13, (dev->usb_conf[0x04] & 1) && (!(dev->pci_conf[0x53] & 0x40))); - break; + /* We're going to cheat a little bit here and use MIRQ's as a substitute for the ALi's INTAJ's, + as they work pretty much the same - specifically, we're going to use MIRQ2 and MIRQ3 for them, + as MIRQ0 and MIRQ1 map to the ALi's MBIRQ0 and MBIRQ1. */ + case 0x44: /* Set IRQ Line for Primary IDE if it's on native mode */ + dev->pci_conf[addr] = val & 0xdf; + soft_reset_pci = !!(val & 0x80); + sff_set_irq_level(dev->ide_controller[0], 0, !(val & 0x10)); + sff_set_irq_level(dev->ide_controller[1], 0, !(val & 0x10)); + ali1543_log("INTAJ = IRQ %i\n", ali1533_irq_routing[val & 0x0f]); + pci_set_mirq_routing(PCI_MIRQ0, ali1533_irq_routing[val & 0x0f]); + pci_set_mirq_routing(PCI_MIRQ2, ali1533_irq_routing[val & 0x0f]); + break; - case 0x54: /* USB Control ? */ - dev->pci_conf[addr] = val & 0xdf; - break; + /* TODO: Implement a ROMCS# assertion bitmask for I/O ports. */ + case 0x45: /* DDMA Enable */ + dev->pci_conf[addr] = val & 0xcb; + ali1533_ddma_handler(dev); + break; - case 0x57: - dev->pci_conf[addr] = val & 0xc7; - break; + /* TODO: For 0x47, we need a way to obtain the memory state for an address + and toggle ROMCS#. */ + case 0x47: /* BIOS chip select control */ + dev->pci_conf[addr] = val; + break; - case 0x58: /* IDE Enable */ - dev->pci_conf[addr] = val & 0x7f; - ali5229_ide_handler(dev); - break; + /* PCI IRQ Routing */ + case 0x48: case 0x49: case 0x4a: case 0x4b: + dev->pci_conf[addr] = val; - case 0x59: - case 0x5a: - dev->pci_conf[addr] = val & 0x0e; - break; + pci_set_irq_routing(((addr & 0x03) << 1) + 2, ali1533_irq_routing[(val >> 4) & 0x0f]); + pci_set_irq_routing(((addr & 0x03) << 1) + 1, ali1533_irq_routing[val & 0x0f]); + break; - case 0x5b: - dev->pci_conf[addr] = val & 0x02; - break; + case 0x4c: /* PCI INT to ISA Level to Edge transfer */ + dev->pci_conf[addr] = val; - case 0x5c: - dev->pci_conf[addr] = val & 0x7f; - break; + for (irq = 1; irq < 9; irq++) + pci_set_irq_level(irq, !(val & (1 << (irq - 1)))); + break; - case 0x5d: - dev->pci_conf[addr] = val & 0x02; - break; + case 0x4d: /* MBIRQ0(SIRQI#), MBIRQ1(SIRQII#) Interrupt to ISA IRQ routing table */ + if (dev->type == 0) { + dev->pci_conf[addr] = val; - case 0x5e: - dev->pci_conf[addr] = val & 0xe0; - break; + ali1543_log("SIRQI = IRQ %i; SIRQII = IRQ %i\n", ali1533_irq_routing[(val >> 4) & 0x0f], ali1533_irq_routing[val & 0x0f]); + // pci_set_mirq_routing(PCI_MIRQ0, ali1533_irq_routing[(val >> 4) & 0x0f]); + // pci_set_mirq_routing(PCI_MIRQ1, ali1533_irq_routing[val & 0x0f]); + } + break; - case 0x5f: - dev->pci_conf[addr] = val; - acpi_update_io_mapping(dev->acpi, (dev->pmu_conf[0x11] << 8) | (dev->pmu_conf[0x10] & 0xc0), (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4))); - smbus_piix4_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xe0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4))); - break; + /* I/O cycle posted-write first port definition */ + case 0x50: + dev->pci_conf[addr] = val; + break; + case 0x51: + dev->pci_conf[addr] = val & 0x8f; + break; - case 0x6d: - dev->pci_conf[addr] = val & 0xbf; - break; + /* I/O cycle posted-write second port definition */ + case 0x52: + dev->pci_conf[addr] = val; + break; + case 0x53: + if (dev->type == 1) + dev->pci_conf[addr] = val; + else + dev->pci_conf[addr] = val & 0xcf; + /* This actually enables/disables the USB *device* rather than the interface itself. */ + dev->usb_dev_enable = !(val & 0x40); + break; - case 0x71: - case 0x72: - dev->pci_conf[addr] = val & 0xef; - break; + /* Hardware setting status bits, read-only (register 0x54) */ - case 0x73: /* DDMA Base Address */ - dev->pci_conf[addr] = val; - ali1533_ddma_handler(dev); - break; + /* Programmable chip select (pin PCSJ) address define */ + case 0x55: case 0x56: + dev->pci_conf[addr] = val; + break; + case 0x57: + if (dev->type == 1) + dev->pci_conf[addr] = val & 0xf0; + else + dev->pci_conf[addr] = val & 0xe0; + break; - case 0x74: /* USB IRQ Routing */ - dev->pci_conf[addr] = val & 0xdf; - break; + /* IDE interface control + TODO: What is IDSEL address? */ + case 0x58: + dev->pci_conf[addr] = val & 0x7f; + ali1543_log("PCI58: %02X\n", val); + dev->ide_dev_enable = !!(val & 0x40); + switch (val & 0x30) { + case 0x00: + dev->ide_slot = 0x10; /* A27 = slot 16 */ + break; + case 0x10: + dev->ide_slot = 0x0f; /* A26 = slot 15 */ + break; + case 0x20: + dev->ide_slot = 0x0e; /* A25 = slot 14 */ + break; + case 0x30: + dev->ide_slot = 0x0d; /* A24 = slot 13 */ + break; + } + ali1543_log("IDE slot = %02X (A%0i)\n", dev->ide_slot - 5, dev->ide_slot + 11); + ali5229_ide_irq_handler(dev); + break; - case 0x75: /* Set IRQ Line for Secondary IDE if it's on native mode */ - dev->pci_conf[addr] = val & 0x1f; - if (dev->ide_conf[0x09] & 8) - sff_set_irq_line(dev->ide_controller[1], ((val & 0x0f) == 0) ? ali1533_irq_routing[(val & 0x0f) - 1] : PCI_IRQ_DISABLED); - break; + /* General Purpose input multiplexed pin(GPI) select */ + case 0x59: + dev->pci_conf[addr] = val & 0x0e; + break; - case 0x76: /* PMU IRQ Routing */ - dev->pci_conf[addr] = val & 0x1f; - acpi_set_irq_line(dev->acpi, val & 0x0f); - break; + /* General Purpose output multiplexed pin(GPO) select low */ + case 0x5a: + dev->pci_conf[addr] = val & 0x0f; + break; + /* General Purpose output multiplexed pin(GPO) select high */ + case 0x5b: + dev->pci_conf[addr] = val & 0x02; + break; - case 0x77: /* SMBus IRQ Routing */ - dev->pci_conf[addr] = val & 0x1f; - break; + case 0x5c: + dev->pci_conf[addr] = val & 0x7f; + break; + case 0x5d: + dev->pci_conf[addr] = val & 0x02; + break; - default: - dev->pci_conf[addr] = val; - break; + case 0x5e: + if (dev->type == 1) + dev->pci_conf[addr] = val & 0xe1; + else + dev->pci_conf[addr] = val & 0xe0; + break; + + case 0x5f: + dev->pci_conf[addr] = val; + dev->pmu_dev_enable = !(val & 0x04); + break; + + case 0x6c: /* Deleted - no idea what it used to do */ + dev->pci_conf[addr] = val; + break; + + case 0x6d: + dev->pci_conf[addr] = val & 0xbf; + break; + + case 0x6e: case 0x70: + dev->pci_conf[addr] = val; + break; + + case 0x71: + dev->pci_conf[addr] = val & 0xef; + break; + + case 0x72: + dev->pci_conf[addr] = val & 0xef; + switch (val & 0x0c) { + case 0x00: + dev->pmu_slot = 0x11; /* A28 = slot 17 */ + break; + case 0x04: + dev->pmu_slot = 0x12; /* A29 = slot 18 */ + break; + case 0x08: + dev->pmu_slot = 0x03; /* A14 = slot 03 */ + break; + case 0x0c: + dev->pmu_slot = 0x04; /* A15 = slot 04 */ + break; + } + ali1543_log("PMU slot = %02X (A%0i)\n", dev->pmu_slot - 5, dev->pmu_slot + 11); + switch (val & 0x03) { + case 0x00: + dev->usb_slot = 0x14; /* A31 = slot 20 */ + break; + case 0x01: + dev->usb_slot = 0x13; /* A30 = slot 19 */ + break; + case 0x02: + dev->usb_slot = 0x02; /* A13 = slot 02 */ + break; + case 0x03: + dev->usb_slot = 0x01; /* A12 = slot 01 */ + break; + } + ali1543_log("USB slot = %02X (A%0i)\n", dev->usb_slot - 5, dev->usb_slot + 11); + break; + + case 0x73: /* DDMA Base Address */ + dev->pci_conf[addr] = val; + ali1533_ddma_handler(dev); + break; + + case 0x74: /* USB IRQ Routing - we cheat and use MIRQ4 */ + dev->pci_conf[addr] = val & 0xdf; + /* TODO: MIRQ level/edge control - if bit 4 = 1, it's level */ + pci_set_mirq_routing(PCI_MIRQ4, ali1533_irq_routing[val & 0x0f]); + break; + + case 0x75: /* Set IRQ Line for Secondary IDE if it's on native mode */ + dev->pci_conf[addr] = val & 0x1f; + sff_set_irq_level(dev->ide_controller[0], 1, !(val & 0x10)); + sff_set_irq_level(dev->ide_controller[1], 1, !(val & 0x10)); + ali1543_log("INTBJ = IRQ %i\n", ali1533_irq_routing[val & 0x0f]); + pci_set_mirq_routing(PCI_MIRQ1, ali1533_irq_routing[val & 0x0f]); + pci_set_mirq_routing(PCI_MIRQ3, ali1533_irq_routing[val & 0x0f]); + break; + + case 0x76: /* PMU IRQ Routing - we cheat and use MIRQ5 */ + if (dev->type == 1) + dev->pci_conf[addr] = val & 0x9f; + else + dev->pci_conf[addr] = val & 0x1f; + acpi_set_mirq_is_level(dev->acpi, !!(val & 0x10)); + if ((dev->type == 1) && (val & 0x80)) + pci_set_mirq_routing(PCI_MIRQ5, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ5, ali1533_irq_routing[val & 0x0f]); + /* TODO: Tell ACPI to use MIRQ5 */ + break; + + case 0x77: /* SMBus IRQ Routing - we cheat and use MIRQ6 */ + dev->pci_conf[addr] = val & 0x1f; + pci_set_mirq_routing(PCI_MIRQ6, ali1533_irq_routing[val & 0x0f]); + break; + + case 0x78: + if (dev->type == 1) { + ali1543_log("PCI78 = %02X\n", val); + dev->pci_conf[addr] = val & 0x33; + } + break; + + case 0x7c ... 0xff: + if ((dev->type == 1) && !dev->pmu_dev_enable) { + dev->pmu_dev_enable = 1; + ali7101_write(func, addr, val, priv); + dev->pmu_dev_enable = 0; + } + break; } } @@ -266,19 +440,124 @@ static uint8_t ali1533_read(int func, int addr, void *priv) { ali1543_t *dev = (ali1543_t *)priv; + uint8_t ret = 0xff; - if (((dev->pci_conf[0x42] & 0x80) && (addr >= 0x40)) || ((dev->pci_conf[0x5f] & 8) && (addr == 4))) - return 0; - else - return dev->pci_conf[addr]; + if (func == 0) { + if (((dev->pci_conf[0x42] & 0x80) && (addr >= 0x40)) || ((dev->pci_conf[0x5f] & 8) && (addr == 4))) + ret = 0x00; + else { + ret = dev->pci_conf[addr]; + if (addr == 0x41) + ret |= (keyboard_at_get_mouse_scan() << 2); + else if (addr == 0x58) + ret = (ret & 0xbf) | (dev->ide_dev_enable ? 0x40 : 0x00); + else if ((dev->type == 1) && ((addr >= 0x7c) && (addr <= 0xff)) && !dev->pmu_dev_enable) { + dev->pmu_dev_enable = 1; + ret = ali7101_read(func, addr, priv); + dev->pmu_dev_enable = 0; + } + } + } + + return ret; } -void ali5229_ide_handler(ali1543_t *dev) + +static void +ali5229_ide_irq_handler(ali1543_t *dev) { - uint16_t native_base_pri_addr = (dev->ide_conf[0x11] | dev->ide_conf[0x10] << 8); - uint16_t native_side_pri_addr = (dev->ide_conf[0x15] | dev->ide_conf[0x14] << 8); - uint16_t native_base_sec_addr = (dev->ide_conf[0x19] | dev->ide_conf[0x18] << 8); - uint16_t native_side_sec_addr = (dev->ide_conf[0x1c] | dev->ide_conf[0x1b] << 8); + int ctl = 0, ch = 0; + int bit = 0; + + if (dev->ide_conf[0x52] & 0x10) { + ctl ^= 1; + ch ^= 1; + bit ^= 5; + } + + if (dev->ide_conf[0x09] & (1 ^ bit)) { + /* Primary IDE is native. */ + ali1543_log("Primary IDE IRQ mode: Native, Native\n"); + sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 4); + sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 4); + } else { + /* Primary IDE is legacy. */ + switch (dev->pci_conf[0x58] & 0x03) { + case 0x00: + /* SIRQI, SIRQII */ + ali1543_log("Primary IDE IRQ mode: SIRQI, SIRQII\n"); + sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 2); + sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 5); + break; + case 0x01: + /* IRQ14, IRQ15 */ + ali1543_log("Primary IDE IRQ mode: IRQ14, IRQ15\n"); + sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); + sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 0); + break; + case 0x02: + /* IRQ14, SIRQII */ + ali1543_log("Primary IDE IRQ mode: IRQ14, SIRQII\n"); + sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); + sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 5); + break; + case 0x03: + /* IRQ14, SIRQI */ + ali1543_log("Primary IDE IRQ mode: IRQ14, SIRQI\n"); + sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); + sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 2); + break; + } + } + + ctl ^= 1; + + if (dev->ide_conf[0x09] & (4 ^ bit)) { + /* Secondary IDE is native. */ + ali1543_log("Secondary IDE IRQ mode: Native, Native\n"); + sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 4); + sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 4); + } else { + /* Secondary IDE is legacy. */ + switch (dev->pci_conf[0x58] & 0x03) { + case 0x00: + /* SIRQI, SIRQII */ + ali1543_log("Secondary IDE IRQ mode: SIRQI, SIRQII\n"); + sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 2); + sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 5); + break; + case 0x01: + /* IRQ14, IRQ15 */ + ali1543_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n"); + sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); + sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 0); + break; + case 0x02: + /* IRQ14, SIRQII */ + ali1543_log("Secondary IDE IRQ mode: IRQ14, SIRQII\n"); + sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); + sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 5); + break; + case 0x03: + /* IRQ14, SIRQI */ + ali1543_log("Secondary IDE IRQ mode: IRQ14, SIRQI\n"); + sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); + sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 2); + break; + } + } +} + + +static void +ali5229_ide_handler(ali1543_t *dev) +{ + uint32_t ch = 0; + + uint16_t native_base_pri_addr = ((dev->ide_conf[0x11] | dev->ide_conf[0x10] << 8)) & 0xfffe; + uint16_t native_side_pri_addr = ((dev->ide_conf[0x15] | dev->ide_conf[0x14] << 8)) & 0xfffe; + uint16_t native_base_sec_addr = ((dev->ide_conf[0x19] | dev->ide_conf[0x18] << 8)) & 0xfffe; + uint16_t native_side_sec_addr = ((dev->ide_conf[0x1c] | dev->ide_conf[0x1b] << 8)) & 0xfffe; uint16_t comp_base_pri_addr = 0x01f0; uint16_t comp_side_pri_addr = 0x03f6; @@ -288,505 +567,71 @@ void ali5229_ide_handler(ali1543_t *dev) uint16_t current_pri_base, current_pri_side, current_sec_base, current_sec_side; /* Primary Channel Programming */ - if (!(dev->ide_conf[0x52] & 0x10)) - { - current_pri_base = (!(dev->ide_conf[0x09] & 1)) ? comp_base_pri_addr : native_base_pri_addr; - current_pri_side = (!(dev->ide_conf[0x09] & 1)) ? comp_side_pri_addr : native_side_pri_addr; - } - else - { - current_pri_base = (!(dev->ide_conf[0x09] & 1)) ? comp_base_sec_addr : native_base_sec_addr; - current_pri_side = (!(dev->ide_conf[0x09] & 1)) ? comp_side_sec_addr : native_side_sec_addr; + if (dev->ide_conf[0x52] & 0x10) { + current_pri_base = (!(dev->ide_conf[0x09] & 1)) ? comp_base_sec_addr : native_base_sec_addr; + current_pri_side = (!(dev->ide_conf[0x09] & 1)) ? comp_side_sec_addr : native_side_sec_addr; + } else { + current_pri_base = (!(dev->ide_conf[0x09] & 1)) ? comp_base_pri_addr : native_base_pri_addr; + current_pri_side = (!(dev->ide_conf[0x09] & 1)) ? comp_side_pri_addr : native_side_pri_addr; } /* Secondary Channel Programming */ - if (!(dev->ide_conf[0x52] & 0x10)) - { - current_sec_base = (!(dev->ide_conf[0x09] & 4)) ? comp_base_sec_addr : native_base_sec_addr; - current_sec_side = (!(dev->ide_conf[0x09] & 4)) ? comp_side_sec_addr : native_side_sec_addr; - } - else - { - current_sec_base = (!(dev->ide_conf[0x09] & 4)) ? comp_base_pri_addr : native_base_pri_addr; - current_sec_side = (!(dev->ide_conf[0x09] & 4)) ? comp_side_pri_addr : native_side_pri_addr; + if (dev->ide_conf[0x52] & 0x10) { + current_sec_base = (!(dev->ide_conf[0x09] & 4)) ? comp_base_pri_addr : native_base_pri_addr; + current_sec_side = (!(dev->ide_conf[0x09] & 4)) ? comp_side_pri_addr : native_side_pri_addr; + } else { + current_sec_base = (!(dev->ide_conf[0x09] & 4)) ? comp_base_sec_addr : native_base_sec_addr; + current_sec_side = (!(dev->ide_conf[0x09] & 4)) ? comp_side_sec_addr : native_side_sec_addr; } - /* Both channels use one port */ - if (dev->ide_conf[0x52] & 0x40) - { - current_pri_base = current_sec_base; - current_pri_side = current_sec_side; - } - - if (dev->ide_conf[0x52] & 0x20) - { - current_sec_base = current_pri_base; - current_sec_side = current_pri_side; - } + if (dev->ide_conf[0x52] & 0x10) + ch ^= 8; + ali1543_log("ali5229_ide_handler(): Disabling primary IDE...\n"); ide_pri_disable(); + ali1543_log("ali5229_ide_handler(): Disabling secondary IDE...\n"); ide_sec_disable(); - if (dev->pci_conf[0x58] & 0x40) - { - sff_set_irq_pin(dev->ide_controller[0], dev->ide_conf[0x3d] & 4); - sff_set_irq_pin(dev->ide_controller[1], dev->ide_conf[0x3d] & 4); + if (dev->ide_conf[0x04] & 0x01) { + /* Primary Channel Setup */ + if ((dev->ide_conf[0x09] & 0x20) || (dev->ide_conf[0x4d] & 0x80)) { + ali1543_log("ali5229_ide_handler(): Primary IDE base now %04X...\n", current_pri_base); + ide_set_base(0, current_pri_base); + ali1543_log("ali5229_ide_handler(): Primary IDE side now %04X...\n", current_pri_side); + ide_set_side(0, current_pri_side); - /* Primary Channel Setup */ - if (dev->ide_conf[0x09] & 0x10) - { - ide_pri_enable(); - if (!(dev->ide_conf[0x09] & 1)) - sff_set_irq_line(dev->ide_controller[0], (dev->ide_conf[0x3c] != 0) ? ali1533_irq_routing[(dev->ide_conf[0x3c] & 0x0f) - 1] : PCI_IRQ_DISABLED); + ali1543_log("ali5229_ide_handler(): Enabling primary IDE...\n"); + ide_pri_enable(); - ide_set_base(0, current_pri_base); - ide_set_side(0, current_pri_side); + sff_bus_master_handler(dev->ide_controller[0], dev->ide_conf[0x04] & 0x01, ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + (0 ^ ch)); + ali1543_log("M5229 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side); + } - sff_bus_master_handler(dev->ide_controller[0], dev->ide_conf[0x09] & 0x80, (dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)); - ali1543_log("M5229 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side); - } + /* Secondary Channel Setup */ + if ((dev->ide_conf[0x09] & 0x10) || (dev->ide_conf[0x4d] & 0x80)) { + ali1543_log("ali5229_ide_handler(): Secondary IDE base now %04X...\n", current_sec_base); + ide_set_base(1, current_sec_base); + ali1543_log("ali5229_ide_handler(): Secondary IDE side now %04X...\n", current_sec_side); + ide_set_side(1, current_sec_side); - /* Secondary Channel Setup */ - if (dev->ide_conf[0x09] & 8) - { - ide_sec_enable(); - if (!(dev->ide_conf[0x09] & 4)) - sff_set_irq_line(dev->ide_controller[1], (dev->ide_conf[0x3c] != 0) ? ali1533_irq_routing[(dev->ide_conf[0x3c] & 0x0f) - 1] : PCI_IRQ_DISABLED); + ali1543_log("ali5229_ide_handler(): Enabling secondary IDE...\n"); + ide_sec_enable(); - ide_set_base(1, current_sec_base); - ide_set_side(1, current_sec_side); - - sff_bus_master_handler(dev->ide_controller[1], dev->ide_conf[0x09] & 0x80, ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + 8); - ali1543_log("M5229 SEC: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side); - } + sff_bus_master_handler(dev->ide_controller[1], dev->ide_conf[0x04] & 0x01, (((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8))) + (8 ^ ch)); + ali1543_log("M5229 SEC: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side); + } + } else { + sff_bus_master_handler(dev->ide_controller[0], dev->ide_conf[0x04] & 0x01, (dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)); + sff_bus_master_handler(dev->ide_controller[1], dev->ide_conf[0x04] & 0x01, ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + 8); } } + static void -ali5229_write(int func, int addr, uint8_t val, void *priv) +ali5229_chip_reset(ali1543_t *dev) { - ali1543_t *dev = (ali1543_t *)priv; - ali1543_log("M5229: dev->ide_conf[%02x] = %02x\n", addr, val); - - switch (addr) - { - case 0x09: /* Control */ - if (dev->ide_conf[0x4d] & 0x80) - dev->ide_conf[addr] |= val & 0x8f; - else - dev->ide_conf[addr] = val; - ali5229_ide_handler(dev); - break; - - case 0x10: /* Primary Base Address */ - case 0x11: - case 0x12: - case 0x13: - case 0x14: - - case 0x18: /* Secondary Base Address */ - case 0x19: - case 0x1a: - case 0x1b: - case 0x1c: - - case 0x20: /* Bus Mastering Base Address */ - case 0x21: - case 0x22: - case 0x23: - dev->ide_conf[addr] = val; - ali5229_ide_handler(dev); - break; - - /* The machines don't touch anything beyond that point so we avoid any programming */ - - case 0x2c: /* Subsystem Vendor */ - case 0x2d: - case 0x2e: - case 0x2f: - if (dev->ide_conf[0x53] & 0x80) - dev->ide_conf[addr] = val; - break; - - case 0x4d: - dev->ide_conf[addr] = val & 0x80; - break; - - case 0x4f: - dev->ide_conf[addr] = val & 0x3f; - break; - - case 0x50: /* Configuration */ - dev->ide_conf[addr] = val & 0x2b; - break; - - case 0x51: - dev->ide_conf[addr] = val & 0xf7; - break; - - case 0x53: /* Subsystem Vendor ID */ - dev->ide_conf[addr] = val & 0x8b; - break; - - case 0x58: - dev->ide_conf[addr] = val & 3; - break; - - case 0x59: - case 0x5a: - case 0x5b: - dev->ide_conf[addr] = val & 0x7f; - break; - - case 0x5c: - dev->ide_conf[addr] = val & 3; - break; - - case 0x5d: - case 0x5e: - case 0x5f: - dev->ide_conf[addr] = val & 0x7f; - break; - - default: - dev->ide_conf[addr] = val; - break; - } -} - -static uint8_t -ali5229_read(int func, int addr, void *priv) -{ - ali1543_t *dev = (ali1543_t *)priv; - return dev->ide_conf[addr]; -} - -static void -ali5237_write(int func, int addr, uint8_t val, void *priv) -{ - ali1543_t *dev = (ali1543_t *)priv; - ali1543_log("M5237: dev->usb_conf[%02x] = %02x\n", addr, val); - switch (addr) - { - case 0x04: /* USB Enable */ - dev->usb_conf[addr] = val; - ohci_update_mem_mapping(dev->usb, 0x10, 0x11, 0x12, (dev->usb_conf[0x04] & 1) && (!(dev->pci_conf[0x53] & 0x40))); - break; - - case 0x05: - dev->usb_conf[addr] = 0x03; - break; - - case 0x06: - dev->usb_conf[addr] = 0xc0; - break; - - case 0x11: - case 0x12: - case 0x13: /* USB Base I/O */ - dev->usb_conf[addr] = val; - ohci_update_mem_mapping(dev->usb, 0x11, 0x12, 0x13, (dev->usb_conf[0x04] & 1) && (!(dev->pci_conf[0x53] & 0x40))); - break; - - case 0x42: - dev->usb_conf[addr] = 0x10; - break; - - default: - dev->usb_conf[addr] = val; - break; - } -} - -static uint8_t -ali5237_read(int func, int addr, void *priv) -{ - ali1543_t *dev = (ali1543_t *)priv; - return dev->usb_conf[addr]; -} - -static void -ali7101_write(int func, int addr, uint8_t val, void *priv) -{ - ali1543_t *dev = (ali1543_t *)priv; - ali1543_log("M7101: dev->pmu_conf[%02x] = %02x\n", addr, val); - - switch (addr) - { - case 0x04: /* Enable PMU */ - dev->pmu_conf[addr] = val & 0x1f; - acpi_update_io_mapping(dev->acpi, (dev->pmu_conf[0x11] << 8) | (dev->pmu_conf[0x10] & 0xc0), (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4))); - smbus_piix4_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xe0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4))); - break; - - case 0x07: - dev->pmu_conf[addr] = val & 0xfe; - break; - - case 0x10: /* PMU Base I/O */ - case 0x11: - if (addr == 0x10) - dev->pmu_conf[addr] = (val & 0xe0) | 1; - else if (addr == 0x11) - dev->pmu_conf[addr] = val; - - acpi_update_io_mapping(dev->acpi, (dev->pmu_conf[0x11] << 8) | (dev->pmu_conf[0x10] & 0xc0), (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4))); - break; - - case 0x14: /* SMBus Base I/O */ - case 0x15: - dev->pmu_conf[addr] = val; - smbus_piix4_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xe0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4))); - break; - - case 0x2c: /* Subsystem Vendor ID */ - case 0x2d: - case 0x2e: - case 0x2f: - if (dev->pmu_conf[0xd8] & 0x10) - dev->pmu_conf[addr] = val; - - case 0x40: - dev->pmu_conf[addr] = val & 0x1f; - break; - - case 0x41: - dev->pmu_conf[addr] = val & 0x10; - break; - - case 0x45: - dev->pmu_conf[addr] = val & 0x9f; - break; - - case 0x46: - dev->pmu_conf[addr] = val & 0x18; - break; - - case 0x48: - dev->pmu_conf[addr] = val & 0x9f; - break; - - case 0x49: - dev->pmu_conf[addr] = val & 0x38; - break; - - case 0x4c: - dev->pmu_conf[addr] = val & 5; - break; - - case 0x4d: - dev->pmu_conf[addr] = val & 1; - break; - - case 0x4e: - dev->pmu_conf[addr] = val & 5; - break; - - case 0x4f: - dev->pmu_conf[addr] = val & 1; - break; - - case 0x55: /* APM Timer */ - dev->pmu_conf[addr] = val & 0x7f; - break; - - case 0x59: - dev->pmu_conf[addr] = val & 0x1f; - break; - - case 0x5b: /* ACPI/SMB Base I/O Control */ - dev->pmu_conf[addr] = val & 0x7f; - break; - - case 0x61: - dev->pmu_conf[addr] = val & 0x13; - break; - - case 0x62: - dev->pmu_conf[addr] = val & 0xf1; - break; - - case 0x63: - dev->pmu_conf[addr] = val & 3; - break; - - case 0x65: - dev->pmu_conf[addr] = val & 0x1f; - break; - - case 0x68: - dev->pmu_conf[addr] = val & 7; - break; - - case 0x6e: - dev->pmu_conf[addr] = val & 0xef; - break; - - case 0x6f: - dev->pmu_conf[addr] = val & 7; - break; - - /* Continue Further Later */ - case 0xc0: /* GPO Registers */ - case 0xc1: - case 0xc2: - case 0xc3: - dev->pmu_conf[addr] = val; - acpi_init_gporeg(dev->acpi, dev->pmu_conf[0xc0], dev->pmu_conf[0xc1], dev->pmu_conf[0xc2], dev->pmu_conf[0xc3]); - break; - - case 0xe0: - dev->pmu_conf[addr] = val; - smbus_piix4_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xe0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4))); - break; - - default: - dev->pmu_conf[addr] = val; - break; - } -} - -static uint8_t -ali7101_read(int func, int addr, void *priv) -{ - ali1543_t *dev = (ali1543_t *)priv; - return dev->pmu_conf[addr]; -} - -void ali1533_sio_fdc_handler(ali1543_t *dev) -{ - fdc_remove(dev->fdc_controller); - if (dev->device_regs[0][0x30] & 1) - { - fdc_set_base(dev->fdc_controller, dev->device_regs[0][0x61] | (dev->device_regs[0][0x60] << 8)); - fdc_set_irq(dev->fdc_controller, dev->device_regs[0][0x70] & 0xf); - fdc_set_dma_ch(dev->fdc_controller, dev->device_regs[0][0x74] & 0x07); - ali1543_log("M1543-SIO FDC: ADDR %04x IRQ %02x DMA %02x\n", dev->device_regs[0][0x61] | (dev->device_regs[0][0x60] << 8), dev->device_regs[0][0x70] & 0xf, dev->device_regs[0][0x74] & 0x07); - } -} - -void ali1533_sio_uart_handler(int num, ali1543_t *dev) -{ - serial_remove(dev->uart[num]); - if (dev->device_regs[num + 4][0x30] & 1) - { - serial_setup(dev->uart[num], dev->device_regs[num + 4][0x61] | (dev->device_regs[num + 4][0x60] << 8), dev->device_regs[num + 4][0x70] & 0xf); - ali1543_log("M1543-SIO UART%d: ADDR %04x IRQ %02x\n", num, dev->device_regs[num + 4][0x61] | (dev->device_regs[num + 4][0x60] << 8), dev->device_regs[num + 4][0x70] & 0xf); - } -} - -void ali1533_sio_lpt_handler(ali1543_t *dev) -{ - lpt1_remove(); - if (dev->device_regs[3][0x30] & 1) - { - lpt1_init(dev->device_regs[3][0x61] | (dev->device_regs[3][0x60] << 8)); - lpt1_irq(dev->device_regs[3][0x70] & 0xf); - ali1543_log("M1543-SIO LPT: ADDR %04x IRQ %02x\n", dev->device_regs[3][0x61] | (dev->device_regs[3][0x60] << 8), dev->device_regs[3][0x70] & 0xf); - } -} - -void ali1533_sio_ldn(uint16_t ldn, ali1543_t *dev) -{ - /* We don't include all LDN's */ - switch (ldn) - { - case 0: /* FDC */ - ali1533_sio_fdc_handler(dev); - break; - case 3: /* LPT */ - ali1533_sio_lpt_handler(dev); - break; - case 4: /* UART */ - case 5: - ali1533_sio_uart_handler(ldn - 4, dev); - break; - } -} - -static void -ali1533_sio_write(uint16_t addr, uint8_t val, void *priv) -{ - ali1543_t *dev = (ali1543_t *)priv; - - switch (addr) - { - case 0x3f0: - dev->sio_index = val; - if (dev->sio_index == 0x51) - { - dev->in_configuration_mode = 1; - } - else if (dev->sio_index == 0xbb) - dev->in_configuration_mode = 0; - break; - - case 0x3f1: - if (dev->in_configuration_mode) - { - switch (dev->sio_index) - { - case 0x07: - dev->sio_regs[dev->sio_index] = val & 0x7; - break; - - case 0x22: - dev->sio_regs[dev->sio_index] = val & 0x39; - break; - - case 0x23: - dev->sio_regs[dev->sio_index] = val & 0x38; - break; - - default: - if ((dev->sio_index < 0x30) || (dev->sio_index == 0x51) || (dev->sio_index == 0xbb)) - dev->sio_regs[dev->sio_index] = val; - else if (dev->sio_regs[0x07] <= 7) - dev->device_regs[dev->sio_regs[0x07]][dev->sio_index] = val; - break; - } - } - break; - } - - if ((!dev->in_configuration_mode) && (dev->sio_regs[0x07] <= 7) && (addr == 0x03f0)) - { - ali1533_sio_ldn(dev->sio_regs[0x07], dev); - } -} - -static uint8_t -ali1533_sio_read(uint16_t addr, void *priv) -{ - ali1543_t *dev = (ali1543_t *)priv; - if (dev->sio_index >= 0x30) - return dev->device_regs[dev->sio_regs[0x07]][dev->sio_index]; - else - return dev->sio_regs[dev->sio_index]; -} - -static void -ali1543_reset(void *priv) -{ - ali1543_t *dev = (ali1543_t *)priv; - - /* M1533 */ - dev->pci_conf[0x00] = 0xb9; - dev->pci_conf[0x01] = 0x10; - dev->pci_conf[0x02] = 0x33; - dev->pci_conf[0x03] = 0x15; - dev->pci_conf[0x04] = 0x0f; - dev->pci_conf[0x08] = 0xb4; - dev->pci_conf[0x0a] = 0x01; - dev->pci_conf[0x0b] = 0x06; - - ali1533_write(0, 0x48, 0x00, dev); // Disables all IRQ's - ali1533_write(0, 0x44, 0x00, dev); - ali1533_write(0, 0x74, 0x00, dev); - ali1533_write(0, 0x75, 0x00, dev); - ali1533_write(0, 0x76, 0x00, dev); - /* M5229 */ + memset(dev->ide_conf, 0x00, sizeof(dev->pmu_conf)); dev->ide_conf[0x00] = 0xb9; dev->ide_conf[0x01] = 0x10; dev->ide_conf[0x02] = 0x29; @@ -794,7 +639,6 @@ ali1543_reset(void *priv) dev->ide_conf[0x06] = 0x80; dev->ide_conf[0x07] = 0x02; dev->ide_conf[0x08] = 0x20; - dev->ide_conf[0x09] = 0xfa; dev->ide_conf[0x0a] = 0x01; dev->ide_conf[0x0b] = 0x01; dev->ide_conf[0x10] = 0xf1; @@ -803,13 +647,14 @@ ali1543_reset(void *priv) dev->ide_conf[0x15] = 0x03; dev->ide_conf[0x18] = 0x71; dev->ide_conf[0x19] = 0x01; - dev->ide_conf[0x1a] = 0x75; - dev->ide_conf[0x1b] = 0x03; + dev->ide_conf[0x1c] = 0x75; + dev->ide_conf[0x1d] = 0x03; dev->ide_conf[0x20] = 0x01; - dev->ide_conf[0x23] = 0xf0; + dev->ide_conf[0x21] = 0xf0; dev->ide_conf[0x3d] = 0x01; - dev->ide_conf[0x3c] = 0x02; - dev->ide_conf[0x3d] = 0x03; + dev->ide_conf[0x3e] = 0x02; + dev->ide_conf[0x3f] = 0x04; + dev->ide_conf[0x53] = 0x03; dev->ide_conf[0x54] = 0x55; dev->ide_conf[0x55] = 0x55; dev->ide_conf[0x63] = 0x01; @@ -817,13 +662,878 @@ ali1543_reset(void *priv) dev->ide_conf[0x67] = 0x01; dev->ide_conf[0x78] = 0x21; + if (dev->type == 1) { + dev->ide_conf[0x08] = 0xc1; + dev->ide_conf[0x43] = 0x00; + dev->ide_conf[0x4b] = 0x4a; + dev->ide_conf[0x4e] = 0xba; + dev->ide_conf[0x4f] = 0x1a; + } + + ali5229_write(0, 0x04, 0x05, dev); + ali5229_write(0, 0x10, 0xf1, dev); + ali5229_write(0, 0x11, 0x01, dev); + ali5229_write(0, 0x14, 0xf5, dev); + ali5229_write(0, 0x15, 0x03, dev); + ali5229_write(0, 0x18, 0x71, dev); + ali5229_write(0, 0x19, 0x01, dev); + ali5229_write(0, 0x1a, 0x75, dev); + ali5229_write(0, 0x1b, 0x03, dev); + ali5229_write(0, 0x20, 0x01, dev); + ali5229_write(0, 0x21, 0xf0, dev); + ali5229_write(0, 0x4d, 0x00, dev); + dev->ide_conf[0x09] = 0xfa; + ali5229_write(0, 0x09, 0xfa, dev); + ali5229_write(0, 0x52, 0x00, dev); + + ali5229_write(0, 0x50, 0x00, dev); + sff_set_slot(dev->ide_controller[0], dev->ide_slot); sff_set_slot(dev->ide_controller[1], dev->ide_slot); sff_bus_master_reset(dev->ide_controller[0], (dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)); sff_bus_master_reset(dev->ide_controller[1], ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + 8); ali5229_ide_handler(dev); +} + + +static void +ali5229_write(int func, int addr, uint8_t val, void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + ali1543_log("M5229: dev->ide_conf[%02x] = %02x\n", addr, val); + + if (func > 0) + return; + + if (!dev->ide_dev_enable) + return; + + switch (addr) { + case 0x04: /* COM - Command Register */ + ali1543_log("IDE04: %02X\n", val); + dev->ide_conf[addr] = val & 0x45; + ali5229_ide_handler(dev); + break; + + case 0x05: + dev->ide_conf[addr] = val & 0x01; + break; + + case 0x07: + dev->ide_conf[addr] &= ~(val & 0xf1); + break; + + case 0x09: /* Control */ + ali1543_log("IDE09: %02X\n", val); + + if (dev->type == 1) { + val &= ~(dev->ide_conf[0x43]); + val |= (dev->ide_conf[addr] & dev->ide_conf[0x43]); + } + + if (dev->ide_conf[0x4d] & 0x80) + dev->ide_conf[addr] = (dev->ide_conf[addr] & 0xfa) | (val & 0x05); + else + dev->ide_conf[addr] = (dev->ide_conf[addr] & 0x8a) | (val & 0x75); + ali5229_ide_handler(dev); + ali5229_ide_irq_handler(dev); + break; + + /* Primary Base Address */ + case 0x10: case 0x11: case 0x14: case 0x15: + /* FALLTHROUGH */ + + /* Secondary Base Address */ + case 0x18: case 0x19: case 0x1c: case 0x1d: + /* FALLTHROUGH */ + + /* Bus Mastering Base Address */ + case 0x20: case 0x21: case 0x22: case 0x23: + dev->ide_conf[addr] = val; + ali5229_ide_handler(dev); + break; + + case 0x2c: /* Subsystem Vendor ID */ + case 0x2d: + case 0x2e: + case 0x2f: + if (!(dev->ide_conf[0x53] & 0x80)) + dev->ide_conf[addr] = val; + break; + + case 0x3c: /* Interrupt Line */ + case 0x3d: /* Interrupt Pin */ + dev->ide_conf[addr] = val; + break; + + /* The machines don't touch anything beyond that point so we avoid any programming */ + case 0x43: + if (dev->type == 1) + dev->ide_conf[addr] = val & 0x7f; + break; + + case 0x4b: + if (dev->type == 1) + dev->ide_conf[addr] = val; + break; + + case 0x4d: + dev->ide_conf[addr] = val & 0x80; + ali5229_ide_handler(dev); + break; + + case 0x4f: + if (dev->type == 0) + dev->ide_conf[addr] = val & 0x3f; + break; + + case 0x50: /* Configuration */ + ali1543_log("IDE50: %02X\n", val); + dev->ide_conf[addr] = val & 0x2b; + dev->ide_dev_enable = !!(val & 0x01); + break; + + case 0x51: + dev->ide_conf[addr] = val & 0xf7; + if (val & 0x80) + ali5229_chip_reset(dev); + else if (val & 0x40) { + sff_bus_master_reset(dev->ide_controller[0], (dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)); + sff_bus_master_reset(dev->ide_controller[1], ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + 8); + } + break; + + case 0x52: /* FCS - Flexible Channel Setting Register */ + dev->ide_conf[addr] = val; + ali5229_ide_handler(dev); + ali5229_ide_irq_handler(dev); + break; + + case 0x53: /* Subsystem Vendor ID */ + dev->ide_conf[addr] = val & 0x8b; + break; + + case 0x54: /* FIFO threshold of primary channel drive 0 and drive 1 */ + case 0x55: /* FIFO threshold of secondary channel drive 0 and drive 1 */ + case 0x56: /* Ultra DMA /33 setting for Primary drive 0 and drive 1 */ + case 0x57: /* Ultra DMA /33 setting for Secondary drive 0 and drive 1 */ + case 0x78: /* IDE clock's frequency (default value is 33 = 21H) */ + dev->ide_conf[addr] = val; + break; + + case 0x58: + dev->ide_conf[addr] = val & 3; + break; + + case 0x59: case 0x5a: + case 0x5b: + dev->ide_conf[addr] = val & 0x7f; + break; + + case 0x5c: + dev->ide_conf[addr] = val & 3; + break; + + case 0x5d: case 0x5e: + case 0x5f: + dev->ide_conf[addr] = val & 0x7f; + break; + } +} + + +static uint8_t +ali5229_read(int func, int addr, void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + uint8_t ret = 0xff; + + if (dev->ide_dev_enable && (func == 0)) { + ret = dev->ide_conf[addr]; + if ((addr == 0x09) && !(dev->ide_conf[0x50] & 0x02)) + ret &= 0x0f; + else if (addr == 0x50) + ret = (ret & 0xfe) | (dev->ide_dev_enable ? 0x01 : 0x00); + else if (addr == 0x75) + ret = ide_read_ali_75(); + else if (addr == 0x76) + ret = ide_read_ali_76(); + } + + return ret; +} + + +static void +ali5237_write(int func, int addr, uint8_t val, void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + ali1543_log("M5237: dev->usb_conf[%02x] = %02x\n", addr, val); + + if (func > 0) + return; + + if (!dev->usb_dev_enable) + return; + + switch (addr) { + case 0x04: /* USB Enable */ + dev->usb_conf[addr] = val & 0x5f; + ohci_update_mem_mapping(dev->usb, dev->usb_conf[0x11], dev->usb_conf[0x12], dev->usb_conf[0x13], dev->usb_conf[0x04] & 1); + break; + + case 0x05: + dev->usb_conf[addr] = 0x01; + break; + + case 0x07: + dev->usb_conf[addr] &= ~(val & 0xc9); + break; + + case 0x0c: /* Cache Line Size */ + case 0x0d: /* Latency Timer */ + case 0x3c: /* Interrupt Line Register */ + + case 0x42: /* Test Mode Register */ + dev->usb_conf[addr] = val & 0x10; + break; + case 0x43: + if (dev->type == 1) + dev->usb_conf[addr] = val & 0x04; + break; + + /* USB Base I/O */ + case 0x11: + dev->usb_conf[addr] = val & 0xf0; + ohci_update_mem_mapping(dev->usb, dev->usb_conf[0x11], dev->usb_conf[0x12], dev->usb_conf[0x13], dev->usb_conf[0x04] & 1); + break; + case 0x12: case 0x13: + dev->usb_conf[addr] = val; + ohci_update_mem_mapping(dev->usb, dev->usb_conf[0x11], dev->usb_conf[0x12], dev->usb_conf[0x13], dev->usb_conf[0x04] & 1); + break; + + case 0x2c: /* Subsystem Vendor ID */ + case 0x2d: + case 0x2e: + case 0x2f: + if (!(dev->usb_conf[0x42] & 0x10)) + dev->usb_conf[addr] = val; + break; + } +} + + +static uint8_t +ali5237_read(int func, int addr, void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + uint8_t ret = 0xff; + + if (dev->usb_dev_enable && (func == 0)) + ret = dev->usb_conf[addr]; + + return ret; +} + + +static void +ali7101_write(int func, int addr, uint8_t val, void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + ali1543_log("M7101: dev->pmu_conf[%02x] = %02x\n", addr, val); + + if (func > 0) + return; + + if (!dev->pmu_dev_enable) + return; + + if ((dev->pmu_conf[0xc9] & 0x01) && (addr >= 0x40) && (addr != 0xc9)) + return; + + switch (addr) { + case 0x04: /* Enable PMU */ + ali1543_log("PMU04: %02X\n", val); + dev->pmu_conf[addr] = val & 0x01; + acpi_update_io_mapping(dev->acpi, (dev->pmu_conf[0x11] << 8) | (dev->pmu_conf[0x10] & 0xc0), dev->pmu_conf[0x04] & 1); + if (dev->type == 1) + smbus_ali7101_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xc0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1)); + else + smbus_ali7101_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xe0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1)); + break; + + /* PMU Base I/O */ + case 0x10: case 0x11: + if (!(dev->pmu_conf[0x5b] & 0x02)) { + if (addr == 0x10) + dev->pmu_conf[addr] = (val & 0xc0) | 1; + else if (addr == 0x11) + dev->pmu_conf[addr] = val; + + ali1543_log("New ACPI base address: %08X\n", (dev->pmu_conf[0x11] << 8) | (dev->pmu_conf[0x10] & 0xc0)); + acpi_update_io_mapping(dev->acpi, (dev->pmu_conf[0x11] << 8) | (dev->pmu_conf[0x10] & 0xc0), dev->pmu_conf[0x04] & 1); + } + break; + + /* SMBus Base I/O */ + case 0x14: case 0x15: + if (!(dev->pmu_conf[0x5b] & 0x04)) { + if (addr == 0x14) { + if (dev->type == 1) + dev->pmu_conf[addr] = (val & 0xc0) | 1; + else + dev->pmu_conf[addr] = (val & 0xe0) | 1; + } else if (addr == 0x15) + dev->pmu_conf[addr] = val; + + if (dev->type == 1) { + ali1543_log("New SMBUS base address: %08X\n", (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xc0)); + smbus_ali7101_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xc0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1)); + } else { + ali1543_log("New SMBUS base address: %08X\n", (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xe0)); + smbus_ali7101_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xe0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1)); + } + } + break; + + /* Subsystem Vendor ID */ + case 0x2c: case 0x2d: case 0x2e: case 0x2f: + if (!(dev->pmu_conf[0xd8] & 0x08)) + dev->pmu_conf[addr] = val; + break; + + case 0x40: + dev->pmu_conf[addr] = val & 0x1f; + pic_set_smi_irq_mask(8, (dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x40] & 0x03)); + break; + case 0x41: + dev->pmu_conf[addr] = val & 0x10; + ali1543_log("PMU41: %02X\n", val); + apm_set_do_smi(dev->acpi->apm, (dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x41] & 0x10)); + break; + + /* TODO: Is the status R/W or R/WC? */ + case 0x42: + dev->pmu_conf[addr] &= ~(val & 0x1f); + break; + case 0x43: + dev->pmu_conf[addr] &= ~(val & 0x10); + if (val & 0x10) + acpi_ali_soft_smi_status_write(dev->acpi, 0); + break; + + case 0x44: + dev->pmu_conf[addr] = val; + break; + case 0x45: + dev->pmu_conf[addr] = val & 0x9f; + break; + case 0x46: + dev->pmu_conf[addr] = val & 0x18; + break; + + /* TODO: Is the status R/W or R/WC? */ + case 0x48: + dev->pmu_conf[addr] &= ~val; + break; + case 0x49: + dev->pmu_conf[addr] &= ~(val & 0x9f); + break; + case 0x4a: + dev->pmu_conf[addr] &= ~(val & 0x38); + break; + + case 0x4c: + dev->pmu_conf[addr] = val & 5; + break; + case 0x4d: + dev->pmu_conf[addr] = val & 1; + break; + + /* TODO: Is the status R/W or R/WC? */ + case 0x4e: + dev->pmu_conf[addr] &= ~(val & 5); + break; + case 0x4f: + dev->pmu_conf[addr] &= ~(val & 1); + break; + + case 0x50: case 0x51: + if (dev->type == 1) + dev->pmu_conf[addr] = val; + break; + + case 0x52: case 0x53: + if (dev->type == 1) + dev->pmu_conf[addr] &= ~val; + break; + + case 0x54: /* Standby timer */ + dev->pmu_conf[addr] = val; + break; + case 0x55: /* APM Timer */ + dev->pmu_conf[addr] = val & 0x7f; + break; + case 0x59: /* Global display timer. */ + dev->pmu_conf[addr] = val & 0x1f; + break; + + case 0x5b: /* ACPI/SMB Base I/O Control */ + if (dev->type == 1) + dev->pmu_conf[addr] = val & 0x87; + else + dev->pmu_conf[addr] = val & 0x7f; + break; + + case 0x60: + dev->pmu_conf[addr] = val; + break; + case 0x61: + dev->pmu_conf[addr] = val & 0x13; + break; + case 0x62: + dev->pmu_conf[addr] = val & 0xf1; + break; + case 0x63: + dev->pmu_conf[addr] = val & 0x07; + break; + + case 0x64: + dev->pmu_conf[addr] = val; + break; + case 0x65: + dev->pmu_conf[addr] = val & 0x11; + break; + + case 0x68: + dev->pmu_conf[addr] = val & 0x07; + break; + + case 0x6c: case 0x6d: + dev->pmu_conf[addr] = val; + break; + case 0x6e: + dev->pmu_conf[addr] = val & 0xbf; + break; + case 0x6f: + if (dev->type == 1) + dev->pmu_conf[addr] = val & 0x1e; + else + dev->pmu_conf[addr] = val & 0x1f; + break; + + case 0x70: + dev->pmu_conf[addr] = val; + break; + case 0x71: + dev->pmu_conf[addr] = val & 0x3f; + break; + + case 0x72: + dev->pmu_conf[addr] = val & 0x0f; + break; + + /* TODO: Is the status R/W or R/WC? */ + case 0x74: + dev->pmu_conf[addr] &= ~(val & 0x33); + break; + + case 0x75: + dev->pmu_conf[addr] = val; + break; + + case 0x76: + dev->pmu_conf[addr] = val & 0x7f; + break; + + case 0x77: + /* TODO: If bit 1 is clear, then status bit is set even if SMI is disabled. */ + dev->pmu_conf[addr] = val; + pic_set_smi_irq_mask(8, (dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x40] & 0x03)); + ali1543_log("PMU77: %02X\n", val); + apm_set_do_smi(dev->acpi->apm, (dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x41] & 0x10)); + break; + + case 0x78: + dev->pmu_conf[addr] = val; + break; + case 0x79: + dev->pmu_conf[addr] = val & 0x0f; + break; + + case 0x7a: + if (dev->type == 1) + dev->pmu_conf[addr] = val & 0x07; + else + dev->pmu_conf[addr] = val & 0x02; + break; + + case 0x7b: + if (dev->type == 1) + dev->pmu_conf[addr] = val; + else + dev->pmu_conf[addr] = val & 0x7f; + break; + + case 0x7c ... 0x7f: + dev->pmu_conf[addr] = val; + break; + + case 0x81: + dev->pmu_conf[addr] = val & 0xf0; + break; + + case 0x82: + if (dev->type == 1) + dev->pmu_conf[addr] = val & 0x01; + break; + + case 0x84 ... 0x87: + if (dev->type == 1) + dev->pmu_conf[addr] = val; + break; + case 0x88 ... 0x8b: + if (dev->type == 1) + dev->pmu_conf[addr] = val; + break; + + case 0x8c: case 0x8d: + dev->pmu_conf[addr] = val & 0x0f; + break; + + case 0x90: + if (dev->type == 1) + dev->pmu_conf[addr] = val & 0x0f; + else + dev->pmu_conf[addr] = val & 0x01; + break; + + case 0x91: + if (dev->type == 1) + dev->pmu_conf[addr] = val & 0x02; + break; + + case 0x94: + dev->pmu_conf[addr] = val & 0xf0; + break; + case 0x95 ... 0x97: + dev->pmu_conf[addr] = val; + break; + + case 0x98: case 0x99: + if (dev->type == 1) + dev->pmu_conf[addr] = val; + break; + + case 0xa4: case 0xa5: + dev->pmu_conf[addr] = val; + break; + + case 0xb2: + dev->pmu_conf[addr] = val & 0x01; + break; + + case 0xb3: + dev->pmu_conf[addr] = val & 0x7f; + break; + + case 0xb4: + dev->pmu_conf[addr] = val & 0x7c; + break; + + case 0xb5: case 0xb7: + dev->pmu_conf[addr] = val & 0x0f; + break; + + case 0xb8: case 0xb9: + if (dev->type == 1) + dev->pmu_conf[addr] = val; + break; + + case 0xbc: + outb(0x70, val); + break; + + case 0xbd: + dev->pmu_conf[addr] = val & 0x0f; + acpi_set_timer32(dev->acpi, val & 0x04); + break; + + case 0xbe: + dev->pmu_conf[addr] = val & 0x03; + break; + + /* Continue Further Later */ + /* GPO Registers */ + case 0xc0: + dev->pmu_conf[addr] = val & 0x0f; + acpi_init_gporeg(dev->acpi, dev->pmu_conf[0xc0], dev->pmu_conf[0xc1], dev->pmu_conf[0xc2] | (dev->pmu_conf[0xc3] << 5), 0x00); + break; + case 0xc1: + dev->pmu_conf[addr] = val & 0x12; + acpi_init_gporeg(dev->acpi, dev->pmu_conf[0xc0], dev->pmu_conf[0xc1], dev->pmu_conf[0xc2] | (dev->pmu_conf[0xc3] << 5), 0x00); + break; + case 0xc2: + dev->pmu_conf[addr] = val & 0x1c; + acpi_init_gporeg(dev->acpi, dev->pmu_conf[0xc0], dev->pmu_conf[0xc1], dev->pmu_conf[0xc2] | (dev->pmu_conf[0xc3] << 5), 0x00); + break; + case 0xc3: + dev->pmu_conf[addr] = val & 0x06; + acpi_init_gporeg(dev->acpi, dev->pmu_conf[0xc0], dev->pmu_conf[0xc1], dev->pmu_conf[0xc2] | (dev->pmu_conf[0xc3] << 5), 0x00); + break; + + case 0xc6: + dev->pmu_conf[addr] = val & 0x06; + break; + + case 0xc8: case 0xc9: + dev->pmu_conf[addr] = val & 0x01; + break; + + case 0xca: + /* TODO: Write to this port causes a beep. */ + dev->pmu_conf[addr] = val; + break; + + case 0xcc: + if (dev->type == 1) + dev->pmu_conf[addr] = val & 0x1f; + break; + case 0xcd: + if (dev->type == 1) + dev->pmu_conf[addr] = val & 0x33; + break; + + case 0xd4: + dev->pmu_conf[addr] = val & 0x01; + break; + + case 0xd8: + dev->pmu_conf[addr] = val & 0xfd; + break; + case 0xd9: + if (dev->type == 1) + dev->pmu_conf[addr] = val & 0x3f; + break; + + case 0xe0: + dev->pmu_conf[addr] = val & 0x03; + if (dev->type == 1) + smbus_ali7101_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xc0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4))); + else + smbus_ali7101_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xe0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4))); + break; + + case 0xe1: + dev->pmu_conf[addr] = val; + break; + + case 0xe2: + dev->pmu_conf[addr] = val & 0xf8; + break; + + default: + dev->pmu_conf[addr] = val; + break; + } +} + + +static uint8_t +ali7101_read(int func, int addr, void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + uint8_t ret = 0xff; + + if (dev->pmu_dev_enable && (func == 0)) { + if ((dev->pmu_conf[0xc9] & 0x01) && (addr >= 0x40) && (addr != 0xc9)) + return 0xff; + + /* TODO: C4, C5 = GPIREG (masks: 0D, 0E) */ + if (addr == 0x43) + ret = acpi_ali_soft_smi_status_read(dev->acpi) ? 0x10 : 0x00; + else if (addr == 0xbc) + ret = inb(0x70); + else + ret = dev->pmu_conf[addr]; + + if (dev->pmu_conf[0x77] & 0x10) { + switch (addr) { + case 0x42: + dev->pmu_conf[addr] &= 0xe0; + break; + case 0x43: + dev->pmu_conf[addr] &= 0xef; + acpi_ali_soft_smi_status_write(dev->acpi, 0); + break; + + case 0x48: + dev->pmu_conf[addr] = 0x00; + break; + case 0x49: + dev->pmu_conf[addr] &= 0x60; + break; + case 0x4a: + dev->pmu_conf[addr] &= 0xc7; + break; + + case 0x4e: + dev->pmu_conf[addr] &= 0xfa; + break; + case 0x4f: + dev->pmu_conf[addr] &= 0xfe; + break; + + case 0x74: + dev->pmu_conf[addr] &= 0xcc; + break; + } + } + } + + return ret; +} + + +static void +ali1533_sio_fdc_handler(ali1543_t *dev) +{ + fdc_remove(dev->fdc_controller); + + if (dev->device_regs[0][0x30] & 1) { + ali1543_log("New FDC base address: %04X\n", dev->device_regs[0][0x61] | (dev->device_regs[0][0x60] << 8)); + fdc_set_base(dev->fdc_controller, dev->device_regs[0][0x61] | (dev->device_regs[0][0x60] << 8)); + fdc_set_irq(dev->fdc_controller, dev->device_regs[0][0x70] & 0xf); + fdc_set_dma_ch(dev->fdc_controller, dev->device_regs[0][0x74] & 0x07); + ali1543_log("M1543-SIO FDC: ADDR %04x IRQ %02x DMA %02x\n", dev->device_regs[0][0x61] | (dev->device_regs[0][0x60] << 8), dev->device_regs[0][0x70] & 0xf, dev->device_regs[0][0x74] & 0x07); + } +} + + +static void +ali1533_sio_uart_handler(int num, ali1543_t *dev) +{ + serial_remove(dev->uart[num]); + + if (dev->device_regs[num + 4][0x30] & 1) { + serial_setup(dev->uart[num], dev->device_regs[num + 4][0x61] | (dev->device_regs[num + 4][0x60] << 8), dev->device_regs[num + 4][0x70] & 0xf); + ali1543_log("M1543-SIO UART%d: ADDR %04x IRQ %02x\n", num, dev->device_regs[num + 4][0x61] | (dev->device_regs[num + 4][0x60] << 8), dev->device_regs[num + 4][0x70] & 0xf); + } +} + + +void +ali1533_sio_lpt_handler(ali1543_t *dev) +{ + lpt1_remove(); + + if (dev->device_regs[3][0x30] & 1) { + lpt1_init(dev->device_regs[3][0x61] | (dev->device_regs[3][0x60] << 8)); + lpt1_irq(dev->device_regs[3][0x70] & 0xf); + ali1543_log("M1543-SIO LPT: ADDR %04x IRQ %02x\n", dev->device_regs[3][0x61] | (dev->device_regs[3][0x60] << 8), dev->device_regs[3][0x70] & 0xf); + } +} + + +void +ali1533_sio_ldn(uint16_t ldn, ali1543_t *dev) +{ + /* We don't include all LDN's */ + switch (ldn) { + case 0: /* FDC */ + ali1533_sio_fdc_handler(dev); + break; + case 3: /* LPT */ + ali1533_sio_lpt_handler(dev); + break; + /* UART */ + case 4: case 5: + ali1533_sio_uart_handler(ldn - 4, dev); + break; + } +} + + +static void +ali1533_sio_write(uint16_t addr, uint8_t val, void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + + switch (addr) { + case 0x3f0: + dev->sio_index = val; + if (dev->sio_index == 0x51) + dev->in_configuration_mode = 1; + else if ((dev->sio_index == 0x23) && (dev->in_configuration_mode == 1)) + dev->in_configuration_mode = 2; + else if (dev->sio_index == 0xbb) + dev->in_configuration_mode = 0; + break; + + case 0x3f1: + if (dev->in_configuration_mode == 2) { + switch (dev->sio_index) { + case 0x07: + dev->sio_regs[dev->sio_index] = val & 0x7; + break; + + case 0x22: + dev->sio_regs[dev->sio_index] = val & 0x39; + break; + + case 0x23: + dev->sio_regs[dev->sio_index] = val & 0x38; + break; + + default: + if ((dev->sio_index < 0x30) || (dev->sio_index == 0x51) || (dev->sio_index == 0xbb)) + dev->sio_regs[dev->sio_index] = val; + else if (dev->sio_regs[0x07] <= 7) + dev->device_regs[dev->sio_regs[0x07]][dev->sio_index] = val; + break; + } + } + break; + } + + if ((!dev->in_configuration_mode) && (dev->sio_regs[0x07] <= 7) && (addr == 0x03f0)) + ali1533_sio_ldn(dev->sio_regs[0x07], dev); +} + + +static uint8_t +ali1533_sio_read(uint16_t addr, void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + uint8_t ret = 0xff; + + if (addr == 0x03f1) { + if (dev->sio_index >= 0x30) + ret = dev->device_regs[dev->sio_regs[0x07]][dev->sio_index]; + else + ret = dev->sio_regs[dev->sio_index]; + } + + return ret; +} + + +static void +ali1543_reset(void *priv) +{ + ali1543_t *dev = (ali1543_t *)priv; + int i; + + /* Temporarily enable everything. Register writes will disable the devices. */ + dev->ide_dev_enable = 1; + dev->usb_dev_enable = 1; + dev->pmu_dev_enable = 1; + + /* M5229 */ + ali5229_chip_reset(dev); /* M5237 */ + memset(dev->usb_conf, 0x00, sizeof(dev->usb_conf)); dev->usb_conf[0x00] = 0xb9; dev->usb_conf[0x01] = 0x10; dev->usb_conf[0x02] = 0x37; @@ -837,24 +1547,75 @@ ali1543_reset(void *priv) dev->usb_conf[0x3d] = 0x01; ali5237_write(0, 0x04, 0x00, dev); + ali5237_write(0, 0x10, 0x00, dev); + ali5237_write(0, 0x11, 0x00, dev); + ali5237_write(0, 0x12, 0x00, dev); + ali5237_write(0, 0x13, 0x00, dev); /* M7101 */ + memset(dev->pmu_conf, 0x00, sizeof(dev->pmu_conf)); dev->pmu_conf[0x00] = 0xb9; dev->pmu_conf[0x01] = 0x10; dev->pmu_conf[0x02] = 0x01; dev->pmu_conf[0x03] = 0x71; - dev->pmu_conf[0x04] = 0x0f; dev->pmu_conf[0x05] = 0x00; dev->pmu_conf[0x0a] = 0x01; dev->pmu_conf[0x0b] = 0x06; + dev->pmu_conf[0xe2] = 0x20; acpi_set_slot(dev->acpi, dev->pmu_slot); acpi_set_nvr(dev->acpi, dev->nvr); - ali7101_write(0, 0x04, 0x00, dev); + ali7101_write(0, 0x04, 0x0f, dev); + ali7101_write(0, 0x10, 0x01, dev); + ali7101_write(0, 0x11, 0x00, dev); + ali7101_write(0, 0x12, 0x00, dev); + ali7101_write(0, 0x13, 0x00, dev); + ali7101_write(0, 0x14, 0x01, dev); + ali7101_write(0, 0x15, 0x00, dev); + ali7101_write(0, 0x16, 0x00, dev); + ali7101_write(0, 0x17, 0x00, dev); + ali7101_write(0, 0x40, 0x00, dev); + ali7101_write(0, 0x41, 0x00, dev); + ali7101_write(0, 0x42, 0x00, dev); + ali7101_write(0, 0x43, 0x00, dev); + ali7101_write(0, 0x77, 0x00, dev); + ali7101_write(0, 0xbd, 0x00, dev); ali7101_write(0, 0xc0, 0x00, dev); + ali7101_write(0, 0xc1, 0x00, dev); + ali7101_write(0, 0xc2, 0x00, dev); + ali7101_write(0, 0xc3, 0x00, dev); + ali7101_write(0, 0xe0, 0x00, dev); + + /* Do the bridge last due to device deactivations. */ + /* M1533 */ + dev->pci_conf[0x00] = 0xb9; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x33; + dev->pci_conf[0x03] = 0x15; + dev->pci_conf[0x04] = 0x0f; + dev->pci_conf[0x07] = 0x02; + if (dev->type == 1) + dev->pci_conf[0x08] = 0xc0; + dev->pci_conf[0x0a] = 0x01; + dev->pci_conf[0x0b] = 0x06; + + ali1533_write(0, 0x48, 0x00, dev); // Disables all IRQ's + ali1533_write(0, 0x44, 0x00, dev); + ali1533_write(0, 0x4d, 0x00, dev); + ali1533_write(0, 0x53, 0x00, dev); + ali1533_write(0, 0x58, 0x00, dev); + ali1533_write(0, 0x5f, 0x00, dev); + ali1533_write(0, 0x72, 0x00, dev); + ali1533_write(0, 0x74, 0x00, dev); + ali1533_write(0, 0x75, 0x00, dev); + ali1533_write(0, 0x76, 0x00, dev); /* M1543 Super I/O */ + memset(dev->sio_regs, 0x00, sizeof(dev->sio_regs)); + for (i = 0; i < 8; i++) + memset(dev->device_regs[i], 0x00, sizeof(dev->device_regs[i])); + dev->device_regs[0][0x60] = 0x03; dev->device_regs[0][0x61] = 0xf0; dev->device_regs[0][0x70] = 0x06; @@ -887,8 +1648,11 @@ ali1543_reset(void *priv) ali1533_sio_uart_handler(0, dev); ali1533_sio_uart_handler(1, dev); ali1533_sio_lpt_handler(dev); + + unmask_a20_in_smm = 1; } + static void ali1543_close(void *priv) { @@ -897,6 +1661,7 @@ ali1543_close(void *priv) free(dev); } + static void * ali1543_init(const device_t *info) { @@ -912,7 +1677,7 @@ ali1543_init(const device_t *info) /* Device 0C: M7101 Power Managment Controller */ dev->pmu_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, ali7101_read, ali7101_write, dev); - /* Device 0D: M5237 USB */ + /* Device 0F: M5237 USB */ dev->usb_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, ali5237_read, ali5237_write, dev); /* Ports 3F0-1h: M1543 Super I/O */ @@ -920,20 +1685,21 @@ ali1543_init(const device_t *info) /* ACPI */ dev->acpi = device_add(&acpi_ali_device); - dev->nvr = device_add(&at_nvr_device); // Generic NVR - - /* APM */ - dev->apm = device_add(&apm_pci_device); + dev->nvr = device_add(&piix4_nvr_device); /* DMA */ dma_alias_set(); + + dma_set_sg_base(0x04); + dma_set_params(1, 0xffffffff); + dma_ext_mode_init(); dma_high_page_init(); /* DDMA */ dev->ddma = device_add(&ddma_device); /* Floppy Disk Controller */ - dev->fdc_controller = device_add(&fdc_at_device); + dev->fdc_controller = device_add(&fdc_at_smc_device); /* IDE Controllers */ dev->ide_controller[0] = device_add_inst(&sff8038i_device, 1); @@ -947,19 +1713,30 @@ ali1543_init(const device_t *info) dev->uart[1] = device_add_inst(&ns16550_device, 2); /* Standard SMBus */ - dev->smbus = device_add(&piix4_smbus_device); + dev->smbus = device_add(&ali7101_smbus_device); /* Super I/O Configuration Mechanism */ - dev->in_configuration_mode = 1; + dev->in_configuration_mode = 0; /* USB */ dev->usb = device_add(&usb_device); + dev->type = info->local; + + pci_enable_mirq(0); + pci_enable_mirq(1); + pci_enable_mirq(2); + pci_enable_mirq(3); + pci_enable_mirq(4); + pci_enable_mirq(5); + pci_enable_mirq(6); + ali1543_reset(dev); return dev; } + const device_t ali1543_device = { "ALi M1543 Desktop South Bridge", DEVICE_PCI, @@ -967,7 +1744,21 @@ const device_t ali1543_device = { ali1543_init, ali1543_close, ali1543_reset, - {NULL}, + { NULL }, NULL, NULL, - NULL}; + NULL +}; + +const device_t ali1543c_device = { + "ALi M1543C Desktop South Bridge", + DEVICE_PCI, + 1, + ali1543_init, + ali1543_close, + ali1543_reset, + { NULL }, + NULL, + NULL, + NULL +}; diff --git a/src/chipset/ali1621.c b/src/chipset/ali1621.c new file mode 100644 index 000000000..cc83899e8 --- /dev/null +++ b/src/chipset/ali1621.c @@ -0,0 +1,685 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the ALi M1621/2 CPU-to-PCI Bridge. + * + * Authors: Miran Grca, + * + * Copyright 2021 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/timer.h> + +#include <86box/device.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/smram.h> +#include <86box/spd.h> + +#include <86box/chipset.h> + + +typedef struct ali1621_t +{ + uint8_t pci_conf[256]; + + smram_t * smram[2]; +} ali1621_t; + + +#ifdef ENABLE_ALI1621_LOG +int ali1621_do_log = ENABLE_ALI1621_LOG; +static void +ali1621_log(const char *fmt, ...) +{ + va_list ap; + + if (ali1621_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define ali1621_log(fmt, ...) +#endif + + +/* Table translated to a more sensible format: + Read cycles: + SMREN SMM Mode Code Data + 0 X X PCI PCI + 1 0 Close PCI PCI + 1 0 Lock PCI PCI + 1 0 Protect PCI PCI + 1 0 Open DRAM DRAM + 1 1 Open DRAM DRAM + 1 1 Protect DRAM DRAM + 1 1 Close DRAM PCI + 1 1 Lock DRAM PCI + + Write cycles: + SMWEN SMM Mode Data + 0 X X PCI + 1 0 Close PCI + 1 0 Lock PCI + 1 0 Protect PCI + 1 0 Open DRAM + 1 1 Open DRAM + 1 1 Protect DRAM + 1 1 Close PCI + 1 1 Lock PCI + + Explanation of the modes based above: + If SM*EN = 0, SMRAM is entirely disabled, otherwise: + If mode is Close or Lock, then SMRAM always goes to PCI outside SMM, + and data to PCI, code to DRAM in SMM; + If mode is Protect, then SMRAM always goes to PCI outside SMM and + DRAM in SMM; + If mode is Open, then SMRAM always goes to DRAM. + Read and write are enabled separately. + */ +static void +ali1621_smram_recalc(uint8_t val, ali1621_t *dev) +{ + uint16_t access_smm = 0x0000, access_normal = 0x0000; + + smram_disable_all(); + + if (val & 0xc0) { + /* SMRAM 0: A0000-BFFFF */ + if (val & 0x80) { + access_smm = ACCESS_SMRAM_X; + + switch (val & 0x30) { + case 0x10: /* Open. */ + access_normal = ACCESS_SMRAM_RX; + /* FALLTHROUGH */ + case 0x30: /* Protect. */ + access_smm |= ACCESS_SMRAM_R; + break; + } + } + + if (val & 0x40) switch (val & 0x30) { + case 0x10: /* Open. */ + access_normal |= ACCESS_SMRAM_W; + /* FALLTHROUGH */ + case 0x30: /* Protect. */ + access_smm |= ACCESS_SMRAM_W; + break; + } + + smram_enable(dev->smram[0], 0xa0000, 0xa0000, 0x20000, ((val & 0x30) == 0x10), (val & 0x30)); + + mem_set_access(ACCESS_NORMAL, 3, 0xa0000, 0x20000, access_normal); + mem_set_access(ACCESS_SMM, 3, 0xa0000, 0x20000, access_smm); + } + + if (val & 0x08) + smram_enable(dev->smram[1], 0x38000, 0xa8000, 0x08000, 0, 1); + + flushmmucache_nopc(); +} + + +static void +ali1621_shadow_recalc(int cur_reg, ali1621_t *dev) +{ + int i, r_bit, w_bit, reg; + uint32_t base, flags = 0; + + shadowbios = shadowbios_write = 0; + + /* C0000-EFFFF */ + for (i = 0; i < 12; i++) { + base = 0x000c0000 + (i << 14); + r_bit = (i << 1) + 4; + reg = 0x84; + if (r_bit > 23) { + r_bit &= 7; + reg += 3; + } else if (r_bit > 15) { + r_bit &= 7; + reg += 2; + } else if (r_bit > 7) { + r_bit &= 7; + reg++; + } + w_bit = r_bit + 1; + + flags = (dev->pci_conf[reg] & (1 << r_bit)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + flags |= ((dev->pci_conf[reg] & (1 << w_bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY); + + if (base >= 0x000e0000) { + if (dev->pci_conf[reg] & (1 << r_bit)) + shadowbios |= 1; + if (dev->pci_conf[reg] & (1 << r_bit)) + shadowbios_write |= 1; + } + + ali1621_log("%08X-%08X shadow: R%c, W%c\n", base, base + 0x00003fff, + (dev->pci_conf[reg] & (1 << r_bit)) ? 'I' : 'E', (dev->pci_conf[reg] & (1 << w_bit)) ? 'I' : 'E'); + mem_set_mem_state_both(base, 0x00004000, flags); + } + + /* F0000-FFFFF */ + base = 0x000f0000; + r_bit = 4; + w_bit = 5; + reg = 0x87; + + flags = (dev->pci_conf[reg] & (1 << r_bit)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + flags |= ((dev->pci_conf[reg] & (1 << w_bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY); + + if (dev->pci_conf[reg] & (1 << r_bit)) + shadowbios |= 1; + if (dev->pci_conf[reg] & (1 << r_bit)) + shadowbios_write |= 1; + + ali1621_log("%08X-%08X shadow: R%c, W%c\n", base, base + 0x0000ffff, + (dev->pci_conf[reg] & (1 << r_bit)) ? 'I' : 'E', (dev->pci_conf[reg] & (1 << w_bit)) ? 'I' : 'E'); + mem_set_mem_state_both(base, 0x00010000, flags); + + flushmmucache_nopc(); +} + + +static void +ali1621_mask_bar(ali1621_t *dev) +{ + uint32_t bar, mask; + + switch (dev->pci_conf[0xbc] & 0x0f) { + case 0x00: + default: + mask = 0x00000000; + break; + case 0x01: + mask = 0xfff00000; + break; + case 0x02: + mask = 0xffe00000; + break; + case 0x03: + mask = 0xffc00000; + break; + case 0x04: + mask = 0xff800000; + break; + case 0x06: + mask = 0xff000000; + break; + case 0x07: + mask = 0xfe000000; + break; + case 0x08: + mask = 0xfc000000; + break; + case 0x09: + mask = 0xf8000000; + break; + case 0x0a: + mask = 0xf0000000; + break; + } + + bar = ((dev->pci_conf[0x13] << 24) | (dev->pci_conf[0x12] << 16)) & mask; + dev->pci_conf[0x12] = (bar >> 16) & 0xff; + dev->pci_conf[0x13] = (bar >> 24) & 0xff; +} + + +static void +ali1621_write(int func, int addr, uint8_t val, void *priv) +{ + ali1621_t *dev = (ali1621_t *)priv; + + switch (addr) { + case 0x04: + dev->pci_conf[addr] = val & 0x01; + break; + case 0x05: + dev->pci_conf[addr] = val & 0x01; + break; + + case 0x07: + dev->pci_conf[addr] &= ~(val & 0xf0); + break; + + case 0x0d: + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x12: + dev->pci_conf[0x12] = (val & 0xc0); + ali1621_mask_bar(dev); + break; + case 0x13: + dev->pci_conf[0x13] = val; + ali1621_mask_bar(dev); + break; + + case 0x34: + dev->pci_conf[addr] = val; + break; + + case 0x40: + dev->pci_conf[addr] = val; + break; + case 0x41: + dev->pci_conf[addr] = val; + break; + + case 0x42: + dev->pci_conf[addr] = val; + break; + case 0x43: + dev->pci_conf[addr] = val; + break; + + case 0x44: + dev->pci_conf[addr] = val; + break; + case 0x45: + dev->pci_conf[addr] = val; + break; + + case 0x46: + dev->pci_conf[addr] = val; + break; + case 0x47: + dev->pci_conf[addr] = val; + break; + + case 0x48: + dev->pci_conf[addr] = val; + break; + case 0x49: + dev->pci_conf[addr] = val; + break; + + case 0x4a: + dev->pci_conf[addr] = val; + break; + + case 0x4b: + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x4c: + dev->pci_conf[addr] = val; + break; + + case 0x4d: + dev->pci_conf[addr] = val; + break; + + case 0x4e: + dev->pci_conf[addr] = val; + break; + case 0x4f: + dev->pci_conf[addr] = val; + break; + + case 0x50: + dev->pci_conf[addr] = val & 0xef; + break; + + case 0x51: + dev->pci_conf[addr] = val; + break; + + case 0x52: + dev->pci_conf[addr] = val & 0x9f; + break; + + case 0x53: + dev->pci_conf[addr] = val; + break; + + case 0x54: + dev->pci_conf[addr] = val & 0xb4; + break; + case 0x55: + dev->pci_conf[addr] = val & 0x01; + break; + + case 0x56: + dev->pci_conf[addr] = val & 0x3f; + break; + + case 0x57: + dev->pci_conf[addr] = val & 0x08; + break; + + case 0x58: + dev->pci_conf[addr] = val; + break; + + case 0x59: + dev->pci_conf[addr] = val; + break; + + case 0x5a: + dev->pci_conf[addr] = val; + break; + + case 0x5c: + dev->pci_conf[addr] = val & 0x01; + break; + + case 0x60: + dev->pci_conf[addr] = val; + break; + + case 0x61: + dev->pci_conf[addr] = val; + break; + + case 0x62: + dev->pci_conf[addr] = val; + break; + + case 0x63: + dev->pci_conf[addr] = val; + break; + + case 0x64: + dev->pci_conf[addr] = val & 0xb7; + break; + case 0x65: + dev->pci_conf[addr] = val & 0x01; + break; + + case 0x66: + dev->pci_conf[addr] &= ~(val & 0x33); + break; + + case 0x67: + dev->pci_conf[addr] = val; + break; + + case 0x68: + dev->pci_conf[addr] = val; + break; + + case 0x69: + dev->pci_conf[addr] = val; + break; + + case 0x6c ... 0x7b: + /* Bits 22:20 = DRAM Row size: + - 000: 4 MB; + - 001: 8 MB; + - 010: 16 MB; + - 011: 32 MB; + - 100: 64 MB; + - 101: 128 MB; + - 110: 256 MB; + - 111: Reserved. */ + dev->pci_conf[addr] = val; + spd_write_drbs_ali1621(dev->pci_conf, 0x6c, 0x7b); + break; + + case 0x7c ... 0x7f: + dev->pci_conf[addr] = val; + break; + + case 0x80: + dev->pci_conf[addr] = val; + break; + case 0x81: + dev->pci_conf[addr] = val & 0xdf; + break; + + case 0x82: + dev->pci_conf[addr] = val & 0xf7; + break; + + case 0x83: + dev->pci_conf[addr] = val & 0xfc; + ali1621_smram_recalc(val & 0xfc, dev); + break; + + case 0x84 ... 0x87: + if (addr == 0x87) + dev->pci_conf[addr] = val & 0x3f; + else + dev->pci_conf[addr] = val; + ali1621_shadow_recalc(val, dev); + break; + + case 0x88: case 0x89: + dev->pci_conf[addr] = val; + break; + case 0x8a: + dev->pci_conf[addr] = val & 0xc5; + break; + case 0x8b: + dev->pci_conf[addr] = val & 0xbf; + break; + + case 0x8c ... 0x8f: + dev->pci_conf[addr] = val; + break; + + case 0x90: + dev->pci_conf[addr] = val; + break; + case 0x91: + dev->pci_conf[addr] = val & 0x07; + break; + + case 0x94 ... 0x97: + dev->pci_conf[addr] = val; + break; + + case 0x98 ... 0x9b: + dev->pci_conf[addr] = val; + break; + + case 0x9c ... 0x9f: + dev->pci_conf[addr] = val; + break; + + case 0xa0: case 0xa1: + dev->pci_conf[addr] = val; + break; + + case 0xbc: + dev->pci_conf[addr] = val & 0x0f; + ali1621_mask_bar(dev); + break; + case 0xbd: + dev->pci_conf[addr] = val & 0xf0; + break; + case 0xbe: case 0xbf: + dev->pci_conf[addr] = val; + break; + + case 0xc0: + dev->pci_conf[addr] = val & 0xb1; + break; + + case 0xc4 ... 0xc7: + dev->pci_conf[addr] = val; + break; + + case 0xc8: + dev->pci_conf[addr] = val & 0x8c; + break; + case 0xc9: + dev->pci_conf[addr] = val; + break; + case 0xca: + dev->pci_conf[addr] = val & 0x7f; + break; + case 0xcb: + dev->pci_conf[addr] = val & 0x87; + break; + + case 0xcc ... 0xcf: + dev->pci_conf[addr] = val; + break; + + case 0xd0: + dev->pci_conf[addr] = val & 0x80; + break; + case 0xd2: + dev->pci_conf[addr] = val & 0x40; + break; + case 0xd3: + dev->pci_conf[addr] = val & 0xb0; + break; + + case 0xd4: + dev->pci_conf[addr] = val; + break; + case 0xd5: + dev->pci_conf[addr] = val & 0xef; + break; + case 0xd6: case 0xd7: + dev->pci_conf[addr] = val; + break; + + case 0xf0 ... 0xff: + dev->pci_conf[addr] = val; + break; + } +} + + +static uint8_t +ali1621_read(int func, int addr, void *priv) +{ + ali1621_t *dev = (ali1621_t *)priv; + uint8_t ret = 0xff; + + ret = dev->pci_conf[addr]; + + return ret; +} + + +static void +ali1621_reset(void *priv) +{ + ali1621_t *dev = (ali1621_t *)priv; + int i; + + /* Default Registers */ + dev->pci_conf[0x00] = 0xb9; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x21; + dev->pci_conf[0x03] = 0x16; + dev->pci_conf[0x04] = 0x06; + dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = 0x10; + dev->pci_conf[0x07] = 0x04; + dev->pci_conf[0x08] = 0x01; + dev->pci_conf[0x09] = 0x00; + dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x10] = 0x08; + dev->pci_conf[0x34] = 0xb0; + dev->pci_conf[0x40] = 0x0c; + dev->pci_conf[0x41] = 0x0c; + dev->pci_conf[0x4c] = 0x04; + dev->pci_conf[0x4d] = 0x04; + dev->pci_conf[0x4e] = 0x7f; + dev->pci_conf[0x4f] = 0x7f; + dev->pci_conf[0x50] = 0x0c; + dev->pci_conf[0x53] = 0x02; + dev->pci_conf[0x5a] = 0x02; + dev->pci_conf[0x63] = 0x02; + dev->pci_conf[0x6c] = dev->pci_conf[0x70] = dev->pci_conf[0x74] = dev->pci_conf[0x78] = 0xff; + dev->pci_conf[0x6d] = dev->pci_conf[0x71] = dev->pci_conf[0x75] = dev->pci_conf[0x79] = 0xff; + dev->pci_conf[0x6e] = dev->pci_conf[0x72] = dev->pci_conf[0x76] = dev->pci_conf[0x7a] = 0x00; + dev->pci_conf[0x6f] = dev->pci_conf[0x73] = dev->pci_conf[0x77] = dev->pci_conf[0x7b] = 0xe0; + dev->pci_conf[0x6f] |= 0x06; + dev->pci_conf[0x7c] = 0x11; + dev->pci_conf[0x7d] = 0xc4; + dev->pci_conf[0x7e] = 0xc7; + dev->pci_conf[0x80] = 0x01; + dev->pci_conf[0x81] = 0xc0; + dev->pci_conf[0x8e] = 0x01; + dev->pci_conf[0xa0] = 0x20; + dev->pci_conf[0xb0] = 0x02; + dev->pci_conf[0xb2] = 0x10; + dev->pci_conf[0xb4] = 0x03; + dev->pci_conf[0xb5] = 0x02; + dev->pci_conf[0xb7] = 0x20; + dev->pci_conf[0xc0] = 0x80; + dev->pci_conf[0xc9] = 0x28; + dev->pci_conf[0xd4] = 0x10; + dev->pci_conf[0xd5] = 0x01; + dev->pci_conf[0xf0] = dev->pci_conf[0xf4] = dev->pci_conf[0xf8] = dev->pci_conf[0xfc] = 0x20; + dev->pci_conf[0xf1] = dev->pci_conf[0xf5] = dev->pci_conf[0xf9] = dev->pci_conf[0xfd] = 0x43; + dev->pci_conf[0xf2] = dev->pci_conf[0xf6] = dev->pci_conf[0xfa] = dev->pci_conf[0xfe] = 0x21; + dev->pci_conf[0xf3] = dev->pci_conf[0xf7] = dev->pci_conf[0xfb] = dev->pci_conf[0xff] = 0x43; + + ali1621_write(0, 0x83, 0x08, dev); + + for (i = 0; i < 4; i++) + ali1621_write(0, 0x84 + i, 0x00, dev); +} + + +static void +ali1621_close(void *priv) +{ + ali1621_t *dev = (ali1621_t *)priv; + + smram_del(dev->smram[1]); + smram_del(dev->smram[0]); + + free(dev); +} + + +static void * +ali1621_init(const device_t *info) +{ + ali1621_t *dev = (ali1621_t *)malloc(sizeof(ali1621_t)); + memset(dev, 0, sizeof(ali1621_t)); + + pci_add_card(PCI_ADD_NORTHBRIDGE, ali1621_read, ali1621_write, dev); + + dev->smram[0] = smram_add(); + dev->smram[1] = smram_add(); + + ali1621_reset(dev); + + device_add(&ali5247_agp_device); + + return dev; +} + + +const device_t ali1621_device = { + "ALi M1621 CPU-to-PCI Bridge", + DEVICE_PCI, + 0, + ali1621_init, + ali1621_close, + ali1621_reset, + {NULL}, + NULL, + NULL, + NULL +}; diff --git a/src/chipset/ali6117.c b/src/chipset/ali6117.c index ae4a30e61..e7196f952 100644 --- a/src/chipset/ali6117.c +++ b/src/chipset/ali6117.c @@ -109,7 +109,7 @@ ali6117_recalcmapping(ali6117_t *dev) } } - flushmmucache(); + flushmmucache_nopc(); } @@ -127,12 +127,16 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv) else if (dev->unlocked) { ali6117_log("ALI6117: regs[%02X] = %02X\n", dev->reg_offset, val); - switch (dev->reg_offset) { + if (!(dev->local & 0x08) || (dev->reg_offset < 0x30)) switch (dev->reg_offset) { case 0x30: case 0x34: case 0x35: case 0x3e: case 0x3f: case 0x46: case 0x4c: case 0x6a: case 0x73: return; /* read-only registers */ + case 0x10: + refresh_at_enable = !(val & 0x02) || !!(dev->regs[0x20] & 0x80); + break; + case 0x12: val &= 0xf7; /* FALL-THROUGH */ @@ -184,7 +188,7 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv) case 0x20: val &= 0xbf; - refresh_at_enable = !!(val & 0x80); + refresh_at_enable = !(dev->regs[0x10] & 0x02) || !!(val & 0x80); break; case 0x31: @@ -311,13 +315,17 @@ ali6117_reset(void *priv) dev->regs[0x1b] = 0xf0; dev->regs[0x1d] = 0xff; dev->regs[0x20] = 0x80; - dev->regs[0x30] = 0x08; - dev->regs[0x31] = 0x01; - dev->regs[0x34] = 0x04; /* enable internal RTC */ - dev->regs[0x35] = 0x20; /* enable internal KBC */ - dev->regs[0x36] = dev->local & 0x4; /* M6117D ID */ + if (dev->local & 0x08) { + dev->regs[0x30] = 0x08; + dev->regs[0x31] = 0x01; + dev->regs[0x34] = 0x04; /* enable internal RTC */ + dev->regs[0x35] = 0x20; /* enable internal KBC */ + dev->regs[0x36] = dev->local & 0x07; /* M6117D ID */ + } cpu_set_isa_speed(7159091); + + refresh_at_enable = 1; } @@ -361,13 +369,28 @@ ali6117_init(const device_t *info) ali6117_setup(dev); ali6117_reset(dev); - pic_elcr_io_handler(0); - refresh_at_enable = 0; + if (!(dev->local & 0x08)) + pic_elcr_io_handler(0); return dev; } +const device_t ali1217_device = +{ + "ALi M1217", + DEVICE_AT, + 0x8, + ali6117_init, + ali6117_close, + ali6117_reset, + { NULL }, + NULL, + NULL, + NULL +}; + + const device_t ali6117d_device = { "ALi M6117D", diff --git a/src/chipset/contaq_82c59x.c b/src/chipset/contaq_82c59x.c new file mode 100644 index 000000000..93c841b9b --- /dev/null +++ b/src/chipset/contaq_82c59x.c @@ -0,0 +1,375 @@ +/* + * 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 Contaq/Cypress 82C596(A) and 597 chipsets. + * + * Authors: Miran Grca, + * + * Copyright 2021 Miran Grca. + */ + +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/mem.h> +#include <86box/smram.h> +#include <86box/chipset.h> + + +#ifdef ENABLE_CONTAQ_82C59X_LOG +int contaq_82c59x_do_log = ENABLE_CONTAQ_82C59X_LOG; + +static void +contaq_82c59x_log(const char *fmt, ...) +{ + va_list ap; + + if (contaq_82c59x_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define contaq_82c59x_log(fmt, ...) +#endif + + +typedef struct +{ + uint32_t phys, virt; +} mem_remapping_t; + + +typedef struct +{ + uint8_t index, green, + smi_status_set, + regs[256], smi_status[2]; + + smram_t *smram[2]; +} contaq_82c59x_t; + + +static void +contaq_82c59x_isa_speed_recalc(contaq_82c59x_t *dev) +{ + if (dev->regs[0x1c] & 0x02) + cpu_set_isa_speed(7159091); + else { + /* TODO: ISA clock dividers for 386 and alt. 486. */ + switch (dev->regs[0x10] & 0x03) { + case 0x00: + cpu_set_isa_speed(cpu_busspeed / 4); + break; + case 0x01: + cpu_set_isa_speed(cpu_busspeed / 6); + break; + case 0x02: + cpu_set_isa_speed(cpu_busspeed / 8); + break; + case 0x03: + cpu_set_isa_speed(cpu_busspeed / 5); + break; + } + } +} + + +static void +contaq_82c59x_shadow_recalc(contaq_82c59x_t *dev) +{ + uint32_t i, base; + uint8_t bit; + + shadowbios = shadowbios_write = 0; + + /* F0000-FFFFF */ + if (dev->regs[0x15] & 0x80) { + shadowbios |= 1; + mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); + } else { + shadowbios_write |= 1; + mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + } + + /* C0000-CFFFF */ + if (dev->regs[0x15] & 0x01) + mem_set_mem_state_both(0xc0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + else { + for (i = 0; i < 4; i++) { + base = 0xc0000 + (i << 14); + bit = 1 << (i + 2); + if (dev->regs[0x15] & bit) { + if (dev->regs[0x15] & 0x02) + mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + else + mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + } else + mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + } + + if (dev->green) { + /* D0000-DFFFF */ + if (dev->regs[0x6e] & 0x01) + mem_set_mem_state_both(0xd0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + else { + for (i = 0; i < 4; i++) { + base = 0xd0000 + (i << 14); + bit = 1 << (i + 2); + if (dev->regs[0x6e] & bit) { + if (dev->regs[0x6e] & 0x02) + mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + else + mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } else + mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + } + + /* E0000-EFFFF */ + if (dev->regs[0x6f] & 0x01) + mem_set_mem_state_both(0xe0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + else { + for (i = 0; i < 4; i++) { + base = 0xe0000 + (i << 14); + bit = 1 << (i + 2); + if (dev->regs[0x6f] & bit) { + shadowbios |= 1; + if (dev->regs[0x6f] & 0x02) + mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + else { + shadowbios_write |= 1; + mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + } else + mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + } + } +} + + +static void +contaq_82c59x_smram_recalc(contaq_82c59x_t *dev) +{ + smram_disable(dev->smram[1]); + + if (dev->regs[0x70] & 0x04) + smram_enable(dev->smram[1], 0x00040000, 0x000a0000, 0x00020000, 1, 1); +} + + +static void +contaq_82c59x_write(uint16_t addr, uint8_t val, void *priv) +{ + contaq_82c59x_t *dev = (contaq_82c59x_t *)priv; + + switch (addr) { + case 0x22: + dev->index = val; + break; + + case 0x23: + contaq_82c59x_log("Contaq 82C59x: dev->regs[%02x] = %02x\n", dev->index, val); + + if ((dev->index >= 0x60) && !dev->green) + return; + + switch (dev->index) { + /* Registers common to 82C596(A) and 82C597. */ + case 0x10: + dev->regs[dev->index] = val; + contaq_82c59x_isa_speed_recalc(dev); + break; + + case 0x11: + dev->regs[dev->index] = val; + cpu_cache_int_enabled = !!(val & 0x01); + cpu_update_waitstates(); + break; + + case 0x12: case 0x13: + dev->regs[dev->index] = val; + break; + + case 0x14: + dev->regs[dev->index] = val; + reset_on_hlt = !!(val & 0x80); + break; + + case 0x15: + dev->regs[dev->index] = val; + contaq_82c59x_shadow_recalc(dev); + break; + + case 0x16 ... 0x1b: + dev->regs[dev->index] = val; + break; + + case 0x1c: + /* TODO: What's NPRST (generated if bit 3 is set)? */ + dev->regs[dev->index] = val; + contaq_82c59x_isa_speed_recalc(dev); + break; + + case 0x1d ... 0x1f: + dev->regs[dev->index] = val; + break; + + /* Green (82C597-specific) registers. */ + case 0x60 ... 0x63: + dev->regs[dev->index] = val; + break; + + case 0x64: + dev->regs[dev->index] = val; + if (val & 0x80) { + if (dev->regs[0x65] & 0x80) + smi_line = 1; + dev->smi_status[0] |= 0x10; + } + break; + + case 0x65 ... 0x69: + dev->regs[dev->index] = val; + break; + + case 0x6a: + dev->regs[dev->index] = val; + dev->smi_status_set = !!(val & 0x80); + break; + + case 0x6b ... 0x6d: + dev->regs[dev->index] = val; + break; + + case 0x6e: case 0x6f: + dev->regs[dev->index] = val; + contaq_82c59x_shadow_recalc(dev); + break; + + case 0x70: + dev->regs[dev->index] = val; + contaq_82c59x_smram_recalc(dev); + break; + + case 0x71 ... 0x79: + dev->regs[dev->index] = val; + break; + + case 0x7b: case 0x7c: + dev->regs[dev->index] = val; + break; + } + break; + } +} + + +static uint8_t +contaq_82c59x_read(uint16_t addr, void *priv) +{ + contaq_82c59x_t *dev = (contaq_82c59x_t *)priv; + uint8_t ret = 0xff; + + if (addr == 0x23) { + if (dev->index == 0x6a) { + ret = dev->smi_status[dev->smi_status_set]; + /* I assume it's cleared on read. */ + dev->smi_status[dev->smi_status_set] = 0x00; + } else + ret = dev->regs[dev->index]; + } + + return ret; +} + + +static void +contaq_82c59x_close(void *priv) +{ + contaq_82c59x_t *dev = (contaq_82c59x_t *)priv; + + smram_del(dev->smram[1]); + smram_del(dev->smram[0]); + + free(dev); +} + + +static void * +contaq_82c59x_init(const device_t *info) +{ + contaq_82c59x_t *dev = (contaq_82c59x_t *)malloc(sizeof(contaq_82c59x_t)); + memset(dev, 0x00, sizeof(contaq_82c59x_t)); + + dev->green = info->local; + + io_sethandler(0x0022, 0x0002, contaq_82c59x_read, NULL, NULL, contaq_82c59x_write, NULL, NULL, dev); + + contaq_82c59x_isa_speed_recalc(dev); + + cpu_cache_int_enabled = 0; + cpu_update_waitstates(); + + reset_on_hlt = 0; + + contaq_82c59x_shadow_recalc(dev); + + if (dev->green) { + /* SMRAM 0: Fixed A0000-BFFFF to A0000-BFFFF DRAM. */ + dev->smram[0] = smram_add(); + smram_enable(dev->smram[0], 0x000a0000, 0x000a0000, 0x00020000, 0, 1); + + /* SMRAM 1: Optional. */ + dev->smram[1] = smram_add(); + contaq_82c59x_smram_recalc(dev); + } + + return dev; +} + + +const device_t contaq_82c596a_device = { + "Contaq 82C596A", + 0, + 0, + contaq_82c59x_init, + contaq_82c59x_close, + NULL, + { NULL }, + NULL, + NULL, + NULL +}; + + +const device_t contaq_82c597_device = { + "Contaq 82C597", + 0, + 1, + contaq_82c59x_init, + contaq_82c59x_close, + NULL, + { NULL }, + NULL, + NULL, + NULL +}; diff --git a/src/chipset/ims8848.c b/src/chipset/ims8848.c new file mode 100644 index 000000000..da758ad5e --- /dev/null +++ b/src/chipset/ims8848.c @@ -0,0 +1,411 @@ +/* + * 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 IMS 8848/8849 chipset. + * + * + * + * Authors: Miran Grca, + * Tiseno100, + * + * Copyright 2021 Miran Grca. + * Copyright 2021 Tiseno100. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/io.h> +#include <86box/device.h> +#include <86box/mem.h> +#include <86box/smram.h> +#include <86box/pci.h> +#include <86box/port_92.h> +#include <86box/chipset.h> + + +/* + IMS 884x Configuration Registers + + Note: IMS 884x are rebadged ATMEL AT 40411/40412 chipsets + + By: Tiseno100, Miran Grca(OBattler) + + Register 00h: + Bit 3: F0000-FFFFF Shadow Enable + Bit 2: E0000-EFFFF Shadow Enable + Bit 0: ???? + + Register 04h: + Bit 3: Cache Write Hit Wait State + Bit 2: Cache Read Hit Wait State + + Register 06h: + Bit 3: System BIOS Cacheable (1: Yes / 0: No) + Bit 1: Power Management Mode (1: IRQ / 0: SMI#) + + Register 08h: + Bit 2: System BIOS Shadow Write (1: Enable / 0: Disable) + Bit 1: System BIOS Shadow Read? + + Register 0Dh: + Bit 0: IO 100H-3FFH Idle Detect (1: Enable / 0: Disable) + + Register 0Eh: + Bit 7: DMA & Local Bus Idle Detect (1: Enable / 0: Disable) + Bit 6: Floppy Disk Idle Detect (1: Enable / 0: Disable) + Bit 5: IDE Idle Detect (1: Enable / 0: Disable) + Bit 4: Serial Port Idle Detect (1: Enable / 0: Disable) + Bit 3: Parallel Port Idle Detect (1: Enable / 0: Disable) + Bit 2: Keyboard Idle Detect (1: Enable / 0: Disable) + Bit 1: Video Idle Detect (1: Enable / 0: Disable) + + Register 12h: + Bits 3-2: Power Saving Timer (00 = 1 MIN, 01 = 3 MIN, 10 = 5 MIN, 11 = 8 MIN) + Bit 1: Base Memory (1: 512KB / 0: 640KB) + + Register 1Ah: + Bit 3: Cache Write Hit W/S For PCI (1: Enabled / 0: Disable) + Bit 2: Cache Read Hit W/S For PCI (1: Enabled / 0: Disable) + Bit 1: VESA Clock Skew (1: 4ns/6ns, 0: No Delay/2ns) + + Register 1Bh: + Bit 6: Enable SMRAM (always at 30000-4FFFF) in SMM + Bit 5: ???? + Bit 4: Software SMI# + Bit 3: DC000-DFFFF Shadow Enable + Bit 2: D8000-DBFFF Shadow Enable + Bit 1: D4000-D7FFF Shadow Enable + Bit 0: D0000-D3FFF Shadow Enable + + Register 1Ch: + Bits 7-4: INTA IRQ routing (0 = disabled, 1 to F = IRQ) + Bit 3: CC000-CFFFF Shadow Enable + Bit 2: C8000-CBFFF Shadow Enable + Bit 1: C4000-C7FFF Shadow Enable + Bit 0: C0000-C3FFF Shadow Enable + + Register 1Dh: + Bits 7-4: INTB IRQ routing (0 = disabled, 1 to F = IRQ) + + Register 1Eh: + Bits 7-4: INTC IRQ routing (0 = disabled, 1 to F = IRQ) + Bit 1: C4000-C7FFF Cacheable + Bit 0: C0000-C3FFF Cacheable + + Register 21h: + Bits 7-4: INTD IRQ routing (0 = disabled, 1 to F = IRQ) + + Register 22h: + Bit 5: Local Bus Master #2 select (0 = VESA, 1 = PCI) + Bit 4: Local Bus Master #1 select (0 = VESA, 1 = PCI) + Bits 1-0: Internal HADS# Delay Always (00 = No Delay, 01 = 1 Clk, 10 = 2 Clks) + + Register 23h: + Bit 7: Seven Bits Tag (1: Enabled / 0: Disable) + Bit 3: Extend LBRDY#(VL Master) (1: Enabled / 0: Disable) + Bit 2: Sync LRDY#(VL Slave) (1: Enabled / 0: Disable) + Bit 0: HADS# Delay After LB. Cycle (1: Enabled / 0: Disable) +*/ + +typedef struct +{ + uint8_t idx, access_data, + regs[256], pci_conf[256]; + + smram_t *smram; +} ims8848_t; + + +#ifdef ENABLE_IMS8848_LOG +int ims8848_do_log = ENABLE_IMS8848_LOG; + + +static void +ims8848_log(const char *fmt, ...) +{ + va_list ap; + + if (ims8848_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define ims8848_log(fmt, ...) +#endif + + +/* Shadow write always enabled, 1B and 1C control C000-DFFF read. */ +static void +ims8848_recalc(ims8848_t *dev) +{ + int i, state_on; + uint32_t base; + ims8848_log("SHADOW: 00 = %02X, 08 = %02X, 1B = %02X, 1C = %02X\n", + dev->regs[0x00], dev->regs[0x08], dev->regs[0x1b], dev->regs[0x1c]); + + state_on = MEM_READ_INTERNAL; + state_on |= (dev->regs[0x08] & 0x04) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + + for (i = 0; i < 2; i++) { + base = 0xe0000 + (i << 16); + if (dev->regs[0x00] & (1 << (i + 2))) + mem_set_mem_state_both(base, 0x10000, state_on); + else + mem_set_mem_state_both(base, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + } + + for (i = 0; i < 4; i++) { + base = 0xc0000 + (i << 14); + if (dev->regs[0x1c] & (1 << i)) + mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + else + mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + + base = 0xd0000 + (i << 14); + if (dev->regs[0x1b] & (1 << i)) + mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + else + mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + } + + flushmmucache_nopc(); +} + + +static void +ims8848_base_memory(ims8848_t *dev) +{ + /* We can use the proper mem_set_access to handle that. */ + mem_set_mem_state_both(0x80000, 0x20000, (dev->regs[0x12] & 2) ? + (MEM_READ_DISABLED | MEM_WRITE_DISABLED) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL)); +} + + +static void +ims8848_smram(ims8848_t *dev) +{ + smram_disable_all(); + + smram_enable(dev->smram, 0x00030000, 0x00030000, 0x20000, dev->regs[0x1b] & 0x40, 1); +} + + +static void +ims8848_write(uint16_t addr, uint8_t val, void *priv) +{ + ims8848_t *dev = (ims8848_t *) priv; + uint8_t old = dev->regs[dev->idx]; + + switch (addr) { + case 0x22: + ims8848_log("[W] IDX = %02X\n", val); + dev->idx = val; + break; + case 0x23: + ims8848_log("[W] IDX IN = %02X\n", val); + if (((val & 0x0f) == ((dev->idx >> 4) & 0x0f)) && ((val & 0xf0) == ((dev->idx << 4) & 0xf0))) + dev->access_data = 1; + break; + case 0x24: + ims8848_log("[W] [%i] REG %02X = %02X\n", dev->access_data, dev->idx, val); + if (dev->access_data) { + dev->regs[dev->idx] = val; + switch (dev->idx) { + case 0x00: case 0x08: case 0x1b: case 0x1c: + /* Shadow RAM */ + ims8848_recalc(dev); + if (dev->idx == 0x1b) { + ims8848_smram(dev); + if (!(old & 0x10) && (val & 0x10)) + smi_line = 1; + } else if (dev->idx == 0x1c) + pci_set_irq_routing(PCI_INTA, (val >> 4) ? (val >> 4) : PCI_IRQ_DISABLED); + break; + + case 0x1d: case 0x1e: + pci_set_irq_routing(PCI_INTB + (dev->idx - 0x1d), (val >> 4) ? (val >> 4) : PCI_IRQ_DISABLED); + break; + case 0x21: + pci_set_irq_routing(PCI_INTD, (val >> 4) ? (val >> 4) : PCI_IRQ_DISABLED); + break; + + case 0x12: + /* Base Memory */ + ims8848_base_memory(dev); + break; + } + dev->access_data = 0; + } + break; + } +} + + +static uint8_t +ims8848_read(uint16_t addr, void *priv) +{ + uint8_t ret = 0xff; + ims8848_t *dev = (ims8848_t *) priv; +#ifdef ENABLE_IMS8848_LOG + uint8_t old_ad = dev->access_data; +#endif + + switch (addr) { + case 0x22: + ims8848_log("[R] IDX = %02X\n", ret); + ret = dev->idx; + break; + case 0x23: + ims8848_log("[R] IDX IN = %02X\n", ret); + ret = (dev->idx >> 4) | (dev->idx << 4); + break; + case 0x24: + if (dev->access_data) { + ret = dev->regs[dev->idx]; + dev->access_data = 0; + } + ims8848_log("[R] [%i] REG %02X = %02X\n", old_ad, dev->idx, ret); + break; + } + + return ret; +} + + +static void +ims8849_pci_write(int func, int addr, uint8_t val, void *priv) +{ + ims8848_t *dev = (ims8848_t *)priv; + + ims8848_log("IMS 884x-PCI: dev->regs[%02x] = %02x POST: %02x\n", addr, val, inb(0x80)); + + if (func == 0) switch (addr) { + case 0x04: + dev->pci_conf[addr] = val; + break; + + case 0x05: + dev->pci_conf[addr] = val & 3; + break; + + case 0x07: + dev->pci_conf[addr] &= val & 0xf7; + break; + + case 0x0c ... 0x0d: + dev->pci_conf[addr] = val; + break; + + case 0x52 ... 0x55: + dev->pci_conf[addr] = val; + break; + } +} + + +static uint8_t +ims8849_pci_read(int func, int addr, void *priv) +{ + ims8848_t *dev = (ims8848_t *)priv; + uint8_t ret = 0xff; + + if (func == 0) + ret = dev->pci_conf[addr]; + + return ret; +} + + +static void +ims8848_reset(void *priv) +{ + ims8848_t *dev = (ims8848_t *)priv; + + memset(dev->regs, 0x00, sizeof(dev->regs)); + memset(dev->pci_conf, 0x00, sizeof(dev->pci_conf)); + + dev->pci_conf[0x00] = 0xe0; /* Integrated Micro Solutions (IMS) */ + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x49; /* 8849 */ + dev->pci_conf[0x03] = 0x88; + + dev->pci_conf[0x04] = 0x07; + dev->pci_conf[0x07] = 0x02; + + dev->pci_conf[0x0b] = 0x06; + + ims8848_recalc(dev); /* Shadow RAM Setup */ + ims8848_base_memory(dev); /* Base Memory Setup */ + + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + + ims8848_smram(dev); +} + + +static void +ims8848_close(void *priv) +{ + ims8848_t *dev = (ims8848_t *) priv; + + smram_del(dev->smram); + + free(dev); +} + + +static void * +ims8848_init(const device_t *info) +{ + ims8848_t *dev = (ims8848_t *) malloc(sizeof(ims8848_t)); + memset(dev, 0, sizeof(ims8848_t)); + + device_add(&port_92_device); + + /* IMS 8848: + 22h Index + 23h Data Unlock + 24h Data + + IMS 8849: + PCI Device 0: IMS 8849 Dummy for compatibility reasons + */ + io_sethandler(0x0022, 0x0003, ims8848_read, NULL, NULL, ims8848_write, NULL, NULL, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, ims8849_pci_read, ims8849_pci_write, dev); + + dev->smram = smram_add(); + smram_set_separate_smram(1); + + cpu_cache_ext_enabled = 1; + cpu_update_waitstates(); + + ims8848_reset(dev); + + return dev; +} + + +const device_t ims8848_device = { + "IMS 8848/8849", + 0, + 0, + ims8848_init, ims8848_close, ims8848_reset, + { NULL }, NULL, NULL, + NULL +}; diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 83eabb5e8..065625377 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -55,6 +55,7 @@ typedef struct smram_locked, max_drb, drb_unit, drb_default; uint8_t regs[256], regs_locked[256]; + uint8_t mem_state[256]; int type; smram_t *smram_low, *smram_high; } i4x0_t; @@ -81,23 +82,18 @@ i4x0_log(const char *fmt, ...) static void -i4x0_map(uint32_t addr, uint32_t size, int state) +i4x0_map(i4x0_t *dev, uint32_t addr, uint32_t size, int state) { - switch (state & 3) { - case 0: - mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - break; - case 1: - mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); - break; - case 2: - mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); - break; - case 3: - mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; + uint32_t base = addr >> 12; + int states[4] = { MEM_READ_EXTANY | MEM_WRITE_EXTANY, MEM_READ_INTERNAL | MEM_WRITE_EXTANY, + MEM_READ_EXTANY | MEM_WRITE_INTERNAL, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL }; + + state &= 3; + if (dev->mem_state[base] != state) { + mem_set_mem_state_both(addr, size, states[state]); + dev->mem_state[base] = state; + flushmmucache_nopc(); } - flushmmucache_nopc(); } @@ -584,10 +580,10 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0x59: /* PAM0 */ if (dev->type <= INTEL_430NX) { if ((regs[0x59] ^ val) & 0x0f) - i4x0_map(0x80000, 0x20000, val & 0x0f); + i4x0_map(dev, 0x80000, 0x20000, val & 0x0f); } if ((regs[0x59] ^ val) & 0xf0) { - i4x0_map(0xf0000, 0x10000, val >> 4); + i4x0_map(dev, 0xf0000, 0x10000, val >> 4); shadowbios = (val & 0x10); } if (dev->type > INTEL_430NX) @@ -597,44 +593,44 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0x5a: /* PAM1 */ if ((regs[0x5a] ^ val) & 0x0f) - i4x0_map(0xc0000, 0x04000, val & 0xf); + i4x0_map(dev, 0xc0000, 0x04000, val & 0xf); if ((regs[0x5a] ^ val) & 0xf0) - i4x0_map(0xc4000, 0x04000, val >> 4); + i4x0_map(dev, 0xc4000, 0x04000, val >> 4); regs[0x5a] = val & 0x77; break; case 0x5b: /*PAM2 */ if ((regs[0x5b] ^ val) & 0x0f) - i4x0_map(0xc8000, 0x04000, val & 0xf); + i4x0_map(dev, 0xc8000, 0x04000, val & 0xf); if ((regs[0x5b] ^ val) & 0xf0) - i4x0_map(0xcc000, 0x04000, val >> 4); + i4x0_map(dev, 0xcc000, 0x04000, val >> 4); regs[0x5b] = val & 0x77; break; case 0x5c: /*PAM3 */ if ((regs[0x5c] ^ val) & 0x0f) - i4x0_map(0xd0000, 0x04000, val & 0xf); + i4x0_map(dev, 0xd0000, 0x04000, val & 0xf); if ((regs[0x5c] ^ val) & 0xf0) - i4x0_map(0xd4000, 0x04000, val >> 4); + i4x0_map(dev, 0xd4000, 0x04000, val >> 4); regs[0x5c] = val & 0x77; break; case 0x5d: /* PAM4 */ if ((regs[0x5d] ^ val) & 0x0f) - i4x0_map(0xd8000, 0x04000, val & 0xf); + i4x0_map(dev, 0xd8000, 0x04000, val & 0xf); if ((regs[0x5d] ^ val) & 0xf0) - i4x0_map(0xdc000, 0x04000, val >> 4); + i4x0_map(dev, 0xdc000, 0x04000, val >> 4); regs[0x5d] = val & 0x77; break; case 0x5e: /* PAM5 */ if ((regs[0x5e] ^ val) & 0x0f) - i4x0_map(0xe0000, 0x04000, val & 0xf); + i4x0_map(dev, 0xe0000, 0x04000, val & 0xf); if ((regs[0x5e] ^ val) & 0xf0) - i4x0_map(0xe4000, 0x04000, val >> 4); + i4x0_map(dev, 0xe4000, 0x04000, val >> 4); regs[0x5e] = val & 0x77; break; case 0x5f: /* PAM6 */ if ((regs[0x5f] ^ val) & 0x0f) - i4x0_map(0xe8000, 0x04000, val & 0xf); + i4x0_map(dev, 0xe8000, 0x04000, val & 0xf); if ((regs[0x5f] ^ val) & 0xf0) - i4x0_map(0xec000, 0x04000, val >> 4); + i4x0_map(dev, 0xec000, 0x04000, val >> 4); regs[0x5f] = val & 0x77; break; case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: @@ -1303,11 +1299,11 @@ static void regs[0x0d] = 0x20; /* According to information from FreeBSD 3.x source code: 0x00 = 486DX, 0x20 = 486SX, 0x40 = 486DX2 or 486DX4, 0x80 = Pentium OverDrive. */ - if (!(hasfpu) && (cpu_multi = 1)) + if (!(hasfpu) && (cpu_multi == 1)) regs[0x50] = 0x20; - else if (!(hasfpu) && (cpu_multi = 2)) + else if (!(hasfpu) && (cpu_multi == 2)) regs[0x50] = 0x60; /* Guess based on the SX, DX, and DX2 values. */ - else if (hasfpu && (cpu_multi = 1)) + else if (hasfpu && (cpu_multi == 1)) regs[0x50] = 0x00; else if (hasfpu && (cpu_multi >= 2) && !(cpu_s->cpu_type == CPU_P24T)) regs[0x50] = 0x40; diff --git a/src/chipset/intel_i450kx.c b/src/chipset/intel_i450kx.c index 5a89f2659..2696db495 100644 --- a/src/chipset/intel_i450kx.c +++ b/src/chipset/intel_i450kx.c @@ -58,71 +58,95 @@ i450kx_log(const char *fmt, ...) #endif -/* Shadow RAM Flags */ -#define LSB_DECISION (((shadow_value & 1) ? MEM_READ_EXTANY : MEM_READ_INTERNAL) | ((shadow_value & 2) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL)) -#define MSB_DECISION (((shadow_value & 0x10) ? MEM_READ_EXTANY : MEM_READ_INTERNAL) | ((shadow_value & 0x20) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL)) -#define LSB_DECISION_MC (((shadow_value & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((shadow_value & 2) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)) -#define MSB_DECISION_MC (((shadow_value & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((shadow_value & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)) - -/* SMRAM */ -#define SMRAM_ADDR (((dev->pb_pci_conf[0xb9] << 8) | dev->pb_pci_conf[0xb8]) << 17) -#define SMRAM_ADDR_MC (((dev->mc_pci_conf[0xb9] << 8) | dev->mc_pci_conf[0xb8]) << 16) -#define SMRAM_SIZE (((dev->pb_pci_conf[0xbb] >> 4) + 1) * 64) -#define SMRAM_SIZE_MC (((dev->mc_pci_conf[0xbb] >> 4) + 1) * 64) - -/* Miscellaneous */ -#define ENABLE_SEGMENT (MEM_READ_EXTANY | MEM_WRITE_EXTANY) -#define DISABLE_SEGMENT (MEM_READ_DISABLED | MEM_WRITE_DISABLED) - - +/* TODO: Finish the bus index stuff. */ typedef struct i450kx_t { - smram_t *smram; + smram_t * smram[2]; - uint8_t pb_pci_conf[256], mc_pci_conf[256]; + uint8_t pb_pci_conf[256], mc_pci_conf[256]; + uint8_t mem_state[2][256]; + + uint8_t bus_index; } i450kx_t; static void -i450kx_shadow(int is_mc, int cur_reg, uint8_t shadow_value, i450kx_t *dev) +i450kx_map(i450kx_t *dev, int bus, uint32_t addr, uint32_t size, int state) { - if (cur_reg == 0x59) { - mem_set_mem_state_both(0x80000, 0x20000, (is_mc) ? LSB_DECISION_MC : LSB_DECISION); - mem_set_mem_state_both(0xf0000, 0x10000, (is_mc) ? MSB_DECISION_MC : MSB_DECISION); - } else { - mem_set_mem_state_both(0xc0000 + (((cur_reg & 7) - 2) * 0x8000), 0x4000, (is_mc) ? LSB_DECISION_MC : LSB_DECISION); - mem_set_mem_state_both(0xc4000 + (((cur_reg & 7) - 2) * 0x8000), 0x4000, (is_mc) ? MSB_DECISION_MC : MSB_DECISION); + uint32_t base = addr >> 12; + int states[4] = { MEM_READ_EXTANY | MEM_WRITE_EXTANY, MEM_READ_INTERNAL | MEM_WRITE_EXTANY, + MEM_READ_EXTANY | MEM_WRITE_INTERNAL, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL }; + + state &= 3; + if (dev->mem_state[bus][base] != state) { + if (bus) + mem_set_mem_state_bus_both(addr, size, states[state]); + else + mem_set_mem_state_cpu_both(addr, size, states[state]); + dev->mem_state[bus][base] = state; + flushmmucache_nopc(); } - flushmmucache_nopc(); } static void -i450kx_smm(uint32_t smram_addr, uint32_t smram_size, i450kx_t *dev) +i450kx_smram_recalc(i450kx_t *dev, int bus) { - smram_disable_all(); + uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf; + uint32_t addr, size; - if ((smram_addr != 0) && !!(dev->mc_pci_conf[0x57] & 8)) - smram_enable(dev->smram, smram_addr, smram_addr, smram_size, !!(dev->pb_pci_conf[0x57] & 8), 1); + smram_disable(dev->smram[bus]); + + addr = ((uint32_t) regs[0xb8] << 16) | ((uint32_t) regs[0xb9] << 24); + size = (((uint32_t) ((regs[0xbb] >> 4) & 0x0f)) << 16) + 0x00010000; + + if ((addr != 0x00000000) && !!(regs[0x57] & 0x08)) { + if (bus) + smram_enable_ex(dev->smram[bus], addr, addr, size, 0, !!(regs[0x57] & 8), 0, 1); + else + smram_enable_ex(dev->smram[bus], addr, addr, size, !!(regs[0x57] & 8), 0, 1, 0); + } flushmmucache(); } +static void +i450kx_vid_buf_recalc(i450kx_t *dev, int bus) +{ + uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf; + + // int state = (regs[0x58] & 0x02) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_DISABLED | MEM_WRITE_DISABLED); + int state = (regs[0x58] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + if (bus) + mem_set_mem_state_bus_both(0x000a0000, 0x00020000, state); + else + mem_set_mem_state_cpu_both(0x000a0000, 0x00020000, state); + + flushmmucache_nopc(); +} + + static void pb_write(int func, int addr, uint8_t val, void *priv) { i450kx_t *dev = (i450kx_t *)priv; - switch (addr) { - case 0x04: - dev->pb_pci_conf[addr] &= val & 0xd7; - break; + // pclog("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); + i450kx_log("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); - case 0x06: - dev->pb_pci_conf[addr] = val & 0x80; + if (func == 0) switch (addr) { + case 0x04: + dev->pb_pci_conf[addr] = (dev->pb_pci_conf[addr] & 0x04) | (val & 0x53); + break; + case 0x05: + dev->pb_pci_conf[addr] = val & 0x01; break; case 0x07: + dev->pb_pci_conf[addr] &= ~(val & 0xf9); + break; + case 0x0d: dev->pb_pci_conf[addr] = val; break; @@ -131,63 +155,106 @@ pb_write(int func, int addr, uint8_t val, void *priv) dev->pb_pci_conf[addr] = val & 0xcf; break; - case 0x40: - case 0x41: + case 0x40: case 0x41: dev->pb_pci_conf[addr] = val; break; - case 0x43: dev->pb_pci_conf[addr] = val & 0x80; break; case 0x48: - dev->pb_pci_conf[addr] = val & 6; + dev->pb_pci_conf[addr] = val & 0x06; break; - case 0x4a: - case 0x4b: + case 0x4a: case 0x4b: dev->pb_pci_conf[addr] = val; + // if (addr == 0x4a) + // pci_remap_bus(dev->bus_index, val); break; case 0x4c: - dev->pb_pci_conf[addr] = val & 0xd8; + dev->pb_pci_conf[addr] = (dev->pb_pci_conf[addr] & 0x01) | (val & 0xd8); + break; + + case 0x51: + dev->pb_pci_conf[addr] = val; break; case 0x53: - dev->pb_pci_conf[addr] = val & 2; + dev->pb_pci_conf[addr] = val & 0x02; break; case 0x54: dev->pb_pci_conf[addr] = val & 0x7b; break; - case 0x55: - dev->pb_pci_conf[addr] = val & 2; + dev->pb_pci_conf[addr] = val & 0x03; break; case 0x57: - dev->pb_pci_conf[addr] = val & 8; - i450kx_smm(SMRAM_ADDR, SMRAM_SIZE, dev); + dev->pb_pci_conf[addr] = val & 0x08; + i450kx_smram_recalc(dev, 1); break; case 0x58: - dev->pb_pci_conf[addr] = val & 2; - mem_set_mem_state_both(0xa0000, 0x20000, (val & 2) ? ENABLE_SEGMENT : DISABLE_SEGMENT); + dev->pb_pci_conf[addr] = val & 0x02; + i450kx_vid_buf_recalc(dev, 1); break; - case 0x59: - case 0x5a: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x5e: - case 0x5f: - dev->pb_pci_conf[addr] = val & 0x33; - i450kx_shadow(0, addr, val, dev); + case 0x59: /* PAM0 */ + if ((dev->pb_pci_conf[0x59] ^ val) & 0x0f) + i450kx_map(dev, 1, 0x80000, 0x20000, val & 0x0f); + if ((dev->pb_pci_conf[0x59] ^ val) & 0xf0) { + i450kx_map(dev, 1, 0xf0000, 0x10000, val >> 4); + shadowbios = (val & 0x10); + } + dev->pb_pci_conf[0x59] = val & 0x33; + break; + case 0x5a: /* PAM1 */ + if ((dev->pb_pci_conf[0x5a] ^ val) & 0x0f) + i450kx_map(dev, 1, 0xc0000, 0x04000, val & 0xf); + if ((dev->pb_pci_conf[0x5a] ^ val) & 0xf0) + i450kx_map(dev, 1, 0xc4000, 0x04000, val >> 4); + dev->pb_pci_conf[0x5a] = val & 0x33; + break; + case 0x5b: /*PAM2 */ + if ((dev->pb_pci_conf[0x5b] ^ val) & 0x0f) + i450kx_map(dev, 1, 0xc8000, 0x04000, val & 0xf); + if ((dev->pb_pci_conf[0x5b] ^ val) & 0xf0) + i450kx_map(dev, 1, 0xcc000, 0x04000, val >> 4); + dev->pb_pci_conf[0x5b] = val & 0x33; + break; + case 0x5c: /*PAM3 */ + if ((dev->pb_pci_conf[0x5c] ^ val) & 0x0f) + i450kx_map(dev, 1, 0xd0000, 0x04000, val & 0xf); + if ((dev->pb_pci_conf[0x5c] ^ val) & 0xf0) + i450kx_map(dev, 1, 0xd4000, 0x04000, val >> 4); + dev->pb_pci_conf[0x5c] = val & 0x33; + break; + case 0x5d: /* PAM4 */ + if ((dev->pb_pci_conf[0x5d] ^ val) & 0x0f) + i450kx_map(dev, 1, 0xd8000, 0x04000, val & 0xf); + if ((dev->pb_pci_conf[0x5d] ^ val) & 0xf0) + i450kx_map(dev, 1, 0xdc000, 0x04000, val >> 4); + dev->pb_pci_conf[0x5d] = val & 0x33; + break; + case 0x5e: /* PAM5 */ + if ((dev->pb_pci_conf[0x5e] ^ val) & 0x0f) + i450kx_map(dev, 1, 0xe0000, 0x04000, val & 0xf); + if ((dev->pb_pci_conf[0x5e] ^ val) & 0xf0) + i450kx_map(dev, 1, 0xe4000, 0x04000, val >> 4); + dev->pb_pci_conf[0x5e] = val & 0x33; + break; + case 0x5f: /* PAM6 */ + if ((dev->pb_pci_conf[0x5f] ^ val) & 0x0f) + i450kx_map(dev, 1, 0xe8000, 0x04000, val & 0xf); + if ((dev->pb_pci_conf[0x5f] ^ val) & 0xf0) + i450kx_map(dev, 1, 0xec000, 0x04000, val >> 4); + dev->pb_pci_conf[0x5f] = val & 0x33; break; case 0x70: - dev->pb_pci_conf[addr] = val & 0xfc; + dev->pb_pci_conf[addr] = val & 0xf8; break; case 0x71: @@ -197,47 +264,49 @@ pb_write(int func, int addr, uint8_t val, void *priv) case 0x78: dev->pb_pci_conf[addr] = val & 0xf0; break; - case 0x79: dev->pb_pci_conf[addr] = val & 0xfc; break; - - case 0x7c: - dev->pb_pci_conf[addr] = val & 0x5f; + case 0x7a: + dev->pb_pci_conf[addr] = val; + break; + case 0x7b: + dev->pb_pci_conf[addr] = val & 0x0f; break; + case 0x7c: + dev->pb_pci_conf[addr] = val & 0x9f; + break; case 0x7d: dev->pb_pci_conf[addr] = val & 0x1a; break; - case 0x7e: dev->pb_pci_conf[addr] = val & 0xf0; break; - case 0x7f: - case 0x88: - case 0x89: - case 0x8a: dev->pb_pci_conf[addr] = val; break; + case 0x88: case 0x89: + dev->pb_pci_conf[addr] = val; + break; case 0x8b: dev->pb_pci_conf[addr] = val & 0x80; break; - - case 0x9c: - dev->pb_pci_conf[addr] = val & 1; - break; - - case 0xa4: - dev->pb_pci_conf[addr] = val & 0xf9; - break; - - case 0xa5: - case 0xa6: + case 0x8c: case 0x8d: dev->pb_pci_conf[addr] = val; break; + case 0x9c: + dev->pb_pci_conf[addr] = val & 0x01; + break; + + case 0xa4: + dev->pb_pci_conf[addr] = val & 0xf8; + break; + case 0xa5: case 0xa6: + dev->pb_pci_conf[addr] = val; + break; case 0xa7: dev->pb_pci_conf[addr] = val & 0x0f; break; @@ -245,36 +314,45 @@ pb_write(int func, int addr, uint8_t val, void *priv) case 0xb0: dev->pb_pci_conf[addr] = val & 0xe0; break; - case 0xb1: - dev->pb_pci_conf[addr] = val & 0x1f; + dev->pb_pci_conf[addr] = val & /*0x1a*/ 0x1f; break; case 0xb4: - dev->pb_pci_conf[addr] = val & 0xe8; + dev->pb_pci_conf[addr] = val & 0xe0; break; - case 0xb5: dev->pb_pci_conf[addr] = val & 0x1f; break; - case 0xb8: - case 0xb9: + case 0xb8: case 0xb9: + dev->pb_pci_conf[addr] = val; + i450kx_smram_recalc(dev, 1); + break; case 0xbb: - dev->pb_pci_conf[addr] = !(addr == 0xbb) ? val : (val & 0xf0); - i450kx_smm(SMRAM_ADDR, SMRAM_SIZE, dev); + dev->pb_pci_conf[addr] = val & 0xf0; + i450kx_smram_recalc(dev, 1); + break; + + case 0xbc: + dev->pb_pci_conf[addr] = val & 0x11; + break; + + case 0xc0: + dev->pb_pci_conf[addr] = val & 0xdf; + break; + case 0xc1: + dev->pb_pci_conf[addr] = val & 0x3f; break; case 0xc4: - dev->pb_pci_conf[addr] = val & 5; + dev->pb_pci_conf[addr] &= ~(val & 0x0f); break; - case 0xc5: - dev->pb_pci_conf[addr] = val & 0x0a; + dev->pb_pci_conf[addr] &= ~(val & 0x0a); break; - case 0xc6: - dev->pb_pci_conf[addr] = val & 0x1d; + dev->pb_pci_conf[addr] &= ~(val & 0x1f); break; case 0xc8: @@ -286,7 +364,6 @@ pb_write(int func, int addr, uint8_t val, void *priv) dev->pb_pci_conf[addr] = val; break; } - i450kx_log("i450KX-PB: dev->regs[%02x] = %02x POST: %02x\n", addr, dev->pb_pci_conf[addr], inb(0x80)); } @@ -294,7 +371,30 @@ static uint8_t pb_read(int func, int addr, void *priv) { i450kx_t *dev = (i450kx_t *)priv; - return dev->pb_pci_conf[addr]; + uint8_t ret = 0xff; + + if (func == 0) + ret = dev->pb_pci_conf[addr]; + + // pclog("i450KX-PB: [R] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80)); + + return ret; +} + + +/* A way to use spd_write_drbs_interlaved() and convert the output to what we need. */ +static void +mc_fill_drbs(i450kx_t *dev) +{ + int i; + + spd_write_drbs_interleaved(dev->mc_pci_conf, 0x60, 0x6f, 4); + for (i = 0x60; i <= 0x6f; i++) { + if (i & 0x01) + dev->mc_pci_conf[i] = 0x00; + else + dev->mc_pci_conf[i] &= 0x7f; + } } @@ -303,75 +403,97 @@ mc_write(int func, int addr, uint8_t val, void *priv) { i450kx_t *dev = (i450kx_t *)priv; - switch (addr) - { + // pclog("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); + i450kx_log("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80)); + + if (func == 0) switch (addr) { case 0x4c: dev->mc_pci_conf[addr] = val & 0xdf; break; - case 0x4d: - dev->mc_pci_conf[addr] = val & 0xdf; + dev->mc_pci_conf[addr] = val & 0xff; break; case 0x57: - dev->mc_pci_conf[addr] = val & 8; - i450kx_smm(SMRAM_ADDR, SMRAM_SIZE, dev); + dev->mc_pci_conf[addr] = val & 0x08; + i450kx_smram_recalc(dev, 0); break; case 0x58: - dev->mc_pci_conf[addr] = val & 2; + dev->mc_pci_conf[addr] = val & 0x02; + i450kx_vid_buf_recalc(dev, 0); break; - case 0x59: - case 0x5a: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x5e: - case 0x5f: - dev->mc_pci_conf[addr] = val & 0x33; - i450kx_shadow(1, addr, val, dev); + case 0x59: /* PAM0 */ + if ((dev->mc_pci_conf[0x59] ^ val) & 0x0f) + i450kx_map(dev, 0, 0x80000, 0x20000, val & 0x0f); + if ((dev->mc_pci_conf[0x59] ^ val) & 0xf0) { + i450kx_map(dev, 0, 0xf0000, 0x10000, val >> 4); + shadowbios = (val & 0x10); + } + dev->mc_pci_conf[0x59] = val & 0x33; + break; + case 0x5a: /* PAM1 */ + if ((dev->mc_pci_conf[0x5a] ^ val) & 0x0f) + i450kx_map(dev, 0, 0xc0000, 0x04000, val & 0xf); + if ((dev->mc_pci_conf[0x5a] ^ val) & 0xf0) + i450kx_map(dev, 0, 0xc4000, 0x04000, val >> 4); + dev->mc_pci_conf[0x5a] = val & 0x33; + break; + case 0x5b: /*PAM2 */ + if ((dev->mc_pci_conf[0x5b] ^ val) & 0x0f) + i450kx_map(dev, 0, 0xc8000, 0x04000, val & 0xf); + if ((dev->mc_pci_conf[0x5b] ^ val) & 0xf0) + i450kx_map(dev, 0, 0xcc000, 0x04000, val >> 4); + dev->mc_pci_conf[0x5b] = val & 0x33; + break; + case 0x5c: /*PAM3 */ + if ((dev->mc_pci_conf[0x5c] ^ val) & 0x0f) + i450kx_map(dev, 0, 0xd0000, 0x04000, val & 0xf); + if ((dev->mc_pci_conf[0x5c] ^ val) & 0xf0) + i450kx_map(dev, 0, 0xd4000, 0x04000, val >> 4); + dev->mc_pci_conf[0x5c] = val & 0x33; + break; + case 0x5d: /* PAM4 */ + if ((dev->mc_pci_conf[0x5d] ^ val) & 0x0f) + i450kx_map(dev, 0, 0xd8000, 0x04000, val & 0xf); + if ((dev->mc_pci_conf[0x5d] ^ val) & 0xf0) + i450kx_map(dev, 0, 0xdc000, 0x04000, val >> 4); + dev->mc_pci_conf[0x5d] = val & 0x33; + break; + case 0x5e: /* PAM5 */ + if ((dev->mc_pci_conf[0x5e] ^ val) & 0x0f) + i450kx_map(dev, 0, 0xe0000, 0x04000, val & 0xf); + if ((dev->mc_pci_conf[0x5e] ^ val) & 0xf0) + i450kx_map(dev, 0, 0xe4000, 0x04000, val >> 4); + dev->mc_pci_conf[0x5e] = val & 0x33; + break; + case 0x5f: /* PAM6 */ + if ((dev->mc_pci_conf[0x5f] ^ val) & 0x0f) + i450kx_map(dev, 0, 0xe8000, 0x04000, val & 0xf); + if ((dev->mc_pci_conf[0x5f] ^ val) & 0xf0) + i450kx_map(dev, 0, 0xec000, 0x04000, val >> 4); + dev->mc_pci_conf[0x5f] = val & 0x33; break; - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - case 0x68: - case 0x69: - case 0x6a: - case 0x6b: - case 0x6c: - case 0x6d: - case 0x6e: - case 0x6f: - dev->mc_pci_conf[addr] = ((addr & 0x0f) % 2) ? 0 : (val & 0x7f); - spd_write_drbs(dev->mc_pci_conf, 0x60, 0x6f, 4); + case 0x60 ... 0x6f: + dev->mc_pci_conf[addr] = ((addr & 0x0f) & 0x01) ? 0x00 : (val & 0x7f); + mc_fill_drbs(dev); break; - case 0x74: - case 0x75: - case 0x76: - case 0x77: + case 0x74 ... 0x77: dev->mc_pci_conf[addr] = val; break; case 0x78: dev->mc_pci_conf[addr] = val & 0xf0; break; - case 0x79: dev->mc_pci_conf[addr] = val & 0xfe; break; - case 0x7a: dev->mc_pci_conf[addr] = val; break; - case 0x7b: dev->mc_pci_conf[addr] = val & 0x0f; break; @@ -379,45 +501,36 @@ mc_write(int func, int addr, uint8_t val, void *priv) case 0x7c: dev->mc_pci_conf[addr] = val & 0x1f; break; - case 0x7d: dev->mc_pci_conf[addr] = val & 0x0c; break; - case 0x7e: dev->mc_pci_conf[addr] = val & 0xf0; break; - case 0x7f: dev->mc_pci_conf[addr] = val; break; - case 0x88: - case 0x89: + case 0x88: case 0x89: dev->mc_pci_conf[addr] = val; break; - case 0x8b: dev->mc_pci_conf[addr] = val & 0x80; break; - case 0x8c: - case 0x8d: + case 0x8c: case 0x8d: dev->mc_pci_conf[addr] = val; break; case 0xa4: - dev->mc_pci_conf[addr] = val & 1; + dev->mc_pci_conf[addr] = val & 0x01; break; - case 0xa5: dev->pb_pci_conf[addr] = val & 0xf0; break; - case 0xa6: dev->mc_pci_conf[addr] = val; break; - case 0xa7: dev->mc_pci_conf[addr] = val & 0x0f; break; @@ -425,49 +538,56 @@ mc_write(int func, int addr, uint8_t val, void *priv) case 0xa8: dev->mc_pci_conf[addr] = val & 0xfe; break; - - case 0xa9: - case 0xaa: - case 0xab: - case 0xac: - case 0xad: - case 0xae: + case 0xa9 ... 0xab: dev->mc_pci_conf[addr] = val; break; + case 0xac ... 0xae: + dev->mc_pci_conf[addr] = val; + break; case 0xaf: dev->mc_pci_conf[addr] = val & 0x7f; break; - case 0xb8: - case 0xb9: + case 0xb8: case 0xb9: + dev->mc_pci_conf[addr] = val; + i450kx_smram_recalc(dev, 0); + break; case 0xbb: - dev->mc_pci_conf[addr] = !(addr == 0xbb) ? val : (val & 0xf0); - - i450kx_smm(SMRAM_ADDR_MC, SMRAM_SIZE_MC, dev); + dev->mc_pci_conf[addr] = val & 0xf0; + i450kx_smram_recalc(dev, 0); break; case 0xbc: - dev->mc_pci_conf[addr] = val & 1; + dev->mc_pci_conf[addr] = val & 0x01; break; case 0xc0: - dev->mc_pci_conf[addr] = val & 7; + dev->mc_pci_conf[addr] = val & 0x07; break; case 0xc2: - dev->mc_pci_conf[addr] = val & 3; + dev->mc_pci_conf[addr] &= ~(val & 0x03); break; case 0xc4: - dev->mc_pci_conf[addr] = val & 0x3f; + dev->mc_pci_conf[addr] = val & 0xbf; + break; + case 0xc5: + dev->mc_pci_conf[addr] = val & 0x03; break; case 0xc6: - dev->mc_pci_conf[addr] = val & 0x19; + dev->mc_pci_conf[addr] &= ~(val & 0x19); + break; + + case 0xc8: + dev->mc_pci_conf[addr] = val & 0x1f; + break; + case 0xca: case 0xcb: + dev->mc_pci_conf[addr] = val; break; } - i450kx_log("i450KX-MC: dev->regs[%02x] = %02x POST: %02x\n", addr, dev->mc_pci_conf[addr], inb(0x80)); } @@ -475,7 +595,14 @@ static uint8_t mc_read(int func, int addr, void *priv) { i450kx_t *dev = (i450kx_t *)priv; - return dev->mc_pci_conf[addr]; + uint8_t ret = 0xff; + + if (func == 0) + ret = dev->mc_pci_conf[addr]; + + // pclog("i450KX-MC: [R] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80)); + + return ret; } @@ -483,57 +610,168 @@ static void i450kx_reset(void *priv) { i450kx_t *dev = (i450kx_t *)priv; + uint32_t i; - /* CONFLICTS WARNING! We do not program anything on reset due to that */ + // pclog("i450KX: i450kx_reset()\n"); /* Defaults PB */ dev->pb_pci_conf[0x00] = 0x86; dev->pb_pci_conf[0x01] = 0x80; dev->pb_pci_conf[0x02] = 0xc4; dev->pb_pci_conf[0x03] = 0x84; - dev->pb_pci_conf[0x05] = 4; + dev->pb_pci_conf[0x04] = 0x07; + dev->pb_pci_conf[0x05] = 0x00; dev->pb_pci_conf[0x06] = 0x40; - dev->pb_pci_conf[0x07] = 2; - dev->pb_pci_conf[0x08] = 2; - dev->pb_pci_conf[0x0b] = 6; - dev->pb_pci_conf[0x0c] = 8; + dev->pb_pci_conf[0x07] = 0x02; + dev->pb_pci_conf[0x08] = 0x02; + dev->pb_pci_conf[0x09] = 0x00; + dev->pb_pci_conf[0x0a] = 0x00; + dev->pb_pci_conf[0x0b] = 0x06; + dev->pb_pci_conf[0x0c] = 0x08; dev->pb_pci_conf[0x0d] = 0x20; - dev->pb_pci_conf[0x49] = 0x14; - dev->pb_pci_conf[0x4c] = 0x39; - dev->pb_pci_conf[0x58] = 2; - dev->pb_pci_conf[0x59] = 0x30; - dev->pb_pci_conf[0x5a] = 0x33; - dev->pb_pci_conf[0x5b] = 0x33; - dev->pb_pci_conf[0x5c] = 0x33; - dev->pb_pci_conf[0x5d] = 0x33; - dev->pb_pci_conf[0x5e] = 0x33; - dev->pb_pci_conf[0x5f] = 0x33; - dev->pb_pci_conf[0xa4] = 1; + dev->pb_pci_conf[0x0e] = 0x00; + dev->pb_pci_conf[0x0f] = 0x00; + dev->pb_pci_conf[0x40] = 0x00; + dev->pb_pci_conf[0x41] = 0x00; + dev->pb_pci_conf[0x42] = 0x00; + dev->pb_pci_conf[0x43] = 0x00; + dev->pb_pci_conf[0x48] = 0x06; + dev->pb_pci_conf[0x49] = 0x19; + dev->pb_pci_conf[0x4a] = 0x00; + dev->pb_pci_conf[0x4b] = 0x00; + dev->pb_pci_conf[0x4c] = 0x19; + dev->pb_pci_conf[0x51] = 0x80; + dev->pb_pci_conf[0x53] = 0x00; + dev->pb_pci_conf[0x54] = 0x00; + dev->pb_pci_conf[0x55] = 0x00; + dev->pb_pci_conf[0x57] = 0x00; + dev->pb_pci_conf[0x58] = 0x02; + dev->pb_pci_conf[0x70] = 0x00; + dev->pb_pci_conf[0x71] = 0x00; + dev->pb_pci_conf[0x78] = 0x00; + dev->pb_pci_conf[0x79] = 0x00; + dev->pb_pci_conf[0x7a] = 0x00; + dev->pb_pci_conf[0x7b] = 0x00; + dev->pb_pci_conf[0x7c] = 0x00; + dev->pb_pci_conf[0x7d] = 0x00; + dev->pb_pci_conf[0x7e] = 0x00; + dev->pb_pci_conf[0x7f] = 0x00; + dev->pb_pci_conf[0x88] = 0x00; + dev->pb_pci_conf[0x89] = 0x00; + dev->pb_pci_conf[0x8a] = 0x00; + dev->pb_pci_conf[0x8b] = 0x00; + dev->pb_pci_conf[0x8c] = 0x00; + dev->pb_pci_conf[0x8d] = 0x00; + dev->pb_pci_conf[0x8e] = 0x00; + dev->pb_pci_conf[0x8f] = 0x00; + dev->pb_pci_conf[0x9c] = 0x00; + dev->pb_pci_conf[0xa4] = 0x01; dev->pb_pci_conf[0xa5] = 0xc0; dev->pb_pci_conf[0xa6] = 0xfe; - dev->pb_pci_conf[0xc8] = 3; - dev->pb_pci_conf[0xb8] = 5; + dev->pb_pci_conf[0xa7] = 0x00; + /* Note: Do NOT reset these two registers on programmed (TRC) hard reset! */ + // dev->pb_pci_conf[0xb0] = 0x00; + // dev->pb_pci_conf[0xb1] = 0x00; + dev->pb_pci_conf[0xb4] = 0x00; + dev->pb_pci_conf[0xb5] = 0x00; + dev->pb_pci_conf[0xb8] = 0x05; + dev->pb_pci_conf[0xb9] = 0x00; + dev->pb_pci_conf[0xba] = 0x00; + dev->pb_pci_conf[0xbb] = 0x00; + dev->pb_pci_conf[0xbc] = 0x01; + dev->pb_pci_conf[0xc0] = 0x02; + dev->pb_pci_conf[0xc1] = 0x00; + dev->pb_pci_conf[0xc2] = 0x00; + dev->pb_pci_conf[0xc3] = 0x00; + dev->pb_pci_conf[0xc4] = 0x00; + dev->pb_pci_conf[0xc5] = 0x00; + dev->pb_pci_conf[0xc6] = 0x00; + dev->pb_pci_conf[0xc7] = 0x00; + dev->pb_pci_conf[0xc8] = 0x03; + dev->pb_pci_conf[0xc9] = 0x00; + dev->pb_pci_conf[0xca] = 0x00; + dev->pb_pci_conf[0xcb] = 0x00; + + // pci_remap_bus(dev->bus_index, 0x00); + i450kx_smram_recalc(dev, 1); + i450kx_vid_buf_recalc(dev, 1); + pb_write(0, 0x59, 0x30, dev); + for (i = 0x5a; i <= 0x5f; i++) + pb_write(0, i, 0x33, dev); /* Defaults MC */ dev->mc_pci_conf[0x00] = 0x86; dev->mc_pci_conf[0x01] = 0x80; dev->mc_pci_conf[0x02] = 0xc5; dev->mc_pci_conf[0x03] = 0x84; + dev->mc_pci_conf[0x04] = 0x00; + dev->mc_pci_conf[0x05] = 0x00; dev->mc_pci_conf[0x06] = 0x80; - dev->mc_pci_conf[0x08] = 4; - dev->mc_pci_conf[0x0b] = 5; + dev->mc_pci_conf[0x07] = 0x00; + dev->mc_pci_conf[0x08] = 0x04; + dev->mc_pci_conf[0x09] = 0x00; + dev->mc_pci_conf[0x0a] = 0x00; + dev->mc_pci_conf[0x0b] = 0x05; dev->mc_pci_conf[0x49] = 0x14; dev->mc_pci_conf[0x4c] = 0x0b; + dev->mc_pci_conf[0x4d] = 0x08; + dev->mc_pci_conf[0x4e] = 0x00; + dev->mc_pci_conf[0x4f] = 0x00; + dev->mc_pci_conf[0x57] = 0x00; + dev->mc_pci_conf[0x58] = 0x00; + dev->mc_pci_conf[0x74] = 0x00; + dev->mc_pci_conf[0x75] = 0x00; + dev->mc_pci_conf[0x76] = 0x00; + dev->mc_pci_conf[0x77] = 0x00; dev->mc_pci_conf[0x78] = 0x10; - dev->mc_pci_conf[0xa4] = 1; + dev->mc_pci_conf[0x79] = 0x00; + dev->mc_pci_conf[0x7a] = 0x00; + dev->mc_pci_conf[0x7b] = 0x00; + dev->mc_pci_conf[0x7c] = 0x00; + dev->mc_pci_conf[0x7d] = 0x00; + dev->mc_pci_conf[0x7e] = 0x10; + dev->mc_pci_conf[0x7f] = 0x00; + dev->mc_pci_conf[0x88] = 0x00; + dev->mc_pci_conf[0x89] = 0x00; + dev->mc_pci_conf[0x8a] = 0x00; + dev->mc_pci_conf[0x8b] = 0x00; + dev->mc_pci_conf[0x8c] = 0x00; + dev->mc_pci_conf[0x8d] = 0x00; + dev->mc_pci_conf[0x8e] = 0x00; + dev->mc_pci_conf[0x8f] = 0x00; + dev->mc_pci_conf[0xa4] = 0x01; dev->mc_pci_conf[0xa5] = 0xc0; dev->mc_pci_conf[0xa6] = 0xfe; + dev->mc_pci_conf[0xa7] = 0x00; + dev->mc_pci_conf[0xa8] = 0x00; + dev->mc_pci_conf[0xa9] = 0x00; + dev->mc_pci_conf[0xaa] = 0x00; + dev->mc_pci_conf[0xab] = 0x00; dev->mc_pci_conf[0xac] = 0x16; dev->mc_pci_conf[0xad] = 0x35; dev->mc_pci_conf[0xae] = 0xdf; dev->mc_pci_conf[0xaf] = 0x30; dev->mc_pci_conf[0xb8] = 0x0a; - dev->mc_pci_conf[0xbc] = 1; + dev->mc_pci_conf[0xb9] = 0x00; + dev->mc_pci_conf[0xba] = 0x00; + dev->mc_pci_conf[0xbb] = 0x00; + dev->mc_pci_conf[0xbc] = 0x01; + dev->mc_pci_conf[0xc0] = 0x00; + dev->mc_pci_conf[0xc1] = 0x00; + dev->mc_pci_conf[0xc2] = 0x00; + dev->mc_pci_conf[0xc3] = 0x00; + dev->mc_pci_conf[0xc4] = 0x00; + dev->mc_pci_conf[0xc5] = 0x00; + dev->mc_pci_conf[0xc6] = 0x00; + dev->mc_pci_conf[0xc7] = 0x00; + + i450kx_smram_recalc(dev, 0); + i450kx_vid_buf_recalc(dev, 0); + mc_write(0, 0x59, 0x03, dev); + for (i = 0x5a; i <= 0x5f; i++) + mc_write(0, i, 0x00, dev); + for (i = 0x60; i <= 0x6f; i++) + dev->mc_pci_conf[i] = 0x01; } @@ -542,7 +780,8 @@ i450kx_close(void *priv) { i450kx_t *dev = (i450kx_t *)priv; - smram_del(dev->smram); + smram_del(dev->smram[1]); + smram_del(dev->smram[0]); free(dev); } @@ -552,10 +791,11 @@ i450kx_init(const device_t *info) { i450kx_t *dev = (i450kx_t *)malloc(sizeof(i450kx_t)); memset(dev, 0, sizeof(i450kx_t)); - pci_add_card(PCI_ADD_NORTHBRIDGE, pb_read, pb_write, dev); /* Device 19: Intel 450KX PCI Bridge PB */ - pci_add_card(PCI_ADD_NORTHBRIDGE, mc_read, mc_write, dev); /* Device 14: Intel 450KX Memory Controller MC */ + pci_add_card(PCI_ADD_NORTHBRIDGE, pb_read, pb_write, dev); /* Device 19h: Intel 450KX PCI Bridge PB */ + pci_add_card(PCI_ADD_AGPBRIDGE, mc_read, mc_write, dev); /* Device 14h: Intel 450KX Memory Controller MC */ - dev->smram = smram_add(); + dev->smram[0] = smram_add(); + dev->smram[1] = smram_add(); cpu_cache_int_enabled = 1; cpu_cache_ext_enabled = 1; diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 095dd5d36..1a278a2c3 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -47,7 +47,7 @@ #include <86box/hdc_ide_sff8038i.h> #include <86box/usb.h> #include <86box/machine.h> -#include <86box/smbus_piix4.h> +#include <86box/smbus.h> #include <86box/chipset.h> @@ -281,7 +281,7 @@ piix_trap_io(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) if (*(trap->en_reg) & trap->en_mask) { *(trap->sts_reg) |= trap->sts_mask; - acpi_raise_smi(trap->dev->acpi); + acpi_raise_smi(trap->dev->acpi, 1); } } @@ -690,6 +690,8 @@ piix_write(int func, int addr, uint8_t val, void *priv) case 0xab: if (dev->type == 3) fregs[addr] &= (val & 0x01); + else if (dev->type < 3) + fregs[addr] = val; break; case 0xb0: if (dev->type == 4) @@ -1406,6 +1408,17 @@ piix_reset(void *p) piix_write(3, 0x91, 0x00, p); piix_write(3, 0xd2, 0x00, p); } + + sff_set_irq_mode(dev->bm[0], 0, 0); + sff_set_irq_mode(dev->bm[1], 0, 0); + + if (dev->type >= 4) { + sff_set_irq_mode(dev->bm[0], 1, 0); + sff_set_irq_mode(dev->bm[1], 1, 0); + } else { + sff_set_irq_mode(dev->bm[0], 1, 2); + sff_set_irq_mode(dev->bm[1], 1, 2); + } } @@ -1461,6 +1474,17 @@ static void ide_board_set_force_ata3(1, 1); } + sff_set_irq_mode(dev->bm[0], 0, 0); + sff_set_irq_mode(dev->bm[1], 0, 0); + + if (dev->type >= 4) { + sff_set_irq_mode(dev->bm[0], 1, 0); + sff_set_irq_mode(dev->bm[1], 1, 0); + } else { + sff_set_irq_mode(dev->bm[0], 1, 2); + sff_set_irq_mode(dev->bm[1], 1, 2); + } + if (dev->type >= 3) dev->usb = device_add(&usb_device); diff --git a/src/chipset/opti391.c b/src/chipset/opti391.c new file mode 100644 index 000000000..f6b1f2686 --- /dev/null +++ b/src/chipset/opti391.c @@ -0,0 +1,226 @@ +/* + * 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 OPTi 82C391/392 chipset. + * + * Authors: Miran Grca, + * + * Copyright 2021 Miran Grca. + */ + +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/mem.h> +#include <86box/chipset.h> + + +#ifdef ENABLE_OPTI391_LOG +int opti391_do_log = ENABLE_OPTI391_LOG; + +static void +opti391_log(const char *fmt, ...) +{ + va_list ap; + + if (opti391_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define opti391_log(fmt, ...) +#endif + + +typedef struct +{ + uint32_t phys, virt; +} mem_remapping_t; + + +typedef struct +{ + uint8_t index, regs[256]; +} opti391_t; + + +static void +opti391_shadow_recalc(opti391_t *dev) +{ + uint32_t i, base; + uint8_t sh_enable, sh_master; + uint8_t sh_wp, sh_write_internal; + + shadowbios = shadowbios_write = 0; + + /* F0000-FFFFF */ + sh_enable = !(dev->regs[0x22] & 0x80); + if (sh_enable) + mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + else + mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); + + sh_write_internal = (dev->regs[0x26] & 0x40); + /* D0000-EFFFF */ + for (i = 0; i < 8; i++) { + base = 0xd0000 + (i << 14); + if (base >= 0xe0000) { + sh_master = (dev->regs[0x22] & 0x40); + sh_wp = (dev->regs[0x22] & 0x10); + } else { + sh_master = (dev->regs[0x22] & 0x20); + sh_wp = (dev->regs[0x22] & 0x08); + } + sh_enable = dev->regs[0x23] & (1 << i); + + if (sh_master) { + if (sh_enable) { + if (sh_wp) + mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); + else + mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } else if (sh_write_internal) + mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + else + mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + } else if (sh_write_internal) + mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + else + mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + } + + /* C0000-CFFFF */ + sh_master = !(dev->regs[0x26] & 0x10); + sh_wp = (dev->regs[0x26] & 0x20); + for (i = 0; i < 4; i++) { + base = 0xc0000 + (i << 14); + sh_enable = dev->regs[0x26] & (1 << i); + + if (sh_master) { + if (sh_enable) { + if (sh_wp) + mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); + else + mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } else if (sh_write_internal) + mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + else + mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + } else if (sh_write_internal) + mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + else + mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + } +} + + +static void +opti391_write(uint16_t addr, uint8_t val, void *priv) +{ + opti391_t *dev = (opti391_t *)priv; + + switch (addr) { + case 0x22: + dev->index = val; + break; + + case 0x24: + opti391_log("OPTi 391: dev->regs[%02x] = %02x\n", dev->index, val); + + switch (dev->index) { + case 0x20: + dev->regs[dev->index] = (dev->regs[dev->index] & 0xc0) | (val & 0x3f); + break; + + case 0x21: case 0x24: case 0x25: case 0x27: + case 0x28: case 0x29: case 0x2a: case 0x2b: + dev->regs[dev->index] = val; + break; + + case 0x22: case 0x23: + case 0x26: + dev->regs[dev->index] = val; + opti391_shadow_recalc(dev); + break; + } + break; + } +} + + +static uint8_t +opti391_read(uint16_t addr, void *priv) +{ + opti391_t *dev = (opti391_t *)priv; + uint8_t ret = 0xff; + + if (addr == 0x24) + ret = dev->regs[dev->index]; + + return ret; +} + + +static void +opti391_close(void *priv) +{ + opti391_t *dev = (opti391_t *)priv; + + free(dev); +} + + +static void * +opti391_init(const device_t *info) +{ + opti391_t *dev = (opti391_t *)malloc(sizeof(opti391_t)); + memset(dev, 0x00, sizeof(opti391_t)); + + io_sethandler(0x0022, 0x0001, opti391_read, NULL, NULL, opti391_write, NULL, NULL, dev); + io_sethandler(0x0024, 0x0001, opti391_read, NULL, NULL, opti391_write, NULL, NULL, dev); + + dev->regs[0x21] = 0x84; + dev->regs[0x24] = 0x07; + dev->regs[0x25] = 0xf0; + dev->regs[0x26] = 0x30; + dev->regs[0x27] = 0x91; + dev->regs[0x28] = 0x80; + dev->regs[0x29] = 0x10; + dev->regs[0x2a] = 0x80; + dev->regs[0x2b] = 0x10; + + opti391_shadow_recalc(dev); + + return dev; +} + + +const device_t opti391_device = { + "OPTi 82C391", + 0, + 0, + opti391_init, + opti391_close, + NULL, + { NULL }, + NULL, + NULL, + NULL +}; diff --git a/src/chipset/opti499.c b/src/chipset/opti499.c new file mode 100644 index 000000000..87bc39c8d --- /dev/null +++ b/src/chipset/opti499.c @@ -0,0 +1,264 @@ +/* + * 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 OPTi 82C493/82C499 chipset. + * + * + * + * Authors: Tiseno100, + * Miran Grca, + * + * Copyright 2008-2020 Tiseno100. + * Copyright 2016-2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/io.h> +#include <86box/device.h> +#include <86box/mem.h> +#include <86box/port_92.h> +#include <86box/chipset.h> + + +typedef struct +{ + uint8_t idx, + regs[256], scratch[2]; +} opti499_t; + + +#ifdef ENABLE_OPTI499_LOG +int opti499_do_log = ENABLE_OPTI499_LOG; + + +static void +opti499_log(const char *fmt, ...) +{ + va_list ap; + + if (opti499_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define opti499_log(fmt, ...) +#endif + + +static void +opti499_recalc(opti499_t *dev) +{ + uint32_t base; + uint32_t i, shflags = 0; + + shadowbios = 0; + shadowbios_write = 0; + + if (dev->regs[0x22] & 0x80) { + shadowbios = 1; + shadowbios_write = 0; + shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL; + } else { + shadowbios = 0; + shadowbios_write = 1; + shflags = MEM_READ_INTERNAL | MEM_WRITE_DISABLED; + } + + mem_set_mem_state_both(0xf0000, 0x10000, shflags); + + for (i = 0; i < 8; i++) { + base = 0xd0000 + (i << 14); + + if ((dev->regs[0x22] & ((base >= 0xe0000) ? 0x20 : 0x40)) && + (dev->regs[0x23] & (1 << i))) { + shflags = MEM_READ_INTERNAL; + shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; + } else { + if (dev->regs[0x2d] && (1 << ((i >> 1) + 2))) + shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY; + else + shflags = MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL; + } + + mem_set_mem_state_both(base, 0x4000, shflags); + } + + for (i = 0; i < 4; i++) { + base = 0xc0000 + (i << 14); + + if ((dev->regs[0x26] & 0x10) && (dev->regs[0x26] & (1 << i))) { + shflags = MEM_READ_INTERNAL; + shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; + } else { + if (dev->regs[0x26] & 0x40) { + if (dev->regs[0x2d] && (1 << (i >> 1))) + shflags = MEM_READ_EXTANY; + else + shflags = MEM_READ_EXTERNAL; + shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; + } else { + if (dev->regs[0x2d] && (1 << (i >> 1))) + shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY; + else + shflags = MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL; + } + } + + mem_set_mem_state_both(base, 0x4000, shflags); + } + + flushmmucache_nopc(); +} + + +static void +opti499_write(uint16_t addr, uint8_t val, void *priv) +{ + opti499_t *dev = (opti499_t *) priv; + + switch (addr) { + case 0x22: + opti499_log("[%04X:%08X] [W] dev->idx = %02X\n", CS, cpu_state.pc, val); + dev->idx = val; + break; + case 0x24: + if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) { + if (dev->idx == 0x20) + dev->regs[dev->idx] = (dev->regs[dev->idx] & 0xc0) | (val & 0x3f); + else + dev->regs[dev->idx] = val; + opti499_log("[%04X:%08X] [W] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, val); + + switch(dev->idx) { + case 0x20: + reset_on_hlt = !(val & 0x02); + break; + + case 0x21: + cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10); + cpu_update_waitstates(); + break; + + case 0x22: case 0x23: + case 0x26: case 0x2d: + opti499_recalc(dev); + break; + } + } + break; + + case 0xe1: case 0xe2: + dev->scratch[addr] = val; + break; + } +} + + +static uint8_t +opti499_read(uint16_t addr, void *priv) +{ + uint8_t ret = 0xff; + opti499_t *dev = (opti499_t *) priv; + + switch (addr) { + case 0x22: + opti499_log("[%04X:%08X] [R] dev->idx = %02X\n", CS, cpu_state.pc, ret); + break; + case 0x24: + if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) { + if (dev->idx == 0x2d) + ret = dev->regs[dev->idx] & 0xbf; + else + ret = dev->regs[dev->idx]; + opti499_log("[%04X:%08X] [R] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, ret); + } + break; + case 0xe1: + case 0xe2: + ret = dev->scratch[addr]; + break; + } + + return ret; +} + + +static void +opti499_reset(void *priv) +{ + opti499_t *dev = (opti499_t *) priv; + + memset(dev->regs, 0xff, sizeof(dev->regs)); + memset(&(dev->regs[0x20]), 0x00, 14 * sizeof(uint8_t)); + + dev->scratch[0] = dev->scratch[1] = 0xff; + + dev->regs[0x22] = 0x84; + dev->regs[0x24] = 0x87; + dev->regs[0x25] = 0xf0; + dev->regs[0x27] = 0xd1; + dev->regs[0x28] = dev->regs[0x2a] = 0x80; + dev->regs[0x29] = dev->regs[0x2b] = 0x10; + dev->regs[0x2d] = 0x40; + + reset_on_hlt = 1; + + cpu_cache_ext_enabled = 0; + cpu_update_waitstates(); + + opti499_recalc(dev); + + free(dev); +} + + +static void +opti499_close(void *priv) +{ + opti499_t *dev = (opti499_t *) priv; + + free(dev); +} + + +static void * +opti499_init(const device_t *info) +{ + opti499_t *dev = (opti499_t *) malloc(sizeof(opti499_t)); + memset(dev, 0, sizeof(opti499_t)); + + device_add(&port_92_device); + + io_sethandler(0x0022, 0x0001, opti499_read, NULL, NULL, opti499_write, NULL, NULL, dev); + io_sethandler(0x0024, 0x0001, opti499_read, NULL, NULL, opti499_write, NULL, NULL, dev); + + opti499_reset(dev); + + io_sethandler(0x00e1, 0x0002, opti499_read, NULL, NULL, opti499_write, NULL, NULL, dev); + + return dev; +} + + +const device_t opti499_device = { + "OPTi 82C499", + 0, + 1, + opti499_init, opti499_close, opti499_reset, + { NULL }, NULL, NULL, + NULL +}; diff --git a/src/chipset/opti895.c b/src/chipset/opti895.c index 49277d53d..289388391 100644 --- a/src/chipset/opti895.c +++ b/src/chipset/opti895.c @@ -43,6 +43,7 @@ typedef struct } opti895_t; +#define ENABLE_OPTI895_LOG 1 #ifdef ENABLE_OPTI895_LOG int opti895_do_log = ENABLE_OPTI895_LOG; @@ -91,11 +92,15 @@ opti895_recalc(opti895_t *dev) shflags = MEM_READ_INTERNAL; shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; } else { - if (dev->regs[0x26] & 0x40) { - shflags = MEM_READ_EXTANY; + shflags = (dev->regs[0x2d] & (1 << ((i >> 1) + 2))) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL; + if (dev->regs[0x26] & 0x40) shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; - } else - shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY; + else { + if (dev->regs[0x26] & 0x80) + shflags |= (dev->regs[0x2d] & (1 << ((i >> 1) + 2))) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL; + else + shflags |= MEM_WRITE_EXTERNAL; + } } mem_set_mem_state_both(base, 0x4000, shflags); @@ -108,17 +113,21 @@ opti895_recalc(opti895_t *dev) shflags = MEM_READ_INTERNAL; shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; } else { - if (dev->regs[0x26] & 0x40) { - shflags = MEM_READ_EXTANY; + shflags = (dev->regs[0x2d] & (1 << (i >> 1))) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL; + if (dev->regs[0x26] & 0x40) shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; - } else - shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY; + else { + if (dev->regs[0x26] & 0x80) + shflags |= (dev->regs[0x2d] & (1 << (i >> 1))) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL; + else + shflags |= MEM_WRITE_EXTERNAL; + } } mem_set_mem_state_both(base, 0x4000, shflags); } - flushmmucache(); + flushmmucache_nopc(); } @@ -138,7 +147,7 @@ opti895_write(uint16_t addr, uint8_t val, void *priv) } break; case 0x24: - if (((dev->idx >= 0x20) && (dev->idx <= 0x2c)) || + if (((dev->idx >= 0x20) && (dev->idx <= 0x2f)) || ((dev->idx >= 0xe0) && (dev->idx <= 0xef))) { dev->regs[dev->idx] = val; opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val); @@ -152,6 +161,7 @@ opti895_write(uint16_t addr, uint8_t val, void *priv) case 0x22: case 0x23: case 0x26: + case 0x2d: opti895_recalc(dev); break; @@ -177,7 +187,7 @@ opti895_write(uint16_t addr, uint8_t val, void *priv) case 0xe1: case 0xe2: - dev->scratch[addr] = val; + dev->scratch[addr - 0xe1] = val; break; } } @@ -195,7 +205,7 @@ opti895_read(uint16_t addr, void *priv) ret = dev->regs[dev->idx]; break; case 0x24: - if (((dev->idx >= 0x20) && (dev->idx <= 0x2c)) || + if (((dev->idx >= 0x20) && (dev->idx <= 0x2f)) || ((dev->idx >= 0xe0) && (dev->idx <= 0xef))) { ret = dev->regs[dev->idx]; if (dev->idx == 0xe0) @@ -204,7 +214,7 @@ opti895_read(uint16_t addr, void *priv) break; case 0xe1: case 0xe2: - ret = dev->scratch[addr]; + ret = dev->scratch[addr - 0xe1]; break; } diff --git a/src/chipset/sis_5511.c b/src/chipset/sis_5511.c index 673d37ebe..f85b021b5 100644 --- a/src/chipset/sis_5511.c +++ b/src/chipset/sis_5511.c @@ -79,40 +79,56 @@ typedef struct sis_5511_t } sis_5511_t; static void -sis_5511_shadow_recalc(int cur_reg, sis_5511_t *dev) +sis_5511_shadow_recalc(sis_5511_t *dev) { - if (cur_reg == 0x86) - mem_set_mem_state_both(0xf0000, 0x10000, ((dev->pci_conf[cur_reg] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->pci_conf[cur_reg] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); - else - { - mem_set_mem_state_both(0xc0000 + ((cur_reg & 7) << 15), 0x4000, ((dev->pci_conf[cur_reg] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->pci_conf[cur_reg] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); - mem_set_mem_state_both(0xc4000 + ((cur_reg & 7) << 15), 0x4000, ((dev->pci_conf[cur_reg] & 8) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->pci_conf[cur_reg] & 2) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); - } + int i, state; + uint32_t base; - flushmmucache_nopc(); + for (i = 0x80; i <= 0x86; i++) { + if (i == 0x86) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(0xf0000, 0x10000, state); + pclog("000F0000-000FFFFF\n"); + } else { + base = ((i & 0x07) << 15) + 0xc0000; + + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base, 0x4000, state); + pclog("%08X-%08X\n", base, base + 0x3fff); + + state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base + 0x4000, 0x4000, state); + pclog("%08X-%08X\n", base + 0x4000, base + 0x7fff); + } + } + + flushmmucache_nopc(); } static void sis_5511_smram_recalc(sis_5511_t *dev) { - smram_disable_all(); + smram_disable_all(); - switch (dev->pci_conf[0x65] >> 6) - { - case 0: - smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); - break; - case 1: - smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); - break; - case 2: - smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); - break; - } + switch (dev->pci_conf[0x65] >> 6) { + case 0: + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); + break; + case 1: + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); + break; + case 2: + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1); + break; + } flushmmucache(); } + void sis_5513_ide_handler(sis_5511_t *dev) { ide_pri_disable(); @@ -140,31 +156,19 @@ void sis_5513_bm_handler(sis_5511_t *dev) sff_bus_master_handler(dev->ide_drive[1], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE + 8); } + static void sis_5511_write(int func, int addr, uint8_t val, void *priv) { - sis_5511_t *dev = (sis_5511_t *)priv; + sis_5511_t *dev = (sis_5511_t *)priv; - switch (addr) - { - case 0x04: /* Command - low byte */ - dev->pci_conf[addr] = val; - break; - - case 0x05: /* Command - high byte */ - dev->pci_conf[addr] = val; - break; - - case 0x06: /* Status - Low Byte */ - dev->pci_conf[addr] &= val; - break; - - case 0x07: /* Status - High Byte */ - dev->pci_conf[addr] &= 0x16; + switch (addr) { + case 0x07: /* Status - High Byte */ + dev->pci_conf[addr] &= 0xb0; break; case 0x50: - dev->pci_conf[addr] = (val & 0xf9) | 4; + dev->pci_conf[addr] = val; cpu_cache_ext_enabled = !!(val & 0x40); cpu_update_waitstates(); break; @@ -177,8 +181,7 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[addr] = val & 0x3f; break; - case 0x53: - case 0x54: + case 0x53: case 0x54: dev->pci_conf[addr] = val; break; @@ -186,15 +189,17 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[addr] = val & 0xf8; break; - case 0x57: - case 0x58: - case 0x59: + case 0x56 ... 0x59: dev->pci_conf[addr] = val; break; case 0x5a: + /* TODO: Fast Gate A20 Emulation and Fast Reset Emulation on the KBC. + The former (bit 7) means the chipset intercepts D1h to 64h and 00h to 60h. + The latter (bit 6) means the chipset intercepts all odd FXh to 64h. + Bit 5 sets fast reset latency. This should be fixed on the other SiS + chipsets as well. */ dev->pci_conf[addr] = val; - port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x80)); break; case 0x5b: @@ -214,22 +219,18 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv) break; case 0x5f: - dev->pci_conf[addr] = val; + dev->pci_conf[addr] = val & 0xfe; break; case 0x60: dev->pci_conf[addr] = val & 0x3e; - if (!!(val & 2) && (dev->pci_conf[0x68] & 1)) - { + if ((dev->pci_conf[0x68] & 1) && (val & 2)) { smi_line = 1; dev->pci_conf[0x69] |= 1; } break; - case 0x61: /* STPCLK# Assertion Timer */ - case 0x62: /* STPCLK# De-assertion Timer */ - case 0x63: /* System Standby Timer */ - case 0x64: + case 0x61 ... 0x64: dev->pci_conf[addr] = val; break; @@ -242,8 +243,7 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[addr] = val & 0x7f; break; - case 0x67: - case 0x68: + case 0x67: case 0x68: dev->pci_conf[addr] = val; break; @@ -251,11 +251,7 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[addr] &= val; break; - case 0x6a: - case 0x6b: - case 0x6c: - case 0x6d: - case 0x6e: + case 0x6a ... 0x6e: dev->pci_conf[addr] = val; break; @@ -329,8 +325,7 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv) case 0x85: case 0x86: dev->pci_conf[addr] = val & ((addr == 0x86) ? 0xe8 : 0xee); - sis_5511_shadow_recalc(addr, dev); - sis_5511_smram_recalc(dev); + sis_5511_shadow_recalc(dev); break; case 0x90: /* 5512 General Purpose Register Index */ @@ -620,24 +615,45 @@ sis_5513_isa_read(uint16_t addr, void *priv) return 0xff; } + static void sis_5511_reset(void *priv) { - sis_5511_t *dev = (sis_5511_t *)priv; + sis_5511_t *dev = (sis_5511_t *)priv; + + /* SiS 5511 */ + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x11; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = 0x07; + dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x02; + dev->pci_conf[0x08] = 0x00; + dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00; + dev->pci_conf[0x52] = 0x20; + dev->pci_conf[0x53] = dev->pci_conf[0x54] = 0x00; + dev->pci_conf[0x55] = dev->pci_conf[0x56] = 0x00; + dev->pci_conf[0x57] = dev->pci_conf[0x58] = 0x00; + dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00; + dev->pci_conf[0x5b] = dev->pci_conf[0x5c] = 0x00; + dev->pci_conf[0x5d] = dev->pci_conf[0x5e] = 0x00; + dev->pci_conf[0x5f] = dev->pci_conf[0x60] = 0x00; + dev->pci_conf[0x61] = dev->pci_conf[0x62] = 0xff; + dev->pci_conf[0x63] = 0xff; + dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00; + dev->pci_conf[0x66] = 0x00; + dev->pci_conf[0x67] = 0xff; + dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; + dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00; + dev->pci_conf[0x6c] = dev->pci_conf[0x6d] = 0x00; + dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00; + + cpu_cache_ext_enabled = 0; + cpu_update_waitstates(); - /* SiS 5511 */ - dev->pci_conf[0x00] = 0x39; - dev->pci_conf[0x01] = 0x10; - dev->pci_conf[0x02] = 0x11; - dev->pci_conf[0x03] = 0x55; - dev->pci_conf[0x04] = 7; - dev->pci_conf[0x07] = 2; - dev->pci_conf[0x0b] = 6; - dev->pci_conf[0x52] = 0x20; - dev->pci_conf[0x61] = 0xff; - dev->pci_conf[0x62] = 0xff; - dev->pci_conf[0x63] = 0xff; - dev->pci_conf[0x67] = 0xff; dev->pci_conf[0x6b] = 0xff; dev->pci_conf[0x6c] = 0xff; dev->pci_conf[0x70] = 4; @@ -652,6 +668,15 @@ sis_5511_reset(void *priv) dev->pci_conf[0x7c] = 4; dev->pci_conf[0x7e] = 4; dev->pci_conf[0x7f] = 0x80; + dev->pci_conf[0x80] = 0x00; + dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x82] = 0x00; + dev->pci_conf[0x83] = 0x00; + dev->pci_conf[0x84] = 0x00; + dev->pci_conf[0x85] = 0x00; + dev->pci_conf[0x86] = 0x00; + sis_5511_smram_recalc(dev); + sis_5511_shadow_recalc(dev); /* SiS 5513 */ dev->pci_conf_sb[0][0x00] = 0x39; diff --git a/src/chipset/sis_85c4xx.c b/src/chipset/sis_85c4xx.c index 0a2bf34af..4ca0c76d7 100644 --- a/src/chipset/sis_85c4xx.c +++ b/src/chipset/sis_85c4xx.c @@ -22,6 +22,7 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include "cpu.h" +#include "x86.h" #include <86box/timer.h> #include <86box/io.h> #include <86box/device.h> @@ -39,6 +40,7 @@ typedef struct reg_base, reg_last, reg_00, is_471, regs[39], scratch[2]; + uint32_t mem_state[8]; smram_t *smram; port_92_t *port_92; } sis_85c4xx_t; @@ -47,7 +49,7 @@ typedef struct static void sis_85c4xx_recalcmapping(sis_85c4xx_t *dev) { - uint32_t base; + uint32_t base, n = 0; uint32_t i, shflags = 0; uint32_t readext, writeext; uint8_t romcs = 0xc0, cur_romcs; @@ -73,12 +75,25 @@ sis_85c4xx_recalcmapping(sis_85c4xx_t *dev) shadowbios_write |= (base >= 0xe0000) && !(dev->regs[0x02] & 0x40); shflags = (dev->regs[0x02] & 0x80) ? MEM_READ_INTERNAL : readext; shflags |= (dev->regs[0x02] & 0x40) ? writeext : MEM_WRITE_INTERNAL; - mem_set_mem_state(base, 0x8000, shflags); - } else - mem_set_mem_state(base, 0x8000, readext | writeext); + if (dev->mem_state[i] != shflags) { + n++; + mem_set_mem_state(base, 0x8000, shflags); + if ((base >= 0xf0000) && (dev->mem_state[i] & MEM_READ_INTERNAL) && !(shflags & MEM_READ_INTERNAL)) + mem_invalidate_range(base, base + 0x7fff); + dev->mem_state[i] = shflags; + } + } else { + shflags = readext | writeext; + if (dev->mem_state[i] != shflags) { + n++; + mem_set_mem_state(base, 0x8000, shflags); + dev->mem_state[i] = shflags; + } + } } - flushmmucache_nopc(); + if (n > 0) + flushmmucache_nopc(); } @@ -141,7 +156,8 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv) case 0x02: case 0x03: case 0x08: - sis_85c4xx_recalcmapping(dev); + if (valxor) + sis_85c4xx_recalcmapping(dev); break; case 0x0b: @@ -237,6 +253,69 @@ sis_85c4xx_in(uint16_t port, void *priv) } +static void +sis_85c4xx_reset(void *priv) +{ + sis_85c4xx_t *dev = (sis_85c4xx_t *) priv; + int mem_size_mb = mem_size >> 10; + static uint8_t ram_4xx[64] = { 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x06, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + static uint8_t ram_471[64] = { 0x00, 0x00, 0x01, 0x01, 0x02, 0x20, 0x09, 0x09, 0x04, 0x04, 0x05, 0x05, 0x0b, 0x0b, 0x0b, 0x0b, + 0x13, 0x21, 0x06, 0x06, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, + 0x1b, 0x1b, 0x1b, 0x1b, 0x0f, 0x0f, 0x0f, 0x0f, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e }; + + memset(dev->regs, 0x00, sizeof(dev->regs)); + + if (cpu_s->rspeed < 25000000) + dev->regs[0x08] = 0x80; + + if (dev->is_471) { + dev->regs[0x09] = 0x40; + if (mem_size_mb >= 64) { + if ((mem_size_mb >= 65) && (mem_size_mb < 68)) + dev->regs[0x09] |= 0x22; + else + dev->regs[0x09] |= 0x24; + } else + dev->regs[0x09] |= ram_471[mem_size_mb]; + + dev->regs[0x11] = 0x09; + dev->regs[0x12] = 0xff; + dev->regs[0x1f] = 0x20; /* Video access enabled. */ + dev->regs[0x23] = 0xf0; + dev->regs[0x26] = 0x01; + + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x00010000, 0, 1); + + port_92_remove(dev->port_92); + + mem_remap_top(256); + soft_reset_mask = 0; + } else { + /* Bits 6 and 7 must be clear on the SiS 40x. */ + if (dev->reg_base == 0x60) + dev->reg_00 = 0x24; + + if (mem_size_mb == 64) + dev->regs[0x00] = 0x1f; + else if (mem_size_mb < 64) + dev->regs[0x00] = ram_4xx[mem_size_mb]; + + dev->regs[0x11] = 0x01; + } + + dev->scratch[0] = dev->scratch[1] = 0xff; + + cpu_cache_ext_enabled = 0; + cpu_update_waitstates(); + + sis_85c4xx_recalcmapping(dev); +} + + static void sis_85c4xx_close(void *priv) { @@ -252,8 +331,6 @@ sis_85c4xx_close(void *priv) static void * sis_85c4xx_init(const device_t *info) { - int mem_size_mb; - sis_85c4xx_t *dev = (sis_85c4xx_t *) malloc(sizeof(sis_85c4xx_t)); memset(dev, 0, sizeof(sis_85c4xx_t)); @@ -261,161 +338,22 @@ sis_85c4xx_init(const device_t *info) dev->reg_base = info->local & 0xff; - mem_size_mb = mem_size >> 10; - - if (cpu_s->rspeed < 25000000) - dev->regs[0x08] = 0x80; - if (dev->is_471) { dev->reg_last = dev->reg_base + 0x76; - dev->regs[0x09] = 0x40; - switch (mem_size_mb) { - case 0: case 1: - dev->regs[0x09] |= 0x00; - break; - case 2: case 3: - dev->regs[0x09] |= 0x01; - break; - case 4: - dev->regs[0x09] |= 0x02; - break; - case 5: - dev->regs[0x09] |= 0x20; - break; - case 6: case 7: - dev->regs[0x09] |= 0x09; - break; - case 8: case 9: - dev->regs[0x09] |= 0x04; - break; - case 10: case 11: - dev->regs[0x09] |= 0x05; - break; - case 12: case 13: case 14: case 15: - dev->regs[0x09] |= 0x0b; - break; - case 16: - dev->regs[0x09] |= 0x13; - break; - case 17: - dev->regs[0x09] |= 0x21; - break; - case 18: case 19: - dev->regs[0x09] |= 0x06; - break; - case 20: case 21: case 22: case 23: - dev->regs[0x09] |= 0x0d; - break; - case 24: case 25: case 26: case 27: - case 28: case 29: case 30: case 31: - dev->regs[0x09] |= 0x0e; - break; - case 32: case 33: case 34: case 35: - dev->regs[0x09] |= 0x1b; - break; - case 36: case 37: case 38: case 39: - dev->regs[0x09] |= 0x0f; - break; - case 40: case 41: case 42: case 43: - case 44: case 45: case 46: case 47: - dev->regs[0x09] |= 0x17; - break; - case 48: - dev->regs[0x09] |= 0x1e; - break; - default: - if (mem_size_mb < 64) - dev->regs[0x09] |= 0x1e; - else if ((mem_size_mb >= 65) && (mem_size_mb < 68)) - dev->regs[0x09] |= 0x22; - else - dev->regs[0x09] |= 0x24; - break; - } - - dev->regs[0x11] = 0x09; - dev->regs[0x12] = 0xff; - dev->regs[0x1f] = 0x20; /* Video access enabled. */ - dev->regs[0x23] = 0xf0; - dev->regs[0x26] = 0x01; - dev->smram = smram_add(); - smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x00010000, 0, 1); dev->port_92 = device_add(&port_92_device); - port_92_remove(dev->port_92); - } else { + } else dev->reg_last = dev->reg_base + 0x11; - /* Bits 6 and 7 must be clear on the SiS 40x. */ - if (dev->reg_base == 0x60) - dev->reg_00 = 0x24; - - switch (mem_size_mb) { - case 1: - default: - dev->regs[0x00] = 0x00; - break; - case 2: - dev->regs[0x00] = 0x01; - break; - case 4: - dev->regs[0x00] = 0x02; - break; - case 6: - dev->regs[0x00] = 0x03; - break; - case 8: - dev->regs[0x00] = 0x04; - break; - case 10: - dev->regs[0x00] = 0x05; - break; - case 12: - dev->regs[0x00] = 0x0b; - break; - case 16: - dev->regs[0x00] = 0x19; - break; - case 18: - dev->regs[0x00] = 0x06; - break; - case 20: - dev->regs[0x00] = 0x14; - break; - case 24: - dev->regs[0x00] = 0x15; - break; - case 32: - dev->regs[0x00] = 0x1b; - break; - case 36: - dev->regs[0x00] = 0x16; - break; - case 40: - dev->regs[0x00] = 0x17; - break; - case 48: - dev->regs[0x00] = 0x1e; - break; - case 64: - dev->regs[0x00] = 0x1f; - break; - } - - dev->regs[0x11] = 0x01; - } - io_sethandler(0x0022, 0x0002, sis_85c4xx_in, NULL, NULL, sis_85c4xx_out, NULL, NULL, dev); - dev->scratch[0] = dev->scratch[1] = 0xff; - io_sethandler(0x00e1, 0x0002, sis_85c4xx_in, NULL, NULL, sis_85c4xx_out, NULL, NULL, dev); - sis_85c4xx_recalcmapping(dev); + sis_85c4xx_reset(dev); return dev; } @@ -425,7 +363,7 @@ const device_t sis_85c401_device = { "SiS 85c401/85c402", 0, 0x060, - sis_85c4xx_init, sis_85c4xx_close, NULL, + sis_85c4xx_init, sis_85c4xx_close, sis_85c4xx_reset, { NULL }, NULL, NULL, NULL }; @@ -434,7 +372,7 @@ const device_t sis_85c460_device = { "SiS 85c460", 0, 0x050, - sis_85c4xx_init, sis_85c4xx_close, NULL, + sis_85c4xx_init, sis_85c4xx_close, sis_85c4xx_reset, { NULL }, NULL, NULL, NULL }; @@ -444,7 +382,7 @@ const device_t sis_85c461_device = { "SiS 85c461", 0, 0x050, - sis_85c4xx_init, sis_85c4xx_close, NULL, + sis_85c4xx_init, sis_85c4xx_close, sis_85c4xx_reset, { NULL }, NULL, NULL, NULL }; @@ -453,7 +391,7 @@ const device_t sis_85c471_device = { "SiS 85c407/85c471", 0, 0x150, - sis_85c4xx_init, sis_85c4xx_close, NULL, + sis_85c4xx_init, sis_85c4xx_close, sis_85c4xx_reset, { NULL }, NULL, NULL, NULL }; diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index bbc8a8ec5..84ad90c91 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -89,7 +89,7 @@ sis_85c50x_shadow_recalc(sis_85c50x_t *dev) mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x56] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY)); } - flushmmucache(); + flushmmucache_nopc(); } @@ -107,8 +107,7 @@ sis_85c50x_smm_recalc(sis_85c50x_t *dev) switch ((dev->pci_conf[0x65] & 0xe0) >> 5) { case 0x00: - if (!(dev->pci_conf[0x54] & 0xc0)) - smram_enable(dev->smram, 0xe0000, 0xe0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); + smram_enable(dev->smram, 0xe0000, 0xe0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1); break; case 0x01: smram_enable(dev->smram, 0xb0000, ram_base, 0x10000, (dev->pci_conf[0x65] & 0x10), 1); diff --git a/src/chipset/umc_8886.c b/src/chipset/umc_8886.c index ca492a0b8..591805329 100644 --- a/src/chipset/umc_8886.c +++ b/src/chipset/umc_8886.c @@ -12,14 +12,17 @@ * reverse engineering the BIOS of various machines using it. * * Authors: Tiseno100, + * Miran Grca, * * Copyright 2021 Tiseno100. + * Copyright 2021 Miran Grca. */ -/* UMC 8886 Configuration Registers +/* + UMC 8886xx Configuration Registers - TODO: - - More Appropriate Bitmasking(If it's even possible) + Note: PMU functionality is quite basic. There may be Enable/Disable bits, IRQ/SMI picks and it also + required for 386_common.c to get patched in order to function properly. Warning: Register documentation may be inaccurate! @@ -34,11 +37,9 @@ Bits 7-4 PCI IRQ for INTD Bits 3-0 PCI IRQ for INTC - Function 0 Register 46: - Bit 7: Replace SMI request for non-SMM CPU's (1: IRQ15/0: IRQ10) - - Function 0 Register 51: - Bit 2: VGA Power Down (0: Standard/1: VESA DPMS) + Function 0 Register 46 (corrected by Miran Grca): + Bit 7: IRQ SMI Request (1: IRQ 15, 0: IRQ 10) + Bit 6: PMU Trigger(1: By IRQ/0: By SMI) Function 0 Register 56: Bit 1-0 ISA Bus Speed @@ -46,10 +47,22 @@ 0 1 PCICLK/4 1 0 PCICLK/2 + Function 0 Register A2 - non-software SMI# status register + (documented by Miran Grca): + Bit 4: I set, graphics card goes into sleep mode + This register is most likely R/WC + + Function 0 Register A3 (added more details by Miran Grca): + Bit 7: Unlock SMM + Bit 6: Software SMI trigger (also doubles as software SMI# status register, + cleared by writing a 0 to it - see the handler used by Phoenix BIOS'es): + If Function 0 Register 46 Bit 6 is set, it raises the specified IRQ (15 + or 10) instead. + Function 0 Register A4: Bit 0: Host to PCI Clock (1: 1 by 1/0: 1 by half) - Function 1 Register 4: + Function 1 Register 4: (UMC 8886AF/8886BF Only!) Bit 0: Enable Internal IDE */ @@ -69,23 +82,28 @@ #include <86box/hdd.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> +#include <86box/pic.h> #include <86box/pci.h> #include <86box/chipset.h> +#define IDE_BIT 0x01 + + #ifdef ENABLE_UMC_8886_LOG int umc_8886_do_log = ENABLE_UMC_8886_LOG; + + static void umc_8886_log(const char *fmt, ...) { va_list ap; - if (umc_8886_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + if (umc_8886_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else @@ -94,23 +112,24 @@ umc_8886_log(const char *fmt, ...) /* PCI IRQ Flags */ -#define INTA (PCI_INTA + (2 * !(addr & 1))) -#define INTB (PCI_INTB + (2 * !(addr & 1))) -#define IRQRECALCA (((val & 0xf0) != 0) ? ((val & 0xf0) >> 4) : PCI_IRQ_DISABLED) -#define IRQRECALCB (((val & 0x0f) != 0) ? (val & 0x0f) : PCI_IRQ_DISABLED) +#define INTA (PCI_INTA + (2 * !(addr & 1))) +#define INTB (PCI_INTB + (2 * !(addr & 1))) +#define IRQRECALCA (((val & 0xf0) != 0) ? ((val & 0xf0) >> 4) : PCI_IRQ_DISABLED) +#define IRQRECALCB (((val & 0x0f) != 0) ? (val & 0x0f) : PCI_IRQ_DISABLED) -/* Disable Internal IDE Flag needed for the BF Southbridge variant */ -#define HAS_IDE dev->has_ide +/* Disable Internal IDE Flag needed for the AF or BF Southbridge variant */ +#define HAS_IDE dev->has_ide /* Southbridge Revision */ -#define SB_ID dev->sb_id +#define SB_ID dev->sb_id typedef struct umc_8886_t { - uint8_t pci_conf_sb[2][256]; /* PCI Registers */ - uint16_t sb_id; /* Southbridge Revision */ - int has_ide; /* Check if Southbridge Revision is AF or F */ + uint8_t max_func, /* Last function number */ + pci_conf_sb[2][256]; /* PCI Registers */ + uint16_t sb_id; /* Southbridge Revision */ + int has_ide; /* Check if Southbridge Revision is AF or F */ } umc_8886_t; @@ -121,39 +140,66 @@ umc_8886_ide_handler(int status) ide_sec_disable(); if (status) { - ide_pri_enable(); - ide_sec_enable(); + ide_pri_enable(); + ide_sec_enable(); } } static void -um8886_write(int func, int addr, uint8_t val, void *priv) +umc_8886_write(int func, int addr, uint8_t val, void *priv) { umc_8886_t *dev = (umc_8886_t *)priv; - umc_8886_log("UM8886: dev->regs[%02x] = %02x (%02x)\n", addr, val, func); - /* We don't know the RW status of registers but Phoenix writes on some RO registers too*/ - if (addr > 3) switch (func) { - case 0: /* Southbridge */ + if (func <= dev->max_func) switch (func) { + case 0: /* PCI to ISA Bridge */ + umc_8886_log("UM8886: dev->regs[%02x] = %02x POST %02x\n", addr, val, inb(0x80)); + switch (addr) { - case 0x43: - case 0x44: + case 0x04: case 0x05: + dev->pci_conf_sb[func][addr] = val; + break; + + case 0x07: + dev->pci_conf_sb[func][addr] &= ~(val & 0xf9); + break; + + case 0x0c: case 0x0d: + dev->pci_conf_sb[func][addr] = val; + break; + + case 0x40: case 0x41: + case 0x42: + dev->pci_conf_sb[func][addr] = val; + break; + + case 0x43: case 0x44: dev->pci_conf_sb[func][addr] = val; pci_set_irq_routing(INTA, IRQRECALCA); pci_set_irq_routing(INTB, IRQRECALCB); break; + case 0x45: + dev->pci_conf_sb[func][addr] = val; + break; + case 0x46: - dev->pci_conf_sb[func][addr] = val & 0xaf; + /* Bit 6 seems to be the IRQ/SMI# toggle, 1 = IRQ, 0 = SMI#. */ + dev->pci_conf_sb[func][addr] = val; break; case 0x47: - dev->pci_conf_sb[func][addr] = val & 0x4f; + dev->pci_conf_sb[func][addr] = val; + break; + + case 0x50: case 0x51: case 0x52: case 0x53: + case 0x54: case 0x55: + dev->pci_conf_sb[func][addr] = val; break; case 0x56: dev->pci_conf_sb[func][addr] = val; + switch (val & 2) { case 0: cpu_set_isa_pci_div(3); @@ -165,52 +211,78 @@ um8886_write(int func, int addr, uint8_t val, void *priv) cpu_set_isa_pci_div(2); break; } + break; case 0x57: - dev->pci_conf_sb[func][addr] = val & 0x38; + case 0x70 ... 0x76: + case 0x80: case 0x81: + case 0x90 ... 0x92: + case 0xa0 ... 0xa1: + dev->pci_conf_sb[func][addr] = val; break; - case 0x71: - dev->pci_conf_sb[func][addr] = val & 1; + case 0xa2: + dev->pci_conf_sb[func][addr] &= ~val; break; - case 0x90: - dev->pci_conf_sb[func][addr] = val & 2; - break; + case 0xa3: + /* SMI Provocation (Bit 7 Enable SMM + Bit 6 Software SMI) */ + if (((val & 0xc0) == 0xc0) && !(dev->pci_conf_sb[0][0xa3] & 0x40)) { + if (dev->pci_conf_sb[0][0x46] & 0x40) + picint(1 << ((dev->pci_conf_sb[0][0x46] & 0x80) ? 15 : 10)); + else + smi_line = 1; + dev->pci_conf_sb[0][0xa3] |= 0x04; + } - case 0x92: - dev->pci_conf_sb[func][addr] = val & 0x1f; - break; - - case 0xa0: - dev->pci_conf_sb[func][addr] = val & 0xfc; + dev->pci_conf_sb[func][addr] = val; break; case 0xa4: - dev->pci_conf_sb[func][addr] = val & 0x89; + dev->pci_conf_sb[func][addr] = val; cpu_set_pci_speed(cpu_busspeed / ((val & 1) ? 1 : 2)); break; - default: + case 0xa5 ... 0xa8: dev->pci_conf_sb[func][addr] = val; break; } break; - case 1: /* IDE Controller */ - dev->pci_conf_sb[func][addr] = val; - if ((addr == 4) && HAS_IDE) - umc_8886_ide_handler(val & 1); + + case 1: /* IDE Controller */ + umc_8886_log("UM8886-IDE: dev->regs[%02x] = %02x POST: %02x\n", addr, val, inb(0x80)); + + switch (addr) { + case 0x04: + dev->pci_conf_sb[func][addr] = val; + umc_8886_ide_handler(val & 1); + break; + + case 0x07: + dev->pci_conf_sb[func][addr] &= ~(val & 0xf9); + break; + + case 0x3c: + case 0x40: case 0x41: + dev->pci_conf_sb[func][addr] = val; + break; + } break; } } static uint8_t -um8886_read(int func, int addr, void *priv) +umc_8886_read(int func, int addr, void *priv) { umc_8886_t *dev = (umc_8886_t *)priv; - return dev->pci_conf_sb[func][addr]; + uint8_t ret = 0xff; + + if (func <= dev->max_func) + ret = dev->pci_conf_sb[func][addr]; + + return ret; } @@ -219,26 +291,57 @@ umc_8886_reset(void *priv) { umc_8886_t *dev = (umc_8886_t *)priv; - /* Defaults */ - dev->pci_conf_sb[0][0] = 0x60; /* UMC */ + memset(dev->pci_conf_sb[0], 0x00, sizeof(dev->pci_conf_sb[0])); + memset(dev->pci_conf_sb[1], 0x00, sizeof(dev->pci_conf_sb[1])); + + dev->pci_conf_sb[0][0] = 0x60; /* UMC */ dev->pci_conf_sb[0][1] = 0x10; - dev->pci_conf_sb[0][2] = (SB_ID & 0xff); /* 8886xx */ + dev->pci_conf_sb[0][2] = (SB_ID & 0xff); /* 8886xx */ dev->pci_conf_sb[0][3] = ((SB_ID >> 8) & 0xff); - dev->pci_conf_sb[0][8] = 1; + dev->pci_conf_sb[0][4] = 0x0f; + dev->pci_conf_sb[0][7] = 2; + + dev->pci_conf_sb[0][8] = 0x0e; dev->pci_conf_sb[0][0x09] = 0x00; dev->pci_conf_sb[0][0x0a] = 0x01; dev->pci_conf_sb[0][0x0b] = 0x06; - for (int i = 1; i < 5; i++) /* Disable all IRQ interrupts */ - pci_set_irq_routing(i, PCI_IRQ_DISABLED); + dev->pci_conf_sb[0][0x40] = 1; + dev->pci_conf_sb[0][0x41] = 6; + dev->pci_conf_sb[0][0x42] = 8; + dev->pci_conf_sb[0][0x43] = 0x9a; + dev->pci_conf_sb[0][0x44] = 0xbc; + dev->pci_conf_sb[0][0x45] = 4; + dev->pci_conf_sb[0][0x47] = 0x40; + dev->pci_conf_sb[0][0x50] = 1; + dev->pci_conf_sb[0][0x51] = 3; + dev->pci_conf_sb[0][0xa8] = 0x20; if (HAS_IDE) { + dev->pci_conf_sb[1][0] = 0x60; /* UMC */ + dev->pci_conf_sb[1][1] = 0x10; + + dev->pci_conf_sb[1][2] = 0x3a; /* 8886BF IDE */ + dev->pci_conf_sb[1][3] = 0x67; + dev->pci_conf_sb[1][4] = 1; /* Start with Internal IDE Enabled */ + + dev->pci_conf_sb[1][8] = 0x10; + + dev->pci_conf_sb[1][0x09] = 0x0f; + dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 1; + umc_8886_ide_handler(1); } + + for (int i = 1; i < 5; i++) /* Disable all IRQ interrupts */ + pci_set_irq_routing(i, PCI_IRQ_DISABLED); + + cpu_set_isa_pci_div(3); + cpu_set_pci_speed(cpu_busspeed / 2); } @@ -257,12 +360,14 @@ umc_8886_init(const device_t *info) umc_8886_t *dev = (umc_8886_t *)malloc(sizeof(umc_8886_t)); memset(dev, 0, sizeof(umc_8886_t)); - dev->has_ide = (info->local == 0x886a); - pci_add_card(PCI_ADD_SOUTHBRIDGE, um8886_read, um8886_write, dev); /* Device 12: UMC 8886xx */ + dev->has_ide = !!(info->local == 0x886a); + pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev); /* Device 12: UMC 8886xx */ /* Add IDE if UM8886AF variant */ if (HAS_IDE) - device_add(&ide_pci_2ch_device); + device_add(&ide_pci_2ch_device); + + dev->max_func = (HAS_IDE) ? 1 : 0; /* Get the Southbridge Revision */ SB_ID = info->local; @@ -277,24 +382,16 @@ const device_t umc_8886f_device = { "UMC 8886F", DEVICE_PCI, 0x8886, - umc_8886_init, - umc_8886_close, - umc_8886_reset, - { NULL }, - NULL, - NULL, + umc_8886_init, umc_8886_close, umc_8886_reset, + { NULL }, NULL, NULL, NULL }; const device_t umc_8886af_device = { - "UMC 8886AF", + "UMC 8886AF/8886BF", DEVICE_PCI, 0x886a, - umc_8886_init, - umc_8886_close, - umc_8886_reset, - { NULL }, - NULL, - NULL, + umc_8886_init, umc_8886_close, umc_8886_reset, + { NULL }, NULL, NULL, NULL }; diff --git a/src/chipset/umc_8890.c b/src/chipset/umc_8890.c deleted file mode 100644 index da49037d1..000000000 --- a/src/chipset/umc_8890.c +++ /dev/null @@ -1,180 +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. - * - * Implementation of the UMC 8890 Chipset. - * - * Note: This chipset has no datasheet, everything were done via - * reverse engineering the BIOS of various machines using it. - * - * - * Authors: Tiseno100, - * - * Copyright 2021 Tiseno100. - */ - -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include "cpu.h" -#include <86box/timer.h> -#include <86box/io.h> -#include <86box/device.h> - -#include <86box/apm.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/port_92.h> -#include <86box/smram.h> - -#include <86box/chipset.h> - -#ifdef ENABLE_UMC_8890_LOG -int umc_8890_do_log = ENABLE_UMC_8890_LOG; -static void -umc_8890_log(const char *fmt, ...) -{ - va_list ap; - - if (umc_8890_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -#define umc_8890_log(fmt, ...) -#endif - -/* Shadow RAM Flags */ -#define ENABLE_SHADOW (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) -#define DISABLE_SHADOW (MEM_READ_EXTANY | MEM_WRITE_EXTANY) - -typedef struct umc_8890_t -{ - apm_t *apm; - smram_t *smram; - - uint8_t pci_conf[256]; -} umc_8890_t; - -uint16_t umc_8890_shadow_flag(uint8_t flag) -{ -return (flag & 1) ? (MEM_READ_INTERNAL | ((flag & 2) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY); -} - -void umc_8890_shadow(umc_8890_t *dev) -{ - - mem_set_mem_state_both(0xe0000, 0x10000, umc_8890_shadow_flag((dev->pci_conf[0x5f] & 0x0c) >> 2)); - mem_set_mem_state_both(0xf0000, 0x10000, umc_8890_shadow_flag((dev->pci_conf[0x5f] & 0xc0) >> 6)); - - for(int i = 0; i < 8; i++) - mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, umc_8890_shadow_flag(!!(dev->pci_conf[0x5d] & (1 << i)))); - - flushmmucache_nopc(); -} - -static void -um8890_write(int func, int addr, uint8_t val, void *priv) -{ - umc_8890_t *dev = (umc_8890_t *)priv; - - dev->pci_conf[addr] = val; - - switch (addr) - { - case 0x5c: - case 0x5d: - case 0x5e: - case 0x5f: - umc_8890_shadow(dev); - break; - - case 0x65: /* We don't know the default SMRAM values */ - smram_disable_all(); - smram_enable(dev->smram, 0xe0000, 0xe0000, 0x10000, dev->pci_conf[0x65] & 0x10, 1); - flushmmucache_nopc(); - break; - } - - umc_8890_log("UM8890: dev->regs[%02x] = %02x POST: %02x\n", addr, dev->pci_conf[addr], inb(0x80)); -} - -static uint8_t -um8890_read(int func, int addr, void *priv) -{ - umc_8890_t *dev = (umc_8890_t *)priv; - return dev->pci_conf[addr]; -} - -static void -umc_8890_reset(void *priv) -{ - umc_8890_t *dev = (umc_8890_t *)priv; - - /* Defaults */ - dev->pci_conf[0] = 0x60; /* UMC */ - dev->pci_conf[1] = 0x10; - - dev->pci_conf[2] = 0x91; /* 8891F */ - dev->pci_conf[3] = 0x88; - - dev->pci_conf[8] = 1; - - dev->pci_conf[0x09] = 0x00; - dev->pci_conf[0x0a] = 0x00; - dev->pci_conf[0x0b] = 0x06; -} - -static void -umc_8890_close(void *priv) -{ - umc_8890_t *dev = (umc_8890_t *)priv; - - smram_del(dev->smram); - free(dev); -} - -static void * -umc_8890_init(const device_t *info) -{ - umc_8890_t *dev = (umc_8890_t *)malloc(sizeof(umc_8890_t)); - memset(dev, 0, sizeof(umc_8890_t)); - pci_add_card(PCI_ADD_NORTHBRIDGE, um8890_read, um8890_write, dev); /* Device 0: UMC 8890 */ - - /* APM */ - dev->apm = device_add(&apm_pci_device); - - /* SMRAM(Needs excessive documentation before we begin SMM implementation) */ - dev->smram = smram_add(); - - /* Port 92 */ - device_add(&port_92_pci_device); - - umc_8890_reset(dev); - - return dev; -} - -const device_t umc_8890_device = { - "UMC 8890(8891BF/8892BF)", - DEVICE_PCI, - 0x886a, - umc_8890_init, - umc_8890_close, - umc_8890_reset, - {NULL}, - NULL, - NULL, - NULL}; diff --git a/src/chipset/umc_hb4.c b/src/chipset/umc_hb4.c index f9371ae5f..0948a228b 100644 --- a/src/chipset/umc_hb4.c +++ b/src/chipset/umc_hb4.c @@ -15,71 +15,77 @@ * around the web. * * Authors: Tiseno100, + * Miran Grca, * * Copyright 2021 Tiseno100. + * Copyright 2021 Miran Grca. */ /* -UMC HB4 Configuration Registers + UMC HB4 Configuration Registers -Sources & Notes: -Cache registers were found at Vogons: https://www.vogons.org/viewtopic.php?f=46&t=68829&start=20 -Basic Reverse engineering effort was done personally by me + Sources & Notes: + Cache registers were found at Vogons: https://www.vogons.org/viewtopic.php?f=46&t=68829&start=20 + Basic Reverse engineering effort was done personally by me -TODO: -- APM, SMM, SMRAM registers(Did some early work. Still quite incomplete) -- More Appropriate Bitmasking(If it's even possible) + Warning: Register documentation may be inaccurate! -Warning: Register documentation may be inaccurate! + UMC 8881x: -UMC 8881x: + Register 50: + Bit 7: Enable L2 Cache + Bit 6: Cache Policy (0: Write Thru / 1: Write Back) -Register 50: -Bit 7: Enable L2 Cache -Bit 6: Cache Policy (0: Write Thru / 1: Write Back) + Bit 5-4 Cache Speed + 0 0 Read 3-2-2-2 Write 3T + 0 1 Read 3-1-1-1 Write 3T + 1 0 Read 2-2-2-2 Write 2T + 1 1 Read 2-1-1-1 Write 2T -Bit 5-4 Cache Speed - 0 0 Read 3-2-2-2 Write 3T - 0 1 Read 3-1-1-1 Write 3T - 1 0 Read 2-2-2-2 Write 2T - 1 1 Read 2-1-1-1 Write 2T + Bit 3 Cache Banks (0: 1 Bank / 1: 2 Banks) -Bit 3 Cache Banks (0: 1 Bank / 1: 2 Banks) + Bit 2-1-0 Cache Size + 0 0 0 0KB + 0 0 1 64KB + x-x-x Multiplications of 2(64*2 for 0 1 0) till 2MB -Bit 2-1-0 Cache Size - 0 0 0 0KB - 0 0 1 64KB - x-x-x Multiplications of 2(64*2 for 0 1 0) till 2MB + Register 51: + Bit 7-6 DRAM Read Speed + 5-4 DRAM Write Speed + 0 0 1 Waits + 0 1 1 Waits + 1 0 1 Wait + 1 1 0 Waits -Register 51: -Bit 7-6 DRAM Read Speed - 5-4 DRAM Write Speed - 0 0 1 Waits - 0 1 1 Waits - 1 0 1 Wait - 1 1 0 Waits + Bit 3 Resource Lock Enable + Bit 2 Graphics Adapter (0: VL Bus / 1: PCI Bus) + Bit 1 L1 WB Policy (0: WT / 1: WB) + Bit 0 L2 Cache Tag Lenght (0: 7 Bits / 1: 8 Bits) -Bit 3 Resource Lock Enable -Bit 2 Graphics Adapter (0: VL Bus / 1: PCI Bus) -Bit 1 L1 WB Policy (0: WT / 1: WB) -Bit 0 L2 Cache Tag Lenght (0: 7 Bits / 1: 8 Bits) + Register 52: + Bit 7: Host-to-PCI Post Write (0: 1 Wait State / 1: 0 Wait States) -Register 52: -Bit 7: Host-to-PCI Post Write (0: 1 Wait State / 1: 0 Wait States) + Register 54: + Bit 7: DC000-DFFFF Read Enable + Bit 6: D8000-DBFFF Read Enable + Bit 5: D4000-D7FFF Read Enable + Bit 4: D0000-D3FFF Read Enable + Bit 3: CC000-CFFFF Read Enable + Bit 2: C8000-CBFFF Read Enable + Bit 1: C0000-C7FFF Read Enable + Bit 0: Enable C0000-DFFFF Shadow Segment Bits -Register 54: -Bit 7: DC000-DFFFF -Bit 6: D8000-DBFFF -Bit 5: D4000-D7FFF -Bit 4: D0000-D3FFF -Bit 3: CC000-CFFFF -Bit 2: C8000-CBFFF -Bit 1: C0000-C7FFF -Bit 0: Reserved + Register 55: + Bit 7: E0000-FFFF Read Enable + Bit 6: Shadow Write Status (1: Write Protect/0: Write) -Register 55: -Bit 7: Enable Shadow Reads For System & Selected Segments -Bit 6: Write Protect Enable + Register 56h & 57h: DRAM Bank 0 Configuration + Register 58h & 59h: DRAM Bank 1 Configuration + + Register 60: + Bit 5: If set and SMRAM is enabled, data cycles go to PCI and code cycles go to DRAM + Bit 0: SMRAM Local Access Enable - if set, SMRAM is also enabled outside SMM + SMRAM appears to always be enabled in SMM, and always set to A0000-BFFFF. */ #include @@ -91,161 +97,331 @@ Bit 6: Write Protect Enable #define HAVE_STDARG_H #include <86box/86box.h> #include "cpu.h" +#include "x86.h" #include <86box/timer.h> #include <86box/io.h> #include <86box/device.h> -#include <86box/apm.h> #include <86box/mem.h> #include <86box/pci.h> #include <86box/port_92.h> #include <86box/smram.h> +#ifdef USE_DYNAREC +# include "codegen_public.h" +#else +#ifdef USE_NEW_DYNAREC +# define PAGE_MASK_SHIFT 6 +#else +# define PAGE_MASK_INDEX_MASK 3 +# define PAGE_MASK_INDEX_SHIFT 10 +# define PAGE_MASK_SHIFT 4 +#endif +# define PAGE_MASK_MASK 63 +#endif #include <86box/chipset.h> + #ifdef ENABLE_HB4_LOG int hb4_do_log = ENABLE_HB4_LOG; + + static void hb4_log(const char *fmt, ...) { va_list ap; - if (hb4_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + if (hb4_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else #define hb4_log(fmt, ...) #endif -/* Shadow RAM Flags */ -#define CAN_READ ((dev->pci_conf[0x55] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) -#define CAN_WRITE ((dev->pci_conf[0x55] & 0x40) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL) -#define DISABLE (MEM_READ_EXTANY | MEM_WRITE_EXTANY) typedef struct hb4_t { - apm_t *apm; - smram_t *smram; - - uint8_t pci_conf[256]; /* PCI Registers */ + uint8_t shadow, + shadow_read, shadow_write, + pci_conf[256]; /* PCI Registers */ + int mem_state[9]; + smram_t *smram[3]; /* SMRAM Handlers */ } hb4_t; -void hb4_shadow(int cur_addr, hb4_t *dev) -{ - mem_set_mem_state_both(0xc0000, 0x8000, (dev->pci_conf[0x54] & 2) ? (CAN_READ | CAN_WRITE) : DISABLE); - for (int i = 2; i < 8; i++) - mem_set_mem_state_both(0xc8000 + ((i - 2) << 14), 0x4000, (dev->pci_conf[0x54] & (1 << i)) ? (CAN_READ | CAN_WRITE) : DISABLE); - mem_set_mem_state_both(0xe0000, 0x20000, CAN_READ | CAN_WRITE); - +static int shadow_bios[4] = { (MEM_READ_EXTANY | MEM_WRITE_INTERNAL), (MEM_READ_EXTANY | MEM_WRITE_EXTANY), + (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL), (MEM_READ_INTERNAL | MEM_WRITE_EXTANY) }; +static int shadow_read[2] = { MEM_READ_EXTANY, MEM_READ_INTERNAL }; +static int shadow_write[2] = { MEM_WRITE_INTERNAL, MEM_WRITE_EXTANY }; + + +int +hb4_shadow_bios_high(hb4_t *dev) +{ + int state; + + state = shadow_bios[dev->pci_conf[0x55] >> 6]; + + if (state != dev->mem_state[8]) { + mem_set_mem_state_both(0xf0000, 0x10000, state); + if ((dev->mem_state[8] & MEM_READ_INTERNAL) && !(state & MEM_READ_INTERNAL)) + mem_invalidate_range(0xf0000, 0xfffff); + dev->mem_state[8] = state; + return 1; + } + + return 0; +} + + +int +hb4_shadow_bios_low(hb4_t *dev) +{ + int state; + + state = shadow_bios[(dev->pci_conf[0x55] >> 6) & (dev->shadow | 0x01)]; + + if (state != dev->mem_state[7]) { + mem_set_mem_state_both(0xe0000, 0x10000, state); + dev->mem_state[7] = state; + return 1; + } + + return 0; +} + + +int +hb4_shadow_main(hb4_t *dev) +{ + int i, state; + int n = 0; + + for (i = 0; i < 6; i++) { + state = shadow_read[dev->shadow && ((dev->pci_conf[0x54] >> (i + 2)) & 0x01)] | + shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01]; + + if (state != dev->mem_state[i + 1]) { + n++; + mem_set_mem_state_both(0xc8000 + (i << 14), 0x4000, state); + dev->mem_state[i + 1] = state; + } + } + + return n; +} + + +int +hb4_shadow_video(hb4_t *dev) +{ + int state; + + state = shadow_read[dev->shadow && ((dev->pci_conf[0x54] >> 1) & 0x01)] | + shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01]; + + if (state != dev->mem_state[0]) { + mem_set_mem_state_both(0xc0000, 0x8000, state); + dev->mem_state[0] = state; + return 1; + } + + return 0; +} + + +void +hb4_shadow(hb4_t *dev) +{ + int n = 0; + hb4_log("SHADOW: %02X%02X\n", dev->pci_conf[0x55], dev->pci_conf[0x54]); + + n = hb4_shadow_bios_high(dev); + n += hb4_shadow_bios_low(dev); + n += hb4_shadow_main(dev); + n += hb4_shadow_video(dev); + + if (n > 0) flushmmucache_nopc(); } + static void -um8881_write(int func, int addr, uint8_t val, void *priv) +hb4_smram(hb4_t *dev) +{ + smram_disable_all(); + + /* Bit 0, if set, enables SMRAM access outside SMM. SMRAM appears to be always enabled + in SMM, and is always set to A0000-BFFFF. */ + smram_enable(dev->smram[0], 0x000a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1); + /* There's a mirror of the SMRAM at 0E0A0000, mapped to A0000. */ + smram_enable(dev->smram[1], 0x0e0a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1); + /* There's another mirror of the SMRAM at 4E0A0000, mapped to A0000. */ + smram_enable(dev->smram[2], 0x4e0a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1); + + /* Bit 5 seems to set data to go to PCI and code to DRAM. The Samsung SPC7700P-LW uses + this. */ + if (dev->pci_conf[0x60] & 0x20) { + if (dev->pci_conf[0x60] & 0x01) + mem_set_mem_state_smram_ex(0, 0x000a0000, 0x20000, 0x02); + mem_set_mem_state_smram_ex(1, 0x000a0000, 0x20000, 0x02); + } +} + + +static void +hb4_write(int func, int addr, uint8_t val, void *priv) { hb4_t *dev = (hb4_t *)priv; - hb4_log("UM8881: dev->regs[%02x] = %02x\n", addr, val); - if (addr > 3) /* We don't know the RW status of registers but Phoenix writes on some RO registers too*/ + hb4_log("UM8881: dev->regs[%02x] = %02x POST: %02x \n", addr, val, inb(0x80)); - switch (addr) - { - case 0x50: - dev->pci_conf[addr] = ((val & 0xf8) | 4); /* Hardcode Cache Size to 512KB */ - cpu_cache_ext_enabled = !!(val & 0x80); /* Fixes freezing issues on the HOT-433A*/ - cpu_update_waitstates(); - break; + switch (addr) { + case 0x04: case 0x05: + dev->pci_conf[addr] = val; + break; - case 0x54: - case 0x55: - dev->pci_conf[addr] = val & (!(addr & 1) ? 0xfe : 0xff); - hb4_shadow(addr, dev); - break; + case 0x07: + dev->pci_conf[addr] &= ~(val & 0xf9); + break; - case 0x60: - dev->pci_conf[addr] = val & 0x3f; - break; + case 0x0c: case 0x0d: + dev->pci_conf[addr] = val; + break; - case 0x61: - dev->pci_conf[addr] = val & 0x0f; - break; + case 0x50: + dev->pci_conf[addr] = ((val & 0xf8) | 4); /* Hardcode Cache Size to 512KB */ + cpu_cache_ext_enabled = !!(val & 0x80); /* Fixes freezing issues on the HOT-433A*/ + cpu_update_waitstates(); + break; - default: - dev->pci_conf[addr] = val; - break; - } + case 0x51: case 0x52: + dev->pci_conf[addr] = val; + break; + + case 0x53: + dev->pci_conf[addr] = val; + hb4_log("HB53: %02X\n", val); + break; + + case 0x55: + dev->shadow_read = (val & 0x80); + dev->shadow_write = (val & 0x40); + dev->pci_conf[addr] = val; + hb4_shadow(dev); + break; + case 0x54: + dev->shadow = (val & 0x01) << 1; + dev->pci_conf[addr] = val; + hb4_shadow(dev); + break; + + case 0x56 ... 0x5f: + dev->pci_conf[addr] = val; + break; + + case 0x60: + dev->pci_conf[addr] = val; + hb4_smram(dev); + break; + + case 0x61: + dev->pci_conf[addr] = val; + break; + } } + static uint8_t -um8881_read(int func, int addr, void *priv) +hb4_read(int func, int addr, void *priv) { hb4_t *dev = (hb4_t *)priv; - return dev->pci_conf[addr]; + uint8_t ret = 0xff; + + if (func == 0) + ret = dev->pci_conf[addr]; + + return ret; } + static void hb4_reset(void *priv) { hb4_t *dev = (hb4_t *)priv; + memset(dev->pci_conf, 0x00, sizeof(dev->pci_conf)); - /* Defaults */ dev->pci_conf[0] = 0x60; /* UMC */ dev->pci_conf[1] = 0x10; dev->pci_conf[2] = 0x81; /* 8881x */ dev->pci_conf[3] = 0x88; - dev->pci_conf[8] = 1; + dev->pci_conf[7] = 2; + + dev->pci_conf[8] = 4; dev->pci_conf[0x09] = 0x00; dev->pci_conf[0x0a] = 0x00; dev->pci_conf[0x0b] = 0x06; + + dev->pci_conf[0x51] = 1; + dev->pci_conf[0x52] = 1; + dev->pci_conf[0x5a] = 4; + dev->pci_conf[0x5c] = 0xc0; + dev->pci_conf[0x5d] = 0x20; + dev->pci_conf[0x5f] = 0xff; + + hb4_write(0, 0x54, 0x00, dev); + hb4_write(0, 0x55, 0x00, dev); + hb4_write(0, 0x60, 0x80, dev); + + cpu_cache_ext_enabled = 0; + cpu_update_waitstates(); + + memset(dev->mem_state, 0x00, sizeof(dev->mem_state)); } + static void hb4_close(void *priv) { hb4_t *dev = (hb4_t *)priv; - //smram_del(dev->smram); free(dev); } + static void * hb4_init(const device_t *info) { hb4_t *dev = (hb4_t *)malloc(sizeof(hb4_t)); memset(dev, 0, sizeof(hb4_t)); - pci_add_card(PCI_ADD_NORTHBRIDGE, um8881_read, um8881_write, dev); /* Device 10: UMC 8881x */ - - /* APM */ - dev->apm = device_add(&apm_pci_device); - - /* SMRAM(Needs excessive documentation before we begin SMM implementation) */ - //dev->smram = smram_add(); + pci_add_card(PCI_ADD_NORTHBRIDGE, hb4_read, hb4_write, dev); /* Device 10: UMC 8881x */ /* Port 92 */ device_add(&port_92_pci_device); + /* SMRAM */ + dev->smram[0] = smram_add(); + dev->smram[1] = smram_add(); + dev->smram[2] = smram_add(); + hb4_reset(dev); return dev; } + const device_t umc_hb4_device = { "UMC HB4(8881F)", DEVICE_PCI, 0x886a, - hb4_init, - hb4_close, - hb4_reset, - {NULL}, - NULL, - NULL, - NULL}; + hb4_init, hb4_close, hb4_reset, + { NULL }, NULL, NULL, + NULL +}; diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index e2adf3657..a3c283591 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -213,13 +213,12 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) return; /*Read-only addresses*/ - if ((addr < 4) || ((addr >= 5) && (addr < 7)) || ((addr >= 8) && (addr < 0xd)) || - ((addr >= 0xe) && (addr < 0x12)) || ((addr >= 0x14) && (addr < 0x50)) || - (addr == 0x69) || ((addr >= 0x79) && (addr < 0x7e)) || - ((addr >= 0x81) && (addr < 0x84)) || ((addr >= 0x85) && (addr < 0x88)) || - ((addr >= 0x8c) && (addr < 0xa8)) || ((addr >= 0xaa) && (addr < 0xac)) || - ((addr >= 0xad) && (addr < 0xf0)) || ((addr >= 0xf8) && (addr < 0xfc)) || - (addr == 0xfd)) + if ((addr < 4) || ((addr > 5) && (addr < 7)) || ((addr >= 8) && (addr < 0xd)) || + ((addr >= 0xe) && (addr != 0x0f) && (addr < 0x12)) || ((addr >= 0x14) && (addr < 0x50)) || + ((addr > 0x7a) && (addr < 0x7e)) || ((addr >= 0x81) && (addr < 0x84)) || + ((addr >= 0x85) && (addr < 0x88)) || ((addr >= 0x8c) && (addr < 0xa8)) || + ((addr >= 0xaa) && (addr < 0xac)) || ((addr > 0xad) && (addr < 0xf0)) || + ((addr >= 0xf8) && (addr < 0xfc))) return; if (((addr == 0x78) || (addr >= 0xad)) && (dev->id == VIA_597)) return; diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index df3b26a8e..3829e337c 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -46,7 +46,7 @@ #include <86box/hdc_ide_sff8038i.h> #include <86box/usb.h> #include <86box/machine.h> -#include <86box/smbus_piix4.h> +#include <86box/smbus.h> #include <86box/chipset.h> #include <86box/sio.h> #include <86box/hwm.h> @@ -172,7 +172,7 @@ pipc_trap_io_pact(int size, uint16_t addr, uint8_t write, uint8_t val, void *pri *(trap->sts_reg) |= trap->mask; trap->dev->acpi->regs.glbsts |= 0x0001; if (trap->dev->acpi->regs.glben & 0x0001) - acpi_raise_smi(trap->dev->acpi); + acpi_raise_smi(trap->dev->acpi, 1); } } @@ -184,7 +184,7 @@ pipc_io_trap_glb(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv if (*(trap->en_reg) & trap->mask) { *(trap->sts_reg) |= trap->mask; - acpi_raise_smi(trap->dev->acpi); + acpi_raise_smi(trap->dev->acpi, 1); } } diff --git a/src/chipset/via_vt82c49x.c b/src/chipset/via_vt82c49x.c index 712ad8f5a..20824b006 100644 --- a/src/chipset/via_vt82c49x.c +++ b/src/chipset/via_vt82c49x.c @@ -133,9 +133,9 @@ vt82c49x_recalc(vt82c49x_t *dev) state = (dev->regs[0x33] & 0x10) ? MEM_WRITE_ROMCS : MEM_WRITE_EXTERNAL; if ((dev->regs[0x32]) & (1 << (bit + 1))) - state = MEM_READ_INTERNAL; + state |= MEM_READ_INTERNAL; else - state = (dev->regs[0x33] & 0x10) ? MEM_READ_ROMCS : MEM_READ_EXTERNAL; + state |= (dev->regs[0x33] & 0x10) ? MEM_READ_ROMCS : MEM_READ_EXTERNAL; } else if ((base >= 0xe8000) && (base <= 0xeffff)) { if (dev->regs[0x40] & 0x20) state = MEM_WRITE_DISABLED; diff --git a/src/chipset/vl82c480.c b/src/chipset/vl82c480.c index 634cb948e..f5cc06d6a 100644 --- a/src/chipset/vl82c480.c +++ b/src/chipset/vl82c480.c @@ -98,9 +98,18 @@ vl82c480_write(uint16_t addr, uint8_t val, void *p) default: dev->regs[dev->idx] = val; break; + case 0x04: + if (dev->regs[0x00] == 0x98) + dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x08) | (val & 0xf7); + else + dev->regs[dev->idx] = val; + break; case 0x05: dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x10) | (val & 0xef); break; + case 0x07: + dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x40) | (val & 0xbf); + break; case 0x0d: case 0x0e: case 0x0f: case 0x10: case 0x11: case 0x12: dev->regs[dev->idx] = val; @@ -163,11 +172,13 @@ vl82c480_init(const device_t *info) vl82c480_t *dev = (vl82c480_t *)malloc(sizeof(vl82c480_t)); memset(dev, 0, sizeof(vl82c480_t)); - dev->regs[0x00] = 0x90; + dev->regs[0x00] = info->local; dev->regs[0x01] = 0xff; dev->regs[0x02] = 0x8a; dev->regs[0x03] = 0x88; dev->regs[0x06] = 0x1b; + if (info->local == 0x98) + dev->regs[0x07] = 0x21; dev->regs[0x08] = 0x38; io_sethandler(0x00ec, 0x0004, vl82c480_read, NULL, NULL, vl82c480_write, NULL, NULL, dev); @@ -181,7 +192,17 @@ vl82c480_init(const device_t *info) const device_t vl82c480_device = { "VLSI VL82c480", 0, - 0, + 0x90, + vl82c480_init, vl82c480_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t vl82c486_device = { + "VLSI VL82c486", + 0, + 0x98, vl82c480_init, vl82c480_close, NULL, { NULL }, NULL, NULL, NULL diff --git a/src/config.c b/src/config.c index 5ca00f360..dd62a2492 100644 --- a/src/config.c +++ b/src/config.c @@ -629,20 +629,26 @@ load_machine(void) machine = machine_get_machine_from_internal_name("pc916sx"); else if (! strcmp(p, "cbm_sl386sx16")) machine = machine_get_machine_from_internal_name("cmdsl386sx16"); - else if (! strcmp(p, "olivetti_m300_08")) - machine = machine_get_machine_from_internal_name("m30008"); - else if (! strcmp(p, "olivetti_m300_15")) - machine = machine_get_machine_from_internal_name("m30015"); else if (! strcmp(p, "cbm_sl386sx25")) machine = machine_get_machine_from_internal_name("cmdsl386sx25"); else if (! strcmp(p, "award386dx")) /* ...merged machines... */ - machine = machine_get_machine_from_internal_name("award486"); + machine = machine_get_machine_from_internal_name("award495"); else if (! strcmp(p, "ami386dx")) - machine = machine_get_machine_from_internal_name("ami486"); + machine = machine_get_machine_from_internal_name("ami495"); else if (! strcmp(p, "mr386dx")) - machine = machine_get_machine_from_internal_name("mr486"); + machine = machine_get_machine_from_internal_name("mr495"); + else if (! strcmp(p, "award486")) + machine = machine_get_machine_from_internal_name("award495"); + else if (! strcmp(p, "ami486")) + machine = machine_get_machine_from_internal_name("ami495"); + else if (! strcmp(p, "mr486")) + machine = machine_get_machine_from_internal_name("mr495"); else if (! strcmp(p, "fw6400gx_s1")) machine = machine_get_machine_from_internal_name("fw6400gx"); + else if (! strcmp(p, "p54vl")) + machine = machine_get_machine_from_internal_name("p5vl"); + else if (! strcmp(p, "chariot")) + machine = machine_get_machine_from_internal_name("fmb"); else if (! strcmp(p, "president")) { /* ...and removed machines */ machine = machine_get_machine_from_internal_name("mb500n"); migrate_from = NULL; @@ -1039,12 +1045,12 @@ load_ports(void) char temp[512]; int c, d; - for (c = 0; c < 4; c++) { + for (c = 0; c < SERIAL_MAX; c++) { sprintf(temp, "serial%d_enabled", c + 1); serial_enabled[c] = !!config_get_int(cat, temp, (c >= 2) ? 0 : 1); } - for (c = 0; c < 3; c++) { + for (c = 0; c < PARALLEL_MAX; c++) { sprintf(temp, "lpt%d_enabled", c + 1); lpt_ports[c].enabled = !!config_get_int(cat, temp, (c == 0) ? 1 : 0); @@ -1056,7 +1062,7 @@ load_ports(void) /* Legacy config compatibility. */ d = config_get_int(cat, "lpt_enabled", 2); if (d < 2) { - for (c = 0; c < 3; c++) + for (c = 0; c < PARALLEL_MAX; c++) lpt_ports[c].enabled = d; } config_delete_var(cat, "lpt_enabled"); @@ -2509,7 +2515,7 @@ save_ports(void) char temp[512]; int c, d; - for (c = 0; c < 4; c++) { + for (c = 0; c < SERIAL_MAX; c++) { sprintf(temp, "serial%d_enabled", c + 1); if (((c < 2) && serial_enabled[c]) || ((c >= 2) && !serial_enabled[c])) config_delete_var(cat, temp); @@ -2517,7 +2523,7 @@ save_ports(void) config_set_int(cat, temp, serial_enabled[c]); } - for (c = 0; c < 3; c++) { + for (c = 0; c < PARALLEL_MAX; c++) { sprintf(temp, "lpt%d_enabled", c + 1); d = (c == 0) ? 1 : 0; if (lpt_ports[c].enabled == d) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 467ea01eb..4eb9530ba 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -591,7 +591,7 @@ smram_restore_state_p5(uint32_t *saved_state) smm_seg_load(&cpu_state.seg_gs); if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION) - smbase = saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET] & 0x00ffffff; + smbase = saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET]; /* Am486/5x86 stuff */ if (!is_pentium) { diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index 5b472298b..8d2b9edf9 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -148,9 +148,9 @@ static int fopcode; static int ILLEGAL(uint32_t fetchdat) { + pclog("[%04X:%08X] Illegal instruction %08X (%02X)\n", CS, cpu_state.pc, fetchdat, fopcode); cpu_state.pc = cpu_state.oldpc; - pclog("Illegal instruction %08X (%02X)\n", fetchdat, fopcode); x86illegal(); return 0; } @@ -457,7 +457,7 @@ const OpFn OP_TABLE(386_0f)[1024] = /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -479,7 +479,7 @@ const OpFn OP_TABLE(386_0f)[1024] = /*32-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a16, opMOV_l_r_a16, opMOV_r_b_a16, opMOV_r_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -501,7 +501,7 @@ const OpFn OP_TABLE(386_0f)[1024] = /*16-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a32, opMOV_w_r_a32, opMOV_r_b_a32, opMOV_r_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -523,7 +523,7 @@ const OpFn OP_TABLE(386_0f)[1024] = /*32-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a32, opMOV_l_r_a32, opMOV_r_b_a32, opMOV_r_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -548,7 +548,7 @@ const OpFn OP_TABLE(486_0f)[1024] = /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -570,7 +570,7 @@ const OpFn OP_TABLE(486_0f)[1024] = /*32-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a16, opMOV_l_r_a16, opMOV_r_b_a16, opMOV_r_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -592,7 +592,7 @@ const OpFn OP_TABLE(486_0f)[1024] = /*16-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a32, opMOV_w_r_a32, opMOV_r_b_a32, opMOV_r_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -614,7 +614,7 @@ const OpFn OP_TABLE(486_0f)[1024] = /*32-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a32, opMOV_l_r_a32, opMOV_r_b_a32, opMOV_r_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -821,7 +821,7 @@ const OpFn OP_TABLE(ibm486_0f)[1024] = /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, ILLEGAL, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -843,7 +843,7 @@ const OpFn OP_TABLE(ibm486_0f)[1024] = /*32-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a16, opMOV_l_r_a16, opMOV_r_b_a16, opMOV_r_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, ILLEGAL, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -865,7 +865,7 @@ const OpFn OP_TABLE(ibm486_0f)[1024] = /*16-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a32, opMOV_w_r_a32, opMOV_r_b_a32, opMOV_r_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, ILLEGAL, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -887,7 +887,7 @@ const OpFn OP_TABLE(ibm486_0f)[1024] = /*32-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a32, opMOV_l_r_a32, opMOV_r_b_a32, opMOV_r_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, ILLEGAL, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1094,7 +1094,7 @@ const OpFn OP_TABLE(pentium_0f)[1024] = /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1116,7 +1116,7 @@ const OpFn OP_TABLE(pentium_0f)[1024] = /*32-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a16, opMOV_l_r_a16, opMOV_r_b_a16, opMOV_r_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1138,7 +1138,7 @@ const OpFn OP_TABLE(pentium_0f)[1024] = /*16-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a32, opMOV_w_r_a32, opMOV_r_b_a32, opMOV_r_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1160,7 +1160,7 @@ const OpFn OP_TABLE(pentium_0f)[1024] = /*32-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ opMOV_b_r_a32, opMOV_l_r_a32, opMOV_r_b_a32, opMOV_r_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt index dd91a5ec1..ab27b77c0 100644 --- a/src/cpu/CMakeLists.txt +++ b/src/cpu/CMakeLists.txt @@ -24,10 +24,6 @@ if(CYRIX_6X86) target_compile_definitions(cpu PRIVATE USE_CYRIX_6X86) endif() -if(M6117) - target_compile_definitions(cpu PRIVATE USE_M6117) -endif() - if(DYNAREC) add_library(cgt OBJECT codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_k6.c diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 1664576fb..14d7a9b63 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -124,6 +124,10 @@ int isa_cycles, cpu_inited, timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate, timing_misaligned; uint32_t cpu_features, cpu_fast_off_flags; +uint32_t _tr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +uint32_t cache_index = 0; +uint8_t _cache[2048]; + uint64_t cpu_CR4_mask, tsc = 0; uint64_t pmc[2] = {0, 0}; @@ -2290,6 +2294,7 @@ amd_k_invalid_rdmsr: EDX = tsc >> 32; break; } + pclog("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); break; case CPU_PENTIUMPRO: @@ -2695,6 +2700,7 @@ amd_k_invalid_wrmsr: case CPU_CxGX1: case CPU_Cx6x86MX: #endif + pclog("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); switch (ECX) { case 0x10: tsc = EAX | ((uint64_t)EDX << 32); diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index b28934951..9beac3fab 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -542,6 +542,9 @@ extern uint64_t amd_efer, star; #define msw cpu_state.CR0.w extern uint32_t cr2, cr3, cr4; extern uint32_t dr[8]; +extern uint32_t _tr[8]; +extern uint32_t cache_index; +extern uint8_t _cache[2048]; /*Segments - @@ -656,6 +659,7 @@ extern void resetx86(void); extern void refreshread(void); extern void resetreadlookup(void); extern void softresetx86(void); +extern void hardresetx86(void); extern void x86_int(int num); extern void x86_int_sw(int num); extern int x86_int_sw_rm(int num); diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index b29e20ce0..b94f429e6 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -186,7 +186,6 @@ const cpu_family_t cpu_families[] = { {"", 0} } }, -#if defined(DEV_BRANCH) && defined(USE_M6117) { .package = CPU_PKG_M6117, .manufacturer = "ALi", @@ -198,7 +197,6 @@ const cpu_family_t cpu_families[] = { {"", 0} } }, -#endif { .package = CPU_PKG_386SLC_IBM, .manufacturer = "IBM", diff --git a/src/cpu/x86.c b/src/cpu/x86.c index e652c5d27..55ef45000 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -26,6 +26,8 @@ #include "cpu.h" #include "x86.h" #include <86box/machine.h> +#include <86box/device.h> +#include <86box/dma.h> #include <86box/io.h> #include <86box/mem.h> #include <86box/rom.h> @@ -239,8 +241,13 @@ reset_common(int hard) leave_smm(); /* Needed for the ALi M1533. */ - if (soft_reset_pci && !hard) + if (is486 && (hard || soft_reset_pci)) { pci_reset(); + if (!hard && soft_reset_pci) { + dma_reset(); + device_reset_all(); + } + } use32 = 0; cpu_cur_status = 0; @@ -299,7 +306,8 @@ reset_common(int hard) smi_block = 0; if (hard) { - smbase = is_am486dxl ? 0x00060000 : 0x00030000; + if (is486) + smbase = is_am486dxl ? 0x00060000 : 0x00030000; ppi_reset(); } in_sys = 0; @@ -307,8 +315,12 @@ reset_common(int hard) shadowbios = shadowbios_write = 0; alt_access = cpu_end_block_after_ins = 0; - if (hard) + if (hard) { reset_on_hlt = hlt_reset_pending = 0; + cache_index = 0; + memset(_tr, 0x00, sizeof(_tr)); + memset(_cache, 0x00, sizeof(_cache)); + } if (!is286) reset_808x(hard); @@ -334,3 +346,21 @@ softresetx86(void) reset_common(0); } + + +/* Actual hard reset. */ +void +hardresetx86(void) +{ + dma_reset(); + device_reset_all(); + + cpu_alt_reset = 0; + + mem_a20_alt = 0; + mem_a20_recalc(); + + flushmmucache(); + + resetx86(); +} diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index a6e7e9193..e630c685b 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -607,6 +607,8 @@ static int opF7_l_a32(uint32_t fetchdat) static int opHLT(uint32_t fetchdat) { + pclog("HLT: CS = %04X, DS = %04X, ES = %04X, SS = %04X, IP = %04X\n", CS, DS, ES, SS, cpu_state.pc); + if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { x86gpf(NULL,0); diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index 17f51b971..28504890c 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -256,54 +256,113 @@ static int opMOV_DRx_r_a32(uint32_t fetchdat) return 0; } +static void opMOV_r_TRx(void) +{ + uint32_t base; + + base = _tr[4] & 0xfffff800; + switch (cpu_reg) { + case 3: + pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]); + _tr[3] = *(uint32_t *) &(_cache[cache_index]); + cache_index = (cache_index + 4) & 0xf; + break; + } + cpu_state.regs[cpu_rm].l = _tr[cpu_reg]; + CLOCK_CYCLES(6); +} static int opMOV_r_TRx_a16(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))) { x86gpf(NULL, 0); return 1; } fetch_ea_16(fetchdat); - cpu_state.regs[cpu_rm].l = 0; - CLOCK_CYCLES(6); + opMOV_r_TRx(); PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); return 0; } static int opMOV_r_TRx_a32(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))) { x86gpf(NULL, 0); return 1; } fetch_ea_32(fetchdat); - cpu_state.regs[cpu_rm].l = 0; - CLOCK_CYCLES(6); + opMOV_r_TRx(); PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); return 0; } +static void opMOV_TRx_r(void) +{ + uint32_t base; + int i, ctl; + + _tr[cpu_reg] = cpu_state.regs[cpu_rm].l; + base = _tr[4] & 0xfffff800; + ctl = _tr[5] & 3; + switch (cpu_reg) { + case 3: + pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]); + *(uint32_t *) &(_cache[cache_index]) = _tr[3]; + cache_index = (cache_index + 4) & 0xf; + break; + case 4: + if (!(cr0 & 1) && !(_tr[5] & (1 << 19))) + pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16); + break; + case 5: + pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0); + if (!(_tr[5] & (1 << 19))) { + switch(ctl) { + case 0: + pclog(" Cache fill or read...\n", base); + break; + case 1: + base += (_tr[5] & 0x7f0); + pclog(" Writing 16 bytes to %08X...\n", base); + for (i = 0; i < 16; i += 4) + mem_writel_phys(base + i, *(uint32_t *) &(_cache[i])); + break; + case 2: + base += (_tr[5] & 0x7f0); + pclog(" Reading 16 bytes from %08X...\n", base); + for (i = 0; i < 16; i += 4) + *(uint32_t *) &(_cache[i]) = mem_readl_phys(base + i); + break; + case 3: + pclog(" Cache invalidate/flush...\n", base); + break; + } + } + break; + } + CLOCK_CYCLES(6); +} static int opMOV_TRx_r_a16(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))) { x86gpf(NULL, 0); return 1; } fetch_ea_16(fetchdat); - CLOCK_CYCLES(6); + opMOV_TRx_r(); PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); return 0; } static int opMOV_TRx_r_a32(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))) { x86gpf(NULL, 0); return 1; } - fetch_ea_16(fetchdat); - CLOCK_CYCLES(6); + fetch_ea_32(fetchdat); + opMOV_TRx_r(); PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); return 0; } diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 8f5798ddb..bd1d1b864 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -942,173 +942,173 @@ void loadcscall(uint16_t seg) segdat[2] = (segdat[2] & ~(3 << (5+8))) | (CPL << (5+8)); } else /* On non-conforming segments, set RPL = CPL */ seg = (seg & 0xfffc) | CPL; - CS = seg; - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif #ifdef ENABLE_X86SEG_LOG - x86seg_log("Complete\n"); + x86seg_log("Complete\n"); #endif - cycles -= timing_call_pm; - } else { - type = segdat[2] & 0x0f00; - x86seg_log("Type %03X\n", type); - switch (type) { - case 0x0400: /* Call gate */ - case 0x0c00: /* 386 Call gate */ - x86seg_log("Callgate %08X\n", cpu_state.pc); - cgate32 = (type & 0x0800); - cgate16 = !cgate32; + cycles -= timing_call_pm; + } else { + type = segdat[2] & 0x0f00; + x86seg_log("Type %03X\n", type); + switch (type) { + case 0x0400: /* Call gate */ + case 0x0c00: /* 386 Call gate */ + x86seg_log("Callgate %08X\n", cpu_state.pc); + cgate32 = (type & 0x0800); + cgate16 = !cgate32; #ifndef USE_NEW_DYNAREC - oldcs = CS; + oldcs = CS; #endif - count = segdat[2] & 0x001f; - if (DPL < CPL) { - x86gpf("loadcscall(): ex DPL < CPL",seg & 0xfffc); - return; - } - if (DPL < (seg & 0x0003)) { - x86gpf("loadcscall(): ex DPL < RPL", seg & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - x86np("Call gate not present", seg & 0xfffc); - return; - } - seg2 = segdat[1]; + count = segdat[2] & 0x001f; + if (DPL < CPL) { + x86gpf("loadcscall(): ex DPL < CPL",seg & 0xfffc); + return; + } + if (DPL < (seg & 0x0003)) { + x86gpf("loadcscall(): ex DPL < RPL", seg & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Call gate not present", seg & 0xfffc); + return; + } + seg2 = segdat[1]; - x86seg_log("New address : %04X:%08X\n", seg2, newpc); + x86seg_log("New address : %04X:%08X\n", seg2, newpc); - if (!(seg2 & 0xfffc)) { - x86gpf("loadcscall(): ex selector is NULL", 0); - return; - } - addr = seg2 & 0xfff8; - dt = (seg2 & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("loadcscall(): ex Selector > DT limit", seg2 & 0xfff8); - return; - } - addr += dt->base; - read_descriptor(addr, segdat, segdat32, 1); - if (cpu_state.abrt) - return; + if (!(seg2 & 0xfffc)) { + x86gpf("loadcscall(): ex selector is NULL", 0); + return; + } + addr = seg2 & 0xfff8; + dt = (seg2 & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("loadcscall(): ex Selector > DT limit", seg2 & 0xfff8); + return; + } + addr += dt->base; + read_descriptor(addr, segdat, segdat32, 1); + if (cpu_state.abrt) + return; x86seg_log("Code seg2 call - %04X - %04X %04X %04X\n", seg2, segdat[0], segdat[1], segdat[2]); - if (DPL > CPL) { - x86gpf("loadcscall(): ex DPL > CPL", seg2 & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - x86seg_log("Call gate CS not present %04X\n", seg2); - x86np("Call gate CS not present", seg2 & 0xfffc); - return; - } + if (DPL > CPL) { + x86gpf("loadcscall(): ex DPL > CPL", seg2 & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + x86seg_log("Call gate CS not present %04X\n", seg2); + x86np("Call gate CS not present", seg2 & 0xfffc); + return; + } - switch (segdat[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming code */ - if (DPL < CPL) { + switch (segdat[2] & 0x1f00) { + case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming code */ + if (DPL < CPL) { #ifdef USE_NEW_DYNAREC - uint16_t oldcs = CS; + uint16_t oldcs = CS; #endif - oaddr = addr; - /* Load new stack */ - oldss = SS; - oldsp = oldsp2 = ESP; - cpl_override = 1; - if (tr.access & 8) { - addr = 4 + tr.base + (DPL << 3); - newss = readmemw(0, addr + 4); - if (cpu_16bitbus) { - newsp = readmemw(0, addr); - newsp |= (readmemw(0, addr + 2) << 16); - } else - newsp = readmeml(0, addr); - } else { - addr = 2 + tr.base + (DPL * 4); - newss = readmemw(0, addr + 2); + oaddr = addr; + /* Load new stack */ + oldss = SS; + oldsp = oldsp2 = ESP; + cpl_override = 1; + if (tr.access & 8) { + addr = 4 + tr.base + (DPL << 3); + newss = readmemw(0, addr + 4); + if (cpu_16bitbus) { newsp = readmemw(0, addr); - } - cpl_override = 0; - if (cpu_state.abrt) - return; - x86seg_log("New stack %04X:%08X\n", newss, newsp); - if (!(newss & 0xfffc)) { - x86ts(NULL, newss & 0xfffc); - return; - } - addr = newss & 0xfff8; - dt = (newss & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - fatal("Bigger than DT limit %04X %08X %04X CSC SS\n", newss, addr, dt->limit); - x86ts(NULL, newss & ~3); - return; - } - addr += dt->base; - x86seg_log("Read stack seg\n"); - read_descriptor(addr, segdat2, segdat232, 1); - if (cpu_state.abrt) - return; - x86seg_log("Read stack seg done!\n"); - if (((newss & 0x0003) != DPL) || (DPL2 != DPL)) { - x86ts(NULL, newss & 0xfffc); - return; - } - if ((segdat2[2] & 0x1a00) != 0x1200) { - x86ts("Call gate loading SS unknown type", newss & 0xfffc); - return; - } - if (!(segdat2[2] & 0x8000)) { - x86ss("Call gate loading SS not present", newss & 0xfffc); - return; - } - if (!stack32) - oldsp &= 0xffff; - SS = newss; - set_stack32((segdat2[3] & 0x0040) ? 1 : 0); - if (stack32) - ESP = newsp; - else - SP = newsp; + newsp |= (readmemw(0, addr + 2) << 16); + } else + newsp = readmeml(0, addr); + } else { + addr = 2 + tr.base + (DPL * 4); + newss = readmemw(0, addr + 2); + newsp = readmemw(0, addr); + } + cpl_override = 0; + if (cpu_state.abrt) + return; + x86seg_log("New stack %04X:%08X\n", newss, newsp); + if (!(newss & 0xfffc)) { + x86ts(NULL, newss & 0xfffc); + return; + } + addr = newss & 0xfff8; + dt = (newss & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + fatal("Bigger than DT limit %04X %08X %04X CSC SS\n", newss, addr, dt->limit); + x86ts(NULL, newss & ~3); + return; + } + addr += dt->base; + x86seg_log("Read stack seg\n"); + read_descriptor(addr, segdat2, segdat232, 1); + if (cpu_state.abrt) + return; + x86seg_log("Read stack seg done!\n"); + if (((newss & 0x0003) != DPL) || (DPL2 != DPL)) { + x86ts(NULL, newss & 0xfffc); + return; + } + if ((segdat2[2] & 0x1a00) != 0x1200) { + x86ts("Call gate loading SS unknown type", newss & 0xfffc); + return; + } + if (!(segdat2[2] & 0x8000)) { + x86ss("Call gate loading SS not present", newss & 0xfffc); + return; + } + if (!stack32) + oldsp &= 0xffff; + SS = newss; + set_stack32((segdat2[3] & 0x0040) ? 1 : 0); + if (stack32) + ESP = newsp; + else + SP = newsp; - do_seg_load(&cpu_state.seg_ss, segdat2); + do_seg_load(&cpu_state.seg_ss, segdat2); - x86seg_log("Set access 1\n"); - cpl_override = 1; - writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + x86seg_log("Set access 1\n"); + cpl_override = 1; + writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - CS = seg2; - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + CS = seg2; + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3] & 0x0040); - cpu_state.pc = newpc; + set_use32(segdat[3] & 0x0040); + cpu_state.pc = newpc; - x86seg_log("Set access 2\n"); + x86seg_log("Set access 2\n"); - cpl_override = 1; - writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + cpl_override = 1; + writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - x86seg_log("Type %04X\n", type); - if (type == 0x0c00) { - PUSHL(oldss); - PUSHL(oldsp2); - if (cpu_state.abrt) { - SS = oldss; - ESP = oldsp2; + x86seg_log("Type %04X\n", type); + if (type == 0x0c00) { + PUSHL(oldss); + PUSHL(oldsp2); + if (cpu_state.abrt) { + SS = oldss; + ESP = oldsp2; #ifdef USE_NEW_DYNAREC - CS = oldcs; + CS = oldcs; #endif - return; + return; } if (count) { while (count--) { diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index 7e78d752f..cbb312aa1 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -15,9 +15,9 @@ add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c hwm_vt82c686.c ibm_5161.c isamem.c isartc.c ../lpt.c pci_bridge.c - postcard.c serial.c vpc2007.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c - smbus_piix4.c keyboard.c keyboard_xt.c keyboard_at.c mouse.c mouse_bus.c - mouse_serial.c mouse_ps2.c phoenix_486_jumper.c) + postcard.c serial.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c + smbus_piix4.c smbus_ali7101.c keyboard.c keyboard_xt.c keyboard_at.c + mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c phoenix_486_jumper.c) if(LASERXT) target_compile_definitions(dev PRIVATE USE_LASERXT) diff --git a/src/device/hwm_gl518sm.c b/src/device/hwm_gl518sm.c index c340ce59c..9c8eae920 100644 --- a/src/device/hwm_gl518sm.c +++ b/src/device/hwm_gl518sm.c @@ -41,7 +41,7 @@ typedef struct { uint16_t regs[32]; uint8_t addr_register: 5; - uint8_t i2c_addr: 7, i2c_state: 2; + uint8_t i2c_addr: 7, i2c_state: 2, i2c_enabled: 1; } gl518sm_t; @@ -78,12 +78,14 @@ gl518sm_remap(gl518sm_t *dev, uint8_t addr) { gl518sm_log("GL518SM: remapping to SMBus %02Xh\n", addr); - i2c_removehandler(i2c_smbus, dev->i2c_addr, 1, gl518sm_i2c_start, gl518sm_i2c_read, gl518sm_i2c_write, NULL, dev); + if (dev->i2c_enabled) + i2c_removehandler(i2c_smbus, dev->i2c_addr, 1, gl518sm_i2c_start, gl518sm_i2c_read, gl518sm_i2c_write, NULL, dev); if (addr < 0x80) i2c_sethandler(i2c_smbus, addr, 1, gl518sm_i2c_start, gl518sm_i2c_read, gl518sm_i2c_write, NULL, dev); - dev->i2c_addr = addr; + dev->i2c_addr = addr & 0x7f; + dev->i2c_enabled = !(addr & 0x80); } @@ -244,6 +246,8 @@ gl518sm_reset(gl518sm_t *dev) dev->regs[0x0b] = 0xdac5; dev->regs[0x0c] = 0xdac5; dev->regs[0x0f] = 0xf8; + + gl518sm_remap(dev, dev->i2c_addr | (dev->i2c_enabled ? 0x00 : 0x80)); } diff --git a/src/device/hwm_lm75.c b/src/device/hwm_lm75.c index 9faf73326..b6988232b 100644 --- a/src/device/hwm_lm75.c +++ b/src/device/hwm_lm75.c @@ -187,13 +187,14 @@ lm75_remap(lm75_t *dev, uint8_t addr) { lm75_log("LM75: remapping to SMBus %02Xh\n", addr); - if (dev->i2c_addr < 0x80) + if (dev->i2c_enabled) i2c_removehandler(i2c_smbus, dev->i2c_addr, 1, lm75_i2c_start, lm75_i2c_read, lm75_i2c_write, NULL, dev); if (addr < 0x80) i2c_sethandler(i2c_smbus, addr, 1, lm75_i2c_start, lm75_i2c_read, lm75_i2c_write, NULL, dev); - dev->i2c_addr = addr; + dev->i2c_addr = addr & 0x7f; + dev->i2c_enabled = !(addr & 0x80); } @@ -203,7 +204,7 @@ lm75_reset(lm75_t *dev) dev->regs[0x3] = 0x4b; dev->regs[0x5] = 0x50; - lm75_remap(dev, dev->local & 0x7f); + lm75_remap(dev, dev->i2c_addr | (dev->i2c_enabled ? 0x00 : 0x80)); } @@ -231,6 +232,9 @@ lm75_init(const device_t *info) hwm_values.temperatures[dev->local >> 8] = 30; dev->values = &hwm_values; + dev->i2c_addr = dev->local & 0x7f; + dev->i2c_enabled = 1; + lm75_reset(dev); return dev; diff --git a/src/device/hwm_lm78.c b/src/device/hwm_lm78.c index b9ed2e699..f15f1ee7c 100644 --- a/src/device/hwm_lm78.c +++ b/src/device/hwm_lm78.c @@ -37,6 +37,7 @@ #define LM78_AS99127F_REV1 0x040000 #define LM78_AS99127F_REV2 0x080000 #define LM78_W83782D 0x100000 +#define LM78_P5A 0x200000 #define LM78_AS99127F (LM78_AS99127F_REV1 | LM78_AS99127F_REV2) /* mask covering both _REV1 and _REV2 */ #define LM78_WINBOND (LM78_W83781D | LM78_AS99127F | LM78_W83782D) /* mask covering all Winbond variants */ #define LM78_WINBOND_VENDOR_ID ((dev->local & LM78_AS99127F_REV1) ? 0x12c3 : 0x5ca3) @@ -72,7 +73,7 @@ typedef struct { }; uint8_t addr_register, data_register; - uint8_t i2c_addr: 7, i2c_state: 1; + uint8_t i2c_addr: 7, i2c_state: 1, i2c_enabled: 1; } lm78_t; @@ -258,8 +259,13 @@ lm78_reset(void *priv) dev->regs[0x46] = 0x40; dev->regs[0x47] = 0x50; if (dev->local & LM78_I2C) { - if (!initialization) /* don't reset main I2C address if the reset was triggered by the INITIALIZATION bit */ - dev->i2c_addr = 0x2d; + if (!initialization) { /* don't reset main I2C address if the reset was triggered by the INITIALIZATION bit */ + if (dev->local & LM78_P5A) + dev->i2c_addr = 0x77; + else + dev->i2c_addr = 0x2d; + dev->i2c_enabled = 1; + } dev->regs[0x48] = dev->i2c_addr; if (dev->local & LM78_WINBOND) dev->regs[0x4a] = 0x01; @@ -315,7 +321,7 @@ lm78_reset(void *priv) dev->regs[0x49] = 0x40; } - lm78_remap(dev, dev->i2c_addr); + lm78_remap(dev, dev->i2c_addr | (dev->i2c_enabled ? 0x00 : 0x80)); } @@ -668,12 +674,14 @@ lm78_remap(lm78_t *dev, uint8_t addr) lm78_log("LM78: remapping to SMBus %02Xh\n", addr); - i2c_removehandler(i2c_smbus, dev->i2c_addr, 1, lm78_i2c_start, lm78_i2c_read, lm78_i2c_write, NULL, dev); + if (dev->i2c_enabled) + i2c_removehandler(i2c_smbus, dev->i2c_addr, 1, lm78_i2c_start, lm78_i2c_read, lm78_i2c_write, NULL, dev); if (addr < 0x80) i2c_sethandler(i2c_smbus, addr, 1, lm78_i2c_start, lm78_i2c_read, lm78_i2c_write, NULL, dev); - dev->i2c_addr = addr; + dev->i2c_addr = addr & 0x7f; + dev->i2c_enabled = !(addr & 0x80); if (dev->local & LM78_AS99127F) { /* Store our handle on the primary LM75 device to ensure reads/writes @@ -798,6 +806,17 @@ const device_t w83781d_device = { }; +/* Winbond W83781D on ISA and SMBus. */ +const device_t w83781d_p5a_device = { + "Winbond W83781D Hardware Monitor (ASUS P5A)", + DEVICE_ISA, + 0x290 | LM78_I2C | LM78_W83781D | LM78_P5A, + lm78_init, lm78_close, lm78_reset, + { NULL }, NULL, NULL, + NULL +}; + + /* The AS99127F is an ASIC manufactured by Holtek for ASUS, containing an I2C-only W83781D clone with additional voltages, GPIOs and fan control. */ const device_t as99127f_device = { diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 1c44880a3..2969ca82d 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -57,8 +57,6 @@ #define STAT_IFULL 0x02 #define STAT_OFULL 0x01 -#define PS2_REFRESH_TIME (16 * TIMER_USEC) - #define RESET_DELAY_TIME (100 * 10) /* 600ms */ #define CCB_UNUSED 0x80 @@ -97,8 +95,8 @@ typedef struct { uint8_t command, status, old_status, out, old_out, secr_phase, mem_addr, input_port, output_port, old_output_port, - key_command, output_locked, ami_stat, want60, - wantirq, key_wantdata, refresh, first_write; + key_command, output_locked, ami_stat, want60, + wantirq, key_wantdata, ami_flags, first_write; uint8_t mem[0x100]; @@ -108,7 +106,7 @@ typedef struct { uint32_t flags; - pc_timer_t refresh_time, pulse_cb; + pc_timer_t pulse_cb; uint8_t (*write60_ven)(void *p, uint8_t val); uint8_t (*write64_ven)(void *p, uint8_t val); @@ -1320,6 +1318,7 @@ write60_ami(void *priv, uint8_t val) case 0xcb: /* set keyboard mode */ kbd_log("ATkbc: AMI - set keyboard mode\n"); + dev->ami_flags = val; return 0; } @@ -1704,11 +1703,6 @@ kbd_write(uint16_t port, uint8_t val, void *priv) uint8_t mask, kbc_ven = 0x0; kbc_ven = dev->flags & KBC_VEN_MASK; - if ((kbc_ven == KBC_VEN_XI8088) && (port == 0x63)) - port = 0x61; - - kbd_log((port == 0x61) ? "" : "ATkbc: write(%04X, %02X)\n", port, val); - switch (port) { case 0x60: dev->status &= ~STAT_CD; @@ -1970,20 +1964,6 @@ kbd_write(uint16_t port, uint8_t val, void *priv) } break; - case 0x61: - ppi.pb = (ppi.pb & 0x10) | (val & 0x0f); - - speaker_update(); - speaker_gated = val & 1; - speaker_enable = val & 2; - if (speaker_enable) - was_speaker_enable = 1; - pit_ctr_set_gate(&pit->counters[2], val & 1); - - if (kbc_ven == KBC_VEN_XI8088) - xi8088_turbo_set(!!(val & 0x04)); - break; - case 0x64: /* Controller command. */ dev->want60 = 0; @@ -2063,7 +2043,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0xca: /* read keyboard mode */ kbd_log("ATkbc: AMI - read keyboard mode\n"); - add_data(dev, ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 0x01 : 0x00); /*ISA mode*/ + add_data(dev, dev->ami_flags); break; case 0xcb: /* set keyboard mode */ @@ -2133,9 +2113,6 @@ kbd_read(uint16_t port, void *priv) if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) cycles -= ISA_CYCLES(8); - if ((kbc_ven == KBC_VEN_XI8088) && (port == 0x63)) - port = 0x61; - switch (port) { case 0x60: ret = dev->out; @@ -2144,56 +2121,6 @@ kbd_read(uint16_t port, void *priv) dev->last_irq = 0; break; - case 0x61: - ret = ppi.pb & ~0xe0; - if (ppispeakon) - ret |= 0x20; - if ((dev->flags & KBC_TYPE_MASK) > KBC_TYPE_PS2_NOREF) { - if (dev->refresh) - ret |= 0x10; - else - ret &= ~0x10; - } - if (kbc_ven == KBC_VEN_XI8088) { - if (xi8088_turbo_get()) - ret |= 0x04; - else - ret &= ~0x04; - } - break; - - case 0x62: - ret = 0xff; - if (kbc_ven == KBC_VEN_OLIVETTI) { - /* SWA on Olivetti M240 mainboard (off=1) */ - ret = 0x00; - if (ppi.pb & 0x8) { - /* Switches 4, 5 - floppy drives (number) */ - int i, fdd_count = 0; - for (i = 0; i < FDD_NUM; i++) { - if (fdd_get_flags(i)) - fdd_count++; - } - if (!fdd_count) - ret |= 0x00; - else - ret |= ((fdd_count - 1) << 2); - /* Switches 6, 7 - monitor type */ - if (video_is_mda()) - ret |= 0x3; - else if (video_is_cga()) - ret |= 0x2; /* 0x10 would be 40x25 */ - else - ret |= 0x0; - } else { - /* bit 2 always on */ - ret |= 0x4; - /* Switch 8 - 8087 FPU. */ - if (hasfpu) - ret |= 0x02; - } - } - break; case 0x64: ret = (dev->status & 0xfb); if (dev->mem[0] & STAT_SYSFLAG) @@ -2217,23 +2144,12 @@ kbd_read(uint16_t port, void *priv) } -static void -kbd_refresh(void *priv) -{ - atkbd_t *dev = (atkbd_t *)priv; - - dev->refresh = !dev->refresh; - timer_advance_u64(&dev->refresh_time, PS2_REFRESH_TIME); -} - - static void kbd_reset(void *priv) { atkbd_t *dev = (atkbd_t *)priv; int i; - uint8_t kbc_ven = 0x0; - kbc_ven = dev->flags & KBC_VEN_MASK; + uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; dev->first_write = 1; // dev->status = STAT_UNLOCKED | STAT_CD; @@ -2271,6 +2187,8 @@ kbd_reset(void *priv) memset(keyboard_set3_flags, 0, 512); set_scancode_map(dev); + + dev->ami_flags = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 0x01 : 0x00; } @@ -2292,7 +2210,6 @@ kbd_close(void *priv) /* Stop timers. */ timer_disable(&dev->send_delay_timer); - timer_disable(&dev->refresh_time); keyboard_scan = 0; keyboard_send = NULL; @@ -2318,15 +2235,11 @@ kbd_init(const device_t *info) video_reset(gfxcard); kbd_reset(dev); - io_sethandler(0x0060, 5, - kbd_read, NULL, NULL, kbd_write, NULL, NULL, dev); + io_sethandler(0x0060, 1, kbd_read, NULL, NULL, kbd_write, NULL, NULL, dev); + io_sethandler(0x0064, 1, kbd_read, NULL, NULL, kbd_write, NULL, NULL, dev); keyboard_send = add_data_kbd; timer_add(&dev->send_delay_timer, kbd_poll, dev, 1); - - if ((dev->flags & KBC_TYPE_MASK) > KBC_TYPE_PS2_NOREF) - timer_add(&dev->refresh_time, kbd_refresh, dev, 1); - timer_add(&dev->pulse_cb, pulse_poll, dev, 0); dev->write60_ven = NULL; diff --git a/src/device/keyboard_xt.c b/src/device/keyboard_xt.c index d10c8bf1f..c6fd51e09 100644 --- a/src/device/keyboard_xt.c +++ b/src/device/keyboard_xt.c @@ -593,20 +593,18 @@ kbd_read(uint16_t port, void *priv) case 0x62: if (kbd->type == 0) ret = 0x00; - else if (kbd->type == 1) { + else if (kbd->type == 1) { if (kbd->pb & 0x04) - ret = ((mem_size-64) / 32) & 0x0f; + ret = ((mem_size - 64) / 32) & 0x0f; else - ret = ((mem_size-64) / 32) >> 4; - } - else if (kbd->type == 8 || kbd->type == 9) { - /* Olivetti M19 or Zenith Data Systems Z-151 */ - if (kbd->pb & 0x04) + ret = ((mem_size - 64) / 32) >> 4; + } else if (kbd->type == 8 || kbd->type == 9) { + /* Olivetti M19 or Zenith Data Systems Z-151 */ + if (kbd->pb & 0x04) ret = kbd->pd & 0xbf; - else - ret = kbd->pd >> 4; - } - else { + else + ret = kbd->pd >> 4; + } else { if (kbd->pb & 0x08) ret = kbd->pd >> 4; else { @@ -638,7 +636,6 @@ kbd_read(uint16_t port, void *priv) case 0x63: if ((kbd->type == 2) || (kbd->type == 3) || (kbd->type == 4) || (kbd->type == 6)) ret = kbd->pd; - break; } @@ -688,119 +685,116 @@ kbd_init(const device_t *info) video_reset(gfxcard); - if (kbd->type <= 3 || kbd-> type == 8) { - + if ((kbd->type <= 3) || (kbd->type == 4) || (kbd->type == 6)) { /* DIP switch readout: bit set = OFF, clear = ON. */ - if (kbd->type != 8) - /* Switches 7, 8 - floppy drives. */ - kbd->pd = get_fdd_switch_settings(); - else - /* Olivetti M19 - * Jumpers J1, J2 - monitor type. - * 01 - mono (high-res) - * 10 - color (low-res, disables 640x400x2 mode) - * 00 - autoswitching - */ - kbd->pd |= 0x00; - - kbd->pd |= get_videomode_switch_settings(); - - /* Switches 3, 4 - memory size. */ - // Note to Compaq/Toshiba keyboard maintainers: type 4 and 6 will never be activated in this block - // Should the top if be closed right after setting floppy drive count? - if ((kbd->type == 3) || (kbd->type == 4) || (kbd->type == 6)) { - switch (mem_size) { - case 256: - kbd->pd |= 0x00; - break; - case 512: - kbd->pd |= 0x04; - break; - case 576: - kbd->pd |= 0x08; - break; - case 640: - default: - kbd->pd |= 0x0c; - break; - } - } else if (kbd->type >= 1) { - switch (mem_size) { - case 64: - kbd->pd |= 0x00; - break; - case 128: - kbd->pd |= 0x04; - break; - case 192: - kbd->pd |= 0x08; - break; - case 256: - default: - kbd->pd |= 0x0c; - break; - } - } else { - switch (mem_size) { - case 16: - kbd->pd |= 0x00; - break; - case 32: - kbd->pd |= 0x04; - break; - case 48: - kbd->pd |= 0x08; - break; - case 64: - default: - kbd->pd |= 0x0c; - break; - } - } + if (kbd->type == 8) + /* Olivetti M19 + * Jumpers J1, J2 - monitor type. + * 01 - mono (high-res) + * 10 - color (low-res, disables 640x400x2 mode) + * 00 - autoswitching + */ + kbd->pd |= 0x00; + else + /* Switches 7, 8 - floppy drives. */ + kbd->pd = get_fdd_switch_settings(); - /* Switch 2 - 8087 FPU. */ - if (hasfpu) - kbd->pd |= 0x02; + kbd->pd |= get_videomode_switch_settings(); - /* Switch 1 - always off. */ - kbd->pd |= 0x01; + /* Switches 3, 4 - memory size. */ + if ((kbd->type == 3) || (kbd->type == 4) || (kbd->type == 6)) { + switch (mem_size) { + case 256: + kbd->pd |= 0x00; + break; + case 512: + kbd->pd |= 0x04; + break; + case 576: + kbd->pd |= 0x08; + break; + case 640: + default: + kbd->pd |= 0x0c; + break; + } + } else if (kbd->type >= 1) { + switch (mem_size) { + case 64: + kbd->pd |= 0x00; + break; + case 128: + kbd->pd |= 0x04; + break; + case 192: + kbd->pd |= 0x08; + break; + case 256: + default: + kbd->pd |= 0x0c; + break; + } + } else { + switch (mem_size) { + case 16: + kbd->pd |= 0x00; + break; + case 32: + kbd->pd |= 0x04; + break; + case 48: + kbd->pd |= 0x08; + break; + case 64: + default: + kbd->pd |= 0x0c; + break; + } + } + + /* Switch 2 - 8087 FPU. */ + if (hasfpu) + kbd->pd |= 0x02; + + /* Switch 1 - always off. */ + kbd->pd |= 0x01; } else if (kbd-> type == 9) { - /* Zenith Data Systems Z-151 - * SW2 switch settings: - * bit 7: monitor frequency - * bits 5-6: autoboot (00-11 resident monitor, 10 hdd, 01 fdd) - * bits 0-4: installed memory - */ - kbd->pd = 0x20; - switch (mem_size) { - case 128: - kbd->pd |= 0x02; - break; - case 192: - kbd->pd |= 0x04; - break; - case 256: - kbd->pd |= 0x02|0x04; - break; - case 320: - kbd->pd |= 0x08; - break; - case 384: - kbd->pd |= 0x02|0x08; - break; - case 448: - kbd->pd |= 0x04|0x08; - break; - case 512: - kbd->pd |= 0x02|0x04|0x08; - break; - case 576: - kbd->pd |= 0x10; - break; - case 640: - default: - kbd->pd |= 0x02|0x10; - break; + /* Zenith Data Systems Z-151 + * SW2 switch settings: + * bit 7: monitor frequency + * bits 5-6: autoboot (00-11 resident monitor, 10 hdd, 01 fdd) + * bits 0-4: installed memory + */ + kbd->pd = 0x20; + switch (mem_size) { + case 128: + kbd->pd |= 0x02; + break; + case 192: + kbd->pd |= 0x04; + break; + case 256: + kbd->pd |= 0x06; + break; + case 320: + kbd->pd |= 0x08; + break; + case 384: + kbd->pd |= 0x0a; + break; + case 448: + kbd->pd |= 0x0c; + break; + case 512: + kbd->pd |= 0x0e; + break; + case 576: + kbd->pd |= 0x10; + break; + case 640: + default: + kbd->pd |= 0x12; + break; } } diff --git a/src/device/mouse_ps2.c b/src/device/mouse_ps2.c index 3fe743748..a28a085ff 100644 --- a/src/device/mouse_ps2.c +++ b/src/device/mouse_ps2.c @@ -96,6 +96,9 @@ ps2_write(uint8_t val, void *priv) if (dev->flags & FLAG_CTRLDAT) { dev->flags &= ~FLAG_CTRLDAT; + if (val == 0xff) + goto mouse_reset; + switch (dev->command) { case 0xe8: /* set mouse resolution */ dev->resolution = val; @@ -191,9 +194,10 @@ ps2_write(uint8_t val, void *priv) case 0xf6: /* set defaults */ case 0xff: /* reset */ +mouse_reset: dev->mode = MODE_STREAM; dev->flags &= 0x88; - mouse_scan = 0; + mouse_scan = 1; keyboard_at_mouse_reset(); keyboard_at_adddata_mouse(0xfa); if (dev->command == 0xff) { diff --git a/src/device/pci_bridge.c b/src/device/pci_bridge.c index ab2d010ac..3980f8df6 100644 --- a/src/device/pci_bridge.c +++ b/src/device/pci_bridge.c @@ -33,6 +33,8 @@ #define PCI_BRIDGE_DEC_21150 0x10110022 +#define AGP_BRIDGE_ALI_M5243 0x10b95243 +#define AGP_BRIDGE_ALI_M5247 0x10b95247 #define AGP_BRIDGE_INTEL_440LX 0x80867181 #define AGP_BRIDGE_INTEL_440BX 0x80867191 #define AGP_BRIDGE_INTEL_440GX 0x808671a1 @@ -41,15 +43,16 @@ #define AGP_BRIDGE_VIA_691 0x11068691 #define AGP_BRIDGE_VIA_8601 0x11068601 +#define AGP_BRIDGE_ALI(x) (((x) >> 16) == 0x10b9) #define AGP_BRIDGE_INTEL(x) (((x) >> 16) == 0x8086) #define AGP_BRIDGE_VIA(x) (((x) >> 16) == 0x1106) -#define AGP_BRIDGE(x) ((x) >= AGP_BRIDGE_VIA_597) +#define AGP_BRIDGE(x) ((x) >= AGP_BRIDGE_ALI_M5243) typedef struct { uint32_t local; - uint8_t type; + uint8_t type, ctl; uint8_t regs[256]; uint8_t bus_index; @@ -77,6 +80,15 @@ pci_bridge_log(const char *fmt, ...) #endif +void +pci_bridge_set_ctl(void *priv, uint8_t ctl) +{ + pci_bridge_t *dev = (pci_bridge_t *) priv; + + dev->ctl = ctl; +} + + static void pci_bridge_write(int func, int addr, uint8_t val, void *priv) { @@ -87,6 +99,9 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) if (func > 0) return; + if ((dev->local == AGP_BRIDGE_ALI_M5247) && (addr >= 0x40)) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x06: case 0x08: case 0x09: case 0x0a: @@ -94,21 +109,26 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: case 0x1e: case 0x34: case 0x3d: case 0x67: case 0xdc: - case 0xdd: case 0xde: case 0xdf: case 0xe0: - case 0xe1: case 0xe2: case 0xe3: + case 0xdd: case 0xde: case 0xdf: return; case 0x04: if (AGP_BRIDGE_INTEL(dev->local)) { if (dev->local == AGP_BRIDGE_INTEL_440BX) val &= 0x1f; - } else + } else if (dev->local == AGP_BRIDGE_ALI_M5243) + val |= 0x02; + else if (dev->local == AGP_BRIDGE_ALI_M5247) + val &= 0xc3; + else val &= 0x67; break; case 0x05: if (AGP_BRIDGE_INTEL(dev->local)) val &= 0x01; + else if (AGP_BRIDGE_ALI(dev->local)) + val &= 0x01; else val &= 0x03; break; @@ -116,6 +136,10 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) case 0x07: if (dev->local == AGP_BRIDGE_INTEL_440LX) dev->regs[addr] &= ~(val & 0x40); + else if (dev->local == AGP_BRIDGE_ALI_M5243) + dev->regs[addr] &= ~(val & 0xf8); + else if (dev->local == AGP_BRIDGE_ALI_M5247) + dev->regs[addr] &= ~(val & 0xc0); return; case 0x0c: case 0x18: @@ -129,6 +153,8 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) return; else if (AGP_BRIDGE_INTEL(dev->local)) val &= 0xf8; + else if (AGP_BRIDGE_ALI(dev->local)) + val &= 0xf8; break; case 0x19: @@ -144,7 +170,8 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) else if ((dev->local == AGP_BRIDGE_INTEL_440BX) || (dev->local == AGP_BRIDGE_INTEL_440GX)) dev->regs[addr] &= ~(val & 0xf0); - } + } else if (AGP_BRIDGE_ALI(dev->local)) + dev->regs[addr] &= ~(val & 0xf0); return; case 0x1c: case 0x1d: case 0x20: case 0x22: @@ -152,9 +179,18 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) val &= 0xf0; break; + case 0x3c: + if (!(dev->ctl & 0x80)) + return; + break; + case 0x3e: if (AGP_BRIDGE_VIA(dev->local)) val &= 0x0c; + else if (dev->local == AGP_BRIDGE_ALI_M5247) + val &= 0x0f; + else if (dev->local == AGP_BRIDGE_ALI_M5243) + return; else if (AGP_BRIDGE(dev->local)) { if ((dev->local == AGP_BRIDGE_INTEL_440BX) || (dev->local == AGP_BRIDGE_INTEL_440GX)) @@ -170,7 +206,11 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) if (dev->local == AGP_BRIDGE_INTEL_440LX) { dev->regs[addr] = ((dev->regs[addr] & 0x04) | (val & 0x02)) & ~(val & 0x04); return; - } else if (AGP_BRIDGE(dev->local)) + } else if (dev->local == AGP_BRIDGE_ALI_M5247) + return; + else if (dev->local == AGP_BRIDGE_ALI_M5243) + val &= 0x06; + else if (AGP_BRIDGE(dev->local)) return; else if (dev->local == PCI_BRIDGE_DEC_21150) val &= 0x0f; @@ -207,6 +247,94 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) if (dev->local == PCI_BRIDGE_DEC_21150) val &= 0x3f; break; + + case 0x86: + if (AGP_BRIDGE_ALI(dev->local)) + val &= 0x3f; + break; + + case 0x87: + if (AGP_BRIDGE_ALI(dev->local)) + val &= 0x60; + break; + + case 0x88: + if (AGP_BRIDGE_ALI(dev->local)) + val &= 0x8c; + break; + + case 0x8b: + if (AGP_BRIDGE_ALI(dev->local)) + val &= 0x0f; + break; + + case 0x8c: + if (AGP_BRIDGE_ALI(dev->local)) + val &= 0x83; + break; + + case 0x8d: + if (AGP_BRIDGE_ALI(dev->local)) + return; + break; + + case 0xe0: case 0xe1: + if (AGP_BRIDGE_ALI(dev->local)) { + if (!(dev->ctl & 0x20)) + return; + } else + return; + break; + + case 0xe2: + if (AGP_BRIDGE_ALI(dev->local)) { + if (dev->ctl & 0x20) + val &= 0x3f; + else + return; + } else + return; + break; + case 0xe3: + if (AGP_BRIDGE_ALI(dev->local)) { + if (dev->ctl & 0x20) + val &= 0xfe; + else + return; + } else + return; + break; + + case 0xe4: + if (AGP_BRIDGE_ALI(dev->local)) { + if (dev->ctl & 0x20) + val &= 0x03; + else + return; + } + break; + case 0xe5: + if (AGP_BRIDGE_ALI(dev->local)) { + if (!(dev->ctl & 0x20)) + return; + } + break; + + case 0xe6: + if (AGP_BRIDGE_ALI(dev->local)) { + if (dev->ctl & 0x20) + val &= 0xc0; + else + return; + } + break; + + case 0xe7: + if (AGP_BRIDGE_ALI(dev->local)) { + if (!(dev->ctl & 0x20)) + return; + } + break; } dev->regs[addr] = val; @@ -251,6 +379,26 @@ pci_bridge_reset(void *priv) dev->regs[0x07] = 0x02; break; + case AGP_BRIDGE_ALI_M5243: + dev->regs[0x04] = 0x06; + dev->regs[0x07] = 0x04; + dev->regs[0x0d] = 0x20; + dev->regs[0x19] = 0x01; + dev->regs[0x1b] = 0x20; + dev->regs[0x34] = 0xe0; + dev->regs[0x89] = 0x20; + dev->regs[0x8a] = 0xa0; + dev->regs[0x8e] = 0x20; + dev->regs[0x8f] = 0x20; + dev->regs[0xe0] = 0x01; + pci_remap_bus(dev->bus_index, 0x01); + break; + + case AGP_BRIDGE_ALI_M5247: + dev->regs[0x04] = 0x03; + dev->regs[0x08] = 0x01; + break; + case AGP_BRIDGE_INTEL_440LX: dev->regs[0x06] = 0xa0; dev->regs[0x07] = 0x02; @@ -266,7 +414,7 @@ pci_bridge_reset(void *priv) case AGP_BRIDGE_VIA_597: case AGP_BRIDGE_VIA_598: case AGP_BRIDGE_VIA_691: - case AGP_BRIDGE_VIA_8601: + case AGP_BRIDGE_VIA_8601: dev->regs[0x04] = 0x07; dev->regs[0x06] = 0x20; dev->regs[0x07] = 0x02; @@ -284,7 +432,9 @@ pci_bridge_reset(void *priv) else dev->regs[0x1c] = dev->regs[0x1d] = 0x01; - if (!AGP_BRIDGE_VIA(dev->local)) { + if (dev->local == AGP_BRIDGE_ALI_M5247) + dev->regs[0x1e] = 0x20; + else if (!AGP_BRIDGE_VIA(dev->local)) { dev->regs[0x1e] = AGP_BRIDGE(dev->local) ? 0xa0 : 0x80; dev->regs[0x1f] = 0x02; } @@ -323,8 +473,10 @@ pci_bridge_init(const device_t *info) dev->slot = pci_add_card(AGP_BRIDGE(dev->local) ? PCI_ADD_AGPBRIDGE : PCI_ADD_BRIDGE, pci_bridge_read, pci_bridge_write, dev); interrupt_count = sizeof(interrupts); interrupt_mask = interrupt_count - 1; - for (i = 0; i < interrupt_count; i++) - interrupts[i] = pci_get_int(dev->slot, PCI_INTA + i); + if (dev->slot < 32) { + for (i = 0; i < interrupt_count; i++) + interrupts[i] = pci_get_int(dev->slot, PCI_INTA + i); + } pci_bridge_log("PCI Bridge %d: upstream bus %02X slot %02X interrupts %02X %02X %02X %02X\n", dev->bus_index, (dev->slot >> 5) & 0xff, dev->slot & 31, interrupts[0], interrupts[1], interrupts[2], interrupts[3]); if (info->local == PCI_BRIDGE_DEC_21150) @@ -362,6 +514,35 @@ const device_t dec21150_device = }; /* AGP bridges */ +const device_t ali5243_agp_device = +{ + "ALi M5243 AGP Bridge", + DEVICE_PCI, + AGP_BRIDGE_ALI_M5243, + pci_bridge_init, + NULL, + pci_bridge_reset, + { NULL }, + NULL, + NULL, + NULL +}; + +/* AGP bridges */ +const device_t ali5247_agp_device = +{ + "ALi M5247 AGP Bridge", + DEVICE_PCI, + AGP_BRIDGE_ALI_M5247, + pci_bridge_init, + NULL, + pci_bridge_reset, + { NULL }, + NULL, + NULL, + NULL +}; + const device_t i440lx_agp_device = { "Intel 82443LX/EX AGP Bridge", diff --git a/src/device/phoenix_486_jumper.c b/src/device/phoenix_486_jumper.c index 5a07362d2..53fea5d92 100644 --- a/src/device/phoenix_486_jumper.c +++ b/src/device/phoenix_486_jumper.c @@ -39,11 +39,14 @@ typedef struct { - uint8_t jumper; + uint8_t type, jumper; } phoenix_486_jumper_t; + #ifdef ENABLE_PHOENIX_486_JUMPER_LOG int phoenix_486_jumper_do_log = ENABLE_PHOENIX_486_JUMPER_LOG; + + static void phoenix_486_jumper_log(const char *fmt, ...) { @@ -59,14 +62,19 @@ phoenix_486_jumper_log(const char *fmt, ...) #define phoenix_486_jumper_log(fmt, ...) #endif + static void phoenix_486_jumper_write(uint16_t addr, uint8_t val, void *priv) { phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) priv; phoenix_486_jumper_log("Phoenix 486 Jumper: Write %02x\n", val); - dev->jumper = val; + if (dev->type == 1) + dev->jumper = val & 0xbf; + else + dev->jumper = val; } + static uint8_t phoenix_486_jumper_read(uint16_t addr, void *priv) { @@ -76,6 +84,21 @@ phoenix_486_jumper_read(uint16_t addr, void *priv) } +static void +phoenix_486_jumper_reset(void *priv) +{ + phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) priv; + + if (dev->type == 1) + dev->jumper = 0x00; + else { + dev->jumper = 0x9f; + if (gfxcard != 0x01) + dev->jumper |= 0x40; + } +} + + static void phoenix_486_jumper_close(void *priv) { @@ -84,26 +107,38 @@ phoenix_486_jumper_close(void *priv) free(dev); } + static void * phoenix_486_jumper_init(const device_t *info) { phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) malloc(sizeof(phoenix_486_jumper_t)); memset(dev, 0, sizeof(phoenix_486_jumper_t)); - dev->jumper = 0x9f; - if (gfxcard != 0x01) - dev->jumper |= 0x40; + dev->type = info->local; + + phoenix_486_jumper_reset(dev); io_sethandler(0x0078, 0x0001, phoenix_486_jumper_read, NULL, NULL, phoenix_486_jumper_write, NULL, NULL, dev); return dev; } + const device_t phoenix_486_jumper_device = { "Phoenix 486 Jumper Readout", 0, 0, - phoenix_486_jumper_init, phoenix_486_jumper_close, NULL, + phoenix_486_jumper_init, phoenix_486_jumper_close, phoenix_486_jumper_reset, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t phoenix_486_jumper_pci_device = { + "Phoenix 486 Jumper Readout (PCI machines)", + 0, + 1, + phoenix_486_jumper_init, phoenix_486_jumper_close, phoenix_486_jumper_reset, { NULL }, NULL, NULL, NULL }; diff --git a/src/device/serial.c b/src/device/serial.c index 3de0c6826..15527fad4 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -717,20 +717,8 @@ serial_set_next_inst(int ni) void serial_standalone_init(void) { - if (next_inst == 0) { - device_add_inst(&i8250_device, 1); - device_add_inst(&i8250_device, 2); - device_add_inst(&i8250_device, 3); - device_add_inst(&i8250_device, 4); - } else if (next_inst == 1) { - device_add_inst(&i8250_device, 2); - device_add_inst(&i8250_device, 3); - device_add_inst(&i8250_device, 4); - } else if (next_inst == 2) { - device_add_inst(&i8250_device, 3); - device_add_inst(&i8250_device, 4); - } else - device_add_inst(&i8250_device, 4); + for ( ; next_inst < 4; ) + device_add_inst(&i8250_device, next_inst + 1); }; diff --git a/src/device/smbus_ali7101.c b/src/device/smbus_ali7101.c new file mode 100644 index 000000000..5b112a1a5 --- /dev/null +++ b/src/device/smbus_ali7101.c @@ -0,0 +1,310 @@ +/* + * 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 a generic ALi M7101-compatible SMBus host + * controller. + * + * Authors: RichardG, + * Miran Grca, + * + * Copyright 2020,2021 RichardG. + * Copyright 2021 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/i2c.h> +#include <86box/smbus.h> + + +#ifdef ENABLE_SMBUS_ALI7101_LOG +int smbus_ali7101_do_log = ENABLE_SMBUS_ALI7101_LOG; + + +static void +smbus_ali7101_log(const char *fmt, ...) +{ + va_list ap; + + if (smbus_ali7101_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define smbus_ali7101_log(fmt, ...) +#endif + + +static uint8_t +smbus_ali7101_read(uint16_t addr, void *priv) +{ + smbus_ali7101_t *dev = (smbus_ali7101_t *) priv; + uint8_t ret = 0x00; + + switch (addr - dev->io_base) { + case 0x00: + ret = dev->stat; + break; + + case 0x03: + ret = dev->addr; + break; + + case 0x04: + ret = dev->data0; + break; + + case 0x05: + ret = dev->data1; + break; + + case 0x06: + ret = dev->data[dev->index++]; + if (dev->index >= SMBUS_ALI7101_BLOCK_DATA_SIZE) + dev->index = 0; + break; + + case 0x07: + ret = dev->cmd; + break; + } + + smbus_ali7101_log("SMBus ALI7101: read(%02X) = %02x\n", addr, ret); + + return ret; +} + + +static void +smbus_ali7101_write(uint16_t addr, uint8_t val, void *priv) +{ + smbus_ali7101_t *dev = (smbus_ali7101_t *) priv; + uint8_t smbus_addr, cmd, read, prev_stat; + uint16_t timer_bytes = 0; + + smbus_ali7101_log("SMBus ALI7101: write(%02X, %02X)\n", addr, val); + + prev_stat = dev->next_stat; + dev->next_stat = 0x04; + switch (addr - dev->io_base) { + case 0x00: + dev->stat &= ~(val & 0xf2); + /* Make sure IDLE is set if we're not busy or errored. */ + if (dev->stat == 0x00) + dev->stat = 0x04; + break; + + case 0x01: + dev->ctl = val & 0xfc; + if (val & 0x04) { /* cancel an in-progress command if KILL is set */ + if (prev_stat) { /* cancel only if a command is in progress */ + timer_disable(&dev->response_timer); + dev->stat = 0x80; /* raise FAILED */ + } + } else if (val & 0x08) { /* T_OUT_CMD */ + if (prev_stat) { /* cancel only if a command is in progress */ + timer_disable(&dev->response_timer); + dev->stat = 0x20; /* raise DEVICE_ERR */ + } + } + + if (val & 0x80) + dev->index = 0; + break; + + case 0x02: + /* dispatch command if START is set */ + timer_bytes++; /* address */ + + smbus_addr = (dev->addr >> 1); + read = dev->addr & 0x01; + + cmd = (dev->ctl >> 4) & 0x7; + smbus_ali7101_log("SMBus ALI7101: addr=%02X read=%d protocol=%X cmd=%02X data0=%02X data1=%02X\n", smbus_addr, read, cmd, dev->cmd, dev->data0, dev->data1); + + /* Raise DEV_ERR if no device is at this address, or if the device returned NAK when starting the transfer. */ + if (!i2c_start(i2c_smbus, smbus_addr, read)) { + dev->next_stat = 0x40; + break; + } + + dev->next_stat = 0x10; /* raise INTER (command completed) by default */ + + /* Decode the command protocol. */ + switch (cmd) { + case 0x0: /* quick R/W */ + break; + + case 0x1: /* byte R/W */ + if (read) /* byte read */ + dev->data0 = i2c_read(i2c_smbus, smbus_addr); + else /* byte write */ + i2c_write(i2c_smbus, smbus_addr, dev->data0); + timer_bytes++; + + break; + + case 0x2: /* byte data R/W */ + /* command write */ + i2c_write(i2c_smbus, smbus_addr, dev->cmd); + timer_bytes++; + + if (read) /* byte read */ + dev->data0 = i2c_read(i2c_smbus, smbus_addr); + else /* byte write */ + i2c_write(i2c_smbus, smbus_addr, dev->data0); + timer_bytes++; + + break; + + case 0x3: /* word data R/W */ + /* command write */ + i2c_write(i2c_smbus, smbus_addr, dev->cmd); + timer_bytes++; + + if (read) { /* word read */ + dev->data0 = i2c_read(i2c_smbus, smbus_addr); + dev->data1 = i2c_read(i2c_smbus, smbus_addr); + } else { /* word write */ + i2c_write(i2c_smbus, smbus_addr, dev->data0); + i2c_write(i2c_smbus, smbus_addr, dev->data1); + } + timer_bytes += 2; + + break; + + case 0x4: /* block R/W */ + timer_bytes++; /* count the SMBus length byte now */ + + /* fall-through */ + + default: /* unknown */ + dev->next_stat = 0x20; /* raise DEV_ERR */ + timer_bytes = 0; + break; + } + + /* Finish transfer. */ + i2c_stop(i2c_smbus, smbus_addr); + break; + + case 0x03: + dev->addr = val; + break; + + case 0x04: + dev->data0 = val; + break; + + case 0x05: + dev->data1 = val; + break; + + case 0x06: + dev->data[dev->index++] = val; + if (dev->index >= SMBUS_ALI7101_BLOCK_DATA_SIZE) + dev->index = 0; + break; + + case 0x07: + dev->cmd = val; + break; + } + + if (dev->next_stat != 0x04) { /* schedule dispatch of any pending status register update */ + dev->stat = 0x08; /* raise HOST_BUSY while waiting */ + timer_disable(&dev->response_timer); + /* delay = ((half clock for start + half clock for stop) + (bytes * (8 bits + ack))) * 60us period measured on real VIA 686B */ + timer_set_delay_u64(&dev->response_timer, (1 + (timer_bytes * 9)) * 60 * TIMER_USEC); + } +} + + +static void +smbus_ali7101_response(void *priv) +{ + smbus_ali7101_t *dev = (smbus_ali7101_t *) priv; + + /* Dispatch the status register update. */ + dev->stat = dev->next_stat; +} + + +void +smbus_ali7101_remap(smbus_ali7101_t *dev, uint16_t new_io_base, uint8_t enable) +{ + if (dev->io_base) + io_removehandler(dev->io_base, 0x10, smbus_ali7101_read, NULL, NULL, smbus_ali7101_write, NULL, NULL, dev); + + dev->io_base = new_io_base; + smbus_ali7101_log("SMBus ALI7101: remap to %04Xh (%sabled)\n", dev->io_base, enable ? "en" : "dis"); + + if (enable && dev->io_base) + io_sethandler(dev->io_base, 0x10, smbus_ali7101_read, NULL, NULL, smbus_ali7101_write, NULL, NULL, dev); +} + + +static void +smbus_ali7101_reset(void *priv) +{ + smbus_ali7101_t *dev = (smbus_ali7101_t *) priv; + + timer_disable(&dev->response_timer); + dev->stat = 0x04; +} + + +static void * +smbus_ali7101_init(const device_t *info) +{ + smbus_ali7101_t *dev = (smbus_ali7101_t *) malloc(sizeof(smbus_ali7101_t)); + memset(dev, 0, sizeof(smbus_ali7101_t)); + + dev->local = info->local; + dev->stat = 0x04; + /* We save the I2C bus handle on dev but use i2c_smbus for all operations because + dev and therefore dev->i2c will be invalidated if a device triggers a hard reset. */ + i2c_smbus = dev->i2c = i2c_addbus("smbus_ali7101"); + + timer_add(&dev->response_timer, smbus_ali7101_response, dev, 0); + + return dev; +} + + +static void +smbus_ali7101_close(void *priv) +{ + smbus_ali7101_t *dev = (smbus_ali7101_t *) priv; + + if (i2c_smbus == dev->i2c) + i2c_smbus = NULL; + i2c_removebus(dev->i2c); + + free(dev); +} + + +const device_t ali7101_smbus_device = { + "ALi M7101-compatible SMBus Host Controller", + DEVICE_AT, + 0, + smbus_ali7101_init, smbus_ali7101_close, smbus_ali7101_reset, + { NULL }, NULL, NULL, + NULL +}; diff --git a/src/device/smbus_piix4.c b/src/device/smbus_piix4.c index 271747d92..297b3543d 100644 --- a/src/device/smbus_piix4.c +++ b/src/device/smbus_piix4.c @@ -26,7 +26,7 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/i2c.h> -#include <86box/smbus_piix4.h> +#include <86box/smbus.h> #ifdef ENABLE_SMBUS_PIIX4_LOG diff --git a/src/device/vpc2007.c b/src/device/vpc2007.c deleted file mode 100644 index 4caf77fbb..000000000 --- a/src/device/vpc2007.c +++ /dev/null @@ -1,186 +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. - * - * Implementation of the port 440h device from Virtual PC 2007. - * - * - * - * Author: RichardG, - * - * Copyright 2020 RichardG. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/io.h> -#include <86box/device.h> -#include <86box/machine.h> -#include <86box/plat.h> -#include <86box/ui.h> -#include <86box/mem.h> -#include "cpu.h" - - -typedef struct { - uint8_t port440, port440read, port442, port443, port444; -} vpc2007_t; - - -#ifdef ENABLE_VPC2007_LOG -int vpc2007_do_log = ENABLE_VPC2007_LOG; - - -static void -vpc2007_log(const char *fmt, ...) -{ - va_list ap; - - if (vpc2007_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -int vpc2007_do_log = 0; - -#define vpc2007_log(fmt, ...) -#endif - - -static uint8_t -vpc2007_read(uint16_t port, void *priv) -{ - vpc2007_t *dev = (vpc2007_t *) priv; - uint8_t ret = 0xff; - - switch (port) { - case 0x440: - ret = dev->port440read; - dev->port440read = 0x02; - break; - - case 0x445: - if ((dev->port440 == 0x1e) && (dev->port442 == 0x48) && (dev->port444 == 0xa7)) { - switch (dev->port443) { - case 0x0b: - ret = 0x00; - break; - - case 0x1b: case 0x05: - ret = 0x01; - break; - - case 0x02: - ret = 0x02; - break; - - case 0x11: - ret = 0x04; - break; - - case 0x12: - ret = 0x06; - break; - - case 0x04: case 0x0d: - ret = 0x08; - break; - - case 0x03: case 0x09: - ret = 0x0b; - break; - - case 0x15: - ret = 0x12; - break; - - case 0x17: - ret = 0x40; - break; - } - } - - if (ret == 0xff) - vpc2007_log("VPC2007: unknown combination %02X %02X %02X %02X\n", dev->port440, dev->port442, dev->port443, dev->port444); - - break; - - default: - vpc2007_log("VPC2007: read from unknown port %02X\n", port); - break; - } - - return ret; -} - - -static void -vpc2007_write(uint16_t port, uint8_t val, void *priv) -{ - vpc2007_t *dev = (vpc2007_t *) priv; - - switch (port) { - case 0x440: - dev->port440 = val; - dev->port440read = 0x03; - break; - - case 0x442: - dev->port442 = val; - break; - - case 0x443: - dev->port443 = val; - break; - - case 0x444: - dev->port444 = val; - break; - } -} - - -static void * -vpc2007_init(const device_t *info) -{ - vpc2007_t *dev = (vpc2007_t *) malloc(sizeof(vpc2007_t)); - memset(dev, 0, sizeof(vpc2007_t)); - - io_sethandler(0x440, 6, - vpc2007_read, NULL, NULL, vpc2007_write, NULL, NULL, dev); - - return dev; -} - - -static void -vpc2007_close(void *priv) -{ - vpc2007_t *dev = (vpc2007_t *) priv; - - io_removehandler(0x440, 6, - vpc2007_read, NULL, NULL, vpc2007_write, NULL, NULL, dev); - - free(dev); -} - - -const device_t vpc2007_device = { - "Virtual PC 2007 Port 440h Device", - DEVICE_ISA, - 0, - vpc2007_init, vpc2007_close, NULL, - { NULL }, NULL, NULL, - NULL -}; diff --git a/src/disk/CMakeLists.txt b/src/disk/CMakeLists.txt index f0ec758fe..9a5c72e00 100644 --- a/src/disk/CMakeLists.txt +++ b/src/disk/CMakeLists.txt @@ -15,7 +15,7 @@ add_library(hdd OBJECT hdd.c hdd_image.c hdd_table.c hdc.c hdc_st506_xt.c hdc_st506_at.c hdc_xta.c hdc_esdi_at.c hdc_esdi_mca.c hdc_xtide.c - hdc_ide.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_sff8038i.c) + hdc_ide.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_cmd646.c hdc_ide_sff8038i.c) add_library(zip OBJECT zip.c) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index c0cc93159..1b048b8b0 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -916,13 +916,14 @@ ide_atapi_attach(ide_t *ide) void ide_set_callback(ide_t *ide, double callback) { - ide_log("ide_set_callback(%i)\n", ide->channel); if (!ide) { - ide_log("Set callback failed\n"); + ide_log("ide_set_callback(NULL): Set callback failed\n"); return; } + ide_log("ide_set_callback(%i)\n", ide->channel); + if (callback == 0.0) timer_stop(&ide->timer); else @@ -2504,6 +2505,60 @@ id_not_found: } +uint8_t +ide_read_ali_75(void) +{ + ide_t *ide0, *ide1; + int ch0, ch1; + uint8_t ret = 0x00; + + ch0 = ide_boards[0]->cur_dev; + ch1 = ide_boards[1]->cur_dev; + ide0 = ide_drives[ch0]; + ide1 = ide_drives[ch1]; + + if (ch1) + ret |= 0x08; + if (ch0) + ret |= 0x04; + if (ide1->irqstat) + ret |= 0x02; + if (ide0->irqstat) + ret |= 0x01; + + return ret; +} + + +uint8_t +ide_read_ali_76(void) +{ + ide_t *ide0, *ide1; + int ch0, ch1; + uint8_t ret = 0x00; + + ch0 = ide_boards[0]->cur_dev; + ch1 = ide_boards[1]->cur_dev; + ide0 = ide_drives[ch0]; + ide1 = ide_drives[ch1]; + + if (ide1->atastat & BSY_STAT) + ret |= 0x40; + if (ide1->atastat & DRQ_STAT) + ret |= 0x20; + if (ide1->atastat & ERR_STAT) + ret |= 0x10; + if (ide0->atastat & BSY_STAT) + ret |= 0x04; + if (ide0->atastat & DRQ_STAT) + ret |= 0x02; + if (ide0->atastat & ERR_STAT) + ret |= 0x01; + + return ret; +} + + static void ide_set_handlers(uint8_t board) { diff --git a/src/disk/hdc_ide_cmd640.c b/src/disk/hdc_ide_cmd640.c index ad2c739cc..ac6146094 100644 --- a/src/disk/hdc_ide_cmd640.c +++ b/src/disk/hdc_ide_cmd640.c @@ -7,7 +7,7 @@ * This file is part of the 86Box distribution. * * Implementation of the CMD PCI-0640B controller. - + * * Authors: Miran Grca, * * Copyright 2020 Miran Grca. @@ -42,7 +42,8 @@ typedef struct { uint8_t vlb_idx, id, in_cfg, single_channel, - regs[256]; + pci, regs[256]; + uint32_t local; int slot, irq_mode[2], irq_pin, irq_line; } cmd640_t; @@ -51,15 +52,45 @@ typedef struct static int next_id = 0; +#ifdef ENABLE_CMD640_LOG +int cmd640_do_log = ENABLE_CMD640_LOG; +static void +cmd640_log(const char *fmt, ...) +{ + va_list ap; + + if (cmd640_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define cmd640_log(fmt, ...) +#endif + + void cmd640_set_irq(int channel, void *priv) { cmd640_t *dev = (cmd640_t *) priv; - dev->regs[0x50] &= ~0x04; - dev->regs[0x50] |= (channel >> 4); + int irq = !!(channel & 0x40); + + if (channel & 0x01) { + if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) { + dev->regs[0x57] &= ~0x10; + dev->regs[0x57] |= (channel >> 2); + } + } else { + if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) { + dev->regs[0x50] &= ~0x04; + dev->regs[0x50] |= (channel >> 4); + } + } channel &= 0x01; - if (dev->regs[0x50] & 0x04) { + if (irq) { if (dev->irq_mode[channel] == 1) pci_set_irq(dev->slot, dev->irq_pin); else @@ -196,6 +227,8 @@ cmd640_vlb_read(uint16_t addr, void *priv) ret = dev->regs[dev->vlb_idx]; if (dev->vlb_idx == 0x50) dev->regs[0x50] &= ~0x04; + else if (dev->vlb_idx == 0x57) + dev->regs[0x57] &= ~0x10; if (dev->regs[0x50] & 0x80) dev->in_cfg = 0; break; @@ -234,6 +267,8 @@ cmd640_pci_write(int func, int addr, uint8_t val, void *priv) { cmd640_t *dev = (cmd640_t *) priv; + cmd640_log("cmd640_pci_write(%i, %02X, %02X)\n", func, addr, val); + if (func == 0x00) switch (addr) { case 0x04: dev->regs[addr] = (val & 0x41); @@ -315,15 +350,20 @@ cmd640_pci_read(int func, int addr, void *priv) ret = dev->regs[addr]; if (addr == 0x50) dev->regs[0x50] &= ~0x04; + else if (addr == 0x57) + dev->regs[0x57] &= ~0x10; } + cmd640_log("cmd640_pci_read(%i, %02X, %02X)\n", func, addr, ret); + return ret; } static void -cmd640_reset(void *p) +cmd640_reset(void *priv) { + cmd640_t *dev = (cmd640_t *) priv; int i = 0; for (i = 0; i < CDROM_NUM; i++) { @@ -342,8 +382,58 @@ cmd640_reset(void *p) mo_reset((scsi_common_t *) mo_drives[i].priv); } - cmd640_set_irq(0x00, p); - cmd640_set_irq(0x01, p); + cmd640_set_irq(0x00, priv); + cmd640_set_irq(0x01, priv); + + memset(dev->regs, 0x00, sizeof(dev->regs)); + + dev->regs[0x50] = 0x02; /* Revision 02 */ + dev->regs[0x50] |= (dev->id << 3); /* Device ID: 00 = 60h, 01 = 61h, 10 = 62h, 11 = 63h */ + + dev->regs[0x59] = 0x40; + + if (dev->pci) { + cmd640_log("dev->local = %08X\n", dev->local); + if ((dev->local & 0xffff) == 0x0a) { + dev->regs[0x50] |= 0x40; /* Enable Base address register R/W; + If 0, they return 0 and are read-only 8 */ + } + + dev->regs[0x00] = 0x95; /* CMD */ + dev->regs[0x01] = 0x10; + dev->regs[0x02] = 0x40; /* PCI-0640B */ + dev->regs[0x03] = 0x06; + dev->regs[0x04] = 0x01; /* Apparently required by the ASUS PCI/I-P5SP4 AND PCI/I-P54SP4 */ + dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */ + dev->regs[0x08] = 0x02; /* Revision 02 */ + dev->regs[0x09] = dev->local; /* Programming interface */ + dev->regs[0x0a] = 0x01; /* IDE controller */ + dev->regs[0x0b] = 0x01; /* Mass storage controller */ + + /* Base addresses (1F0, 3F4, 170, 374) */ + if (dev->regs[0x50] & 0x40) { + dev->regs[0x10] = 0xf1; dev->regs[0x11] = 0x01; + dev->regs[0x14] = 0xf5; dev->regs[0x15] = 0x03; + dev->regs[0x18] = 0x71; dev->regs[0x19] = 0x01; + dev->regs[0x1c] = 0x75; dev->regs[0x1d] = 0x03; + } + + dev->regs[0x3c] = 0x14; /* IRQ 14 */ + dev->regs[0x3d] = 0x01; /* INTA */ + + dev->irq_mode[0] = dev->irq_mode[1] = 0; + dev->irq_pin = PCI_INTA; + dev->irq_line = 14; + } else { + if ((dev->local & 0xffff) == 0x0078) + dev->regs[0x50] |= 0x20; /* 0 = 178h, 17Ch; 1 = 078h, 07Ch */ + + /* If bit 7 is 1, then device ID has to be written on port x78h before + accessing the configuration registers */ + dev->in_cfg = 1; /* Configuration registers are accessible */ + } + + cmd640_ide_handlers(dev); } @@ -366,45 +456,13 @@ cmd640_init(const device_t *info) dev->id = next_id | 0x60; - dev->regs[0x50] = 0x02; /* Revision 02 */ - dev->regs[0x50] |= (next_id << 3); /* Device ID: 00 = 60h, 01 = 61h, 10 = 62h, 11 = 63h */ - - dev->regs[0x59] = 0x40; + dev->pci = !!(info->flags & DEVICE_PCI); + dev->local = info->local; if (info->flags & DEVICE_PCI) { - if ((info->local & 0xffff) == 0x0a) { - dev->regs[0x50] |= 0x40; /* Enable Base address register R/W; - If 0, they return 0 and are read-only 8 */ - } - - dev->regs[0x00] = 0x95; /* CMD */ - dev->regs[0x01] = 0x10; - dev->regs[0x02] = 0x40; /* PCI-0640B */ - dev->regs[0x03] = 0x06; - dev->regs[0x04] = 0x01; /* Apparently required by the ASUS PCI/I-P5SP4 AND PCI/I-P54SP4 */ - dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */ - dev->regs[0x08] = 0x02; /* Revision 02 */ - dev->regs[0x09] = info->local; /* Programming interface */ - dev->regs[0x0a] = 0x01; /* IDE controller */ - dev->regs[0x0b] = 0x01; /* Mass storage controller */ - - /* Base addresses (1F0, 3F4, 170, 374) */ - if (dev->regs[0x50] & 0x40) { - dev->regs[0x10] = 0xf1; dev->regs[0x11] = 0x01; - dev->regs[0x14] = 0xf5; dev->regs[0x15] = 0x03; - dev->regs[0x18] = 0x71; dev->regs[0x19] = 0x01; - dev->regs[0x1c] = 0x75; dev->regs[0x1d] = 0x03; - } - - dev->regs[0x3c] = 0x14; /* IRQ 14 */ - dev->regs[0x3d] = 0x01; /* INTA */ - device_add(&ide_pci_2ch_device); dev->slot = pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev); - dev->irq_mode[0] = dev->irq_mode[1] = 0; - dev->irq_pin = PCI_INTA; - dev->irq_line = 14; ide_set_bus_master(0, NULL, cmd640_set_irq, dev); ide_set_bus_master(1, NULL, cmd640_set_irq, dev); @@ -416,12 +474,6 @@ cmd640_init(const device_t *info) // ide_pri_disable(); } else if (info->flags & DEVICE_VLB) { - if ((info->local & 0xffff) == 0x0078) - dev->regs[0x50] |= 0x20; /* 0 = 178h, 17Ch; 1 = 078h, 07Ch */ - /* If bit 7 is 1, then device ID has to be written on port x78h before - accessing the configuration registers */ - dev->in_cfg = 1; /* Configuration register are accessible */ - device_add(&ide_vlb_2ch_device); io_sethandler(info->local & 0xffff, 0x0008, @@ -432,11 +484,10 @@ cmd640_init(const device_t *info) dev->single_channel = !!(info->local & 0x20000); - if (!dev->single_channel) - ide_sec_disable(); - next_id++; + cmd640_reset(dev); + return dev; } @@ -445,7 +496,7 @@ const device_t ide_cmd640_vlb_device = { "CMD PCI-0640B VLB", DEVICE_VLB, 0x0078, - cmd640_init, cmd640_close, NULL, + cmd640_init, cmd640_close, cmd640_reset, { NULL }, NULL, NULL, NULL }; @@ -454,7 +505,7 @@ const device_t ide_cmd640_vlb_178_device = { "CMD PCI-0640B VLB (Port 178h)", DEVICE_VLB, 0x0178, - cmd640_init, cmd640_close, NULL, + cmd640_init, cmd640_close, cmd640_reset, { NULL }, NULL, NULL, NULL }; diff --git a/src/disk/hdc_ide_cmd646.c b/src/disk/hdc_ide_cmd646.c new file mode 100644 index 000000000..4a8e9a176 --- /dev/null +++ b/src/disk/hdc_ide_cmd646.c @@ -0,0 +1,435 @@ +/* + * 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 CMD PCI-0646 controller. + * + * Authors: Miran Grca, + * + * Copyright 2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/cdrom.h> +#include <86box/scsi_device.h> +#include <86box/scsi_cdrom.h> +#include <86box/dma.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/keyboard.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/timer.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/zip.h> +#include <86box/mo.h> + + +typedef struct +{ + uint8_t vlb_idx, single_channel, + in_cfg, regs[256]; + uint32_t local; + int slot, irq_mode[2], + irq_pin; + sff8038i_t *bm[2]; +} cmd646_t; + + +#ifdef ENABLE_CMD646_LOG +int cmd646_do_log = ENABLE_CMD646_LOG; +static void +cmd646_log(const char *fmt, ...) +{ + va_list ap; + + if (cmd646_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define cmd646_log(fmt, ...) +#endif + + +static void +cmd646_set_irq(int channel, void *priv) +{ + cmd646_t *dev = (cmd646_t *) priv; + + if (channel & 0x01) { + if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) { + dev->regs[0x57] &= ~0x10; + dev->regs[0x57] |= (channel >> 2); + } + } else { + if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) { + dev->regs[0x50] &= ~0x04; + dev->regs[0x50] |= (channel >> 4); + } + } + + sff_bus_master_set_irq(channel, dev->bm[channel & 0x01]); +} + + +static int +cmd646_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv) +{ + cmd646_t *dev = (cmd646_t *) priv; + + return sff_bus_master_dma(channel, data, transfer_length, out, dev->bm[channel & 0x01]); +} + + +static void +cmd646_ide_handlers(cmd646_t *dev) +{ + uint16_t main, side; + int irq_mode[2] = { 0, 0 }; + + ide_pri_disable(); + + if ((dev->regs[0x09] & 0x01) && (dev->regs[0x50] & 0x40)) { + main = (dev->regs[0x11] << 8) | (dev->regs[0x10] & 0xf8); + side = ((dev->regs[0x15] << 8) | (dev->regs[0x14] & 0xfc)) + 2; + } else { + main = 0x1f0; + side = 0x3f6; + } + + ide_set_base(0, main); + ide_set_side(0, side); + + if (dev->regs[0x09] & 0x01) + irq_mode[0] = 1; + + sff_set_irq_mode(dev->bm[0], 0, irq_mode[0]); + sff_set_irq_mode(dev->bm[0], 1, irq_mode[1]); + + if (dev->regs[0x04] & 0x01) + ide_pri_enable(); + + if (dev->single_channel) + return; + + ide_sec_disable(); + + if ((dev->regs[0x09] & 0x04) && (dev->regs[0x50] & 0x40)) { + main = (dev->regs[0x19] << 8) | (dev->regs[0x18] & 0xf8); + side = ((dev->regs[0x1d] << 8) | (dev->regs[0x1c] & 0xfc)) + 2; + } else { + main = 0x170; + side = 0x376; + } + + ide_set_base(1, main); + ide_set_side(1, side); + + if (dev->regs[0x09] & 0x04) + irq_mode[1] = 1; + + sff_set_irq_mode(dev->bm[1], 0, irq_mode[0]); + sff_set_irq_mode(dev->bm[1], 1, irq_mode[1]); + + if ((dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08)) + ide_sec_enable(); + +} + + +static void +cmd646_ide_bm_handlers(cmd646_t *dev) +{ + uint16_t base = (dev->regs[0x20] & 0xf0) | (dev->regs[0x21] << 8); + + sff_bus_master_handler(dev->bm[0], (dev->regs[0x04] & 1), base); + sff_bus_master_handler(dev->bm[1], (dev->regs[0x04] & 1), base + 8); +} + + +static void +cmd646_pci_write(int func, int addr, uint8_t val, void *priv) +{ + cmd646_t *dev = (cmd646_t *) priv; + + cmd646_log("[%04X:%08X] (%08X) cmd646_pci_write(%i, %02X, %02X)\n", CS, cpu_state.pc, ESI, func, addr, val); + + if (func == 0x00) switch (addr) { + case 0x04: + dev->regs[addr] = (val & 0x45); + cmd646_ide_handlers(dev); + break; + case 0x07: + dev->regs[addr] &= ~(val & 0xb1); + break; + case 0x09: + if ((dev->regs[addr] & 0x0a) == 0x0a) { + dev->regs[addr] = (dev->regs[addr] & 0x0a) | (val & 0x05); + dev->irq_mode[0] = !!(val & 0x01); + dev->irq_mode[1] = !!(val & 0x04); + cmd646_ide_handlers(dev); + } + break; + case 0x10: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x10] = (val & 0xf8) | 1; + cmd646_ide_handlers(dev); + } + break; + case 0x11: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x11] = val; + cmd646_ide_handlers(dev); + } + break; + case 0x14: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x14] = (val & 0xfc) | 1; + cmd646_ide_handlers(dev); + } + break; + case 0x15: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x15] = val; + cmd646_ide_handlers(dev); + } + break; + case 0x18: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x18] = (val & 0xf8) | 1; + cmd646_ide_handlers(dev); + } + break; + case 0x19: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x19] = val; + cmd646_ide_handlers(dev); + } + break; + case 0x1c: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x1c] = (val & 0xfc) | 1; + cmd646_ide_handlers(dev); + } + break; + case 0x1d: + if (dev->regs[0x50] & 0x40) { + dev->regs[0x1d] = val; + cmd646_ide_handlers(dev); + } + break; + case 0x20: + dev->regs[0x20] = (val & 0xf0) | 1; + cmd646_ide_bm_handlers(dev); + break; + case 0x21: + dev->regs[0x21] = val; + cmd646_ide_bm_handlers(dev); + break; + case 0x51: + dev->regs[addr] = val & 0xc8; + cmd646_ide_handlers(dev); + break; + case 0x52: case 0x54: case 0x56: case 0x58: + case 0x59: case 0x5b: + dev->regs[addr] = val; + break; + case 0x53: case 0x55: + dev->regs[addr] = val & 0xc0; + break; + case 0x57: + dev->regs[addr] = (dev->regs[addr] & 0x10) | (val & 0xcc); + break; + case 0x70 ... 0x77: + sff_bus_master_write(addr & 0x0f, val, dev->bm[0]); + break; + case 0x78 ... 0x7f: + sff_bus_master_write(addr & 0x0f, val, dev->bm[1]); + break; + } +} + + +static uint8_t +cmd646_pci_read(int func, int addr, void *priv) +{ + cmd646_t *dev = (cmd646_t *) priv; + uint8_t ret = 0xff; + + if (func == 0x00) { + ret = dev->regs[addr]; + + if (addr == 0x50) + dev->regs[0x50] &= ~0x04; + else if (addr == 0x57) + dev->regs[0x57] &= ~0x10; + else if ((addr >= 0x70) && (addr <= 0x77)) + ret = sff_bus_master_read(addr & 0x0f, dev->bm[0]); + else if ((addr >= 0x78) && (addr <= 0x7f)) + ret = sff_bus_master_read(addr & 0x0f, dev->bm[0]); + } + + cmd646_log("[%04X:%08X] (%08X) cmd646_pci_read(%i, %02X, %02X)\n", CS, cpu_state.pc, ESI, func, addr, ret); + + return ret; +} + + +static void +cmd646_reset(void *priv) +{ + cmd646_t *dev = (cmd646_t *) priv; + int i = 0; + + for (i = 0; i < CDROM_NUM; i++) { + if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && + (cdrom[i].ide_channel < 4) && cdrom[i].priv) + scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); + } + for (i = 0; i < ZIP_NUM; i++) { + if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && + (zip_drives[i].ide_channel < 4) && zip_drives[i].priv) + zip_reset((scsi_common_t *) zip_drives[i].priv); + } + for (i = 0; i < MO_NUM; i++) { + if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && + (mo_drives[i].ide_channel < 4) && mo_drives[i].priv) + mo_reset((scsi_common_t *) mo_drives[i].priv); + } + + cmd646_set_irq(0x00, priv); + cmd646_set_irq(0x01, priv); + + memset(dev->regs, 0x00, sizeof(dev->regs)); + + dev->regs[0x00] = 0x95; /* CMD */ + dev->regs[0x01] = 0x10; + dev->regs[0x02] = 0x46; /* PCI-0646 */ + dev->regs[0x03] = 0x06; + dev->regs[0x04] = 0x00; + dev->regs[0x06] = 0x80; + dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */ + dev->regs[0x09] = dev->local; /* Programming interface */ + dev->regs[0x0a] = 0x01; /* IDE controller */ + dev->regs[0x0b] = 0x01; /* Mass storage controller */ + + if ((dev->local & 0xffff) == 0x8a) { + dev->regs[0x50] = 0x40; /* Enable Base address register R/W; + If 0, they return 0 and are read-only 8 */ + + /* Base addresses (1F0, 3F4, 170, 374) */ + dev->regs[0x10] = 0xf1; dev->regs[0x11] = 0x01; + dev->regs[0x14] = 0xf5; dev->regs[0x15] = 0x03; + dev->regs[0x18] = 0x71; dev->regs[0x19] = 0x01; + dev->regs[0x1c] = 0x75; dev->regs[0x1d] = 0x03; + } + + dev->regs[0x20] = 0x01; + + dev->regs[0x3c] = 0x0e; /* IRQ 14 */ + dev->regs[0x3d] = 0x01; /* INTA */ + dev->regs[0x3e] = 0x02; /* Min_Gnt */ + dev->regs[0x3f] = 0x04; /* Max_Iat */ + + if (!dev->single_channel) + dev->regs[0x51] = 0x08; + + dev->regs[0x57] = 0x0c; + dev->regs[0x59] = 0x40; + + dev->irq_mode[0] = dev->irq_mode[1] = 0; + dev->irq_pin = PCI_INTA; + + cmd646_ide_handlers(dev); + cmd646_ide_bm_handlers(dev); +} + + +static void +cmd646_close(void *priv) +{ + cmd646_t *dev = (cmd646_t *) priv; + + free(dev); +} + + +static void * +cmd646_init(const device_t *info) +{ + cmd646_t *dev = (cmd646_t *) malloc(sizeof(cmd646_t)); + memset(dev, 0x00, sizeof(cmd646_t)); + + dev->local = info->local; + + device_add(&ide_pci_2ch_device); + + dev->slot = pci_add_card(PCI_ADD_IDE, cmd646_pci_read, cmd646_pci_write, dev); + + dev->single_channel = !!(info->local & 0x20000); + + dev->bm[0] = device_add_inst(&sff8038i_device, 1); + if (!dev->single_channel) + dev->bm[1] = device_add_inst(&sff8038i_device, 2); + + ide_set_bus_master(0, cmd646_bus_master_dma, cmd646_set_irq, dev); + if (!dev->single_channel) + ide_set_bus_master(1, cmd646_bus_master_dma, cmd646_set_irq, dev); + + sff_set_irq_mode(dev->bm[0], 0, 0); + sff_set_irq_mode(dev->bm[0], 1, 0); + + if (!dev->single_channel) { + sff_set_irq_mode(dev->bm[1], 0, 0); + sff_set_irq_mode(dev->bm[1], 1, 0); + } + + cmd646_reset(dev); + + return dev; +} + + +const device_t ide_cmd646_device = { + "CMD PCI-0646", + DEVICE_PCI, + 0x8a, + cmd646_init, cmd646_close, cmd646_reset, + { NULL }, NULL, NULL, + NULL +}; + +const device_t ide_cmd646_legacy_only_device = { + "CMD PCI-0646 (Legacy Mode Only)", + DEVICE_PCI, + 0x80, + cmd646_init, cmd646_close, cmd646_reset, + { NULL }, NULL, NULL, + NULL +}; + +const device_t ide_cmd646_single_channel_device = { + "CMD PCI-0646", + DEVICE_PCI, + 0x2008a, + cmd646_init, cmd646_close, cmd646_reset, + { NULL }, NULL, NULL, + NULL +}; diff --git a/src/disk/hdc_ide_opti611.c b/src/disk/hdc_ide_opti611.c index 73a52a723..4cdf06b78 100644 --- a/src/disk/hdc_ide_opti611.c +++ b/src/disk/hdc_ide_opti611.c @@ -56,11 +56,11 @@ opti611_cfg_write(uint16_t addr, uint8_t val, void *priv) case 0x0002: dev->regs[0x12] = (val & 0xc1) | 0x02; if (val & 0xc0) { + if (val & 0x40) + dev->cfg_locked = 1; dev->in_cfg = 0; opti611_ide_handler(dev); } - if (val & 0x40) - dev->cfg_locked = 1; break; case 0x0003: dev->regs[0x03] = (val & 0xdf); diff --git a/src/disk/hdc_ide_sff8038i.c b/src/disk/hdc_ide_sff8038i.c index b00b2a66d..8fe9fec88 100644 --- a/src/disk/hdc_ide_sff8038i.c +++ b/src/disk/hdc_ide_sff8038i.c @@ -47,10 +47,10 @@ static int next_id = 0; -static uint8_t sff_bus_master_read(uint16_t port, void *priv); +uint8_t sff_bus_master_read(uint16_t port, void *priv); static uint16_t sff_bus_master_readw(uint16_t port, void *priv); static uint32_t sff_bus_master_readl(uint16_t port, void *priv); -static void sff_bus_master_write(uint16_t port, uint8_t val, void *priv); +void sff_bus_master_write(uint16_t port, uint8_t val, void *priv); static void sff_bus_master_writew(uint16_t port, uint16_t val, void *priv); static void sff_bus_master_writel(uint16_t port, uint32_t val, void *priv); @@ -112,7 +112,7 @@ sff_bus_master_next_addr(sff8038i_t *dev) } -static void +void sff_bus_master_write(uint16_t port, uint8_t val, void *priv) { sff8038i_t *dev = (sff8038i_t *) priv; @@ -138,6 +138,9 @@ sff_bus_master_write(uint16_t port, uint8_t val, void *priv) dev->command = val; break; + case 1: + dev->dma_mode = val & 0x03; + break; case 2: sff_log("sff Status: val = %02X, old = %02X\n", val, dev->status); dev->status &= 0x07; @@ -177,6 +180,7 @@ sff_bus_master_writew(uint16_t port, uint16_t val, void *priv) switch (port & 7) { case 0: + case 1: case 2: sff_bus_master_write(port, val & 0xff, priv); break; @@ -202,6 +206,7 @@ sff_bus_master_writel(uint16_t port, uint32_t val, void *priv) switch (port & 7) { case 0: + case 1: case 2: sff_bus_master_write(port, val & 0xff, priv); break; @@ -214,7 +219,7 @@ sff_bus_master_writel(uint16_t port, uint32_t val, void *priv) } -static uint8_t +uint8_t sff_bus_master_read(uint16_t port, void *priv) { sff8038i_t *dev = (sff8038i_t *) priv; @@ -225,6 +230,9 @@ sff_bus_master_read(uint16_t port, void *priv) case 0: ret = dev->command; break; + case 1: + ret = dev->dma_mode & 0x03; + break; case 2: ret = dev->status & 0x67; break; @@ -257,6 +265,7 @@ sff_bus_master_readw(uint16_t port, void *priv) switch (port & 7) { case 0: + case 1: case 2: ret = (uint16_t) sff_bus_master_read(port, priv); break; @@ -283,6 +292,7 @@ sff_bus_master_readl(uint16_t port, void *priv) switch (port & 7) { case 0: + case 1: case 2: ret = (uint32_t) sff_bus_master_read(port, priv); break; @@ -297,7 +307,7 @@ sff_bus_master_readl(uint16_t port, void *priv) } -static int +int sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv) { sff8038i_t *dev = (sff8038i_t *) priv; @@ -311,8 +321,10 @@ sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, voi sop = out ? "Read" : "Writ"; #endif - if (!(dev->status & 1)) + if (!(dev->status & 1)) { + sff_log("DMA disabled\n"); return 2; /*DMA disabled*/ + } sff_log("SFF-8038i Bus master %s: %i bytes\n", out ? "write" : "read", transfer_length); @@ -373,31 +385,50 @@ sff_bus_master_set_irq(int channel, void *priv) uint8_t irq = !!(channel & 0x40); if (!(dev->status & 0x04) || (channel & 0x40)) { - dev->status &= ~4; + dev->status &= ~0x04; dev->status |= (channel >> 4); } channel &= 0x01; - if (irq) { - sff_log("SFF8038i: Channel %i IRQ raise\n", channel); - if (dev->irq_mode[channel] == 3) - picintlevel(1 << dev->irq_line); - else if ((dev->irq_mode[channel] == 2) && channel && pci_use_mirq(0)) - pci_set_mirq(0, 0); - else if (dev->irq_mode[channel] == 1) - pci_set_irq(dev->slot, dev->irq_pin); - else - picint(1 << (14 + channel)); - } else { - sff_log("SFF8038i: Channel %i IRQ lower\n", channel); - if (dev->irq_mode[channel] == 3) - picintc(1 << dev->irq_line); - else if ((dev->irq_mode[channel] == 2) && channel && pci_use_mirq(0)) - pci_clear_mirq(0, 0); - else if (dev->irq_mode[channel] == 1) - pci_clear_irq(dev->slot, dev->irq_pin); - else - picintc(1 << (14 + channel)); + + switch (dev->irq_mode[channel]) { + case 0: + default: + /* Legacy IRQ mode. */ + if (irq) + picint(1 << (14 + channel)); + else + picintc(1 << (14 + channel)); + break; + case 1: + /* Native PCI IRQ mode with interrupt pin. */ + if (irq) + pci_set_irq(dev->slot, dev->irq_pin); + else + pci_clear_irq(dev->slot, dev->irq_pin); + break; + case 2: + case 5: + /* MIRQ 0 or 1. */ + if (irq) + pci_set_mirq(dev->irq_mode[channel] & 1, 0); + else + pci_clear_mirq(dev->irq_mode[channel] & 1, 0); + break; + case 3: + /* Native PCI IRQ mode with specified interrupt line. */ + if (irq) + picintlevel(1 << dev->irq_line); + else + picintc(1 << dev->irq_line); + break; + case 4: + /* ALi Aladdin Native PCI INTAJ mode. */ + if (irq) + pci_set_mirq(channel + 2, dev->irq_level[channel]); + else + pci_clear_mirq(channel + 2, dev->irq_level[channel]); + break; } } @@ -470,10 +501,42 @@ sff_set_irq_line(sff8038i_t *dev, int irq_line) } +void +sff_set_irq_level(sff8038i_t *dev, int channel, int irq_level) +{ + dev->irq_level[channel] = 0; +} + + void sff_set_irq_mode(sff8038i_t *dev, int channel, int irq_mode) { dev->irq_mode[channel] = irq_mode; + + switch (dev->irq_mode[channel]) { + case 0: + default: + /* Legacy IRQ mode. */ + sff_log("[%08X] Setting channel %i to legacy IRQ %i\n", dev, channel, 14 + channel); + break; + case 1: + /* Native PCI IRQ mode with interrupt pin. */ + sff_log("[%08X] Setting channel %i to native PCI INT%c\n", dev, channel, '@' + dev->irq_pin); + break; + case 2: + case 5: + /* MIRQ 0 or 1. */ + sff_log("[%08X] Setting channel %i to PCI MIRQ%i\n", dev, channel, irq_mode & 1); + break; + case 3: + /* Native PCI IRQ mode with specified interrupt line. */ + sff_log("[%08X] Setting channel %i to native PCI IRQ %i\n", dev, channel, dev->irq_line); + break; + case 4: + /* ALi Aladdin Native PCI INTAJ mode. */ + sff_log("[%08X] Setting channel %i to INT%cJ\n", dev, channel, 'A' + channel); + break; + } } @@ -510,9 +573,11 @@ static void ide_set_bus_master(next_id, sff_bus_master_dma, sff_bus_master_set_irq, dev); dev->slot = 7; - dev->irq_mode[0] = dev->irq_mode[1] = 2; + dev->irq_mode[0] = 0; /* Channel 0 goes to IRQ 14. */ + dev->irq_mode[1] = 2; /* Channel 1 goes to MIRQ0. */ dev->irq_pin = PCI_INTA; dev->irq_line = 14; + dev->irq_level[0] = dev->irq_level[1] = 0; next_id++; diff --git a/src/dma.c b/src/dma.c index 54e97f9e6..aa91ad988 100644 --- a/src/dma.c +++ b/src/dma.c @@ -166,6 +166,28 @@ dma_block_transfer(int channel) } +static void +dma_mem_to_mem_transfer(void) +{ + int i; + + if ((dma[0].mode & 0x0c) != 0x08) + fatal("DMA memory to memory transfer: channel 0 mode not read\n"); + if ((dma[1].mode & 0x0c) != 0x04) + fatal("DMA memory to memory transfer: channel 1 mode not write\n"); + + dma_req_is_soft = 1; + + for (i = 0; i <= dma[0].cb; i++) + dma_buffer[i] = dma_channel_read(0); + + for (i = 0; i <= dma[1].cb; i++) + dma_channel_write(1, dma_buffer[i]); + + dma_req_is_soft = 0; +} + + static void dma_sg_write(uint16_t port, uint8_t val, void *priv) { @@ -506,14 +528,18 @@ dma_write(uint16_t addr, uint8_t val, void *priv) case 8: /*Control register*/ dma_command[0] = val; if (val & 0x01) - fatal("Memory-to-memory enable\n"); + pclog("[%08X:%04X] Memory-to-memory enable\n", CS, cpu_state.pc); return; case 9: /*Request register */ channel = (val & 3); if (val & 4) { dma_stat_rq_pc |= (1 << channel); - dma_block_transfer(channel); + if ((channel == 0) && (dma_command[0] & 0x01)) { + pclog("Memory to memory transfer start\n"); + dma_mem_to_mem_transfer(); + } else + dma_block_transfer(channel); } else dma_stat_rq_pc &= ~(1 << channel); break; diff --git a/src/include/86box/acpi.h b/src/include/86box/acpi.h index 91c63b74e..10facb21e 100644 --- a/src/include/86box/acpi.h +++ b/src/include/86box/acpi.h @@ -61,7 +61,7 @@ typedef struct { uint8_t acpitst, auxen, auxsts, plvl2, plvl3, smicmd, gpio_dir, - gpio_val, muxcntrl, pad, + gpio_val, muxcntrl, ali_soft_smi, timer32, smireg, gpireg[3], gporeg[4], extiotrapsts, extiotrapen; @@ -92,7 +92,8 @@ typedef struct uint16_t io_base, aux_io_base; int vendor, slot, irq_mode, - irq_pin, irq_line; + irq_pin, irq_line, + mirq_is_level; pc_timer_t timer, resume_timer; nvr_t *nvr; apm_t *apm; @@ -114,7 +115,7 @@ extern const device_t acpi_via_596b_device; /* Functions */ extern void acpi_update_irq(acpi_t *dev); -extern void acpi_raise_smi(acpi_t *dev); +extern void acpi_raise_smi(void *priv, int do_smi); extern void acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en); extern void acpi_update_aux_io_mapping(acpi_t *dev, uint32_t base, int chipset_en); extern void acpi_init_gporeg(acpi_t *dev, uint8_t val0, uint8_t val1, uint8_t val2, uint8_t val3); @@ -123,9 +124,12 @@ extern void acpi_set_slot(acpi_t *dev, int slot); extern void acpi_set_irq_mode(acpi_t *dev, int irq_mode); extern void acpi_set_irq_pin(acpi_t *dev, int irq_pin); extern void acpi_set_irq_line(acpi_t *dev, int irq_line); +extern void acpi_set_mirq_is_level(acpi_t *dev, int mirq_is_level); extern void acpi_set_gpireg2_default(acpi_t *dev, uint8_t gpireg2_default); extern void acpi_set_nvr(acpi_t *dev, nvr_t *nvr); extern void acpi_set_trap_update(acpi_t *dev, void (*update)(void *priv), void *priv); +extern uint8_t acpi_ali_soft_smi_status_read(acpi_t *dev); +extern void acpi_ali_soft_smi_status_write(acpi_t *dev, uint8_t soft_smi); #ifdef __cplusplus } diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 3ea2e52f8..ae97b156e 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -24,18 +24,22 @@ extern const device_t acc2168_device; /* ALi */ extern const device_t ali1217_device; extern const device_t ali1429_device; +extern const device_t ali1429g_device; extern const device_t ali1489_device; -#if defined(DEV_BRANCH) && defined(USE_M154X) extern const device_t ali1531_device; +extern const device_t ali1541_device; extern const device_t ali1543_device; -#endif -#if defined(DEV_BRANCH) && defined(USE_M6117) +extern const device_t ali1543c_device; +extern const device_t ali1621_device; extern const device_t ali6117d_device; -#endif /* AMD */ extern const device_t amd640_device; +/* Contaq/Cypress */ +extern const device_t contaq_82c596a_device; +extern const device_t contaq_82c597_device; + /* C&T */ extern const device_t ct_82c100_device; extern const device_t neat_device; @@ -45,9 +49,6 @@ extern const device_t scat_sx_device; extern const device_t cs8230_device; extern const device_t cs4031_device; -/* ETEQ */ -extern const device_t et6000_device; - /* G2 */ extern const device_t gc100_device; extern const device_t gc100a_device; @@ -58,9 +59,13 @@ extern const device_t headland_ht18a_device; extern const device_t headland_ht18b_device; extern const device_t headland_ht18c_device; +/* IMS */ +extern const device_t ims8848_device; + /* Intel */ extern const device_t intel_82335_device; extern const device_t i420ex_device; +extern const device_t i420ex_ide_device; extern const device_t i420tx_device; extern const device_t i420zx_device; extern const device_t i430lx_device; @@ -78,10 +83,7 @@ extern const device_t i440bx_device; extern const device_t i440bx_no_agp_device; extern const device_t i440gx_device; extern const device_t i440zx_device; - -#if defined(DEV_BRANCH) && defined(USE_I450KX) extern const device_t i450kx_device; -#endif extern const device_t sio_device; extern const device_t sio_zb_device; @@ -128,11 +130,10 @@ extern const device_t stpc_serial_device; extern const device_t stpc_lpt_device; /* UMC */ -extern const device_t umc_hb4_device; -extern const device_t umc_8890_device; - +extern const device_t umc_um82c49x_device; extern const device_t umc_8886f_device; extern const device_t umc_8886af_device; +extern const device_t umc_hb4_device; /* VIA */ extern const device_t via_vt82c49x_device; @@ -155,6 +156,7 @@ extern const device_t via_vt8231_device; /* VLSI */ extern const device_t vl82c480_device; +extern const device_t vl82c486_device; extern const device_t vlsi_scamp_device; /* WD */ @@ -162,7 +164,7 @@ extern const device_t wd76c10_device; /* Miscellaneous Hardware */ extern const device_t phoenix_486_jumper_device; -extern const device_t vpc2007_device; +extern const device_t phoenix_486_jumper_pci_device; #if defined(DEV_BRANCH) && defined(USE_OLIVETTI) extern const device_t olivetti_eva_device; diff --git a/src/include/86box/config.h b/src/include/86box/config.h index 549306daa..b630d0c80 100644 --- a/src/include/86box/config.h +++ b/src/include/86box/config.h @@ -110,9 +110,9 @@ typedef struct { /* Ports category */ char parallel_devices[3][32]; /* LPT device names */ #ifdef USE_SERIAL_DEVICES - char serial_devices[2][32]; /* Serial device names */ + char serial_devices[4][32]; /* Serial device names */ #endif - int serial_enabled[2], /* Serial ports 1 and 2 enabled */ + int serial_enabled[4], /* Serial ports 1 and 2 enabled */ parallel_enabled[3]; /* LPT1, LPT2, LPT3 enabled */ /* Other peripherals category */ diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index 9175dddaf..1008b38c9 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -56,6 +56,9 @@ extern const device_t ide_cmd640_vlb_178_device; /* CMD PCI-640B VLB (Port 178h extern const device_t ide_cmd640_pci_device; /* CMD PCI-640B PCI */ extern const device_t ide_cmd640_pci_legacy_only_device; /* CMD PCI-640B PCI (Legacy Mode Only) */ extern const device_t ide_cmd640_pci_single_channel_device; /* CMD PCI-640B PCI (Only primary channel) */ +extern const device_t ide_cmd646_device; /* CMD PCI-646 */ +extern const device_t ide_cmd646_legacy_only_device; /* CMD PCI-646 (Legacy Mode Only) */ +extern const device_t ide_cmd646_single_channel_device; /* CMD PCI-646 (Only primary channel) */ extern const device_t ide_opti611_vlb_device; /* OPTi 82c611/611A VLB */ diff --git a/src/include/86box/hdc_ide.h b/src/include/86box/hdc_ide.h index 20742004e..d6914b905 100644 --- a/src/include/86box/hdc_ide.h +++ b/src/include/86box/hdc_ide.h @@ -153,5 +153,8 @@ extern int (*ide_bus_master_dma)(int channel, uint8_t *data, int transfer_length extern void (*ide_bus_master_set_irq)(int channel, void *priv); extern void *ide_bus_master_priv[2]; +extern uint8_t ide_read_ali_75(void); +extern uint8_t ide_read_ali_76(void); + #endif /*EMU_IDE_H*/ diff --git a/src/include/86box/hdc_ide_sff8038i.h b/src/include/86box/hdc_ide_sff8038i.h index 43288aa99..700684dae 100644 --- a/src/include/86box/hdc_ide_sff8038i.h +++ b/src/include/86box/hdc_ide_sff8038i.h @@ -19,14 +19,16 @@ typedef struct { uint8_t command, status, - ptr0, enabled; - uint16_t base, pad; + ptr0, enabled, + dma_mode, pad, + pad0, pad1; + uint16_t base, pad2; uint32_t ptr, ptr_cur, addr; int count, eot, slot, - irq_mode[2], irq_pin, - irq_line; + irq_mode[2], irq_level[2], + irq_pin, irq_line; } sff8038i_t; @@ -39,6 +41,11 @@ extern int sff_bus_master_dma_write(int channel, uint8_t *data, int transfer_len extern void sff_bus_master_set_irq(int channel, void *priv); +extern int sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv); + +extern void sff_bus_master_write(uint16_t port, uint8_t val, void *priv); +extern uint8_t sff_bus_master_read(uint16_t port, void *priv); + extern void sff_bus_master_reset(sff8038i_t *dev, uint16_t old_base); extern void sff_set_slot(sff8038i_t *dev, int slot); @@ -47,3 +54,5 @@ extern void sff_set_irq_line(sff8038i_t *dev, int irq_line); extern void sff_set_irq_mode(sff8038i_t *dev, int channel, int irq_mode); extern void sff_set_irq_pin(sff8038i_t *dev, int irq_pin); + +extern void sff_set_irq_level(sff8038i_t *dev, int channel, int irq_level); diff --git a/src/include/86box/hwm.h b/src/include/86box/hwm.h index 6172ec693..ef5621da6 100644 --- a/src/include/86box/hwm.h +++ b/src/include/86box/hwm.h @@ -36,6 +36,7 @@ typedef struct { uint8_t regs[8]; uint8_t addr_register; uint8_t i2c_addr: 7, i2c_state: 2; + uint8_t i2c_enabled: 1; } lm75_t; @@ -63,6 +64,7 @@ extern const device_t lm75_w83781d_device; extern const device_t lm78_device; extern const device_t w83781d_device; +extern const device_t w83781d_p5a_device; extern const device_t as99127f_device; extern const device_t as99127f_rev2_device; extern const device_t w83782d_device; diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 3ca6089cc..206feeefc 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -72,14 +72,12 @@ extern const device_t keyboard_xt_olivetti_device; extern const device_t keyboard_xt_zenith_device; extern const device_t keyboard_at_device; extern const device_t keyboard_at_ami_device; -extern const device_t keyboard_at_samsung_device; extern const device_t keyboard_at_toshiba_device; extern const device_t keyboard_at_olivetti_device; extern const device_t keyboard_at_ncr_device; extern const device_t keyboard_ps2_device; extern const device_t keyboard_ps2_ps1_device; extern const device_t keyboard_ps2_ps1_pci_device; -extern const device_t keyboard_ps2_ps2_device; extern const device_t keyboard_ps2_xi8088_device; extern const device_t keyboard_ps2_ami_device; extern const device_t keyboard_ps2_olivetti_device; @@ -108,12 +106,15 @@ extern int keyboard_isfsexit(void); extern int keyboard_ismsexit(void); extern void keyboard_set_is_amstrad(int ams); -extern void keyboard_at_adddata_keyboard_raw(uint8_t val); extern void keyboard_at_adddata_mouse(uint8_t val); +extern void keyboard_at_adddata_mouse_direct(uint8_t val); +extern void keyboard_at_adddata_mouse_cmd(uint8_t val); extern void keyboard_at_mouse_reset(void); extern uint8_t keyboard_at_mouse_pos(void); +extern int keyboard_at_fixed_channel(void); extern void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val,void *), void *); extern void keyboard_at_set_a20_key(int state); +extern void keyboard_at_set_mode(int ps2); extern uint8_t keyboard_at_get_mouse_scan(void); extern void keyboard_at_set_mouse_scan(uint8_t val); extern void keyboard_at_reset(void); diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 50cedccca..2767789b3 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -98,9 +98,11 @@ enum { MACHINE_TYPE_8086, MACHINE_TYPE_286, MACHINE_TYPE_386SX, + MACHINE_TYPE_486SLC, MACHINE_TYPE_386DX, MACHINE_TYPE_386DX_486, MACHINE_TYPE_486, + MACHINE_TYPE_486_S2, MACHINE_TYPE_486_S3, MACHINE_TYPE_486_MISC, MACHINE_TYPE_SOCKET4, @@ -252,6 +254,8 @@ extern int machine_at_mr286_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_quadt386sx_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 *); @@ -273,20 +277,19 @@ 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_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_sbc_350a_init(const machine_t *); extern int machine_at_flytech386_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_awardsx_init(const machine_t *); -#if defined(DEV_BRANCH) && defined(USE_M6117) -extern int machine_at_arb1375_init(const machine_t *); -extern int machine_at_pja511m_init(const machine_t *); -#endif -extern int machine_at_pc916sx_init(const machine_t *); - -extern int machine_at_m30008_init(const machine_t *); -extern int machine_at_m30015_init(const machine_t *); +extern int machine_at_pc916sx_init(const machine_t *); #ifdef EMU_DEVICE_H extern const device_t *at_ama932j_get_device(void); @@ -294,7 +297,6 @@ extern const device_t *at_flytech386_get_device(void); extern const device_t *at_cmdsl386sx25_get_device(void); extern const device_t *at_spc4620p_get_device(void); extern const device_t *at_spc6033p_get_device(void); -extern const device_t *at_m30008_get_device(void); #endif /* m_at_386dx_486.c */ @@ -312,6 +314,9 @@ extern int machine_at_cs4031_init(const machine_t *); extern int machine_at_pb410a_init(const machine_t *); +extern int machine_at_decpc_lpv_init(const machine_t *); +extern int machine_at_acerv10_init(const machine_t *); + extern int machine_at_acera1g_init(const machine_t *); extern int machine_at_ali1429_init(const machine_t *); extern int machine_at_winbios1429_init(const machine_t *); @@ -323,9 +328,9 @@ extern int machine_at_opti495_mr_init(const machine_t *); extern int machine_at_vect486vl_init(const machine_t *); extern int machine_at_d824_init(const machine_t *); -extern int machine_at_pcs46c_init(const machine_t *); - extern int machine_at_403tg_init(const machine_t *); +extern int machine_at_403tg_rev_d_init(const machine_t *); +extern int machine_at_403tg_rev_d_mr_init(const machine_t *); extern int machine_at_pc330_6573_init(const machine_t *); extern int machine_at_mvi486_init(const machine_t *); @@ -340,6 +345,7 @@ extern int machine_at_dtk486_init(const machine_t *); extern int machine_at_px471_init(const machine_t *); extern int machine_at_win471_init(const machine_t *); extern int machine_at_vi15g_init(const machine_t *); +extern int machine_at_green_b_init(const machine_t *); extern int machine_at_r418_init(const machine_t *); extern int machine_at_ls486e_init(const machine_t *); @@ -347,29 +353,42 @@ extern int machine_at_4dps_init(const machine_t *); extern int machine_at_4sa2_init(const machine_t *); extern int machine_at_m4li_init(const machine_t *); extern int machine_at_alfredo_init(const machine_t *); +extern int machine_at_ninja_init(const machine_t *); extern int machine_at_486sp3_init(const machine_t *); extern int machine_at_486sp3c_init(const machine_t *); extern int machine_at_486sp3g_init(const machine_t *); extern int machine_at_486ap4_init(const machine_t *); +extern int machine_at_g486vpa_init(const machine_t *); extern int machine_at_486vipio2_init(const machine_t *); extern int machine_at_abpb4_init(const machine_t *); extern int machine_at_win486pci_init(const machine_t *); +extern int machine_at_ms4145_init(const machine_t *); +extern int machine_at_sbc_490_init(const machine_t *); +extern int machine_at_tf_486_init(const machine_t *); -extern int machine_at_atc1415_init(const machine_t *); -extern int machine_at_ecs486_init(const machine_t *); -extern int machine_at_hot433_init(const machine_t *); +extern int machine_at_pci400c_b_init(const machine_t *); +extern int machine_at_g486ip_init(const machine_t *); extern int machine_at_itoxstar_init(const machine_t *); +extern int machine_at_arb1423c_init(const machine_t *); extern int machine_at_arb1479_init(const machine_t *); extern int machine_at_pcm9340_init(const machine_t *); extern int machine_at_pcm5330_init(const machine_t *); +extern int machine_at_ecs486_init(const machine_t *); +extern int machine_at_hot433_init(const machine_t *); +extern int machine_at_atc1415_init(const machine_t *); +extern int machine_at_actionpc2600_init(const machine_t *); +extern int machine_at_m919_init(const machine_t *); +extern int machine_at_spc7700p_lw_init(const machine_t *); + #ifdef EMU_DEVICE_H extern const device_t *at_acera1g_get_device(void); extern const device_t *at_vect486vl_get_device(void); extern const device_t *at_d824_get_device(void); extern const device_t *at_pcs46c_get_device(void); extern const device_t *at_valuepoint433_get_device(void); +extern const device_t *at_sbc_490_get_device(void); #endif /* m_at_commodore.c */ @@ -383,118 +402,144 @@ extern int machine_at_portableiii386_init(const machine_t *); extern const device_t *at_cpqiii_get_device(void); #endif -/* m_at_socket4_5.c */ -extern int machine_at_excalibur_init(const machine_t *); +/* m_at_socket4.c */ +extern void machine_at_premiere_common_init(const machine_t *, int); +extern void machine_at_award_common_init(const machine_t *); -extern int machine_at_pat54pv_init(const machine_t *); +extern void machine_at_sp4_common_init(const machine_t *model); -extern int machine_at_hot543_init(const machine_t *); -extern int machine_at_p54vl_init(const machine_t *); - -extern int machine_at_batman_init(const machine_t *); -extern int machine_at_ambradp60_init(const machine_t *); +extern int machine_at_excalibur_pci_init(const machine_t *); +extern int machine_at_p5mp3_init(const machine_t *); extern int machine_at_dellxp60_init(const machine_t *); extern int machine_at_opti560l_init(const machine_t *); +extern int machine_at_ambradp60_init(const machine_t *); extern int machine_at_valuepointp60_init(const machine_t *); -extern int machine_at_p5mp3_init(const machine_t *); -extern int machine_at_pb520r_init(const machine_t *); +extern int machine_at_revenge_init(const machine_t *); extern int machine_at_586mc1_init(const machine_t *); +extern int machine_at_pb520r_init(const machine_t *); +extern int machine_at_excalibur_init(const machine_t *); + +extern int machine_at_p5vl_init(const machine_t *); + +extern int machine_at_excalibur_pci_2_init(const machine_t *); +extern int machine_at_p5sp4_init(const machine_t *); + +#ifdef EMU_DEVICE_H +extern const device_t *at_pb520r_get_device(void); +#endif + +/* m_at_socket5.c */ extern int machine_at_plato_init(const machine_t *); extern int machine_at_ambradp90_init(const machine_t *); extern int machine_at_430nx_init(const machine_t *); -extern int machine_at_p54tp4xe_init(const machine_t *); -extern int machine_at_endeavor_init(const machine_t *); -extern int machine_at_zappa_init(const machine_t *); -extern int machine_at_mb500n_init(const machine_t *); -extern int machine_at_apollo_init(const machine_t *); -extern int machine_at_vectra54_init(const machine_t *); -extern int machine_at_powermatev_init(const machine_t *); extern int machine_at_acerv30_init(const machine_t *); +extern int machine_at_apollo_init(const machine_t *); +extern int machine_at_exp8551_init(const machine_t *); +extern int machine_at_vectra54_init(const machine_t *); +extern int machine_at_zappa_init(const machine_t *); +extern int machine_at_powermatev_init(const machine_t *); +extern int machine_at_mb500n_init(const machine_t *); +extern int machine_at_hawk_init(const machine_t *); + +extern int machine_at_pat54pv_init(const machine_t *); + +extern int machine_at_hot543_init(const machine_t *); -extern int machine_at_p5sp4_init(const machine_t *); extern int machine_at_p54sp4_init(const machine_t *); extern int machine_at_sq588_init(const machine_t *); -extern int machine_at_hot539_init(const machine_t *); +#ifdef EMU_DEVICE_H +#define at_vectra54_get_device at_endeavor_get_device +#endif + +/* m_at_socket7_3v.c */ +extern int machine_at_p54tp4xe_init(const machine_t *); +extern int machine_at_mr586_init(const machine_t *); +extern int machine_at_gw2katx_init(const machine_t *); +extern int machine_at_thor_init(const machine_t *); +extern int machine_at_mrthor_init(const machine_t *); +extern int machine_at_endeavor_init(const machine_t *); +extern int machine_at_ms5119_init(const machine_t *); +extern int machine_at_pb640_init(const machine_t *); +extern int machine_at_fmb_init(const machine_t *); + +extern int machine_at_acerm3a_init(const machine_t *); +extern int machine_at_ap53_init(const machine_t *); +extern int machine_at_8500tuc_init(const machine_t *); +extern int machine_at_p55t2s_init(const machine_t *); + +extern int machine_at_p5vxb_init(const machine_t *); +extern int machine_at_gw2kte_init(const machine_t *); + +extern int machine_at_ap5s_init(const machine_t *); #ifdef EMU_DEVICE_H extern const device_t *at_endeavor_get_device(void); -#define at_vectra54_get_device at_endeavor_get_device -extern const device_t *at_pb520r_get_device(void); extern const device_t *at_thor_get_device(void); +#define at_mrthor_get_device at_thor_get_device +extern const device_t *at_pb640_get_device(void); #endif -/* m_at_socket7_s7.c */ -extern int machine_at_ap5s_init(const machine_t *); - -extern int machine_at_chariot_init(const machine_t *); -extern int machine_at_mr586_init(const machine_t *); -extern int machine_at_thor_init(const machine_t *); -extern int machine_at_gw2katx_init(const machine_t *); -extern int machine_at_mrthor_init(const machine_t *); -extern int machine_at_pb640_init(const machine_t *); - -extern int machine_at_acerm3a_init(const machine_t *); +/* m_at_socket7.c */ extern int machine_at_acerv35n_init(const machine_t *); -extern int machine_at_ap53_init(const machine_t *); extern int machine_at_p55t2p4_init(const machine_t *); -extern int machine_at_p55t2s_init(const machine_t *); -extern int machine_at_8500tuc_init(const machine_t *); extern int machine_at_m7shi_init(const machine_t *); extern int machine_at_tc430hx_init(const machine_t *); extern int machine_at_equium5200_init(const machine_t *); extern int machine_at_pcv240_init(const machine_t *); extern int machine_at_p65up5_cp55t2d_init(const machine_t *); -extern int machine_at_mb520n_init(const machine_t *); +extern int machine_at_ap5vm_init(const machine_t *); extern int machine_at_p55tvp4_init(const machine_t *); -extern int machine_at_p55va_init(const machine_t *); -extern int machine_at_i430vx_init(const machine_t *); extern int machine_at_5ivg_init(const machine_t *); -extern int machine_at_brio80xx_init(const machine_t *); extern int machine_at_8500tvxa_init(const machine_t *); extern int machine_at_presario2240_init(const machine_t *); extern int machine_at_presario4500_init(const machine_t *); -extern int machine_at_gw2kte_init(const machine_t *); +extern int machine_at_p55va_init(const machine_t *); +extern int machine_at_brio80xx_init(const machine_t *); extern int machine_at_pb680_init(const machine_t *); +extern int machine_at_mb520n_init(const machine_t *); +extern int machine_at_i430vx_init(const machine_t *); extern int machine_at_nupro592_init(const machine_t *); extern int machine_at_tx97_init(const machine_t *); -extern int machine_at_ym430tx_init(const machine_t *); #if defined(DEV_BRANCH) && defined(NO_SIO) extern int machine_at_an430tx_init(const machine_t *); #endif +extern int machine_at_ym430tx_init(const machine_t *); extern int machine_at_mb540n_init(const machine_t *); extern int machine_at_p5mms98_init(const machine_t *); -extern int machine_at_r534f_init(const machine_t *); -extern int machine_at_ms5146_init(const machine_t *); - -#if defined(DEV_BRANCH) && defined(USE_M154X) -extern int machine_at_m560_init(const machine_t *); -extern int machine_at_ms5164_init(const machine_t *); -#endif - extern int machine_at_ficva502_init(const machine_t *); extern int machine_at_ficpa2012_init(const machine_t *); +extern int machine_at_r534f_init(const machine_t *); +extern int machine_at_ms5146_init(const machine_t *); + +extern int machine_at_m560_init(const machine_t *); +extern int machine_at_ms5164_init(const machine_t *); + #ifdef EMU_DEVICE_H -extern const device_t *at_thor_get_device(void); -extern const device_t *at_pb640_get_device(void); +extern const device_t *at_presario2240_get_device(void); +#define at_presario4500_get_device at_presario2240_get_device #endif -/* m_at_super7_ss7.c */ +/* m_at_sockets7.c */ +extern int machine_at_p5a_init(const machine_t *); +extern int machine_at_m579_init(const machine_t *); +extern int machine_at_ga_5aa_init(const machine_t *); +extern int machine_at_ga_5ax_init(const machine_t *); + extern int machine_at_ax59pro_init(const machine_t *); extern int machine_at_mvp3_init(const machine_t *); extern int machine_at_ficva503a_init(const machine_t *); +extern int machine_at_sy_5ema_pro_init(const machine_t *); /* m_at_socket8.c */ -#if defined(DEV_BRANCH) && defined(USE_I450KX) extern int machine_at_p6rp4_init(const machine_t *); -#endif extern int machine_at_686nx_init(const machine_t *); extern int machine_at_v60n_init(const machine_t *); @@ -509,6 +554,8 @@ extern void machine_at_p65up5_common_init(const machine_t *, const device_t *nor extern int machine_at_p65up5_cp6nd_init(const machine_t *); /* m_at_slot1.c */ +extern int machine_at_m729_init(const machine_t *); + extern int machine_at_p65up5_cpknd_init(const machine_t *); extern int machine_at_kn97_init(const machine_t *); @@ -525,9 +572,6 @@ extern int machine_at_atc6310bxii_init(const machine_t *); extern int machine_at_686bx_init(const machine_t *); extern int machine_at_tsunamiatx_init(const machine_t *); extern int machine_at_p6sba_init(const machine_t *); -#if defined(DEV_BRANCH) && defined(NO_SIO) -extern int machine_at_ergox365_init(const machine_t *); -#endif extern int machine_at_ficka6130_init(const machine_t *); extern int machine_at_p3v133_init(const machine_t *); extern int machine_at_p3v4x_init(const machine_t *); @@ -651,10 +695,6 @@ extern int machine_xt_pc500_init(const machine_t *); extern int machine_xt_iskra3104_init(const machine_t *); -#if defined(DEV_BRANCH) && defined(USE_HEDAKA) -extern int machine_xt_hed919_init(const machine_t *); -#endif - /* m_xt_compaq.c */ extern int machine_xt_compaq_deskpro_init(const machine_t *); extern int machine_xt_compaq_portable_init(const machine_t *); diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 700c92981..5d1f6848c 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -64,6 +64,15 @@ #define ACCESS_READ 1 #define ACCESS_WRITE 2 +#define ACCESS_SMRAM_OFF 0 +#define ACCESS_SMRAM_X 1 +#define ACCESS_SMRAM_W 2 +#define ACCESS_SMRAM_WX 3 +#define ACCESS_SMRAM_R 4 +#define ACCESS_SMRAM_RX 5 +#define ACCESS_SMRAM_RW 6 +#define ACCESS_SMRAM_RWX 7 + /* Conversion #define's - we need these to seamlessly convert the old mem_set_mem_state() calls to the new stuff in order to make this a drop in replacement. @@ -80,7 +89,10 @@ /* Internal execute access, external read access. */ #define MEM_READ_EXTERNAL_EX 0 #define MEM_READ_SMRAM (ACCESS_X_SMRAM | ACCESS_R_SMRAM) +#define MEM_READ_CACHE (ACCESS_X_CACHE | ACCESS_R_CACHE) #define MEM_READ_SMRAM_EX (ACCESS_X_SMRAM) +#define MEM_EXEC_SMRAM MEM_READ_SMRAM_EX +#define MEM_READ_SMRAM_2 (ACCESS_R_SMRAM) /* Theese two are going to be identical. */ #define MEM_READ_DISABLED_EX MEM_READ_DISABLED #define MEM_READ_MASK 0x7c1f @@ -93,6 +105,7 @@ #define MEM_WRITE_ROMCS (ACCESS_W_ROMCS) #define MEM_WRITE_EXTANY (ACCESS_W_ROMCS) #define MEM_WRITE_SMRAM (ACCESS_W_SMRAM) +#define MEM_WRITE_CACHE (ACCESS_W_CACHE) /* Theese two are going to be identical. */ #define MEM_WRITE_DISABLED_EX MEM_READ_DISABLED #define MEM_WRITE_MASK 0x03e0 @@ -132,10 +145,18 @@ mem_set_access(ACCESS_SMM, 0, base, size, access) #define mem_set_mem_state_both(base, size, access) \ mem_set_access(ACCESS_ALL, 0, base, size, access) +#define mem_set_mem_state_cpu_both(base, size, access) \ + mem_set_access(ACCESS_CPU_BOTH, 0, base, size, access) +#define mem_set_mem_state_bus_both(base, size, access) \ + mem_set_access(ACCESS_BUS_BOTH, 0, base, size, access) #define mem_set_mem_state_smram(smm, base, size, is_smram) \ mem_set_access((smm ? ACCESS_SMM : ACCESS_NORMAL), 1, base, size, is_smram) #define mem_set_mem_state_smram_ex(smm, base, size, is_smram) \ mem_set_access((smm ? ACCESS_SMM : ACCESS_NORMAL), 2, base, size, is_smram) +#define mem_set_access_smram_cpu(smm, base, size, is_smram) \ + mem_set_access((smm ? ACCESS_CPU_SMM : ACCESS_CPU), 1, base, size, is_smram) +#define mem_set_access_smram_bus(smm, base, size, is_smram) \ + mem_set_access((smm ? ACCESS_BUS_SMM : ACCESS_BUS), 1, base, size, is_smram) #define flushmmucache_cr3 \ flushmmucache_nopc diff --git a/src/include/86box/nvr.h b/src/include/86box/nvr.h index f1776bf79..386954b54 100644 --- a/src/include/86box/nvr.h +++ b/src/include/86box/nvr.h @@ -95,6 +95,7 @@ extern const device_t piix4_nvr_device; extern const device_t ls486e_nvr_device; extern const device_t ami_apollo_nvr_device; extern const device_t via_nvr_device; +extern const device_t p6rp4_nvr_device; #endif diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index 210ff1d4e..b9fa700bf 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -45,9 +45,15 @@ #define PCI_MIRQ1 1 #define PCI_MIRQ2 2 #define PCI_MIRQ3 3 +#define PCI_MIRQ4 4 +#define PCI_MIRQ5 5 +#define PCI_MIRQ6 6 +#define PCI_MIRQ7 7 #define PCI_IRQ_DISABLED -1 +#define PCI_ADD_STRICT 0x80 + enum { PCI_CARD_NORTHBRIDGE = 0, PCI_CARD_AGPBRIDGE, @@ -119,10 +125,14 @@ extern void trc_init(void); extern uint8_t trc_read(uint16_t port, void *priv); extern void trc_write(uint16_t port, uint8_t val, void *priv); +extern void pci_bridge_set_ctl(void *priv, uint8_t ctl); + #ifdef EMU_DEVICE_H extern const device_t dec21150_device; +extern const device_t ali5243_agp_device; +extern const device_t ali5247_agp_device; extern const device_t i440lx_agp_device; extern const device_t i440bx_agp_device; extern const device_t i440gx_agp_device; diff --git a/src/include/86box/pic.h b/src/include/86box/pic.h index 50ed0914e..33be66135 100644 --- a/src/include/86box/pic.h +++ b/src/include/86box/pic.h @@ -33,6 +33,11 @@ typedef struct pic { extern pic_t pic, pic2; +extern void pic_reset_smi_irq_mask(void); +extern void pic_set_smi_irq_mask(int irq, int set); +extern uint16_t pic_get_smi_irq_status(void); +extern void pic_clear_smi_irq_status(int irq); + extern int pic_elcr_get_enabled(void); extern void pic_elcr_set_enabled(int enabled); extern void pic_elcr_io_handler(int set); @@ -40,6 +45,7 @@ extern void pic_elcr_write(uint16_t port, uint8_t val, void *priv); extern uint8_t pic_elcr_read(uint16_t port, void *priv); extern void pic_set_shadow(int sh); +extern void pic_set_pci(void); extern void pic_init(void); extern void pic_init_pcjr(void); extern void pic2_init(void); diff --git a/src/include/86box/port_6x.h b/src/include/86box/port_6x.h new file mode 100644 index 000000000..74172728a --- /dev/null +++ b/src/include/86box/port_6x.h @@ -0,0 +1,38 @@ +/* + * 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. + * + * Header for the implementation of Port 6x used by various + * machines. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2021 Miran Grca. + */ +#ifndef EMU_PORT_6X_H +# define EMU_PORT_6X_H + + +#ifdef _TIMER_H_ +typedef struct +{ + uint8_t refresh, flags; + + pc_timer_t refresh_timer; +} port_6x_t; +#endif + + +extern const device_t port_6x_device; +extern const device_t port_6x_xi8088_device; +extern const device_t port_6x_ps2_device; +extern const device_t port_6x_olivetti_device; + + +#endif /*EMU_PORT_6X_H*/ diff --git a/src/include/86box/serial.h b/src/include/86box/serial.h index 0b6b99aa5..f580f9f9f 100644 --- a/src/include/86box/serial.h +++ b/src/include/86box/serial.h @@ -27,6 +27,8 @@ #define SERIAL_NS16450 2 #define SERIAL_NS16550 3 +#define SERIAL_FIFO_SIZE 16 + /* Default settings for the standard ports. */ #define SERIAL1_ADDR 0x03f8 #define SERIAL1_IRQ 4 @@ -54,7 +56,7 @@ typedef struct serial_s uint8_t rcvr_fifo_pos, xmit_fifo_pos, pad0, pad1, - rcvr_fifo[16], xmit_fifo[16]; + rcvr_fifo[SERIAL_FIFO_SIZE], xmit_fifo[SERIAL_FIFO_SIZE]; pc_timer_t transmit_timer, timeout_timer; double clock_src, transmit_period; diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index f409f4d48..667f39276 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -22,12 +22,14 @@ extern const device_t acc3221_device; extern const device_t f82c710_device; extern const device_t f82c606_device; extern const device_t fdc37c651_device; +extern const device_t fdc37c651_ide_device; extern const device_t fdc37c661_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 fdc37c666_device; +extern const device_t fdc37c67x_device; extern const device_t fdc37c669_device; extern const device_t fdc37c669_370_device; extern const device_t fdc37c931apm_device; @@ -54,6 +56,7 @@ 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 pc97307_device; extern const device_t prime3b_device; diff --git a/src/include/86box/smbus.h b/src/include/86box/smbus.h new file mode 100644 index 000000000..6661a25c6 --- /dev/null +++ b/src/include/86box/smbus.h @@ -0,0 +1,70 @@ +/* + * 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. + * + * Definitions for the SMBus host controllers. + * + * + * + * Authors: RichardG, + * + * Copyright 2020 RichardG. + */ +#ifndef EMU_SMBUS_PIIX4_H +# define EMU_SMBUS_PIIX4_H + + +#define SMBUS_PIIX4_BLOCK_DATA_SIZE 32 +#define SMBUS_PIIX4_BLOCK_DATA_MASK (SMBUS_PIIX4_BLOCK_DATA_SIZE - 1) + +#define SMBUS_ALI7101_BLOCK_DATA_SIZE 32 +#define SMBUS_ALI7101_BLOCK_DATA_MASK (SMBUS_ALI7101_BLOCK_DATA_SIZE - 1) + + +enum { + SMBUS_PIIX4 = 0, + SMBUS_VIA +}; + +typedef struct { + uint32_t local; + uint16_t io_base; + int clock; + double bit_period; + uint8_t stat, next_stat, ctl, cmd, addr, + data0, data1, + index, data[SMBUS_PIIX4_BLOCK_DATA_SIZE]; + pc_timer_t response_timer; + void *i2c; +} smbus_piix4_t; + +typedef struct { + uint32_t local; + uint16_t io_base; + uint8_t stat, next_stat, ctl, cmd, addr, + data0, data1, + index, data[SMBUS_ALI7101_BLOCK_DATA_SIZE]; + pc_timer_t response_timer; + void *i2c; +} smbus_ali7101_t; + + +extern void smbus_piix4_remap(smbus_piix4_t *dev, uint16_t new_io_base, uint8_t enable); +extern void smbus_piix4_setclock(smbus_piix4_t *dev, int clock); + +extern void smbus_ali7101_remap(smbus_ali7101_t *dev, uint16_t new_io_base, uint8_t enable); + + +#ifdef EMU_DEVICE_H +extern const device_t piix4_smbus_device; +extern const device_t via_smbus_device; + +extern const device_t ali7101_smbus_device; +#endif + + +#endif /*EMU_SMBUS_PIIX4_H*/ diff --git a/src/include/86box/smram.h b/src/include/86box/smram.h index 3d91c1e96..996e5df30 100644 --- a/src/include/86box/smram.h +++ b/src/include/86box/smram.h @@ -39,12 +39,19 @@ extern void smram_recalc_all(int ret); extern void smram_del(smram_t *smr); /* Add a SMRAM mapping. */ extern smram_t *smram_add(void); +/* Set memory state in the specified model (normal or SMM) according to the specified flags, + separately for bus and CPU. */ +extern void smram_map_ex(int bus, int smm, uint32_t addr, uint32_t size, int is_smram); /* Set memory state in the specified model (normal or SMM) according to the specified flags. */ extern void smram_map(int smm, uint32_t addr, uint32_t size, int is_smram); /* Disable a specific SMRAM mapping. */ extern void smram_disable(smram_t *smr); /* Disable all SMRAM mappings. */ extern void smram_disable_all(void); +/* Enable SMRAM mappings according to flags for both normal and SMM modes, separately for bus + and CPU. */ +extern void smram_enable_ex(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size, + int flags_normal, int flags_normal_bus, int flags_smm, int flags_smm_bus); /* Enable SMRAM mappings according to flags for both normal and SMM modes. */ extern void smram_enable(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size, int flags_normal, int flags_smm); @@ -52,6 +59,8 @@ extern void smram_enable(smram_t *smr, uint32_t host_base, uint32_t ram_base, ui extern int smram_enabled(smram_t *smr); /* Changes the SMRAM state. */ extern void smram_state_change(smram_t *smr, int smm, int flags); +/* Enables or disables the use of a separate SMRAM for addresses below A0000. */ +extern void smram_set_separate_smram(uint8_t set); #endif /*EMU_SMRAM_H*/ diff --git a/src/include/86box/spd.h b/src/include/86box/spd.h index 53492d0e8..81216a6f6 100644 --- a/src/include/86box/spd.h +++ b/src/include/86box/spd.h @@ -106,6 +106,8 @@ typedef struct { extern void spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size); extern void spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit); +extern void spd_write_drbs_interleaved(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit); +extern void spd_write_drbs_ali1621(uint8_t *regs, uint8_t reg_min, uint8_t reg_max); #endif /*EMU_SPD_H*/ diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 30d30254c..9022a4a86 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -25,7 +25,7 @@ #define FLAG_NOSKEW 16 #define FLAG_ADDR_BY16 32 #define FLAG_RAMDAC_SHIFT 64 - +#define FLAG_128K_MASK 128 typedef struct { int ena, @@ -50,7 +50,8 @@ typedef struct svga_t lowres, interlace, linedbl, rowcount, set_reset_disabled, bpp, ramdac_type, fb_only, readmode, writemode, readplane, - hwcursor_oddeven, dac_hwcursor_oddeven, overlay_oddeven; + hwcursor_oddeven, dac_hwcursor_oddeven, overlay_oddeven, + fcr, hblank_overscan; int dac_addr, dac_pos, dac_r, dac_g, vtotal, dispend, vsyncstart, split, vblankstart, @@ -60,8 +61,9 @@ typedef struct svga_t con, cursoron, blink, scrollcache, char_width, firstline, lastline, firstline_draw, lastline_draw, displine, fullchange, x_add, y_add, pan, - vram_display_mask, vidclock, - hwcursor_on, dac_hwcursor_on, overlay_on, set_override; + vram_display_mask, vidclock, dots_per_clock, hblank_ext, + hwcursor_on, dac_hwcursor_on, overlay_on, set_override, + hblankstart, hblankend, hblank_sub, hblank_end_val, hblank_end_len; /*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 : 0MB-1MB - VRAM diff --git a/src/include/86box/vid_svga_render.h b/src/include/86box/vid_svga_render.h index 46c37f655..1bae05385 100644 --- a/src/include/86box/vid_svga_render.h +++ b/src/include/86box/vid_svga_render.h @@ -44,6 +44,8 @@ void svga_render_4bpp_lowres(svga_t *svga); void svga_render_4bpp_highres(svga_t *svga); void svga_render_8bpp_lowres(svga_t *svga); void svga_render_8bpp_highres(svga_t *svga); +void svga_render_8bpp_tseng_lowres(svga_t *svga); +void svga_render_8bpp_tseng_highres(svga_t *svga); void svga_render_8bpp_gs_lowres(svga_t *svga); void svga_render_8bpp_gs_highres(svga_t *svga); void svga_render_8bpp_rgb_lowres(svga_t *svga); diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 63f854fb9..d5a352826 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -176,6 +176,7 @@ extern void updatewindowsize(int x, int y); extern void video_init(void); extern void video_close(void); extern void video_reset_close(void); +extern void video_pre_reset(int card); extern void video_reset(int card); extern uint8_t video_force_resize_get(void); extern void video_force_resize_set(uint8_t res); @@ -264,7 +265,11 @@ extern const device_t f82c425_video_device; /* NCR NGA */ extern const device_t nga_device; +/* Tseng ET3000AX */ +extern const device_t et3000_isa_device; + /* Tseng ET4000AX */ +extern const device_t et4000_tc6058af_isa_device; extern const device_t et4000_isa_device; extern const device_t et4000k_isa_device; extern const device_t et4000k_tg286_isa_device; @@ -316,7 +321,6 @@ extern const device_t oti037c_device; extern const device_t oti067_device; extern const device_t oti067_acer386_device; extern const device_t oti067_ama932j_device; -extern const device_t oti067_m300_device; extern const device_t oti077_device; /* Paradise/WD (S)VGA */ @@ -375,6 +379,7 @@ extern const device_t s3_spea_mercury_p64v_pci_device; extern const device_t s3_elsa_winner2000_pro_x_964_pci_device; extern const device_t s3_elsa_winner2000_pro_x_pci_device; extern const device_t s3_trio64v2_dx_pci_device; +extern const device_t s3_trio64v2_dx_onboard_pci_device; /* S3 ViRGE */ extern const device_t s3_virge_325_pci_device; @@ -397,6 +402,7 @@ extern const device_t sigma_device; extern const device_t tgui9400cxi_device; extern const device_t tgui9440_vlb_device; extern const device_t tgui9440_pci_device; +extern const device_t tgui9440_onboard_pci_device; extern const device_t tgui9660_pci_device; extern const device_t tgui9680_pci_device; diff --git a/src/io.c b/src/io.c index d704a036a..92b6b591c 100644 --- a/src/io.c +++ b/src/io.c @@ -322,6 +322,10 @@ inb(uint16_t port) if (!found) cycles -= io_delay; + /* TriGem 486-BIOS MHz output. */ + if (port == 0x1ed) + ret = 0xfe; + io_log("[%04X:%08X] (%i, %i, %04i) in b(%04X) = %02X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret); return(ret); @@ -345,7 +349,7 @@ outb(uint16_t port, uint8_t val) } p = q; } - + if (!found) { cycles -= io_delay; #ifdef USE_DYNAREC diff --git a/src/log.c b/src/log.c index a20a8d520..99bab97a5 100644 --- a/src/log.c +++ b/src/log.c @@ -43,6 +43,9 @@ typedef struct } log_t; +extern FILE *stdlog; /* file to log output to */ + + void log_set_suppr_seen(void *priv, int suppr_seen) { diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt index ac62fbe16..c20d21a75 100644 --- a/src/machine/CMakeLists.txt +++ b/src/machine/CMakeLists.txt @@ -20,17 +20,14 @@ add_library(mch OBJECT machine.c machine_table.c m_xt.c m_xt_compaq.c m_at.c m_at_commodore.c m_at_t3100e.c m_at_t3100e_vid.c m_ps1.c m_ps1_hdc.c m_ps2_isa.c m_ps2_mca.c m_at_compaq.c m_at_286_386sx.c m_at_386dx_486.c - m_at_socket4_5.c m_at_socket7.c m_at_sockets7.c m_at_socket8.c - m_at_slot1.c m_at_slot2.c m_at_socket370.c m_at_misc.c) + m_at_socket4.c m_at_socket5.c m_at_socket7_3v.c m_at_socket7.c + m_at_sockets7.c m_at_socket8.c m_at_slot1.c m_at_slot2.c m_at_socket370.c + m_at_misc.c) if(HEDAKA) target_compile_definitions(mch PRIVATE USE_HEDAKA) endif() -if(I450KX) - target_compile_definitions(mch PRIVATE USE_I450KX) -endif() - if(LASERXT) target_sources(mch PRIVATE m_xt_laserxt.c) target_compile_definitions(mch PRIVATE USE_LASERXT) @@ -46,8 +43,4 @@ endif() if(M154X) target_compile_definitions(mch PRIVATE USE_M154X) -endif() - -if(M6117) - target_compile_definitions(mch PRIVATE USE_M6117) endif() \ No newline at end of file diff --git a/src/machine/m_at.c b/src/machine/m_at.c index 0e5589927..dc47b6207 100644 --- a/src/machine/m_at.c +++ b/src/machine/m_at.c @@ -56,6 +56,7 @@ #include <86box/lpt.h> #include <86box/rom.h> #include <86box/hdc.h> +#include <86box/port_6x.h> #include <86box/machine.h> @@ -69,6 +70,10 @@ machine_at_common_init_ex(const machine_t *model, int type) pic2_init(); dma16_init(); + if (!(type & 4)) + device_add(&port_6x_device); + type &= 3; + if (type == 1) device_add(&ibmat_nvr_device); else if (type == 0) diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 10de113f6..c2f9a433d 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -37,6 +37,7 @@ #include <86box/fdc.h> #include <86box/fdc_ext.h> #include <86box/hdc.h> +#include <86box/port_6x.h> #include <86box/sio.h> #include <86box/serial.h> #include <86box/video.h> @@ -119,11 +120,11 @@ machine_at_ama932j_init(const machine_t *model) machine_at_common_ide_init(model); - machine_at_headland_common_init(1); - if (gfxcard == VID_INTERNAL) device_add(&oti067_ama932j_device); + machine_at_headland_common_init(1); + return ret; } @@ -141,7 +142,7 @@ machine_at_quadt286_init(const machine_t *model) return ret; machine_at_common_init(model); - device_add(&keyboard_at_device); + device_add(&keyboard_at_device); if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); @@ -152,6 +153,30 @@ machine_at_quadt286_init(const machine_t *model) } +int +machine_at_quadt386sx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/quadt386sx/QTC-SXM-EVEN-U3-05-07.BIN", + "roms/machines/quadt386sx/QTC-SXM-ODD-U3-05-07.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&keyboard_at_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&headland_gc10x_device); + + return ret; +} + + int machine_at_neat_init(const machine_t *model) { @@ -414,14 +439,14 @@ machine_at_spc4620p_init(const machine_t *model) if (bios_only || !ret) return ret; + if (gfxcard == VID_INTERNAL) + device_add(&ati28800k_spc4620p_device); + machine_at_scat_init(model, 1); if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); - if (gfxcard == VID_INTERNAL) - device_add(&ati28800k_spc4620p_device); - return ret; } @@ -525,13 +550,13 @@ machine_at_wd76c10_init(const machine_t *model) machine_at_common_init(model); + if (gfxcard == VID_INTERNAL) + device_add(¶dise_wd90c11_megapc_device); + device_add(&keyboard_ps2_quadtel_device); device_add(&wd76c10_device); - if (gfxcard == VID_INTERNAL) - device_add(¶dise_wd90c11_megapc_device); - return ret; } @@ -565,14 +590,17 @@ machine_at_cmdsl386sx16_init(const machine_t *model) static void -machine_at_scamp_common_init(const machine_t *model) +machine_at_scamp_common_init(const machine_t *model, int is_ps2) { machine_at_common_ide_init(model); - device_add(&keyboard_ps2_ami_device); + if (is_ps2) + device_add(&keyboard_ps2_ami_device); + else + device_add(&keyboard_at_ami_device); if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); + device_add(&fdc_at_device); device_add(&vlsi_scamp_device); } @@ -596,11 +624,28 @@ machine_at_cmdsl386sx25_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_scamp_common_init(model); - if (gfxcard == VID_INTERNAL) device_add(&gd5402_onboard_device); + machine_at_scamp_common_init(model, 1); + + 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; } @@ -623,11 +668,11 @@ machine_at_spc6033p_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_scamp_common_init(model); - if (gfxcard == VID_INTERNAL) device_add(&ati28800k_spc6033p_device); + machine_at_scamp_common_init(model, 1); + return ret; } @@ -653,6 +698,49 @@ machine_at_awardsx_init(const machine_t *model) 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(&keyboard_ps2_ami_device); + + return ret; +} + + +int +machine_at_sbc_350a_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/sbc_350a/350a.rom", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&ali1217_device); + device_add(&fdc37c665_ide_device); + device_add(&keyboard_at_device); + + return ret; +} + + int machine_at_flytech386_init(const machine_t *model) { @@ -668,38 +756,40 @@ machine_at_flytech386_init(const machine_t *model) device_add(&ali1217_device); device_add(&w83787f_ide_en_device); - device_add(&keyboard_ps2_device); if (gfxcard == VID_INTERNAL) device_add(&tvga8900d_device); + device_add(&keyboard_ps2_device); + return ret; } + const device_t * at_flytech386_get_device(void) { return &tvga8900d_device; } -#if defined(DEV_BRANCH) && defined(USE_M6117) + int -machine_at_arb1375_init(const machine_t *model) +machine_at_mr1217_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/arb1375/a1375v25.u11-a", - 0x000e0000, 131072, 0); + 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(&fdc37c669_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&ali6117d_device); - device_add(&sst_flash_29ee010_device); + device_add(&ali1217_device); + device_add(&fdc_at_device); + device_add(&ide_isa_device); + device_add(&keyboard_ps2_device); return ret; } @@ -719,14 +809,36 @@ machine_at_pja511m_init(const machine_t *model) machine_at_common_init(model); device_add_inst(&fdc37c669_device, 1); - //device_add_inst(&fdc37c669_device, 2); /* enable when dual FDC37C669 is implemented */ + device_add_inst(&fdc37c669_device, 2); device_add(&keyboard_ps2_ami_pci_device); device_add(&ali6117d_device); device_add(&sst_flash_29ee010_device); return ret; } -#endif + + +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(&keyboard_ps2_ami_pci_device); + device_add(&ali6117d_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + /* * Current bugs: @@ -753,6 +865,7 @@ machine_at_pc8_init(const machine_t *model) return ret; } + /* * Current bugs: * - ctrl-alt-del produces an 8042 error @@ -775,17 +888,19 @@ machine_at_3302_init(const machine_t *model) machine_at_common_ide_init(model); device_add(&neat_device); - device_add(&keyboard_at_ncr_device); if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); if (gfxcard == VID_INTERNAL) device_add(¶dise_pvga1a_ncr3302_device); + + device_add(&keyboard_at_ncr_device); return ret; } + /* * Current bugs: * - soft-reboot after saving CMOS settings/pressing ctrl-alt-del produces an 8042 error @@ -813,6 +928,7 @@ machine_at_pc916sx_init(const machine_t *model) return ret; } + #if defined(DEV_BRANCH) && defined(USE_OLIVETTI) int machine_at_m290_init(const machine_t *model) @@ -825,9 +941,10 @@ machine_at_m290_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 4); device_add(&keyboard_at_olivetti_device); - + device_add(&port_6x_olivetti_device); + if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); @@ -836,58 +953,3 @@ machine_at_m290_init(const machine_t *model) return ret; } #endif - -const device_t * -at_m30008_get_device(void) -{ - return &oti067_m300_device; -} - -int -machine_at_m30008_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/m30008/BIOS.ROM", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - - device_add(&opti283_device); - device_add(&keyboard_ps2_olivetti_device); - device_add(&pc87310_ide_device); - - if (gfxcard == VID_INTERNAL) - device_add(&oti067_m300_device); - - return ret; -} - -/* Almost identical to M300-08, save for CPU speed, VRAM, and BIOS identification string */ -int -machine_at_m30015_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/m30015/BIOS.ROM", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - - device_add(&opti283_device); - device_add(&keyboard_ps2_olivetti_device); - device_add(&pc87310_ide_device); - - /* Stock VRAM is maxed out, so no need to expose video card config */ - if (gfxcard == VID_INTERNAL) - device_add(&oti067_m300_device); - - return ret; -} - diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 03ba605f3..50718475b 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -32,12 +32,17 @@ #include <86box/mem.h> #include <86box/nvr.h> #include <86box/pci.h> +#include <86box/dma.h> #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/fdc_ext.h> +#include <86box/gameport.h> +#include <86box/pic.h> +#include <86box/pit.h> #include <86box/rom.h> #include <86box/sio.h> #include <86box/hdc.h> +#include <86box/port_6x.h> #include <86box/video.h> #include <86box/flash.h> #include <86box/scsi_ncr53c8xx.h> @@ -61,7 +66,7 @@ machine_at_acc386_init(const machine_t *model) device_add(&keyboard_at_ami_device); if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); + device_add(&fdc_at_device); return ret; } @@ -170,23 +175,25 @@ machine_at_valuepoint433_init(const machine_t *model) // hangs without the PS/2 machine_at_common_ide_init(model); device_add(&sis_85c461_device); - device_add(&keyboard_ps2_device); - - if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); - if (gfxcard == VID_INTERNAL) device_add(&et4000w32_onboard_device); + device_add(&keyboard_ps2_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + return ret; } + const device_t * at_valuepoint433_get_device(void) { return &et4000w32_onboard_device; } + int machine_at_ecs386_init(const machine_t *model) { @@ -229,7 +236,7 @@ machine_at_spc6000a_init(const machine_t *model) if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); - device_add(&keyboard_at_samsung_device); + device_add(&keyboard_at_ami_device); return ret; } @@ -297,7 +304,7 @@ machine_at_cs4031_init(const machine_t *model) device_add(&keyboard_at_ami_device); if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); + device_add(&fdc_at_device); return ret; } @@ -341,15 +348,16 @@ machine_at_vect486vl_init(const machine_t *model) // has HDC problems if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_ide_init(model); device_add(&vl82c480_device); - device_add(&keyboard_ps2_ami_device); - device_add(&fdc37c651_device); if (gfxcard == VID_INTERNAL) device_add(&gd5428_onboard_device); + device_add(&keyboard_ps2_ami_device); + device_add(&fdc37c651_ide_device); + return ret; } @@ -359,6 +367,7 @@ at_vect486vl_get_device(void) return &gd5428_onboard_device; } + int machine_at_d824_init(const machine_t *model) { @@ -373,48 +382,23 @@ machine_at_d824_init(const machine_t *model) machine_at_common_init(model); device_add(&vl82c480_device); - device_add(&keyboard_ps2_device); - device_add(&fdc37c651_device); if (gfxcard == VID_INTERNAL) device_add(&gd5428_onboard_device); + device_add(&keyboard_ps2_device); + device_add(&fdc37c651_device); + return ret; } + const device_t * at_d824_get_device(void) { return &gd5428_onboard_device; } -int -machine_at_pcs46c_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/pcs46c/OLIVETTI.BIN", - 0x000e0000, 131072, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_ide_init(model); - - device_add(&et6000_device); - device_add(&keyboard_ps2_device); - - if (gfxcard == VID_INTERNAL) - device_add(&gd5428_onboard_device); - - return ret; -} - -const device_t * -at_pcs46c_get_device(void) -{ - return &gd5428_onboard_device; -} int machine_at_acera1g_init(const machine_t *model) @@ -428,16 +412,16 @@ machine_at_acera1g_init(const machine_t *model) return ret; machine_at_common_init(model); + device_add(&ali1429g_device); if (gfxcard == VID_INTERNAL) device_add(&gd5428_onboard_device); - device_add(&ali1429_device); device_add(&keyboard_ps2_acer_pci_device); device_add(&ide_isa_2ch_device); if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); + device_add(&fdc_at_device); return ret; } @@ -450,12 +434,62 @@ at_acera1g_get_device(void) } +int +machine_at_acerv10_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/acerv10/ALL.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&sis_85c461_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&ide_isa_2ch_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + + +int +machine_at_decpc_lpv_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/decpc_lpv/bios.bin-5f2c71ca0a0a5135083487.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&sis_85c461_device); + /* TODO: Phoenix MultiKey KBC */ + device_add(&keyboard_ps2_ami_pci_device); + device_add(&ide_isa_2ch_device); + device_add(&fdc37c663_device); + /* TODO: On-board S3 805 with AT&T 490 RAM DAC. */ + + return ret; +} + static void -machine_at_ali1429_common_init(const machine_t *model) +machine_at_ali1429_common_init(const machine_t *model, int is_green) { machine_at_common_ide_init(model); - device_add(&ali1429_device); + if (is_green) + device_add(&ali1429g_device); + else + device_add(&ali1429_device); device_add(&keyboard_at_ami_device); @@ -475,7 +509,7 @@ machine_at_ali1429_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_ali1429_common_init(model); + machine_at_ali1429_common_init(model, 0); return ret; } @@ -492,7 +526,7 @@ machine_at_winbios1429_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_ali1429_common_init(model); + machine_at_ali1429_common_init(model, 1); return ret; } @@ -569,6 +603,25 @@ machine_at_opti495_mr_init(const machine_t *model) return ret; } + +static void +machine_at_403tg_common_init(const machine_t *model, int nvr_hack) +{ + if (nvr_hack) { + machine_at_common_init_ex(model, 2); + device_add(&ls486e_nvr_device); + } else + machine_at_common_init(model); + + device_add(&opti895_device); + + device_add(&keyboard_at_ami_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); +} + + int machine_at_403tg_init(const machine_t *model) { @@ -580,14 +633,41 @@ machine_at_403tg_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_403tg_common_init(model, 0); - device_add(&opti895_device); + return ret; +} - device_add(&keyboard_at_device); - if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); +int +machine_at_403tg_rev_d_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/403tg_rev_d/J403TGRevD.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_403tg_common_init(model, 1); + + return ret; +} + + +int +machine_at_403tg_rev_d_mr_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/403tg_rev_d/MRBiosOPT895.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_403tg_common_init(model, 0); return ret; } @@ -647,7 +727,7 @@ machine_at_sis_85c471_common_init(const machine_t *model) machine_at_common_init(model); if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); + device_add(&fdc_at_device); device_add(&sis_85c471_device); } @@ -685,7 +765,7 @@ machine_at_vli486sv2g_init(const machine_t *model) machine_at_sis_85c471_common_init(model); device_add(&ide_vlb_2ch_device); - device_add(&keyboard_at_device); + device_add(&keyboard_ps2_ami_device); return ret; } @@ -767,6 +847,30 @@ machine_at_vi15g_init(const machine_t *model) } +int +machine_at_green_b_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/green-b/4gpv31-ami-1993-8273517.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&contaq_82c597_device); + + device_add(&keyboard_at_ami_device); + + return ret; +} + + static void machine_at_sis_85c496_common_init(const machine_t *model) { @@ -884,7 +988,7 @@ machine_at_4dps_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&w83787f_device); - device_add(&keyboard_ps2_pci_device); + device_add(&keyboard_at_ami_device); device_add(&intel_flash_bxt_device); @@ -970,7 +1074,7 @@ machine_at_alfredo_init(const machine_t *model) pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&keyboard_ps2_pci_device); device_add(&sio_device); device_add(&fdc37c663_device); device_add(&intel_flash_bxt_ami_device); @@ -981,6 +1085,34 @@ machine_at_alfredo_init(const machine_t *model) } +int +machine_at_ninja_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined("roms/machines/ninja/1008AY0_.BIO", + "roms/machines/ninja/1008AY0_.BI1", 0x1c000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 2, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 1, 2, 1); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&intel_flash_bxt_ami_device); + + device_add(&i420ex_device); + device_add(&i82091aa_device); + + return ret; +} + + int machine_at_486sp3_init(const machine_t *model) { @@ -1015,6 +1147,68 @@ machine_at_486sp3_init(const machine_t *model) } +int +machine_at_pci400c_b_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/pci400c-b/032295.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&ide_isa_device); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 3, 2, 1); /* 0F = Slot 1 */ + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 0E = Slot 2 */ + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 0D = Slot 3 */ + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 0C = Slot 4 */ + device_add(&keyboard_ps2_ami_pci_device); /* Assume AMI Megakey 1993 stanalone ('P') + because of the Tekram machine below. */ + + device_add(&ims8848_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + + +int +machine_at_g486ip_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/g486ip/G486IP.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&ide_isa_device); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 03 = Slot 1 */ + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 04 = Slot 2 */ + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 05 = Slot 3 */ + device_add(&keyboard_ps2_ami_pci_device); /* AMI Megakey 1993 stanalone ('P') */ + + device_add(&ims8848_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + + int machine_at_486sp3g_init(const machine_t *model) { @@ -1071,7 +1265,7 @@ machine_at_486ap4_init(const machine_t *model) device_add(&keyboard_ps2_ami_pci_device); /* Uses the AMIKEY KBC */ if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); + device_add(&fdc_at_device); device_add(&i420ex_device); @@ -1079,6 +1273,36 @@ machine_at_486ap4_init(const machine_t *model) } +int +machine_at_g486vpa_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/g486vpa/3.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(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + + device_add(&via_vt82c49x_pci_ide_device); + device_add(&via_vt82c505_device); + device_add(&pc87332_398_ide_sec_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + + int machine_at_486vipio2_init(const machine_t *model) { @@ -1166,11 +1390,11 @@ machine_at_win486pci_init(const machine_t *model) int -machine_at_atc1415_init(const machine_t *model) +machine_at_ms4145_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/atc1415/1415V330.ROM", + ret = bios_load_linear("roms/machines/ms4145/AG56S.ROM", 0x000e0000, 131072, 0); if (bios_only || !ret) @@ -1179,29 +1403,27 @@ machine_at_atc1415_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0c, 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(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); - device_add(&umc_hb4_device); - device_add(&umc_8886af_device); + device_add(&ali1489_device); + device_add(&w83787f_device); device_add(&keyboard_at_ami_device); - - if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); + device_add(&sst_flash_29ee010_device); return ret; } int -machine_at_ecs486_init(const machine_t *model) +machine_at_sbc_490_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/ecs486/8810AIO.32J", + ret = bios_load_linear("roms/machines/sbc-490/07159589.rom", 0x000e0000, 131072, 0); if (bios_only || !ret) @@ -1210,29 +1432,39 @@ machine_at_ecs486_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0c, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0d, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0e, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0f, PCI_CARD_IDE, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_VIDEO, 4, 1, 2, 3); - device_add(&umc_hb4_device); - device_add(&umc_8886f_device); - device_add(&ide_cmd640_pci_legacy_only_device); + device_add(&ali1489_device); device_add(&fdc37c665_device); - device_add(&keyboard_at_ami_device); + + if (gfxcard == VID_INTERNAL) + device_add(&tgui9440_onboard_pci_device); + + device_add(&keyboard_ps2_ami_device); + device_add(&sst_flash_29ee010_device); return ret; } +const device_t * +at_sbc_490_get_device(void) +{ + return &tgui9440_onboard_pci_device; +} + + int -machine_at_hot433_init(const machine_t *model) +machine_at_tf_486_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/hot433/433AUS33.ROM", + ret = bios_load_linear("roms/machines/tf-486/tf486v10.BIN", 0x000e0000, 131072, 0); if (bios_only || !ret) @@ -1241,18 +1473,13 @@ machine_at_hot433_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0c, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0d, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0e, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0f, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); - device_add(&umc_hb4_device); - device_add(&umc_8886af_device); - device_add(&um8669f_device); - device_add(&intel_flash_bxt_device); - device_add(&keyboard_at_ami_device); + device_add(&ali1489_device); + device_add(&w83977ef_device); + device_add(&keyboard_ps2_device); + device_add(&sst_flash_29ee010_device); return ret; } @@ -1288,6 +1515,34 @@ machine_at_itoxstar_init(const machine_t *model) } +int +machine_at_arb1423c_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/arb1423c/A1423C.v12", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + 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, 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(&keyboard_ps2_ami_pci_device); + device_add(&stpc_consumer2_device); + device_add(&winbond_flash_w29c020_device); + + return ret; +} + + int machine_at_arb1479_init(const machine_t *model) { @@ -1372,3 +1627,191 @@ machine_at_pcm5330_init(const machine_t *model) return ret; } + + +int +machine_at_ecs486_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ecs486/8810AIO.32J", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_IDE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + + device_add(&umc_hb4_device); + device_add(&umc_8886f_device); + device_add(&ide_cmd640_pci_legacy_only_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_device); + device_add(&keyboard_at_ami_device); + + return ret; +} + + +int +machine_at_hot433_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/hot433/433AUS33.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + + device_add(&umc_hb4_device); + device_add(&umc_8886af_device); + device_add(&um8669f_device); + // device_add(&intel_flash_bxt_device); + device_add(&sst_flash_29ee010_device); + // device_add(&keyboard_at_ami_device); + device_add(&keyboard_ps2_ami_device); + + return ret; +} + + +int +machine_at_atc1415_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/atc1415/1415V330.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0C, 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); + + device_add(&umc_hb4_device); + device_add(&umc_8886af_device); + device_add(&intel_flash_bxt_device); + device_add(&keyboard_at_ami_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + + +int +machine_at_actionpc2600_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/actionpc2600/action2600.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + + device_add(&umc_hb4_device); + device_add(&umc_8886af_device); + device_add(&um8669f_device); + device_add(&intel_flash_bxt_device); + device_add(&keyboard_at_ami_device); + + return ret; +} + + +int +machine_at_m919_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/m919/9190914s.rom", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + + device_add(&umc_hb4_device); + device_add(&umc_8886af_device); + device_add(&um8669f_device); + device_add(&sst_flash_29ee010_device); + device_add(&keyboard_at_ami_device); + + return ret; +} + + +int +machine_at_spc7700p_lw_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/spc7700p-lw/77LW13FH.P24", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + + device_add(&umc_hb4_device); + device_add(&umc_8886af_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_device); + device_add(&keyboard_at_ami_device); + + return ret; +} diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 4772c3ccc..4e9d9e152 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -810,8 +810,6 @@ at_cpqiii_get_device(void) static void machine_at_compaq_init(const machine_t *model, int type) { - machine_at_init(model); - if (type != COMPAQ_DESKPRO386) mem_remap_top(384); @@ -846,6 +844,8 @@ machine_at_compaq_init(const machine_t *model, int type) device_add(&ide_isa_device); break; } + + machine_at_init(model); } diff --git a/src/machine/m_at_misc.c b/src/machine/m_at_misc.c index f96523bf3..b41735d74 100644 --- a/src/machine/m_at_misc.c +++ b/src/machine/m_at_misc.c @@ -68,7 +68,6 @@ machine_at_vpc2007_init(const machine_t *model) device_add(&w83977f_370_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&intel_flash_bxt_device); - device_add(&vpc2007_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); /* real VPC provides invalid SPD data */ return ret; diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index c69226ebc..3c9baaa05 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -489,37 +489,6 @@ at_tsunamiatx_get_device(void) return &es1371_onboard_device; } -#if defined(DEV_BRANCH) && defined(NO_SIO) -int -machine_at_ergox365_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/ergox365/M63v115.rom", - 0x00080000, 524288, 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); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x08, PCI_CARD_VIDEO, 3, 0, 0, 0); - device_add(&i440bx_device); - device_add(&piix4e_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&fdc37c665_device); /* Placeholder for the SM(S)C FDC37C675 */ - device_add(&sst_flash_39sf040_device); /* Placeholder for the Intel 28F004 flash chip */ - spd_register(SPD_TYPE_SDRAM, 0xF, 256); - - return ret; -} -#endif int machine_at_ficka6130_init(const machine_t *model) @@ -651,8 +620,10 @@ machine_at_vei8_init(const machine_t *model) device_add(&piix4e_device); device_add(&fdc37m60x_370_device); device_add(&keyboard_ps2_ami_pci_device); + device_add(ics9xxx_get(ICS9250_08)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x3, 512); + device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */ return ret; } @@ -674,13 +645,14 @@ machine_at_ms6168_common_init(const machine_t *model) device_add(&i440zx_device); device_add(&piix4e_device); device_add(&w83977ef_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&intel_flash_bxt_device); - spd_register(SPD_TYPE_SDRAM, 0x3, 256); if (gfxcard == VID_INTERNAL) device_add(&voodoo_3_2000_agp_onboard_8m_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 256); + if (sound_card_current == SOUND_INTERNAL) { device_add(&es1371_onboard_device); device_add(&cs4297_device); @@ -724,3 +696,36 @@ machine_at_ms6168_init(const machine_t *model) return ret; } + + +int +machine_at_m729_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/m729/M729NEW.BIN", + 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(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2); + device_add(&ali1621_device); + device_add(&ali1543c_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_29ee010_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + + return ret; +} diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 4d8b5c5a5..caa5b20fa 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -101,7 +101,7 @@ machine_at_trinity371_init(const machine_t *model) device_add(&i440bx_device); device_add(&piix4e_device); device_add(&keyboard_ps2_ami_pci_device); - device_add(&w83977f_370_device); + device_add(&w83977ef_370_device); device_add(&intel_flash_bxt_device); return ret; diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c new file mode 100644 index 000000000..7e8dd9232 --- /dev/null +++ b/src/machine/m_at_socket4.c @@ -0,0 +1,471 @@ +/* + * 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 Socket 4 machines. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2010-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/mem.h> +#include <86box/io.h> +#include <86box/rom.h> +#include <86box/pci.h> +#include <86box/device.h> +#include <86box/chipset.h> +#include <86box/fdc_ext.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/timer.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/keyboard.h> +#include <86box/flash.h> +#include <86box/nvr.h> +#include <86box/scsi_ncr53c8xx.h> +#include <86box/sio.h> +#include <86box/video.h> +#include <86box/machine.h> + + +void +machine_at_premiere_common_init(const machine_t *model, int pci_switch) +{ + machine_at_common_init(model); + device_add(&ide_pci_2ch_device); + + pci_init(PCI_CONFIG_TYPE_2 | pci_switch); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_IDE, 0, 0, 0, 0); + pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&sio_zb_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_ami_device); +} + + +void +machine_at_award_common_init(const machine_t *model) +{ + machine_at_common_init(model); + device_add(&ide_pci_2ch_device); + + pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_IDE, 0, 0, 0, 0); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 03 = Slot 1 */ + pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 04 = Slot 2 */ + pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 05 = Slot 3 */ + pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 06 = Slot 4 */ + pci_register_slot(0x07, PCI_CARD_SCSI, 1, 2, 3, 4); /* 07 = SCSI */ + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + // device_add(&keyboard_ps2_pci_device); + device_add(&keyboard_ps2_ami_pci_device); +} + + +void +machine_at_sp4_common_init(const machine_t *model) +{ + 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(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + /* Excluded: 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F, 10, 11, 12, 13, 14 */ + pci_register_slot(0x0D, PCI_CARD_IDE, 1, 2, 3, 4); + /* Excluded: 02, 03*, 04*, 05*, 06*, 07*, 08* */ + /* Slots: 09 (04), 0A (03), 0B (02), 0C (07) */ + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&sis_85c50x_device); + device_add(&ide_cmd640_pci_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_device); +} + + +int +machine_at_excalibur_pci_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_inverted("roms/machines/excalibur_pci/S701P.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_2); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x03, PCI_CARD_IDE, 0, 0, 0, 0); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + 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(&keyboard_ps2_ami_pci_device); + device_add(&ide_cmd640_pci_legacy_only_device); + + device_add(&i430lx_device); + device_add(&sio_zb_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + + +int +machine_at_p5mp3_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/p5mp3/0205.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&ide_pci_device); + + pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x05, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 05 = Slot 1 */ + pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 04 = Slot 2 */ + pci_register_slot(0x03, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 03 = Slot 3 */ + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&fdc_at_device); + device_add(&keyboard_ps2_pci_device); + + device_add(&sio_zb_device); + device_add(&catalyst_flash_device); + device_add(&i430lx_device); + + return ret; +} + + +int +machine_at_dellxp60_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_inverted("roms/machines/dellxp60/XP60-A08.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&ide_pci_2ch_device); + + pci_init(PCI_CONFIG_TYPE_2); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + /* Not: 00, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F. */ + /* Yes: 01, 10, 11, 12, 13, 14. */ + pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 3, 2, 4); + pci_register_slot(0x04, PCI_CARD_NORMAL, 4, 4, 3, 3); + pci_register_slot(0x05, PCI_CARD_NORMAL, 1, 4, 3, 2); + pci_register_slot(0x06, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&i430lx_device); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&sio_zb_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + + +int +machine_at_opti560l_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_inverted("roms/machines/opti560l/560L_A06.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&ide_pci_2ch_device); + + pci_init(PCI_CONFIG_TYPE_2); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x03, PCI_CARD_NORMAL, 4, 4, 3, 3); + pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 4, 3, 2); + pci_register_slot(0x08, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&i430lx_device); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&sio_zb_device); + device_add(&i82091aa_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + + +int +machine_at_ambradp60_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined("roms/machines/ambradp60/1004AF1P.BIO", + "roms/machines/ambradp60/1004AF1P.BI1", 0x1c000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_premiere_common_init(model, 0); + + device_add(&i430lx_device); + + return ret; +} + + +int +machine_at_valuepointp60_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined("roms/machines/valuepointp60/1006AV0M.BIO", + "roms/machines/valuepointp60/1006AV0M.BI1", 0x1d000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&ide_pci_2ch_device); + + pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_IDE, 0, 0, 0, 0); + pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&keyboard_ps2_ps1_pci_device); + device_add(&sio_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_ami_device); + + device_add(&i430lx_device); + + return ret; +} + + +int +machine_at_revenge_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined("roms/machines/revenge/1009af2_.bio", + "roms/machines/revenge/1009af2_.bi1", 0x1c000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_premiere_common_init(model, 0); + + device_add(&i430lx_device); + + return ret; +} + + +int +machine_at_586mc1_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/586mc1/IS.34", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_award_common_init(model); + + device_add(&sio_device); + device_add(&intel_flash_bxt_device); + device_add(&i430lx_device); + + return ret; +} + + +int +machine_at_pb520r_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined("roms/machines/pb520r/1009bc0r.bio", + "roms/machines/pb520r/1009bc0r.bi1", 0x1c000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_2); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_IDE, 0, 0, 0, 0); + pci_register_slot(0x03, PCI_CARD_VIDEO, 3, 3, 3, 3); + pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&i430lx_device); + device_add(&ide_cmd640_pci_single_channel_device); + + if (gfxcard == VID_INTERNAL) + device_add(&gd5434_onboard_pci_device); + + device_add(&keyboard_ps2_pci_device); + device_add(&sio_zb_device); + device_add(&i82091aa_ide_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + + +const device_t * +at_pb520r_get_device(void) +{ + return &gd5434_onboard_pci_device; +} + + +int +machine_at_excalibur_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_inverted("roms/machines/excalibur/S75P.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&opti5x7_device); + device_add(&ide_opti611_vlb_device); + device_add(&fdc37c661_device); + device_add(&keyboard_ps2_intel_ami_pci_device); + + return ret; +} + + +int +machine_at_p5vl_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/p5vl/SM507.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + 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); + device_add(&opti5x7_device); + device_add(&opti822_device); + device_add(&sst_flash_29ee010_device); + device_add(&keyboard_at_ami_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + + +int +machine_at_excalibur_pci_2_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_inverted("roms/machines/excalibur_pci-2/S722P.ROM", + 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(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_IDE, 0, 0, 0, 0); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); + 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(&keyboard_ps2_ami_pci_device); + device_add(&ide_cmd640_pci_legacy_only_device); + + device_add(&sis_85c50x_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + + +int +machine_at_p5sp4_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/p5sp4/0106.001", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_sp4_common_init(model); + + return ret; +} diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c new file mode 100644 index 000000000..2748210e0 --- /dev/null +++ b/src/machine/m_at_socket5.c @@ -0,0 +1,446 @@ +/* + * 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 Socket 5 machines. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2010-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/mem.h> +#include <86box/io.h> +#include <86box/rom.h> +#include <86box/pci.h> +#include <86box/device.h> +#include <86box/chipset.h> +#include <86box/fdc_ext.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/timer.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/keyboard.h> +#include <86box/flash.h> +#include <86box/nvr.h> +#include <86box/scsi_ncr53c8xx.h> +#include <86box/sio.h> +#include <86box/video.h> +#include <86box/machine.h> + + +int +machine_at_plato_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined("roms/machines/plato/1016ax1_.bio", + "roms/machines/plato/1016ax1_.bi1", 0x1d000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_premiere_common_init(model, PCI_CAN_SWITCH_TYPE); + + device_add(&i430nx_device); + + return ret; +} + + +int +machine_at_ambradp90_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined("roms/machines/ambradp90/1002AX1P.BIO", + "roms/machines/ambradp90/1002AX1P.BI1", 0x1d000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_premiere_common_init(model, PCI_CAN_SWITCH_TYPE); + + device_add(&i430nx_device); + + return ret; +} + + +int +machine_at_430nx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/430nx/IP.20", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_award_common_init(model); + + device_add(&sio_device); + device_add(&intel_flash_bxt_device); + device_add(&i430nx_device); + + return ret; +} + + +int +machine_at_acerv30_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/acerv30/V30R01N9.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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&keyboard_ps2_acer_pci_device); + device_add(&fdc37c665_device); + + device_add(&sst_flash_29ee010_device); + + return ret; +} + + +int +machine_at_apollo_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/apollo/S728P.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + device_add(&ami_apollo_nvr_device); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&pc87332_398_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + + +int +machine_at_exp8551_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/exp8551/AMI20.BIO", + 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(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&w83787f_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + + +int +machine_at_vectra54_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/vectra54/GT0724.22", + 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(0x0F, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_VIDEO, 0, 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); + + if (gfxcard == VID_INTERNAL) + device_add(&s3_phoenix_trio64_onboard_pci_device); + + device_add(&keyboard_ps2_ami_pci_device); + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&fdc37c931apm_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + + +int +machine_at_zappa_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined("roms/machines/zappa/1006bs0_.bio", + "roms/machines/zappa/1006bs0_.bi1", 0x20000, 128); + + 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(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&pc87306_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + + +int +machine_at_powermatev_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/powermatev/BIOS.ROM", + 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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_NORMAL, 0, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + + +int +machine_at_mb500n_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/mb500n/031396s.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(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&keyboard_ps2_pci_device); + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + + +int +machine_at_hawk_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/hawk/HAWK.ROM", + 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(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + + +int +machine_at_pat54pv_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/pat54pv/pat54pv.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&opti5x7_device); + device_add(&keyboard_ps2_intel_ami_pci_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + + +int +machine_at_hot543_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/hot543/543_R21.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + 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); + device_add(&opti5x7_device); + device_add(&opti822_device); + device_add(&sst_flash_29ee010_device); + device_add(&keyboard_at_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + + +int +machine_at_p54sp4_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/p54sp4/SI5I0204.AWD", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_sp4_common_init(model); + + return ret; +} + + +int +machine_at_sq588_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/sq588/sq588b03.rom", + 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(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + /* Correct: 0D (01), 0F (02), 11 (03), 13 (04) */ + pci_register_slot(0x02, PCI_CARD_IDE, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&sis_85c50x_device); + device_add(&ide_cmd640_pci_single_channel_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c665_ide_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} \ No newline at end of file diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 2edf96595..d9e9b7cd1 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -6,7 +6,7 @@ * * This file is part of the 86Box distribution. * - * Implementation of Socket 7 machines. + * Implementation of Socket 7 (Dual Voltage) machines. * * * @@ -44,239 +44,7 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/nvr.h> - -int -machine_at_ap5s_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/ap5s/AP5S150.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(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 2, 1); - pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 3, 2, 1); - - device_add(&sis_5511_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&fdc37c665_device); - device_add(&sst_flash_29ee010_device); - - return ret; -} - -int -machine_at_chariot_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/chariot/P5IV183.ROM", - 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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 2, 1); - pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 3, 2, 1); - - device_add(&i430fx_device); - device_add(&piix_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&pc87306_device); - device_add(&intel_flash_bxt_device); - - return ret; -} - -int -machine_at_mr586_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/mr586/TRITON.BIO", - 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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); - - device_add(&i430fx_device); - device_add(&piix_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&fdc37c665_device); - device_add(&intel_flash_bxt_device); - - return ret; -} - -static void -machine_at_thor_common_init(const machine_t *model, int mr) -{ - machine_at_common_init_ex(model, mr); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 2, 1); - pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 3, 2, 1); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - - device_add(&keyboard_ps2_ami_pci_device); - device_add(&i430fx_device); - device_add(&piix_device); - device_add(&pc87306_device); - device_add(&intel_flash_bxt_ami_device); -} - - -int -machine_at_thor_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear_combined("roms/machines/thor/1006cn0_.bio", - "roms/machines/thor/1006cn0_.bi1", 0x20000, 128); - - if (bios_only || !ret) - return ret; - - machine_at_thor_common_init(model, 0); - - return ret; -} - - -int -machine_at_gw2katx_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear_combined("roms/machines/gw2katx/1003cn0t.bio", - "roms/machines/gw2katx/1003cn0t.bi1", 0x20000, 128); - - if (bios_only || !ret) - return ret; - - machine_at_thor_common_init(model, 0); - - return ret; -} - - -int -machine_at_mrthor_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/mrthor/mr_atx.bio", - 0x000e0000, 131072, 0); - - if (bios_only || !ret) - return ret; - - machine_at_thor_common_init(model, 1); - - return ret; -} - - -int -machine_at_pb640_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear_combined("roms/machines/pb640/1007CP0R.BIO", - "roms/machines/pb640/1007CP0R.BI1", 0x1d000, 128); - - 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(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); - pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 3, 4); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 2, 1, 4); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&i430fx_rev02_device); - device_add(&piix_rev02_device); - - if (gfxcard == VID_INTERNAL) - device_add(&gd5440_onboard_pci_device); - - device_add(&keyboard_ps2_intel_ami_pci_device); - device_add(&pc87306_device); - device_add(&intel_flash_bxt_ami_device); - - return ret; -} - -const device_t * -at_pb640_get_device(void) -{ - return &gd5440_onboard_pci_device; -} - - -int -machine_at_acerm3a_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/acerm3a/r01-b3.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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x10, PCI_CARD_VIDEO, 4, 0, 0, 0); - device_add(&i430hx_device); - device_add(&piix3_device); - device_add(&keyboard_ps2_pci_device); - device_add(&fdc37c932fr_device); - - device_add(&sst_flash_29ee010_device); - - return ret; -} +#include <86box/scsi_ncr53c8xx.h> int @@ -312,11 +80,11 @@ machine_at_acerv35n_init(const machine_t *model) int -machine_at_ap53_init(const machine_t *model) +machine_at_ap5vm_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/ap53/ap53r2c0.rom", + ret = bios_load_linear("roms/machines/ap5vm/AP5V270.ROM", 0x000e0000, 131072, 0); if (bios_only || !ret) @@ -326,16 +94,20 @@ machine_at_ap53_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - 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); + /* It seems there were plans for an on-board NCR 53C810 according to some clues + left in the manual, but were latter scrapped. The BIOS still support that + PCI device, though, so why not. */ + pci_register_slot(0x06, PCI_CARD_SCSI, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x06, PCI_CARD_VIDEO, 1, 2, 3, 4); - device_add(&i430hx_device); + device_add(&i430vx_device); device_add(&piix3_device); device_add(&keyboard_ps2_ami_pci_device); - device_add(&fdc37c669_device); + device_add(&fdc37c665_device); + device_add(&ncr53c810_onboard_pci_device); device_add(&intel_flash_bxt_device); return ret; @@ -372,66 +144,6 @@ machine_at_p55t2p4_init(const machine_t *model) } -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(model); - - 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(&keyboard_ps2_ami_pci_device); - device_add(&pc87306_device); - device_add(&intel_flash_bxt_device); - - return ret; -} - - -int -machine_at_8500tuc_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/8500tuc/Tuc0221b.rom", - 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(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - device_add(&i430hx_device); - device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&um8669f_device); - device_add(&intel_flash_bxt_device); - - return ret; -} - - int machine_at_m7shi_init(const machine_t *model) { @@ -461,6 +173,7 @@ machine_at_m7shi_init(const machine_t *model) return ret; } + int machine_at_tc430hx_init(const machine_t *model) { @@ -496,8 +209,9 @@ machine_at_tc430hx_init(const machine_t *model) } +/* Information about that machine on machine.h */ int -machine_at_equium5200_init(const machine_t *model) // Information about that machine on machine.h +machine_at_equium5200_init(const machine_t *model) { int ret; @@ -530,6 +244,7 @@ machine_at_equium5200_init(const machine_t *model) // Information about that mac return ret; } + int machine_at_pcv240_init(const machine_t *model) { @@ -564,6 +279,7 @@ machine_at_pcv240_init(const machine_t *model) return ret; } + int machine_at_p65up5_cp55t2d_init(const machine_t *model) { @@ -581,36 +297,6 @@ machine_at_p65up5_cp55t2d_init(const machine_t *model) } -int -machine_at_mb520n_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/mb520n/520n503s.rom", - 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(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&i430vx_device); - device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&fdc37c669_device); - device_add(&intel_flash_bxt_device); - - return ret; -} - - int machine_at_p55tvp4_init(const machine_t *model) { @@ -640,6 +326,7 @@ machine_at_p55tvp4_init(const machine_t *model) return ret; } + int machine_at_5ivg_init(const machine_t *model) { @@ -668,92 +355,6 @@ machine_at_5ivg_init(const machine_t *model) return ret; } -int -machine_at_i430vx_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/430vx/55xwuq0e.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(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&i430vx_device); - device_add(&piix3_device); - device_add(&keyboard_ps2_pci_device); - device_add(&um8669f_device); - device_add(&intel_flash_bxt_device); - - return ret; -} - -int -machine_at_p55va_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/p55va/va021297.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(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&i430vx_device); - device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&fdc37c932fr_device); - device_add(&intel_flash_bxt_device); - - return ret; -} - -int -machine_at_brio80xx_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/brio80xx/Hf0705.rom", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x14, PCI_CARD_VIDEO, 4, 0, 0, 0); - pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - device_add(&i430vx_device); - device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&fdc37c935_device); - device_add(&sst_flash_29ee020_device); - - return ret; -} int machine_at_8500tvxa_init(const machine_t *model) @@ -801,9 +402,12 @@ machine_at_presario2240_init(const machine_t *model) 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); - pci_register_slot(0x14, PCI_CARD_SOUND, 3, 0, 0, 0); + pci_register_slot(0x14, PCI_CARD_VIDEO, 3, 0, 0, 0); pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4); + if (gfxcard == VID_INTERNAL) + device_add(&s3_trio64v2_dx_onboard_pci_device); + device_add(&i430vx_device); device_add(&piix3_device); device_add(&keyboard_ps2_ami_pci_device); @@ -814,6 +418,13 @@ machine_at_presario2240_init(const machine_t *model) } +const device_t * +at_presario2240_get_device(void) +{ + return &s3_trio64v2_dx_onboard_pci_device; +} + + int machine_at_presario4500_init(const machine_t *model) { @@ -830,8 +441,11 @@ machine_at_presario4500_init(const machine_t *model) 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); - pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x14, PCI_CARD_VIDEO, 3, 0, 0, 0); + pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4); + + if (gfxcard == VID_INTERNAL) + device_add(&s3_trio64v2_dx_onboard_pci_device); device_add(&i430vx_device); device_add(&piix3_device); @@ -843,6 +457,66 @@ machine_at_presario4500_init(const machine_t *model) } +int +machine_at_p55va_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/p55va/va021297.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(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&i430vx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c932fr_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + + +int +machine_at_brio80xx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/brio80xx/Hf0705.rom", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x14, PCI_CARD_VIDEO, 4, 0, 0, 0); + pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + device_add(&i430vx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c935_device); + device_add(&sst_flash_29ee020_device); + + return ret; +} + + int machine_at_pb680_init(const machine_t *model) { @@ -878,16 +552,12 @@ machine_at_pb680_init(const machine_t *model) int -machine_at_gw2kte_init(const machine_t *model) +machine_at_mb520n_init(const machine_t *model) { int ret; - ret = bios_load_linear_combined2("roms/machines/gw2kte/1008CY1T.BIO", - "roms/machines/gw2kte/1008CY1T.BI1", - "roms/machines/gw2kte/1008CY1T.BI2", - "roms/machines/gw2kte/1008CY1T.BI3", - "roms/machines/gw2kte/1008CY1T.RCV", - 0x3a000, 128); + ret = bios_load_linear("roms/machines/mb520n/520n503s.rom", + 0x000e0000, 131072, 0); if (bios_only || !ret) return ret; @@ -896,17 +566,46 @@ machine_at_gw2kte_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); device_add(&keyboard_ps2_ami_pci_device); - device_add(&fdc37c932fr_device); - device_add(&intel_flash_bxt_ami_device); + device_add(&fdc37c669_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + + +int +machine_at_i430vx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/430vx/55xwuq0e.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(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&i430vx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_pci_device); + device_add(&um8669f_device); + device_add(&intel_flash_bxt_device); return ret; } @@ -949,6 +648,7 @@ machine_at_nupro592_init(const machine_t *model) return ret; } + int machine_at_tx97_init(const machine_t *model) { @@ -989,6 +689,53 @@ machine_at_tx97_init(const machine_t *model) } +#if defined(DEV_BRANCH) && defined(NO_SIO) +int +machine_at_an430tx_init(const machine_t *model) +{ + int ret; + +#if 1 + ret = bios_load_linear_combined2("roms/machines/an430tx/P10-0095.BIO", + "roms/machines/an430tx/P10-0095.BI1", + "roms/machines/an430tx/P10-0095.BI2", + "roms/machines/an430tx/P10-0095.BI3", + "roms/machines/an430tx/P10-0095.RCV", + 0x3a000, 160); +#else + ret = bios_load_linear_combined2("roms/machines/an430tx/P06-0062.BIO", + "roms/machines/an430tx/P06-0062.BI1", + "roms/machines/an430tx/P06-0062.BI2", + "roms/machines/an430tx/P06-0062.BI3", + "roms/machines/an430tx/P10-0095.RCV", + 0x3a000, 160); +#endif + + 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(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&i430tx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&pc87307_both_device); + device_add(&intel_flash_bxt_ami_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + + return ret; +} +#endif + + int machine_at_ym430tx_init(const machine_t *model) { @@ -1022,44 +769,6 @@ machine_at_ym430tx_init(const machine_t *model) } -#if defined(DEV_BRANCH) && defined(NO_SIO) -int -machine_at_an430tx_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear_combined2("roms/machines/an430tx/P10-0095.BIO", - "roms/machines/an430tx/P10-0095.BI1", - "roms/machines/an430tx/P10-0095.BI2", - "roms/machines/an430tx/P10-0095.BI3", - "roms/machines/an430tx/P10-0095.RCV", - 0x3a000, 160); - - 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(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); - device_add(&i430tx_device); - device_add(&piix4_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&pc87307_both_device); - device_add(&intel_flash_bxt_ami_device); - spd_register(SPD_TYPE_SDRAM, 0x3, 128); - - return ret; -} -#endif - - int machine_at_mb540n_init(const machine_t *model) { @@ -1123,132 +832,6 @@ machine_at_p5mms98_init(const machine_t *model) return ret; } -#if defined(DEV_BRANCH) && defined(USE_M154X) -int -machine_at_m560_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/m560/5600410s.ami", - 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(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0D, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 2, 3, 4); - device_add(&ali1531_device); - device_add(&ali1543_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&sst_flash_29ee010_device); - spd_register(SPD_TYPE_SDRAM, 0x3, 128); - - return ret; -} - -int -machine_at_ms5164_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/ms5164/W564MS43.005", - 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(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0D, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 2, 3, 4); - - device_add(&ali1531_device); - device_add(&ali1543_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&sst_flash_29ee010_device); - spd_register(SPD_TYPE_SDRAM, 0x3, 128); - - return ret; -} -#endif - -int -machine_at_r534f_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/r534f/r534f008.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(0x01, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); - - device_add(&sis_5571_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&w83877f_device); - device_add(&sst_flash_29ee010_device); - - return ret; -} - -int -machine_at_ms5146_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/ms5146/A546MS11.ROM", - 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(0x01, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); - - device_add(&sis_5571_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&w83877f_device); - device_add(&sst_flash_29ee010_device); - - return ret; -} int machine_at_ficva502_init(const machine_t *model) @@ -1312,3 +895,131 @@ machine_at_ficpa2012_init(const machine_t *model) return ret; } + + +int +machine_at_r534f_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/r534f/r534f008.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(0x01, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); + + device_add(&sis_5571_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877f_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + + +int +machine_at_ms5146_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ms5146/A546MS11.ROM", + 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(0x01, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); + + device_add(&sis_5571_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877f_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + + +int +machine_at_m560_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/m560/5600410s.ami", + 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(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&ali1531_device); + device_add(&ali1543_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_29ee010_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + + return ret; +} + + +int +machine_at_ms5164_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ms5164/W564MS43.005", + 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(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_SOUTHBRIDGE, 5, 6, 0, 0); + pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 2, 3, 4); + + device_add(&ali1531_device); + device_add(&ali1543_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_29ee010_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + + return ret; +} diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c new file mode 100644 index 000000000..5ee87fc44 --- /dev/null +++ b/src/machine/m_at_socket7_3v.c @@ -0,0 +1,554 @@ +/* + * 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 Socket 7 (Single Voltage) machines. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * Melissa Goad, + * + * Copyright 2010-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/mem.h> +#include <86box/io.h> +#include <86box/rom.h> +#include <86box/pci.h> +#include <86box/device.h> +#include <86box/chipset.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/keyboard.h> +#include <86box/flash.h> +#include <86box/sio.h> +#include <86box/hwm.h> +#include <86box/video.h> +#include <86box/spd.h> +#include "cpu.h" +#include <86box/machine.h> +#include <86box/timer.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/nvr.h> + + +static void +machine_at_thor_common_init(const machine_t *model, int mr) +{ + machine_at_common_init_ex(model, mr); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 2, 1); + pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 3, 2, 1); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + + if (gfxcard == VID_INTERNAL) + device_add(&s3_phoenix_trio64vplus_onboard_pci_device); + + // device_add(&keyboard_ps2_ami_pci_device); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&pc87306_device); + device_add(&intel_flash_bxt_ami_device); +} + + +int +machine_at_p54tp4xe_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/p54tp4xe/t15i0302.awd", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + /* Award BIOS, SMC FDC37C665. */ + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, 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, 0); + device_add(&keyboard_ps2_pci_device); + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + + +int +machine_at_mr586_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/mr586/TRITON.BIO", + 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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + + +int +machine_at_gw2katx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined("roms/machines/gw2katx/1003cn0t.bio", + "roms/machines/gw2katx/1003cn0t.bi1", 0x20000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_thor_common_init(model, 0); + + return ret; +} + + +int +machine_at_thor_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined("roms/machines/thor/1006cn0_.bio", + "roms/machines/thor/1006cn0_.bi1", 0x20000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_thor_common_init(model, 0); + + return ret; +} + + +const device_t * +at_thor_get_device(void) +{ + return &s3_phoenix_trio64vplus_onboard_pci_device; +} + + +int +machine_at_mrthor_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/mrthor/mr_atx.bio", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_thor_common_init(model, 1); + + return ret; +} + + +int +machine_at_endeavor_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined("roms/machines/endeavor/1006cb0_.bio", + "roms/machines/endeavor/1006cb0_.bi1", 0x1d000, 128); + + 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(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + + if (gfxcard == VID_INTERNAL) + device_add(&s3_phoenix_trio64_onboard_pci_device); + + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&pc87306_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + + +const device_t * +at_endeavor_get_device(void) +{ + return &s3_phoenix_trio64_onboard_pci_device; +} + + +int +machine_at_ms5119_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ms5119/A37E.ROM", + 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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0d, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0e, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0f, PCI_CARD_NORMAL, 3, 4, 1, 2); + + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83787f_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + + +int +machine_at_pb640_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined("roms/machines/pb640/1007CP0R.BIO", + "roms/machines/pb640/1007CP0R.BI1", 0x1d000, 128); + + 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(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 2, 1, 4); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&i430fx_rev02_device); + device_add(&piix_rev02_device); + + if (gfxcard == VID_INTERNAL) + device_add(&gd5440_onboard_pci_device); + + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&pc87306_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + + +const device_t * +at_pb640_get_device(void) +{ + return &gd5440_onboard_pci_device; +} + + +int +machine_at_fmb_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/fmb/P5IV183.ROM", + 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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 2, 1); + pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 3, 2, 1); + + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83787f_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + + +int +machine_at_acerm3a_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/acerm3a/r01-b3.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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x10, PCI_CARD_VIDEO, 4, 0, 0, 0); + device_add(&i430hx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_pci_device); + device_add(&fdc37c932fr_device); + + device_add(&sst_flash_29ee010_device); + + return ret; +} + + +int +machine_at_ap53_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ap53/ap53r2c0.rom", + 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(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); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x06, PCI_CARD_VIDEO, 1, 2, 3, 4); + device_add(&i430hx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c669_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + + +int +machine_at_8500tuc_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/8500tuc/Tuc0221b.rom", + 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(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + device_add(&i430hx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&um8669f_device); + device_add(&intel_flash_bxt_device); + + 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(model); + + 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(&keyboard_ps2_ami_pci_device); + device_add(&pc87306_device); + device_add(&intel_flash_bxt_device); + + 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(&keyboard_ps2_ami_pci_device); + device_add(&w83877f_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + + +int +machine_at_gw2kte_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined2("roms/machines/gw2kte/1008CY1T.BIO", + "roms/machines/gw2kte/1008CY1T.BI1", + "roms/machines/gw2kte/1008CY1T.BI2", + "roms/machines/gw2kte/1008CY1T.BI3", + "roms/machines/gw2kte/1008CY1T.RCV", + 0x3a000, 128); + + 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(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); + device_add(&i430vx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c932fr_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + + +int +machine_at_ap5s_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ap5s/AP5S150.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(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 2, 1); + pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 3, 2, 1); + + device_add(&sis_5511_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c665_device); + 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 318e8dfea..8067e17b0 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -30,6 +30,8 @@ #include <86box/hdc_ide.h> #include <86box/keyboard.h> #include <86box/flash.h> +#include <86box/timer.h> +#include <86box/nvr.h> #include <86box/sio.h> #include <86box/hwm.h> #include <86box/spd.h> @@ -37,7 +39,7 @@ #include "cpu.h" #include <86box/machine.h> -#if defined(DEV_BRANCH) && defined(USE_I450KX) + int machine_at_p6rp4_init(const machine_t *model) { @@ -49,11 +51,12 @@ machine_at_p6rp4_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); + device_add(&p6rp4_nvr_device); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x19, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x12, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x14, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_IDE, 0, 0, 0, 0); pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 2, 3, 4); @@ -62,14 +65,15 @@ machine_at_p6rp4_init(const machine_t *model) pci_register_slot(0x04, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i450kx_device); device_add(&sio_zb_device); + device_add(&ide_cmd646_device); + /* Input port bit 2 must be 1 or CMOS Setup is disabled. */ device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c665_device); - device_add(&ide_cmd640_pci_device); device_add(&intel_flash_bxt_device); return ret; } -#endif + int machine_at_686nx_init(const machine_t *model) diff --git a/src/machine/m_at_sockets7.c b/src/machine/m_at_sockets7.c index ca6c957e2..66eca228f 100644 --- a/src/machine/m_at_sockets7.c +++ b/src/machine/m_at_sockets7.c @@ -41,6 +41,145 @@ #include "cpu.h" #include <86box/machine.h> #include <86box/snd_ac97.h> +#include <86box/clock.h> + + +int +machine_at_p5a_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/p5a/1011.005", + 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(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 4, 1, 2); + device_add(&ali1541_device); + device_add(&ali1543c_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 256); + device_add(&w83781d_p5a_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */ + + return ret; +} + + +int +machine_at_m579_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/m579/MS6260S_Socket7_ALi_M1542_AMI.BIN", + 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(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&ali1541_device); + device_add(&ali1543c_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_29ee010_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + + return ret; +} + + +int +machine_at_ga_5aa_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ga-5aa/GA-5AA.F7b", + 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(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + device_add(&ali1541_device); + device_add(&ali1543c_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_29ee010_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + + return ret; +} + + +int +machine_at_ga_5ax_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ga-5ax/5AX.F4", + 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(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&ali1541_device); + device_add(&ali1543c_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_29ee010_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + + return ret; +} int @@ -145,3 +284,44 @@ machine_at_ficva503a_init(const machine_t *model) return ret; } + + +int +machine_at_sy_5ema_pro_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/sy-5ema_pro/5emo1aa2.bin", + 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, 0, 0, 3, 4); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + + device_add(&via_mvp3_device); + device_add(&via_vt82c686a_device); + device_add(&keyboard_ps2_ami_pci_device); + // device_add(&via_vt82c686_sio_device); + device_add(&fdc37c669_device); + device_add(&sst_flash_39sf010_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + device_add(&via_vt82c686_hwm_device); /* fans: CPU1, Chassis; temperatures: CPU, System, unused */ + hwm_values.temperatures[0] += 2; /* CPU offset */ + hwm_values.temperatures[1] += 2; /* System offset */ + hwm_values.temperatures[2] = 0; /* unused */ + + device_add(&wm9701a_device); /* on daughtercard */ + + return ret; +} diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index 35ddfe6da..482c26ed6 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -867,7 +867,7 @@ machine_pcjr_init(const machine_t *model) device_add(&fdc_pcjr_device); device_add(&i8250_pcjr_device); - serial_set_next_inst(2); /* So that serial_standalone_init() won't do anything. */ + serial_set_next_inst(MAX_SERIAL); /* So that serial_standalone_init() won't do anything. */ return ret; } diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index 33b67aabe..ca444421c 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -59,6 +59,7 @@ #include <86box/hdc_ide.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/port_6x.h> #include <86box/sound.h> #include <86box/snd_sn76489.h> #include <86box/video.h> @@ -514,6 +515,7 @@ ps1_common_init(const machine_t *model) pic2_init(); device_add(&keyboard_ps2_ps1_device); + device_add(&port_6x_device); /* Audio uses ports 200h and 202-207h, so only initialize gameport on 201h. */ standalone_gameport_type = &gameport_201_device; diff --git a/src/machine/m_ps2_isa.c b/src/machine/m_ps2_isa.c index 0b9dbaeb4..987b29f2e 100644 --- a/src/machine/m_ps2_isa.c +++ b/src/machine/m_ps2_isa.c @@ -15,6 +15,7 @@ #include <86box/nvr.h> #include <86box/keyboard.h> #include <86box/lpt.h> +#include <86box/port_6x.h> #include <86box/port_92.h> #include <86box/serial.h> #include <86box/hdc.h> @@ -186,7 +187,8 @@ machine_ps2_m30_286_init(const machine_t *model) refresh_at_enable = 1; pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_at); dma16_init(); - device_add(&keyboard_ps2_ps2_device); + device_add(&keyboard_ps2_device); + device_add(&port_6x_ps2_device); device_add(&ps_nvr_device); pic2_init(); ps2board_init(); diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index 59a3fe535..b1b611d94 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -63,6 +63,7 @@ #include <86box/keyboard.h> #include <86box/lpt.h> #include <86box/mouse.h> +#include <86box/port_6x.h> #include <86box/port_92.h> #include <86box/serial.h> #include <86box/video.h> @@ -793,7 +794,8 @@ static void ps2_mca_board_common_init() io_sethandler(0x0096, 0x0001, ps2_mca_read, NULL, NULL, ps2_mca_write, NULL, NULL, NULL); io_sethandler(0x0100, 0x0008, ps2_mca_read, NULL, NULL, ps2_mca_write, NULL, NULL, NULL); - device_add(&port_92_device); + device_add(&port_6x_ps2_device); + device_add(&port_92_device); ps2.setup = 0xff; diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 6e68c81bf..ede52cf6f 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -290,28 +290,6 @@ machine_xt_pcxt_init(const machine_t *model) } -#if defined(DEV_BRANCH) && defined(USE_HEDAKA) -int -machine_xt_hed919_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/hed919/Hedaka_HED-919_bios_version_3.28f.bin", - 0x000fe000, 8192, 0); - - if (bios_only || !ret) - return ret; - - machine_xt_clone_init(model); - - if (mem_size > 640) - mem_remap_top(mem_size - 640); - - return ret; -} -#endif - - int machine_xt_pxxt_init(const machine_t *model) { diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index efff2a9c0..a76a3cfc8 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -44,6 +44,7 @@ #include <86box/fdc.h> #include <86box/fdc_ext.h> #include <86box/gameport.h> +#include <86box/port_6x.h> #include <86box/sound.h> #include <86box/snd_speaker.h> #include <86box/video.h> @@ -804,6 +805,9 @@ machine_xt_m240_init(const machine_t *model) pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt); + /* Address 66-67 = mainboard dip-switch settings */ + io_sethandler(0x0066, 2, m24_read, NULL, NULL, NULL, NULL, NULL, NULL); + /* * port 60: should return jumper settings only under unknown conditions * SWB on mainboard (off=1) @@ -811,6 +815,7 @@ machine_xt_m240_init(const machine_t *model) * bit 6 - use OCG/CGA display adapter (on) / other display adapter (off) */ device_add(&keyboard_at_olivetti_device); + device_add(&port_6x_olivetti_device); /* FIXME: make sure this is correct?? */ device_add(&at_nvr_device); diff --git a/src/machine/m_xt_xi8088.c b/src/machine/m_xt_xi8088.c index 3250c0022..f192c6d86 100644 --- a/src/machine/m_xt_xi8088.c +++ b/src/machine/m_xt_xi8088.c @@ -20,6 +20,7 @@ #include <86box/lpt.h> #include <86box/rom.h> #include <86box/hdc.h> +#include <86box/port_6x.h> #include <86box/video.h> #include <86box/machine.h> #include "cpu.h" @@ -222,6 +223,7 @@ machine_xt_xi8088_init(const machine_t *model) device_add(&fdc_at_device); device_add(&keyboard_ps2_xi8088_device); + device_add(&port_6x_xi8088_device); nmi_init(); device_add(&ibmat_nvr_device); pic2_init(); diff --git a/src/machine/m_xt_zenith.c b/src/machine/m_xt_zenith.c index 1ca553227..791ebdcd1 100644 --- a/src/machine/m_xt_zenith.c +++ b/src/machine/m_xt_zenith.c @@ -154,7 +154,7 @@ machine_xt_z184_init(const machine_t *model) lpt2_remove(); lpt1_init(0x278); device_add(&i8250_device); - serial_set_next_inst(2); /* So that serial_standalone_init() won't do anything. */ + serial_set_next_inst(MAX_SERIAL); /* So that serial_standalone_init() won't do anything. */ device_add(&cga_device); diff --git a/src/machine/machine.c b/src/machine/machine.c index afa79b02c..91cdbef33 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -97,6 +97,10 @@ machine_init_ex(int m) device_add(&cassette_device); cart_reset(); + + /* Prepare some video-related things if we're using internal + or no video. */ + video_pre_reset(gfxcard); } /* All good, boot the machine! */ diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index e4d5ff9bc..5077b3ea3 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -39,10 +39,12 @@ const machine_type_t machine_types[] = { { "8086", MACHINE_TYPE_8086 }, { "80286", MACHINE_TYPE_286 }, { "i386SX", MACHINE_TYPE_386SX }, + { "486SLC", MACHINE_TYPE_486SLC }, { "i386DX", MACHINE_TYPE_386DX }, { "i386DX/i486", MACHINE_TYPE_386DX_486 }, { "i486 (Socket 168 and 1)", MACHINE_TYPE_486 }, - { "i486 (Socket 2 and 3)", MACHINE_TYPE_486_S3 }, + { "i486 (Socket 2)", MACHINE_TYPE_486_S2 }, + { "i486 (Socket 3)", MACHINE_TYPE_486_S3 }, { "i486 (Miscellaneous)", MACHINE_TYPE_486_MISC }, { "Socket 4", MACHINE_TYPE_SOCKET4 }, { "Socket 5", MACHINE_TYPE_SOCKET5 }, @@ -58,6 +60,47 @@ const machine_type_t machine_types[] = { }; +/* Machines to add before machine freeze: + - PCChips M773 (440BX + SMSC with AMI BIOS); + - Rise R418 (was removed on my end, has to be re-added); + - TMC Mycomp PCI54ST; + - Zeos Quadtel 486. + + NOTE: The AMI MegaKey tests were done on a real Intel Advanced/ATX + (thanks, MrKsoft for running my AMIKEY.COM on it), but the + technical specifications of the other Intel machines confirm + that the other boards also have the MegaKey. + + NOTE: The later (ie. not AMI Color) Intel AMI BIOS'es execute a + sequence of commands (B8, BA, BB) during one of the very first + phases of POST, in a way that is only valid on the AMIKey-3 + KBC firmware, that includes the Classic PCI/ED (Ninja) BIOS + which otherwise does not execute any AMI KBC commands, which + indicates that the sequence is a leftover of whatever AMI + BIOS (likely a laptop one since the AMIKey-3 is a laptop KBC + firmware!) Intel forked. + + NOTE: The VIA VT82C42N returns 0x46 ('F') in command 0xA1 (so it + emulates the AMI KF/AMIKey KBC firmware), and 0x42 ('B') in + command 0xAF. + The version on the VIA VT82C686B southbridge also returns + 'F' in command 0xA1, but 0x45 ('E') in command 0xAF. + The version on the VIA VT82C586B southbridge also returns + 'F' in command 0xA1, but 0x44 ('D') in command 0xAF. + The version on the VIA VT82C586A southbridge also returns + 'F' in command 0xA1, but 0x43 ('C') in command 0xAF. + + NOTE: The AMI MegaKey commands blanked in the technical reference + are CC and and C4, which are Set P14 High and Set P14 Low, + respectively. Also, AMI KBC command C1, mysteriously missing + from the technical references of AMI MegaKey and earlier, is + Write Input Port, same as on AMIKey-3. + + Machines to remove: + - Hedaka HED-919. +*/ + + const machine_t machines[] = { /* 8088 Machines */ { "[8088] IBM PC (1981)", "ibmpc", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 16, 64, 16, 0, machine_pc_init, NULL }, @@ -69,7 +112,7 @@ const machine_t machines[] = { { "[8088] AMI XT clone", "amixt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_amixt_init, NULL }, { "[8088] Columbia Data Products MPC-1600", "mpc1600", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 512, 64, 0, machine_xt_mpc1600_init, NULL }, { "[8088] Compaq Portable", "portable", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 128, 0, machine_xt_compaq_portable_init, NULL }, - { "[8088] DTK XT clone", "dtk", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_dtk_init, NULL }, + { "[8088] DTK PIM-TB10-Z", "dtk", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_dtk_init, NULL }, { "[8088] Eagle PC Spirit", "pcspirit", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_pcspirit_init, NULL }, { "[8088] Generic XT clone", "genxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_genxt_init, NULL }, { "[8088] Juko ST", "jukopc", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_jukopc_init, NULL }, @@ -88,6 +131,7 @@ const machine_t machines[] = { #if defined(DEV_BRANCH) && defined(USE_LASERXT) { "[8088] VTech Laser Turbo XT", "ltxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 640, 256, 0, machine_xt_laserxt_init, NULL }, #endif + /* Has a standard PS/2 KBC (so, use IBM PS/2 Type 1). */ { "[8088] Xi8088", "xi8088", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2, 64, 1024, 128, 127, machine_xt_xi8088_init, xi8088_get_device }, { "[8088] Zenith Data Systems Z-151/152/161","zdsz151", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_z151_init, NULL }, { "[8088] Zenith Data Systems Z-159", "zdsz159", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_z159_init, NULL }, @@ -103,6 +147,7 @@ const machine_t machines[] = { { "[8086] Amstrad PPC512/640", "ppc512", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO | MACHINE_MOUSE | MACHINE_NONMI, 512, 640, 128, 63, machine_ppc512_init, ppc512_get_device }, { "[8086] Compaq Deskpro", "deskpro", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 128, 0, machine_xt_compaq_deskpro_init, NULL }, { "[8086] Olivetti M21/24/24SP", "m24", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO | MACHINE_MOUSE, 128, 640, 128, 0, machine_xt_m24_init, m24_get_device }, + /* Has Olivetti KBC firmware. */ { "[8086] Olivetti M240", "m240", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 128, 0, machine_xt_m240_init, NULL }, { "[8086] Schetmash Iskra-3104", "iskra3104", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 128, 0, machine_xt_iskra3104_init, NULL }, { "[8086] Tandy 1000 SL/2", "tandy1000sl2", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 512, 768, 128, 0, machine_tandy1000sl2_init, tandy1k_sl_get_device }, @@ -113,355 +158,765 @@ const machine_t machines[] = { { "[8086] VTech Laser XT3", "lxt3", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 640, 256, 0, machine_xt_lxt3_init, NULL }, #endif - /* 286 XT machines */ -#if defined(DEV_BRANCH) && defined(USE_HEDAKA) - { "[Citygate D30 XT] Hedaka HED-919", "hed919", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 1024, 64, 0, machine_xt_hed919_init, NULL }, -#endif - /* 286 AT machines */ + /* Has IBM AT KBC firmware. */ { "[ISA] IBM AT", "ibmat", MACHINE_TYPE_286, CPU_PKG_286, 0, 6000000, 8000000, 0, 0, 0, 0, MACHINE_AT, 256, 15872, 128, 63, machine_at_ibm_init, NULL }, + /* Has IBM PS/2 Type 1 KBC firmware. */ { "[ISA] IBM PS/1 model 2011", "ibmps1es", MACHINE_TYPE_286, CPU_PKG_286, 0, 10000000, 10000000, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_XTA | MACHINE_VIDEO_FIXED, 512, 16384, 512, 63, machine_ps1_m2011_init, NULL }, + /* Has IBM PS/2 Type 1 KBC firmware. */ { "[ISA] IBM PS/2 model 30-286", "ibmps2_m30_286", MACHINE_TYPE_286, CPU_PKG_286 | CPU_PKG_486SLC_IBM, 0, 10000000, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_XTA | MACHINE_VIDEO_FIXED, 1024, 16384,1024, 127, machine_ps2_m30_286_init, NULL }, + /* Has IBM AT KBC firmware. */ { "[ISA] IBM XT Model 286", "ibmxt286", MACHINE_TYPE_286, CPU_PKG_286, 0, 6000000, 6000000, 0, 0, 0, 0, MACHINE_AT, 256, 15872, 128, 127, machine_at_ibmxt286_init, NULL }, + /* AMI BIOS for a chipset-less machine, most likely has AMI 'F' KBC firmware. */ { "[ISA] AMI IBM AT", "ibmatami", MACHINE_TYPE_286, CPU_PKG_286, 0, 6000000, 8000000, 0, 0, 0, 0, MACHINE_AT, 256, 15872, 128, 63, machine_at_ibmatami_init, NULL }, + /* Uses Commodore (CBM) KBC firmware, to be implemented as identical to the + IBM AT KBC firmware unless evidence emerges of any proprietary commands. */ { "[ISA] Commodore PC 30 III", "cmdpc30", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 640, 16384, 128, 127, machine_at_cmdpc_init, NULL }, + /* Uses Compaq KBC firmware. */ { "[ISA] Compaq Portable II", "portableii", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 640, 16384, 128, 127, machine_at_portableii_init, NULL }, + /* Uses Compaq KBC firmware. */ { "[ISA] Compaq Portable III", "portableiii", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_VIDEO, 640, 16384, 128, 127, machine_at_portableiii_init, at_cpqiii_get_device }, + /* Has IBM AT KBC firmware. */ { "[ISA] MR 286 clone", "mr286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 512, 16384, 128, 127, machine_at_mr286_init, NULL }, + /* Has IBM AT KBC firmware. */ { "[ISA] NCR PC8/810/710/3390/3392", "pc8", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_pc8_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_OLIVETTI) + /* Has Olivetti KBC firmware. */ { "[ISA] Olivetti M290", "m290", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 640, 16384, 128, 127, machine_at_m290_init, NULL }, #endif - #if defined(DEV_BRANCH) && defined(USE_OPEN_AT) +#if defined(DEV_BRANCH) && defined(USE_OPEN_AT) + /* Has IBM AT KBC firmware. */ { "[ISA] OpenAT", "openat", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 256, 15872, 128, 63, machine_at_openat_init, NULL }, #endif + /* Has IBM AT KBC firmware. */ { "[ISA] Phoenix IBM AT", "ibmatpx", MACHINE_TYPE_286, CPU_PKG_286, 0, 6000000, 8000000, 0, 0, 0, 0, MACHINE_AT, 256, 15872, 128, 63, machine_at_ibmatpx_init, NULL }, + /* Has Quadtel KBC firmware. */ { "[ISA] Quadtel IBM AT", "ibmatquadtel", MACHINE_TYPE_286, CPU_PKG_286, 0, 6000000, 8000000, 0, 0, 0, 0, MACHINE_AT, 256, 15872, 128, 63, machine_at_ibmatquadtel_init, NULL }, + /* This has a Siemens proprietary KBC which is completely undocumented. */ { "[ISA] Siemens PCD-2L", "siemens", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 256, 15872, 128, 63, machine_at_siemens_init, NULL }, + /* This has Toshiba's proprietary KBC, which is already implemented. */ { "[ISA] Toshiba T3100e", "t3100e", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE | MACHINE_VIDEO_FIXED, 1024, 5120, 256, 63, machine_at_t3100e_init, NULL }, + /* Has Quadtel KBC firmware. */ { "[GC103] Quadtel 286 clone", "quadt286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_quadt286_init, NULL }, + /* Most likely has AMI 'F' KBC firmware. */ { "[GC103] Trigem 286M", "tg286m", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 512, 8192, 128, 127, machine_at_tg286m_init, NULL }, - { "[NEAT] AMI 286 clone", "ami286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_ami_init, NULL }, + /* This has "AMI KEYBOARD BIOS", most likely 'F'. */ + { "[NEAT] Dataexpert 286", "ami286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_ami_init, NULL }, + /* Has IBM AT KBC firmware. */ { "[NEAT] NCR 3302", "3302", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_VIDEO, 512, 16384, 128, 127, machine_at_3302_init, NULL }, + /* Has IBM AT KBC firmware. */ { "[NEAT] Phoenix 286 clone", "px286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_px286_init, NULL }, - { "[SCAT] Award 286 clone", "award286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_award286_init, NULL }, + /* Has Chips & Technologies KBC firmware. */ { "[SCAT] GW-286CT GEAR", "gw286ct", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 512, 16384, 128, 127, machine_at_gw286ct_init, NULL }, + /* Has IBM PS/2 Type 1 KBC firmware. */ { "[SCAT] Goldstar GDC-212M", "gdc212m", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE | MACHINE_BUS_PS2, 512, 4096, 512, 127, machine_at_gdc212m_init, NULL }, + /* Has a VIA VT82C42N KBC. */ + { "[SCAT] Hyundai Solomon 286KP", "award286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_award286_init, NULL }, + /* Has a VIA VT82C42N KBC. */ { "[SCAT] Hyundai Super-286TR", "super286tr", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_super286tr_init, NULL }, + /* Has IBM PS/2 Type 1 KBC firmware. */ { "[SCAT] Samsung SPC-4200P", "spc4200p", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2, 512, 2048, 128, 127, machine_at_spc4200p_init, NULL }, + /* Has IBM PS/2 Type 1 KBC firmware. */ { "[SCAT] Samsung SPC-4216P", "spc4216p", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2, 1024, 5120,1024, 127, machine_at_spc4216p_init, NULL }, + /* Has IBM PS/2 Type 1 KBC firmware. */ { "[SCAT] Samsung SPC-4620P", "spc4620p", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_VIDEO, 1024, 5120,1024, 127, machine_at_spc4620p_init, NULL }, + /* Has IBM AT KBC firmware. */ { "[SCAT] Samsung Deskmaster 286", "deskmaster286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_deskmaster286_init, NULL }, /* 286 machines that utilize the MCA bus */ + /* Has IBM PS/2 Type 2 KBC firmware. */ { "[MCA] IBM PS/2 model 50", "ibmps2_m50", MACHINE_TYPE_286, CPU_PKG_286 | CPU_PKG_486SLC_IBM, 0, 10000000, 0, 0, 0, 0, 0, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 1024, 10240,1024, 63, machine_ps2_model_50_init, NULL }, /* 386SX machines */ - { "[ISA] IBM PS/1 model 2121", "ibmps1_2121", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO_FIXED, 2048, 6144,1024, 63, machine_ps1_m2121_init, NULL }, - { "[ISA] IBM PS/1 m.2121+ISA", "ibmps1_2121_isa", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2048, 6144,1024, 63, machine_ps1_m2121_init, NULL }, - { "[ISA] NCR PC916SX", "pc916sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 16384, 128, 127, machine_at_pc916sx_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_M6117) - { "[ALi M6117] Acrosser AR-B1375", "arb1375", MACHINE_TYPE_386SX, CPU_PKG_M6117, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 32768,1024, 127, machine_at_arb1375_init, NULL }, + /* ISA slots available because an official IBM expansion for that existed. */ + /* Has IBM PS/2 Type 1 KBC firmware. */ + { "[ISA] IBM PS/1 model 2121", "ibmps1_2121", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2048, 6144,1024, 63, machine_ps1_m2121_init, NULL }, + /* Has IBM AT KBC firmware. */ + { "[ISA] NCR PC916SX", "pc916sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 16384, 128, 127, machine_at_pc916sx_init, NULL }, + /* Has Quadtel KBC firmware. */ + { "[ISA] QTC-SXM KT X20T02/HI", "quadt386sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 16384, 128, 127, machine_at_quadt386sx_init, NULL }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { "[ALi M1217] Acrosser AR-B1374", "arb1374", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 32768,1024, 127, machine_at_arb1374_init, NULL }, + /* Has the AMIKey KBC firmware, which is an updated 'F' type. */ + { "[ALi M1217] AAEON SBC-350A", "sbc-350a", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 16384, 1024, 127, machine_at_sbc_350a_init, 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. */ + { "[ALi M1217] Flytech 386", "flytech386", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 1024, 16384, 1024, 127, machine_at_flytech386_init, at_flytech386_get_device }, + /* I'm going to assume this has a standard/generic IBM-compatible AT KBC + firmware until the board is identified. */ + { "[ALi M1217] MR 386SX clone", "mr1217", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 1024, 16384, 1024, 127, machine_at_mr1217_init, NULL }, + /* Has IBM PS/2 Type 1 KBC firmware. */ { "[ALi M6117] Acrosser PJ-A511M", "pja511m", MACHINE_TYPE_386SX, CPU_PKG_M6117, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 32768,1024, 127, machine_at_pja511m_init, NULL }, -#endif - { "[ALi M1217] Flytech 386", "flytech386", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE | MACHINE_BUS_PS2 | MACHINE_VIDEO, 1024, 16384, 1024, 127, machine_at_flytech386_init, at_flytech386_get_device }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { "[ALi M6117C] Protech ProX-1332", "prox1332", MACHINE_TYPE_386SX, CPU_PKG_M6117, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 32768,1024, 127, machine_at_prox1332_init, 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. */ { "[HT18] AMA-932J", "ama932j", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE | MACHINE_VIDEO, 512, 8192, 128, 127, machine_at_ama932j_init, at_ama932j_get_device }, - { "[Intel 82335] ADI 386SX", "adi386sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_adi386sx_init, NULL }, + /* Has an unknown KBC firmware with commands B8 and BB in the style of + Phoenix MultiKey and AMIKey-3(!), but also commands E1 and EA with + unknown functions. */ + { "[Intel 82335 ADI 386SX", "adi386sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_adi386sx_init, NULL }, + /* Has an AMI Keyboard BIOS PLUS KBC firmware ('8'). */ { "[Intel 82335] Shuttle 386SX", "shuttle386sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_shuttle386sx_init, NULL }, + /* Uses Commodore (CBM) KBC firmware, to be implemented as identical to + the IBM PS/2 Type 1 KBC firmware unless evidence emerges of any + proprietary commands. */ { "[NEAT] Commodore SL386SX-16", "cmdsl386sx16", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 8192, 512, 127, machine_at_cmdsl386sx16_init, NULL }, + /* Has IBM AT KBC firmware. */ { "[NEAT] DTK 386SX clone", "dtk386", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_init, NULL }, - { "[OPTi 283] Olivetti M300-08", "m30008", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 20000000, 20000000, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2048, 16384, 2048, 127, machine_at_m30008_init, at_m30008_get_device }, - { "[OPTi 283] Olivetti M300-15", "m30015", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 25000000, 25000000, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2048, 16384, 2048, 127, machine_at_m30015_init, NULL }, + /* Has IBM AT KBC firmware. */ { "[OPTi 291] DTK PPM-3333P", "awardsx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 16384, 1024, 127, machine_at_awardsx_init, NULL }, + /* Uses Commodore (CBM) KBC firmware, to be implemented as identical to + the IBM PS/2 Type 1 KBC firmware unless evidence emerges of any + proprietary commands. */ { "[SCAMP] Commodore SL386SX-25", "cmdsl386sx25", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 1024, 8192, 512, 127, machine_at_cmdsl386sx25_init, at_cmdsl386sx25_get_device }, + /* The closest BIOS string I find to this one's, differs only in one part, + and ends in -8, so I'm going to assume that this, too, has an AMI '8' + (AMI Keyboard BIOS Plus) KBC firmware. */ + { "[SCAMP] DataExpert 386SX", "dataexpert386sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 10000000, 25000000, 0, 0, 0, 0, MACHINE_AT, 1024, 16384, 1024, 127, machine_at_dataexpert386sx_init, NULL }, + /* Has IBM PS/2 Type 1 KBC firmware. */ { "[SCAMP] Samsung SPC-6033P", "spc6033p", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2048, 12288, 2048, 127, machine_at_spc6033p_init, at_spc6033p_get_device }, + /* Has an unknown AMI KBC firmware, I'm going to assume 'F' until a + photo or real hardware BIOS string is found. */ { "[SCAT] KMX-C-02", "kmxc02", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 512, 127, machine_at_kmxc02_init, NULL }, + /* Has Quadtel KBC firmware. */ { "[WD76C10] Amstrad MegaPC", "megapc", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 1024, 32768, 1024, 127, machine_at_wd76c10_init, NULL }, /* 386SX machines which utilize the MCA bus */ + /* Has IBM PS/2 Type 1 KBC firmware. */ { "[MCA] IBM PS/2 model 55SX", "ibmps2_m55sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 1024, 8192, 1024, 63, machine_ps2_model_55sx_init, NULL }, + /* 486SLC machines */ + /* 486SLC machines with just the ISA slot */ + /* Has AMIKey H KBC firmware. */ + { "[OPTi 283] RYC Leopard LX", "rycleopardlx", MACHINE_TYPE_486SLC, CPU_PKG_486SLC_IBM, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 1024, 16384, 1024, 127, machine_at_rycleopardlx_init, NULL }, + /* 386DX machines */ { "[ACC 2168] AMI 386DX clone", "acc386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 16384, 1024, 127, machine_at_acc386_init, NULL }, + /* Has an AMI Keyboard BIOS PLUS KBC firmware ('8'). */ { "[C&T 386] ECS 386/32", "ecs386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 16384, 1024, 127, machine_at_ecs386_init, NULL }, + /* Has IBM AT KBC firmware. */ { "[C&T 386] Samsung SPC-6000A", "spc6000a", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 1024, 32768, 1024, 127, machine_at_spc6000a_init, NULL }, + /* Uses Compaq KBC firmware. */ { "[ISA] Compaq Portable III (386)", "portableiii386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE | MACHINE_VIDEO, 1024, 14336, 1024, 127, machine_at_portableiii386_init, at_cpqiii_get_device }, - { "[ISA] Micronics 386 clone", "micronics386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_micronics386_init, NULL }, - { "[SiS 310] ASUS ISA-386C", "asus386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_asus386_init, NULL }, + /* Has IBM AT KBC firmware. */ + { "[ISA] Micronics 09-00021", "micronics386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_micronics386_init, NULL }, + /* Has AMIKey F KBC firmware. */ + { "[SiS 310] ASUS ISA-386C", "asus386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 32768, 1024, 127, machine_at_asus386_init, NULL }, /* 386DX machines which utilize the MCA bus */ + /* Has IBM PS/2 Type 1 KBC firmware. */ { "[MCA] IBM PS/2 model 70 (type 3)", "ibmps2_m70_type3", MACHINE_TYPE_386DX, CPU_PKG_386DX | CPU_PKG_486BL, 0, 0, 0, 0, 0, 0, 0, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 2048, 16384, 2048, 63, machine_ps2_model_70_type3_init, NULL }, + /* Has IBM PS/2 Type 1 KBC firmware. */ { "[MCA] IBM PS/2 model 80", "ibmps2_m80", MACHINE_TYPE_386DX, CPU_PKG_386DX | CPU_PKG_486BL, 0, 0, 0, 0, 0, 0, 0, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 1024, 12288, 1024, 63, machine_ps2_model_80_init, NULL }, + /* Has IBM PS/2 Type 1 KBC firmware. */ { "[MCA] IBM PS/2 model 80 (type 3)", "ibmps2_m80_type3", MACHINE_TYPE_386DX, CPU_PKG_386DX | CPU_PKG_486BL, 0, 0, 0, 0, 0, 0, 0, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 2048, 12288, 2048, 63, machine_ps2_model_80_axx_init, NULL }, /* 386DX/486 machines */ - { "[OPTi 495] Award 486 clone", "award486", MACHINE_TYPE_386DX_486, CPU_PKG_386DX | CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 32768, 1024, 127, machine_at_opti495_init, NULL }, - { "[OPTi 495] Dataexpert SX495 (486)", "ami486", MACHINE_TYPE_386DX_486, CPU_PKG_386DX | CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 32768, 1024, 127, machine_at_opti495_ami_init, NULL }, - { "[OPTi 495] MR 486 clone", "mr486", MACHINE_TYPE_386DX_486, CPU_PKG_386DX | CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 32768, 1024, 127, machine_at_opti495_mr_init, NULL }, + /* The BIOS sends commands C9 without a parameter and D5, both of which are + Phoenix MultiKey commands. */ + { "[OPTi 495] Award 486 clone", "award495", MACHINE_TYPE_386DX_486, CPU_PKG_386DX | CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 32768, 1024, 127, machine_at_opti495_init, NULL }, + /* Has AMIKey F KBC firmware. */ + { "[OPTi 495] Dataexpert SX495", "ami495", MACHINE_TYPE_386DX_486, CPU_PKG_386DX | CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 32768, 1024, 127, machine_at_opti495_ami_init, NULL }, + /* Has AMIKey F KBC firmware (it's just the MR BIOS for the above machine). */ + { "[OPTi 495] Dataexpert SX495 (MR BIOS)", "mr495", MACHINE_TYPE_386DX_486, CPU_PKG_386DX | CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 32768, 1024, 127, machine_at_opti495_mr_init, NULL }, /* 486 machines - Socket 1 */ + /* Has JetKey 5 KBC Firmware which looks like it is a clone of AMIKey type F. + It also has those Ex commands also seen on the VIA VT82C42N (the BIOS + supposedly sends command EF. + The board was also seen in 2003 with a -H string - perhaps someone swapped + the KBC? */ { "[ALi M1429] Olystar LIL1429", "ali1429", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 32768, 1024, 127, machine_at_ali1429_init, NULL }, + /* Has JetKey 5 KBC Firmware - but the BIOS string ends in a hardcoded -F, and + the BIOS also explicitly expects command A1 to return a 'F', so it looks like + the JetKey 5 is a clone of AMIKey type F. */ { "[CS4031] AMI 486 CS4031", "cs4031", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB, 1024, 65536, 1024, 127, machine_at_cs4031_init, NULL }, - { "[ETEQ ET6000] Olivetti PCS-46C", "pcs46c", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE | MACHINE_VIDEO, 4096, 32768, 4096, 127, machine_at_pcs46c_init, at_pcs46c_get_device }, + /* Uses some variant of Phoenix MultiKey/42 as the Intel 8242 chip has a Phoenix + copyright. */ { "[OPTi 895] Mylex MVI486", "mvi486", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE_DUAL, 1024, 65536, 1024, 127, machine_at_mvi486_init, NULL }, + /* Has AMI KF KBC firmware. */ + { "[SiS 401] ASUS ISA-486", "isa486", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_isa486_init, NULL }, + /* Has AMIKey H KBC firmware, per the screenshot in "How computers & MS-DOS work". */ + { "[SiS 401] Chaintech 433SC", "sis401", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_sis401_init, NULL }, + /* Has AMIKey F KBC firmware, per a photo of a monitor with the BIOS screen on + eBay. */ + { "[SiS 460] ABIT AV4", "av4", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_av4_init, NULL }, + /* Has a MR (!) KBC firmware, which is a clone of the standard IBM PS/2 KBC firmware. */ + { "[SiS 471] SiS VL-BUS 471 REV. A1", "px471", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024,131072, 1024, 127, machine_at_px471_init, NULL }, + /* The chip is a Lance LT38C41, a clone of the Intel 8041, and the BIOS sends + commands BC, BD, and C9 which exist on both AMIKey and Phoenix MultiKey/42, + but it does not write a byte after C9, which is consistent with AMIKey, so + this must have some form of AMIKey. */ { "[VIA VT82C495] FIC 486-VC-HD", "486vchd", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 64512, 1024, 127, machine_at_486vchd_init, NULL }, + /* According to Deksor on the Win3x.org forum, the BIOS string ends in a -0, + indicating an unknown KBC firmware. But it does send the AMIKey get version + command, so it must expect an AMIKey. */ { "[VLSI 82C480] HP Vectra 486VL", "vect486vl", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2048, 32768, 2048, 127, machine_at_vect486vl_init, at_vect486vl_get_device }, - { "[VLSI 82C481] Siemens Nixdorf D824", "d824", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2048, 32768, 2048, 127, machine_at_d824_init, at_d824_get_device }, + /* Has a standard IBM PS/2 KBC firmware or a clone thereof. */ + { "[VLSI 82C481] Siemens Nixdorf D824", "d824", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2048, 32768, 2048, 127, machine_at_d824_init, at_d824_get_device }, + + /* 486 machines - Socket 2 */ + /* 486 machines with just the ISA slot */ + /* Uses some variant of Phoenix MultiKey/42 as the BIOS sends keyboard controller + command C7 (OR input byte with received data byte). */ + { "[ACC 2168] Packard Bell PB410A", "pb410a", MACHINE_TYPE_486_S2, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 4096, 36864, 1024, 127, machine_at_pb410a_init, NULL }, + /* Uses an ACER/NEC 90M002A (UPD82C42C, 8042 clone) with unknown firmware (V4.01H). */ + { "[ALi M1429G] Acer A1G", "acera1g", MACHINE_TYPE_486_S2, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 4096, 36864, 1024, 127, machine_at_acera1g_init, at_acera1g_get_device }, + /* There are two similar BIOS strings with -H, and one with -U, so I'm going to + give it an AMIKey H KBC firmware. */ + { "[ALi M1429G] Kaimei 486", "win486", MACHINE_TYPE_486_S2, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 32768, 1024, 127, machine_at_winbios1429_init, NULL }, + /* Uses an Intel KBC with Phoenix MultiKey KBC firmware. */ + { "[SiS 461] DEC DECpc LPV", "decpc_lpv", MACHINE_TYPE_486_S2, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 1024, 32768, 1024, 127, machine_at_decpc_lpv_init, NULL }, + /* Uses an NEC 90M002A (UPD82C42C, 8042 clone) with unknown firmware. */ + { "[SiS 461] Acer V10", "acerv10", MACHINE_TYPE_486_S2, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 1024, 32768, 1024, 127, machine_at_acerv10_init, NULL }, + /* The BIOS does not send any non-standard keyboard controller commands and wants + a PS/2 mouse, so it's an IBM PS/2 KBC (Type 1) firmware. */ + { "[SiS 461] IBM PS/ValuePoint 433DX/Si", "valuepoint433", MACHINE_TYPE_486_S2, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 1024, 65536, 1024, 127, machine_at_valuepoint433_init, NULL }, + /* The BIOS string ends in -U, unless command 0xA1 (AMIKey get version) returns an + 'F', in which case, it ends in -F, so it has an AMIKey F KBC firmware. + The photo of the board shows an AMIKey KBC which is indeed F. */ + { "[SiS 471] ABit AB-AH4", "win471", MACHINE_TYPE_486_S2, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_win471_init, NULL }, /* 486 machines - Socket 3 */ /* 486 machines with just the ISA slot */ - { "[ACC 2168] Packard Bell PB410A", "pb410a", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 4096, 36864, 1024, 127, machine_at_pb410a_init, NULL }, - { "[ALi M1429G] Acer A1G", "acera1g", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 4096, 36864, 1024, 127, machine_at_acera1g_init, at_acera1g_get_device }, - { "[ALi M1429] AMI WinBIOS 486", "win486", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 32768, 1024, 127, machine_at_winbios1429_init, NULL }, + /* Has AMI MegaKey KBC firmware. */ + { "[Contaq 82C597] Green-B", "green-b", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB, 1024, 65536, 1024, 127, machine_at_green_b_init, NULL }, + /* Has a VIA VT82C42N KBC. */ { "[OPTi 895] Jetway J-403TG", "403tg", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB, 1024, 65536, 1024, 127, machine_at_403tg_init, NULL }, - { "[SiS 401] AMI 486 Clone", "sis401", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_sis401_init, NULL }, - { "[SiS 401] ASUS ISA-486", "isa486", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_isa486_init, NULL }, - { "[SiS 460] ABIT AV4", "av4", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_av4_init, NULL }, - { "[SiS 461] IBM PS/ValuePoint 433DX/Si", "valuepoint433", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 1024, 65536, 1024, 127, machine_at_valuepoint433_init, NULL }, - { "[SiS 471] AMI 486 Clone", "ami471", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_ami471_init, NULL }, - { "[SiS 471] AMI WinBIOS 486 clone", "win471", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_win471_init, NULL }, + /* Has JetKey 5 KBC Firmware which looks like it is a clone of AMIKey type F. */ + { "[OPTi 895] Jetway J-403TG Rev D", "403tg_rev_d", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB, 1024, 65536, 1024, 127, machine_at_403tg_rev_d_init, NULL }, + /* Has JetKey 5 KBC Firmware which looks like it is a clone of AMIKey type F. */ + { "[OPTi 895] Jetway J-403TG Rev D (MR BIOS)","403tg_rev_d_mr", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB, 1024, 65536, 1024, 127, machine_at_403tg_rev_d_mr_init, NULL }, + /* Has AMIKey H keyboard BIOS. */ { "[SiS 471] AOpen Vi15G", "vi15g", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_vi15g_init, NULL }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ { "[SiS 471] ASUS VL/I-486SV2G (GX4)", "vli486sv2g", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024, 65536, 1024, 127, machine_at_vli486sv2g_init, NULL }, + /* Has JetKey 5 KBC Firmware which looks like it is a clone of AMIKey type F. */ { "[SiS 471] DTK PKM-0038S E-2", "dtk486", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_dtk486_init, NULL }, - { "[SiS 471] Phoenix SiS 471", "px471", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024,131072, 1024, 127, machine_at_px471_init, NULL }, + /* Unknown Epox VLB Socket 3 board, has AMIKey F keyboard BIOS. */ + { "[SiS 471] Epox 486SX/DX Green", "ami471", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_ami471_init, NULL }, /* 486 machines which utilize the PCI bus */ + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { "[ALi M1489] AAEON SBC-490", "sbc-490", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 1024, 65536, 1024, 255, machine_at_sbc_490_init, at_sbc_490_get_device }, + /* Has the ALi M1487/9's on-chip keyboard controller which clones a standard AT + KBC. */ { "[ALi M1489] ABIT AB-PB4", "abpb4", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 65536, 1024, 255, machine_at_abpb4_init, NULL }, + /* Has the ALi M1487/9's on-chip keyboard controller which clones a standard AT + KBC. + The BIOS string always ends in -U, but the BIOS will send AMIKey commands 0xCA + and 0xCB if command 0xA1 returns a letter in the 0x5x or 0x7x ranges, so I'm + going to give it an AMI 'U' KBC. */ { "[ALi M1489] AMI WinBIOS 486 PCI", "win486pci", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 65536, 1024, 255, machine_at_win486pci_init, NULL }, + /* Has the ALi M1487/9's on-chip keyboard controller which clones a standard AT + KBC. + The known BIOS string ends in -E, and the BIOS returns whatever command 0xA1 + returns (but only if command 0xA1 is instant response), so said ALi keyboard + controller likely returns 'E'. */ + { "[ALi M1489] MSI MS-4145", "ms4145", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 65536, 1024, 255, machine_at_ms4145_init, NULL }, + /* Has an ALi M5042 keyboard controller with Phoenix MultiKey/42 v1.40 firmware. */ + { "[ALi M1489] ESA TF-486", "tf-486", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024, 65536, 1024, 255, machine_at_tf_486_init, NULL }, + /* Has IBM PS/2 Type 1 KBC firmware. */ { "[OPTi 802G] IBM PC 330 (type 6573)", "pc330_6573", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3_PC330, 0, 25000000, 33333333, 0, 0, 2.0, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_pc330_6573_init, NULL }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ { "[i420EX] ASUS PVI-486AP4", "486ap4", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCIV | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024, 131072, 1024, 127, machine_at_486ap4_init, NULL }, + /* This has the Phoenix MultiKey KBC firmware. */ + { "[i420EX] Intel Classic/PCI ED", "ninja", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024, 131072, 1024, 127, machine_at_ninja_init, NULL }, + /* This has an AMIKey-2, which is an updated version of type 'H'. Also has a + SST 29EE010 Flash chip. */ { "[i420ZX] ASUS PCI/I-486SP3G", "486sp3g", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_SCSI, 1024, 131072, 1024, 127, machine_at_486sp3g_init, NULL }, + /* I'm going to assume this as an AMIKey-2 like the other two 486SP3's. */ { "[i420TX] ASUS PCI/I-486SP3", "486sp3", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL | MACHINE_SCSI, 1024, 131072, 1024, 127, machine_at_486sp3_init, NULL }, + /* This has the Phoenix MultiKey KBC firmware. */ { "[i420TX] Intel Classic/PCI", "alfredo", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_alfredo_init, NULL }, + /* This most likely has a standalone AMI Megakey 1993, which is type 'P', like the below Tekram board. */ + { "[IMS 8848] J-Bond PCI400C-B", "pci400c_b", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_pci400c_b_init, NULL }, + /* This has a standalone AMI Megakey 1993, which is type 'P'. */ + { "[IMS 8848] Tekram G486IP", "g486ip", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_g486ip_init, NULL }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ { "[SiS 496] ASUS PVI-486SP3C", "486sp3c", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCIV | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024, 261120, 1024, 255, machine_at_486sp3c_init, NULL }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ { "[SiS 496] Lucky Star LS-486E", "ls486e", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 131072, 1024, 255, machine_at_ls486e_init, NULL }, + /* The BIOS does not send a single non-standard KBC command, so it has a standard PS/2 KBC. */ { "[SiS 496] Micronics M4Li", "m4li", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024, 131072, 1024, 127, machine_at_m4li_init, NULL }, + /* Has a BestKey KBC which clones AMI type 'H'. */ { "[SiS 496] Rise Computer R418", "r418", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 261120, 1024, 255, machine_at_r418_init, NULL }, + /* This has a Holtek KBC and the BIOS does not send a single non-standard KBC command, so it + must be an ASIC that clones the standard IBM PS/2 KBC. */ { "[SiS 496] Soyo 4SA2", "4sa2", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, CPU_BLOCK(CPU_i486SX, CPU_i486DX, CPU_Am486SX, CPU_Am486DX), 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 261120, 1024, 255, machine_at_4sa2_init, NULL }, + /* According to MrKsoft, his real 4DPS has an AMIKey-2, which is an updated version + of type 'H'. */ { "[SiS 496] Zida Tomato 4DP", "4dps", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024, 261120, 1024, 255, machine_at_4dps_init, NULL }, - { "[UMC 8881] A-Trend ATC-1415", "atc1415", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 65536, 1024, 255, machine_at_atc1415_init, NULL }, - { "[UMC 8881] ECS Elite UM8810PAIO", "ecs486", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 131072, 1024, 255, machine_at_ecs486_init, NULL }, - { "[UMC 8881] Shuttle HOT-433A", "hot433", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 262144, 1024, 255, machine_at_hot433_init, NULL }, + /* This has the UMC 88xx on-chip KBC. */ + { "[UMC 888x] A-Trend ATC-1415", "atc1415", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 65536, 1024, 255, machine_at_atc1415_init, NULL }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { "[UMC 888x] ECS Elite UM8810PAIO", "ecs486", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 131072, 1024, 255, machine_at_ecs486_init, NULL }, + /* Has AMIKey Z(!) KBC firmware. */ + { "[UMC 888x] Epson Action PC 2600", "actionpc2600", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 262144, 1024, 255, machine_at_actionpc2600_init, NULL }, + /* This has the UMC 88xx on-chip KBC. All the copies of the BIOS string I can find, end in + in -H, so the UMC on-chip KBC likely emulates the AMI 'H' KBC firmware. */ + { "[UMC 888x] PC Chips M919", "m919", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_VLB | MACHINE_IDE_DUAL, 1024, 131072, 1024, 255, machine_at_m919_init, NULL }, + /* Has IBM PS/2 Type 1 KBC firmware. Uses a mysterious I/O port C05. */ + { "[UMC 888x] Samsung SPC7700P-LW", "spc7700p-lw", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024, 131072, 1024, 255, machine_at_spc7700p_lw_init, NULL }, + /* This has a Holtek KBC. */ + { "[UMC 888x] Shuttle HOT-433A", "hot433", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 262144, 1024, 255, machine_at_hot433_init, NULL }, + /* Has a VIA VT82C406 KBC+RTC that likely has identical commands to the VT82C42N. */ + { "[VIA VT82C496G] DFI G486VPA", "g486vpa", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCIV | MACHINE_IDE_DUAL, 1024, 131072, 1024, 255, machine_at_g486vpa_init, NULL }, + /* Has a VIA VT82C42N KBC. */ { "[VIA VT82C496G] FIC VIP-IO2", "486vipio2", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCIV | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024, 131072, 1024, 255, machine_at_486vipio2_init, NULL }, /* 486 machines - Miscellaneous */ - /* 486 machines with just the ISA slot */ - { "[OPTi 283] RYC Leopard LX", "rycleopardlx", MACHINE_TYPE_486_MISC, CPU_PKG_486SLC_IBM, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 1024, 16384, 1024, 127, machine_at_rycleopardlx_init, NULL }, - /* 486 machines which utilize the PCI bus */ + /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[STPC Client] ITOX STAR", "itoxstar", MACHINE_TYPE_486_MISC, CPU_PKG_STPC, 0, 66666667, 75000000, 0, 0, 1.0, 1.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 255, machine_at_itoxstar_init, NULL }, + /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { "[STPC Consumer-II] Acrosser AR-B1423C", "arb1423c", MACHINE_TYPE_486_MISC, CPU_PKG_STPC, 0, 66666667, 66666667, 0, 0, 2.0, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 32768, 163840, 8192, 255, machine_at_arb1423c_init, NULL }, + /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[STPC Consumer-II] Acrosser AR-B1479", "arb1479", MACHINE_TYPE_486_MISC, CPU_PKG_STPC, 0, 66666667, 66666667, 0, 0, 2.0, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 32768, 163840, 8192, 255, machine_at_arb1479_init, NULL }, + /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[STPC Elite] Advantech PCM-9340", "pcm9340", MACHINE_TYPE_486_MISC, CPU_PKG_STPC, 0, 66666667, 66666667, 0, 0, 2.0, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 32768, 98304, 8192, 255, machine_at_pcm9340_init, NULL }, + /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[STPC Atlas] AAEON PCM-5330", "pcm5330", MACHINE_TYPE_486_MISC, CPU_PKG_STPC, 0, 66666667, 66666667, 0, 0, 2.0, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 32768, 131072,32768, 255, machine_at_pcm5330_init, NULL }, /* Socket 4 machines */ /* 430LX */ + /* Has AMIKey H KBC firmware (AMIKey-2), per POST screen with BIOS string + shown in the manual. Has PS/2 mouse support with serial-style (DB9) + connector. + The boot block for BIOS recovery requires an unknown bit on port 805h + to be clear. */ + { "[i430LX] AMI Excalibur PCI Pentium", "excalibur_pci", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_excalibur_pci_init, NULL }, + /* Has AMIKey F KBC firmware (AMIKey). */ { "[i430LX] ASUS P/I-P5MP3", "p5mp3", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE, 2048, 196608, 2048, 127, machine_at_p5mp3_init, NULL }, + /* Has IBM PS/2 Type 1 KBC firmware. */ { "[i430LX] Dell Dimension XPS P60", "dellxp60", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE, 2048, 131072, 2048, 127, machine_at_dellxp60_init, NULL }, + /* Has IBM PS/2 Type 1 KBC firmware. */ { "[i430LX] Dell OptiPlex 560/L", "opti560l", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_opti560l_init, NULL }, + /* This has the Phoenix MultiKey KBC firmware. + This is basically an Intel Batman (*NOT* Batman's Revenge) with a fancier + POST screen */ { "[i430LX] AMBRA DP60 PCI", "ambradp60", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_ambradp60_init, NULL }, + /* Has IBM PS/2 Type 1 KBC firmware. */ { "[i430LX] IBM PS/ValuePoint P60", "valuepointp60", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_valuepointp60_init, NULL }, - { "[i430LX] Intel Premiere/PCI", "revenge", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_batman_init, NULL }, + /* This has the Phoenix MultiKey KBC firmware. */ + { "[i430LX] Intel Premiere/PCI", "revenge", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_revenge_init, NULL }, + /* Has AMI MegaKey KBC firmware. */ { "[i430LX] Micro Star 586MC1", "586mc1", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_586mc1_init, NULL }, + /* This has the Phoenix MultiKey KBC firmware. */ { "[i430LX] Packard Bell PB520R", "pb520r", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8192, 139264, 2048, 127, machine_at_pb520r_init, at_pb520r_get_device }, /* OPTi 596/597 */ + /* This uses an AMI KBC firmware in PS/2 mode (it sends command A5 with the + PS/2 "Load Security" meaning), most likely MegaKey as it sends command AF + (Set Extended Controller RAM) just like the later Intel AMI BIOS'es. */ { "[OPTi 597] AMI Excalibur VLB", "excalibur", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_VLB | MACHINE_BUS_PS2 | MACHINE_IDE, 2048, 65536, 2048, 127, machine_at_excalibur_init, NULL }, - /* SiS 85C50x */ - { "[SiS 85C50x] ASUS PCI/I-P5SP4", "p5sp4", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_p5sp4_init, NULL }, + /* OPTi 596/597/822 */ + /* This has AMIKey 'F' KBC firmware. */ + { "[OPTi 597] Supermicro P5VL-PCI", "p5vl", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_VLB, 8192, 131072, 8192, 127, machine_at_p5vl_init, NULL }, + + /* SiS 50x */ + /* This has an unknown AMI KBC firmware, most likely AMIKey / type 'F'. */ + { "[SiS 50x] AMI Excalibur PCI-II Pentium ISA","excalibur_pci-2", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_excalibur_pci_2_init, NULL }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { "[SiS 50x] ASUS PCI/I-P5SP4", "p5sp4", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_p5sp4_init, NULL }, /* Socket 5 machines */ /* 430NX */ + /* This has the Phoenix MultiKey KBC firmware. */ { "[i430NX] Intel Premiere/PCI II", "plato", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_plato_init, NULL }, + /* This has the Phoenix MultiKey KBC firmware. + This is basically an Intel Premiere/PCI II with a fancier POST screen. */ { "[i430NX] AMBRA DP90 PCI", "ambradp90", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 1.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_ambradp90_init, NULL }, + /* Has AMI MegaKey KBC firmware. */ { "[i430NX] Gigabyte GA-586IP", "430nx", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_430nx_init, NULL }, /* 430FX */ + /* Uses an ACER/NEC 90M002A (UPD82C42C, 8042 clone) with unknown firmware (V5.0). */ { "[i430FX] Acer V30", "acerv30", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_acerv30_init, NULL }, + /* Has AMIKey F KBC firmware. */ { "[i430FX] AMI Apollo", "apollo", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_apollo_init, NULL }, + /* Has AMIKey H KBC firmware. */ + { "[i430FX] Dataexpert EXP8551", "exp8551", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_exp8551_init, NULL }, + /* The BIOS does not send a single non-standard KBC command, but the board has a SMC Super I/O + chip with on-chip KBC and AMI MegaKey KBC firmware. */ { "[i430FX] HP Vectra VL 5 Series 4", "vectra54", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8192, 131072, 8192, 511, machine_at_vectra54_init, at_vectra54_get_device }, + /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the + PC87306 Super I/O chip, command 0xA1 returns '5'. + Command 0xA0 copyright string: (C)1994 AMI . */ { "[i430FX] Intel Advanced/ZP", "zappa", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_zappa_init, NULL }, + /* The BIOS sends KBC command B3 which indicates an AMI (or VIA VT82C42N) KBC. */ { "[i430FX] NEC PowerMate V", "powermatev", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_powermatev_init, NULL }, + /* Has a VIA VT82C42N KBC. */ { "[i430FX] PC Partner MB500N", "mb500n", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_mb500n_init, NULL }, + /* Has AMIKey Z(!) KBC firmware. */ + { "[i430FX] Trigem Hawk", "hawk", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_hawk_init, NULL }, /* OPTi 596/597 */ + /* This uses an AMI KBC firmware in PS/2 mode (it sends command A5 with the + PS/2 "Load Security" meaning), most likely MegaKey as it sends command AF + (Set Extended Controller RAM) just like the later Intel AMI BIOS'es. */ { "[OPTi 597] TMC PAT54PV", "pat54pv", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, CPU_BLOCK(CPU_K5, CPU_5K86), 50000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_VLB, 2048, 65536, 2048, 127, machine_at_pat54pv_init, NULL }, /* OPTi 596/597/822 */ { "[OPTi 597] Shuttle HOT-543", "hot543", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_PCI | MACHINE_VLB, 8192, 131072, 8192, 127, machine_at_hot543_init, NULL }, - { "[OPTi 597] Supermicro P54VL-PCI", "p54vl", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_PCI | MACHINE_VLB, 8192, 131072, 8192, 127, machine_at_p54vl_init, NULL }, /* SiS 85C50x */ + /* This has an AMIKey-2, which is an updated version of type 'H'. */ { "[SiS 85C50x] ASUS PCI/I-P54SP4", "p54sp4", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, CPU_BLOCK(CPU_K5, CPU_5K86), 40000000, 66666667, 3380, 3520, 1.5, 1.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_p54sp4_init, NULL }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ { "[SiS 85C50x] BCM SQ-588", "sq588", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, CPU_BLOCK(CPU_PENTIUMMMX), 50000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_sq588_init, NULL }, - /* UMC 889x */ - { "[UMC 889x] Shuttle HOT-539", "hot539", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, CPU_BLOCK(CPU_K5, CPU_5K86), 40000000, 66666667, 3380, 3600, 1.5, 2.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 127, machine_at_hot539_init, NULL }, - /* Socket 7 (Single Voltage) machines */ /* 430FX */ + /* This has an AMIKey-2, which is an updated version of type 'H'. */ { "[i430FX] ASUS P/I-P54TP4XE", "p54tp4xe", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3600, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_p54tp4xe_init, NULL }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ { "[i430FX] ASUS P/I-P54TP4XE (MR BIOS)", "mr586", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3600, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_mr586_init, NULL }, - { "[i430FX] Gateway 2000 Thor", "gw2katx", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8192, 131072, 8192, 127, machine_at_gw2katx_init, NULL }, - { "[i430FX] Intel Advanced/ATX", "thor", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8192, 131072, 8192, 127, machine_at_thor_init, NULL }, - { "[i430FX] Intel Advanced/ATX (MR BIOS)", "mrthor", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8192, 131072, 8192, 127, machine_at_mrthor_init, NULL }, + /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the + PC87306 Super I/O chip, command 0xA1 returns '5'. + Command 0xA0 copyright string: (C)1994 AMI . */ + { "[i430FX] Gateway 2000 Thor", "gw2katx", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_gw2katx_init, NULL }, + /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the + PC87306 Super I/O chip, command 0xA1 returns '5'. + Command 0xA0 copyright string: (C)1994 AMI . */ + { "[i430FX] Intel Advanced/ATX", "thor", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8192, 131072, 8192, 127, machine_at_thor_init, at_thor_get_device }, + /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the + PC87306 Super I/O chip, command 0xA1 returns '5'. + Command 0xA0 copyright string: (C)1994 AMI . */ + { "[i430FX] Intel Advanced/ATX (MR BIOS)", "mrthor", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_mrthor_init, at_mrthor_get_device }, + /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the + PC87306 Super I/O chip, command 0xA1 returns '5'. + Command 0xA0 copyright string: (C)1994 AMI . */ { "[i430FX] Intel Advanced/EV", "endeavor", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8192, 131072, 8192, 127, machine_at_endeavor_init, at_endeavor_get_device }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { "[i430FX] MSI MS-5119", "ms5119", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_ms5119_init, NULL }, + /* This most likely uses AMI MegaKey KBC firmware as well due to having the same + Super I/O chip (that has the KBC firmware on it) as eg. the Advanced/EV. */ { "[i430FX] Packard Bell PB640", "pb640", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8192, 131072, 8192, 127, machine_at_pb640_init, at_pb640_get_device }, - { "[i430FX] QDI Chariot", "chariot", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, CPU_BLOCK(CPU_WINCHIP, CPU_WINCHIP2, CPU_Cx6x86, CPU_Cx6x86L, CPU_Cx6x86MX), 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_chariot_init, NULL }, + /* Has an AMI 'H' KBC firmware (1992). */ + { "[i430FX] QDI FMB", "fmb", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, CPU_BLOCK(CPU_WINCHIP, CPU_WINCHIP2, CPU_Cx6x86, CPU_Cx6x86L, CPU_Cx6x86MX), 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_fmb_init, NULL }, /* 430HX */ + /* I can't determine what KBC firmware this has, but given that the Acer V35N and + V60 have Phoenix MultiKey KBC firmware on the chip, I'm going to assume so + does the M3A. */ { "[i430HX] Acer M3A", "acerm3a", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3300, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 196608, 8192, 127, machine_at_acerm3a_init, NULL }, + /* Has AMIKey F KBC firmware. */ { "[i430HX] AOpen AP53", "ap53", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3450, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 524288, 8192, 127, machine_at_ap53_init, NULL }, + /* [TEST] Has a VIA 82C42N KBC, with AMIKey F KBC firmware. */ { "[i430HX] Biostar MB-8500TUC", "8500tuc", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 524288, 8192, 127, machine_at_8500tuc_init, NULL }, + /* [TEST] Unable to determine what KBC this has. A list on a Danish site shows + the BIOS as having a -0 string, indicating non-AMI KBC firmware. */ { "[i430HX] SuperMicro Super P55T2S", "p55t2s", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3300, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 127, machine_at_p55t2s_init, NULL }, /* 430VX */ + /* Has AMIKey H KBC firmware (AMIKey-2). */ + { "[i430VX] ECS P5VX-B", "p5vxb", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_p5vxb_init, NULL }, + /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the + PC87306 Super I/O chip, command 0xA1 returns '5'. + Command 0xA0 copyright string: (C)1994 AMI . */ { "[i430VX] Gateway 2000 Tigereye", "gw2kte", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_gw2kte_init, NULL }, /* SiS 5511 */ - { "[SiS 5511] AOpen AP5S", "ap5s", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 524288, 8192, 127, machine_at_ap5s_init, NULL }, + /* Has AMIKey H KBC firmware (AMIKey-2). */ + { "[SiS 5511] AOpen AP5S", "ap5s", MACHINE_TYPE_SOCKET7_3V, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 524288, 8192, 127, machine_at_ap5s_init, NULL }, /* Socket 7 (Dual Voltage) machines */ /* 430HX */ + /* Has SST flash and the SMC FDC73C935's on-chip KBC with Phoenix MultiKey firmware. */ { "[i430HX] Acer V35N", "acerv35n", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, CPU_BLOCK(CPU_Cx6x86MX), 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 196608, 8192, 127, machine_at_acerv35n_init, NULL }, + /* Has AMIKey H KBC firmware (AMIKey-2). */ { "[i430HX] ASUS P/I-P55T2P4", "p55t2p4", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 83333333, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 127, machine_at_p55t2p4_init, NULL }, + /* Has the SMC FDC73C935's on-chip KBC with Phoenix MultiKey firmware. */ { "[i430HX] Micronics M7S-Hi", "m7shi", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 511, machine_at_m7shi_init, NULL }, + /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the + PC87306 Super I/O chip, command 0xA1 returns '5'. + Command 0xA0 copyright string: (C)1994 AMI . */ { "[i430HX] Intel TC430HX", "tc430hx", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 255, machine_at_tc430hx_init, NULL }, + /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the + PC87306 Super I/O chip, command 0xA1 returns '5'. + Command 0xA0 copyright string: (C)1994 AMI . */ { "[i430HX] Toshiba Equium 5200D", "equium5200", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 196608, 8192, 127, machine_at_equium5200_init, NULL }, + /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the + PC87306 Super I/O chip, command 0xA1 returns '5'. + Command 0xA0 copyright string: (C)1994 AMI . + Yes, this is an Intel AMI BIOS with a fancy splash screen. */ { "[i430HX] Sony Vaio PCV-240", "pcv240", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 196608, 8192, 127, machine_at_pcv240_init, NULL }, + /* The base board has AMIKey-2 (updated 'H') KBC firmware. */ { "[i430HX] ASUS P/I-P65UP5 (C-P55T2D)", "p65up5_cp55t2d", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 524288, 8192, 127, machine_at_p65up5_cp55t2d_init, NULL }, /* 430VX */ + /* This has the VIA VT82C42N KBC. */ + { "[i430VX] AOpen AP5VM", "ap5vm", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2600, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_SCSI, 8192, 131072, 8192, 127, machine_at_ap5vm_init, NULL }, + /* Has AMIKey H KBC firmware (AMIKey-2). */ { "[i430VX] ASUS P/I-P55TVP4", "p55tvp4", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_p55tvp4_init, NULL }, + /* The BIOS does not send a single non-standard KBC command, so it must have a standard IBM + PS/2 KBC firmware or a clone thereof. */ { "[i430VX] Azza 5IVG", "5ivg", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_5ivg_init, NULL }, + /* [TEST] Has AMIKey 'F' KBC firmware. */ { "[i430VX] Biostar MB-8500TVX-A", "8500tvxa", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2600, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_8500tvxa_init, NULL }, - { "[i430VX] Compaq Presario 2240", "presario2240", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8192, 131072, 8192, 127, machine_at_presario2240_init, NULL }, - { "[i430VX] Compaq Presario 4500", "presario4500", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8192, 131072, 8192, 127, machine_at_presario4500_init, NULL }, + /* The BIOS does not send a single non-standard KBC command, but the board has a SMC Super I/O + chip with on-chip KBC and AMI MegaKey KBC firmware. */ + { "[i430VX] Compaq Presario 2240", "presario2240", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8192, 131072, 8192, 127, machine_at_presario2240_init, at_presario2240_get_device }, + /* This most likely has AMI MegaKey as above. */ + { "[i430VX] Compaq Presario 4500", "presario4500", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8192, 131072, 8192, 127, machine_at_presario4500_init, at_presario4500_get_device }, + /* The BIOS sends KBC command CB which is an AMI KBC command, so it has an AMI KBC firmware. */ { "[i430VX] Epox P55-VA", "p55va", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_p55va_init, NULL }, + /* The BIOS does not send a single non-standard KBC command. */ { "[i430VX] HP Brio 80xx", "brio80xx", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 66666667, 66666667, 2200, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_brio80xx_init, NULL }, + /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the + PC87306 Super I/O chip, command 0xA1 returns '5'. + Command 0xA0 copyright string: (C)1994 AMI . */ { "[i430VX] Packard Bell PB680", "pb680", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_pb680_init, NULL }, + /* This has the AMIKey 'H' firmware, possibly AMIKey-2. Photos show it with a BestKey, so it + likely clones the behavior of AMIKey 'H'. */ { "[i430VX] PC Partner MB520N", "mb520n", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2600, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_mb520n_init, NULL }, + /* This has a Holtek KBC and the BIOS does not send a single non-standard KBC command, so it + must be an ASIC that clones the standard IBM PS/2 KBC. */ { "[i430VX] Shuttle HOT-557", "430vx", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_GAMEPORT, 8192, 131072, 8192, 127, machine_at_i430vx_init, NULL }, /* 430TX */ + /* The BIOS sends KBC command B8, CA, and CB, so it has an AMI KBC firmware. */ { "[i430TX] ADLink NuPRO-592", "nupro592", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 66666667, 66666667, 1900, 2800, 1.5, 5.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 255, machine_at_nupro592_init, NULL }, + /* This has the AMIKey KBC firmware, which is an updated 'F' type (YM430TX is based on the TX97). */ { "[i430TX] ASUS TX97", "tx97", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 75000000, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 255, machine_at_tx97_init, NULL }, #if defined(DEV_BRANCH) && defined(NO_SIO) + /* This has the Phoenix MultiKey KBC firmware. */ { "[i430TX] Intel AN430TX", "an430tx", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 255, machine_at_an430tx_init, NULL }, #endif + /* This has the AMIKey KBC firmware, which is an updated 'F' type. */ { "[i430TX] Intel YM430TX", "ym430tx", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 255, machine_at_ym430tx_init, NULL }, + /* The BIOS sends KBC command BB and expects it to output a byte, which is AMI KBC behavior. */ { "[i430TX] PC Partner MB540N", "mb540n", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 2700, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 255, machine_at_mb540n_init, NULL }, + /* [TEST] Has AMIKey 'H' KBC firmware. */ { "[i430TX] SuperMicro Super P5MMS98", "p5mms98", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2100, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 255, machine_at_p5mms98_init, NULL }, /* Apollo VPX */ + /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ { "[VIA VPX] FIC VA-502", "ficva502", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 75000000, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 524288, 8192, 127, machine_at_ficva502_init, NULL }, /* Apollo VP3 */ + /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ { "[VIA VP3] FIC PA-2012", "ficpa2012", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 55000000, 75000000, 2100, 3520, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 127, machine_at_ficpa2012_init, NULL }, /* SiS 5571 */ + /* Has the SiS 5571 chipset with on-chip KBC. */ { "[SiS 5571] Rise R534F", "r534f", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 393216, 8192, 127, machine_at_r534f_init, NULL }, + /* Has the SiS 5571 chipset with on-chip KBC. */ { "[SiS 5571] MSI MS-5146", "ms5146", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 127, machine_at_ms5146_init, NULL }, - /* ALi ALADDiN IV */ -#if defined(DEV_BRANCH) && defined(USE_M154X) - { "[ALi ALADDiN IV] PC Chips M560", "m560", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 83333333, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 255, machine_at_m560_init, NULL }, - { "[ALi ALADDiN IV] MSI MS-5164", "ms5164", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 2100, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 255, machine_at_ms5164_init, NULL }, -#endif + /* ALi ALADDiN IV+ */ + /* Has the ALi M1543 southbridge with on-chip KBC. */ + { "[ALi ALADDiN IV+] PC Chips M560", "m560", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 83333333, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 255, machine_at_m560_init, NULL }, + /* Has the ALi M1543 southbridge with on-chip KBC. */ + { "[ALi ALADDiN IV+] MSI MS-5164", "ms5164", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 2100, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 255, machine_at_ms5164_init, NULL }, /* Super Socket 7 machines */ + /* ALi ALADDiN V */ + /* Has the ALi M1543C southbridge with on-chip KBC. */ + { "[ALi ALADDiN V] ASUS P5A", "p5a", MACHINE_TYPE_SOCKETS7, CPU_PKG_SOCKET5_7, 0, 66666667, 124242424, 2000, 3200, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024,2097152, 8192, 255, machine_at_p5a_init, NULL }, + /* Is the exact same as the Matsonic MS6260S. Has the ALi M1543C southbridge + with on-chip KBC. */ + { "[ALi ALADDiN V] PC Chips M579", "m579", MACHINE_TYPE_SOCKETS7, CPU_PKG_SOCKET5_7, 0, 66666667, 124242424, 2000, 3200, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024,2097152, 8192, 255, machine_at_m579_init, NULL }, + /* Has the ALi M1543C southbridge with on-chip KBC. */ + { "[ALi ALADDiN V] Gigabyte GA-5AA", "ga-5aa", MACHINE_TYPE_SOCKETS7, CPU_PKG_SOCKET5_7, 0, 66666667, 124242424, 2000, 3200, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024,2097152, 8192, 255, machine_at_ga_5aa_init, NULL }, + /* Has the ALi M1543C southbridge with on-chip KBC. */ + { "[ALi ALADDiN V] Gigabyte GA-5AX", "ga-5ax", MACHINE_TYPE_SOCKETS7, CPU_PKG_SOCKET5_7, 0, 66666667, 124242424, 2000, 3200, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024,2097152, 8192, 255, machine_at_ga_5ax_init, NULL }, + /* Apollo MVP3 */ + /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ { "[VIA MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_TYPE_SOCKETS7, CPU_PKG_SOCKET5_7, 0, 66666667, 124242424, 1300, 3520, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_ax59pro_init, NULL }, + /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ { "[VIA MVP3] FIC VA-503+", "ficva503p", MACHINE_TYPE_SOCKETS7, CPU_PKG_SOCKET5_7, 0, 66666667, 124242424, 2000, 3200, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_mvp3_init, NULL }, + /* Has the VIA VT82C686A southbridge with on-chip KBC identical to the VIA + VT82C42N. */ { "[VIA MVP3] FIC VA-503A", "ficva503a", MACHINE_TYPE_SOCKETS7, CPU_PKG_SOCKET5_7, 0, 66666667, 124242424, 1800, 3100, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_ficva503a_init, NULL }, + /* Has the VIA VT82C686A southbridge with on-chip KBC identical to the VIA + VT82C42N. */ + { "[VIA MVP3] Soyo SY-5EMA Pro", "sy-5ema_pro", MACHINE_TYPE_SOCKETS7, CPU_PKG_SOCKET5_7, 0, 66666667, 124242424, 1800, 3100, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_sy_5ema_pro_init, NULL }, /* Socket 8 machines */ /* 450KX */ -#if defined(DEV_BRANCH) && defined(USE_I450KX) + /* This has an AMIKey-2, which is an updated version of type 'H'. */ { "[i450KX] ASUS P/I-P6RP4", "p6rp4", MACHINE_TYPE_SOCKET8, CPU_PKG_SOCKET8, 0, 60000000, 66666667, 2100, 3500, 1.5, 8.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 524288, 8192, 127, machine_at_p6rp4_init, NULL }, -#endif /* 440FX */ + /* Has the SMC FDC73C935's on-chip KBC with Phoenix MultiKey firmware. */ { "[i440FX] Acer V60N", "v60n", MACHINE_TYPE_SOCKET8, CPU_PKG_SOCKET8, 0, 60000000, 66666667, 2500, 3500, 1.5, 8.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 524288, 8192, 127, machine_at_v60n_init, NULL }, + /* The base board has AMIKey-2 (updated 'H') KBC firmware. */ { "[i440FX] ASUS P/I-P65UP5 (C-P6ND)", "p65up5_cp6nd", MACHINE_TYPE_SOCKET8, CPU_PKG_SOCKET8, 0, 60000000, 66666667, 2100, 3500, 1.5, 8.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 127, machine_at_p65up5_cp6nd_init, NULL }, + /* The MB-8600TTX has an AMIKey 'F' KBC firmware, so I'm going to assume so does + the MB-8600TTC until someone can actually identify it. */ { "[i440FX] Biostar MB-8600TTC", "8600ttc", MACHINE_TYPE_SOCKET8, CPU_PKG_SOCKET8, 0, 50000000, 66666667, 2900, 3300, 2.0, 5.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 127, machine_at_8500ttc_init, NULL }, { "[i440FX] Gigabyte GA-686NX", "686nx", MACHINE_TYPE_SOCKET8, CPU_PKG_SOCKET8, 0, 60000000, 66666667, 2100, 3500, 2.0, 5.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 524288, 8192, 127, machine_at_686nx_init, NULL }, + /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the + PC87306 Super I/O chip, command 0xA1 returns '5'. + Command 0xA0 copyright string: (C)1994 AMI . */ { "[i440FX] Intel AP440FX", "ap440fx", MACHINE_TYPE_SOCKET8, CPU_PKG_SOCKET8, 0, 60000000, 66666667, 2100, 3500, 2.0, 3.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_ap440fx_init, NULL }, + /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the + PC87306 Super I/O chip, command 0xA1 returns '5'. + Command 0xA0 copyright string: (C)1994 AMI . */ { "[i440FX] Intel VS440FX", "vs440fx", MACHINE_TYPE_SOCKET8, CPU_PKG_SOCKET8, 0, 60000000, 66666667, 2100, 3500, 2.0, 3.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 524288, 8192, 127, machine_at_vs440fx_init, NULL }, + /* Has the SMC FDC73C935's on-chip KBC with Phoenix MultiKey firmware. */ { "[i440FX] Micronics M6Mi", "m6mi", MACHINE_TYPE_SOCKET8, CPU_PKG_SOCKET8, 0, 60000000, 66666667, 2900, 3300, 1.5, 8.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 127, machine_at_m6mi_init, NULL }, + /* I found a BIOS string of it that ends in -S, but it could be a typo for -5 + (there's quite a few AMI BIOS strings around with typo'd KBC codes), so I'm + going to give it an AMI MegaKey. */ { "[i440FX] PC Partner MB600N", "mb600n", MACHINE_TYPE_SOCKET8, CPU_PKG_SOCKET8, 0, 60000000, 66666667, 2100, 3500, 1.5, 8.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 524288, 8192, 127, machine_at_mb600n_init, NULL }, /* Slot 1 machines */ + /* ALi ALADDiN V */ + /* Has the ALi M1543C southbridge with on-chip KBC. */ + { "[ALi ALADDiN-PRO II] PC Chips M729", "m729", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 50000000, 66666667, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024,2097152, 8192, 255, machine_at_m729_init, NULL }, + /* 440FX */ + /* The base board has AMIKey-2 (updated 'H') KBC firmware. */ { "[i440FX] ASUS P/I-P65UP5 (C-PKND)", "p65up5_cpknd", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 50000000, 66666667, 1800, 3500, 1.5, 8.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 127, machine_at_p65up5_cpknd_init, NULL }, + /* This has a Holtek KBC and the BIOS does not send a single non-standard KBC command, so it + must be an ASIC that clones the standard IBM PS/2 KBC. */ { "[i440FX] ASUS KN97", "kn97", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 60000000, 83333333, 1800, 3500, 1.5, 8.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 127, machine_at_kn97_init, NULL }, /* 440LX */ + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[i440LX] ABIT LX6", "lx6", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 60000000, 100000000, 1500, 3500, 2.0, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_lx6_init, NULL }, + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey KBC firmware. */ { "[i440LX] Micronics Spitfire", "spitfire", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 66666667, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_spitfire_init, NULL }, /* 440EX */ + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[i440EX] QDI EXCELLENT II", "p6i440e2", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 83333333, 1800, 3500, 3.0, 8.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 524288, 8192, 255, machine_at_p6i440e2_init, NULL }, /* 440BX */ + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[i440BX] ASUS P2B-LS", "p2bls", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 50000000, 112121212, 1300, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_p2bls_init, NULL }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[i440BX] ASUS P3B-F", "p3bf", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 150000000, 1300, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_p3bf_init, NULL }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[i440BX] ABIT BF6", "bf6", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 133333333, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_bf6_init, NULL }, + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[i440BX] AOpen AX6BC", "ax6bc", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 112121212, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_ax6bc_init, NULL }, + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[i440BX] Gigabyte GA-686BX", "686bx", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 100000000, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_686bx_init, NULL }, + /* Has a SM(S)C FDC37M60x Super I/O chip with on-chip KBC with most likely + AMIKey-2 KBC firmware. */ { "[i440BX] HP Vectra VEi 8", "vei8", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 100000000, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_vei8_init, NULL }, + /* Has a National Semiconductors PC87309 Super I/O chip with on-chip KBC + with most likely AMIKey-2 KBC firmware. */ { "[i440BX] Tyan Tsunami ATX", "tsunamiatx", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 112121212, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_SOUND, 8192,1048576, 8192, 255, machine_at_tsunamiatx_init, at_tsunamiatx_get_device }, + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[i440BX] SuperMicro Super P6SBA", "p6sba", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 100000000, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_p6sba_init, NULL }, -#if defined(DEV_BRANCH) && defined(NO_SIO) - { "[i440BX] Fujitsu ErgoPro x365", "ergox365", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 100000000, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 393216, 8192, 511, machine_at_ergox365_init, NULL }, -#endif /* 440ZX */ + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[i440ZX] MSI MS-6168", "ms6168", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 100000000, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_SOUND,8192, 524288, 8192, 255, machine_at_ms6168_init, NULL }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[i440ZX] Packard Bell Bora Pro", "borapro", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 66666667, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_SOUND,8192, 524288, 8192, 255, machine_at_borapro_init, NULL }, /* SMSC VictoryBX-66 */ + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[SMSC VictoryBX-66] A-Trend ATC6310BXII","atc6310bxii", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 133333333, 1300, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_atc6310bxii_init, NULL }, /* VIA Apollo Pro */ + /* Has the VIA VT82C596B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ { "[VIA Apollo Pro] FIC KA-6130", "ficka6130", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 100000000, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 524288, 8192, 255, machine_at_ficka6130_init, NULL }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[VIA Apollo Pro133] ASUS P3V133", "p3v133", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 150000000, 1300, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1572864, 8192, 255, machine_at_p3v133_init, NULL }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[VIA Apollo Pro133A] ASUS P3V4X", "p3v4x", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 150000000, 1300, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,2097152, 8192, 255, machine_at_p3v4x_init, NULL }, /* Slot 1/2 machines */ /* 440GX */ + /* Has a National Semiconductors PC87309 Super I/O chip with on-chip KBC + with most likely AMIKey-2 KBC firmware. */ { "[i440GX] Freeway FW-6400GX", "fw6400gx", MACHINE_TYPE_SLOT1_2, CPU_PKG_SLOT1 | CPU_PKG_SLOT2, 0, 100000000, 150000000, 1800, 3500, 3.0, 8.0, (MACHINE_AGP & ~MACHINE_AT) | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 16384,2080768,16384, 511, machine_at_fw6400gx_init, NULL }, /* Slot 2 machines */ /* 440GX */ + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[i440GX] Gigabyte GA-6GXU", "6gxu", MACHINE_TYPE_SLOT2, CPU_PKG_SLOT2, 0, 100000000, 133333333, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 16384,2097152,16384, 511, machine_at_6gxu_init, NULL }, + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[i440GX] SuperMicro Super S2DGE", "s2dge", MACHINE_TYPE_SLOT2, CPU_PKG_SLOT2, 0, 66666667, 100000000, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 16384,2097152,16384, 511, machine_at_s2dge_init, NULL }, /* PGA370 machines */ /* 440LX */ + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[i440LX] SuperMicro Super 370SLM", "s370slm", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 100000000, 1800, 3500, MACHINE_MULTIPLIER_FIXED, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_s370slm_init, NULL }, /* 440BX */ + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[i440BX] AEWIN AW-O671R", "awo671r", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1300, 3500, 1.5, 8.0, /* limits assumed */ MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 524288, 8192, 255, machine_at_awo671r_init, NULL }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[i440BX] ASUS CUBX", "cubx", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1300, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_cubx_init, NULL }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[i440BX] AmazePC AM-BX133", "ambx133", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1300, 3500, 1.5, 8.0, /* limits assumed */ MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_ambx133_init, NULL }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[i440BX] Tyan Trinity 371", "trinity371", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1300, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_trinity371_init, NULL }, /* 440ZX */ + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[i440ZX] Soltek SL-63A1", "63a", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 100000000, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 524288, 8192, 255, machine_at_63a_init, NULL }, /* SMSC VictoryBX-66 */ + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[SMSC VictoryBX-66] A-Trend ATC7020BXII","atc7020bxii", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1300, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_atc7020bxii_init, NULL }, /* VIA Apollo Pro */ + /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ { "[VIA Apollo Pro] PC Partner APAS3", "apas3", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 100000000, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_apas3_init, NULL }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[VIA Apollo Pro133] ECS P6BAP", "p6bap", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1300, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1572864, 8192, 255, machine_at_p6bap_init, NULL }, - { "[VIA Apollo Pro133A] BCM GT694VA", "gt694va", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1300, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 16384,3145728, 8192, 255, machine_at_gt694va_init, NULL }, - { "[VIA Apollo Pro133A] ASUS CUV4X-LS", "cuv4xls", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1300, 3500, 1.5, 8.0, (MACHINE_AGP & ~MACHINE_AT) | MACHINE_BUS_PS2 | MACHINE_BUS_AC97 | MACHINE_IDE_DUAL,16384,4194304, 8192, 255, machine_at_cuv4xls_init, NULL }, + /* Has the VIA VT82C686B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ { "[VIA Apollo Pro133A] Acorp 6VIA90AP", "6via90ap", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1300, 3500, MACHINE_MULTIPLIER_FIXED, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_GAMEPORT, 16384,3145728, 8192, 255, machine_at_6via90ap_init, NULL }, + /* Has the VIA VT82C686B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ + { "[VIA Apollo Pro133A] ASUS CUV4X-LS", "cuv4xls", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1300, 3500, 1.5, 8.0, (MACHINE_AGP & ~MACHINE_AT) | MACHINE_BUS_PS2 | MACHINE_BUS_AC97 | MACHINE_IDE_DUAL,16384,4194304, 8192, 255, machine_at_cuv4xls_init, NULL }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { "[VIA Apollo Pro133A] BCM GT694VA", "gt694va", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1300, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 16384,3145728, 8192, 255, machine_at_gt694va_init, NULL }, /* Miscellaneous/Fake/Hypervisor machines */ + /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ { "[i440BX] Microsoft Virtual PC 2007", "vpc2007", MACHINE_TYPE_MISC, CPU_PKG_SLOT1, CPU_BLOCK(CPU_PENTIUM2, CPU_CYRIX3S), 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_vpc2007_init, NULL }, { NULL, NULL, MACHINE_TYPE_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL } diff --git a/src/mem/mem.c b/src/mem/mem.c index 75ddb8c53..da2e1f31e 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -1802,7 +1802,7 @@ mem_read_ram(uint32_t addr, void *priv) mem_log("Read B %02X from %08X\n", ram[addr], addr); #endif - if (AT) + if (is286 || AT) addreadlookup(mem_logical_addr, addr); return ram[addr]; @@ -1817,7 +1817,7 @@ mem_read_ramw(uint32_t addr, void *priv) mem_log("Read W %04X from %08X\n", *(uint16_t *)&ram[addr], addr); #endif - if (AT) + if (is286 || AT) addreadlookup(mem_logical_addr, addr); return *(uint16_t *)&ram[addr]; @@ -1832,7 +1832,7 @@ mem_read_raml(uint32_t addr, void *priv) mem_log("Read L %08X from %08X\n", *(uint32_t *)&ram[addr], addr); #endif - if (AT) + if (is286 || AT) addreadlookup(mem_logical_addr, addr); return *(uint32_t *)&ram[addr]; @@ -1919,13 +1919,13 @@ page_remove_from_evict_list(page_t *p) void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) { - if ((p != NULL) && (p->mem == page_ff)) + if (p == NULL) return; #ifdef USE_DYNAREC - if (val != p->mem[addr & 0xfff] || codegen_in_recompile) { + if ((p->mem == NULL) || (p->mem == page_ff) || (val != p->mem[addr & 0xfff]) || codegen_in_recompile) { #else - if (val != p->mem[addr & 0xfff]) { + if ((p->mem == NULL) || (p->mem == page_ff) || (val != p->mem[addr & 0xfff])) { #endif uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; @@ -1945,13 +1945,13 @@ mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) { - if ((p != NULL) && (p->mem == page_ff)) + if (p == NULL) return; #ifdef USE_DYNAREC - if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { + if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint16_t *)&p->mem[addr & 0xfff]) || codegen_in_recompile) { #else - if (val != *(uint16_t *)&p->mem[addr & 0xfff]) { + if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint16_t *)&p->mem[addr & 0xfff])) { #endif uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; @@ -1981,13 +1981,13 @@ mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) { - if ((p != NULL) && (p->mem == page_ff)) + if (p == NULL) return; #ifdef USE_DYNAREC - if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { + if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint32_t *)&p->mem[addr & 0xfff]) || codegen_in_recompile) { #else - if (val != *(uint32_t *)&p->mem[addr & 0xfff]) { + if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint32_t *)&p->mem[addr & 0xfff])) { #endif uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; @@ -2013,13 +2013,13 @@ mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) { - if ((p != NULL) && (p->mem == page_ff)) + if (p == NULL) return; #ifdef USE_DYNAREC - if ((p == NULL) || (p->mem == NULL) || (val != p->mem[addr & 0xfff]) || codegen_in_recompile) { + if ((p->mem == NULL) || (p->mem == page_ff) || (val != p->mem[addr & 0xfff]) || codegen_in_recompile) { #else - if ((p == NULL) || (p->mem == NULL) || (val != p->mem[addr & 0xfff])) { + if ((p->mem == NULL) || (p->mem == page_ff) || (val != p->mem[addr & 0xfff])) { #endif uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; @@ -2031,13 +2031,13 @@ mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) { - if ((p != NULL) && (p->mem == page_ff)) + if (p == NULL) return; #ifdef USE_DYNAREC - if ((p == NULL) || (p->mem == NULL) || (val != *(uint16_t *)&p->mem[addr & 0xfff]) || codegen_in_recompile) { + if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint16_t *)&p->mem[addr & 0xfff]) || codegen_in_recompile) { #else - if ((p == NULL) || (p->mem == NULL) || (val != *(uint16_t *)&p->mem[addr & 0xfff])) { + if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint16_t *)&p->mem[addr & 0xfff])) { #endif uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); if ((addr & 0xf) == 0xf) @@ -2051,13 +2051,13 @@ mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) { - if ((p != NULL) && (p->mem == page_ff)) + if (p == NULL) return; #ifdef USE_DYNAREC - if ((p == NULL) || (p->mem == NULL) || (val != *(uint32_t *)&p->mem[addr & 0xfff]) || codegen_in_recompile) { + if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint32_t *)&p->mem[addr & 0xfff]) || codegen_in_recompile) { #else - if ((p == NULL) || (p->mem == NULL) || (val != *(uint32_t *)&p->mem[addr & 0xfff])) { + if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint32_t *)&p->mem[addr & 0xfff])) { #endif uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); if ((addr & 0xf) >= 0xd) @@ -2076,7 +2076,7 @@ mem_write_ram(uint32_t addr, uint8_t val, void *priv) if ((addr >= 0xa0000) && (addr <= 0xbffff)) mem_log("Write B %02X to %08X\n", val, addr); #endif - if (AT) { + if (is286 || AT) { addwritelookup(mem_logical_addr, addr); mem_write_ramb_page(addr, val, &pages[addr >> 12]); } else @@ -2091,7 +2091,7 @@ mem_write_ramw(uint32_t addr, uint16_t val, void *priv) if ((addr >= 0xa0000) && (addr <= 0xbffff)) mem_log("Write W %04X to %08X\n", val, addr); #endif - if (AT) { + if (is286 || AT) { addwritelookup(mem_logical_addr, addr); mem_write_ramw_page(addr, val, &pages[addr >> 12]); } else @@ -2106,7 +2106,7 @@ mem_write_raml(uint32_t addr, uint32_t val, void *priv) if ((addr >= 0xa0000) && (addr <= 0xbffff)) mem_log("Write L %08X to %08X\n", val, addr); #endif - if (AT) { + if (is286 || AT) { addwritelookup(mem_logical_addr, addr); mem_write_raml_page(addr, val, &pages[addr >> 12]); } else @@ -2118,7 +2118,7 @@ static uint8_t mem_read_remapped(uint32_t addr, void *priv) { addr = 0xA0000 + (addr - remap_start_addr); - if (AT) + if (is286 || AT) addreadlookup(mem_logical_addr, addr); return ram[addr]; } @@ -2128,7 +2128,7 @@ static uint16_t mem_read_remappedw(uint32_t addr, void *priv) { addr = 0xA0000 + (addr - remap_start_addr); - if (AT) + if (is286 || AT) addreadlookup(mem_logical_addr, addr); return *(uint16_t *)&ram[addr]; } @@ -2138,7 +2138,7 @@ static uint32_t mem_read_remappedl(uint32_t addr, void *priv) { addr = 0xA0000 + (addr - remap_start_addr); - if (AT) + if (is286 || AT) addreadlookup(mem_logical_addr, addr); return *(uint32_t *)&ram[addr]; } @@ -2149,7 +2149,7 @@ mem_write_remapped(uint32_t addr, uint8_t val, void *priv) { uint32_t oldaddr = addr; addr = 0xA0000 + (addr - remap_start_addr); - if (AT) { + if (is286 || AT) { addwritelookup(mem_logical_addr, addr); mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]); } else @@ -2162,7 +2162,7 @@ mem_write_remappedw(uint32_t addr, uint16_t val, void *priv) { uint32_t oldaddr = addr; addr = 0xA0000 + (addr - remap_start_addr); - if (AT) { + if (is286 || AT) { addwritelookup(mem_logical_addr, addr); mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]); } else @@ -2175,7 +2175,7 @@ mem_write_remappedl(uint32_t addr, uint32_t val, void *priv) { uint32_t oldaddr = addr; addr = 0xA0000 + (addr - remap_start_addr); - if (AT) { + if (is286 || AT) { addwritelookup(mem_logical_addr, addr); mem_write_raml_page(addr, val, &pages[oldaddr >> 12]); } else @@ -2186,42 +2186,27 @@ mem_write_remappedl(uint32_t addr, uint32_t val, void *priv) void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) { - uint64_t mask; #ifdef USE_NEW_DYNAREC int byte_offset; uint64_t byte_mask; - uint32_t i; page_t *p; start_addr &= ~PAGE_MASK_MASK; end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; - for (; start_addr <= end_addr; start_addr += (1 << PAGE_MASK_SHIFT)) { + for (; start_addr <= end_addr; start_addr += 0x1000) { if ((start_addr >> 12) >= pages_sz) continue; - mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - p = &pages[start_addr >> 12]; - p->dirty_mask |= mask; - if ((p->code_present_mask & mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); + if (p) { + p->dirty_mask = 0xffffffffffffffffULL; - for (i = start_addr; (i <= end_addr) && (i < (start_addr + (1 << PAGE_MASK_SHIFT))); i++) { - /* Do not look at the byte stuff if start_addr >= (mem_size * 1024), as we do not allocate the - byte dirty and code present mask arrays beyond the end of RAM. */ - if (i < (mem_size << 10)) { - byte_offset = (i >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - byte_mask = (uint64_t)1 << (i & PAGE_BYTE_MASK_MASK); + if (p->byte_dirty_mask) + memset(p->byte_dirty_mask, 0xff, 64 * sizeof(uint64_t)); - if (p) { - if (p->byte_dirty_mask) - p->byte_dirty_mask[byte_offset] |= byte_mask; - if (p->byte_code_present_mask && (p->byte_code_present_mask[byte_offset] & byte_mask) && - !page_in_evict_list(p)) - page_add_to_evict_list(p); - } - } + if (!page_in_evict_list(p)) + page_add_to_evict_list(p); } } #else @@ -2229,14 +2214,12 @@ mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) start_addr &= ~PAGE_MASK_MASK; end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; - for (; start_addr <= end_addr; start_addr += (1 << PAGE_MASK_SHIFT)) { - mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - + for (; start_addr <= end_addr; start_addr += 0x1000) { /* Do nothing if the pages array is empty or DMA reads/writes to/from PCI device memory addresses may crash the emulator. */ cur_addr = (start_addr >> 12); if (cur_addr < pages_sz) - pages[cur_addr].dirty_mask[(start_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; + memset(pages[cur_addr].dirty_mask, 0xff, sizeof(pages[cur_addr].dirty_mask)); } #endif } @@ -2264,6 +2247,12 @@ mem_mapping_access_allowed(uint32_t flags, uint16_t access) ret = ret && !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_SMRAM); } else ret = !(flags & MEM_MAPPING_EXTERNAL) && !(flags & MEM_MAPPING_SMRAM); + } else { + /* Still allow SMRAM if access is DISABLED but also has CACHE and/or SMRAM flags set. */ + if (access & ACCESS_CACHE) + ret = (flags & MEM_MAPPING_CACHE); + else if (access & ACCESS_SMRAM) + ret = (flags & MEM_MAPPING_SMRAM); } return ret; @@ -2501,6 +2490,7 @@ mem_set_access(uint8_t bitmap, int mode, uint32_t base, uint32_t size, uint16_t uint16_t mask, smstate = 0x0000; const uint16_t smstates[4] = { 0x0000, (MEM_READ_SMRAM | MEM_WRITE_SMRAM), MEM_READ_SMRAM_EX, (MEM_READ_DISABLED_EX | MEM_WRITE_DISABLED_EX) }; + int i; if (mode) @@ -2512,7 +2502,15 @@ mem_set_access(uint8_t bitmap, int mode, uint32_t base, uint32_t size, uint16_t if (mode == 1) access = !!access; - smstate = smstates[access & 0x03]; + if (mode == 3) { + if (access & ACCESS_SMRAM_X) + smstate |= MEM_EXEC_SMRAM; + if (access & ACCESS_SMRAM_R) + smstate |= MEM_READ_SMRAM_2; + if (access & ACCESS_SMRAM_W) + smstate |= MEM_WRITE_SMRAM; + } else + smstate = smstates[access & 0x07]; } else smstate = access & 0x6f7b; @@ -2544,7 +2542,7 @@ mem_a20_init(void) flushmmucache(); mem_a20_state = mem_a20_key | mem_a20_alt; } else { - rammask = 0xfffff; + rammask = is286 ? 0xffffff : 0xfffff; flushmmucache(); mem_a20_key = mem_a20_alt = mem_a20_state = 0; } @@ -2669,15 +2667,20 @@ mem_reset(void) */ if (AT) { if (cpu_16bitbus) { - /* 80186/286; maximum address space is 16MB. */ + /* 80286/386SX; maximum address space is 16MB. */ m = 4096; } else { - /* 80386+; maximum address space is 4GB. */ + /* 80386DX+; maximum address space is 4GB. */ m = 1048576; } } else { - /* 8088/86; maximum address space is 1MB. */ - m = 256; + if (is286) { + /* 80286; maximum address space is 16MB. */ + m = 4096; + } else { + /* 8088/86; maximum address space is 1MB. */ + m = 256; + } } /* @@ -2703,6 +2706,7 @@ mem_reset(void) if ((c << 12) >= (mem_size << 10)) pages[c].mem = page_ff; else { +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) if (mem_size > 1048576) { if ((c << 12) < (1 << 30)) pages[c].mem = &ram[c << 12]; @@ -2710,6 +2714,9 @@ mem_reset(void) pages[c].mem = &ram2[(c << 12) - (1 << 30)]; } else pages[c].mem = &ram[c << 12]; +#else + pages[c].mem = &ram[c << 12]; +#endif } if (c < m) { pages[c].write_b = mem_write_ramb_page; @@ -2871,7 +2878,7 @@ mem_a20_recalc(void) int state; if (! AT) { - rammask = 0xfffff; + rammask = is286 ? 0xffffff : 0xfffff; flushmmucache(); mem_a20_key = mem_a20_alt = mem_a20_state = 0; diff --git a/src/mem/rom.c b/src/mem/rom.c index d9f152af8..3d7f28934 100644 --- a/src/mem/rom.c +++ b/src/mem/rom.c @@ -417,10 +417,12 @@ static void bios_add(void) { int temp_cpu_type, temp_cpu_16bitbus = 1; + int temp_is286 = 0; - if (AT && cpu_s) { + if (/*AT && */cpu_s) { temp_cpu_type = cpu_s->cpu_type; temp_cpu_16bitbus = (temp_cpu_type == CPU_286 || temp_cpu_type == CPU_386SX || temp_cpu_type == CPU_486SLC || temp_cpu_type == CPU_IBM386SLC || temp_cpu_type == CPU_IBM486SLC ); + temp_is286 = (temp_cpu_type == CPU_286); } if (biosmask > 0x1ffff) { @@ -442,7 +444,7 @@ bios_add(void) MEM_READ_ROMCS | MEM_WRITE_ROMCS); } - if (AT) { + if (temp_is286 || AT) { mem_mapping_add(&bios_high_mapping, biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, bios_read,bios_readw,bios_readl, NULL,NULL,NULL, diff --git a/src/mem/smram.c b/src/mem/smram.c index 1173d716a..8b1f9fd40 100644 --- a/src/mem/smram.c +++ b/src/mem/smram.c @@ -32,6 +32,9 @@ static smram_t *base_smram, *last_smram; +static uint8_t use_separate_smram = 0; +static uint8_t smram[0x40000]; + #ifdef ENABLE_SMRAM_LOG int smram_do_log = ENABLE_SMRAM_LOG; @@ -61,8 +64,10 @@ smram_read(uint32_t addr, void *priv) if (new_addr >= (1 << 30)) return mem_read_ram_2gb(new_addr, priv); - else + else if (!use_separate_smram || (new_addr >= 0xa0000)) return mem_read_ram(new_addr, priv); + else + return dev->mapping.exec[addr - dev->host_base]; } @@ -74,8 +79,10 @@ smram_readw(uint32_t addr, void *priv) if (new_addr >= (1 << 30)) return mem_read_ram_2gbw(new_addr, priv); - else + else if (!use_separate_smram || (new_addr >= 0xa0000)) return mem_read_ramw(new_addr, priv); + else + return *(uint16_t *) &(dev->mapping.exec[addr - dev->host_base]); } @@ -87,8 +94,10 @@ smram_readl(uint32_t addr, void *priv) if (new_addr >= (1 << 30)) return mem_read_ram_2gbl(new_addr, priv); - else + else if (!use_separate_smram || (new_addr >= 0xa0000)) return mem_read_raml(new_addr, priv); + else + return *(uint32_t *) &(dev->mapping.exec[addr - dev->host_base]); } @@ -98,7 +107,10 @@ smram_write(uint32_t addr, uint8_t val, void *priv) smram_t *dev = (smram_t *) priv; uint32_t new_addr = addr - dev->host_base + dev->ram_base; - mem_write_ram(new_addr, val, priv); + if (!use_separate_smram || (new_addr >= 0xa0000)) + mem_write_ram(new_addr, val, priv); + else + dev->mapping.exec[addr - dev->host_base] = val; } @@ -108,7 +120,10 @@ smram_writew(uint32_t addr, uint16_t val, void *priv) smram_t *dev = (smram_t *) priv; uint32_t new_addr = addr - dev->host_base + dev->ram_base; - mem_write_ramw(new_addr, val, priv); + if (!use_separate_smram || (new_addr >= 0xa0000)) + mem_write_ramw(new_addr, val, priv); + else + *(uint16_t *) &(dev->mapping.exec[addr - dev->host_base]) = val; } @@ -118,7 +133,10 @@ smram_writel(uint32_t addr, uint32_t val, void *priv) smram_t *dev = (smram_t *) priv; uint32_t new_addr = addr - dev->host_base + dev->ram_base; - mem_write_raml(new_addr, val, priv); + if (!use_separate_smram || (new_addr >= 0xa0000)) + mem_write_raml(new_addr, val, priv); + else + *(uint32_t *) &(dev->mapping.exec[addr - dev->host_base]) = val; } @@ -263,15 +281,30 @@ smram_add(void) smram_write,smram_writew,smram_writel, ram, MEM_MAPPING_SMRAM, temp_smram); + smram_set_separate_smram(0); + return temp_smram; } +/* Set memory state in the specified model (normal or SMM) according to the specified flags, + separately for bus and CPU. */ +void +smram_map_ex(int bus, int smm, uint32_t addr, uint32_t size, int is_smram) +{ + if (bus) + mem_set_access_smram_bus(smm, addr, size, is_smram); + else + mem_set_access_smram_cpu(smm, addr, size, is_smram); +} + + /* Set memory state in the specified model (normal or SMM) according to the specified flags. */ void smram_map(int smm, uint32_t addr, uint32_t size, int is_smram) { - mem_set_mem_state_smram(smm, addr, size, is_smram); + smram_map_ex(0, smm, addr, size, is_smram); + smram_map_ex(1, smm, addr, size, is_smram); } @@ -311,9 +344,11 @@ smram_disable_all(void) } -/* Enable SMRAM mappings according to flags for both normal and SMM modes. */ +/* Enable SMRAM mappings according to flags for both normal and SMM modes, separately for bus + and CPU. */ void -smram_enable(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size, int flags_normal, int flags_smm) +smram_enable_ex(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size, + int flags_normal, int flags_normal_bus, int flags_smm, int flags_smm_bus) { if (smr == NULL) { fatal("smram_add(): Invalid SMRAM mapping\n"); @@ -326,18 +361,39 @@ smram_enable(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size, smr->size = size; mem_mapping_set_addr(&(smr->mapping), smr->host_base, smr->size); - if (smr->ram_base < (1 << 30)) - mem_mapping_set_exec(&(smr->mapping), ram + smr->ram_base); - else - mem_mapping_set_exec(&(smr->mapping), ram2 + smr->ram_base - (1 << 30)); + if (!use_separate_smram || (smr->ram_base >= 0x000a0000)) { + if (smr->ram_base < (1 << 30)) + mem_mapping_set_exec(&(smr->mapping), ram + smr->ram_base); + else + mem_mapping_set_exec(&(smr->mapping), ram2 + smr->ram_base - (1 << 30)); + } else { + if (smr->ram_base == 0x00030000) + mem_mapping_set_exec(&(smr->mapping), smram); + else if (smr->ram_base == 0x00040000) + mem_mapping_set_exec(&(smr->mapping), smram + 0x10000); + else if (smr->ram_base == 0x00060000) + mem_mapping_set_exec(&(smr->mapping), smram + 0x20000); + else if (smr->ram_base == 0x00070000) + mem_mapping_set_exec(&(smr->mapping), smram + 0x30000); + } - smram_map(0, host_base, size, flags_normal); - smram_map(1, host_base, size, flags_smm); + smram_map_ex(0, 0, host_base, size, flags_normal); + smram_map_ex(1, 0, host_base, size, flags_normal_bus); + smram_map_ex(0, 1, host_base, size, flags_smm); + smram_map_ex(1, 1, host_base, size, flags_smm_bus); } else smram_disable(smr); } +/* Enable SMRAM mappings according to flags for both normal and SMM modes. */ +void +smram_enable(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size, int flags_normal, int flags_smm) +{ + smram_enable_ex(smr, host_base, ram_base, size, flags_normal, flags_normal, flags_smm, flags_smm); +} + + /* Checks if a SMRAM mapping is enabled or not. */ int smram_enabled(smram_t *smr) @@ -364,3 +420,10 @@ smram_state_change(smram_t *smr, int smm, int flags) smram_map(smm, smr->host_base, smr->size, flags); } + + +void +smram_set_separate_smram(uint8_t set) +{ + use_separate_smram = set; +} diff --git a/src/mem/spd.c b/src/mem/spd.c index b5400de4b..9e5ec9706 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -400,6 +400,133 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit } +/* Used by ALi M1531 and M1541/2. */ +void +spd_write_drbs_interleaved(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit) +{ + uint8_t row, dimm; + uint8_t drb; + uint16_t size, size_acc; + uint16_t rows[SPD_MAX_SLOTS]; + + /* No SPD: split SIMMs into pairs as if they were "DIMM"s. */ + if (!spd_present) { + dimm = ((reg_max - reg_min) + 1) >> 2; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */ + spd_populate(rows, dimm, mem_size >> 10, drb_unit, 1 << (log2i((machines[machine].max_ram >> 10) / dimm)), 0); + } + + /* Write DRBs for each row. */ + spd_log("SPD: Writing DRBs... regs=[%02X:%02X] unit=%d\n", reg_min, reg_max, drb_unit); + for (row = 0; row <= (reg_max - reg_min); row += 2) { + dimm = (row >> 2); + size = 0; + + if (spd_present) { + /* SPD enabled: use SPD info for this slot, if present. */ + if (spd_modules[dimm]) { + if (spd_modules[dimm]->row1 < drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */ + size = ((row >> 1) & 1) ? 0 : drb_unit; + else + size = ((row >> 1) & 1) ? spd_modules[dimm]->row2 : spd_modules[dimm]->row1; + } + } else { + /* No SPD: use the values calculated above. */ + size = (rows[dimm] >> 1); + } + + /* Determine the DRB register to write. */ + drb = reg_min + row; + + /* Calculate previous and new size. */ + if (row == 0) + size_acc = 0; + else + size_acc += (size / drb_unit); + + /* Write DRB register, adding the previous DRB's value. */ + regs[drb] = size_acc & 0xff; + regs[drb + 1] = (regs[drb + 1] & 0xf0) | ((size_acc >> 8) & 0x0f); + + spd_log("SPD: DRB[%d] = %d MB (%02Xh raw)\n", row >> 1, size, regs[drb]); + } +} + + +/* This is needed because the ALi M1621 does this stuff completely differently, + as it has DRAM bank registers instead of DRAM row boundary registers. */ +void +spd_write_drbs_ali1621(uint8_t *regs, uint8_t reg_min, uint8_t reg_max) +{ + uint8_t dimm, drb; + uint16_t size; + uint16_t rows[SPD_MAX_SLOTS]; + + /* No SPD: split SIMMs into pairs as if they were "DIMM"s. */ + if (!spd_present) { + dimm = ((reg_max - reg_min) + 1) >> 2; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */ + spd_populate(rows, dimm, mem_size >> 10, 4, 1 << (log2i((machines[machine].max_ram >> 10) / dimm)), 0); + } + + /* Write DRBs for each row. */ + spd_log("SPD: Writing DRBs... regs=[%02X:%02X] unit=%d\n", reg_min, reg_max, drb_unit); + for (dimm = 0; dimm <= ((reg_max - reg_min) >> 2); dimm++) { + size = 0; + drb = reg_min + (dimm << 2); + + regs[drb] = 0xff; + regs[drb + 1] = 0xff; + regs[drb + 2] = 0x00; + regs[drb + 3] = 0xf0; + + if (spd_modules[dimm] == NULL) + continue; + + if (spd_present) { + /* SPD enabled: use SPD info for this slot, if present. */ + size = (spd_modules[dimm]->row1 + spd_modules[dimm]->row2) >> 1; + } else { + /* No SPD: use the values calculated above. */ + size = (rows[dimm] >> 1); + } + + if (spd_modules[dimm]->row1) + regs[drb + 3] |= 0x06; + + switch (size) { + case 4: + default: + regs[drb + 2] = 0x00; + break; + case 8: + regs[drb + 2] = 0x10; + break; + case 16: + regs[drb + 2] = 0x20; + break; + case 32: + regs[drb + 2] = 0x30; + break; + case 64: + regs[drb + 2] = 0x40; + break; + case 128: + regs[drb + 2] = 0x50; + break; + case 256: + regs[drb + 2] = 0x60; + break; + } + + if (spd_modules[dimm]->row2) { + regs[drb + 3] |= 0x01; + regs[drb + 2] |= 0x80; + } + + spd_log("SPD: DIMM %i: %02X %02X %02X %02X\n", regs[drb], regs[drb + 1], regs[drb + 2], regs[drb + 3]); + } +} + + static const device_t spd_device = { "Serial Presence Detect ROMs", DEVICE_ISA, diff --git a/src/mem/sst_flash.c b/src/mem/sst_flash.c index 8d0645f07..23110cb75 100644 --- a/src/mem/sst_flash.c +++ b/src/mem/sst_flash.c @@ -462,8 +462,10 @@ sst_close(void *p) if (dev->dirty) { f = nvr_fopen(flash_path, "wb"); - fwrite(&(dev->array[0x00000]), dev->size, 1, f); - fclose(f); + if (f != NULL) { + fwrite(&(dev->array[0x00000]), dev->size, 1, f); + fclose(f); + } } free(dev->array); diff --git a/src/nvr_at.c b/src/nvr_at.c index 171a131cc..03f3ea6bb 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -292,7 +292,8 @@ #define FLAG_LS_HACK 0x01 #define FLAG_APOLLO_HACK 0x02 -#define FLAG_PIIX4 0x04 +#define FLAG_P6RP4_HACK 0x04 +#define FLAG_PIIX4 0x08 typedef struct { @@ -559,6 +560,26 @@ timer_tick(nvr_t *nvr) } +static void +nvr_reg_common_write(uint16_t reg, uint8_t val, nvr_t *nvr, local_t *local) +{ + if ((reg == 0x2c) && (local->flags & FLAG_LS_HACK)) + nvr->new = 0; + if ((reg == 0x52) && (local->flags & FLAG_APOLLO_HACK)) + nvr->new = 0; + if ((reg >= 0x38) && (reg <= 0x3f) && local->wp[0]) + return; + if ((reg >= 0xb8) && (reg <= 0xbf) && local->wp[1]) + return; + if (local->lock[reg]) + return; + if (nvr->regs[reg] != val) { + nvr->regs[reg] = val; + nvr_dosave = 1; + } +} + + /* This must be exposed because ACPI uses it. */ void nvr_reg_write(uint16_t reg, uint8_t val, void *priv) @@ -604,28 +625,17 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv) nvr->regs[0x2f] = checksum & 0xff; break; } - /*FALLTHROUGH*/ + nvr_reg_common_write(reg, val, nvr, local); + break; case 0x32: if ((reg == 0x32) && (local->cent == RTC_CENTURY_VIA) && local->wp_32) break; - /* FALLTHROUGH */ + nvr_reg_common_write(reg, val, nvr, local); + break; default: /* non-RTC registers are just NVRAM */ - if ((reg == 0x2c) && (local->flags & FLAG_LS_HACK)) - nvr->new = 0; - if ((reg == 0x52) && (local->flags & FLAG_APOLLO_HACK)) - nvr->new = 0; - if ((reg >= 0x38) && (reg <= 0x3f) && local->wp[0]) - break; - if ((reg >= 0xb8) && (reg <= 0xbf) && local->wp[1]) - break; - if (local->lock[reg]) - break; - if (nvr->regs[reg] != val) { - nvr->regs[reg] = val; - nvr_dosave = 1; - } + nvr_reg_common_write(reg, val, nvr, local); break; } @@ -746,10 +756,31 @@ nvr_read(uint16_t addr, void *priv) ret = checksum >> 8; else ret = checksum & 0xff; + } else if (!nvr->new && (local->flags & FLAG_P6RP4_HACK)) { + /* The checksum at 3E-3F is for 37-3D and 40-51. */ + for (i = 0x37; i <= 0x3d; i++) + checksum += nvr->regs[i]; + for (i = 0x40; i <= 0x51; i++) { + if (i == 0x43) + checksum += (nvr->regs[i] | 0x02); + else + checksum += nvr->regs[i]; + } + if (local->addr[addr_id] == 0x3e) + ret = checksum >> 8; + else + ret = checksum & 0xff; } else ret = nvr->regs[local->addr[addr_id]]; break; + case 0x43: + if (!nvr->new && (local->flags & FLAG_P6RP4_HACK)) + ret = nvr->regs[local->addr[addr_id]] | 0x02; + else + ret = nvr->regs[local->addr[addr_id]]; + break; + case 0x52: if (!nvr->new && (local->flags & FLAG_APOLLO_HACK)) ret = nvr->regs[local->addr[addr_id]] & 0xf3; @@ -963,8 +994,14 @@ nvr_at_init(const device_t *info) local->flags = 0x00; switch(info->local & 7) { case 0: /* standard AT, no century register */ - nvr->irq = 8; - local->cent = 0xff; + if (info->local == 16) { + local->flags |= FLAG_P6RP4_HACK; + nvr->irq = 8; + local->cent = RTC_CENTURY_AT; + } else { + nvr->irq = 8; + local->cent = 0xff; + } break; case 1: /* standard AT */ @@ -1153,3 +1190,12 @@ const device_t via_nvr_device = { { NULL }, nvr_at_speed_changed, NULL }; + +const device_t p6rp4_nvr_device = { + "ASUS P/I-P6RP4 PC/AT NVRAM", + DEVICE_ISA | DEVICE_AT, + 16, + nvr_at_init, nvr_at_close, nvr_at_reset, + { NULL }, nvr_at_speed_changed, + NULL +}; diff --git a/src/pci.c b/src/pci.c index 746cad811..fc6e1e75e 100644 --- a/src/pci.c +++ b/src/pci.c @@ -59,7 +59,7 @@ static uint8_t pci_pmc = 0, last_pci_card = 0, last_normal_pci_card = 0, last_p static uint8_t pci_card_to_slot_mapping[256][32], pci_bus_number_to_index_mapping[256]; static uint8_t pci_irqs[16], pci_irq_level[16]; static uint64_t pci_irq_hold[16]; -static pci_mirq_t pci_mirqs[4]; +static pci_mirq_t pci_mirqs[8]; static int pci_type, pci_switch, pci_index, @@ -74,6 +74,7 @@ static int trc_reg = 0; static void pci_reset_regs(void); +// #define ENABLE_PCI_LOG 1 #ifdef ENABLE_PCI_LOG int pci_do_log = ENABLE_PCI_LOG; @@ -149,6 +150,80 @@ pci_write(uint16_t port, uint8_t val, void *priv) } +static void +pci_writew(uint16_t port, uint16_t val, void *priv) +{ + uint8_t slot = 0; + + if (in_smm) + pci_log("(%i) %03x write: %02X\n", pci_enable, port, val); + + switch (port) { + case 0xcfc: case 0xcfe: + if (! pci_enable) + return; + + pci_log("Writing %04X to PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", val, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); + slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; + if (slot != 0xff) { + if (pci_cards[slot].write) { + pci_log("Writing to PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); + pci_cards[slot].write(pci_func, pci_index | (port & 3), val & 0xff, pci_cards[slot].priv); + pci_cards[slot].write(pci_func, pci_index | (port & 3) | 1, val >> 8, pci_cards[slot].priv); + } +#ifdef ENABLE_PCI_LOG + else + pci_log("Writing to empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); +#endif + } +#ifdef ENABLE_PCI_LOG + else + pci_log("Writing to unassigned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); +#endif + + break; + } +} + + +static void +pci_writel(uint16_t port, uint32_t val, void *priv) +{ + uint8_t slot = 0; + + if (in_smm) + pci_log("(%i) %03x write: %02X\n", pci_enable, port, val); + + switch (port) { + case 0xcfc: + if (! pci_enable) + return; + + pci_log("Writing %08X to PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", val, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); + slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; + if (slot != 0xff) { + if (pci_cards[slot].write) { + pci_log("Writing to PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); + pci_cards[slot].write(pci_func, pci_index | (port & 3), val & 0xff, pci_cards[slot].priv); + pci_cards[slot].write(pci_func, pci_index | (port & 3) | 1, (val >> 8) & 0xff, pci_cards[slot].priv); + pci_cards[slot].write(pci_func, pci_index | (port & 3) | 2, (val >> 16) & 0xff, pci_cards[slot].priv); + pci_cards[slot].write(pci_func, pci_index | (port & 3) | 3, (val >> 24) & 0xff, pci_cards[slot].priv); + } +#ifdef ENABLE_PCI_LOG + else + pci_log("Writing to empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); +#endif + } +#ifdef ENABLE_PCI_LOG + else + pci_log("Writing to unassigned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); +#endif + + break; + } +} + + static uint8_t pci_read(uint16_t port, void *priv) { @@ -184,6 +259,82 @@ pci_read(uint16_t port, void *priv) } +static uint16_t +pci_readw(uint16_t port, void *priv) +{ + uint8_t slot = 0; + uint16_t ret = 0xffff; + + if (in_smm) + pci_log("(%i) %03x read\n", pci_enable, port); + + switch (port) { + case 0xcfc: case 0xcfe: + if (! pci_enable) + return 0xff; + + slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; + if (slot != 0xff) { + if (pci_cards[slot].read) { + ret = pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); + ret |= (pci_cards[slot].read(pci_func, pci_index | (port & 3) | 1, pci_cards[slot].priv) << 8); + } +#ifdef ENABLE_PCI_LOG + else + pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); +#endif + } +#ifdef ENABLE_PCI_LOG + else + pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); +#endif + } + + pci_log("Reading %04X, from PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", ret, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); + + return ret; +} + + +static uint32_t +pci_readl(uint16_t port, void *priv) +{ + uint8_t slot = 0; + uint32_t ret = 0xffffffff; + + if (in_smm) + pci_log("(%i) %03x read\n", pci_enable, port); + + switch (port) { + case 0xcfc: case 0xcfe: + if (! pci_enable) + return 0xff; + + slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; + if (slot != 0xff) { + if (pci_cards[slot].read) { + ret = pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); + ret |= (pci_cards[slot].read(pci_func, pci_index | (port & 3) | 1, pci_cards[slot].priv) << 8); + ret |= (pci_cards[slot].read(pci_func, pci_index | (port & 3) | 2, pci_cards[slot].priv) << 16); + ret |= (pci_cards[slot].read(pci_func, pci_index | (port & 3) | 3, pci_cards[slot].priv) << 24); + } +#ifdef ENABLE_PCI_LOG + else + pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); +#endif + } +#ifdef ENABLE_PCI_LOG + else + pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); +#endif + } + + pci_log("Reading %08X, from PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", ret, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); + + return ret; +} + + static void pci_type2_write(uint16_t port, uint8_t val, void *priv); static uint8_t pci_type2_read(uint16_t port, void *priv); @@ -802,7 +953,7 @@ pci_init(int type) io_sethandler(0x0cf8, 1, NULL,NULL,pci_cf8_read, NULL,NULL,pci_cf8_write, NULL); io_sethandler(0x0cfc, 4, - pci_read,NULL,NULL, pci_write,NULL,NULL, NULL); + pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL); pci_pmc = 1; } else { io_sethandler(0x0cf8, 1, @@ -887,10 +1038,17 @@ pci_find_slot(uint8_t add_type, uint8_t ignore_slot) dev = &pci_cards[i]; if (!dev->read && !dev->write && ((ignore_slot == 0xff) || (i != ignore_slot))) { - if (((dev->type == PCI_CARD_NORMAL) && (add_type >= PCI_ADD_NORMAL)) || - (dev->type == add_type)) { - ret = i; - break; + if (add_type & PCI_ADD_STRICT) { + if (dev->type == (add_type & 0x7f)) { + ret = i; + break; + } + } else { + if (((dev->type == PCI_CARD_NORMAL) && ((add_type & 0x7f) >= PCI_ADD_NORMAL)) || + (dev->type == (add_type & 0x7f))) { + ret = i; + break; + } } } } diff --git a/src/pic.c b/src/pic.c index ad165ee5c..c77f08023 100644 --- a/src/pic.c +++ b/src/pic.c @@ -54,6 +54,8 @@ static pc_timer_t pic_timer; static int shadow = 0, elcr_enabled = 0, tmr_inited = 0, latched = 0; +static uint16_t smi_irq_mask = 0x0000, + smi_irq_status = 0x0000; static void (*update_pending)(void); @@ -79,6 +81,39 @@ pic_log(const char *fmt, ...) #endif +void +pic_reset_smi_irq_mask(void) +{ + smi_irq_mask = 0x0000; +} + + +void +pic_set_smi_irq_mask(int irq, int set) +{ + if ((irq >= 0) && (irq <= 15)) { + if (set) + smi_irq_mask |= (1 << irq); + else + smi_irq_mask &= ~(1 << irq); + } +} + +uint16_t +pic_get_smi_irq_status(void) +{ + return smi_irq_status; +} + + +void +pic_clear_smi_irq_status(int irq) +{ + if ((irq >= 0) && (irq <= 15)) + smi_irq_status &= ~(1 << irq); +} + + void pic_elcr_write(uint16_t port, uint8_t val, void *priv) { @@ -255,6 +290,8 @@ pic_reset() update_pending = is_at ? pic_update_pending_at : pic_update_pending_xt; pic.at = pic2.at = is_at; + + smi_irq_mask = smi_irq_status = 0x0000; } @@ -478,6 +515,23 @@ pic_write(uint16_t addr, uint8_t val, void *priv) } +void +pic_set_pci(void) +{ + int i; + + for (i = 0x0024; i < 0x0040; i += 4) { + io_sethandler(i, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic); + io_sethandler(i + 0x0080, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic2); + } + + for (i = 0x1120; i < 0x1140; i += 4) { + io_sethandler(i, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic); + io_sethandler(i + 0x0080, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic2); + } +} + + void pic_init(void) { @@ -541,6 +595,11 @@ picint_common(uint16_t num, int level, int set) acpi_rtc_status = !!set; if (set) { + if (smi_irq_mask & num) { + smi_line = 1; + smi_irq_status |= num; + } + if (num & 0xff00) { if (level) pic2.lines |= (num >> 8); @@ -555,6 +614,8 @@ picint_common(uint16_t num, int level, int set) pic.irr |= num; } } else { + smi_irq_status &= ~num; + if (num & 0xff00) { pic2.lines &= ~(num >> 8); pic2.irr &= ~(num >> 8); diff --git a/src/port_6x.c b/src/port_6x.c new file mode 100644 index 000000000..98cd4350d --- /dev/null +++ b/src/port_6x.c @@ -0,0 +1,214 @@ +/* + * 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 Ports 61, 62, and 63 used by various + * machines. + * + * Authors: Miran Grca, + * + * Copyright 2021 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/device.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/keyboard.h> +#include <86box/mem.h> +#include <86box/m_xt_xi8088.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/sound.h> +#include <86box/snd_speaker.h> +#include <86box/pit.h> +#include <86box/ppi.h> +#include <86box/video.h> +#include <86box/port_6x.h> + + +#define PS2_REFRESH_TIME (16 * TIMER_USEC) + +#define PORT_6X_TURBO 1 +#define PORT_6X_EXT_REF 2 +#define PORT_6X_MIRROR 4 +#define PORT_6X_SWA 8 + + +static void +port_6x_write(uint16_t port, uint8_t val, void *priv) +{ + port_6x_t *dev = (port_6x_t *) priv; + + port &= 3; + + if ((port == 3) && (dev->flags & PORT_6X_MIRROR)) + port = 1; + + switch (port) { + case 1: + ppi.pb = (ppi.pb & 0x10) | (val & 0x0f); + + speaker_update(); + speaker_gated = val & 1; + speaker_enable = val & 2; + if (speaker_enable) + was_speaker_enable = 1; + pit_ctr_set_gate(&pit->counters[2], val & 1); + + if (dev->flags & PORT_6X_TURBO) + xi8088_turbo_set(!!(val & 0x04)); + break; + } +} + + +static uint8_t +port_6x_read(uint16_t port, void *priv) +{ + port_6x_t *dev = (port_6x_t *) priv; + uint8_t ret = 0xff; + + port &= 3; + + if ((port == 3) && (dev->flags & PORT_6X_MIRROR)) + port = 1; + + switch (port) { + case 1: + if (dev->flags & PORT_6X_EXT_REF) { + ret = ppi.pb & 0x0f; + + if (dev->refresh) + ret |= 0x10; + } else + ret = ppi.pb & 0x1f; + + if (ppispeakon) + ret |= 0x20; + + if (dev->flags & PORT_6X_TURBO) + ret = (ret & 0xfb) | (xi8088_turbo_get() ? 0x04 : 0x00); + break; + case 2: + if (dev->flags & PORT_6X_SWA) { + /* SWA on Olivetti M240 mainboard (off=1) */ + ret = 0x00; + if (ppi.pb & 0x8) { + /* Switches 4, 5 - floppy drives (number) */ + int i, fdd_count = 0; + for (i = 0; i < FDD_NUM; i++) { + if (fdd_get_flags(i)) + fdd_count++; + } + if (!fdd_count) + ret |= 0x00; + else + ret |= ((fdd_count - 1) << 2); + /* Switches 6, 7 - monitor type */ + if (video_is_mda()) + ret |= 0x3; + else if (video_is_cga()) + ret |= 0x2; /* 0x10 would be 40x25 */ + else + ret |= 0x0; + } else { + /* bit 2 always on */ + ret |= 0x4; + /* Switch 8 - 8087 FPU. */ + if (hasfpu) + ret |= 0x02; + } + } + break; + } + + return(ret); +} + + +static void +port_6x_refresh(void *priv) +{ + port_6x_t *dev = (port_6x_t *) priv; + + dev->refresh = !dev->refresh; + timer_advance_u64(&dev->refresh_timer, PS2_REFRESH_TIME); +} + + +static void +port_6x_close(void *priv) +{ + port_6x_t *dev = (port_6x_t *) priv; + + timer_disable(&dev->refresh_timer); + + free(dev); +} + + +void * +port_6x_init(const device_t *info) +{ + port_6x_t *dev = (port_6x_t *) malloc(sizeof(port_6x_t)); + memset(dev, 0, sizeof(port_6x_t)); + + dev->flags = info->local & 0xff; + + io_sethandler(0x0061, 3, port_6x_read, NULL, NULL, port_6x_write, NULL, NULL, dev); + + if (dev->flags & PORT_6X_EXT_REF) + timer_add(&dev->refresh_timer, port_6x_refresh, dev, 1); + + return dev; +} + + +const device_t port_6x_device = { + "Port 6x Registers", + 0, + 0, + port_6x_init, port_6x_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t port_6x_xi8088_device = { + "Port 6x Registers (Xi8088)", + 0, + PORT_6X_TURBO | PORT_6X_EXT_REF | PORT_6X_MIRROR, + port_6x_init, port_6x_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t port_6x_ps2_device = { + "Port 6x Registers (IBM PS/2)", + 0, + PORT_6X_EXT_REF, + port_6x_init, port_6x_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +const device_t port_6x_olivetti_device = { + "Port 6x Registers (Olivetti)", + 0, + PORT_6X_SWA, + port_6x_init, port_6x_close, NULL, + { NULL }, NULL, NULL, + NULL +}; diff --git a/src/port_92.c b/src/port_92.c index d46d2327b..5e19bee34 100644 --- a/src/port_92.c +++ b/src/port_92.c @@ -64,7 +64,13 @@ port_92_readb(uint16_t port, void *priv) static uint16_t port_92_readw(uint16_t port, void *priv) { - return port_92_readb(port, priv); + uint16_t ret = 0xffff; + port_92_t *dev = (port_92_t *) priv; + + if (!(dev->flags & PORT_92_PCI)) + ret = port_92_readb(port, priv); + + return ret; } @@ -106,7 +112,10 @@ port_92_writeb(uint16_t port, uint8_t val, void *priv) static void port_92_writew(uint16_t port, uint16_t val, void *priv) { - port_92_writeb(port, val & 0xff, priv); + port_92_t *dev = (port_92_t *) priv; + + if (!(dev->flags & PORT_92_PCI)) + port_92_writeb(port, val & 0xff, priv); } @@ -146,7 +155,7 @@ port_92_add(void *priv) { port_92_t *dev = (port_92_t *) priv; - if (dev->flags & PORT_92_WORD) + if (dev->flags & (PORT_92_WORD | PORT_92_PCI)) io_sethandler(0x0092, 2, port_92_readb, port_92_readw, NULL, port_92_writeb, port_92_writew, NULL, dev); else @@ -160,7 +169,7 @@ port_92_remove(void *priv) { port_92_t *dev = (port_92_t *) priv; - if (dev->flags & PORT_92_WORD) + if (dev->flags & (PORT_92_WORD | PORT_92_PCI)) io_removehandler(0x0092, 2, port_92_readb, port_92_readw, NULL, port_92_writeb, port_92_writew, NULL, dev); else diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index ce9b9852c..a69413596 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -160,6 +160,7 @@ static uint64_t scsi_cdrom_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_DISCONNECT_PAGE | GPMODEP_CDROM_PAGE | GPMODEP_CDROM_AUDIO_PAGE | + (1ULL << 0x0fULL) | GPMODEP_CAPABILITIES_PAGE | GPMODEP_ALL_PAGES); @@ -180,7 +181,7 @@ static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default = { 0, 0 }, { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 255, 2, 255, 0, 0, 0, 0 }, - { 0, 0 }, + { 0x0F, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, @@ -227,7 +228,7 @@ static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default_scsi = { 0, 0 }, { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, { 0x8E, 0xE, 5, 4, 0,128, 0, 75, 1, 255, 2, 255, 0, 0, 0, 0 }, - { 0, 0 }, + { 0x0F, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, @@ -261,7 +262,7 @@ static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_changeable = { { { 0, 0 }, { GPMODE_R_W_ERROR_PAGE, 6, 0xFF, 0xFF, 0, 0, 0, 0 }, - { GPMODE_DISCONNECT_PAGE, 0x0e, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 }, + { GPMODE_DISCONNECT_PAGE, 0x0E, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, @@ -274,7 +275,7 @@ static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_changeable = { 0, 0 }, { GPMODE_CDROM_PAGE, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, { 0x8E, 0xE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0, 0 }, + { 0x0F, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, diff --git a/src/sio/CMakeLists.txt b/src/sio/CMakeLists.txt index 9eff04f30..856f6aaa6 100644 --- a/src/sio/CMakeLists.txt +++ b/src/sio/CMakeLists.txt @@ -13,8 +13,8 @@ # Copyright 2020,2021 David Hrdlička. # -add_library(sio OBJECT sio_acc3221.c sio_f82c710.c sio_82091aa.c sio_fdc37c651.c sio_fdc37c661.c - sio_fdc37c66x.c sio_fdc37c669.c sio_fdc37c93x.c sio_fdc37m60x.c +add_library(sio OBJECT sio_acc3221.c sio_f82c710.c sio_82091aa.c sio_fdc37c6xx.c + sio_fdc37c67x.c sio_fdc37c669.c sio_fdc37c93x.c sio_fdc37m60x.c sio_it8661f.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 diff --git a/src/sio/sio_detect.c b/src/sio/sio_detect.c index 7a0f8821e..8df3864c3 100644 --- a/src/sio/sio_detect.c +++ b/src/sio/sio_detect.c @@ -53,7 +53,7 @@ sio_detect_read(uint16_t port, void *priv) pclog("sio_detect_read : port=%04x = %02X\n", port, dev->regs[port & 1]); - return dev->regs[port & 1]; + return 0xff /*dev->regs[port & 1]*/; } diff --git a/src/sio/sio_fdc37c651.c b/src/sio/sio_fdc37c651.c deleted file mode 100644 index 2bfd3fd93..000000000 --- a/src/sio/sio_fdc37c651.c +++ /dev/null @@ -1,190 +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 SMC FDC37C651 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> - -#ifdef ENABLE_FDC37C651_LOG -int fdc37c651_do_log = ENABLE_FDC37C651_LOG; -static void -fdc37c651_log(const char *fmt, ...) -{ - va_list ap; - - if (fdc37c651_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -#define fdc37c651_log(fmt, ...) -#endif - -typedef struct -{ - uint8_t configuration_select, regs[3]; - uint16_t com3, com4; - - fdc_t *fdc_controller; - serial_t *uart[2]; - -} fdc37c651_t; - -static void -fdc37c651_write(uint16_t addr, uint8_t val, void *priv) -{ - fdc37c651_t *dev = (fdc37c651_t *)priv; - - switch (addr) - { - case 0x3f0: - dev->configuration_select = val; - break; - case 0x3f1: - switch (dev->configuration_select) - { - case 0: /* CR0 */ - dev->regs[dev->configuration_select] = val; - ide_pri_disable(); - fdc_remove(dev->fdc_controller); - - if (val & 1) /* Enable IDE */ - ide_pri_enable(); - - if (val & 0x10) /* Enable FDC */ - fdc_set_base(dev->fdc_controller, 0x3f0); - - break; - - case 1: /* CR1 */ - dev->regs[dev->configuration_select] = val; - lpt1_remove(); - - if ((val & 3) != 0) /* Program LPT if not Disabled */ - lpt1_init((val & 2) ? ((val & 1) ? 0x278 : 0x378) : 0x3f8); - - switch ((val >> 4) & 3) /* COM3 & 4 Select*/ - { - case 0: - dev->com3 = 0x338; - dev->com4 = 0x238; - break; - case 1: - dev->com3 = 0x3e8; - dev->com4 = 0x2e8; - break; - case 2: - dev->com3 = 0x2e8; - dev->com4 = 0x2e0; - break; - case 3: - dev->com3 = 0x220; - dev->com4 = 0x228; - break; - } - - break; - - case 2: /* CR2 */ - dev->regs[dev->configuration_select] = val; - serial_remove(dev->uart[0]); - serial_remove(dev->uart[1]); - - if (val & 4) - serial_setup(dev->uart[0], (val & 2) ? ((val & 1) ? dev->com4 : dev->com3) : ((val & 1) ? 0x2f8 : 0x3f8), 4); - - if (val & 0x40) - serial_setup(dev->uart[1], (val & 0x20) ? ((val & 0x10) ? dev->com4 : dev->com3) : ((val & 0x10) ? 0x2f8 : 0x3f8), 3); - - break; - } - break; - } -} - -static uint8_t -fdc37c651_read(uint16_t addr, void *priv) -{ - fdc37c651_t *dev = (fdc37c651_t *)priv; - - return dev->regs[dev->configuration_select]; -} - -static void -fdc37c651_close(void *priv) -{ - fdc37c651_t *dev = (fdc37c651_t *)priv; - free(dev); -} - -static void * -fdc37c651_init(const device_t *info) -{ - fdc37c651_t *dev = (fdc37c651_t *)malloc(sizeof(fdc37c651_t)); - memset(dev, 0, sizeof(fdc37c651_t)); - - dev->fdc_controller = device_add(&fdc_at_smc_device); - dev->uart[0] = device_add_inst(&ns16450_device, 1); - dev->uart[1] = device_add_inst(&ns16450_device, 2); - device_add(&ide_isa_device); - - /* Program Defaults */ - dev->regs[0] = 0x3f; - dev->regs[1] = 0x9f; - dev->regs[2] = 0xdc; - ide_pri_disable(); - fdc_remove(dev->fdc_controller); - lpt1_remove(); - serial_remove(dev->uart[0]); - serial_remove(dev->uart[1]); - - ide_pri_enable(); - fdc_set_base(dev->fdc_controller, 0x3f0); - lpt1_init(0x278); - serial_setup(dev->uart[0], 0x2f8, 4); - serial_setup(dev->uart[1], 0x3f8, 3); - - io_sethandler(0x03f0, 2, fdc37c651_read, NULL, NULL, fdc37c651_write, NULL, NULL, dev); - - return dev; -} - -const device_t fdc37c651_device = { - "SMC FDC37C651", - 0, - 0, - fdc37c651_init, - fdc37c651_close, - NULL, - {NULL}, - NULL, - NULL, - NULL}; diff --git a/src/sio/sio_fdc37c661.c b/src/sio/sio_fdc37c661.c deleted file mode 100644 index 159a68d47..000000000 --- a/src/sio/sio_fdc37c661.c +++ /dev/null @@ -1,277 +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. - * - * Implementation of the SMC FDC37C661 Super - * I/O Chip. - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2020 plant/nerd73. - */ -#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 { - uint8_t lock[2], - regs[4]; - int cur_reg, - com3_addr, com4_addr; - fdc_t *fdc; - serial_t *uart[2]; -} fdc37c661_t; - - -static void -write_lock(fdc37c661_t *dev, uint8_t val) -{ - if (val == 0x55 && dev->lock[1] == 0x55) - fdc_3f1_enable(dev->fdc, 0); - if ((dev->lock[0] == 0x55) && (dev->lock[1] == 0x55) && (val != 0x55)) - fdc_3f1_enable(dev->fdc, 1); - - dev->lock[0] = dev->lock[1]; - dev->lock[1] = val; -} - - -static void -set_com34_addr(fdc37c661_t *dev) -{ - switch (dev->regs[1] & 0x60) { - case 0x00: - dev->com3_addr = 0x338; - dev->com4_addr = 0x238; - break; - case 0x20: - dev->com3_addr = 0x3e8; - dev->com4_addr = 0x2e8; - break; - case 0x40: - dev->com3_addr = 0x3e8; - dev->com4_addr = 0x2e0; - break; - case 0x60: - dev->com3_addr = 0x220; - dev->com4_addr = 0x228; - break; - } -} - - -static void -set_serial_addr(fdc37c661_t *dev, int port) -{ - uint8_t shift = (port << 4); - - if (dev->regs[2] & (4 << shift)) { - switch (dev->regs[2] & (3 << shift)) { - case 0: - serial_setup(dev->uart[port], SERIAL1_ADDR, SERIAL1_IRQ); - break; - case 1: - serial_setup(dev->uart[port], SERIAL2_ADDR, SERIAL2_IRQ); - break; - case 2: - serial_setup(dev->uart[port], dev->com3_addr, 4); - break; - case 3: - serial_setup(dev->uart[port], dev->com4_addr, 3); - break; - } - } -} - - -static void -lpt1_handler(fdc37c661_t *dev) -{ - lpt1_remove(); - switch (dev->regs[1] & 3) { - case 1: - lpt1_init(0x3bc); - lpt1_irq(7); - break; - case 2: - lpt1_init(0x378); - lpt1_irq(5); - break; - case 3: - lpt1_init(0x278); - lpt1_irq(5); - break; - } -} - - -static void -fdc_handler(fdc37c661_t *dev) -{ - fdc_remove(dev->fdc); - if (dev->regs[0] & 0x10) - fdc_set_base(dev->fdc, 0x03f0); -} - - -static void -fdc37c661_write(uint16_t port, uint8_t val, void *priv) -{ - fdc37c661_t *dev = (fdc37c661_t *) priv; - uint8_t valxor = 0; - - if ((dev->lock[0] == 0x55) && (dev->lock[1] == 0x55)) { - if (port == 0x3f0) { - if (val == 0xaa) - write_lock(dev, val); - else - dev->cur_reg = val; - } else { - if (dev->cur_reg > 4) - return; - - valxor = val ^ dev->regs[dev->cur_reg]; - dev->regs[dev->cur_reg] = val; - - switch(dev->cur_reg) { - case 0: - if (valxor & 0x10) - fdc_handler(dev); - break; - case 1: - if (valxor & 3) - lpt1_handler(dev); - if (valxor & 0x60) { - serial_remove(dev->uart[0]); - serial_remove(dev->uart[1]); - set_com34_addr(dev); - set_serial_addr(dev, 0); - set_serial_addr(dev, 1); - } - break; - case 2: - if (valxor & 7) { - serial_remove(dev->uart[0]); - set_serial_addr(dev, 0); - } - if (valxor & 0x70) { - serial_remove(dev->uart[1]); - set_serial_addr(dev, 1); - } - break; - case 3: - if (valxor & 4) - fdc_update_enh_mode(dev->fdc, (dev->regs[3] & 4) ? 1 : 0); - break; - } - } - } else { - if (port == 0x3f0) - write_lock(dev, val); - } -} - - -static uint8_t -fdc37c661_read(uint16_t port, void *priv) -{ - fdc37c661_t *dev = (fdc37c661_t *) priv; - uint8_t ret = 0xff; - - if ((dev->lock[0] == 0x55) && (dev->lock[1] == 0x55)) { - if (port == 0x3f1) - ret = dev->regs[dev->cur_reg]; - } - - return ret; -} - - -static void -fdc37c661_reset(fdc37c661_t *dev) -{ - dev->com3_addr = 0x338; - dev->com4_addr = 0x238; - - serial_remove(dev->uart[0]); - serial_setup(dev->uart[0], SERIAL1_ADDR, SERIAL1_IRQ); - - serial_remove(dev->uart[1]); - serial_setup(dev->uart[1], SERIAL2_ADDR, SERIAL2_IRQ); - - lpt1_remove(); - lpt1_init(0x378); - - fdc_reset(dev->fdc); - - memset(dev->lock, 0, 2); - memset(dev->regs, 0, 16); - - dev->regs[0x0] = 0x3f; - dev->regs[0x1] = 0x9f; - dev->regs[0x2] = 0xdc; - dev->regs[0x3] = 0x78; -} - - -static void -fdc37c661_close(void *priv) -{ - fdc37c661_t *dev = (fdc37c661_t *) priv; - - free(dev); -} - - -static void * -fdc37c661_init(const device_t *info) -{ - fdc37c661_t *dev = (fdc37c661_t *) malloc(sizeof(fdc37c661_t)); - memset(dev, 0, sizeof(fdc37c661_t)); - - dev->fdc = device_add(&fdc_at_smc_device); - - dev->uart[0] = device_add_inst(&ns16550_device, 1); - dev->uart[1] = device_add_inst(&ns16550_device, 2); - - io_sethandler(0x03f0, 0x0002, - fdc37c661_read, NULL, NULL, fdc37c661_write, NULL, NULL, dev); - - fdc37c661_reset(dev); - - return dev; -} - -const device_t fdc37c661_device = { - "SMC FDC37C661 Super I/O", - 0, - 0, - fdc37c661_init, fdc37c661_close, NULL, - { NULL }, NULL, NULL, - NULL -}; - diff --git a/src/sio/sio_fdc37c669.c b/src/sio/sio_fdc37c669.c index b2d76814e..d223cf0df 100644 --- a/src/sio/sio_fdc37c669.c +++ b/src/sio/sio_fdc37c669.c @@ -33,7 +33,7 @@ typedef struct { - uint8_t tries, + uint8_t id, tries, regs[42]; int locked, rw_locked, cur_reg; @@ -42,6 +42,9 @@ typedef struct { } fdc37c669_t; +static int next_id = 0; + + static uint16_t make_port(fdc37c669_t *dev, uint8_t reg) { @@ -114,7 +117,7 @@ fdc37c669_write(uint16_t port, uint8_t val, void *priv) switch(dev->cur_reg) { case 0: - if (valxor & 8) { + if (!dev->id && (valxor & 8)) { fdc_remove(dev->fdc); if ((dev->regs[0] & 8) && (dev->regs[0x20] & 0xc0)) fdc_set_base(dev->fdc, make_port(dev, 0x20)); @@ -122,9 +125,15 @@ fdc37c669_write(uint16_t port, uint8_t val, void *priv) break; case 1: if (valxor & 4) { - lpt1_remove(); - if ((dev->regs[1] & 4) && (dev->regs[0x23] >= 0x40)) - lpt1_init(make_port(dev, 0x23)); + if (dev->id) { + lpt2_remove(); + if ((dev->regs[1] & 4) && (dev->regs[0x23] >= 0x40)) + lpt2_init(make_port(dev, 0x23)); + } else { + lpt1_remove(); + if ((dev->regs[1] & 4) && (dev->regs[0x23] >= 0x40)) + lpt1_init(make_port(dev, 0x23)); + } } if (valxor & 7) dev->rw_locked = (val & 8) ? 0 : 1; @@ -142,23 +151,23 @@ fdc37c669_write(uint16_t port, uint8_t val, void *priv) } break; case 3: - if (valxor & 2) + if (!dev->id && (valxor & 2)) fdc_update_enh_mode(dev->fdc, (val & 2) ? 1 : 0); break; case 5: - if (valxor & 0x18) + if (!dev->id && (valxor & 0x18)) fdc_update_densel_force(dev->fdc, (val & 0x18) >> 3); - if (valxor & 0x20) + if (!dev->id && (valxor & 0x20)) fdc_set_swap(dev->fdc, (val & 0x20) >> 5); break; case 0xB: - if (valxor & 3) + if (!dev->id && (valxor & 3)) fdc_update_rwc(dev->fdc, 0, val & 3); - if (valxor & 0xC) + if (!dev->id && (valxor & 0xC)) fdc_update_rwc(dev->fdc, 1, (val & 0xC) >> 2); break; case 0x20: - if (valxor & 0xfc) { + if (!dev->id && (valxor & 0xfc)) { fdc_remove(dev->fdc); if ((dev->regs[0] & 8) && (dev->regs[0x20] & 0xc0)) fdc_set_base(dev->fdc, make_port(dev, 0x20)); @@ -166,9 +175,15 @@ fdc37c669_write(uint16_t port, uint8_t val, void *priv) break; case 0x23: if (valxor) { - lpt1_remove(); - if ((dev->regs[1] & 4) && (dev->regs[0x23] >= 0x40)) - lpt1_init(make_port(dev, 0x23)); + if (dev->id) { + lpt2_remove(); + if ((dev->regs[1] & 4) && (dev->regs[0x23] >= 0x40)) + lpt2_init(make_port(dev, 0x23)); + } else { + lpt1_remove(); + if ((dev->regs[1] & 4) && (dev->regs[0x23] >= 0x40)) + lpt1_init(make_port(dev, 0x23)); + } } break; case 0x24: @@ -186,8 +201,12 @@ fdc37c669_write(uint16_t port, uint8_t val, void *priv) } break; case 0x27: - if (valxor & 0xf) - lpt1_irq(val & 0xf); + if (valxor & 0xf) { + if (dev->id) + lpt2_irq(val & 0xf); + else + lpt1_irq(val & 0xf); + } break; case 0x28: if (valxor & 0xf) { @@ -226,17 +245,12 @@ fdc37c669_read(uint16_t port, void *priv) static void fdc37c669_reset(fdc37c669_t *dev) { - fdc_reset(dev->fdc); - serial_remove(dev->uart[0]); serial_setup(dev->uart[0], SERIAL1_ADDR, SERIAL1_IRQ); serial_remove(dev->uart[1]); serial_setup(dev->uart[1], SERIAL2_ADDR, SERIAL2_IRQ); - lpt1_remove(); - lpt1_init(0x378); - memset(dev->regs, 0, 42); dev->regs[0x00] = 0x28; dev->regs[0x01] = 0x9c; @@ -249,11 +263,27 @@ fdc37c669_reset(fdc37c669_t *dev) dev->regs[0x20] = (0x3f0 >> 2) & 0xfc; dev->regs[0x21] = (0x1f0 >> 2) & 0xfc; dev->regs[0x22] = ((0x3f6 >> 2) & 0xfc) | 1; - dev->regs[0x23] = (0x378 >> 2); - dev->regs[0x24] = (0x3f8 >> 2) & 0xfe; - dev->regs[0x25] = (0x2f8 >> 2) & 0xfe; + if (dev->id == 1) { + dev->regs[0x23] = (0x278 >> 2); + + lpt2_remove(); + lpt2_init(0x278); + + dev->regs[0x24] = (SERIAL3_ADDR >> 2) & 0xfe; + dev->regs[0x25] = (SERIAL4_ADDR >> 2) & 0xfe; + } else { + fdc_reset(dev->fdc); + + lpt1_remove(); + lpt1_init(0x378); + + dev->regs[0x23] = (0x378 >> 2); + + dev->regs[0x24] = (SERIAL1_ADDR >> 2) & 0xfe; + dev->regs[0x25] = (SERIAL2_ADDR >> 2) & 0xfe; + } dev->regs[0x26] = (2 << 4) | 3; - dev->regs[0x27] = (6 << 4) | 7; + dev->regs[0x27] = (6 << 4) | (dev->id ? 5 : 7); dev->regs[0x28] = (4 << 4) | 3; dev->locked = 0; @@ -266,6 +296,8 @@ fdc37c669_close(void *priv) { fdc37c669_t *dev = (fdc37c669_t *) priv; + next_id = 0; + free(dev); } @@ -276,16 +308,21 @@ fdc37c669_init(const device_t *info) fdc37c669_t *dev = (fdc37c669_t *) malloc(sizeof(fdc37c669_t)); memset(dev, 0, sizeof(fdc37c669_t)); - dev->fdc = device_add(&fdc_at_smc_device); + dev->id = next_id; - dev->uart[0] = device_add_inst(&ns16550_device, 1); - dev->uart[1] = device_add_inst(&ns16550_device, 2); + if (next_id != 1) + dev->fdc = device_add(&fdc_at_smc_device); - io_sethandler(info->local ? 0x370 : 0x3f0, 0x0002, + dev->uart[0] = device_add_inst(&ns16550_device, (next_id << 1) + 1); + dev->uart[1] = device_add_inst(&ns16550_device, (next_id << 1) + 2); + + io_sethandler(info->local ? 0x370 : (next_id ? 0x370 : 0x3f0), 0x0002, fdc37c669_read, NULL, NULL, fdc37c669_write, NULL, NULL, dev); fdc37c669_reset(dev); + next_id++; + return dev; } diff --git a/src/sio/sio_fdc37c67x.c b/src/sio/sio_fdc37c67x.c new file mode 100644 index 000000000..d6905a72d --- /dev/null +++ b/src/sio/sio_fdc37c67x.c @@ -0,0 +1,613 @@ +/* + * 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 SMC FDC37C67X Super I/O Chip. + * + * + * + * Author: Miran Grca, + * Copyright 2016-2018 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/pic.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 "cpu.h" +#include <86box/sio.h> + + +#define AB_RST 0x80 + + +typedef struct { + uint8_t chip_id, is_apm, + tries, + gpio_regs[2], auxio_reg, + regs[48], + ld_regs[11][256]; + uint16_t gpio_base, /* Set to EA */ + auxio_base, sio_base; + int locked, + cur_reg; + fdc_t *fdc; + serial_t *uart[2]; +} fdc37c67x_t; + + +static void fdc37c67x_write(uint16_t port, uint8_t val, void *priv); +static uint8_t fdc37c67x_read(uint16_t port, void *priv); + + +static uint16_t +make_port(fdc37c67x_t *dev, uint8_t ld) +{ + uint16_t r0 = dev->ld_regs[ld][0x60]; + uint16_t r1 = dev->ld_regs[ld][0x61]; + + uint16_t p = (r0 << 8) + r1; + + return p; +} + + +static uint8_t +fdc37c67x_auxio_read(uint16_t port, void *priv) +{ + fdc37c67x_t *dev = (fdc37c67x_t *) priv; + + return dev->auxio_reg; +} + + +static void +fdc37c67x_auxio_write(uint16_t port, uint8_t val, void *priv) +{ + fdc37c67x_t *dev = (fdc37c67x_t *) priv; + + dev->auxio_reg = val; +} + + +static uint8_t +fdc37c67x_gpio_read(uint16_t port, void *priv) +{ + fdc37c67x_t *dev = (fdc37c67x_t *) priv; + uint8_t ret = 0xff; + + ret = dev->gpio_regs[port & 1]; + + return ret; +} + + +static void +fdc37c67x_gpio_write(uint16_t port, uint8_t val, void *priv) +{ + fdc37c67x_t *dev = (fdc37c67x_t *) priv; + + if (!(port & 1)) + dev->gpio_regs[0] = (dev->gpio_regs[0] & 0xfc) | (val & 0x03); +} + + +static void +fdc37c67x_fdc_handler(fdc37c67x_t *dev) +{ + uint16_t ld_port = 0; + uint8_t global_enable = !!(dev->regs[0x22] & (1 << 0)); + uint8_t local_enable = !!dev->ld_regs[0][0x30]; + + fdc_remove(dev->fdc); + if (global_enable && local_enable) { + ld_port = make_port(dev, 0) & 0xFFF8; + if ((ld_port >= 0x0100) && (ld_port <= 0x0FF8)) + fdc_set_base(dev->fdc, ld_port); + } +} + + +static void +fdc37c67x_lpt_handler(fdc37c67x_t *dev) +{ + uint16_t ld_port = 0; + uint8_t global_enable = !!(dev->regs[0x22] & (1 << 3)); + uint8_t local_enable = !!dev->ld_regs[3][0x30]; + uint8_t lpt_irq = dev->ld_regs[3][0x70]; + + if (lpt_irq > 15) + lpt_irq = 0xff; + + lpt1_remove(); + if (global_enable && local_enable) { + ld_port = make_port(dev, 3) & 0xFFFC; + if ((ld_port >= 0x0100) && (ld_port <= 0x0FFC)) + lpt1_init(ld_port); + } + lpt1_irq(lpt_irq); +} + + +static void +fdc37c67x_serial_handler(fdc37c67x_t *dev, int uart) +{ + uint16_t ld_port = 0; + uint8_t uart_no = 4 + uart; + uint8_t global_enable = !!(dev->regs[0x22] & (1 << uart_no)); + uint8_t local_enable = !!dev->ld_regs[uart_no][0x30]; + + serial_remove(dev->uart[uart]); + if (global_enable && local_enable) { + ld_port = make_port(dev, uart_no) & 0xFFF8; + if ((ld_port >= 0x0100) && (ld_port <= 0x0FF8)) + serial_setup(dev->uart[uart], ld_port, dev->ld_regs[uart_no][0x70]); + } +} + + +static void +fdc37c67x_auxio_handler(fdc37c67x_t *dev) +{ + uint16_t ld_port = 0; + uint8_t local_enable = !!dev->ld_regs[8][0x30]; + + io_removehandler(dev->auxio_base, 0x0001, + fdc37c67x_auxio_read, NULL, NULL, fdc37c67x_auxio_write, NULL, NULL, dev); + if (local_enable) { + dev->auxio_base = ld_port = make_port(dev, 8); + if ((ld_port >= 0x0100) && (ld_port <= 0x0FFF)) + io_sethandler(dev->auxio_base, 0x0001, + fdc37c67x_auxio_read, NULL, NULL, fdc37c67x_auxio_write, NULL, NULL, dev); + } +} + + +static void +fdc37c67x_sio_handler(fdc37c67x_t *dev) +{ +#if 0 + if (dev->sio_base) { + io_removehandler(dev->sio_base, 0x0002, + fdc37c67x_read, NULL, NULL, fdc37c67x_write, NULL, NULL, dev); + } + dev->sio_base = (((uint16_t) dev->regs[0x27]) << 8) | dev->regs[0x26]; + if (dev->sio_base) { + io_sethandler(dev->sio_base, 0x0002, + fdc37c67x_read, NULL, NULL, fdc37c67x_write, NULL, NULL, dev); + } +#endif +} + + +static void +fdc37c67x_gpio_handler(fdc37c67x_t *dev) +{ + uint16_t ld_port = 0; + uint8_t local_enable; + + local_enable = !!(dev->regs[0x03] & 0x80); + + io_removehandler(dev->gpio_base, 0x0002, + fdc37c67x_gpio_read, NULL, NULL, fdc37c67x_gpio_write, NULL, NULL, dev); + if (local_enable) { + switch (dev->regs[0x03] & 0x03) { + case 0: + ld_port = 0xe0; + break; + case 1: + ld_port = 0xe2; + break; + case 2: + ld_port = 0xe4; + break; + case 3: + ld_port = 0xea; /* Default */ + break; + } + dev->gpio_base = ld_port; + if (ld_port > 0x0000) + io_sethandler(dev->gpio_base, 0x0002, + fdc37c67x_gpio_read, NULL, NULL, fdc37c67x_gpio_write, NULL, NULL, dev); + } +} + + +static void +fdc37c67x_smi_handler(fdc37c67x_t *dev) +{ + /* TODO: 8042 P1.2 SMI#. */ + pic_reset_smi_irq_mask(); + pic_set_smi_irq_mask(dev->ld_regs[3][0x70], dev->ld_regs[8][0xb4] & 0x02); + pic_set_smi_irq_mask(dev->ld_regs[5][0x70], dev->ld_regs[8][0xb4] & 0x04); + pic_set_smi_irq_mask(dev->ld_regs[4][0x70], dev->ld_regs[8][0xb4] & 0x08); + pic_set_smi_irq_mask(dev->ld_regs[0][0x70], dev->ld_regs[8][0xb4] & 0x10); + pic_set_smi_irq_mask(12, dev->ld_regs[8][0xb5] & 0x01); + pic_set_smi_irq_mask(1, dev->ld_regs[8][0xb5] & 0x02); + pic_set_smi_irq_mask(10, dev->ld_regs[8][0xb5] & 0x80); +} + + +static void +fdc37c67x_write(uint16_t port, uint8_t val, void *priv) +{ + fdc37c67x_t *dev = (fdc37c67x_t *) priv; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t valxor = 0x00, keep = 0x00; + + if (index) { + if ((val == 0x55) && !dev->locked) { + if (dev->tries) { + dev->locked = 1; + fdc_3f1_enable(dev->fdc, 0); + dev->tries = 0; + } else + dev->tries++; + } else { + if (dev->locked) { + if (val == 0xaa) { + dev->locked = 0; + fdc_3f1_enable(dev->fdc, 1); + return; + } + dev->cur_reg = val; + } else { + if (dev->tries) + dev->tries = 0; + } + } + return; + } else { + if (dev->locked) { + if (dev->cur_reg < 48) { + valxor = val ^ dev->regs[dev->cur_reg]; + if ((val == 0x20) || (val == 0x21)) + return; + dev->regs[dev->cur_reg] = val; + } else { + valxor = val ^ dev->ld_regs[dev->regs[7]][dev->cur_reg]; + if (((dev->cur_reg & 0xF0) == 0x70) && (dev->regs[7] < 4)) + return; + /* Block writes to some logical devices. */ + if (dev->regs[7] > 0x0a) + return; + else switch (dev->regs[7]) { + case 0x01: + case 0x02: + case 0x07: + return; + } + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val | keep; + } + } else + return; + } + + if (dev->cur_reg < 48) { + switch(dev->cur_reg) { + case 0x03: + if (valxor & 0x83) + fdc37c67x_gpio_handler(dev); + dev->regs[0x03] &= 0x83; + break; + case 0x22: + if (valxor & 0x01) + fdc37c67x_fdc_handler(dev); + if (valxor & 0x08) + fdc37c67x_lpt_handler(dev); + if (valxor & 0x10) + fdc37c67x_serial_handler(dev, 0); + if (valxor & 0x20) + fdc37c67x_serial_handler(dev, 1); + break; + case 0x26: case 0x27: + fdc37c67x_sio_handler(dev); + } + + return; + } + + switch(dev->regs[7]) { + case 0: + /* FDD */ + switch(dev->cur_reg) { + case 0x30: + case 0x60: + case 0x61: + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x01; + if (valxor) + fdc37c67x_fdc_handler(dev); + break; + case 0xF0: + if (valxor & 0x01) + fdc_update_enh_mode(dev->fdc, val & 0x01); + if (valxor & 0x10) + fdc_set_swap(dev->fdc, (val & 0x10) >> 4); + break; + case 0xF1: + if (valxor & 0xC) + fdc_update_densel_force(dev->fdc, (val & 0xc) >> 2); + break; + case 0xF2: + 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: + if (valxor & 0x18) + fdc_update_drvrate(dev->fdc, 0, (val & 0x18) >> 3); + break; + case 0xF5: + if (valxor & 0x18) + fdc_update_drvrate(dev->fdc, 1, (val & 0x18) >> 3); + break; + case 0xF6: + if (valxor & 0x18) + fdc_update_drvrate(dev->fdc, 2, (val & 0x18) >> 3); + break; + case 0xF7: + if (valxor & 0x18) + fdc_update_drvrate(dev->fdc, 3, (val & 0x18) >> 3); + break; + } + break; + case 3: + /* Parallel port */ + switch(dev->cur_reg) { + case 0x30: + case 0x60: + case 0x61: + case 0x70: + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x08; + if (valxor) + fdc37c67x_lpt_handler(dev); + if (dev->cur_reg == 0x70) + fdc37c67x_smi_handler(dev); + break; + } + break; + case 4: + /* Serial port 1 */ + switch(dev->cur_reg) { + case 0x30: + case 0x60: + case 0x61: + case 0x70: + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x10; + if (valxor) + fdc37c67x_serial_handler(dev, 0); + if (dev->cur_reg == 0x70) + fdc37c67x_smi_handler(dev); + break; + } + break; + case 5: + /* Serial port 2 */ + switch(dev->cur_reg) { + case 0x30: + case 0x60: + case 0x61: + case 0x70: + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x20; + if (valxor) + fdc37c67x_serial_handler(dev, 1); + if (dev->cur_reg == 0x70) + fdc37c67x_smi_handler(dev); + break; + } + break; + case 8: + /* Auxiliary I/O */ + switch(dev->cur_reg) { + case 0x30: + case 0x60: + case 0x61: + case 0x70: + if (valxor) + fdc37c67x_auxio_handler(dev); + break; + case 0xb4: + case 0xb5: + fdc37c67x_smi_handler(dev); + break; + } + break; + } +} + + +static uint8_t +fdc37c67x_read(uint16_t port, void *priv) +{ + fdc37c67x_t *dev = (fdc37c67x_t *) priv; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t ret = 0xff; + uint16_t smi_stat = pic_get_smi_irq_status(); + int f_irq = dev->ld_regs[0][0x70]; + int p_irq = dev->ld_regs[3][0x70]; + int s1_irq = dev->ld_regs[4][0x70]; + int s2_irq = dev->ld_regs[5][0x70]; + + if (dev->locked) { + if (index) + ret = dev->cur_reg; + else { + if (dev->cur_reg < 0x30) { + if (dev->cur_reg == 0x20) + ret = dev->chip_id; + else + ret = dev->regs[dev->cur_reg]; + } else { + if ((dev->regs[7] == 0) && (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]; + + /* TODO: 8042 P1.2 SMI#. */ + if ((dev->regs[7] == 8) && (dev->cur_reg == 0xb6)) { + ret = dev->regs[dev->cur_reg] & 0xe1; + ret |= ((!!(smi_stat & (1 << p_irq))) << 1); + ret |= ((!!(smi_stat & (1 << s2_irq))) << 2); + ret |= ((!!(smi_stat & (1 << s1_irq))) << 3); + ret |= ((!!(smi_stat & (1 << f_irq))) << 4); + } else if ((dev->regs[7] == 8) && (dev->cur_reg == 0xb7)) { + ret = dev->regs[dev->cur_reg] & 0xec; + ret |= ((!!(smi_stat & (1 << 12))) << 0); + ret |= ((!!(smi_stat & (1 << 1))) << 1); + ret |= ((!!(smi_stat & (1 << 10))) << 4); + } + } + } + } + + return ret; +} + + +static void +fdc37c67x_reset(fdc37c67x_t *dev) +{ + int i = 0; + + memset(dev->regs, 0, 48); + + dev->regs[0x03] = 0x03; + dev->regs[0x20] = dev->chip_id; + dev->regs[0x22] = 0x39; + dev->regs[0x24] = 0x04; + dev->regs[0x26] = 0xf0; + dev->regs[0x27] = 0x03; + + for (i = 0; i < 11; i++) + memset(dev->ld_regs[i], 0, 256); + + /* Logical device 0: FDD */ + dev->ld_regs[0][0x30] = 1; + dev->ld_regs[0][0x60] = 3; + dev->ld_regs[0][0x61] = 0xf0; + dev->ld_regs[0][0x70] = 6; + dev->ld_regs[0][0x74] = 2; + dev->ld_regs[0][0xf0] = 0x0e; + dev->ld_regs[0][0xf2] = 0xff; + + /* Logical device 3: Parallel Port */ + dev->ld_regs[3][0x30] = 1; + dev->ld_regs[3][0x60] = 3; + dev->ld_regs[3][0x61] = 0x78; + dev->ld_regs[3][0x70] = 7; + dev->ld_regs[3][0x74] = 4; + dev->ld_regs[3][0xf0] = 0x3c; + + /* Logical device 4: Serial Port 1 */ + dev->ld_regs[4][0x30] = 1; + dev->ld_regs[4][0x60] = 3; + dev->ld_regs[4][0x61] = 0xf8; + dev->ld_regs[4][0x70] = 4; + dev->ld_regs[4][0xf0] = 3; + serial_setup(dev->uart[0], 0x3f8, dev->ld_regs[4][0x70]); + + /* Logical device 5: Serial Port 2 */ + dev->ld_regs[5][0x30] = 1; + dev->ld_regs[5][0x60] = 2; + dev->ld_regs[5][0x61] = 0xf8; + dev->ld_regs[5][0x70] = 3; + dev->ld_regs[5][0x74] = 4; + dev->ld_regs[5][0xf1] = 2; + dev->ld_regs[5][0xf2] = 3; + serial_setup(dev->uart[1], 0x2f8, dev->ld_regs[5][0x70]); + + /* Logical device 7: Keyboard */ + dev->ld_regs[7][0x30] = 1; + dev->ld_regs[7][0x61] = 0x60; + dev->ld_regs[7][0x70] = 1; + dev->ld_regs[7][0x72] = 12; + + /* Logical device 8: Auxiliary I/O */ + dev->ld_regs[8][0xc0] = 6; + dev->ld_regs[8][0xc1] = 3; + + fdc37c67x_gpio_handler(dev); + fdc37c67x_lpt_handler(dev); + fdc37c67x_serial_handler(dev, 0); + fdc37c67x_serial_handler(dev, 1); + fdc37c67x_auxio_handler(dev); + fdc37c67x_sio_handler(dev); + + fdc_reset(dev->fdc); + fdc37c67x_fdc_handler(dev); + + dev->locked = 0; +} + + +static void +fdc37c67x_close(void *priv) +{ + fdc37c67x_t *dev = (fdc37c67x_t *) priv; + + free(dev); +} + + +static void * +fdc37c67x_init(const device_t *info) +{ + fdc37c67x_t *dev = (fdc37c67x_t *) malloc(sizeof(fdc37c67x_t)); + memset(dev, 0, sizeof(fdc37c67x_t)); + + dev->fdc = device_add(&fdc_at_smc_device); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + dev->chip_id = info->local & 0xff; + + dev->gpio_regs[0] = 0xff; + // dev->gpio_regs[1] = (info->local == 0x0030) ? 0xff : 0xfd; + dev->gpio_regs[1] = (dev->chip_id == 0x30) ? 0xff : 0xfd; + + fdc37c67x_reset(dev); + + io_sethandler(0x370, 0x0002, + fdc37c67x_read, NULL, NULL, fdc37c67x_write, NULL, NULL, dev); + io_sethandler(0x3f0, 0x0002, + fdc37c67x_read, NULL, NULL, fdc37c67x_write, NULL, NULL, dev); + + return dev; +} + + +const device_t fdc37c67x_device = { + "SMC FDC37C67X Super I/O", + 0, + 0x40, + fdc37c67x_init, fdc37c67x_close, NULL, + { NULL }, NULL, NULL, + NULL +}; diff --git a/src/sio/sio_fdc37c66x.c b/src/sio/sio_fdc37c6xx.c similarity index 71% rename from src/sio/sio_fdc37c66x.c rename to src/sio/sio_fdc37c6xx.c index 812bbf91b..59f93c1fa 100644 --- a/src/sio/sio_fdc37c66x.c +++ b/src/sio/sio_fdc37c6xx.c @@ -37,17 +37,18 @@ typedef struct { - uint8_t chip_id, tries, - has_ide, regs[16]; + uint8_t max_reg, chip_id, + tries, has_ide, + regs[16]; int cur_reg, com3_addr, com4_addr; fdc_t *fdc; serial_t *uart[2]; -} fdc37c66x_t; +} fdc37c6xx_t; static void -set_com34_addr(fdc37c66x_t *dev) +set_com34_addr(fdc37c6xx_t *dev) { switch (dev->regs[1] & 0x60) { case 0x00: @@ -71,7 +72,7 @@ set_com34_addr(fdc37c66x_t *dev) static void -set_serial_addr(fdc37c66x_t *dev, int port) +set_serial_addr(fdc37c6xx_t *dev, int port) { uint8_t shift = (port << 2); double clock_src = 24000000.0 / 13.0; @@ -102,7 +103,7 @@ set_serial_addr(fdc37c66x_t *dev, int port) static void -lpt1_handler(fdc37c66x_t *dev) +lpt1_handler(fdc37c6xx_t *dev) { lpt1_remove(); switch (dev->regs[1] & 3) { @@ -123,7 +124,7 @@ lpt1_handler(fdc37c66x_t *dev) static void -fdc_handler(fdc37c66x_t *dev) +fdc_handler(fdc37c6xx_t *dev) { fdc_remove(dev->fdc); if (dev->regs[0] & 0x10) @@ -133,7 +134,7 @@ fdc_handler(fdc37c66x_t *dev) static void -ide_handler(fdc37c66x_t *dev) +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) { @@ -153,9 +154,9 @@ ide_handler(fdc37c66x_t *dev) static void -fdc37c66x_write(uint16_t port, uint8_t val, void *priv) +fdc37c6xx_write(uint16_t port, uint8_t val, void *priv) { - fdc37c66x_t *dev = (fdc37c66x_t *) priv; + fdc37c6xx_t *dev = (fdc37c6xx_t *) priv; uint8_t valxor = 0; if (dev->tries == 2) { @@ -165,7 +166,7 @@ fdc37c66x_write(uint16_t port, uint8_t val, void *priv) else dev->cur_reg = val; } else { - if (dev->cur_reg > 15) + if (dev->cur_reg > dev->max_reg) return; valxor = val ^ dev->regs[dev->cur_reg]; @@ -221,9 +222,9 @@ fdc37c66x_write(uint16_t port, uint8_t val, void *priv) static uint8_t -fdc37c66x_read(uint16_t port, void *priv) +fdc37c6xx_read(uint16_t port, void *priv) { - fdc37c66x_t *dev = (fdc37c66x_t *) priv; + fdc37c6xx_t *dev = (fdc37c6xx_t *) priv; uint8_t ret = 0x00; if (dev->tries == 2) { @@ -236,7 +237,7 @@ fdc37c66x_read(uint16_t port, void *priv) static void -fdc37c66x_reset(fdc37c66x_t *dev) +fdc37c6xx_reset(fdc37c6xx_t *dev) { dev->com3_addr = 0x338; dev->com4_addr = 0x238; @@ -256,13 +257,33 @@ fdc37c66x_reset(fdc37c66x_t *dev) dev->tries = 0; memset(dev->regs, 0, 16); - dev->regs[0x0] = 0x2a; + switch (dev->chip_id) { + case 0x63: case 0x65: + dev->max_reg = 0x0f; + dev->regs[0x0] = 0x3b; + break; + case 0x64: case 0x66: + dev->max_reg = 0x0f; + dev->regs[0x0] = 0x2b; + break; + default: + dev->max_reg = (dev->chip_id >= 0x61) ? 0x03 : 0x02; + dev->regs[0x0] = 0x3f; + break; + } + dev->regs[0x1] = 0x9f; dev->regs[0x2] = 0xdc; dev->regs[0x3] = 0x78; - dev->regs[0x6] = 0xff; - dev->regs[0xd] = dev->chip_id; - dev->regs[0xe] = 0x01; + + if (dev->chip_id >= 0x63) { + dev->regs[0x6] = 0xff; + dev->regs[0xd] = dev->chip_id; + if (dev->chip_id >= 0x65) + dev->regs[0xe] = 0x02; + else + dev->regs[0xe] = 0x01; + } set_serial_addr(dev, 0); set_serial_addr(dev, 1); @@ -277,32 +298,37 @@ fdc37c66x_reset(fdc37c66x_t *dev) static void -fdc37c66x_close(void *priv) +fdc37c6xx_close(void *priv) { - fdc37c66x_t *dev = (fdc37c66x_t *) priv; + fdc37c6xx_t *dev = (fdc37c6xx_t *) priv; free(dev); } static void * -fdc37c66x_init(const device_t *info) +fdc37c6xx_init(const device_t *info) { - fdc37c66x_t *dev = (fdc37c66x_t *) malloc(sizeof(fdc37c66x_t)); - memset(dev, 0, sizeof(fdc37c66x_t)); + fdc37c6xx_t *dev = (fdc37c6xx_t *) malloc(sizeof(fdc37c6xx_t)); + memset(dev, 0, sizeof(fdc37c6xx_t)); dev->fdc = device_add(&fdc_at_smc_device); - dev->uart[0] = device_add_inst(&ns16550_device, 1); - dev->uart[1] = device_add_inst(&ns16550_device, 2); - dev->chip_id = info->local & 0xff; dev->has_ide = (info->local >> 8) & 0xff; - io_sethandler(0x03f0, 0x0002, - fdc37c66x_read, NULL, NULL, fdc37c66x_write, NULL, NULL, dev); + if (dev->chip_id >= 0x63) { + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + } else { + dev->uart[0] = device_add_inst(&ns16450_device, 1); + dev->uart[1] = device_add_inst(&ns16450_device, 2); + } - fdc37c66x_reset(dev); + io_sethandler(0x03f0, 0x0002, + fdc37c6xx_read, NULL, NULL, fdc37c6xx_write, NULL, NULL, dev); + + fdc37c6xx_reset(dev); return dev; } @@ -310,11 +336,47 @@ fdc37c66x_init(const device_t *info) /* The three appear to differ only in the chip ID, if I understood their datasheets correctly. */ +const device_t fdc37c651_device = { + "SMC FDC37C651 Super I/O", + 0, + 0x51, + fdc37c6xx_init, fdc37c6xx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + +const device_t fdc37c651_ide_device = { + "SMC FDC37C651 Super I/O (With IDE)", + 0, + 0x151, + fdc37c6xx_init, fdc37c6xx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + +const device_t fdc37c661_device = { + "SMC FDC37C661 Super I/O", + 0, + 0x61, + fdc37c6xx_init, fdc37c6xx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + +const device_t fdc37c661_ide_device = { + "SMC FDC37C661 Super I/O (With IDE)", + 0, + 0x161, + fdc37c6xx_init, fdc37c6xx_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + const device_t fdc37c663_device = { "SMC FDC37C663 Super I/O", 0, 0x63, - fdc37c66x_init, fdc37c66x_close, NULL, + fdc37c6xx_init, fdc37c6xx_close, NULL, { NULL }, NULL, NULL, NULL }; @@ -323,7 +385,7 @@ const device_t fdc37c663_ide_device = { "SMC FDC37C663 Super I/O (With IDE)", 0, 0x163, - fdc37c66x_init, fdc37c66x_close, NULL, + fdc37c6xx_init, fdc37c6xx_close, NULL, { NULL }, NULL, NULL, NULL }; @@ -332,7 +394,7 @@ const device_t fdc37c665_device = { "SMC FDC37C665 Super I/O", 0, 0x65, - fdc37c66x_init, fdc37c66x_close, NULL, + fdc37c6xx_init, fdc37c6xx_close, NULL, { NULL }, NULL, NULL, NULL }; @@ -341,7 +403,7 @@ const device_t fdc37c665_ide_device = { "SMC FDC37C665 Super I/O (With IDE)", 0, 0x265, - fdc37c66x_init, fdc37c66x_close, NULL, + fdc37c6xx_init, fdc37c6xx_close, NULL, { NULL }, NULL, NULL, NULL }; @@ -350,7 +412,7 @@ const device_t fdc37c666_device = { "SMC FDC37C666 Super I/O", 0, 0x66, - fdc37c66x_init, fdc37c66x_close, NULL, + fdc37c6xx_init, fdc37c6xx_close, NULL, { NULL }, NULL, NULL, NULL }; diff --git a/src/sio/sio_fdc37c93x.c b/src/sio/sio_fdc37c93x.c index 35cfe862b..a20349aff 100644 --- a/src/sio/sio_fdc37c93x.c +++ b/src/sio/sio_fdc37c93x.c @@ -206,7 +206,7 @@ fdc37c93x_nvr_sec_handler(fdc37c93x_t *dev) dev->nvr_sec_base = ld_port = make_port_sec(dev, 6) & 0xFFFE; /* 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 ((ld_port >= 0x0000) && (ld_port <= 0x0FFE)) + if (ld_port <= 0x0FFE) nvr_at_sec_handler(1, dev->nvr_sec_base, dev->nvr); } } diff --git a/src/sio/sio_pc87332.c b/src/sio/sio_pc87332.c index 267de0543..c5eb40e60 100644 --- a/src/sio/sio_pc87332.c +++ b/src/sio/sio_pc87332.c @@ -366,6 +366,16 @@ const device_t pc87332_398_ide_device = { }; +const device_t pc87332_398_ide_sec_device = { + "National Semiconductor PC87332 Super I/O (Port 398h) (With Secondary IDE)", + 0, + 0x201, + pc87332_init, pc87332_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + const device_t pc87332_398_ide_fdcon_device = { "National Semiconductor PC87332 Super I/O (Port 398h) (With IDE and FDC on)", 0, diff --git a/src/sio/sio_w83977f.c b/src/sio/sio_w83977f.c index dc3f1c012..46a75ac9e 100644 --- a/src/sio/sio_w83977f.c +++ b/src/sio/sio_w83977f.c @@ -268,11 +268,11 @@ w83977f_write(uint16_t port, uint8_t val, void *priv) if (dev->id == 1) break; - if (valxor & 0x20) + if (!dev->id && (valxor & 0x20)) fdc_update_drv2en(dev->fdc, (val & 0x20) ? 0 : 1); - if (valxor & 0x10) + if (!dev->id && (valxor & 0x10)) fdc_set_swap(dev->fdc, (val & 0x10) ? 1 : 0); - if (valxor & 0x01) + if (!dev->id && (valxor & 0x01)) fdc_update_enh_mode(dev->fdc, (val & 0x01) ? 1 : 0); break; case 0x01: @@ -291,13 +291,13 @@ w83977f_write(uint16_t port, uint8_t val, void *priv) if (dev->id == 1) break; - if (valxor & 0xc0) + if (!dev->id && (valxor & 0xc0)) fdc_update_boot_drive(dev->fdc, (val & 0xc0) >> 6); - if (valxor & 0x0c) + if (!dev->id && (valxor & 0x0c)) fdc_update_densel_force(dev->fdc, (val & 0x0c) >> 2); - if (valxor & 0x02) + if (!dev->id && (valxor & 0x02)) fdc_set_diswr(dev->fdc, (val & 0x02) ? 1 : 0); - if (valxor & 0x01) + if (!dev->id && (valxor & 0x01)) fdc_set_swwp(dev->fdc, (val & 0x01) ? 1 : 0); break; } @@ -308,13 +308,13 @@ w83977f_write(uint16_t port, uint8_t val, void *priv) if (dev->id == 1) break; - if (valxor & 0xc0) + if (!dev->id && (valxor & 0xc0)) fdc_update_rwc(dev->fdc, 3, (val & 0xc0) >> 6); - if (valxor & 0x30) + if (!dev->id && (valxor & 0x30)) fdc_update_rwc(dev->fdc, 2, (val & 0x30) >> 4); - if (valxor & 0x0c) + if (!dev->id && (valxor & 0x0c)) fdc_update_rwc(dev->fdc, 1, (val & 0x0c) >> 2); - if (valxor & 0x03) + if (!dev->id && (valxor & 0x03)) fdc_update_rwc(dev->fdc, 0, val & 0x03); break; } @@ -325,7 +325,7 @@ w83977f_write(uint16_t port, uint8_t val, void *priv) if (dev->id == 1) break; - if (valxor & 0x18) + if (!dev->id && (valxor & 0x18)) fdc_update_drvrate(dev->fdc, dev->cur_reg & 0x03, (val & 0x18) >> 3); break; } @@ -347,7 +347,7 @@ w83977f_read(uint16_t port, void *priv) ret = dev->cur_reg; else { if (!dev->rw_locked) { - if ((dev->cur_reg == 0xf2) && (ld == 0x00)) + 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]; @@ -506,7 +506,7 @@ w83977f_reset(w83977f_t *dev) dev->dev_regs[10][0xc0] = 0x8f; } - if (next_id == 1) { + if (dev->id == 1) { serial_setup(dev->uart[0], SERIAL3_ADDR, SERIAL3_IRQ); serial_setup(dev->uart[1], SERIAL4_ADDR, SERIAL4_IRQ); } else { diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index cdec4c7c2..f52e78c6c 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -961,8 +961,9 @@ sb_ct1745_mixer_read(uint16_t addr, void *p) /* 0 = none, 1 = digital 8bit or SBMIDI, 2 = digital 16bit, 4 = MPU-401 */ /* 0x02000 DSP v4.04, 0x4000 DSP v4.05, 0x8000 DSP v4.12. I haven't seen this making any difference, but I'm keeping it for now. */ + /* If QEMU is any indication, then the values are actually 0x20, 0x40, and 0x80. */ temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | - ((sb->dsp.sb_irq401) ? 4 : 0) | 0x4000; + ((sb->dsp.sb_irq401) ? 4 : 0) | 0x40; ret = temp; break; diff --git a/src/usb.c b/src/usb.c index 9692068b2..dce1a31af 100644 --- a/src/usb.c +++ b/src/usb.c @@ -146,6 +146,9 @@ ohci_mmio_read(uint32_t addr, void *p) ret = dev->ohci_mmio[addr]; + if (addr == 0x101) + ret = (ret & 0xfe) | (!!mem_a20_key); + return ret; } diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index c04a00b78..7dff04e4a 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -85,6 +85,7 @@ enum S3_METHEUS_86C928, S3_AMI_86C924, S3_TRIO64V2_DX, + S3_TRIO64V2_DX_ONBOARD, S3_PHOENIX_TRIO64VPLUS, S3_PHOENIX_TRIO64VPLUS_ONBOARD, S3_DIAMOND_STEALTH_SE, @@ -6806,6 +6807,11 @@ static void *s3_init(const device_t *info) chip = S3_TRIO64V2; video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); break; + case S3_TRIO64V2_DX_ONBOARD: + bios_fn = NULL; + chip = S3_TRIO64V2; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); + break; default: free(s3); return NULL; @@ -7165,6 +7171,7 @@ static void *s3_init(const device_t *info) break; case S3_TRIO64V2_DX: + case S3_TRIO64V2_DX_ONBOARD: svga->decode_mask = (4 << 20) - 1; s3->id = 0xe1; /*Trio64V2*/ s3->id_ext = s3->id_ext_pci = 0x01; @@ -8094,3 +8101,18 @@ const device_t s3_trio64v2_dx_pci_device = s3_standard_config }; + +const device_t s3_trio64v2_dx_onboard_pci_device = +{ + "S3 Trio64V2/DX On-Board PCI", + DEVICE_PCI, + S3_TRIO64V2_DX_ONBOARD, + s3_init, + s3_close, + NULL, + { NULL }, + s3_speed_changed, + s3_force_redraw, + s3_standard_config +}; + diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 9b457326e..32865df01 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -242,18 +242,9 @@ video_reset_close(void) } -void -video_reset(int card) +static void +video_prepare(void) { - /* This is needed to avoid duplicate resets. */ - if ((video_get_type() != VIDEO_FLAG_TYPE_NONE) && was_reset) - return; - - vid_table_log("VIDEO: reset (gfxcard=%d, internal=%d)\n", - card, (machines[machine].flags & MACHINE_VIDEO)?1:0); - - loadfont("roms/video/mda/mda.rom", 0); - /* Reset (deallocate) the video font arrays. */ if (fontdatksc5601) { free(fontdatksc5601); @@ -267,14 +258,39 @@ video_reset(int card) /* Reset the blend. */ herc_blend = 0; + /* Do an inform on the default values, so that that there's some sane values initialized + even if the device init function does not do an inform of its own. */ + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_default); +} + + +void +video_pre_reset(int card) +{ + if ((card == VID_NONE) || \ + (card == VID_INTERNAL) || (machines[machine].flags & MACHINE_VIDEO_ONLY)) + video_prepare(); +} + + +void +video_reset(int card) +{ + /* This is needed to avoid duplicate resets. */ + if ((video_get_type() != VIDEO_FLAG_TYPE_NONE) && was_reset) + return; + + vid_table_log("VIDEO: reset (gfxcard=%d, internal=%d)\n", + card, (machines[machine].flags & MACHINE_VIDEO)?1:0); + + loadfont("roms/video/mda/mda.rom", 0); + /* Do not initialize internal cards here. */ if (!(card == VID_NONE) && \ !(card == VID_INTERNAL) && !(machines[machine].flags & MACHINE_VIDEO_ONLY)) { vid_table_log("VIDEO: initializing '%s'\n", video_cards[card].name); - /* Do an inform on the default values, so that that there's some sane values initialized - even if the device init function does not do an inform of its own. */ - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_default); + video_prepare(); /* Initialize the video card. */ device_add(video_cards[card].device); diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index b961fbf78..e067d7a4b 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -88,10 +88,12 @@ enum { TGUI_9400CXI = 0, TGUI_9440, - TGUI_9660, - TGUI_9680 + TGUI_9660, + TGUI_9680 }; +#define ONBOARD 0x0100 + typedef struct tgui_t { mem_mapping_t linear_mapping; @@ -162,6 +164,8 @@ typedef struct tgui_t volatile int write_blitter; void *i2c, *ddc; + + int has_bios; } tgui_t; video_timings_t timing_tgui_vlb = {VIDEO_BUS, 4, 8, 16, 4, 8, 16}; @@ -933,13 +937,13 @@ uint8_t tgui_pci_read(int func, int addr, void *p) case 0x16: return tgui->mmio_base >> 16; case 0x17: return tgui->mmio_base >> 24; - case 0x30: return (tgui->pci_regs[0x30] & 0x01); /*BIOS ROM address*/ - case 0x31: return 0x00; - case 0x32: return tgui->pci_regs[0x32]; - case 0x33: return tgui->pci_regs[0x33]; - - case 0x3c: return tgui->int_line; - case 0x3d: return PCI_INTA; + case 0x30: return tgui->has_bios ? (tgui->pci_regs[0x30] & 0x01) : 0x00; /*BIOS ROM address*/ + case 0x31: return 0x00; + case 0x32: return tgui->has_bios ? tgui->pci_regs[0x32] : 0x00; + case 0x33: return tgui->has_bios ? tgui->pci_regs[0x33] : 0x00; + + case 0x3c: return tgui->int_line; + case 0x3d: return PCI_INTA; } return 0; } @@ -993,23 +997,25 @@ void tgui_pci_write(int func, int addr, uint8_t val, void *p) tgui->mmio_base = (tgui->mmio_base & 0x00e00000) | (val << 24); tgui_recalcmapping(tgui); break; - - case 0x30: case 0x32: case 0x33: - tgui->pci_regs[addr] = val; - if (tgui->pci_regs[0x30] & 0x01) - { - uint32_t biosaddr = (tgui->pci_regs[0x32] << 16) | (tgui->pci_regs[0x33] << 24); - mem_mapping_set_addr(&tgui->bios_rom.mapping, biosaddr, 0x8000); - } - else - { - mem_mapping_disable(&tgui->bios_rom.mapping); - } - return; - - case 0x3c: - tgui->int_line = val; - return; + + case 0x30: case 0x32: case 0x33: + if (tgui->has_bios) { + tgui->pci_regs[addr] = val; + if (tgui->pci_regs[0x30] & 0x01) + { + uint32_t biosaddr = (tgui->pci_regs[0x32] << 16) | (tgui->pci_regs[0x33] << 24); + mem_mapping_set_addr(&tgui->bios_rom.mapping, biosaddr, 0x8000); + } + else + { + mem_mapping_disable(&tgui->bios_rom.mapping); + } + } + return; + + case 0x3c: + tgui->int_line = val; + return; } } @@ -2936,16 +2942,15 @@ tgui_mmio_read_l(uint32_t addr, void *p) static void *tgui_init(const device_t *info) { const char *bios_fn; - int type = info->local; tgui_t *tgui = malloc(sizeof(tgui_t)); - svga_t *svga = &tgui->svga; + svga_t *svga = &tgui->svga; memset(tgui, 0, sizeof(tgui_t)); tgui->vram_size = device_get_config_int("memory") << 20; tgui->vram_mask = tgui->vram_size - 1; - tgui->type = type; + tgui->type = info->local & 0xff; tgui->pci = !!(info->flags & DEVICE_PCI); @@ -2954,7 +2959,7 @@ static void *tgui_init(const device_t *info) bios_fn = ROM_TGUI_9400CXI; break; case TGUI_9440: - bios_fn = ROM_TGUI_9440; + bios_fn = (info->local & ONBOARD) ? NULL : ROM_TGUI_9440; break; case TGUI_9660: case TGUI_9680: @@ -2965,7 +2970,10 @@ static void *tgui_init(const device_t *info) return NULL; } - rom_init(&tgui->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + tgui->has_bios = (bios_fn != NULL); + + if (tgui->has_bios) + rom_init(&tgui->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (tgui->pci) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tgui_pci); @@ -2979,28 +2987,39 @@ static void *tgui_init(const device_t *info) NULL); if (tgui->type == TGUI_9400CXI) - svga->ramdac = device_add(&tkd8001_ramdac_device); + svga->ramdac = device_add(&tkd8001_ramdac_device); mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, tgui_accel_write_fb_b, tgui_accel_write_fb_w, tgui_accel_write_fb_l, NULL, MEM_MAPPING_EXTERNAL, svga); mem_mapping_add(&tgui->accel_mapping, 0, 0, tgui_accel_read, tgui_accel_read_w, tgui_accel_read_l, tgui_accel_write, tgui_accel_write_w, tgui_accel_write_l, NULL, MEM_MAPPING_EXTERNAL, tgui); - if (tgui->type >= TGUI_9440) - mem_mapping_add(&tgui->mmio_mapping, 0, 0, tgui_mmio_read, tgui_mmio_read_w, tgui_mmio_read_l, tgui_mmio_write, tgui_mmio_write_w, tgui_mmio_write_l, NULL, MEM_MAPPING_EXTERNAL, tgui); + if (tgui->type >= TGUI_9440) + mem_mapping_add(&tgui->mmio_mapping, 0, 0, tgui_mmio_read, tgui_mmio_read_w, tgui_mmio_read_l, tgui_mmio_write, tgui_mmio_write_w, tgui_mmio_write_l, NULL, MEM_MAPPING_EXTERNAL, tgui); mem_mapping_disable(&tgui->accel_mapping); - mem_mapping_disable(&tgui->mmio_mapping); + mem_mapping_disable(&tgui->mmio_mapping); - tgui_set_io(tgui); + tgui_set_io(tgui); - if (tgui->pci && (tgui->type >= TGUI_9440)) + if (tgui->pci && (tgui->type >= TGUI_9440)) { + if (tgui->has_bios) tgui->card = pci_add_card(PCI_ADD_VIDEO, tgui_pci_read, tgui_pci_write, tgui); + else + tgui->card = pci_add_card(PCI_ADD_VIDEO | PCI_ADD_STRICT, tgui_pci_read, tgui_pci_write, tgui); + } - tgui->pci_regs[PCI_REG_COMMAND] = 7; + tgui->pci_regs[PCI_REG_COMMAND] = 7; + if (tgui->has_bios) { tgui->pci_regs[0x30] = 0x00; tgui->pci_regs[0x32] = 0x0c; tgui->pci_regs[0x33] = 0x00; + } - if (tgui->type >= TGUI_9440) - svga->packed_chain4 = 1; + if (tgui->type >= TGUI_9440) + svga->packed_chain4 = 1; + + if (tgui->type >= TGUI_9660) { + tgui->i2c = i2c_gpio_init("ddc_tgui"); + tgui->ddc = ddc_init(i2c_gpio_get_bus(tgui->i2c)); + } return tgui; } @@ -3144,6 +3163,20 @@ const device_t tgui9440_pci_device = tgui9440_config }; +const device_t tgui9440_onboard_pci_device = +{ + "Trident TGUI 9440AGi On-Board PCI", + DEVICE_PCI, + TGUI_9440 | ONBOARD, + tgui_init, + tgui_close, + NULL, + { NULL }, + tgui_speed_changed, + tgui_force_redraw, + tgui9440_config +}; + const device_t tgui9660_pci_device = { "Trident TGUI 9660XGi PCI", diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index ddafd98d0..8414f538f 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -45,12 +45,6 @@ ifeq ($(DEV_BUILD), y) ifndef HEDAKA HEDAKA := y endif - ifndef I450KX - I450KX := y - endif - ifndef M154X - M154X := y - endif ifndef LASERXT LASERXT := y endif @@ -75,12 +69,6 @@ ifeq ($(DEV_BUILD), y) ifndef SIO_DETECT SIO_DETECT := y endif - ifndef M154X - M154X := y - endif - ifndef M6117 - M6117 := y - endif ifndef VGAWONDER VGAWONDER := y endif @@ -96,6 +84,9 @@ ifeq ($(DEV_BUILD), y) ifndef OLIVETTI OLIVETTI := y endif + ifndef NEW_KBC + NEW_KBC := n + endif else ifndef DEBUG DEBUG := n @@ -115,15 +106,9 @@ else ifndef HEDAKA HEDAKA := n endif - ifndef I450KX - I450KX := n - endif ifndef LASERXT LASERXT := n endif - ifndef M154X - M154X := n - endif ifndef MGA MGA := n endif @@ -145,12 +130,6 @@ else ifndef SIO_DETECT SIO_DETECT := n endif - ifndef M154X - M154X := n - endif - ifndef M6117 - M6117 := n - endif ifndef VGAWONDER VGAWONDER := n endif @@ -166,6 +145,9 @@ else ifndef OLIVETTI OLIVETTI := n endif + ifndef NEW_KBC + NEW_KBC := n + endif endif # Defaults for several build options (possibly defined in a chained file.) @@ -347,7 +329,7 @@ else endif endif ifeq ($(DEBUG), y) - DFLAGS += -ggdb -DDEBUG + DFLAGS += -ggdb -DDEBUG -DUSE_ACYCS AOPTIM := ifndef COPTIM COPTIM := -Og @@ -513,11 +495,6 @@ ifeq ($(HEDAKA), y) OPTS += -DUSE_HEDAKA endif -ifeq ($(I450KX), y) -OPTS += -DUSE_I450KX -DEVBROBJ += intel_i450kx.o -endif - ifeq ($(LASERXT), y) OPTS += -DUSE_LASERXT DEVBROBJ += m_xt_laserxt.o @@ -556,16 +533,6 @@ OPTS += -DUSE_SIO_DETECT DEVBROBJ += sio_detect.o endif -ifeq ($(M154X), y) -OPTS += -DUSE_M154X -DEVBROBJ += ali1531.o ali1543.o -endif - -ifeq ($(M6117), y) -OPTS += -DUSE_M6117 -DEVBROBJ += ali6117.o -endif - ifeq ($(VGAWONDER), y) OPTS += -DUSE_VGAWONDER endif @@ -597,8 +564,8 @@ CXXFLAGS := $(CFLAGS) ######################################################################### # Create the (final) list of objects to build. # ######################################################################### -MAINOBJ := 86box.o config.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ - nmi.o pic.o pit.o port_92.o ppi.o pci.o mca.o \ +MAINOBJ := 86box.o config.o log.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ + nmi.o pic.o pit.o port_6x.o port_92.o ppi.o pci.o mca.o \ usb.o device.o nvr.o nvr_at.o nvr_ps2.o \ $(VNCOBJ) @@ -610,13 +577,21 @@ CPUOBJ := $(DYNARECOBJ) \ 808x.o 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o \ x86seg.o x87.o x87_timings.o -CHIPSETOBJ := 82c100.o acc2168.o cs8230.o ali1217.o ali1429.o ali1489.o et6000.o headland.o intel_82335.o cs4031.o \ - intel_420ex.o intel_4x0.o intel_sio.o intel_piix.o ioapic.o \ - neat.o opti495.o opti822.o opti895.o opti5x7.o scamp.o scat.o via_vt82c49x.o via_vt82c505.o \ - gc100.o \ - sis_85c310.o sis_85c4xx.o sis_85c496.o sis_85c50x.o sis_5511.o sis_5571.o stpc.o opti283.o opti291.o \ - umc_8886.o umc_8890.o umc_hb4.o \ - via_apollo.o via_pipc.o wd76c10.o vl82c480.o +CHIPSETOBJ := 82c100.o acc2168.o \ + contaq_82c59x.o \ + cs4031.o cs8230.o \ + ali1429.o ali1489.o ali1531.o ali1541.o ali1543.o ali1621.o ali6117.o \ + gc100.o headland.o \ + ims8848.o intel_82335.o intel_420ex.o intel_4x0.o intel_i450kx.o intel_sio.o intel_piix.o \ + ioapic.o \ + neat.o \ + opti283.o opti291.o opti391.o opti495.o opti822.o opti895.o opti5x7.o \ + scamp.o scat.o \ + stpc.o \ + wd76c10.o vl82c480.o \ + umc_8886.o umc_hb4.o \ + via_vt82c49x.o via_vt82c505.o via_apollo.o via_pipc.o \ + sis_85c310.o sis_85c4xx.o sis_85c496.o sis_85c50x.o sis_5511.o sis_5571.o MCHOBJ := machine.o machine_table.o \ m_xt.o m_xt_compaq.o \ @@ -632,24 +607,37 @@ MCHOBJ := machine.o machine_table.o \ m_ps2_isa.o m_ps2_mca.o \ m_at_compaq.o \ m_at_286_386sx.o m_at_386dx_486.o \ - m_at_socket4_5.o m_at_socket7.o m_at_sockets7.o \ + m_at_socket4.o m_at_socket5.o m_at_socket7_3v.o m_at_socket7.o m_at_sockets7.o \ m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o \ m_at_misc.o +ifeq ($(NEW_KBC), y) DEVOBJ := bugger.o cartridge.o cassette.o hasp.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o \ ibm_5161.o isamem.o isartc.o lpt.o pci_bridge.o postcard.o serial.o \ - vpc2007.o clock_ics9xxx.o isapnp.o \ - i2c.o i2c_gpio.o smbus_piix4.o \ + clock_ics9xxx.o isapnp.o \ + i2c.o i2c_gpio.o smbus_ali7101.o smbus_piix4.o \ + keyboard.o \ + keyboard_xt.o kbc_at.o kbd_at.o \ + mouse.o \ + mouse_bus.o \ + mouse_serial.o mouse_ps2.o \ + phoenix_486_jumper.o +else +DEVOBJ := bugger.o cartridge.o cassette.o hasp.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o \ + ibm_5161.o isamem.o isartc.o lpt.o pci_bridge.o postcard.o serial.o \ + clock_ics9xxx.o isapnp.o \ + i2c.o i2c_gpio.o smbus_ali7101.o smbus_piix4.o \ keyboard.o \ keyboard_xt.o keyboard_at.o \ mouse.o \ mouse_bus.o \ mouse_serial.o mouse_ps2.o \ phoenix_486_jumper.o +endif SIOOBJ := sio_acc3221.o \ - sio_f82c710.o sio_82091aa.o sio_fdc37c651.o \ - sio_fdc37c661.o sio_fdc37c66x.o sio_fdc37c669.o sio_fdc37c93x.o sio_fdc37m60x.o \ + sio_f82c710.o sio_82091aa.o sio_fdc37c6xx.o \ + sio_fdc37c67x.o sio_fdc37c669.o sio_fdc37c93x.o sio_fdc37m60x.o \ sio_it8661f.o \ sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87310.o sio_pc87311.o sio_pc87332.o \ sio_prime3b.o sio_prime3c.o \ @@ -676,7 +664,8 @@ HDDOBJ := hdd.o \ hdc_esdi_at.o hdc_esdi_mca.o \ hdc_xtide.o hdc_ide.o \ hdc_ide_opti611.o \ - hdc_ide_cmd640.o hdc_ide_sff8038i.o + hdc_ide_cmd640.o hdc_ide_cmd646.o \ + hdc_ide_sff8038i.o MINIVHDOBJ := cwalk.o libxml2_encoding.o minivhd_convert.o \ minivhd_create.o minivhd_io.o minivhd_manage.o \ diff --git a/src/win/win.c b/src/win/win.c index a6845424c..7339947c2 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -548,7 +548,8 @@ main_thread(void *param) frames = 0; } } else /* Just so we dont overload the host OS. */ - Sleep(1); + Sleep((drawits < -1) ? 1 : 0); + // Sleep(1); /* If needed, handle a screen resize. */ if (doresize && !video_fullscreen && !is_quit) { diff --git a/src/win/win_joystick_rawinput.c b/src/win/win_joystick_rawinput.c index c4f947bac..be808fc47 100644 --- a/src/win/win_joystick_rawinput.c +++ b/src/win/win_joystick_rawinput.c @@ -56,7 +56,7 @@ typedef struct { HANDLE hdevice; PHIDP_PREPARSED_DATA data; - USAGE usage_button[128]; + USAGE usage_button[256]; struct raw_axis_t { USAGE usage; diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 3f3b4511d..d7fdb3816 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -969,6 +969,8 @@ win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) win_settings_machine_recalc_machine(hdlg); } + + free(lptsTemp); } break; case IDC_COMBO_MACHINE: