diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a2bead497..49025d4dd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -63,6 +63,11 @@ if(MINGW) set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".dll.a") endif() +if(APPLE) + # Force using the newest library if it's installed by homebrew + set(CMAKE_FIND_FRAMEWORK LAST) +endif() + find_package(Freetype REQUIRED) include_directories(${FREETYPE_INCLUDE_DIRS}) @@ -77,7 +82,11 @@ if(MINGW) elseif(WIN32) target_link_libraries(86Box SDL2::SDL2) else() - target_link_libraries(86Box ${SDL2_LIBRARIES}) + if (TARGET SDL2::SDL2) + target_link_libraries(86Box SDL2::SDL2) + else() + target_link_libraries(86Box ${SDL2_LIBRARIES}) + endif() endif() find_package(PNG REQUIRED) diff --git a/src/acpi.c b/src/acpi.c index ef336105f..9b0ba6734 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -62,13 +62,10 @@ acpi_log(const char *fmt, ...) #endif -static void -acpi_update_irq(void *priv) +void +acpi_update_irq(acpi_t *dev) { - acpi_t *dev = (acpi_t *) priv; - int sci_level; - - sci_level = (dev->regs.pmsts & dev->regs.pmen) & (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN); + int sci_level = (dev->regs.pmsts & dev->regs.pmen) & (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN); if (dev->vendor == VEN_SMC) sci_level |= (dev->regs.pmsts & BM_STS); @@ -86,11 +83,9 @@ acpi_update_irq(void *priv) } -static void -acpi_raise_smi(void *priv) +void +acpi_raise_smi(acpi_t *dev) { - 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)) { @@ -529,10 +524,11 @@ acpi_reg_read_via_596b(int size, uint16_t addr, void *p) shift32 = (addr & 3) << 3; switch (addr) { - case 0x42: - /* GPIO port Output Value */ - if (size == 1) - ret = dev->regs.gpio_val & 0x13; + case 0x40: /* Extended I/O Trap Status (686A/B) */ + ret = dev->regs.extiotrapsts; + break; + case 0x42: /* Extended I/O Trap Enable (686A/B) */ + ret = dev->regs.extiotrapen; break; case 0x44: case 0x45: /* External SMI Input Value */ @@ -643,37 +639,47 @@ acpi_reg_write_common_regs(int size, uint16_t addr, uint8_t val, void *p) case 0x04: case 0x05: /* PMCNTRL - Power Management Control Register (IO) */ if ((addr == 0x05) && (val & 0x20)) { - sus_typ = (val >> 2) & 7; - switch (sus_typ) { - case 0: - /* Soft power off. */ - plat_power_off(); - break; - case 1: + sus_typ = dev->suspend_types[(val >> 2) & 7]; + + if (sus_typ & SUS_POWER_OFF) { + /* Soft power off. */ + plat_power_off(); + return; + } + + if (sus_typ & SUS_SUSPEND) { + if (sus_typ & SUS_NVR) { /* Suspend to RAM. */ nvr_reg_write(0x000f, 0xff, dev->nvr); + } - /* Do a hard reset. */ + if (sus_typ & SUS_RESET_PCI) device_reset_all_pci(); + if (sus_typ & SUS_RESET_CPU) cpu_alt_reset = 0; + if (sus_typ & SUS_RESET_PCI) { pci_reset(); keyboard_at_reset(); mem_a20_alt = 0; mem_a20_recalc(); + } + if (sus_typ & (SUS_RESET_CPU | SUS_RESET_CACHE)) flushmmucache(); + if (sus_typ & SUS_RESET_CPU) resetx86(); - break; - default: - dev->regs.pmcntrl = ((dev->regs.pmcntrl & ~(0xff << shift16)) | (val << shift16)) & 0x3f07 /* 0x3c07 */; - break; + + /* Since the UI doesn't have a power button at the moment, pause emulation, + then trigger a resume event so that the system resumes after unpausing. */ + plat_pause(1); + timer_set_delay_u64(&dev->resume_timer, 50 * TIMER_USEC); } - } else - dev->regs.pmcntrl = ((dev->regs.pmcntrl & ~(0xff << shift16)) | (val << shift16)) & 0x3f07 /* 0x3c07 */; + } + dev->regs.pmcntrl = ((dev->regs.pmcntrl & ~(0xff << shift16)) | (val << shift16)) & 0x3f07 /* 0x3c07 */; break; } } @@ -807,6 +813,8 @@ acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p) case 0x2c: case 0x2d: case 0x2e: case 0x2f: /* DEVCTL - Device Control Register (IO) */ dev->regs.devctl = ((dev->regs.devctl & ~(0xff << shift32)) | (val << shift32)) & 0x0fffffff; + if (dev->trap_update) + dev->trap_update(dev->trap_priv); break; case 0x34: case 0x35: case 0x36: case 0x37: /* GPOREG - General Purpose Output Register (IO) */ @@ -947,14 +955,6 @@ acpi_reg_write_via_common(int size, uint16_t addr, uint8_t val, void *p) /* Power Supply Control */ dev->regs.pscntrl = ((dev->regs.pscntrl & ~(0xff << shift16)) | (val << shift16)) & 0x0701; break; - case 0x28: case 0x29: - /* GLBSTS - Global Status Register (IO) */ - dev->regs.glbsts &= ~((val << shift16) & 0x007f); - break; - case 0x2a: case 0x2b: - /* GLBEN - Global Enable Register (IO) */ - dev->regs.glben = ((dev->regs.glben & ~(0xff << shift16)) | (val << shift16)) & 0x007f; - break; case 0x2c: /* GLBCTL - Global Control Register (IO) */ dev->regs.glbctl = (dev->regs.glbctl & ~0xff) | (val & 0xff); @@ -981,14 +981,6 @@ acpi_reg_write_via_common(int size, uint16_t addr, uint8_t val, void *p) acpi_raise_smi(dev); } break; - case 0x30: case 0x31: case 0x32: case 0x33: - /* Primary Activity Detect Status */ - dev->regs.padsts &= ~((val << shift32) & 0x000000fd); - break; - case 0x34: case 0x35: case 0x36: case 0x37: - /* Primary Activity Detect Enable */ - dev->regs.paden = ((dev->regs.paden & ~(0xff << shift32)) | (val << shift32)) & 0x000000fd; - break; case 0x38: case 0x39: case 0x3a: case 0x3b: /* GP Timer Reload Enable */ dev->regs.gptren = ((dev->regs.gptren & ~(0xff << shift32)) | (val << shift32)) & 0x000000d9; @@ -1020,13 +1012,32 @@ static void acpi_reg_write_via(int size, uint16_t addr, uint8_t val, void *p) { acpi_t *dev = (acpi_t *) p; - int shift16; + int shift16, shift32; addr &= 0xff; acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val); shift16 = (addr & 1) << 3; + shift32 = (addr & 3) << 3; switch (addr) { + case 0x28: case 0x29: + /* GLBSTS - Global Status Register (IO) */ + dev->regs.glbsts &= ~((val << shift16) & 0x007f); + break; + case 0x2a: case 0x2b: + /* GLBEN - Global Enable Register (IO) */ + dev->regs.glben = ((dev->regs.glben & ~(0xff << shift16)) | (val << shift16)) & 0x007f; + break; + case 0x30: case 0x31: case 0x32: case 0x33: + /* Primary Activity Detect Status */ + dev->regs.padsts &= ~((val << shift32) & 0x000000fd); + break; + case 0x34: case 0x35: case 0x36: case 0x37: + /* Primary Activity Detect Enable */ + dev->regs.paden = ((dev->regs.paden & ~(0xff << shift32)) | (val << shift32)) & 0x000000fd; + if (dev->trap_update) + dev->trap_update(dev->trap_priv); + break; case 0x40: /* GPIO Direction Control */ if (size == 1) { @@ -1056,17 +1067,37 @@ static void acpi_reg_write_via_596b(int size, uint16_t addr, uint8_t val, void *p) { acpi_t *dev = (acpi_t *) p; - int shift32; + int shift16, shift32; addr &= 0x7f; acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val); + shift16 = (addr & 1) << 3; shift32 = (addr & 3) << 3; switch (addr) { - case 0x42: - /* GPIO port Output Value */ - if (size == 1) - dev->regs.gpio_val = val & 0x13; + case 0x28: case 0x29: + /* GLBSTS - Global Status Register (IO) */ + dev->regs.glbsts &= ~((val << shift16) & 0xfdff); + break; + case 0x2a: case 0x2b: + /* GLBEN - Global Enable Register (IO) */ + dev->regs.glben = ((dev->regs.glben & ~(0xff << shift16)) | (val << shift16)) & 0xfdff; + break; + case 0x30: case 0x31: case 0x32: case 0x33: + /* Primary Activity Detect Status */ + dev->regs.padsts &= ~((val << shift32) & 0x000007ff); + break; + case 0x34: case 0x35: case 0x36: case 0x37: + /* Primary Activity Detect Enable */ + dev->regs.paden = ((dev->regs.paden & ~(0xff << shift32)) | (val << shift32)) & 0x000007ff; + if (dev->trap_update) + dev->trap_update(dev->trap_priv); + break; + case 0x40: /* Extended I/O Trap Status (686A/B) */ + dev->regs.extiotrapsts &= ~(val & 0x13); + break; + case 0x42: /* Extended I/O Trap Enable (686A/B) */ + dev->regs.extiotrapen = val & 0x13; break; case 0x4c: case 0x4d: case 0x4e: case 0x4f: /* GPO Port Output Value */ @@ -1173,9 +1204,9 @@ acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *p) { acpi_t *dev = (acpi_t *) p; - if (dev->vendor == VEN_ALI) + if (dev->vendor == VEN_ALI) acpi_reg_write_ali(size, addr, val, p); - if (dev->vendor == VEN_VIA) + else if (dev->vendor == VEN_VIA) acpi_reg_write_via(size, addr, val, p); else if (dev->vendor == VEN_VIA_596B) acpi_reg_write_via_596b(size, addr, val, p); @@ -1255,7 +1286,7 @@ acpi_reg_read(uint16_t addr, void *p) static uint32_t -acpi_aux_read_readl(uint16_t addr, void *p) +acpi_aux_reg_readl(uint16_t addr, void *p) { uint32_t ret = 0x00000000; @@ -1264,33 +1295,35 @@ acpi_aux_read_readl(uint16_t addr, void *p) ret |= (acpi_aux_reg_read_common(4, addr + 2, p) << 16); ret |= (acpi_aux_reg_read_common(4, addr + 3, p) << 24); - acpi_log("ACPI: Read L %08X from %04X\n", ret, addr); + acpi_log("ACPI: Read Aux L %08X from %04X\n", ret, addr); return ret; } static uint16_t -acpi_aux_read_readw(uint16_t addr, void *p) +acpi_aux_reg_readw(uint16_t addr, void *p) { uint16_t ret = 0x0000; ret = acpi_aux_reg_read_common(2, addr, p); ret |= (acpi_aux_reg_read_common(2, addr + 1, p) << 8); - acpi_log("ACPI: Read W %08X from %04X\n", ret, addr); + acpi_log("ACPI: Read Aux W %04X from %04X\n", ret, addr); return ret; } static uint8_t -acpi_aux_read_read(uint16_t addr, void *p) +acpi_aux_reg_read(uint16_t addr, void *p) { uint8_t ret = 0x00; ret = acpi_aux_reg_read_common(1, addr, p); + acpi_log("ACPI: Read Aux B %02X from %04X\n", ret, addr); + return ret; } @@ -1329,6 +1362,8 @@ acpi_reg_write(uint16_t addr, uint8_t val, void *p) static void acpi_aux_reg_writel(uint16_t addr, uint32_t val, void *p) { + acpi_log("ACPI: Write Aux L %08X to %04X\n", val, addr); + acpi_aux_reg_write_common(4, addr, val & 0xff, p); acpi_aux_reg_write_common(4, addr + 1, (val >> 8) & 0xff, p); acpi_aux_reg_write_common(4, addr + 2, (val >> 16) & 0xff, p); @@ -1339,6 +1374,8 @@ acpi_aux_reg_writel(uint16_t addr, uint32_t val, void *p) static void acpi_aux_reg_writew(uint16_t addr, uint16_t val, void *p) { + acpi_log("ACPI: Write Aux W %04X to %04X\n", val, addr); + acpi_aux_reg_write_common(2, addr, val & 0xff, p); acpi_aux_reg_write_common(2, addr + 1, (val >> 8) & 0xff, p); } @@ -1347,6 +1384,8 @@ acpi_aux_reg_writew(uint16_t addr, uint16_t val, void *p) static void acpi_aux_reg_write(uint16_t addr, uint8_t val, void *p) { + acpi_log("ACPI: Write Aux B %02X to %04X\n", val, addr); + acpi_aux_reg_write_common(1, addr, val, p); } @@ -1376,6 +1415,8 @@ acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en) break; } + acpi_log("ACPI: Update I/O %04X to %04X (%sabled)\n", dev->io_base, base, chipset_en ? "en" : "dis"); + if (dev->io_base != 0x0000) { io_removehandler(dev->io_base, size, acpi_reg_read, acpi_reg_readw, acpi_reg_readl, @@ -1395,17 +1436,30 @@ acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en) void acpi_update_aux_io_mapping(acpi_t *dev, uint32_t base, int chipset_en) { + int size; + + switch (dev->vendor) { + case VEN_SMC: + size = 0x008; + break; + default: + size = 0x000; + break; + } + + acpi_log("ACPI: Update Aux I/O %04X to %04X (%sabled)\n", dev->aux_io_base, base, chipset_en ? "en" : "dis"); + if (dev->aux_io_base != 0x0000) { - io_removehandler(dev->aux_io_base, 0x08, - acpi_aux_read_read, acpi_aux_read_readw, acpi_aux_read_readl, + io_removehandler(dev->aux_io_base, size, + acpi_aux_reg_read, acpi_aux_reg_readw, acpi_aux_reg_readl, acpi_aux_reg_write, acpi_aux_reg_writew, acpi_aux_reg_writel, dev); } dev->aux_io_base = base; if (chipset_en && (dev->aux_io_base != 0x0000)) { - io_sethandler(dev->aux_io_base, 0x08, - acpi_aux_read_read, acpi_aux_read_readw, acpi_aux_read_readl, + io_sethandler(dev->aux_io_base, size, + acpi_aux_reg_read, acpi_aux_reg_readw, acpi_aux_reg_readl, acpi_aux_reg_write, acpi_aux_reg_writew, acpi_aux_reg_writel, dev); } } @@ -1437,6 +1491,20 @@ acpi_timer_count(void *priv) } +static void +acpi_timer_resume(void *priv) +{ + acpi_t *dev = (acpi_t *) priv; + + dev->regs.pmsts |= 0x8000; + + /* Nasty workaround for ASUS P2B-LS and potentially others, where the PMCNTRL + SMI trap handler clears the resume bit before returning control to the OS. */ + if (in_smm) + timer_set_delay_u64(&dev->resume_timer, 50 * TIMER_USEC); +} + + void acpi_init_gporeg(acpi_t *dev, uint8_t val0, uint8_t val1, uint8_t val2, uint8_t val3) { @@ -1501,6 +1569,14 @@ acpi_set_nvr(acpi_t *dev, nvr_t *nvr) } +void +acpi_set_trap_update(acpi_t *dev, void (*update)(void *priv), void *priv) +{ + dev->trap_update = update; + dev->trap_priv = priv; +} + + static void acpi_apm_out(uint16_t port, uint8_t val, void *p) { @@ -1567,22 +1643,18 @@ acpi_reset(void *priv) ASUS P3V4X: - Bit 15: 80-conductor cable on secondary IDE channel (active low) - Bit 5: 80-conductor cable on primary IDE channel (active low) - AEWIN WCF-681: - - Bit 3: 80-conductor cable on primary IDE channel (active low) - - Bit 2: 80-conductor cable on secondary IDE channel (active low) + BCM GT694VA: + - Bit 19: 80-conductor cable on secondary IDE channel (active low) + - Bit 17: 80-conductor cable on primary IDE channel (active low) ASUS CUV4X-LS: - Bit 2: 80-conductor cable on secondary IDE channel (active low) - Bit 1: 80-conductor cable on primary IDE channel (active low) Acorp 6VIA90AP: - Bit 3: 80-conductor cable on secondary IDE channel (active low) - Bit 1: 80-conductor cable on primary IDE channel (active low) */ - dev->regs.gpi_val = 0xffff7fc1; - if (!strcmp(machines[machine].internal_name, "ficva503a")) + dev->regs.gpi_val = 0xfff57fc1; + if (!strcmp(machines[machine].internal_name, "ficva503a") || !strcmp(machines[machine].internal_name, "6via90ap")) dev->regs.gpi_val |= 0x00000004; - if (!strcmp(machines[machine].internal_name, "6via90ap")) - dev->regs.gpi_val |= 0x00000004; - // dev->regs.gpi_val = 0xffffffe5; - // dev->regs.gpi_val = 0x00000004; } /* Power on always generates a resume event. */ @@ -1640,8 +1712,44 @@ acpi_init(const device_t *info) i2c_smbus = i2c_gpio_get_bus(dev->i2c); } + switch (dev->vendor) { + case VEN_ALI: + dev->suspend_types[0] = SUS_POWER_OFF; + dev->suspend_types[1] = SUS_POWER_OFF; + dev->suspend_types[2] = SUS_SUSPEND | SUS_NVR | SUS_RESET_CPU | SUS_RESET_PCI; + dev->suspend_types[3] = SUS_SUSPEND; + break; + + case VEN_VIA: + dev->suspend_types[0] = SUS_POWER_OFF; + dev->suspend_types[2] = SUS_SUSPEND; + break; + + case VEN_VIA_596B: + dev->suspend_types[1] = SUS_SUSPEND | SUS_NVR | SUS_RESET_CPU | SUS_RESET_PCI; + dev->suspend_types[2] = SUS_POWER_OFF; + dev->suspend_types[4] = SUS_SUSPEND; + dev->suspend_types[5] = SUS_SUSPEND | SUS_RESET_CPU; + dev->suspend_types[6] = SUS_SUSPEND | SUS_RESET_CPU | SUS_RESET_PCI; + break; + + case VEN_INTEL: + dev->suspend_types[0] = SUS_POWER_OFF; + dev->suspend_types[1] = SUS_SUSPEND | SUS_NVR | SUS_RESET_CPU | SUS_RESET_PCI; + dev->suspend_types[2] = SUS_SUSPEND | SUS_RESET_CPU; + dev->suspend_types[3] = SUS_SUSPEND | SUS_RESET_CACHE; + dev->suspend_types[4] = SUS_SUSPEND; + break; + + case VEN_SIS: + dev->suspend_types[0] = SUS_SUSPEND; + dev->suspend_types[4] = SUS_POWER_OFF; + break; + } + timer_add(&dev->timer, acpi_timer_count, dev, 0); timer_set_delay_u64(&dev->timer, ACPICONST); + timer_add(&dev->resume_timer, acpi_timer_resume, dev, 0); acpi_reset(dev); @@ -1707,7 +1815,7 @@ const device_t acpi_via_device = const device_t acpi_via_596b_device = { - "VIA ACPI (VT82C596B)", + "VIA VT82C596 ACPI", DEVICE_PCI, VEN_VIA_596B, acpi_init, diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt index 12006a878..f506ecc42 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -16,7 +16,7 @@ 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 sis_5598.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 diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 0b157f4dd..83eabb5e8 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -1507,7 +1507,7 @@ static void regs[0x02] = (regs[0x7a] & 0x02) ? 0x92 : 0x90; regs[0x03] = 0x71; /* 82443BX */ regs[0x06] = (regs[0x7a] & 0x02) ? 0x00 : 0x10; - regs[0x08] = 0x02; + regs[0x08] = (regs[0x7a] & 0x02) ? 0x03 : 0x02; regs[0x10] = 0x08; regs[0x34] = (regs[0x7a] & 0x02) ? 0x00 : 0xa0; if (cpu_busspeed <= 66666667) @@ -1779,7 +1779,6 @@ const device_t i440ex_device = NULL }; - const device_t i440bx_device = { "Intel 82443BX", @@ -1794,6 +1793,20 @@ const device_t i440bx_device = NULL }; +const device_t i440bx_no_agp_device = +{ + "Intel 82443BX", + DEVICE_PCI, + 0x8200 | INTEL_440BX, + i4x0_init, + i4x0_close, + i4x0_reset, + { NULL }, + NULL, + NULL, + NULL +}; + const device_t i440gx_device = { "Intel 82443GX", diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index a865e045a..095dd5d36 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -41,6 +41,8 @@ #include <86box/pic.h> #include <86box/pit.h> #include <86box/port_92.h> +#include <86box/scsi_device.h> +#include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/hdc_ide_sff8038i.h> #include <86box/usb.h> @@ -49,8 +51,14 @@ #include <86box/chipset.h> -typedef struct -{ +typedef struct { + struct _piix_ *dev; + void *trap; + uint8_t dev_id; + uint32_t *sts_reg, *en_reg, sts_mask, en_mask; +} piix_io_trap_t; + +typedef struct _piix_ { uint8_t cur_readout_reg, rev, type, func_shift, max_func, pci_slot, @@ -66,6 +74,7 @@ typedef struct ddma_t * ddma; usb_t * usb; acpi_t * acpi; + piix_io_trap_t io_traps[26]; port_92_t * port_92; pc_timer_t fast_off_timer; } piix_t; @@ -265,6 +274,159 @@ nvr_update_io_mapping(piix_t *dev) } +static void +piix_trap_io(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + piix_io_trap_t *trap = (piix_io_trap_t *) priv; + + if (*(trap->en_reg) & trap->en_mask) { + *(trap->sts_reg) |= trap->sts_mask; + acpi_raise_smi(trap->dev->acpi); + } +} + + +static void +piix_trap_io_ide(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + piix_io_trap_t *trap = (piix_io_trap_t *) priv; + + /* IDE traps are per drive, not per channel. */ + if (ide_drives[trap->dev_id]->selected) + piix_trap_io(size, addr, write, val, priv); +} + + +static void +piix_trap_update_devctl(piix_t *dev, uint8_t trap_id, uint8_t dev_id, + uint32_t devctl_mask, uint8_t enable, + uint16_t addr, uint16_t size) +{ + piix_io_trap_t *trap = &dev->io_traps[trap_id]; + enable = (dev->acpi->regs.devctl & devctl_mask) && enable; + + /* Set up Device I/O traps dynamically. */ + if (enable && !trap->trap) { + trap->dev = dev; + trap->trap = io_trap_add((dev_id <= 3) ? piix_trap_io_ide : piix_trap_io, trap); + trap->dev_id = dev_id; + trap->sts_reg = &dev->acpi->regs.devsts; + trap->sts_mask = 0x00010000 << dev_id; + trap->en_reg = &dev->acpi->regs.devctl; + trap->en_mask = devctl_mask; + } + +#ifdef ENABLE_PIIX_LOG + if ((dev_id == 9) || (dev_id == 10) || (dev_id == 12) || (dev_id == 13)) + piix_log("PIIX: Mapping trap device %d to %04X-%04X (enable %d)\n", dev_id, addr, addr + size - 1, enable); +#endif + + /* Remap I/O trap. */ + io_trap_remap(trap->trap, enable, addr, size); +} + + +static void +piix_trap_update(void *priv) +{ + piix_t *dev = (piix_t *) priv; + uint8_t trap_id = 0, *fregs = dev->regs[3]; + uint16_t temp; + + piix_trap_update_devctl(dev, trap_id++, 0, 0x00000002, 1, 0x1f0, 8); + piix_trap_update_devctl(dev, trap_id++, 0, 0x00000002, 1, 0x3f6, 1); + + piix_trap_update_devctl(dev, trap_id++, 1, 0x00000008, 1, 0x1f0, 8); + piix_trap_update_devctl(dev, trap_id++, 1, 0x00000008, 1, 0x3f6, 1); + + piix_trap_update_devctl(dev, trap_id++, 2, 0x00000020, 1, 0x170, 8); + piix_trap_update_devctl(dev, trap_id++, 2, 0x00000020, 1, 0x376, 1); + + piix_trap_update_devctl(dev, trap_id++, 3, 0x00000080, 1, 0x170, 8); + piix_trap_update_devctl(dev, trap_id++, 3, 0x00000080, 1, 0x376, 1); + + piix_trap_update_devctl(dev, trap_id++, 4, 0x00000200, fregs[0x5c] & 0x08, 0x220 + (0x20 * ((fregs[0x5c] >> 5) & 0x03)), 20); + piix_trap_update_devctl(dev, trap_id++, 4, 0x00000200, fregs[0x5c] & 0x10, 0x200, 8); + piix_trap_update_devctl(dev, trap_id++, 4, 0x00000200, fregs[0x5c] & 0x08, 0x388, 4); + switch (fregs[0x5d] & 0x03) { + case 0x00: temp = 0x530; break; + case 0x01: temp = 0x604; break; + case 0x02: temp = 0xe80; break; + default: temp = 0xf40; break; + } + piix_trap_update_devctl(dev, trap_id++, 4, 0x00000200, fregs[0x5c] & 0x80, temp, 8); + piix_trap_update_devctl(dev, trap_id++, 4, 0x00000200, fregs[0x5c] & 0x01, 0x300 + (0x10 * ((fregs[0x5c] >> 1) & 0x03)), 4); + + piix_trap_update_devctl(dev, trap_id++, 5, 0x00000800, fregs[0x51] & 0x10, 0x370 + (0x80 * !(fregs[0x63] & 0x10)), 6); + piix_trap_update_devctl(dev, trap_id++, 5, 0x00000800, fregs[0x51] & 0x10, 0x377 + (0x80 * !(fregs[0x63] & 0x10)), 1); + + switch (fregs[0x67] & 0x07) { + case 0x00: temp = 0x3f8; break; + case 0x01: temp = 0x2f8; break; + case 0x02: temp = 0x220; break; + case 0x03: temp = 0x228; break; + case 0x04: temp = 0x238; break; + case 0x05: temp = 0x2e8; break; + case 0x06: temp = 0x338; break; + default: temp = 0x3e8; break; + } + piix_trap_update_devctl(dev, trap_id++, 6, 0x00002000, fregs[0x51] & 0x40, temp, 8); + + switch (fregs[0x67] & 0x70) { + case 0x00: temp = 0x3f8; break; + case 0x10: temp = 0x2f8; break; + case 0x20: temp = 0x220; break; + case 0x30: temp = 0x228; break; + case 0x40: temp = 0x238; break; + case 0x50: temp = 0x2e8; break; + case 0x60: temp = 0x338; break; + default: temp = 0x3e8; break; + } + piix_trap_update_devctl(dev, trap_id++, 7, 0x00008000, fregs[0x52] & 0x01, temp, 8); + + switch (fregs[0x63] & 0x06) { + case 0x00: + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x3bc, 4); + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x7bc, 3); + break; + + case 0x02: + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x378, 8); + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x778, 3); + break; + + case 0x04: + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x278, 8); + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0x678, 3); + break; + + default: + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0, 0); + piix_trap_update_devctl(dev, trap_id++, 8, 0x00020000, fregs[0x52] & 0x04, 0, 0); + break; + } + + temp = fregs[0x62] & 0x0f; + piix_trap_update_devctl(dev, trap_id++, 9, 0x00080000, fregs[0x62] & 0x20, (fregs[0x60] | (fregs[0x61] << 8)) & ~temp, temp + 1); + + temp = fregs[0x66] & 0x0f; + piix_trap_update_devctl(dev, trap_id++, 10, 0x00200000, fregs[0x66] & 0x20, (fregs[0x64] | (fregs[0x65] << 8)) & ~temp, temp + 1); + + piix_trap_update_devctl(dev, trap_id++, 11, 0x00800000, fregs[0x5f] & 0x04, 0x3b0, 48); + piix_trap_update_devctl(dev, trap_id++, 11, 0x00800000, fregs[0x5f] & 0x10, 0x60, 1); + piix_trap_update_devctl(dev, trap_id++, 11, 0x00800000, fregs[0x5f] & 0x10, 0x64, 1); + /* [A0000:BFFFF] memory trap not implemented. */ + + temp = fregs[0x6a] & 0x0f; + piix_trap_update_devctl(dev, trap_id++, 12, 0x01000000, fregs[0x6a] & 0x10, (fregs[0x68] | (fregs[0x69] << 8)) & ~temp, temp + 1); + /* Programmable memory trap not implemented. */ + + temp = fregs[0x72] & 0x0f; + piix_trap_update_devctl(dev, trap_id++, 13, 0x02000000, fregs[0x72] & 0x10, (fregs[0x70] | (fregs[0x71] << 8)) & ~temp, temp + 1); + /* Programmable memory trap not implemented. */ +} + + static void piix_write(int func, int addr, uint8_t val, void *priv) { @@ -835,6 +997,10 @@ piix_write(int func, int addr, uint8_t val, void *priv) case 0xd3: case 0xd4: case 0xd5: fregs[addr] = val; + if ((addr == 0x5c) || (addr == 0x60) || (addr == 0x61) || (addr == 0x62) || + (addr == 0x64) || (addr == 0x65) || (addr == 0x68) || (addr == 0x69) || + (addr == 0x70) || (addr == 0x71)) + piix_trap_update(dev); break; case 0x4a: fregs[addr] = val & 0x73; @@ -854,9 +1020,11 @@ piix_write(int func, int addr, uint8_t val, void *priv) break; case 0x51: fregs[addr] = val & 0x58; + piix_trap_update(dev); break; case 0x52: fregs[addr] = val & 0x7f; + piix_trap_update(dev); break; case 0x58: fregs[addr] = val & 0x77; @@ -867,12 +1035,16 @@ piix_write(int func, int addr, uint8_t val, void *priv) break; case 0x63: fregs[addr] = val & 0xf7; + piix_trap_update(dev); break; case 0x66: fregs[addr] = val & 0xef; + piix_trap_update(dev); break; case 0x6a: case 0x72: case 0x7a: case 0x7e: fregs[addr] = val & 0x1f; + if ((addr == 0x6a) || (addr == 0x72)) + piix_trap_update(dev); break; case 0x6d: case 0x75: fregs[addr] = val & 0x80; @@ -900,7 +1072,7 @@ piix_read(int func, int addr, void *priv) /* Return on unsupported function. */ if ((func <= dev->max_func) || ((func == 1) && (dev->max_func == 0))) { - fregs = (uint8_t *) dev->regs[func]; + fregs = (uint8_t *) dev->regs[func]; ret = fregs[addr]; if ((func == 0) && (addr == 0x4e)) ret |= keyboard_at_get_mouse_scan(); @@ -988,21 +1160,21 @@ piix_reset_hard(piix_t *dev) /* Clear all 4 functions' arrays and set their vendor and device ID's. */ for (i = 0; i < 4; i++) { - memset(dev->regs[i], 0, 256); - if (dev->type == 5) { - dev->regs[i][0x00] = 0x55; dev->regs[i][0x01] = 0x10; /* SMSC/EFAR */ - if (i == 1) { /* IDE controller is 9130, breaking convention */ - dev->regs[i][0x02] = 0x30; - dev->regs[i][0x03] = 0x91; - } else { - dev->regs[i][0x02] = (dev->func0_id & 0xff) + (i << dev->func_shift); - dev->regs[i][0x03] = (dev->func0_id >> 8); - } - } else { - dev->regs[i][0x00] = 0x86; dev->regs[i][0x01] = 0x80; /* Intel */ - dev->regs[i][0x02] = (dev->func0_id & 0xff) + (i << dev->func_shift); - dev->regs[i][0x03] = (dev->func0_id >> 8); - } + memset(dev->regs[i], 0, 256); + if (dev->type == 5) { + dev->regs[i][0x00] = 0x55; dev->regs[i][0x01] = 0x10; /* SMSC/EFAR */ + if (i == 1) { /* IDE controller is 9130, breaking convention */ + dev->regs[i][0x02] = 0x30; + dev->regs[i][0x03] = 0x91; + } else { + dev->regs[i][0x02] = (dev->func0_id & 0xff) + (i << dev->func_shift); + dev->regs[i][0x03] = (dev->func0_id >> 8); + } + } else { + dev->regs[i][0x00] = 0x86; dev->regs[i][0x01] = 0x80; /* Intel */ + dev->regs[i][0x02] = (dev->func0_id & 0xff) + (i << dev->func_shift); + dev->regs[i][0x03] = (dev->func0_id >> 8); + } } /* Function 0: PCI to ISA Bridge */ @@ -1013,7 +1185,7 @@ piix_reset_hard(piix_t *dev) if (dev->type == 4) fregs[0x08] = (dev->rev & 0x08) ? 0x02 : (dev->rev & 0x07); else - fregs[0x08] = dev->rev; + fregs[0x08] = dev->rev; fregs[0x09] = 0x00; fregs[0x0a] = 0x01; fregs[0x0b] = 0x06; fregs[0x0e] = ((dev->type > 1) || (dev->rev != 2)) ? 0x80 : 0x00; @@ -1238,11 +1410,14 @@ piix_reset(void *p) static void -piix_close(void *p) +piix_close(void *priv) { - piix_t *piix = (piix_t *)p; + piix_t *dev = (piix_t *) priv; - free(piix); + for (int i = 0; i < (sizeof(dev->io_traps) / sizeof(dev->io_traps[0])); i++) + io_trap_remove(dev->io_traps[i].trap); + + free(dev); } @@ -1297,6 +1472,7 @@ static void acpi_set_slot(dev->acpi, dev->pci_slot); acpi_set_nvr(dev->acpi, dev->nvr); acpi_set_gpireg2_default(dev->acpi, (dev->type > 4) ? 0xf1 : 0xdd); + acpi_set_trap_update(dev->acpi, piix_trap_update, dev); dev->ddma = device_add(&ddma_device); } else @@ -1313,7 +1489,7 @@ static void /* On PIIX4, PIIX4E, and SMSC, APM is added by the ACPI device. */ if (dev->type < 4) { - dev->apm = device_add(&apm_pci_device); + dev->apm = device_add(&apm_pci_device); /* APM intercept handler to update PIIX/PIIX3 and PIIX4/4E/SMSC ACPI SMI status on APM SMI. */ io_sethandler(0x00b2, 0x0001, NULL, NULL, NULL, piix_apm_out, NULL, NULL, dev); } diff --git a/src/chipset/sis_5598.c b/src/chipset/sis_5598.c deleted file mode 100644 index e37074d6f..000000000 --- a/src/chipset/sis_5598.c +++ /dev/null @@ -1,969 +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 SiS 5597/5598 Pentium PCI/ISA Chipset. - * - * - * - * 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/nvr.h> - -#include <86box/acpi.h> -#include <86box/ddma.h> -#include <86box/hdc.h> -#include <86box/hdc_ide.h> -#include <86box/hdc_ide_sff8038i.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/port_92.h> -#include <86box/smram.h> -#include <86box/usb.h> - -#include <86box/chipset.h> - -/* ACPI Flags */ -#define ACPI_BASE ((dev->pci_conf_sb[0][0x91] << 8) | dev->pci_conf_sb[0][0x90]) -#define ACPI_EN (dev->pci_conf_sb[0][0x40] & 0x80) - -/* DIMM */ -#define DIMM_BANK0 dev->pci_conf[0x60] -#define DIMM_BANK1 dev->pci_conf[0x61] -#define DIMM_BANK_ENABLE dev->pci_conf[0x63] - -/* IDE Flags (1 Native / 0 Compatibility)*/ -#define PRIMARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 1) -#define SECONDARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 4) -#define PRIMARY_NATIVE_BASE (dev->pci_conf_sb[1][0x11] << 8) | (dev->pci_conf_sb[1][0x10] & 0xf8) -#define PRIMARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x15] << 8) | (dev->pci_conf_sb[1][0x14] & 0xfc)) + 2) -#define SECONDARY_NATIVE_BASE (dev->pci_conf_sb[1][0x19] << 8) | (dev->pci_conf_sb[1][0x18] & 0xf8) -#define SECONDARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x1d] << 8) | (dev->pci_conf_sb[1][0x1c] & 0xfc)) + 2) -#define BUS_MASTER_BASE ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) - -#ifdef ENABLE_SIS_5598_LOG -int sis_5598_do_log = ENABLE_SIS_5598_LOG; -static void -sis_5598_log(const char *fmt, ...) -{ - va_list ap; - - if (sis_5598_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -#define sis_5598_log(fmt, ...) -#endif - -typedef struct sis_5598_t -{ - acpi_t *acpi; - ddma_t *ddma; - nvr_t *nvr; - sff8038i_t *ide_drive[2]; - smram_t *smram; - port_92_t *port_92; - usb_t *usb; - - int nb_device_id, sb_device_id; - uint8_t pci_conf[256], pci_conf_sb[3][256]; -} sis_5598_t; - -void sis_5598_dimm_programming(sis_5598_t *dev) -{ -/* -Based completely off the PC Chips M571 Manual -Configurations are forced and don't work as intended -*/ - switch (mem_size >> 10) - { - case 8: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc0; - break; - case 16: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc0; - DIMM_BANK1 = 0xc0; - break; - case 24: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc2; - DIMM_BANK1 = 0xc0; - break; - case 32: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc2; - DIMM_BANK1 = 0xc2; - break; - case 40: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc8; - DIMM_BANK1 = 0xc0; - break; - case 48: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc8; - DIMM_BANK1 = 0xc2; - break; - case 56: /* Unintended */ - case 64: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc8; - DIMM_BANK1 = 0xc8; - break; - case 72: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc6; - DIMM_BANK1 = 0xc0; - break; - case 80: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc6; - DIMM_BANK1 = 0xc2; - break; - case 88: /* Unintended */ - case 96: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc6; - DIMM_BANK1 = 0xc8; - break; - case 104: /* Unintended */ - case 112: /* Unintended */ - case 120: /* Unintended */ - case 128: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 0xc6; - DIMM_BANK1 = 0xc6; - break; - case 136: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 10 | 0xca; - DIMM_BANK1 = 0xc0; - break; - case 144: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 10 | 0xca; - DIMM_BANK1 = 2 | 0xc2; - break; - case 152: /* Unintended */ - case 160: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 10 | 0xca; - DIMM_BANK1 = 8 | 0xc8; - break; - case 168: /* Unintended */ - case 176: /* Unintended */ - case 184: /* Unintended */ - case 192: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 10 | 0xca; - DIMM_BANK1 = 6 | 0xc6; - break; - case 200: /* Unintended */ - case 208: /* Unintended */ - case 216: /* Unintended */ - case 224: /* Unintended */ - case 232: /* Unintended */ - case 240: /* Unintended */ - case 248: /* Unintended */ - case 256: - DIMM_BANK_ENABLE = 1; - DIMM_BANK0 = 10 | 0xca; - DIMM_BANK1 = 10 | 0xca; - break; - } -} - -void sis_5598_shadow(int cur_reg, sis_5598_t *dev) -{ - if (cur_reg == 0x76) - { - 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) * 0x8000), 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) * 0x8000), 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)); - } - flushmmucache_nopc(); -} - -void sis_5598_smram(sis_5598_t *dev) -{ - smram_disable_all(); - - switch ((dev->pci_conf[0xa3] & 0xc0) >> 6) - { - case 0: - if (dev->pci_conf[0x74] == 0) - smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); - break; - case 1: - if (dev->pci_conf[0x74] == 0) - smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1); - break; - case 2: - if (dev->pci_conf[0x74] == 0) - smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1); - break; - case 3: - smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1); - break; - } - - flushmmucache(); -} - -void sis_5598_ddma_update(sis_5598_t *dev) -{ - for (int i = 0; i < 8; i++) - if (i != 4) - ddma_update_io_mapping(dev->ddma, i, dev->pci_conf_sb[0][0x80] >> 4, dev->pci_conf_sb[0][0x81], dev->pci_conf_sb[0][0x80] & 1); -} - -void sis_5598_ide_handler(sis_5598_t *dev) -{ - ide_pri_disable(); - ide_sec_disable(); - if (dev->pci_conf_sb[1][4] & 1) - { - if (dev->pci_conf_sb[1][0x4a] & 4) - { - ide_set_base(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_BASE : 0x1f0); - ide_set_side(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_SIDE : 0x3f6); - ide_pri_enable(); - } - if (dev->pci_conf_sb[1][0x4a] & 2) - { - ide_set_base(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_BASE : 0x170); - ide_set_side(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_SIDE : 0x376); - ide_sec_enable(); - } - } -} - -void sis_5598_bm_handler(sis_5598_t *dev) -{ - sff_bus_master_handler(dev->ide_drive[0], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE); - sff_bus_master_handler(dev->ide_drive[1], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE + 8); -} - -static void -sis_5597_write(int func, int addr, uint8_t val, void *priv) -{ - sis_5598_t *dev = (sis_5598_t *)priv; - - switch (addr) - { - case 0x04: /* Command */ - dev->pci_conf[addr] = val & 3; - break; - - case 0x05: /* Command */ - dev->pci_conf[addr] = val & 2; - break; - - case 0x07: /* Status */ - dev->pci_conf[addr] &= val & 0xb9; - break; - - case 0x0d: /* Master latency timer */ - dev->pci_conf[addr] = val; - break; - - case 0x50: /* Host Interface and DRAM arbiter */ - dev->pci_conf[addr] = val & 0xfc; - break; - - case 0x51: /* L2 Cache Controller */ - dev->pci_conf[addr] = (val & 0xcf) | 0x20; /* 512KB L2 Cache Installed */ - cpu_cache_ext_enabled = !!(val & 0x40); - cpu_update_waitstates(); - break; - - case 0x52: /* Control Register */ - dev->pci_conf[addr] = val & 0xe3; - break; - - case 0x53: /* DRAM Control Register */ - case 0x54: /* DRAM Control Register 0*/ - dev->pci_conf[addr] = val; - break; - - case 0x55: /* FPM/EDO DRAM Control Register 1 */ - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x56: /* Memory Data Latch Enable (MDLE) Delay Control Register */ - case 0x57: /* SDRAM Control Register */ - dev->pci_conf[addr] = val; - break; - - case 0x58: - dev->pci_conf[addr] = val & 0xfc; - break; - - case 0x59: /* DRAM signals driving current Control */ - dev->pci_conf[addr] = val; - break; - - case 0x5a: /* PCI signals driving current Control */ - dev->pci_conf[addr] = val & 3; - break; - - case 0x6c: /* Integrated VGA Controller Control */ - dev->pci_conf[addr] = 0; /* Kill the Integrated GPU */ - break; - - case 0x6d: /* Starting Address of Shared Memory Hole HA[28:23] */ - dev->pci_conf[addr] = val & 2; - break; - - case 0x6e: - dev->pci_conf[addr] = val & 0xc0; - break; - - case 0x70: /* shadow RAM Registers */ - case 0x71: /* shadow RAM Registers */ - case 0x72: /* shadow RAM Registers */ - case 0x73: /* shadow RAM Registers */ - case 0x74: /* shadow RAM Registers */ - case 0x75: /* shadow RAM Registers */ - case 0x76: /* Attribute of shadow RAM for BIOS area */ - dev->pci_conf[addr] = (addr == 0x76) ? (val & 0xe4) : (val & 0xee); - sis_5598_shadow(addr, dev); - break; - - case 0x77: /* Characteristics of non-cacheable area */ - dev->pci_conf[addr] = val & 0x0f; - break; - - case 0x78: /* Allocation of Non-Cacheable area I */ - case 0x79: - case 0x7a: /* Allocation of Non-Cacheable area II */ - case 0x7b: - dev->pci_conf[addr] = val; - break; - - case 0x80: /* PCI master characteristics */ - dev->pci_conf[addr] = val & 0xfe; - break; - - case 0x81: - dev->pci_conf[addr] = val & 0xbe; - break; - - case 0x82: - dev->pci_conf[addr] = val; - break; - - case 0x83: /* CPU to PCI characteristics */ - dev->pci_conf[addr] = val; - port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x80)); - break; - - case 0x84: /* PCI grant timer */ - case 0x85: - case 0x86: /* CPU idle timer */ - dev->pci_conf[addr] = val; - break; - - case 0x87: /* Miscellaneous register */ - dev->pci_conf[addr] = val & 0xfc; - break; - - case 0x88: /* Base address of fast back-to-back area */ - case 0x89: - dev->pci_conf[addr] = val; - break; - - case 0x8a: /* Size of fast back-to-back area */ - case 0x8b: - case 0x90: /* Legacy PMU control register */ - case 0x91: /* Address trap for Legacy PMU function */ - case 0x92: - dev->pci_conf[addr] = val; - break; - - case 0x93: /* STPCLK# and APM SMI control */ - dev->pci_conf[addr] = val; - if ((dev->pci_conf[0x9b] & 1) && (val & 1)) - { - smi_line = 1; - dev->pci_conf[0x9d] |= 1; - } - break; - - case 0x94: /* Cyrix 6x86 and PMU function control */ - dev->pci_conf[addr] = val & 0xf8; - break; - - case 0x95: - dev->pci_conf[addr] = val & 0xfb; - break; - - case 0x96: /* Time slot and Programmable 10-bit I/O port definition */ - dev->pci_conf[addr] = val & 0xfb; - break; - - case 0x97: /* Programmable 10-bit I/O port address bits A9~A2 */ - case 0x98: /* Programmable 16-bit I/O port */ - case 0x99: - case 0x9a: /* System Standby Timer events control */ - case 0x9b: /* Monitor Standdby Timer events control */ - case 0x9c: /* SMI Request events status 0 */ - case 0x9d: /* SMI Request events status 1 */ - case 0x9e: /* STPCLK# Assertion Timer */ - case 0x9f: /* STPCLK# De-assertion Timer */ - case 0xa0: /* Monitor Standby Timer */ - case 0xa1: - case 0xa2: /* System Standby Time */ - dev->pci_conf[addr] = val; - break; - - case 0xa3: /* SMRAM access control and Power supply control */ - dev->pci_conf[addr] = val & 0xd0; - sis_5598_smram(dev); - break; - } - - sis_5598_log("SiS 5597: dev->regs[%02x] = %02x POST: %02x\n", addr, dev->pci_conf[addr], inb(0x80)); -} - -static uint8_t -sis_5597_read(int func, int addr, void *priv) -{ - sis_5598_t *dev = (sis_5598_t *)priv; - sis_5598_log("SiS 5597: dev->regs[%02x] (%02x) POST: %02x\n", addr, dev->pci_conf[addr], inb(0x80)); - return dev->pci_conf[addr]; -} - -void sis_5598_pcitoisa_write(int addr, uint8_t val, sis_5598_t *dev) -{ - switch (addr) - { - case 0x04: /* Command Port */ - dev->pci_conf_sb[0][addr] = val & 0x0f; - break; - - case 0x07: /* Status */ - dev->pci_conf_sb[0][addr] &= val & 0x3f; - break; - - case 0x0d: /* Master latency timer */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x40: /* BIOS Control Register */ - dev->pci_conf_sb[0][addr] = val; - acpi_update_io_mapping(dev->acpi, ACPI_BASE, ACPI_EN); - break; - - case 0x41: /* INTA#/INTB#INTC# Remapping Control Register */ - case 0x42: - case 0x43: - case 0x44: /* INTD# Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val & ((addr == 0x44) ? 0x9f : 0x8f); - pci_set_irq_routing(addr & 7, (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); - break; - - case 0x45: - dev->pci_conf_sb[0][addr] = val & 0xfc; - switch ((val & 0xc0) >> 6) - { - case 0: - cpu_set_isa_speed(7159091); - break; - case 1: - cpu_set_isa_pci_div(4); - break; - case 2: - cpu_set_isa_pci_div(3); - break; - } - - break; - - case 0x46: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x47: /* DMA Clock and Wait State Control Register */ - dev->pci_conf_sb[0][addr] = val & 0x7f; - break; - - case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ - case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ - case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ - case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ - case 0x4c: /* 4Ch/4Dh/4Eh/4Fh Initialization Command Word 1/2/3/4 Mirror Register I */ - case 0x4d: /* 4Ch/4Dh/4Eh/4Fh Initialization Command Word 1/2/3/4 Mirror Register I */ - case 0x4e: /* 4Ch/4Dh/4Eh/4Fh Initialization Command Word 1/2/3/4 Mirror Register I */ - case 0x4f: /* 4Ch/4Dh/4Eh/4Fh Initialization Command Word 1/2/3/4 Mirror Register I */ - case 0x50: /* Initialization Command Word 1/2/3/4 mirror Register II */ - case 0x51: /* Initialization Command Word 1/2/3/4 mirror Register II */ - case 0x52: /* Initialization Command Word 1/2/3/4 mirror Register II */ - case 0x53: /* Initialization Command Word 1/2/3/4 mirror Register II */ - case 0x54: /* Operational Control Word 2/3 Mirror Register I */ - case 0x55: - case 0x56: /* Operational Control Word 2/3 Mirror Register II */ - case 0x57: - case 0x58: /* Counter Access Ports Mirror Register 0 */ - case 0x59: - case 0x5a: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x5e: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x5f: - dev->pci_conf_sb[0][addr] = val & 0x3f; - break; - - case 0x60: /* Mirror port */ - dev->pci_conf_sb[0][addr] = (uint8_t)inb(0x70); - break; - - case 0x61: /* IDEIRQ Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val & 0xcf; - if (val & 0x80) - { - sff_set_irq_line(dev->ide_drive[0], val & 0x0f); - sff_set_irq_line(dev->ide_drive[1], val & 0x0f); - } - break; - - case 0x62: /* USBIRQ Remapping Control Register */ - case 0x63: /* GPCS0 Control Register */ - case 0x64: /* GPCS1 Control Register */ - case 0x65: /* GPCS0 Output Mode Control Register */ - case 0x66: - case 0x67: /* GPCS1 Output Mode Control Register */ - case 0x68: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x69: /* GPCS0/1 De-Bounce Control Register */ - dev->pci_conf_sb[0][addr] = val & 0xdf; - break; - - case 0x6a: /* ACPI/SCI IRQ Remapping Control Register */ - dev->pci_conf_sb[0][addr] = val; - if (val & 0x80) - acpi_set_irq_line(dev->acpi, val & 0x0f); - break; - - case 0x6b: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x6c: - dev->pci_conf_sb[0][addr] = val & 0xfe; - break; - - case 0x6d: - case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ - case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ - case 0x70: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x71: /* Type-F DMA Control Register */ - dev->pci_conf_sb[0][addr] = val & 0xef; - break; - - case 0x72: /* SMI Triggered By IRQ Control */ - dev->pci_conf_sb[0][addr] = val & 0xfa; - break; - - case 0x73: /* SMI Triggered By IRQ Control */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x74: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */ - dev->pci_conf_sb[0][addr] = val & 0xfb; - break; - - case 0x75: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x76: /* Monitor Standby Timer Reload And Monitor Standby State Exit Control */ - dev->pci_conf_sb[0][addr] = val & 0xfb; - break; - - case 0x77: /* Monitor Standby Timer Reload And Monitor Standby State Exit Control */ - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x80: /* DDMA Control Register */ - case 0x81: - dev->pci_conf_sb[0][addr] = val & ((addr == 0x81) ? 0xff : 0xf1); - sis_5598_ddma_update(dev); - break; - - case 0x84: - dev->pci_conf_sb[0][addr] = val & 0xef; - break; - - case 0x88: - dev->pci_conf_sb[0][addr] = val; - break; - - case 0x89: /* Serial Interrupt Enable Register 1 */ - dev->pci_conf_sb[0][addr] = val & 0x7e; - break; - - case 0x8a: /* Serial Interrupt Enable Register 2 */ - dev->pci_conf_sb[0][addr] = val & 0xef; - break; - - case 0x90: /* ACPI Base Address Register */ - case 0x91: /* ACPI Base Address Register */ - dev->pci_conf_sb[0][addr] = val; - acpi_update_io_mapping(dev->acpi, ACPI_BASE, ACPI_EN); - break; - } -} - -void sis_5598_ide_write(int addr, uint8_t val, sis_5598_t *dev) -{ - switch (addr) - { - case 0x04: /* Command */ - dev->pci_conf_sb[1][addr] = val & 7; - sis_5598_ide_handler(dev); - sis_5598_bm_handler(dev); - break; - - case 0x06: /* Status */ - dev->pci_conf_sb[1][addr] = val & 0x20; - break; - - case 0x07: /* Status */ - dev->pci_conf_sb[1][addr] = val & 0x3c; - break; - - case 0x0d: /* Latency Timer */ - dev->pci_conf_sb[1][addr] = val; - break; - - case 0x09: /* Programming Interface Byte */ - case 0x10: /* Primary Channel Command Block Base Address Register */ - case 0x11: /* Primary Channel Command Block Base Address Register */ - case 0x12: /* Primary Channel Command Block Base Address Register */ - case 0x13: /* Primary Channel Command Block Base Address Register */ - case 0x14: /* Primary Channel Control Block Base Address Register */ - case 0x15: /* Primary Channel Control Block Base Address Register */ - case 0x16: /* Primary Channel Control Block Base Address Register */ - case 0x17: /* Primary Channel Control Block Base Address Register */ - case 0x18: /* Secondary Channel Command Block Base Address Register */ - case 0x19: /* Secondary Channel Command Block Base Address Register */ - case 0x1a: /* Secondary Channel Command Block Base Address Register */ - case 0x1b: /* Secondary Channel Command Block Base Address Register */ - case 0x1c: /* Secondary Channel Control Block Base Address Register */ - case 0x1d: /* Secondary Channel Control Block Base Address Register */ - case 0x1e: /* Secondary Channel Control Block Base Address Register */ - case 0x1f: /* Secondary Channel Control Block Base Address Register */ - dev->pci_conf_sb[1][addr] = val & ((addr == 9) ? 0x0f : 0xff); - sis_5598_ide_handler(dev); - break; - - case 0x20: /* Bus Master IDE Control Register Base Address */ - case 0x21: /* Bus Master IDE Control Register Base Address */ - case 0x22: /* Bus Master IDE Control Register Base Address */ - case 0x23: /* Bus Master IDE Control Register Base Address */ - dev->pci_conf_sb[1][addr] = val; - sis_5598_bm_handler(dev); - break; - - case 0x2c: /* Subsystem ID */ - dev->pci_conf_sb[1][addr] = val; - break; - - case 0x30: /* Expansion ROM Base Address */ - case 0x31: /* Expansion ROM Base Address */ - case 0x32: /* Expansion ROM Base Address */ - case 0x33: /* Expansion ROM Base Address */ - dev->pci_conf_sb[1][addr] = val; - break; - - case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */ - dev->pci_conf_sb[1][addr] = val & 0xcf; - break; - - case 0x41: /* IDE Primary Channel/Master Drive Control */ - dev->pci_conf_sb[1][addr] = val & 0xe7; - break; - - case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */ - dev->pci_conf_sb[1][addr] = val & 0x0f; - break; - - case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */ - case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */ - case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */ - dev->pci_conf_sb[1][addr] = val & 0xe7; - break; - - case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */ - dev->pci_conf_sb[1][addr] = val & 0x0f; - break; - - case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */ - dev->pci_conf_sb[1][addr] = val & 0xe7; - break; - - case 0x48: /* IDE Command Recovery Time Control */ - case 0x49: /* IDE Command Active Time Control */ - dev->pci_conf_sb[1][addr] = val & 0x0f; - break; - - case 0x4a: /* IDE General Control Register 0 */ - dev->pci_conf_sb[1][addr] = val; - sis_5598_ide_handler(dev); - break; - - case 0x4b: /* IDE General Control register 1 */ - case 0x4c: /* Prefetch Count of Primary Channel */ - case 0x4d: - case 0x4e: /* Prefetch Count of Secondary Channel */ - case 0x4f: - case 0x50: /* IDE minimum accessed time register */ - case 0x51: - dev->pci_conf_sb[1][addr] = val; - break; - - case 0x52: /* IDE Miscellaneous Control Register */ - dev->pci_conf_sb[1][addr] = val & 0x0f; - break; - } -} - -void sis_5598_usb_write(int addr, uint8_t val, sis_5598_t *dev) -{ - switch (addr) - { - case 0x04: /* Command */ - dev->pci_conf_sb[2][addr] = val; - ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1); - break; - - case 0x05: /* Command */ - dev->pci_conf_sb[2][addr] = val & 3; - break; - - case 0x06: /* Status */ - dev->pci_conf_sb[2][addr] &= val & 0xf0; - break; - - case 0x07: /* Status */ - dev->pci_conf_sb[2][addr] &= val; - break; - - case 0x0d: /* Latency Timer */ - dev->pci_conf_sb[2][addr] = val; - break; - - case 0x11: /* USB Memory Space Base Address Register */ - case 0x12: /* USB Memory Space Base Address Register */ - case 0x13: /* USB Memory Space Base Address Register */ - dev->pci_conf_sb[2][addr] = val & ((addr == 0x11) ? 0x0f : 0xff); - ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1); - break; - - case 0x3c: /* Interrupt Line */ - case 0x3d: /* Interrupt Pin */ - case 0x3e: /* Minimum Grant Time */ - case 0x3f: /* Maximum Latency Time */ - dev->pci_conf_sb[2][addr] = val; - break; - } -} - -static void -sis_5598_write(int func, int addr, uint8_t val, void *priv) -{ - sis_5598_t *dev = (sis_5598_t *)priv; - switch (func) - { - case 0: - sis_5598_pcitoisa_write(addr, val, dev); - break; - case 1: - sis_5598_ide_write(addr, val, dev); - break; - case 2: - sis_5598_usb_write(addr, val, dev); - break; - } - sis_5598_log("SiS 5598: dev->regs[%02x][%02x] = %02x POST: %02x\n", func, addr, dev->pci_conf_sb[func][addr], inb(0x80)); -} - -static uint8_t -sis_5598_read(int func, int addr, void *priv) -{ - sis_5598_t *dev = (sis_5598_t *)priv; - if ((func >= 0) && (func <= 2)) - { - sis_5598_log("SiS 5598: dev->regs[%02x][%02x] (%02x) POST: %02x\n", func, addr, dev->pci_conf_sb[func][addr], inb(0x80)); - return dev->pci_conf_sb[func][addr]; - } - else - return 0xff; -} - -static void -sis_5598_defaults(sis_5598_t *dev) -{ - dev->pci_conf[0x00] = 0x39; /* SiS */ - dev->pci_conf[0x01] = 0x10; - dev->pci_conf[0x02] = 0x97; /* 5597 */ - dev->pci_conf[0x03] = 0x55; - dev->pci_conf[0x08] = 4; - dev->pci_conf[0x0b] = 6; - dev->pci_conf[0x0d] = 0xff; - dev->pci_conf[0x9e] = 0xff; - dev->pci_conf[0x9f] = 0xff; - dev->pci_conf[0xa0] = 0xff; - - dev->pci_conf_sb[0][0x00] = 0x39; /* SiS */ - dev->pci_conf_sb[0][0x01] = 0x10; - dev->pci_conf_sb[0][0x02] = 8; /* 5598 */ - dev->pci_conf_sb[0][0x08] = 1; - dev->pci_conf_sb[0][0x0a] = 1; - dev->pci_conf_sb[0][0x0b] = 6; - dev->pci_conf_sb[0][0x0d] = 0xff; - dev->pci_conf_sb[0][0x0e] = 0x30; - dev->pci_conf_sb[0][0x0f] = 0x30; - dev->pci_conf_sb[0][0x48] = 1; - dev->pci_conf_sb[0][0x4a] = 0x10; - dev->pci_conf_sb[0][0x4b] = 0x0f; - dev->pci_conf_sb[0][0x6d] = 0x19; - dev->pci_conf_sb[0][0x70] = 0x12; - - dev->pci_conf_sb[1][0x00] = 0x39; /* SiS */ - dev->pci_conf_sb[1][0x01] = 0x10; - dev->pci_conf_sb[1][0x02] = 0x13; /* 5513 */ - dev->pci_conf_sb[1][0x03] = 0x55; - dev->pci_conf_sb[1][0x08] = 0xd0; - dev->pci_conf_sb[0][0x09] = 0x80; - dev->pci_conf_sb[1][0x0a] = 1; - dev->pci_conf_sb[1][0x0b] = 1; - - dev->pci_conf_sb[2][0x00] = 0x39; /* SiS */ - dev->pci_conf_sb[2][0x01] = 0x10; - dev->pci_conf_sb[2][0x02] = 1; /* 7710 */ - dev->pci_conf_sb[2][0x03] = 0x70; - dev->pci_conf_sb[2][0x06] = 2; - dev->pci_conf_sb[2][0x07] = 0x80; - dev->pci_conf_sb[2][0x08] = 0xe0; - dev->pci_conf_sb[2][0x09] = 0x10; - dev->pci_conf_sb[2][0x0a] = 3; - dev->pci_conf_sb[2][0x0b] = 0x0c; - dev->pci_conf_sb[2][0x0e] = 0x10; - dev->pci_conf_sb[2][0x3d] = 1; -} - -static void -sis_5598_reset(void *priv) -{ - sis_5598_t *dev = (sis_5598_t *)priv; - - /* Program defaults */ - sis_5598_defaults(dev); - - /* Set up ACPI */ - acpi_set_slot(dev->acpi, dev->sb_device_id); - acpi_set_nvr(dev->acpi, dev->nvr); - - /* Set up IDE */ - sff_set_slot(dev->ide_drive[0], dev->sb_device_id); - sff_set_slot(dev->ide_drive[1], dev->sb_device_id); - sff_bus_master_reset(dev->ide_drive[0], BUS_MASTER_BASE); - sff_bus_master_reset(dev->ide_drive[1], BUS_MASTER_BASE + 8); -} - -static void -sis_5598_close(void *priv) -{ - sis_5598_t *dev = (sis_5598_t *)priv; - - smram_del(dev->smram); - free(dev); -} - -static void * -sis_5598_init(const device_t *info) -{ - sis_5598_t *dev = (sis_5598_t *)malloc(sizeof(sis_5598_t)); - memset(dev, 0, sizeof(sis_5598_t)); - dev->nb_device_id = pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5597_read, sis_5597_write, dev); /* Device 0: SiS 5597 */ - dev->sb_device_id = pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5598_read, sis_5598_write, dev); /* Device 1: SiS 5598 */ - - /* ACPI */ - dev->acpi = device_add(&acpi_sis_device); - dev->nvr = device_add(&at_nvr_device); - - /* DDMA */ - dev->ddma = device_add(&ddma_device); - - /* RAM Bank Programming */ - sis_5598_dimm_programming(dev); - - /* SFF IDE */ - dev->ide_drive[0] = device_add_inst(&sff8038i_device, 1); - dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2); - - /* SMRAM */ - dev->smram = smram_add(); - - /* Port 92 */ - dev->port_92 = device_add(&port_92_pci_device); - - /* USB */ - dev->usb = device_add(&usb_device); - - sis_5598_reset(dev); - - return dev; -} - -const device_t sis_5598_device = { - "SiS 5597/5598", - DEVICE_PCI, - 0, - sis_5598_init, - sis_5598_close, - sis_5598_reset, - {NULL}, - NULL, - NULL, - NULL}; diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index 41667edfd..df3b26a8e 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -67,23 +67,69 @@ #define VIA_PIPC_8231 0x82311000 -typedef struct -{ +enum { + TRAP_DRQ = 0, + TRAP_PIRQ, + TRAP_PIDE_MAIN, + TRAP_PIDE_SIDE, + TRAP_SIDE_MAIN, + TRAP_SIDE_SIDE, + TRAP_FLP_MAIN, + TRAP_FLP_SIDE, + TRAP_COM1, + TRAP_COM3, + TRAP_COM2, + TRAP_COM4, + TRAP_LPT_LPT1, + TRAP_LPT_LPT2, + TRAP_VGA, + TRAP_KBC, + TRAP_AUD_MIDI_0, + TRAP_AUD_MIDI_1, + TRAP_AUD_MIDI_2, + TRAP_AUD_MIDI_3, + TRAP_AUD_SB_0, + TRAP_AUD_SB_1, + TRAP_AUD_SB_2, + TRAP_AUD_SB_3, + TRAP_AUD_GAME, + TRAP_AUD_WSS_0, + TRAP_AUD_WSS_1, + TRAP_AUD_WSS_2, + TRAP_AUD_WSS_3, + TRAP_GR0, + TRAP_GR1, + TRAP_GR2, + TRAP_GR3, + TRAP_MAX +}; + +typedef struct { + struct _pipc_ *dev; + void *trap; + uint32_t *sts_reg, *en_reg, mask; +} pipc_io_trap_t; + +typedef struct _pipc_ { uint32_t local; - uint8_t max_func; + uint8_t max_func, max_pcs; uint8_t pci_isa_regs[256], ide_regs[256], usb_regs[2][256], power_regs[256], ac97_regs[2][256], fmnmi_regs[4]; + sff8038i_t *bm[2]; nvr_t *nvr; int nvr_enabled, slot; ddma_t *ddma; smbus_piix4_t *smbus; usb_t *usb[2]; + acpi_t *acpi; + pipc_io_trap_t io_traps[TRAP_MAX]; + void *gameport, *ac97; sb_t *sb; uint16_t midigame_base, sb_base, fmnmi_base; @@ -117,6 +163,32 @@ static uint8_t pipc_read(int func, int addr, void *priv); static void pipc_write(int func, int addr, uint8_t val, void *priv); +static void +pipc_trap_io_pact(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + pipc_io_trap_t *trap = (pipc_io_trap_t *) priv; + + if (*(trap->en_reg) & trap->mask) { + *(trap->sts_reg) |= trap->mask; + trap->dev->acpi->regs.glbsts |= 0x0001; + if (trap->dev->acpi->regs.glben & 0x0001) + acpi_raise_smi(trap->dev->acpi); + } +} + + +static void +pipc_io_trap_glb(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +{ + pipc_io_trap_t *trap = (pipc_io_trap_t *) priv; + + if (*(trap->en_reg) & trap->mask) { + *(trap->sts_reg) |= trap->mask; + acpi_raise_smi(trap->dev->acpi); + } +} + + static void pipc_reset_hard(void *priv) { @@ -136,7 +208,7 @@ pipc_reset_hard(void *priv) memset(dev->power_regs, 0, 256); memset(dev->ac97_regs, 0, 512); - /* PCI-ISA bridge registers */ + /* PCI-ISA bridge registers. */ dev->pci_isa_regs[0x00] = 0x06; dev->pci_isa_regs[0x01] = 0x11; dev->pci_isa_regs[0x02] = dev->local >> 16; dev->pci_isa_regs[0x03] = dev->local >> 24; @@ -164,7 +236,9 @@ pipc_reset_hard(void *priv) pic_set_shadow(0); - /* IDE registers */ + dev->max_pcs = (dev->local >= VIA_PIPC_686A) ? 3 : 1; + + /* IDE registers. */ dev->max_func++; dev->ide_regs[0x00] = 0x06; dev->ide_regs[0x01] = 0x11; dev->ide_regs[0x02] = 0x71; dev->ide_regs[0x03] = 0x05; @@ -212,7 +286,7 @@ pipc_reset_hard(void *priv) dev->ide_regs[0xc2] = 0x02; } - /* USB registers */ + /* USB registers. */ for (i = 0; i <= (dev->local >= VIA_PIPC_686A); i++) { dev->max_func++; dev->usb_regs[i][0x00] = 0x06; dev->usb_regs[i][0x01] = 0x11; @@ -260,7 +334,7 @@ pipc_reset_hard(void *priv) dev->usb_regs[i][0xc1] = 0x20; } - /* power management registers */ + /* Power management registers. */ if (dev->acpi) { dev->max_func++; dev->power_regs[0x00] = 0x06; dev->power_regs[0x01] = 0x11; @@ -317,9 +391,26 @@ pipc_reset_hard(void *priv) dev->power_regs[0x80] = 0x01; else if (dev->local >= VIA_PIPC_596B) dev->power_regs[0x90] = 0x01; + + /* Set up PCS I/O traps. */ + pipc_io_trap_t *trap; + for (i = 0; i <= dev->max_pcs; i++) { + trap = &dev->io_traps[TRAP_GR0 + i]; + trap->dev = dev; + trap->trap = io_trap_add(pipc_io_trap_glb, trap); + if (i & 2) { + trap->sts_reg = (uint32_t *) &dev->acpi->regs.extiotrapsts; + trap->en_reg = (uint32_t *) &dev->acpi->regs.extiotrapen; + trap->mask = 0x01 << (i & 1); + } else { + trap->sts_reg = &dev->acpi->regs.glbsts; + trap->en_reg = &dev->acpi->regs.glben; + trap->mask = 0x4000 << i; + } + } } - /* AC97/MC97 registers */ + /* AC97/MC97 registers. */ if (dev->local >= VIA_PIPC_686A) { for (i = 0; i <= 1; i++) { dev->max_func++; @@ -459,6 +550,139 @@ pipc_bus_master_handlers(pipc_t *dev) } +static void +pipc_pcs_update(pipc_t *dev) +{ + uint8_t i, io_base_reg, io_mask_reg, io_mask_shift, enable; + uint16_t io_base, io_mask; + + for (i = 0; i <= dev->max_pcs; i++) { + if (i & 2) { + io_base_reg = 0x8c; + io_mask_reg = 0x8a; + } else { + io_base_reg = 0x78; + io_mask_reg = 0x80; + } + io_base_reg |= (i & 1) << 1; + io_mask_shift = (i & 1) << 2; + + if (dev->local <= VIA_PIPC_596B) + enable = dev->pci_isa_regs[0x76] & (0x10 << i); + else + enable = dev->pci_isa_regs[0x8b] & (0x01 << i); + + io_base = dev->pci_isa_regs[io_base_reg] | (dev->pci_isa_regs[io_base_reg | 1] << 8); + io_mask = (dev->pci_isa_regs[io_mask_reg] >> io_mask_shift) & 0x000f; + + pipc_log("PIPC: Mapping PCS%d to %04X-%04X (enable %d)\n", i, io_base, io_base + io_mask, enable); + io_trap_remap(dev->io_traps[TRAP_GR0 + i].trap, enable, io_base & ~io_mask, io_mask + 1); + } +} + + +static void +pipc_trap_update_paden(pipc_t *dev, uint8_t trap_id, + uint32_t paden_mask, uint8_t enable, + uint16_t addr, uint16_t size) +{ + pipc_io_trap_t *trap = &dev->io_traps[trap_id]; + enable = (dev->acpi->regs.paden & paden_mask) && enable; + + /* Set up Primary Activity Detect I/O traps dynamically. */ + if (enable && !trap->trap) { + trap->dev = dev; + trap->trap = io_trap_add(pipc_trap_io_pact, trap); + trap->sts_reg = &dev->acpi->regs.padsts; + trap->en_reg = &dev->acpi->regs.paden; + trap->mask = paden_mask; + } + + /* Remap I/O trap. */ + io_trap_remap(trap->trap, enable, addr, size); +} + + +static void +pipc_trap_update_586(void *priv) +{ + pipc_t *dev = (pipc_t *) priv; + + /* TRAP_DRQ (00000001) and TRAP_PIRQ (00000002) not implemented. */ + + pipc_trap_update_paden(dev, TRAP_PIDE_MAIN, 0x00000008, 1, 0x1f0, 8); + pipc_trap_update_paden(dev, TRAP_SIDE_MAIN, 0x00000008, 1, 0x170, 8); + pipc_trap_update_paden(dev, TRAP_FLP_MAIN, 0x00000008, 1, 0x3f5, 1); + + pipc_trap_update_paden(dev, TRAP_VGA, 0x00000010, 1, 0x3b0, 48); + /* [A0000:BFFFF] memory trap not implemented. */ + + pipc_trap_update_paden(dev, TRAP_LPT_LPT1, 0x00000020, 1, 0x378, 8); + pipc_trap_update_paden(dev, TRAP_LPT_LPT2, 0x00000020, 1, 0x278, 8); + + pipc_trap_update_paden(dev, TRAP_COM1, 0x00000040, 1, 0x3f8, 8); + pipc_trap_update_paden(dev, TRAP_COM2, 0x00000040, 1, 0x2f8, 8); + pipc_trap_update_paden(dev, TRAP_COM3, 0x00000040, 1, 0x3e8, 8); + pipc_trap_update_paden(dev, TRAP_COM4, 0x00000040, 1, 0x2e8, 8); + + pipc_trap_update_paden(dev, TRAP_KBC, 0x00000080, 1, 0x60, 1); +} + + +static void +pipc_trap_update_596(void *priv) +{ + pipc_t *dev = (pipc_t *) priv; + int i; + + /* TRAP_DRQ (00000001) and TRAP_PIRQ (00000002) not implemented. */ + + pipc_trap_update_paden(dev, TRAP_PIDE_MAIN, 0x00000004, 1, 0x1f0, 8); + pipc_trap_update_paden(dev, TRAP_PIDE_SIDE, 0x00000004, 1, 0x3f6, 1); + + pipc_trap_update_paden(dev, TRAP_SIDE_MAIN, 0x00000008, 1, 0x170, 8); + pipc_trap_update_paden(dev, TRAP_SIDE_SIDE, 0x00000008, 1, 0x376, 1); + + pipc_trap_update_paden(dev, TRAP_FLP_MAIN, 0x00000010, 1, 0x3f0, 6); + pipc_trap_update_paden(dev, TRAP_FLP_SIDE, 0x00000010, 1, 0x3f7, 1); + + pipc_trap_update_paden(dev, TRAP_COM1, 0x00000020, 1, 0x3f8, 8); + pipc_trap_update_paden(dev, TRAP_COM3, 0x00000020, 1, 0x3e8, 8); + + pipc_trap_update_paden(dev, TRAP_COM2, 0x00000040, 1, 0x2f8, 8); + pipc_trap_update_paden(dev, TRAP_COM4, 0x00000040, 1, 0x2e8, 8); + + pipc_trap_update_paden(dev, TRAP_LPT_LPT1, 0x00000080, 1, 0x378, 8); + pipc_trap_update_paden(dev, TRAP_LPT_LPT2, 0x00000080, 1, 0x278, 8); + + pipc_trap_update_paden(dev, TRAP_VGA, 0x00000100, 1, 0x3b0, 48); + /* [A0000:BFFFF] memory trap not implemented. */ + + pipc_trap_update_paden(dev, TRAP_KBC, 0x00000200, 1, 0x60, 1); + + /* The following traps are poorly documented and assumed to operate on all ranges allowed + by the Positive Decoding Control registers. I couldn't probe this behavior on hardware. + It's better to be safe and cover all of them than to assume Intel-like behavior (one range). */ + + for (i = 0; i < 3; i++) { + pipc_trap_update_paden(dev, TRAP_AUD_MIDI_0 + i, + 0x00000400, (dev->local <= VIA_PIPC_596B) || (dev->power_regs[0x40] & 0x01), + 0x300 + (0x10 * i), 4); + + pipc_trap_update_paden(dev, TRAP_AUD_SB_0 + i, + 0x00000400, (dev->local <= VIA_PIPC_596B) || (dev->power_regs[0x40] & 0x02), + 0x220 + (0x20 * i), 20); + } + + pipc_trap_update_paden(dev, TRAP_AUD_GAME, 0x00000400, (dev->local <= VIA_PIPC_596B) || (dev->power_regs[0x40] & 0x04), 0x200, 8); + + pipc_trap_update_paden(dev, TRAP_AUD_WSS_0, 0x00000400, (dev->local <= VIA_PIPC_596B) || (dev->power_regs[0x40] & 0x08), 0x530, 8); + pipc_trap_update_paden(dev, TRAP_AUD_WSS_1, 0x00000400, (dev->local <= VIA_PIPC_596B) || (dev->power_regs[0x40] & 0x08), 0x604, 8); + pipc_trap_update_paden(dev, TRAP_AUD_WSS_2, 0x00000400, (dev->local <= VIA_PIPC_596B) || (dev->power_regs[0x40] & 0x08), 0xe80, 8); + pipc_trap_update_paden(dev, TRAP_AUD_WSS_3, 0x00000400, (dev->local <= VIA_PIPC_596B) || (dev->power_regs[0x40] & 0x08), 0xf40, 8); +} + + static void pipc_sgd_handlers(pipc_t *dev, uint8_t modem) { @@ -882,17 +1106,21 @@ pipc_write(int func, int addr, uint8_t val, void *priv) dev->pci_isa_regs[(addr - 0x44)] = val; break; + case 0x74: case 0x8b: + case 0x78: case 0x79: case 0x7a: case 0x7b: + case 0x8c: case 0x8d: case 0x8e: case 0x8f: + case 0x80: case 0x8a: + dev->pci_isa_regs[addr] = val; + pipc_pcs_update(dev); + break; + case 0x77: - if (val & 0x10) + if ((dev->local >= VIA_PIPC_686A) && (val & 0x10)) pclog("PIPC: Warning: Internal I/O APIC enabled.\n"); nvr_via_wp_set(!!(val & 0x04), 0x32, dev->nvr); nvr_via_wp_set(!!(val & 0x02), 0x0d, dev->nvr); break; - case 0x80: case 0x86: case 0x87: - dev->pci_isa_regs[addr] &= ~(val); - break; - default: dev->pci_isa_regs[addr] = val; break; @@ -1326,10 +1554,13 @@ pipc_init(const device_t *info) else if (dev->local >= VIA_PIPC_596A) dev->smbus = device_add(&piix4_smbus_device); - if (dev->local >= VIA_PIPC_596A) + if (dev->local >= VIA_PIPC_596A) { dev->acpi = device_add(&acpi_via_596b_device); - else if (dev->local >= VIA_PIPC_586B) + acpi_set_trap_update(dev->acpi, pipc_trap_update_596, dev); + } else if (dev->local >= VIA_PIPC_586B) { dev->acpi = device_add(&acpi_via_device); + acpi_set_trap_update(dev->acpi, pipc_trap_update_586, dev); + } dev->usb[0] = device_add_inst(&usb_device, 1); if (dev->local >= VIA_PIPC_686A) { @@ -1383,6 +1614,9 @@ pipc_close(void *p) pipc_log("PIPC: close()\n"); + for (int i = 0; i < TRAP_MAX; i++) + io_trap_remove(dev->io_traps[i].trap); + free(dev); } diff --git a/src/codegen/codegen_x86-64.c b/src/codegen/codegen_x86-64.c index e3e6ced89..289411b37 100644 --- a/src/codegen/codegen_x86-64.c +++ b/src/codegen/codegen_x86-64.c @@ -21,7 +21,7 @@ #include "codegen_ops.h" #include "codegen_ops_x86-64.h" -#if defined(__linux__) || defined(__APPLE__) +#if defined(__unix__) || defined(__APPLE__) #include #include #endif @@ -63,16 +63,11 @@ static int last_ssegs; void codegen_init() { int c; - -#if defined(__linux__) || defined(__APPLE__) - void *start; - size_t len; - long pagesize = sysconf(_SC_PAGESIZE); - long pagemask = ~(pagesize - 1); -#endif #if _WIN64 codeblock = VirtualAlloc(NULL, BLOCK_SIZE * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); +#elif defined(__unix__) || defined(__APPLE__) + codeblock = mmap(NULL, BLOCK_SIZE * sizeof(codeblock_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, 0, 0); #else codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); #endif @@ -83,16 +78,6 @@ void codegen_init() for (c = 0; c < BLOCK_SIZE; c++) codeblock[c].valid = 0; - -#if defined(__linux__) || defined(__APPLE__) - start = (void *)((long)codeblock & pagemask); - len = ((BLOCK_SIZE * sizeof(codeblock_t)) + pagesize) & pagemask; - if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) - { - perror("mprotect"); - exit(-1); - } -#endif } void codegen_reset() diff --git a/src/codegen/codegen_x86.c b/src/codegen/codegen_x86.c index beb245963..b4ba9bc9f 100644 --- a/src/codegen/codegen_x86.c +++ b/src/codegen/codegen_x86.c @@ -61,7 +61,7 @@ #include "codegen_ops.h" #include "codegen_ops_x86.h" -#ifdef __linux__ +#ifdef __unix__ #include #include #endif @@ -1173,15 +1173,10 @@ static uint32_t gen_MEM_CHECK_WRITE_L() void codegen_init() { -#ifdef __linux__ - void *start; - size_t len; - long pagesize = sysconf(_SC_PAGESIZE); - long pagemask = ~(pagesize - 1); -#endif - #ifdef _WIN32 codeblock = VirtualAlloc(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); +#elif defined __unix__ + codeblock = mmap(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, 0, 0); #else codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); #endif @@ -1190,16 +1185,6 @@ void codegen_init() memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); -#ifdef __linux__ - start = (void *)((long)codeblock & pagemask); - len = (((BLOCK_SIZE+1) * sizeof(codeblock_t)) + pagesize) & pagemask; - if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) - { - perror("mprotect"); - exit(-1); - } -#endif - block_current = BLOCK_SIZE; block_pos = 0; mem_abrt_rout = (uint32_t)&codeblock[block_current].data[block_pos]; diff --git a/src/config.c b/src/config.c index e0928cabe..7323b6a81 100644 --- a/src/config.c +++ b/src/config.c @@ -2056,28 +2056,29 @@ config_load(void) cassette_ui_writeprot = 0; config_log("Config file not present or invalid!\n"); - return; + } else { + load_general(); /* General */ + load_machine(); /* Machine */ + load_video(); /* Video */ + load_input_devices(); /* Input devices */ + load_sound(); /* Sound */ + load_network(); /* Network */ + load_ports(); /* Ports (COM & LPT) */ + load_storage_controllers(); /* Storage controllers */ + load_hard_disks(); /* Hard disks */ + load_floppy_and_cdrom_drives(); /* Floppy and CD-ROM drives */ + /* TODO: Backwards compatibility, get rid of this when enough time has passed. */ + load_floppy_drives(); /* Floppy drives */ + load_other_removable_devices(); /* Other removable devices */ + load_other_peripherals(); /* Other peripherals */ + + /* Mark the configuration as changed. */ + config_changed = 1; + + config_log("Config loaded.\n\n"); } - load_general(); /* General */ - load_machine(); /* Machine */ - load_video(); /* Video */ - load_input_devices(); /* Input devices */ - load_sound(); /* Sound */ - load_network(); /* Network */ - load_ports(); /* Ports (COM & LPT) */ - load_storage_controllers(); /* Storage controllers */ - load_hard_disks(); /* Hard disks */ - load_floppy_and_cdrom_drives(); /* Floppy and CD-ROM drives */ - /* TODO: Backwards compatibility, get rid of this when enough time has passed. */ - load_floppy_drives(); /* Floppy drives */ - load_other_removable_devices(); /* Other removable devices */ - load_other_peripherals(); /* Other peripherals */ - - /* Mark the configuration as changed. */ - config_changed = 1; - - config_log("Config loaded.\n\n"); + video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; } diff --git a/src/device/clock_ics9xxx.c b/src/device/clock_ics9xxx.c index df7aaf5fa..9f7e790af 100644 --- a/src/device/clock_ics9xxx.c +++ b/src/device/clock_ics9xxx.c @@ -124,7 +124,7 @@ static const ics9xxx_model_t ics9xxx_models[] = { .hw_select = {0, 3}, .frequencies_ref = ICS9250_08 ICS9xxx_MODEL_END() -#if 0 +#ifdef ENABLE_ICS9xxx_DETECT ICS9xxx_MODEL(ICS9248_81) .max_reg = 5, .regs = {0x82, 0xfe, 0x7f, 0xff, 0xff, 0xb7}, @@ -522,7 +522,7 @@ static const ics9xxx_model_t ics9xxx_models[] = { ICS9xxx_MODEL(ICS9250_08) .max_reg = 5, .regs = {0x00, 0xff, 0xff, 0xff, 0x6d, 0xbf}, - .fs_regs = {{0, 4, 4, 7}, {0, 5, 4, 4}, {0, 6, 5, 6}, {0, 7, 4, 1}, {-1, -1, -1, -1}}, + .fs_regs = {{0, 4, 4, 7}, {0, 5, 4, 4}, {0, 6, 5, 6}, {0, 2, 4, 1}, {-1, -1, -1, -1}}, .hw_select = {0, 3}, .frequencies = (const ics9xxx_frequency_t[]) { {.bus = 12400, .pci_div = 3}, @@ -544,7 +544,7 @@ static const ics9xxx_model_t ics9xxx_models[] = { {0} } ICS9xxx_MODEL_END() -#if 0 +#ifdef ENABLE_ICS9xxx_DETECT ICS9xxx_MODEL(ICS9250_10) .max_reg = 5, .regs = {0x1f, 0xff, 0xfe, 0x00, 0x00, 0x06}, @@ -703,7 +703,7 @@ static const ics9xxx_model_t ics9xxx_models[] = { {0} } ICS9xxx_MODEL_END() -#if 0 +#ifdef ENABLE_ICS9xxx_DETECT ICS9xxx_MODEL(ICS9250_19) .max_reg = 5, .regs = {0x02, 0xff, 0xff, 0xff, 0x6d, 0xbf}, @@ -1199,7 +1199,7 @@ ics9xxx_init(const device_t *info) uint8_t i; #ifdef ENABLE_ICS9xxx_DETECT - for (i = 0; i < ICS9xxx_MAX; i++) { + for (i = ICS9xxx_xx + 1; i < ICS9xxx_MAX; i++) { if (ics9xxx_models[i].frequencies_ref || !ics9xxx_models[i].name) continue; for (uint8_t j = 0; j < i; j++) { diff --git a/src/device/hwm_lm78.c b/src/device/hwm_lm78.c index e849190cf..b9ed2e699 100644 --- a/src/device/hwm_lm78.c +++ b/src/device/hwm_lm78.c @@ -37,8 +37,8 @@ #define LM78_AS99127F_REV1 0x040000 #define LM78_AS99127F_REV2 0x080000 #define LM78_W83782D 0x100000 -#define LM78_AS99127F (LM78_AS99127F_REV1 | LM78_AS99127F_REV2) /* special mask covering both _REV1 and _REV2 */ -#define LM78_WINBOND (LM78_W83781D | LM78_AS99127F | LM78_W83782D) /* special mask covering all Winbond variants */ +#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) #define LM78_WINBOND_BANK (dev->regs[0x4e] & 0x07) @@ -363,9 +363,12 @@ lm78_read(lm78_t *dev, uint8_t reg, uint8_t bank) ret = LM78_VOLTAGE_TO_REG(dev->values->voltages[7 + masked_reg]); else if (masked_reg == 0x27) /* temperature */ ret = dev->values->temperatures[0]; - else if ((masked_reg >= 0x28) && (masked_reg <= 0x2a)) /* fan speeds */ - ret = LM78_RPM_TO_REG(dev->values->fans[reg & 3], 1 << ((dev->regs[((reg & 3) == 2) ? 0x4b : 0x47] >> ((reg & 3) ? 6 : 4)) & 0x3)); - else if ((reg == 0x4f) && (dev->local & LM78_WINBOND)) /* two-byte vendor ID register */ + else if ((masked_reg >= 0x28) && (masked_reg <= 0x2a)) { /* fan speeds */ + ret = (dev->regs[((reg & 3) == 2) ? 0x4b : 0x47] >> ((reg & 3) ? 6 : 4)) & 0x03; /* bits [1:0] */ + if (dev->local & LM78_W83782D) + ret |= (dev->regs[0x5d] >> (3 + (reg & 3))) & 0x04; /* bit 2 */ + ret = LM78_RPM_TO_REG(dev->values->fans[reg & 3], 1 << ret); + } else if ((reg == 0x4f) && (dev->local & LM78_WINBOND)) /* two-byte vendor ID register */ ret = (dev->regs[0x4e] & 0x80) ? (uint8_t) (LM78_WINBOND_VENDOR_ID >> 8) : (uint8_t) LM78_WINBOND_VENDOR_ID; else ret = dev->regs[masked_reg]; diff --git a/src/include/86box/acpi.h b/src/include/86box/acpi.h index 08019d352..91c63b74e 100644 --- a/src/include/86box/acpi.h +++ b/src/include/86box/acpi.h @@ -39,6 +39,13 @@ extern "C" { #define SCI_EN (1 << 0) #define SUS_EN (1 << 13) +#define SUS_POWER_OFF (1 << 0) +#define SUS_SUSPEND (1 << 1) +#define SUS_NVR (1 << 2) +#define SUS_RESET_CPU (1 << 3) +#define SUS_RESET_CACHE (1 << 4) +#define SUS_RESET_PCI (1 << 5) + #define ACPI_ENABLE 0xf1 #define ACPI_DISABLE 0xf0 @@ -56,7 +63,8 @@ typedef struct smicmd, gpio_dir, gpio_val, muxcntrl, pad, timer32, smireg, - gpireg[3], gporeg[4]; + gpireg[3], gporeg[4], + extiotrapsts, extiotrapen; uint16_t pmsts, pmen, pmcntrl, gpsts, gpsts1, gpen, gpen1, gpscien, @@ -79,15 +87,17 @@ typedef struct { acpi_regs_t regs; uint8_t gpireg2_default, pad[3], - gporeg_default[4]; + gporeg_default[4], + suspend_types[8]; uint16_t io_base, aux_io_base; int vendor, slot, irq_mode, irq_pin, irq_line; - pc_timer_t timer; + pc_timer_t timer, resume_timer; nvr_t *nvr; apm_t *apm; - void *i2c; + void *i2c, + (*trap_update)(void *priv), *trap_priv; } acpi_t; @@ -103,6 +113,8 @@ 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_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); @@ -113,6 +125,7 @@ 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_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); #ifdef __cplusplus } diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 0c0e36299..3ea2e52f8 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -75,6 +75,7 @@ extern const device_t i440fx_device; extern const device_t i440lx_device; extern const device_t i440ex_device; 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; @@ -117,7 +118,6 @@ extern const device_t sis_85c496_ls486e_device; extern const device_t sis_85c50x_device; extern const device_t sis_5511_device; extern const device_t sis_5571_device; -extern const device_t sis_5598_device; /* ST */ extern const device_t stpc_client_device; diff --git a/src/include/86box/clock.h b/src/include/86box/clock.h index b1a3df478..7d2be9f05 100644 --- a/src/include/86box/clock.h +++ b/src/include/86box/clock.h @@ -22,7 +22,6 @@ enum { ICS9xxx_xx, ICS9150_08, ICS9248_39, -#if 0 ICS9248_81, ICS9248_95, ICS9248_98, @@ -35,16 +34,12 @@ enum { ICS9248_143, ICS9248_151, ICS9248_192, -#endif ICS9250_08, -#if 0 ICS9250_10, ICS9250_13, ICS9250_14, ICS9250_16, -#endif ICS9250_18, -#if 0 ICS9250_19, ICS9250_23, ICS9250_25, @@ -56,7 +51,6 @@ enum { ICS9250_32, ICS9250_38, ICS9250_50, -#endif ICS9xxx_MAX }; diff --git a/src/include/86box/io.h b/src/include/86box/io.h index 6112ea8e4..c483819ce 100644 --- a/src/include/86box/io.h +++ b/src/include/86box/io.h @@ -111,5 +111,10 @@ extern void outw(uint16_t port, uint16_t val); extern uint32_t inl(uint16_t port); extern void outl(uint16_t port, uint32_t val); +extern void *io_trap_add(void (*func)(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv), + void *priv); +extern void io_trap_remap(void *handle, int enable, uint16_t addr, uint16_t size); +extern void io_trap_remove(void *handle); + #endif /*EMU_IO_H*/ diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 69ba7645e..50cedccca 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -481,9 +481,6 @@ extern int machine_at_ficva502_init(const machine_t *); extern int machine_at_ficpa2012_init(const machine_t *); -extern int machine_at_sp97xv_init(const machine_t *); -extern int machine_at_m571_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); @@ -559,10 +556,9 @@ extern int machine_at_awo671r_init(const machine_t *); extern int machine_at_63a_init(const machine_t *); extern int machine_at_s370sba_init(const machine_t *); extern int machine_at_apas3_init(const machine_t *); -extern int machine_at_wcf681_init(const machine_t *); +extern int machine_at_gt694va_init(const machine_t *); extern int machine_at_cuv4xls_init(const machine_t *); extern int machine_at_6via90ap_init(const machine_t *); -extern int machine_at_603tcf_init(const machine_t *); extern int machine_at_trinity371_init(const machine_t *); extern int machine_at_p6bap_init(const machine_t *); @@ -651,7 +647,7 @@ extern int machine_xt_pc4i_init(const machine_t *); extern int machine_xt_mpc1600_init(const machine_t *); extern int machine_xt_pcspirit_init(const machine_t *); extern int machine_xt_pc700_init(const machine_t *); -extern int machine_xt_multitechpc500_init(const machine_t *); +extern int machine_xt_pc500_init(const machine_t *); extern int machine_xt_iskra3104_init(const machine_t *); diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 95a74f65f..d413add7d 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -105,6 +105,8 @@ extern void plat_path_slash(char *path); extern int plat_path_abs(char *path); extern int plat_dir_check(char *path); extern int plat_dir_create(char *path); +extern void *plat_mmap(size_t size, uint8_t executable); +extern void plat_munmap(void *ptr, size_t size); extern uint64_t plat_timer_read(void); extern uint32_t plat_get_ticks(void); extern uint32_t plat_get_micro_ticks(void); diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 91559aa72..30d30254c 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -23,7 +23,8 @@ #define FLAG_EXT_WRITE 4 #define FLAG_LATCH8 8 #define FLAG_NOSKEW 16 -#define FLAG_ADDR_BY16 32 +#define FLAG_ADDR_BY16 32 +#define FLAG_RAMDAC_SHIFT 64 typedef struct { @@ -289,7 +290,7 @@ extern const device_t icd2061_device; extern const device_t ics9161_device; extern const device_t sc11483_ramdac_device; extern const device_t sc11487_ramdac_device; -extern const device_t sc11484_ramdac_device; +extern const device_t sc11486_ramdac_device; extern const device_t sc11484_nors2_ramdac_device; extern const device_t sc1502x_ramdac_device; extern const device_t sdac_ramdac_device; diff --git a/src/include/86box/vid_voodoo_codegen_x86-64.h b/src/include/86box/vid_voodoo_codegen_x86-64.h index 4e6cbcaf2..443edc2cd 100644 --- a/src/include/86box/vid_voodoo_codegen_x86-64.h +++ b/src/include/86box/vid_voodoo_codegen_x86-64.h @@ -5,16 +5,6 @@ fbzColorPath */ -#if defined(__linux__) || defined(__APPLE__) -#include -#include -#endif -#if _WIN64 -#define BITMAP windows_BITMAP -#include -#undef BITMAP -#endif - #ifdef _MSC_VER #include #else @@ -3432,11 +3422,7 @@ void voodoo_codegen_init(voodoo_t *voodoo) { int c; -#if _WIN64 - voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM * 4, MEM_COMMIT, PAGE_EXECUTE_READWRITE); -#else - voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); -#endif + voodoo->codegen_data = plat_mmap(sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, 1); for (c = 0; c < 256; c++) { @@ -3462,10 +3448,5 @@ void voodoo_codegen_init(voodoo_t *voodoo) void voodoo_codegen_close(voodoo_t *voodoo) { -#if _WIN64 - VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE); -#else - munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4); -#endif + plat_munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4); } - diff --git a/src/include/86box/vid_voodoo_codegen_x86.h b/src/include/86box/vid_voodoo_codegen_x86.h index f84ee00aa..d54a7e683 100644 --- a/src/include/86box/vid_voodoo_codegen_x86.h +++ b/src/include/86box/vid_voodoo_codegen_x86.h @@ -5,16 +5,6 @@ fbzColorPath */ -#if defined(__linux__) || defined(__APPLE__) -#include -#include -#endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 -#define BITMAP windows_BITMAP -#include -#undef BITMAP -#endif - #ifdef _MSC_VER #include #else @@ -3378,11 +3368,7 @@ void voodoo_codegen_init(voodoo_t *voodoo) long pagemask = ~(pagesize - 1); #endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 - voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, MEM_COMMIT, PAGE_EXECUTE_READWRITE); -#else - voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); -#endif + voodoo->codegen_data = plat_mmap(sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, 1); for (c = 0; c < 256; c++) { @@ -3408,9 +3394,5 @@ void voodoo_codegen_init(voodoo_t *voodoo) void voodoo_codegen_close(voodoo_t *voodoo) { -#if defined WIN32 || defined _WIN32 || defined _WIN32 - VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE); -#else - munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4); -#endif + plat_munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4); } diff --git a/src/include/86box/video.h b/src/include/86box/video.h index e22eda015..63f854fb9 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -133,6 +133,15 @@ extern int readflash; /* Function handler pointers. */ extern void (*video_recalctimings)(void); +extern void video_screenshot(uint32_t *buf, int start_x, int start_y, int row_len); + +#ifdef _WIN32 +extern void * __cdecl (*video_copy)(void *_Dst, const void *_Src, size_t _Size); +extern void * __cdecl video_transform_copy(void *_Dst, const void *_Src, size_t _Size); +#else +extern void * (*video_copy)(void *__restrict _Dst, const void *__restrict _Src, size_t _Size); +extern void * video_transform_copy(void *__restrict _Dst, const void *__restrict _Src, size_t _Size); +#endif /* Table functions. */ diff --git a/src/io.c b/src/io.c index 2751cc639..d704a036a 100644 --- a/src/io.c +++ b/src/io.c @@ -35,19 +35,26 @@ typedef struct _io_ { - uint8_t (*inb)(uint16_t addr, void *priv); - uint16_t (*inw)(uint16_t addr, void *priv); - uint32_t (*inl)(uint16_t addr, void *priv); + uint8_t (*inb)(uint16_t addr, void *priv); + uint16_t (*inw)(uint16_t addr, void *priv); + uint32_t (*inl)(uint16_t addr, void *priv); - void (*outb)(uint16_t addr, uint8_t val, void *priv); - void (*outw)(uint16_t addr, uint16_t val, void *priv); - void (*outl)(uint16_t addr, uint32_t val, void *priv); + void (*outb)(uint16_t addr, uint8_t val, void *priv); + void (*outw)(uint16_t addr, uint16_t val, void *priv); + void (*outl)(uint16_t addr, uint32_t val, void *priv); - void *priv; + void *priv; - struct _io_ *prev, *next; + struct _io_ *prev, *next; } io_t; +typedef struct { + uint8_t enable; + uint16_t base, size; + void (*func)(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv), + *priv; +} io_trap_t; + int initialized = 0; io_t *io[NPORTS], *io_last[NPORTS]; @@ -583,3 +590,116 @@ outl(uint16_t port, uint32_t val) return; } + + +static uint8_t +io_trap_readb(uint16_t addr, void *priv) +{ + io_trap_t *trap = (io_trap_t *) priv; + trap->func(1, addr, 0, 0, trap->priv); + return 0xff; +} + + +static uint16_t +io_trap_readw(uint16_t addr, void *priv) +{ + io_trap_t *trap = (io_trap_t *) priv; + trap->func(2, addr, 0, 0, trap->priv); + return 0xffff; +} + + +static uint32_t +io_trap_readl(uint16_t addr, void *priv) +{ + io_trap_t *trap = (io_trap_t *) priv; + trap->func(4, addr, 0, 0, trap->priv); + return 0xffffffff; +} + + +static void +io_trap_writeb(uint16_t addr, uint8_t val, void *priv) +{ + io_trap_t *trap = (io_trap_t *) priv; + trap->func(1, addr, 1, val, trap->priv); +} + + +static void +io_trap_writew(uint16_t addr, uint16_t val, void *priv) +{ + io_trap_t *trap = (io_trap_t *) priv; + trap->func(2, addr, 1, val, trap->priv); +} + + +static void +io_trap_writel(uint16_t addr, uint32_t val, void *priv) +{ + io_trap_t *trap = (io_trap_t *) priv; + trap->func(4, addr, 1, val, trap->priv); +} + + +void * +io_trap_add(void (*func)(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv), + void *priv) +{ + /* Instantiate new I/O trap. */ + io_trap_t *trap = (io_trap_t *) malloc(sizeof(io_trap_t)); + trap->enable = 0; + trap->base = trap->size = 0; + trap->func = func; + trap->priv = priv; + + return trap; +} + + +void +io_trap_remap(void *handle, int enable, uint16_t addr, uint16_t size) +{ + io_trap_t *trap = (io_trap_t *) handle; + if (!trap) + return; + + io_log("I/O: Remapping trap from %04X-%04X (enable %d) to %04X-%04X (enable %d)\n", + trap->base, trap->base + trap->size - 1, trap->enable, addr, addr + size - 1, enable); + + /* Remove old I/O mapping. */ + if (trap->enable && trap->base && trap->size) { + io_removehandler(trap->base, trap->size, + io_trap_readb, io_trap_readw, io_trap_readl, + io_trap_writeb, io_trap_writew, io_trap_writel, + trap); + } + + /* Set trap enable flag, base address and size. */ + trap->enable = !!enable; + trap->base = addr; + trap->size = size; + + /* Add new I/O mapping. */ + if (trap->enable && trap->base && trap->size) { + io_sethandler(trap->base, trap->size, + io_trap_readb, io_trap_readw, io_trap_readl, + io_trap_writeb, io_trap_writew, io_trap_writel, + trap); + } +} + + +void +io_trap_remove(void *handle) +{ + io_trap_t *trap = (io_trap_t *) handle; + if (!trap) + return; + + /* Unmap I/O trap before freeing it. */ + io_trap_remap(trap, 0, 0, 0); + + free(trap); +} diff --git a/src/machine/m_at_misc.c b/src/machine/m_at_misc.c index aff270d95..f96523bf3 100644 --- a/src/machine/m_at_misc.c +++ b/src/machine/m_at_misc.c @@ -63,7 +63,7 @@ machine_at_vpc2007_init(const machine_t *model) pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); - device_add(&i440bx_device); + device_add(&i440bx_no_agp_device); device_add(&piix4e_device); device_add(&w83977f_370_device); device_add(&keyboard_ps2_ami_pci_device); diff --git a/src/machine/m_at_slot2.c b/src/machine/m_at_slot2.c index cf7a29acf..84c789990 100644 --- a/src/machine/m_at_slot2.c +++ b/src/machine/m_at_slot2.c @@ -9,7 +9,8 @@ * Implementation of Slot 2 machines. * * Slot 2 is quite a rare type of Slot. Used mostly by Pentium II & III Xeons - * These boards were also capable to take Slot 1 CPU's using Slot 2 to 1 adapters. + * + * * * Authors: Miran Grca, * @@ -35,6 +36,7 @@ #include <86box/hwm.h> #include <86box/spd.h> #include <86box/video.h> +#include <86box/clock.h> #include "cpu.h" #include <86box/machine.h> @@ -67,10 +69,7 @@ machine_at_6gxu_init(const machine_t *model) device_add(&w83977ef_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 512); - device_add(&w83782d_device); /* fans: ???, ???, System; temperatures: System, CPU, unused */ - hwm_values.fans[0] = 2000; - hwm_values.fans[1] = 2500; - hwm_values.fans[2] = 3000; + device_add(&w83782d_device); /* fans: CPU, Power, System; temperatures: System, CPU, unused */ hwm_values.temperatures[2] = 0; /* unused */ hwm_values.voltages[1] = 1500; /* VGTL */ @@ -143,6 +142,7 @@ machine_at_fw6400gx_init(const machine_t *model) device_add(&piix4e_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&pc87309_15c_device); + device_add(ics9xxx_get(ICS9250_08)); device_add(&sst_flash_29ee020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 512); device_add(&w83781d_device); /* fans: Chassis, Power, CPU; temperatures: System, CPU, unused */ diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 14f5e0dca..4d8b5c5a5 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -343,11 +343,11 @@ machine_at_apas3_init(const machine_t *model) int -machine_at_wcf681_init(const machine_t *model) +machine_at_gt694va_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/wcf681/681osda2.bin", + ret = bios_load_linear("roms/machines/gt694va/21071100.bin", 0x000c0000, 262144, 0); if (bios_only || !ret) @@ -357,24 +357,24 @@ machine_at_wcf681_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, 0, 0); - pci_register_slot(0x14, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x12, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&via_apro133a_device); device_add(&via_vt82c596b_device); - device_add(&w83977tf_device); + device_add(&w83977ef_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0x3, 512); - device_add(&w83781d_device); /* fans: CPU, unused, unused; temperatures: System, unused, CPU */ - hwm_values.voltages[1] = 2500; /* +2.5V */ + spd_register(SPD_TYPE_SDRAM, 0x7, 1024); + device_add(&w83782d_device); /* fans: CPU, unused, unused; temperatures: System, CPU1, unused */ + hwm_values.voltages[1] = 1500; /* IN1 (unknown purpose, assumed Vtt) */ + hwm_values.fans[0] = 4500; /* BIOS does not display <4411 RPM */ hwm_values.fans[1] = 0; /* unused */ hwm_values.fans[2] = 0; /* unused */ - hwm_values.temperatures[1] = 0; /* unused */ + hwm_values.temperatures[2] = 0; /* unused */ return ret; } @@ -411,7 +411,7 @@ machine_at_cuv4xls_init(const machine_t *model) device_add(&keyboard_ps2_ami_pci_device); device_add(ics9xxx_get(ICS9250_18)); device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 512); + spd_register(SPD_TYPE_SDRAM, 0xF, 1024); device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */ return ret; @@ -446,7 +446,7 @@ machine_at_6via90ap_init(const machine_t *model) device_add(&keyboard_ps2_ami_pci_device); device_add(ics9xxx_get(ICS9250_18)); device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 512); + spd_register(SPD_TYPE_SDRAM, 0x7, 1024); device_add(&via_vt82c686_hwm_device); /* fans: CPU1, CPU2; temperatures: CPU, System, unused */ hwm_values.temperatures[0] += 2; /* CPU offset */ hwm_values.temperatures[1] += 2; /* System offset */ @@ -456,39 +456,3 @@ machine_at_6via90ap_init(const machine_t *model) return ret; } - - -int -machine_at_603tcf_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/603tcf/603tcfA4.BIN", - 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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 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(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&via_vt8601_device); - device_add(&via_vt82c686b_device); - device_add(&via_vt82c686_sio_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0x3, 512); - device_add(&via_vt82c686_hwm_device); /* fans: 1, 2; temperatures: CPU, System, unused */ - hwm_values.temperatures[0] += 2; /* CPU offset */ - hwm_values.temperatures[1] += 2; /* System offset */ - hwm_values.temperatures[2] = 0; /* unused */ - - return ret; -} diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 5ba8a69a3..2edf96595 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1312,55 +1312,3 @@ machine_at_ficpa2012_init(const machine_t *model) return ret; } - -int -machine_at_sp97xv_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/sp97xv/0109XV.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(0x01, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - device_add(&sis_5598_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&w83877f_device); - device_add(&sst_flash_29ee010_device); - - return ret; -} - -int -machine_at_m571_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/m571/2k0621s.rom", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); - device_add(&sis_5598_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&it8661f_device); - device_add(&sst_flash_29ee020_device); - - return ret; -} diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index 1aa892415..318e8dfea 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -55,11 +55,11 @@ machine_at_p6rp4_init(const machine_t *model) 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(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); pci_register_slot(0x06, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x04, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x08, PCI_CARD_IDE, 0, 0, 0, 0); device_add(&i450kx_device); device_add(&sio_zb_device); device_add(&keyboard_ps2_ami_pci_device); diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index c54c7f0c7..35ddfe6da 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -859,8 +859,8 @@ machine_pcjr_init(const machine_t *model) keyboard_set_table(scancode_xt); keyboard_send = kbd_adddata_ex; - /* Technically it's the SN76496N, but the NCR 8496 is a drop-in replacement for it. */ - device_add(&ncr8496_device); + /* Technically it's the SN76496N, but the SN76489 is identical to the SN76496N. */ + device_add(&sn76489_device); nmi_mask = 0x80; diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index ce251eda7..6e68c81bf 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -427,11 +427,11 @@ machine_xt_pc700_init(const machine_t *model) int -machine_xt_multitechpc500_init(const machine_t* model) +machine_xt_pc500_init(const machine_t* model) { int ret; - ret = bios_load_linear("roms/machines/multitech_pc500/rom404.bin", + ret = bios_load_linear("roms/machines/pc500/rom404.bin", 0x000f8000, 32768, 0); if (bios_only || !ret) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 4f65bb383..9dd5db1fa 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -73,7 +73,7 @@ const machine_t machines[] = { { "[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 }, - { "[8088] Multitech PC-500", "multitech_pc500", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_multitechpc500_init, NULL }, + { "[8088] Multitech PC-500", "pc500", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_pc500_init, NULL }, { "[8088] Multitech PC-700", "pc700", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_pc700_init, NULL }, { "[8088] NCR PC4i", "pc4i", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 640, 256, 0, machine_xt_pc4i_init, NULL }, { "[8088] Olivetti M19", "m19", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 4772728, 7159092, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 256, 640, 256, 0, machine_xt_m19_init, m19_get_device }, @@ -242,7 +242,7 @@ const machine_t machines[] = { { "[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 }, - { "[VIA VT82C496G] FIC VIP-IO2", "486vipio2", 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_486vipio2_init, NULL }, + { "[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 */ @@ -364,10 +364,6 @@ const machine_t machines[] = { { "[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 }, { "[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 }, - /* SiS 5598 */ - { "[SiS 5598] ASUS SP97-XV", "sp97xv", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 2100, 3200, 1.5, 2.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 255, machine_at_sp97xv_init, NULL }, - { "[SiS 5598] PC Chips M571", "m571", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 75000000, 2500, 3500, 1.5, 3.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 255, machine_at_m571_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 }, @@ -459,15 +455,14 @@ const machine_t machines[] = { { "[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 */ - { "[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 }, - { "[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] AEWIN WCF-681", "wcf681", 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,1048576, 8192, 255, machine_at_wcf681_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,1572864, 8192, 255, machine_at_cuv4xls_init, NULL }, - { "[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, 8192,1572864, 8192, 255, machine_at_6via90ap_init, NULL }, - { "[VIA Apollo ProMedia] Jetway 603TCF", "603tcf", 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_603tcf_init, NULL }, + { "[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 }, + { "[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 }, + { "[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 }, /* Miscellaneous/Fake/Hypervisor machines */ - { "[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_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_vpc2007_init, NULL }, + { "[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 4a3a9145f..75ddb8c53 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -34,6 +34,7 @@ #include <86box/config.h> #include <86box/io.h> #include <86box/mem.h> +#include <86box/plat.h> #include <86box/rom.h> #ifdef USE_DYNAREC # include "codegen_public.h" @@ -128,6 +129,11 @@ static uint8_t *_mem_exec[MEM_MAPPINGS_NO]; static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff }; static mem_state_t _mem_state[MEM_MAPPINGS_NO]; static uint32_t remap_start_addr; +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) +static size_t ram_size = 0, ram2_size = 0; +#else +static size_t ram_size = 0; +#endif #ifdef ENABLE_MEM_LOG @@ -1590,7 +1596,7 @@ do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write) a64[i] = (uint64_t) addr; for (i = 0; i < num; i++) { - if (cr0 >> 31) { + if (cr0 >> 31) { if (write && ((i == 0) || !(addr & 0xfff))) cond = (!page_lookup[addr >> 12] || !page_lookup[addr >> 12]->write_b); @@ -1660,7 +1666,7 @@ mem_readw_phys(uint32_t addr) p = (uint16_t *) &(map->exec[addr - map->base]); ret = *p; } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->read_w)) - ret = map->read_w(addr, map->p); + ret = map->read_w(addr, map->p); else { ret = mem_readb_phys(addr + 1) << 8; ret |= mem_readb_phys(addr); @@ -1682,7 +1688,7 @@ mem_readl_phys(uint32_t addr) p = (uint32_t *) &(map->exec[addr - map->base]); ret = *p; } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->read_l)) - ret = map->read_l(addr, map->p); + ret = map->read_l(addr, map->p); else { ret = mem_readw_phys(addr + 2) << 16; ret |= mem_readw_phys(addr); @@ -1740,7 +1746,7 @@ mem_writew_phys(uint32_t addr, uint16_t val) p = (uint16_t *) &(map->exec[addr - map->base]); *p = val; } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->write_w)) - map->write_w(addr, val, map->p); + map->write_w(addr, val, map->p); else { mem_writeb_phys(addr, val & 0xff); mem_writeb_phys(addr + 1, (val >> 8) & 0xff); @@ -1760,7 +1766,7 @@ mem_writel_phys(uint32_t addr, uint32_t val) p = (uint32_t *) &(map->exec[addr - map->base]); *p = val; } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->write_l)) - map->write_l(addr, val, map->p); + map->write_l(addr, val, map->p); else { mem_writew_phys(addr, val & 0xffff); mem_writew_phys(addr + 2, (val >> 16) & 0xffff); @@ -2606,30 +2612,34 @@ mem_reset(void) } if (ram != NULL) { - free(ram); + plat_munmap(ram, ram_size); ram = NULL; + ram_size = 0; } #if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) if (ram2 != NULL) { - free(ram2); + plat_munmap(ram2, ram2_size); ram2 = NULL; + ram2_size = 0; } -#endif if (mem_size > 2097152) - fatal("Attempting to use more than 2 GB of emulated RAM\n"); + mem_size = 2097152; +#endif m = 1024UL * mem_size; #if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) if (mem_size > 1048576) { - ram = (uint8_t *)malloc(1 << 30); /* allocate and clear the RAM block of the first 1 GB */ + ram_size = 1 << 30; + ram = (uint8_t *) plat_mmap(ram_size, 0); /* allocate and clear the RAM block of the first 1 GB */ if (ram == NULL) { fatal("Failed to allocate primary RAM block. Make sure you have enough RAM available.\n"); return; } - memset(ram, 0x00, (1 << 30)); - ram2 = (uint8_t *)malloc(m - (1 << 30)); /* allocate and clear the RAM block above 1 GB */ + memset(ram, 0x00, ram_size); + ram2_size = m - (1 << 30); + ram2 = (uint8_t *) plat_mmap(ram2_size, 0); /* allocate and clear the RAM block above 1 GB */ if (ram2 == NULL) { if (config_changed == 2) fatal(EMU_NAME " must be restarted for the memory amount change to be applied.\n"); @@ -2637,25 +2647,20 @@ mem_reset(void) fatal("Failed to allocate secondary RAM block. Make sure you have enough RAM available.\n"); return; } - memset(ram2, 0x00, m - (1 << 30)); - } else { - ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */ + memset(ram2, 0x00, ram2_size); + } else +#endif + { + ram_size = m; + ram = (uint8_t *) plat_mmap(ram_size, 0); /* allocate and clear the RAM block */ if (ram == NULL) { fatal("Failed to allocate RAM block. Make sure you have enough RAM available.\n"); return; } - memset(ram, 0x00, m); + memset(ram, 0x00, ram_size); + if (mem_size > 1048576) + ram2 = &(ram[1 << 30]); } -#else - ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */ - if (ram == NULL) { - fatal("Failed to allocate RAM block. Make sure you have enough RAM available.\n"); - return; - } - memset(ram, 0x00, m); - if (mem_size > 1048576) - ram2 = &(ram[1 << 30]); -#endif /* * Allocate the page table based on how much RAM we have. diff --git a/src/mem/spd.c b/src/mem/spd.c index 32b49a101..b5400de4b 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -167,6 +167,22 @@ spd_populate(uint16_t *rows, uint8_t slot_count, uint16_t total_size, uint16_t m } +static int +spd_write_part_no(char *part_no, char *type, uint16_t size) +{ + char size_unit; + + if (size >= 1024) { + size_unit = 'G'; + size >>= 10; + } else { + size_unit = 'M'; + } + + return sprintf(part_no, EMU_NAME "-%s-%03d%c", type, size, size_unit); +} + + void spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) { @@ -204,7 +220,7 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) /* Register SPD devices and populate their data according to the rows. */ row = 0; - for (slot = 0; slot < SPD_MAX_SLOTS && rows[row]; slot++) { + for (slot = 0; (slot < SPD_MAX_SLOTS) && rows[row]; slot++) { if (!(slot_mask & (1 << slot))) continue; /* slot disabled */ @@ -249,8 +265,8 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) edo_data->dram_width = 8; edo_data->spd_rev = 0x12; - sprintf(edo_data->part_no, EMU_NAME "-%s-%03dM", (ram_type == SPD_TYPE_FPM) ? "FPM" : "EDO", rows[row]); - for (i = strlen(edo_data->part_no); i < sizeof(edo_data->part_no); i++) + for (i = spd_write_part_no(edo_data->part_no, (ram_type == SPD_TYPE_FPM) ? "FPM" : "EDO", rows[row]); + i < sizeof(edo_data->part_no); i++) edo_data->part_no[i] = ' '; /* part number should be space-padded */ edo_data->rev_code[0] = BCD8(EMU_VERSION_MAJ); edo_data->rev_code[1] = BCD8(EMU_VERSION_MIN); @@ -303,8 +319,8 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) sdram_data->ca_hold = sdram_data->data_hold = 0x08; sdram_data->spd_rev = 0x12; - sprintf(sdram_data->part_no, EMU_NAME "-SDR-%03dM", rows[row]); - for (i = strlen(sdram_data->part_no); i < sizeof(sdram_data->part_no); i++) + for (i = spd_write_part_no(sdram_data->part_no, "SDR", rows[row]); + i < sizeof(sdram_data->part_no); i++) sdram_data->part_no[i] = ' '; /* part number should be space-padded */ sdram_data->rev_code[0] = BCD8(EMU_VERSION_MAJ); sdram_data->rev_code[1] = BCD8(EMU_VERSION_MIN); diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index b081d7632..4956f7742 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -145,6 +145,8 @@ typedef struct { #define INT_DAC2_EN (1<<5) #define INT_UART_EN (1<<3) +#define SI_P2_PAUSE (1<<12) +#define SI_P1_PAUSE (1<<11) #define SI_P2_INTR_EN (1<<9) #define SI_P1_INTR_EN (1<<8) @@ -1507,6 +1509,9 @@ es1371_pci_write(int func, int addr, uint8_t val, void *p) static void es1371_fetch(es1371_t *dev, int dac_nr) { + if (dev->si_cr & (dac_nr ? SI_P2_PAUSE : SI_P1_PAUSE)) + return; + int format = dac_nr ? ((dev->si_cr >> 2) & 3) : (dev->si_cr & 3); int pos = dev->dac[dac_nr].buffer_pos & 63; int c; diff --git a/src/sound/snd_cms.c b/src/sound/snd_cms.c index 631e00c6a..15a065776 100644 --- a/src/sound/snd_cms.c +++ b/src/sound/snd_cms.c @@ -207,7 +207,7 @@ static const device_config_t cms_config[] = const device_t cms_device = { "Creative Music System / Game Blaster", - 0, 0, + DEVICE_ISA, 0, cms_init, cms_close, NULL, { NULL }, NULL, NULL, cms_config diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index fe94ebf2f..003b93b58 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -1315,7 +1315,7 @@ static const device_config_t gus_config[] = { const device_t gus_device = { "Gravis UltraSound", - DEVICE_ISA, + DEVICE_ISA | DEVICE_AT, 0, gus_init, gus_close, NULL, { NULL }, diff --git a/src/sound/snd_mpu401.c b/src/sound/snd_mpu401.c index b407ceea9..95cdb1a52 100644 --- a/src/sound/snd_mpu401.c +++ b/src/sound/snd_mpu401.c @@ -1805,22 +1805,43 @@ static const device_config_t mpu401_standalone_config[] = { "base", "MPU-401 Address", CONFIG_HEX16, "", 0x330, "", { 0 }, { + { + "0x220", 0x220 + }, + { + "0x230", 0x230 + }, + { + "0x240", 0x240 + }, + { + "0x250", 0x250 + }, { "0x300", 0x300 }, + { + "0x320", 0x320 + }, { "0x330", 0x330 }, + { + "0x340", 0x340 + }, + { + "0x350", 0x350 + }, { "" } } }, { - "irq", "MPU-401 IRQ", CONFIG_SELECTION, "", 9, "", { 0 }, + "irq", "MPU-401 IRQ", CONFIG_SELECTION, "", 2, "", { 0 }, { { - "IRQ 9", 9 + "IRQ 2", 2 }, { "IRQ 3", 3 @@ -1832,10 +1853,10 @@ static const device_config_t mpu401_standalone_config[] = "IRQ 5", 5 }, { - "IRQ 7", 7 + "IRQ 6", 6 }, { - "IRQ 10", 10 + "IRQ 7", 7 }, { "" diff --git a/src/sound/snd_pssj.c b/src/sound/snd_pssj.c index bdf013e2e..4eab5c856 100644 --- a/src/sound/snd_pssj.c +++ b/src/sound/snd_pssj.c @@ -201,6 +201,20 @@ void *pssj_init(const device_t *info) return pssj; } +void *pssj_1e0_init(const device_t *info) +{ + pssj_t *pssj = malloc(sizeof(pssj_t)); + memset(pssj, 0, sizeof(pssj_t)); + + sn76489_init(&pssj->sn76489, 0x01e0, 0x0004, PSSJ, 3579545); + + io_sethandler(0x01E4, 0x0004, pssj_read, NULL, NULL, pssj_write, NULL, NULL, pssj); + timer_add(&pssj->timer_count, pssj_callback, pssj, pssj->enable); + sound_add_handler(pssj_get_buffer, pssj); + + return pssj; +} + void pssj_close(void *p) { pssj_t *pssj = (pssj_t *)p; @@ -219,3 +233,15 @@ const device_t pssj_device = NULL, NULL }; + +const device_t pssj_1e0_device = +{ + "Tandy PSSJ (port 1e0h)", + 0, 0, + pssj_1e0_init, + pssj_close, + NULL, + { NULL }, + NULL, + NULL +}; diff --git a/src/sound/snd_ssi2001.c b/src/sound/snd_ssi2001.c index bd4e70ea9..400700131 100644 --- a/src/sound/snd_ssi2001.c +++ b/src/sound/snd_ssi2001.c @@ -8,6 +8,7 @@ #include <86box/86box.h> #include <86box/io.h> #include <86box/device.h> +#include <86box/gameport.h> #include <86box/sound.h> #include <86box/snd_resid.h> @@ -17,6 +18,7 @@ typedef struct ssi2001_t void *psid; int16_t buffer[SOUNDBUFLEN * 2]; int pos; + int gameport_enabled; } ssi2001_t; static void ssi2001_update(ssi2001_t *ssi2001) @@ -66,7 +68,10 @@ void *ssi2001_init(const device_t *info) ssi2001->psid = sid_init(); sid_reset(ssi2001->psid); uint16_t addr = device_get_config_hex16("base"); + ssi2001->gameport_enabled = device_get_config_int("gameport"); io_sethandler(addr, 0x0020, ssi2001_read, NULL, NULL, ssi2001_write, NULL, NULL, ssi2001); + if (ssi2001->gameport_enabled) + gameport_remap(gameport_add(&gameport_201_device), 0x201); sound_add_handler(ssi2001_get_buffer, ssi2001); return ssi2001; } @@ -102,6 +107,9 @@ static const device_config_t ssi2001_config[] = } } }, + { + "gameport", "Enable Game port", CONFIG_BINARY, "", 1 + }, { "", "", -1 } @@ -110,7 +118,7 @@ static const device_config_t ssi2001_config[] = const device_t ssi2001_device = { "Innovation SSI-2001", - 0, 0, + DEVICE_ISA, 0, ssi2001_init, ssi2001_close, NULL, { NULL }, NULL, NULL, ssi2001_config diff --git a/src/unix/CMakeLists.txt b/src/unix/CMakeLists.txt index d0524e38b..e21265370 100644 --- a/src/unix/CMakeLists.txt +++ b/src/unix/CMakeLists.txt @@ -12,10 +12,22 @@ add_library(plat STATIC ${PLAT_SOURCES} unix_thread.c) add_library(ui STATIC unix.c unix_sdl.c unix_cdrom.c) target_compile_definitions(ui PUBLIC _FILE_OFFSET_BITS=64) target_link_libraries(ui dl) + +find_package(SDL2 REQUIRED) +include_directories(${SDL2_INCLUDE_DIRS}) +if(MINGW) + target_link_libraries(ui SDL2::SDL2-static) +else() + if (TARGET SDL2::SDL2) + target_link_libraries(ui SDL2::SDL2) + else() + target_link_libraries(ui ${SDL2_LIBRARIES}) + endif() +endif() if (ALSA_FOUND) target_link_libraries(plat ALSA::ALSA) endif() set(THREADS_PREFER_PTHREAD_FLAG TRUE) find_package(Threads REQUIRED) -target_link_libraries(86Box Threads::Threads) \ No newline at end of file +target_link_libraries(86Box Threads::Threads) diff --git a/src/unix/unix.c b/src/unix/unix.c index d15572dcd..286b937bd 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -249,6 +250,12 @@ wchar_t* plat_get_string(int i) return L"Make sure libpcap is installed and that you are on a libpcap-compatible network connection."; case IDS_2114: return L"Unable to initialize Ghostscript"; + case IDS_2063: + return L"Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine."; + case IDS_2064: + return L"Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card."; + case IDS_2128: + return L"Hardware not available"; } return L""; } @@ -296,7 +303,7 @@ plat_get_basename(const char *path) while (c > 0) { if (path[c] == '/') - return((char *)&path[c]); + return((char *)&path[c + 1]); c--; } @@ -360,6 +367,23 @@ plat_dir_create(char *path) return mkdir(path, S_IRWXU); } +void * +plat_mmap(size_t size, uint8_t executable) +{ +#if defined __APPLE__ && defined MAP_JIT + void *ret = mmap(0, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0), MAP_ANON | MAP_PRIVATE | (executable ? MAP_JIT : 0), 0, 0); +#else + void *ret = mmap(0, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0), MAP_ANON | MAP_PRIVATE, 0, 0); +#endif + return (ret < 0) ? NULL : ret; +} + +void +plat_munmap(void *ptr, size_t size) +{ + munmap(ptr, size); +} + uint64_t plat_timer_read(void) { @@ -563,22 +587,48 @@ do_stop(void) int ui_msgbox(int flags, void *message) { - return ui_msgbox_header(flags, message, NULL); + return ui_msgbox_header(flags, NULL, message); } -int ui_msgbox_header(int flags, void *message, void* header) +int ui_msgbox_header(int flags, void *header, void* message) { - if (!header) header = L"86Box"; + SDL_MessageBoxData msgdata; + SDL_MessageBoxButtonData msgbtn; + if (!header) header = (flags & MBX_ANSI) ? "86Box" : L"86Box"; + if (header <= (void*)7168) header = plat_get_string(header); + if (message <= (void*)7168) message = plat_get_string(message); + msgbtn.buttonid = 1; + msgbtn.text = "OK"; + msgbtn.flags = 0; + memset(&msgdata, 0, sizeof(SDL_MessageBoxData)); + msgdata.numbuttons = 1; + msgdata.buttons = &msgbtn; + int msgflags = 0; + if (msgflags & MBX_FATAL) msgflags |= SDL_MESSAGEBOX_ERROR; + else if (msgflags & MBX_ERROR || msgflags & MBX_WARNING) msgflags |= SDL_MESSAGEBOX_WARNING; + else msgflags |= SDL_MESSAGEBOX_INFORMATION; + msgdata.flags = msgflags; if (flags & MBX_ANSI) { - fwprintf(stderr, L"%s\n", header); - fprintf(stderr, "==========================\n" - "%s\n", message); - return 0; + int button = 0; + msgdata.title = header; + msgdata.message = message; + SDL_ShowMessageBox(&msgdata, &button); + return button; } - fwprintf(stderr, L"%s\n", header); - fwprintf(stderr, L"==========================\n" - L"%s\n", plat_get_string(message)); + else + { + int button = 0; + char *res = SDL_iconv_string("UTF-8", sizeof(wchar_t) == 2 ? "UTF-16LE" : "UTF-32LE", (char *)message, wcslen(message) * sizeof(wchar_t) + sizeof(wchar_t)); + char *res2 = SDL_iconv_string("UTF-8", sizeof(wchar_t) == 2 ? "UTF-16LE" : "UTF-32LE", (char *)header, wcslen(header) * sizeof(wchar_t) + sizeof(wchar_t)); + msgdata.message = res; + msgdata.title = res2; + SDL_ShowMessageBox(&msgdata, &button); + free(res); + free(res2); + return button; + } + return 0; } @@ -973,7 +1023,7 @@ int main(int argc, char** argv) SDL_Init(0); pc_init(argc, argv); if (! pc_init_modules()) { - fprintf(stderr, "No ROMs found.\n"); + ui_msgbox_header(MBX_FATAL, L"No ROMs found.", L"86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory."); SDL_Quit(); return 6; } diff --git a/src/unix/unix_sdl.c b/src/unix/unix_sdl.c index a61d338e6..4c309144f 100644 --- a/src/unix/unix_sdl.c +++ b/src/unix/unix_sdl.c @@ -133,7 +133,10 @@ sdl_blit_shim(int x, int y, int w, int h) params.y = y; params.w = w; params.h = h; - if (!(!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL))) memcpy(interpixels, &(buffer32->line[y][x]), h * (2048 + 64) * sizeof(uint32_t)); + if (!(!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL))) + video_copy(interpixels, &(buffer32->line[y][x]), h * (2048 + 64) * sizeof(uint32_t)); + if (screenshots) + video_screenshot(interpixels, 0, 0, (2048 + 64)); blitreq = 1; video_blit_complete(); } diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index d6630ccf8..565418e84 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -59,6 +59,7 @@ #endif #define BIOS_ROM_PATH "roms/video/ati28800/bios.bin" +#define BIOS_VGAXL_ROM_PATH "roms/video/ati28800/ATI_VGAWonder_XL.bin" typedef struct ati28800_t @@ -82,6 +83,8 @@ typedef struct ati28800_t int get_korean_font_index; uint16_t get_korean_font_base; int ksc5601_mode_enabled; + + int type, type_korean; } ati28800_t; @@ -111,7 +114,6 @@ ati28800_log(const char *fmt, ...) static void ati28800_recalctimings(svga_t *svga); - static void ati28800_out(uint16_t addr, uint8_t val, void *p) { @@ -134,37 +136,36 @@ ati28800_out(uint16_t addr, uint8_t val, void *p) ati28800_log("ATI 28800 write reg=0x%02X, val=0x%02X\n", ati28800->index, val); switch (ati28800->index) { case 0xa3: - ati28800->regs[0xa3] = val & 0x1f; - svga_recalctimings(svga); + if ((old ^ val) & 0x10) + svga_recalctimings(svga); break; - case 0xa6: - ati28800->regs[0xa6] = val & 0xc9; - break; - case 0xab: - ati28800->regs[0xab] = val & 0xdf; + case 0xa7: + if ((old ^ val) & 0x80) + svga_recalctimings(svga); break; case 0xb0: - ati28800->regs[0xb0] = val & 0x7d; - svga_recalctimings(svga); - break; - case 0xb1: - ati28800->regs[0xb0] = val & 0x7f; + if ((old ^ val) & 0x60) + svga_recalctimings(svga); break; case 0xb2: + case 0xbe: if (ati28800->regs[0xbe] & 0x08) { /* Read/write bank mode */ - svga->read_bank = (((val & 0x01) << 3) | ((val & 0xe0) >> 5)) * 0x10000; - svga->write_bank = ((val & 0x1e) >> 1) * 0x10000; + svga->read_bank = (((ati28800->regs[0xb2] & 0x01) << 3) | ((ati28800->regs[0xb2] & 0xe0) >> 5)) * 0x10000; + svga->write_bank = ((ati28800->regs[0xb2] & 0x1e) >> 1) * 0x10000; } else { /* Single bank mode */ - svga->read_bank = ((val & 0x1e) >> 1) * 0x10000; - svga->write_bank = ((val & 0x1e) >> 1) * 0x10000; + svga->read_bank = ((ati28800->regs[0xb2] & 0x1e) >> 1) * 0x10000; + svga->write_bank = ((ati28800->regs[0xb2] & 0x1e) >> 1) * 0x10000; + } + if (ati28800->index == 0xbe) { + if ((old ^ val) & 0x10) + svga_recalctimings(svga); } break; case 0xb3: - ati28800->regs[0xb3] = val & 0xef; ati_eeprom_write(&ati28800->eeprom, val & 8, val & 2, val & 1); break; case 0xb6: - if ((old ^ val) & 0x10) + if ((old ^ val) & 0x11) svga_recalctimings(svga); break; case 0xb8: @@ -179,7 +180,10 @@ ati28800_out(uint16_t addr, uint8_t val, void *p) break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - sc1502x_ramdac_out(addr, val, svga->ramdac, svga); + if (ati28800->type == 1) + sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); + else + svga_out(addr, val, svga); return; case 0x3D4: @@ -190,12 +194,6 @@ ati28800_out(uint16_t addr, uint8_t val, void *p) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) val = (svga->crtc[7] & ~0x10) | (val & 0x10); - if ((ati28800->regs[0xb4] & 0x10) && ((svga->crtcreg == 0x0a) || (svga->crtcreg == 0x0b))) - return; - if ((ati28800->regs[0xb4] & 0x20) && ((svga->crtc[0x08] & 0x7f) && (svga->crtc[0x14] & 0x1f))) - return; - if ((ati28800->regs[0xb4] & 0x40) && ((svga->crtcreg <= 0x06) && (svga->crtc[0x07] & 0x10) != 0x10)) - return; old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; @@ -299,22 +297,23 @@ ati28800_in(uint16_t addr, void *p) break; case 0x1cf: switch (ati28800->index) { - case 0xa0: - temp = 0x10; - break; case 0xaa: temp = ati28800->id; break; case 0xb0: - if (ati28800->memory == 1024) - temp = 0x08; - else if (ati28800->memory == 512) - temp = 0x10; - else - temp = 0x00; + temp = ati28800->regs[0xb0] | 0x80; + if (ati28800->memory == 1024) { + temp &= ~0x10; + temp |= 0x08; + } else if (ati28800->memory == 512) { + temp |= 0x10; + temp &= ~0x08; + } else { + temp &= ~0x18; + } break; case 0xb7: - temp = ati28800->regs[ati28800->index] & ~8; + temp = ati28800->regs[0xb7] & ~8; if (ati_eeprom_read(&ati28800->eeprom)) temp |= 8; break; @@ -333,7 +332,9 @@ ati28800_in(uint16_t addr, void *p) break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - return sc1502x_ramdac_in(addr, svga->ramdac, svga); + if (ati28800->type == 1) + return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); + return svga_in(addr, svga); case 0x3D4: temp = svga->crtcreg; @@ -401,8 +402,14 @@ ati28800_recalctimings(svga_t *svga) { ati28800_t *ati28800 = (ati28800_t *)svga->p; - switch (((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1) | - ((svga->miscout & 0x0C) >> 2)) { + if (ati28800->regs[0xa3] & 0x10) + svga->ma_latch |= 0x10000; + + if (ati28800->regs[0xb0] & 0x40) + svga->ma_latch |= 0x20000; + + switch (((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1) | + ((svga->miscout & 0x0C) >> 2)) { case 0x00: svga->clock = (cpuclock * (double)(1ull << 32)) / 42954000.0; break; case 0x01: svga->clock = (cpuclock * (double)(1ull << 32)) / 48771000.0; break; case 0x02: ati28800_log ("clock 2\n"); break; @@ -420,38 +427,69 @@ ati28800_recalctimings(svga_t *svga) case 0x0E: svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0; break; case 0x0F: svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; break; default: break; - } + } - if (ati28800->regs[0xb8] & 0x40) + if (ati28800->regs[0xb8] & 0x40) svga->clock *= 2; - if (ati28800->regs[0xa3] & 0x10) - svga->ma |= 0x10000; + if (ati28800->regs[0xa7] & 0x80) + svga->clock *= 3; - if (ati28800->regs[0xb0] & 0x40) - svga->ma |= 0x20000; - - if (ati28800->regs[0xb6] & 0x10) { + if (ati28800->regs[0xb6] & 0x10) { svga->hdisp <<= 1; svga->htotal <<= 1; svga->rowoffset <<= 1; - } - - if (!svga->scrblank && (ati28800->regs[0xb0] & 0x20)) { /* Extended 256 colour modes */ - switch (svga->bpp) { - case 8: - svga->render = svga_render_8bpp_highres; - svga->rowoffset <<= 1; - svga->ma <<= 1; - break; - case 15: - svga->render = svga_render_15bpp_highres; - svga->hdisp >>= 1; - svga->rowoffset <<= 1; - svga->ma <<= 1; - break; + svga->gdcreg[5] &= ~0x40; } - } + + if (ati28800->regs[0xb0] & 0x20) { + svga->gdcreg[5] |= 0x40; + } + + if (!svga->scrblank && svga->attr_palette_enable) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + switch (svga->gdcreg[5] & 0x60) { + case 0x00: + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_4bpp_lowres; + else + svga->render = svga_render_4bpp_highres; + break; + case 0x20: /*4 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; + break; + case 0x40: case 0x60: /*256+ colours*/ + switch (svga->bpp) { + case 8: + svga->map8 = svga->pallook; + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; + else { + svga->render = svga_render_8bpp_highres; + svga->rowoffset <<= 1; + svga->ma_latch <<= 1; + } + break; + case 15: + if (svga->lowres) + svga->render = svga_render_15bpp_lowres; + else { + svga->render = svga_render_15bpp_highres; + svga->hdisp >>= 1; + svga->rowoffset <<= 1; + svga->ma_latch <<= 1; + } + break; + } + break; + } + } + } + + svga->vram_display_mask = (ati28800->regs[0xb6] & 1) ? ((ati28800->memory << 10) - 1) : 0x3ffff; } @@ -466,14 +504,15 @@ ati28800k_recalctimings(svga_t *svga) svga->render = svga_render_text_80_ksc5601; } - void * ati28800k_init(const device_t *info) { ati28800_t *ati28800 = (ati28800_t *) malloc(sizeof(ati28800_t)); memset(ati28800, 0, sizeof(ati28800_t)); - if (info->local == 0) { + ati28800->type_korean = info->local; + + if (ati28800->type_korean == 0) { ati28800->memory = device_get_config_int("memory"); video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati28800); } else { @@ -489,7 +528,7 @@ ati28800k_init(const device_t *info) ati28800->in_get_korean_font_kind_set = 0; ati28800->ksc5601_mode_enabled = 0; - switch(info->local) { + switch(ati28800->type_korean) { case 0: default: rom_init(&ati28800->bios_rom, BIOS_ATIKOR_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -512,12 +551,12 @@ ati28800k_init(const device_t *info) NULL, NULL); - ati28800->svga.ramdac = device_add(&sc1502x_ramdac_device); - io_sethandler(0x01ce, 0x0002, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); ati28800->svga.miscout = 1; + ati28800->svga.bpp = 8; + ati28800->svga.packed_chain4 = 1; ati28800->svga.ksc5601_sbyte_mask = 0; ati28800->svga.ksc5601_udc_area_msb[0] = 0xC9; ati28800->svga.ksc5601_udc_area_msb[1] = 0xFE; @@ -541,14 +580,16 @@ ati28800_init(const device_t *info) ati28800->memory = device_get_config_int("memory"); - switch(info->local) { + ati28800->type = info->local; + + switch(ati28800->type) { case VGAWONDERXL: - ati28800->id = 6; - rom_init_interleaved(&ati28800->bios_rom, - BIOS_VGAXL_EVEN_PATH, - BIOS_VGAXL_ODD_PATH, - 0xc0000, 0x10000, 0xffff, - 0, MEM_MAPPING_EXTERNAL); + ati28800->id = 5; + rom_init(&ati28800->bios_rom, + BIOS_VGAXL_ROM_PATH, + 0xc0000, 0x8000, 0x7fff, + 0, MEM_MAPPING_EXTERNAL); + ati28800->svga.ramdac = device_add(&sc11486_ramdac_device); break; #if defined(DEV_BRANCH) && defined(USE_XL24) @@ -576,8 +617,6 @@ ati28800_init(const device_t *info) ati28800_in, ati28800_out, NULL, NULL); - - ati28800->svga.ramdac = device_add(&sc1502x_ramdac_device); io_sethandler(0x01ce, 2, ati28800_in, NULL, NULL, @@ -587,8 +626,10 @@ ati28800_init(const device_t *info) ati28800_out, NULL, NULL, ati28800); ati28800->svga.miscout = 1; + ati28800->svga.bpp = 8; + ati28800->svga.packed_chain4 = 1; - switch (info->local) { + switch (ati28800->type) { case VGAWONDERXL: ati_eeprom_load(&ati28800->eeprom, "ati28800xl.nvr", 0); break; @@ -616,7 +657,7 @@ ati28800_available(void) static int -ati28800k_available() +ati28800k_available(void) { return ((rom_present(BIOS_ATIKOR_PATH) && rom_present(FONT_ATIKOR_PATH))); } @@ -625,7 +666,7 @@ ati28800k_available() static int compaq_ati28800_available(void) { - return((rom_present(BIOS_VGAXL_EVEN_PATH) && rom_present(BIOS_VGAXL_ODD_PATH))); + return((rom_present(BIOS_VGAXL_ROM_PATH))); } @@ -719,7 +760,7 @@ static const device_config_t ati28800_wonderxl_config[] = const device_t ati28800_device = { - "ATI-28800", + "ATI 28800-5 (ATI VGA Charger)", DEVICE_ISA, 0, ati28800_init, ati28800_close, NULL, @@ -765,7 +806,7 @@ const device_t ati28800k_spc6033p_device = const device_t compaq_ati28800_device = { - "Compaq ATI-28800", + "ATI 28800-5 (ATI VGA Wonder XL)", DEVICE_ISA, VGAWONDERXL, ati28800_init, ati28800_close, NULL, diff --git a/src/video/vid_att20c49x_ramdac.c b/src/video/vid_att20c49x_ramdac.c index ce6379f1d..4c09f1e8f 100644 --- a/src/video/vid_att20c49x_ramdac.c +++ b/src/video/vid_att20c49x_ramdac.c @@ -50,7 +50,7 @@ att49x_ramdac_control(uint8_t val, void *p, svga_t *svga) { att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p; ramdac->ctrl = val; - switch (ramdac->ctrl >> 4) { + switch ((ramdac->ctrl >> 5) & 7) { case 0: case 1: case 2: @@ -62,11 +62,9 @@ att49x_ramdac_control(uint8_t val, void *p, svga_t *svga) svga->bpp = 15; break; case 6: - case 0xc: svga->bpp = 16; break; case 7: - case 0xe: svga->bpp = 24; break; } diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index c1eb9ac2d..7ba2efb3c 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -212,7 +212,7 @@ typedef struct gd54xx_t uint8_t fc; /* Feature Connector */ - int card; + int card, id; uint8_t pos_regs[8]; @@ -3727,6 +3727,79 @@ gd5428_mca_feedb(void *p) return 1; } +static void +gd54xx_reset(void *priv) +{ + gd54xx_t *gd54xx = (gd54xx_t *) priv; + svga_t *svga = &gd54xx->svga; + + memset(svga->crtc, 0x00, sizeof(svga->crtc)); + memset(svga->seqregs, 0x00, sizeof(svga->seqregs)); + memset(svga->gdcreg, 0x00, sizeof(svga->gdcreg)); + svga->crtc[0] = 63; + svga->crtc[6] = 255; + svga->dispontime = 1000ull << 32; + svga->dispofftime = 1000ull << 32; + svga->bpp = 8; + + io_removehandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); + io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); + + mem_mapping_disable(&gd54xx->vgablt_mapping); + if (gd54xx->has_bios && gd54xx->pci) + mem_mapping_disable(&gd54xx->bios_rom.mapping); + + memset(gd54xx->pci_regs, 0x00, 256); + + mem_mapping_set_p(&svga->mapping, gd54xx); + mem_mapping_disable(&gd54xx->mmio_mapping); + mem_mapping_disable(&gd54xx->linear_mapping); + mem_mapping_disable(&gd54xx->aperture2_mapping); + mem_mapping_disable(&gd54xx->vgablt_mapping); + + gd543x_recalc_mapping(gd54xx); + gd54xx_recalc_banking(gd54xx); + + svga->hwcursor.yoff = svga->hwcursor.xoff = 0; + + if (gd54xx->id >= CIRRUS_ID_CLGD5420) { + gd54xx->vclk_n[0] = 0x4a; + gd54xx->vclk_d[0] = 0x2b; + gd54xx->vclk_n[1] = 0x5b; + gd54xx->vclk_d[1] = 0x2f; + gd54xx->vclk_n[2] = 0x45; + gd54xx->vclk_d[2] = 0x30; + gd54xx->vclk_n[3] = 0x7e; + gd54xx->vclk_d[3] = 0x33; + } else { + gd54xx->vclk_n[0] = 0x66; + gd54xx->vclk_d[0] = 0x3b; + gd54xx->vclk_n[1] = 0x5b; + gd54xx->vclk_d[1] = 0x2f; + gd54xx->vclk_n[2] = 0x45; + gd54xx->vclk_d[2] = 0x2c; + gd54xx->vclk_n[3] = 0x7e; + gd54xx->vclk_d[3] = 0x33; + } + + svga->extra_banks[1] = 0x8000; + + gd54xx->pci_regs[PCI_REG_COMMAND] = 7; + + gd54xx->pci_regs[0x30] = 0x00; + gd54xx->pci_regs[0x32] = 0x0c; + gd54xx->pci_regs[0x33] = 0x00; + + svga->crtc[0x27] = gd54xx->id; + + svga->seqregs[6] = 0x0f; + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429) + gd54xx->unlocked = 1; + else + gd54xx->unlocked = 0; +} + + static void *gd54xx_init(const device_t *info) { @@ -3745,8 +3818,9 @@ static void gd54xx->rev = 0; gd54xx->has_bios = 1; - switch (id) { - + gd54xx->id = id; + + switch (id) { case CIRRUS_ID_CLGD5401: romfn = BIOS_GD5401_PATH; break; @@ -3921,14 +3995,17 @@ static void gd5480_vgablt_write, gd5480_vgablt_writew, NULL, NULL, MEM_MAPPING_EXTERNAL, gd54xx); } + io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); + + if (gd54xx->pci && id >= CIRRUS_ID_CLGD5430) + pci_add_card(PCI_ADD_VIDEO, cl_pci_read, cl_pci_write, gd54xx); + mem_mapping_set_p(&svga->mapping, gd54xx); mem_mapping_disable(&gd54xx->mmio_mapping); mem_mapping_disable(&gd54xx->linear_mapping); mem_mapping_disable(&gd54xx->aperture2_mapping); mem_mapping_disable(&gd54xx->vgablt_mapping); - io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); - svga->hwcursor.yoff = svga->hwcursor.xoff = 0; if (id >= CIRRUS_ID_CLGD5420) { @@ -3953,15 +4030,12 @@ static void svga->extra_banks[1] = 0x8000; - if (gd54xx->pci && id >= CIRRUS_ID_CLGD5430) - pci_add_card(PCI_ADD_VIDEO, cl_pci_read, cl_pci_write, gd54xx); - gd54xx->pci_regs[PCI_REG_COMMAND] = 7; gd54xx->pci_regs[0x30] = 0x00; gd54xx->pci_regs[0x32] = 0x0c; gd54xx->pci_regs[0x33] = 0x00; - + svga->crtc[0x27] = id; svga->seqregs[6] = 0x0f; @@ -4260,7 +4334,7 @@ const device_t gd5401_isa_device = DEVICE_ISA, CIRRUS_ID_CLGD5401, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5401_available }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4273,7 +4347,7 @@ const device_t gd5402_isa_device = DEVICE_ISA, CIRRUS_ID_CLGD5402, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5402_available }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4286,7 +4360,7 @@ const device_t gd5402_onboard_device = DEVICE_AT | DEVICE_ISA, CIRRUS_ID_CLGD5402 | 0x200, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { NULL }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4299,7 +4373,7 @@ const device_t gd5420_isa_device = DEVICE_AT | DEVICE_ISA, CIRRUS_ID_CLGD5420, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5420_available }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4311,7 +4385,7 @@ const device_t gd5422_isa_device = { DEVICE_AT | DEVICE_ISA, CIRRUS_ID_CLGD5422, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5422_available }, /* Common BIOS between 5422 and 5424 */ gd54xx_speed_changed, gd54xx_force_redraw, @@ -4323,7 +4397,7 @@ const device_t gd5424_vlb_device = { DEVICE_VLB, CIRRUS_ID_CLGD5424, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5422_available }, /* Common BIOS between 5422 and 5424 */ gd54xx_speed_changed, gd54xx_force_redraw, @@ -4337,7 +4411,7 @@ const device_t gd5426_vlb_device = CIRRUS_ID_CLGD5426, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5426_available }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4351,7 +4425,7 @@ const device_t gd5426_onboard_device = CIRRUS_ID_CLGD5426 | 0x200, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { NULL }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4365,7 +4439,7 @@ const device_t gd5428_isa_device = CIRRUS_ID_CLGD5428, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5428_isa_available }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4379,7 +4453,7 @@ const device_t gd5428_vlb_device = CIRRUS_ID_CLGD5428, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5428_available }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4393,7 +4467,7 @@ const device_t gd5428_mca_device = CIRRUS_ID_CLGD5428, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5428_mca_available }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4407,7 +4481,7 @@ const device_t gd5428_onboard_device = CIRRUS_ID_CLGD5428, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5428_isa_available }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4421,7 +4495,7 @@ const device_t gd5429_isa_device = CIRRUS_ID_CLGD5429, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5429_available }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4435,7 +4509,7 @@ const device_t gd5429_vlb_device = CIRRUS_ID_CLGD5429, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5429_available }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4449,7 +4523,7 @@ const device_t gd5430_vlb_device = CIRRUS_ID_CLGD5430, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5430_vlb_available }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4463,7 +4537,7 @@ const device_t gd5430_pci_device = CIRRUS_ID_CLGD5430, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5430_pci_available }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4477,7 +4551,7 @@ const device_t gd5434_isa_device = CIRRUS_ID_CLGD5434, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5434_available }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4491,7 +4565,7 @@ const device_t gd5434_onboard_pci_device = CIRRUS_ID_CLGD5434 | 0x200, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { NULL }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4505,7 +4579,7 @@ const device_t gd5434_vlb_device = CIRRUS_ID_CLGD5434, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5434_available }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4519,7 +4593,7 @@ const device_t gd5434_pci_device = CIRRUS_ID_CLGD5434, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5434_available }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4533,7 +4607,7 @@ const device_t gd5436_pci_device = CIRRUS_ID_CLGD5436, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5436_available }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4547,7 +4621,7 @@ const device_t gd5440_onboard_pci_device = CIRRUS_ID_CLGD5440 | 0x600, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { NULL }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4561,7 +4635,7 @@ const device_t gd5440_pci_device = CIRRUS_ID_CLGD5440 | 0x400, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5440_available }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4575,7 +4649,7 @@ const device_t gd5446_pci_device = CIRRUS_ID_CLGD5446, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5446_available }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4589,7 +4663,7 @@ const device_t gd5446_stb_pci_device = CIRRUS_ID_CLGD5446 | 0x100, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5446_stb_available }, gd54xx_speed_changed, gd54xx_force_redraw, @@ -4603,7 +4677,7 @@ const device_t gd5480_pci_device = CIRRUS_ID_CLGD5480, gd54xx_init, gd54xx_close, - NULL, + gd54xx_reset, { gd5480_available }, gd54xx_speed_changed, gd54xx_force_redraw, diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 36f8b67fb..233783439 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -97,11 +97,12 @@ typedef struct et4000w32p_t uint32_t pattern_addr, source_addr, dest_addr, mix_addr; } queued, internal; + uint8_t osr; uint8_t status; int pattern_x, source_x, pattern_x_back, source_x_back, pattern_y, source_y, cpu_dat_pos, pix_pos, - cpu_input_num; + cpu_input_num, queue; uint32_t pattern_addr, source_addr, dest_addr, mix_addr, pattern_back, source_back, dest_back, mix_back, @@ -119,9 +120,9 @@ typedef struct et4000w32p_t static int et4000w32_vbus[4] = {1, 2, 4, 4}; -static int et4000w32_max_x[8] = {0, 0, 4, 8, 16, 32, 64, 0x70000000}; -static int et4000w32_wrap_x[8] = {0, 0, 3, 7, 15, 31, 63, 0xffffffff}; -static int et4000w32_wrap_y[8] = {1, 2, 4, 8, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}; +static int et4000w32_max_x[8] = {0,0,4,8,0x10,0x20,0x40,0x70000000}; +static int et4000w32_wrap_x[8] = {0,0,3,7,0x0F,0x1F,0x3F,~0}; +static int et4000w32_wrap_y[8] = {1,2,4,8,~0,~0,~0,~0}; static video_timings_t timing_et4000w32_vlb = {VIDEO_BUS, 4, 4, 4, 10, 10, 10}; static video_timings_t timing_et4000w32_pci = {VIDEO_PCI, 4, 4, 4, 10, 10, 10}; @@ -271,14 +272,24 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p) switch (svga->bpp) { case 8: svga->hwcursor.xoff += 32; - break; + break; } } if (svga->hwcursor.xsize == 128) { svga->hwcursor.xoff &= 0x7f; svga->hwcursor.yoff &= 0x7f; + if (et4000->type > ET4000W32P_REVC) { + if (svga->bpp == 24) { + et4000->adjust_cursor = 2; + } + } } else { + if (et4000->type > ET4000W32P_REVC) { + if (svga->bpp == 24 && et4000->adjust_cursor) { + et4000->adjust_cursor = 0; + } + } svga->hwcursor.xoff &= 0x3f; svga->hwcursor.yoff &= 0x3f; } @@ -331,10 +342,15 @@ et4000w32p_in(uint16_t addr, void *p) case 0x214B: case 0x215B: case 0x216B: case 0x217B: if (et4000->index == 0xec) return (et4000->regs[0xec] & 0xf) | (et4000->rev << 4); - if (et4000->index == 0xee) { /* Preliminary implementation */ - if (svga->bpp == 8) - return 3; - else if (svga->bpp == 16) + if (et4000->index == 0xee) { + if (svga->bpp == 8) { + if ((svga->gdcreg[5] & 0x60) >= 0x40) + return 3; + else if ((svga->gdcreg[5] & 0x60) == 0x20) + return 1; + else + return 2; + } else if (svga->bpp == 15 || svga->bpp == 16) return 4; else break; @@ -409,13 +425,21 @@ et4000w32p_recalctimings(svga_t *svga) switch (svga->bpp) { case 15: case 16: svga->hdisp >>= 1; - if (et4000->type <= ET4000W32P_REVC) - et4000->adjust_cursor = 1; + if (et4000->type <= ET4000W32P_REVC) { + if (et4000->type == ET4000W32P_REVC) { + if (svga->hdisp != 1024) + et4000->adjust_cursor = 1; + } else + et4000->adjust_cursor = 1; + } break; case 24: svga->hdisp /= 3; if (et4000->type <= ET4000W32P_REVC) et4000->adjust_cursor = 2; + if (et4000->type == ET4000W32P_DIAMOND && (svga->hdisp == 640/2 || svga->hdisp == 1232)) { + svga->hdisp = 640; + } break; } @@ -569,45 +593,51 @@ et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val) case 0x7f80: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFFFFFF00) | val; break; case 0x7f81: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFFFF00FF) | (val << 8); break; case 0x7f82: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFF00FFFF) | (val << 16); break; - case 0x7f83: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x00FFFFFF) | (val << 24); break; + case 0x7f83: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x00FFFFFF) | (val << 24); et4000->acl.queue++; break; case 0x7f84: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFFFFFF00) | val; break; case 0x7f85: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFFFF00FF) | (val << 8); break; case 0x7f86: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFF00FFFF) | (val << 16); break; - case 0x7f87: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x00FFFFFF) | (val << 24); break; + case 0x7f87: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x00FFFFFF) | (val << 24); et4000->acl.queue++; break; case 0x7f88: et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0xFF00) | val; break; - case 0x7f89: et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x00FF) | (val << 8); break; + case 0x7f89: et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x00FF) | (val << 8); et4000->acl.queue++; break; case 0x7f8a: et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0xFF00) | val; break; - case 0x7f8b: et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x00FF) | (val << 8); break; + case 0x7f8b: et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x00FF) | (val << 8); et4000->acl.queue++;break; case 0x7f8c: et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0xFF00) | val; break; - case 0x7f8d: et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x00FF) | (val << 8); break; + case 0x7f8d: et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x00FF) | (val << 8); et4000->acl.queue++; break; case 0x7f8e: + et4000->acl.queue++; if (et4000->type >= ET4000W32P_REVC) et4000->acl.queued.pixel_depth = val; else et4000->acl.queued.vbus = val; break; - case 0x7f8f: et4000->acl.queued.xy_dir = val; break; - case 0x7f90: et4000->acl.queued.pattern_wrap = val; break; - case 0x7f92: et4000->acl.queued.source_wrap = val; break; + case 0x7f8f: et4000->acl.queued.xy_dir = val; et4000->acl.queue++; break; + case 0x7f90: et4000->acl.queued.pattern_wrap = val; et4000->acl.queue++; break; + case 0x7f92: et4000->acl.queued.source_wrap = val; et4000->acl.queue++; break; case 0x7f98: et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0xFF00) | val; break; - case 0x7f99: et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x00FF) | (val << 8); break; + case 0x7f99: et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x00FF) | (val << 8); et4000->acl.queue++; break; case 0x7f9a: et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0xFF00) | val; break; - case 0x7f9b: et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x00FF) | (val << 8); break; - case 0x7f9c: et4000->acl.queued.ctrl_routing = val; break; - case 0x7f9d: et4000->acl.queued.ctrl_reload = val; break; - case 0x7f9e: et4000->acl.queued.rop_bg = val; break; - case 0x7f9f: et4000->acl.queued.rop_fg = val; break; + case 0x7f9b: et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x00FF) | (val << 8); et4000->acl.queue++; break; + case 0x7f9c: et4000->acl.queued.ctrl_routing = val; et4000->acl.queue++; break; + case 0x7f9d: et4000->acl.queued.ctrl_reload = val; et4000->acl.queue++; break; + case 0x7f9e: et4000->acl.queued.rop_bg = val; et4000->acl.queue++; break; + case 0x7f9f: et4000->acl.queued.rop_fg = val; et4000->acl.queue++; break; case 0x7fa0: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFFFFFF00) | val; break; case 0x7fa1: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFFFF00FF) | (val << 8); break; case 0x7fa2: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFF00FFFF) | (val << 16); break; case 0x7fa3: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x00FFFFFF) | (val << 24); + et4000->acl.queue++; et4000->acl.internal = et4000->acl.queued; if (et4000->type >= ET4000W32P_REVC) { - et4000w32p_blit_start(et4000); - if (!(et4000->acl.queued.ctrl_routing & 0x43)) - et4000w32p_blit(0xffffff, ~0, 0, 0, et4000); - if ((et4000->acl.queued.ctrl_routing & 0x40) && !(et4000->acl.internal.ctrl_routing & 3)) - et4000w32p_blit(4, ~0, 0, 0, et4000); + if (et4000->acl.osr & 0x10) { + et4000w32p_blit_start(et4000); + if (!(et4000->acl.queued.ctrl_routing & 0x43)) { + et4000w32p_blit(0xffffff, ~0, 0, 0, et4000); + } + if ((et4000->acl.queued.ctrl_routing & 0x40) && !(et4000->acl.internal.ctrl_routing & 3)) { + et4000w32p_blit(4, ~0, 0, 0, et4000); + } + } } else { et4000w32_blit_start(et4000); et4000->acl.cpu_input_num = 0; @@ -618,15 +648,15 @@ et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val) case 0x7fa4: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFFFF00) | val; break; case 0x7fa5: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFF00FF) | (val << 8); break; case 0x7fa6: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFF00FFFF) | (val << 16); break; - case 0x7fa7: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0x00FFFFFF) | (val << 24); break; + case 0x7fa7: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0x00FFFFFF) | (val << 24); et4000->acl.queue++; break; case 0x7fa8: et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0xFF00) | val; break; - case 0x7fa9: et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0x00FF) | (val << 8); break; + case 0x7fa9: et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0x00FF) | (val << 8); et4000->acl.queue++; break; case 0x7faa: et4000->acl.queued.error = (et4000->acl.queued.error & 0xFF00) | val; break; - case 0x7fab: et4000->acl.queued.error = (et4000->acl.queued.error & 0x00FF) | (val << 8); break; + case 0x7fab: et4000->acl.queued.error = (et4000->acl.queued.error & 0x00FF) | (val << 8); et4000->acl.queue++; break; case 0x7fac: et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0xFF00) | val; break; - case 0x7fad: et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0x00FF) | (val << 8); break; + case 0x7fad: et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0x00FF) | (val << 8); et4000->acl.queue++; break; case 0x7fae: et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0xFF00) | val; break; - case 0x7faf: et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0x00FF) | (val << 8); break; + case 0x7faf: et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0x00FF) | (val << 8); et4000->acl.queue++; break; } } @@ -638,17 +668,17 @@ et4000w32p_accel_write_mmu(et4000w32p_t *et4000, uint32_t addr, uint8_t val) if (!(et4000->acl.status & ACL_XYST)) return; if (et4000->acl.internal.ctrl_routing & 3) { + et4000->acl.queue++; if ((et4000->acl.internal.ctrl_routing & 3) == 2) { - if (et4000->acl.mix_addr & 7) - et4000w32p_blit(8 - (et4000->acl.mix_addr & 7), val >> (et4000->acl.mix_addr & 7), 0, 1, et4000); - else - et4000w32p_blit(8, val, 0, 1, et4000); + et4000w32p_blit(8 - (et4000->acl.mix_addr & 7), val >> (et4000->acl.mix_addr & 7), 0, 1, et4000); } - else if ((et4000->acl.internal.ctrl_routing & 3) == 1) + else if ((et4000->acl.internal.ctrl_routing & 3) == 1) { et4000w32p_blit(1, ~0, val, 2, et4000); + } } } else { if (!(et4000->acl.status & ACL_XYST)) { + et4000->acl.queue++; et4000->acl.queued.dest_addr = (addr & 0x1FFF) + et4000->mmu.base[et4000->bank]; et4000->acl.internal = et4000->acl.queued; et4000w32_blit_start(et4000); @@ -658,6 +688,7 @@ et4000w32p_accel_write_mmu(et4000w32p_t *et4000, uint32_t addr, uint8_t val) } if (et4000->acl.internal.ctrl_routing & 7) { + et4000->acl.queue++; et4000->acl.cpu_input = (et4000->acl.cpu_input &~ (0xFF << (et4000->acl.cpu_input_num << 3))) | (val << (et4000->acl.cpu_input_num << 3)); et4000->acl.cpu_input_num++; @@ -716,6 +747,7 @@ et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p) case 0x7f0a: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFF00FFFF) | (val << 16); break; case 0x7f0b: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x00FFFFFF) | (val << 24); break; case 0x7f13: et4000->mmu.ctrl = val; break; + case 0x7f31: et4000->acl.osr = val; break; } break; } @@ -771,13 +803,23 @@ et4000w32p_mmu_read(uint32_t addr, void *p) case 0x7f13: return et4000->mmu.ctrl; case 0x7f36: - if (et4000->type >= ET4000W32P_REVC) { + if (et4000->type >= ET4000W32P_REVC) { + if (et4000->acl.queue) { + et4000->acl.status |= ACL_RDST; + et4000->acl.queue = 0; + } else + et4000->acl.status &= ~ACL_RDST; + temp = et4000->acl.status; - temp &= ~(ACL_RDST | ACL_WRST); - if (temp == ACL_XYST && (et4000->acl.internal.ctrl_routing == 1 || et4000->acl.internal.ctrl_routing == 2)) - temp |= ACL_RDST; } else { et4000->acl.status &= ~(ACL_XYST | ACL_SSO); + + if (et4000->acl.queue) { + et4000->acl.status |= ACL_RDST; + et4000->acl.queue = 0; + } else + et4000->acl.status &= ~ACL_RDST; + temp = et4000->acl.status; } return temp; @@ -883,7 +925,7 @@ et4000w32p_blit_start(et4000w32p_t *et4000) et4000->acl.status |= ACL_XYST; et4000w32_log("ACL status XYST set\n"); if ((!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) && !(et4000->acl.internal.ctrl_routing & 0x40)) - et4000->acl.status |= ACL_SSO; + et4000->acl.status |= ACL_SSO; if (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]) { et4000->acl.pattern_x = et4000->acl.pattern_addr & et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]; @@ -997,7 +1039,7 @@ et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32 if (!(et4000->acl.status & ACL_XYST) && (et4000->type >= ET4000W32P_REVC)) return; - if (et4000->acl.internal.xy_dir & 0x80){ /* Line draw */ + if (et4000->acl.internal.xy_dir & 0x80) { /* Line draw */ while (count--) { et4000w32_log("%i,%i : ", et4000->acl.internal.pos_x, et4000->acl.internal.pos_y); pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask]; diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index 3f12bdfdc..50bedb377 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -59,7 +59,7 @@ typedef struct ht216_t uint8_t bg_plane_sel, fg_plane_sel; uint8_t ht_regs[256]; - uint8_t extensions; + uint8_t extensions, reg_3cb; uint8_t pos_regs[8]; } ht216_t; @@ -179,7 +179,7 @@ ht216_out(uint16_t addr, uint8_t val, void *p) ht216_log("ht216 %i out %04X %02X %04X:%04X\n", svga->miscout & 1, addr, val, CS, cpu_state.pc); if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + addr ^= 0x60; switch (addr) { case 0x3c2: @@ -300,6 +300,12 @@ ht216_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.ena = !!(val & 0x80); break; + case 0xc0: + break; + + case 0xc1: + break; + case 0xc8: if ((old ^ val) & HT_REG_C8_E256) { svga->fullchange = changeframecount; @@ -313,6 +319,10 @@ ht216_out(uint16_t addr, uint8_t val, void *p) break; case 0xe0: + svga->adv_flags &= ~FLAG_RAMDAC_SHIFT; + if (val & 0x04) + svga->adv_flags |= FLAG_RAMDAC_SHIFT; + /* FALLTHROUGH */ /*Bank registers*/ case 0xe8: case 0xe9: ht216_log("HT216 reg 0x%02x write = %02x, mode = 1, chain4 = %x\n", svga->seqaddr & 0xff, val, svga->chain4); @@ -377,70 +387,76 @@ ht216_out(uint16_t addr, uint8_t val, void *p) } break; - case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: + case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: if (ht216->id == 0x7152) sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); else svga_out(addr, val, svga); return; - case 0x3cf: - if (svga->gdcaddr == 5) { - svga->chain2_read = val & 0x10; - ht216_remap(ht216); - } else if (svga->gdcaddr == 6) { - if (val & 8) - svga->banked_mask = 0x7fff; - else - svga->banked_mask = 0xffff; - } - - if (svga->gdcaddr <= 8) { - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && - !svga->gdcreg[1]) && svga->chain4 && svga->packed_chain4; - } - break; + case 0x3cb: + if (ht216->id == 0x7152) { + ht216->reg_3cb = val; + svga_set_ramdac_type(svga, (val & 0x20) ? RAMDAC_6BIT : RAMDAC_8BIT); + } + break; - case 0x3D4: - svga->crtcreg = val & 0x3f; + case 0x3cf: + if (svga->gdcaddr == 5) { + svga->chain2_read = val & 0x10; + ht216_remap(ht216); + } else if (svga->gdcaddr == 6) { + if (val & 8) + svga->banked_mask = 0x7fff; + else + svga->banked_mask = 0xffff; + } + + if (svga->gdcaddr <= 8) { + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && + !svga->gdcreg[1]) && svga->chain4 && svga->packed_chain4; + } + break; + + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { - svga->fullchange = 3; + svga->fullchange = 3; svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = changeframecount; - svga_recalctimings(svga); + svga_recalctimings(svga); } - } } - break; + } + break; - case 0x46e8: + case 0x46e8: + if ((ht216->id == 0x7152) && ht216->isabus) + io_removehandler(0x0105, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + io_removehandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&ht216->linear_mapping); + if (val & 8) { if ((ht216->id == 0x7152) && ht216->isabus) - io_removehandler(0x0105, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); - io_removehandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&ht216->linear_mapping); - if (val & 8) { - if ((ht216->id == 0x7152) && ht216->isabus) - io_sethandler(0x0105, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); - io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); - mem_mapping_enable(&svga->mapping); - ht216_remap(ht216); - } - break; + io_sethandler(0x0105, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + mem_mapping_enable(&svga->mapping); + ht216_remap(ht216); + } + break; } svga_out(addr, val, svga); @@ -457,10 +473,10 @@ ht216_in(uint16_t addr, void *p) if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; - if ((ht216->id == 0x7152) && ht216->isabus) { - if (addr == 0x105) - return ht216->extensions; - } + if ((ht216->id == 0x7152) && ht216->isabus) { + if (addr == 0x105) + return ht216->extensions; + } switch (addr) { case 0x3c4: @@ -523,6 +539,11 @@ ht216_in(uint16_t addr, void *p) return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); return svga_in(addr, svga); + case 0x3cb: + if (ht216->id == 0x7152) + return ht216->reg_3cb; + break; + case 0x3cc: return svga->miscout; @@ -618,52 +639,62 @@ ht216_recalctimings(svga_t *svga) ht216->adjust_cursor = 0; - if (svga->crtc[0x17] == 0xeb) { - svga->rowoffset <<= 1; - svga->render = svga_render_2bpp_headland_highres; - } - - if (svga->bpp == 8) { - ht216_log("regC8 = %02x, gdcreg5 bit 6 = %02x, no lowres = %02x, regf8 bit 7 = %02x, regfc = %02x\n", ht216->ht_regs[0xc8] & HT_REG_C8_E256, svga->gdcreg[5] & 0x40, !svga->lowres, ht216->ht_regs[0xf6] & 0x80, ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE); - if (((ht216->ht_regs[0xc8] & HT_REG_C8_E256) || (svga->gdcreg[5] & 0x40)) && (!svga->lowres || (ht216->ht_regs[0xf6] & 0x80))) { - if (high_res_256) { - svga->hdisp >>= 1; - ht216->adjust_cursor = 1; - } - svga->render = svga_render_8bpp_highres; - } else if (svga->lowres) { - if (high_res_256) { - svga->hdisp >>= 1; - ht216->adjust_cursor = 1; - svga->render = svga_render_8bpp_highres; + if (!svga->scrblank && svga->attr_palette_enable) { + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + if (svga->seqregs[1] & 8) /*40 column*/ { + svga->render = svga_render_text_40; } else { - ht216_log("8bpp low, packed = %02x, chain4 = %02x\n", svga->packed_chain4, svga->chain4); - svga->render = svga_render_8bpp_lowres; + svga->render = svga_render_text_80; } - } else if (ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE) { - if (ht216->id == 0x7152) { - svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); - if (!(svga->crtc[1] & 1)) - svga->hdisp--; - svga->hdisp++; - svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; - svga->rowoffset <<= 1; - if ((svga->crtc[0x17] & 0x60) == 0x20) /*Would result in a garbled screen with trailing cursor glitches*/ - svga->force_byte_mode = 1; - else - svga->force_byte_mode = 0; - } - svga->render = svga_render_8bpp_highres; - } - } else if (svga->bpp == 15) { + } else { + if (svga->crtc[0x17] == 0xeb) { svga->rowoffset <<= 1; - svga->hdisp >>= 1; - svga->render = svga_render_15bpp_highres; - } + svga->render = svga_render_2bpp_headland_highres; + } + if (svga->bpp == 8) { + ht216_log("regC8 = %02x, gdcreg5 bit 6 = %02x, no lowres = %02x, regf8 bit 7 = %02x, regfc = %02x\n", ht216->ht_regs[0xc8] & HT_REG_C8_E256, svga->gdcreg[5] & 0x40, !svga->lowres, ht216->ht_regs[0xf6] & 0x80, ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE); + if (((ht216->ht_regs[0xc8] & HT_REG_C8_E256) || (svga->gdcreg[5] & 0x40)) && (!svga->lowres || (ht216->ht_regs[0xf6] & 0x80))) { + if (high_res_256) { + svga->hdisp >>= 1; + ht216->adjust_cursor = 1; + } + svga->render = svga_render_8bpp_highres; + } else if (svga->lowres) { + if (high_res_256) { + svga->hdisp >>= 1; + ht216->adjust_cursor = 1; + svga->render = svga_render_8bpp_highres; + } else { + ht216_log("8bpp low, packed = %02x, chain4 = %02x\n", svga->packed_chain4, svga->chain4); + svga->render = svga_render_8bpp_lowres; + } + } else if (ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE) { + if (ht216->id == 0x7152) { + svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); + if (!(svga->crtc[1] & 1)) + svga->hdisp--; + svga->hdisp++; + svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; + svga->rowoffset <<= 1; + if ((svga->crtc[0x17] & 0x60) == 0x20) /*Would result in a garbled screen with trailing cursor glitches*/ + svga->crtc[0x17] |= 0x40; + } + svga->render = svga_render_8bpp_highres; + } + } else if (svga->bpp == 15) { + svga->rowoffset <<= 1; + svga->hdisp >>= 1; + if ((svga->crtc[0x17] & 0x60) == 0x20) /*Would result in a garbled screen with trailing cursor glitches*/ + svga->crtc[0x17] |= 0x40; + svga->render = svga_render_15bpp_highres; + } + } + } + svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 14); - if (svga->crtc[0x17] == 0xeb) /*Looks like that 1024x768 mono mode expects 512K of video memory*/ + if (svga->crtc[0x17] == 0xeb) /*Looks like 1024x768 mono mode expects 512K of video memory*/ svga->vram_display_mask = 0x7ffff; else svga->vram_display_mask = (ht216->ht_regs[0xf6] & 0x40) ? ht216->vram_mask : 0x3ffff; @@ -1390,7 +1421,7 @@ void video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_v7vga_vlb); else if (info->flags & DEVICE_MCA) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_v7vga_mca); - else + else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_v7vga_isa); svga_init(info, svga, ht216, mem_size, @@ -1466,11 +1497,11 @@ void mem_mapping_disable(&ht216->linear_mapping); ht216->id = info->local; - ht216->isabus = (info->flags & DEVICE_ISA); - ht216->mca = (info->flags & DEVICE_MCA); - - io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); - io_sethandler(0x46e8, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + ht216->isabus = (info->flags & DEVICE_ISA); + ht216->mca = (info->flags & DEVICE_MCA); + + io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + io_sethandler(0x46e8, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); svga->bpp = 8; svga->miscout = 1; @@ -1478,6 +1509,9 @@ void if (ht216->id == 0x7861) ht216->ht_regs[0xb4] = 0x08; /*32-bit DRAM bus*/ + if (ht216->id == 0x7152) + ht216->reg_3cb = 0x20; + /* Initialize the cursor pointer towards the end of its segment, needed for ht256sf.drv to work correctly when Windows 3.1 is started after boot. */ ht216->ht_regs[0x94] = 0xff; diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index 892967837..941359987 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -28,6 +28,7 @@ #include <86box/device.h> #include <86box/video.h> #include <86box/vid_svga.h> +#include <86box/vid_svga_render.h> #define BIOS_037C_PATH "roms/video/oti/bios.bin" #define BIOS_067_AMA932J_PATH "roms/machines/ama932j/oti067.bin" @@ -85,6 +86,14 @@ oti_out(uint16_t addr, uint8_t val, void *p) return; } else break; + break; + + case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: + if (oti->chip_id == OTI_077) + sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); + else + svga_out(addr, val, svga); + return; case 0x3D4: if (oti->chip_id) @@ -216,6 +225,11 @@ oti_in(uint16_t addr, void *p) temp = oti->enable_register; break; + case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: + if (oti->chip_id == OTI_077) + return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); + return svga_in(addr, svga); + case 0x3CF: return svga->gdcreg[svga->gdcaddr & 0xf]; @@ -343,6 +357,14 @@ oti_recalctimings(svga_t *svga) if ((oti->regs[0x0d] & 0x0c) && !(oti->regs[0x0d] & 0x10)) svga->rowoffset <<= 1; svga->interlace = oti->regs[0x14] & 0x80; + + if (svga->bpp == 16) { + svga->render = svga_render_16bpp_highres; + svga->hdisp >>= 1; + } else if (svga->bpp == 15) { + svga->render = svga_render_15bpp_highres; + svga->hdisp >>= 1; + } } @@ -406,6 +428,9 @@ oti_init(const device_t *info) svga_init(info, &oti->svga, oti, oti->vram_size << 10, oti_recalctimings, oti_in, oti_out, NULL, NULL); + if (oti->chip_id == OTI_077) + oti->svga.ramdac = device_add(&sc11487_ramdac_device); /*Actually a 82c487, probably a clone.*/ + io_sethandler(0x03c0, 32, oti_in, NULL, NULL, oti_out, NULL, NULL, oti); diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index edb732032..5fd0aada0 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -54,6 +54,7 @@ typedef struct paradise_t uint32_t read_bank[4], write_bank[4]; int interlace; + int check; struct { uint8_t reg_block_ptr; @@ -105,6 +106,13 @@ void paradise_out(uint16_t addr, uint8_t val, void *p) } break; + case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: + if (paradise->type == WD90C30) + sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); + else + svga_out(addr, val, svga); + return; + case 0x3cf: if (svga->gdcaddr >= 9 && svga->gdcaddr <= 0x0e) { if ((paradise->pr5 & 7) != 5) @@ -215,7 +223,12 @@ uint8_t paradise_in(uint16_t addr, void *p) return svga->seqregs[svga->seqaddr & 0x1f]; } break; - + + case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: + if (paradise->type == WD90C30) + return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); + return svga_in(addr, svga); + case 0x3cf: if (svga->gdcaddr >= 9 && svga->gdcaddr <= 0x0e) { if ((paradise->pr5 & 7) != 5) @@ -232,8 +245,11 @@ uint8_t paradise_in(uint16_t addr, void *p) paradise->pr1 &= ~0x40; } else if (paradise->vram_mask == (1024 << 10) - 1) { paradise->pr1 |= 0xc0; - if (svga->bpp >= 8 && !svga->lowres) /*Horrible tweak, but needed to get around black corruption in 1M mode*/ + /*The following is a horrible tweak, but needed to get around black corruption in 1M mode*/ + if (svga->bpp >= 8 && (svga->gdcreg[0x0e] & 0x01) && paradise->check) paradise->pr1 &= ~0x40; + else if (!(svga->gdcreg[0x0e] & 0x01) && !(svga->crtc[0x14] & 0x40) && paradise->check) + paradise->check = 0; } return paradise->pr1; case 6: @@ -336,9 +352,25 @@ void paradise_recalctimings(svga_t *svga) svga->interlace = 1; } } - - if (svga->bpp >= 8 && !svga->lowres) - svga->render = svga_render_8bpp_highres; + + if (paradise->type < WD90C30) { + if (svga->bpp >= 8 && !svga->lowres) + svga->render = svga_render_8bpp_highres; + } else { + if (svga->bpp >= 8 && !svga->lowres) { + if (svga->bpp == 16) { + svga->render = svga_render_16bpp_highres; + svga->hdisp >>= 1; + } else if (svga->bpp == 15) { + svga->render = svga_render_15bpp_highres; + svga->hdisp >>= 1; + } else { + if ((svga->crtc[0x17] == 0xc2) && (svga->crtc[0x14] & 0x40)) + paradise->check = 1; + svga->render = svga_render_8bpp_highres; + } + } + } } static void paradise_write(uint32_t addr, uint8_t val, void *p) @@ -348,7 +380,7 @@ static void paradise_write(uint32_t addr, uint8_t val, void *p) addr &= svga->banked_mask; addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; - + svga_write_linear(addr, val, svga); } static void paradise_writew(uint32_t addr, uint16_t val, void *p) @@ -421,6 +453,7 @@ void *paradise_init(const device_t *info, uint32_t memsize) NULL); paradise->vram_mask = memsize - 1; svga->decode_mask = memsize - 1; + svga->ramdac = device_add(&sc11487_ramdac_device); /*Actually a Winbond W82c487-80, probably a clone.*/ break; } diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index f305a2f59..c04a00b78 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -238,7 +238,7 @@ typedef struct s3_t uint16_t multifunc[16]; uint8_t pix_trans[4]; int ssv_state; - + int cx, cy; int px, py; int sx, sy; @@ -347,10 +347,13 @@ typedef struct s3_t int translate; int enable_8514; + int color_16bit; volatile int busy, force_busy; uint8_t thread_run, serialport; void *i2c, *ddc; + + int vram; } s3_t; #define INT_VSY (1 << 0) @@ -385,7 +388,8 @@ static uint32_t s3_accel_in_l(uint16_t port, void *p); static uint8_t s3_pci_read(int func, int addr, void *p); static void s3_pci_write(int func, int addr, uint8_t val, void *p); -/*Remap address for chain-4/doubleword style layout*/ +/*Remap address for chain-4/doubleword style layout. + These will stay for convenience.*/ static __inline uint32_t dword_remap(svga_t *svga, uint32_t in_addr) { @@ -450,7 +454,7 @@ static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3); temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; \ #define READ_PIXTRANS_WORD \ - if (s3->bpp == 0) { \ + if (s3->bpp == 0 && !s3->color_16bit) { \ temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; \ temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 1)) & s3->vram_mask] << 8); \ } else { \ @@ -458,7 +462,7 @@ static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3); } #define READ_PIXTRANS_LONG \ - if (s3->bpp == 0) { \ + if (s3->bpp == 0 && !s3->color_16bit) { \ temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; \ temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 1)) & s3->vram_mask] << 8); \ temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 2)) & s3->vram_mask] << 16); \ @@ -516,7 +520,7 @@ static void s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) { svga_t *svga = &s3->svga; - + if (s3->accel.cmd & 0x100) { switch (s3->accel.cmd & 0x600) { case 0x000: @@ -527,8 +531,12 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) s3_accel_start(8, 1, val | (val << 16), 0, s3); } else s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); - } else - s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); + } else { + if (s3->color_16bit) + s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + else + s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); + } break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -697,12 +705,14 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.cur_x2 = (s3->accel.cur_x2 & 0xff) | ((val & 0x0f) << 8); s3->accel.poly_cx2 = s3->accel.cur_x2 << 20; break; - + + case 0xcae8: case 0x8948: case 0x8ae8: s3->accel.draw_fifo_slot++; s3->accel.desty_axstp = (s3->accel.desty_axstp & 0x3f00) | val; s3->accel.point_1_updated = 1; break; + case 0xcae9: case 0x8949: case 0x8ae9: s3->accel.desty_axstp = (s3->accel.desty_axstp & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) @@ -802,7 +812,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.short_stroke = (s3->accel.short_stroke & 0xff00) | val; break; case 0x9d49: case 0x9ee9: - s3->accel.short_stroke = (s3->accel.short_stroke & 0xff) | (val << 8); + s3->accel.short_stroke = (s3->accel.short_stroke & 0xff) | (val << 8); s3->accel.ssv_state = 1; s3->accel.cx = s3->accel.cur_x; @@ -1012,7 +1022,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.setup_fifo_slot++; s3->accel.frgd_mix = val; break; - + case 0xbd48: case 0xbee8: s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff00) | val; break; @@ -1135,8 +1145,12 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); else s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - } else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + } else { + if (s3->color_16bit) + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + else + s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + } } } break; @@ -1153,8 +1167,9 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3_accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); else s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - } else + } else { s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + } break; case 0x200: /*Windows 95's built-in driver expects this to be loaded regardless of the byte swap bit (0xE2E9) in the 86c928*/ @@ -1276,7 +1291,7 @@ static void s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) { if (port != 0x9ee8 && port != 0x9d48) { - if (port == 0xb2e8) { + if (port == 0xb2e8 || port == 0xb148) { s3->accel.b2e8_pix = 1; } else { s3->accel.b2e8_pix = 0; @@ -1305,11 +1320,12 @@ s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) static void s3_accel_out_fifo_l(s3_t *s3, uint16_t port, uint32_t val) { - if (port == 0xb2e8) { + if (port == 0xb2e8 || port == 0xb148) { s3->accel.b2e8_pix = 1; } else { s3->accel.b2e8_pix = 0; } + s3_accel_out_pixtrans_l(s3, val); } @@ -1491,7 +1507,7 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); } } - } + } } } @@ -2222,11 +2238,13 @@ s3_io_remove(s3_t *s3) io_removehandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xcae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xd2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xe2e8, 0x0004, s3_accel_in, s3_accel_in_w, s3_accel_in_l, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); io_removehandler(0xe6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xeae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xeee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xfee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); s3_io_remove_alt(s3); } @@ -2339,13 +2357,15 @@ s3_io_set(s3_t *s3) io_sethandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xcae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0xe2e8, 0x0004, s3_accel_in, s3_accel_in_w, s3_accel_in_l, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) { io_sethandler(0xd2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0xe6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0xeae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0xeee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - } + } + io_sethandler(0xfee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); s3_io_set_alt(s3); } @@ -2383,7 +2403,7 @@ s3_out(uint16_t addr, uint8_t val, void *p) } if (svga->seqaddr == 4) /*Chain-4 - update banking*/ { - if (val & 8) + if (val & 0x08) svga->write_bank = svga->read_bank = s3->bank << 16; else svga->write_bank = svga->read_bank = s3->bank << 14; @@ -2428,9 +2448,9 @@ s3_out(uint16_t addr, uint8_t val, void *p) tvp3026_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && (s3->card_type != S3_MIROCRYSTAL10SD_805 && s3->card_type != S3_MIROCRYSTAL8S_805)) att49x_ramdac_out(addr, rs2, val, svga->ramdac, svga); - else if (s3->chip <= S3_86C924) - sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); - else + else if (s3->chip <= S3_86C924) { + sc1148x_ramdac_out(addr, rs2, val, svga->ramdac, svga); + } else sdac_ramdac_out(addr, rs2, val, svga->ramdac, svga); return; @@ -2450,7 +2470,9 @@ s3_out(uint16_t addr, uint8_t val, void *p) return; if ((svga->crtcreg == 0x36) && (svga->crtc[0x39] != 0xa5)) return; - if ((s3->chip == S3_TRIO64V2) && svga->crtcreg >= 0x80) + if ((s3->chip == S3_TRIO64V2) && (svga->crtcreg >= 0x80)) + return; + if ((s3->chip <= S3_86C924) && (svga->crtcreg >= 0x50)) return; old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; @@ -2459,8 +2481,6 @@ s3_out(uint16_t addr, uint8_t val, void *p) { case 0x31: s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); - if (!svga->packed_chain4) - svga->force_dword_mode = val & 0x08; break; case 0x32: if ((svga->crtc[0x31] & 0x30) && (svga->crtc[0x51] & 0x01) && (val & 0x40)) @@ -2513,6 +2533,7 @@ s3_out(uint16_t addr, uint8_t val, void *p) else svga->write_bank = svga->read_bank = s3->bank << 14; break; + case 0x51: if (s3->chip == S3_86C801 || s3->chip == S3_86C805) { s3->bank = (s3->bank & 0x6f) | ((val & 0x4) << 2); @@ -2714,7 +2735,7 @@ s3_in(uint16_t addr, void *p) } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && (s3->card_type != S3_MIROCRYSTAL10SD_805 && s3->card_type != S3_MIROCRYSTAL8S_805)) return att49x_ramdac_in(addr, rs2, svga->ramdac, svga); else if (s3->chip <= S3_86C924) - return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); + return sc1148x_ramdac_in(addr, rs2, svga->ramdac, svga); else return sdac_ramdac_in(addr, rs2, svga->ramdac, svga); break; @@ -2781,11 +2802,12 @@ static void s3_recalctimings(svga_t *svga) if (!svga->scrblank && svga->attr_palette_enable) { if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - if (svga->crtc[0x3a] & 0x10) /*256+ color register*/ + if (svga->crtc[0x3a] & 0x10) { /*256+ color register*/ svga->gdcreg[5] |= 0x40; + } } } - + svga->ma_latch |= (s3->ma_ext << 16); if (s3->chip >= S3_86C928) { svga->hdisp = svga->hdisp_old; @@ -2834,7 +2856,7 @@ static void s3_recalctimings(svga_t *svga) if (s3->card_type == S3_MIROCRYSTAL10SD_805 || s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_MIROCRYSTAL20SV_964 || s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805 || s3->card_type == S3_MIROCRYSTAL8S_805) { - if (svga->bpp != 32) { + if (svga->bpp != 32) { if (svga->crtc[0x31] & 2) /*This is needed if the pixel width gets set with delays*/ s3->width = 2048; } @@ -2844,8 +2866,22 @@ static void s3_recalctimings(svga_t *svga) s3->width = 1024; } } + + if ((svga->crtc[0x43] & 0x08) && (s3->color_16bit == 0) && (s3->chip <= S3_86C805)) { + s3->color_16bit = 1; + s3->width = 1024; + } else if (!(svga->crtc[0x43] & 0x08) && (s3->color_16bit == 1) && (s3->chip <= S3_86C805)) { + s3->color_16bit = 0; + if (s3->chip <= S3_86C924) { + if (s3->accel.advfunc_cntl & 4) + s3->width = 1024; + else + s3->width = 640; + } + } if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { + svga->fb_only = 1; switch (svga->bpp) { case 8: svga->render = svga_render_8bpp_highres; @@ -2867,7 +2903,7 @@ static void s3_recalctimings(svga_t *svga) if (svga->hdisp != 1408) svga->hdisp = s3->width; if (s3->card_type == S3_MIROCRYSTAL20SD_864) { - if (s3->width == 2048) { + if (s3->width == 2048 || s3->width == 1600 || s3->width == 800) { switch (svga->dispend) { case 400: case 480: @@ -2879,6 +2915,8 @@ static void s3_recalctimings(svga_t *svga) break; case 600: + if (s3->width == 1600) + s3->width = 800; svga->hdisp = 800; break; @@ -2906,8 +2944,6 @@ static void s3_recalctimings(svga_t *svga) break; case 15: svga->render = svga_render_15bpp_highres; - if (s3->chip <= S3_86C924) - svga->rowoffset >>= 1; if ((s3->chip != S3_VISION964) && (s3->card_type != S3_SPEA_MIRAGE_86C801) && (s3->card_type != S3_SPEA_MIRAGE_86C805)) { if (s3->chip == S3_86C928) @@ -2933,8 +2969,6 @@ static void s3_recalctimings(svga_t *svga) break; case 16: svga->render = svga_render_16bpp_highres; - if (s3->chip <= S3_86C924) - svga->rowoffset >>= 1; if ((s3->chip != S3_VISION964) && (s3->card_type != S3_SPEA_MIRAGE_86C801) && (s3->card_type != S3_SPEA_MIRAGE_86C805)) { if (s3->chip == S3_86C928) @@ -2974,7 +3008,7 @@ static void s3_recalctimings(svga_t *svga) } break; case 32: - svga->render = svga_render_32bpp_highres; + svga->render = svga_render_32bpp_highres; if ((s3->chip < S3_TRIO32) && (s3->chip != S3_VISION964) && (s3->chip != S3_VISION968) && (s3->chip != S3_86C928)) { if (s3->chip == S3_VISION868) @@ -2989,7 +3023,7 @@ static void s3_recalctimings(svga_t *svga) s3->card_type == S3_SPEA_MERCURY_P64V) { svga->hdisp = s3->width; if (s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_MIROCRYSTAL20SV_964) { - if ((svga->crtc[0x31] & 2) && (svga->crtc[0x50] & 0xc1) != 0x00) { + if (s3->width == 800 || s3->width == 1024 || s3->width == 1600) { switch (svga->dispend) { case 400: case 480: @@ -2997,22 +3031,37 @@ static void s3_recalctimings(svga_t *svga) break; case 576: + if (s3->width == 1600) + s3->width = 800; svga->hdisp = 768; break; case 600: + if (s3->width == 1600) + s3->width = 800; svga->hdisp = 800; break; - } + } } } } break; } } else { - if (svga->gdcreg[5] & 0x40) { - if (!svga->lowres) - svga->rowoffset <<= 1; + svga->fb_only = 0; + if (!svga->scrblank && svga->attr_palette_enable) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + if ((svga->crtc[0x31] & 0x08) && ((svga->gdcreg[5] & 0x60) == 0x00)) { + if (svga->bpp == 8) { + svga->render = svga_render_8bpp_highres; /*Enhanced 4bpp mode, just like the 8bpp mode per spec.*/ + if (svga->hdisp <= 1024) + s3->width = 1024; + } + } + } else { + if (s3->chip <= S3_86C924) + s3->width = 1024; + } } } } @@ -3028,9 +3077,7 @@ static void s3_trio64v_recalctimings(svga_t *svga) svga->gdcreg[5] |= 0x40; } } - svga->hdisp = svga->hdisp_old; - if (svga->crtc[0x5d] & 0x01) svga->htotal |= 0x100; if (svga->crtc[0x5d] & 0x02) { svga->hdisp_time |= 0x100; @@ -3053,7 +3100,9 @@ static void s3_trio64v_recalctimings(svga_t *svga) if (!svga->rowoffset) svga->rowoffset = 256; svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); + if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { + svga->fb_only = 1; switch (svga->bpp) { case 8: svga->render = svga_render_8bpp_highres; @@ -3074,10 +3123,13 @@ static void s3_trio64v_recalctimings(svga_t *svga) svga->render = svga_render_32bpp_highres; break; } - } + } else + svga->fb_only = 0; } else /*Streams mode*/ { + svga->fb_only = 1; + if (s3->streams.buffer_ctrl & 1) svga->ma_latch = s3->streams.pri_fb1 >> 2; else @@ -3163,7 +3215,7 @@ s3_updatemapping(s3_t *s3) svga->banked_mask = 0x7fff; break; } - + if (s3->chip >= S3_86C928) { s3->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); @@ -3207,25 +3259,21 @@ s3_updatemapping(s3_t *s3) s3->linear_base &= ~(s3->linear_size - 1); if (s3->linear_base == 0xa0000) { mem_mapping_disable(&s3->linear_mapping); - if (!(svga->crtc[0x53] & 0x10)) - { - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + if (!(svga->crtc[0x53] & 0x10)) { + mem_mapping_set_addr(&svga->mapping, s3->linear_base, 0x10000); svga->banked_mask = 0xffff; } } else { if (s3->chip >= S3_TRIO64V) { s3->linear_base &= 0xfc000000; - svga->fb_only = 1; } else if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) { s3->linear_base &= 0xfe000000; - svga->fb_only = 1; } + mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); } - } else { + } else { mem_mapping_disable(&s3->linear_mapping); - if (s3->chip >= S3_TRIO64V || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) - svga->fb_only = 0; } /* Memory mapped I/O. */ @@ -3236,11 +3284,13 @@ s3_updatemapping(s3_t *s3) mem_mapping_set_addr(&s3->mmio_mapping, 0xb8000, 0x8000); else mem_mapping_set_addr(&s3->mmio_mapping, 0xa0000, 0x10000); - } else + } else { mem_mapping_enable(&s3->mmio_mapping); - } else + } + } else { mem_mapping_disable(&s3->mmio_mapping); - + } + /* New MMIO. */ if (svga->crtc[0x53] & 0x08) mem_mapping_set_addr(&s3->new_mmio_mapping, s3->linear_base + 0x1000000, 0x20000); @@ -3271,15 +3321,12 @@ s3_accel_out(uint16_t port, uint8_t val, void *p) s3_t *s3 = (s3_t *)p; svga_t *svga = &s3->svga; - if (port >= 0x8000) - { + if (port >= 0x8000) { if (!s3->enable_8514) return; - + s3_accel_out_fifo(s3, port, val); - } - else - { + } else { switch (port) { case 0x4148: case 0x42e8: @@ -3299,8 +3346,12 @@ s3_accel_out(uint16_t port, uint8_t val, void *p) s3->width = (val & 4) ? 1600 : 800; svga->fullchange = changeframecount; svga_recalctimings(svga); + } else if (s3->chip <= S3_86C805) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); } - s3_updatemapping(s3); + if (s3->chip > S3_86C924) + s3_updatemapping(s3); break; } } @@ -3764,21 +3815,28 @@ s3_accel_in_w(uint16_t port, void *p) if (s3->accel.cmd & 0x1000) temp = (temp >> 8) | (temp << 8); s3_accel_start(8, 1, temp | (temp << 16), 0, s3); - } else + } else { s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); - } else - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); + } + } else { + if (s3->color_16bit) { + s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + } else { + s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); + } + } break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) - temp = (temp >> 8) | (temp << 8); + temp = (temp >> 8) | (temp << 8); s3_accel_start(16, 1, temp | (temp << 16), 0, s3); } else s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); - } else + } else { s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + } break; } } @@ -4223,8 +4281,8 @@ polygon_setup(s3_t *s3) } } -#define READ(addr, dat) if (s3->bpp == 0) dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \ - else if (s3->bpp == 1) dat = vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)]; \ +#define READ(addr, dat) if (s3->bpp == 0 && !s3->color_16bit) dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \ + else if (s3->bpp == 1 || s3->color_16bit) dat = vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)]; \ else if (s3->bpp == 2) dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \ else dat = vram_l[dword_remap_l(svga, addr) & (s3->vram_mask >> 2)]; @@ -4529,12 +4587,12 @@ polygon_setup(s3_t *s3) } -#define WRITE(addr, dat) if (s3->bpp == 0) \ +#define WRITE(addr, dat) if (s3->bpp == 0 && !s3->color_16bit) \ { \ - svga->vram[dword_remap(svga, addr) & s3->vram_mask] = dat; \ + svga->vram[dword_remap(svga, addr) & s3->vram_mask] = dat; \ svga->changedvram[(dword_remap(svga, addr) & s3->vram_mask) >> 12] = changeframecount; \ } \ - else if (s3->bpp == 1) \ + else if (s3->bpp == 1 || s3->color_16bit) \ { \ vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)] = dat; \ svga->changedvram[(dword_remap_w(svga, addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \ @@ -5040,44 +5098,37 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ uint32_t rd_mask = s3->accel.rd_mask; int cmd = s3->accel.cmd >> 13; uint32_t srcbase, dstbase; - - if (s3->chip <= S3_86C805) { /*Chicago 4.00.58s' s3 driver has a weird bug, not sure on real hardware*/ - if (s3->bpp == 0 && svga->bpp == 15 && s3->width == 2048) { - s3->bpp = 1; - s3->width >>= 1; - } - } if ((s3->chip >= S3_TRIO64 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (s3->accel.cmd & (1 << 11))) { cmd |= 8; } - // SRC-BASE/DST-BASE - if ((s3->accel.multifunc[0xd] >> 4) & 7) { - srcbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 4) & 3); - } else { - srcbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 2) & 3); - } - if ((s3->accel.multifunc[0xd] >> 0) & 7) { - dstbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 0) & 3); - } else { - dstbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 0) & 3); - } - if (s3->bpp == 1) { - srcbase >>= 1; - dstbase >>= 1; - } else if (s3->bpp == 3) { - srcbase >>= 2; - dstbase >>= 2; - } + // SRC-BASE/DST-BASE + if ((s3->accel.multifunc[0xd] >> 4) & 7) { + srcbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 4) & 3); + } else { + srcbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 2) & 3); + } + if ((s3->accel.multifunc[0xd] >> 0) & 7) { + dstbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 0) & 3); + } else { + dstbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 0) & 3); + } + if (s3->bpp == 1) { + srcbase >>= 1; + dstbase >>= 1; + } else if (s3->bpp == 3) { + srcbase >>= 2; + dstbase >>= 2; + } - if ((s3->accel.cmd & 0x100) && ((s3_cpu_src(s3) || (s3_cpu_dest(s3))) && !cpu_input)) { + if ((s3->accel.cmd & 0x100) && ((s3_cpu_src(s3) || (s3_cpu_dest(s3)))) && (!cpu_input || (s3_enable_fifo(s3) == 0))) { s3->force_busy = 1; } if (!cpu_input) s3->accel.dat_count = 0; - + if (cpu_input && (((s3->accel.multifunc[0xa] & 0xc0) != 0x80) || (!(s3->accel.cmd & 2)))) { if ((s3->bpp == 3) && count == 2) { if (s3->accel.dat_count) { @@ -5089,19 +5140,19 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dat_count = 1; } } - if (s3->bpp == 1) + if (s3->bpp == 1 || s3->color_16bit) count >>= 1; if (s3->bpp == 3) count >>= 2; } - if (s3->bpp == 0) + if (s3->bpp == 0 && !s3->color_16bit) rd_mask &= 0xff; - else if (s3->bpp == 1) + else if (s3->bpp == 1 || s3->color_16bit) rd_mask &= 0xffff; - if (s3->bpp == 0) compare &= 0xff; - if (s3->bpp == 1) compare &= 0xffff; + if (s3->bpp == 0 && !s3->color_16bit) compare &= 0xff; + if (s3->bpp == 1 || s3->color_16bit) compare &= 0xffff; switch (s3->accel.cmd & 0x600) { @@ -5114,6 +5165,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on the NOP command)*/ + switch (cmd) { case 0: /*NOP (Short Stroke Vectors)*/ @@ -5187,14 +5239,13 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; s3->accel.sy = s3->accel.maj_axis_pcnt; - + s3_fifo_slots(s3); - + if (s3_cpu_src(s3)) { return; /*Wait for data from CPU*/ } } - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; @@ -5213,24 +5264,26 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 3: src_dat = 0; break; } - if (((compare_mode == 2 && src_dat != compare) || + if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || - compare_mode < 2)) + compare_mode < 2) { READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - + MIX - if (s3->accel.cmd & 0x10) { - WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - } + WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); } } mix_dat <<= 1; mix_dat |= 1; - if (s3->bpp == 0) cpu_dat >>= 8; - else cpu_dat >>= 16; + if (s3->bpp == 0 && !s3->color_16bit) + cpu_dat >>= 8; + else { + cpu_dat >>= 16; + } + if (!s3->accel.sy) { break; } @@ -5246,7 +5299,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 0xc0: s3->accel.cy++; break; case 0xe0: s3->accel.cx++; s3->accel.cy++; break; } - s3->accel.sy--; } s3->accel.cur_x = s3->accel.cx; @@ -5254,7 +5306,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ } else /*Bresenham*/ { - if (s3->accel.b2e8_pix && count == 16) { /*Stupid undocumented 0xB2E8 on 911/924*/ + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && count == 16) { /*Stupid undocumented 0xB2E8 on 911/924*/ count = s3->accel.maj_axis_pcnt + 1; s3->accel.temp_cnt = 16; } @@ -5277,17 +5329,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 3: src_dat = 0; break; } - if (((compare_mode == 2 && src_dat != compare) || + if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || - compare_mode < 2)) + compare_mode < 2) { READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); MIX - if (s3->accel.cmd & 0x10) { - WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - } + WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); } } @@ -5301,13 +5351,16 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ mix_dat <<= 1; mix_dat |= 1; } - if (s3->bpp == 0) cpu_dat >>= 8; - else cpu_dat >>= 16; + if (s3->bpp == 0 && !s3->color_16bit) + cpu_dat >>= 8; + else { + cpu_dat >>= 16; + } if (!s3->accel.sy) { break; } - + if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) { s3->accel.err_term += s3->accel.destx_distp; /*Step minor axis*/ @@ -5338,7 +5391,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 0xc0: s3->accel.cy++; break; case 0xe0: s3->accel.cy++; break; } - s3->accel.sy--; } s3->accel.cur_x = s3->accel.cx; @@ -5446,10 +5498,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ mix_dat |= 1; } - if (s3->bpp == 0) + if (s3->bpp == 0 && !s3->color_16bit) cpu_dat >>= 8; - else + else { cpu_dat >>= 16; + } if (s3->accel.cmd & 0x20) s3->accel.cx++; @@ -5474,6 +5527,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.sy--; if (cpu_input) { + if (s3->accel.b2e8_pix) { + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; + } return; } if (s3->accel.sy < 0) { @@ -5620,7 +5677,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ frgd_mix = (s3->accel.frgd_mix >> 5) & 3; bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - if (!cpu_input && frgd_mix == 3 && !vram_mask && !compare_mode && (s3->accel.cmd & 0xa0) == 0xa0 && (s3->accel.frgd_mix & 0xf) == 7 && (s3->accel.bkgd_mix & 0xf) == 7) @@ -5705,8 +5761,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ mix_dat <<= 1; mix_dat |= 1; - if (s3->bpp == 0) cpu_dat >>= 8; - else cpu_dat >>= 16; + if (s3->bpp == 0 && !s3->color_16bit) + cpu_dat >>= 8; + else { + cpu_dat >>= 16; + } if (s3->accel.cmd & 0x20) { @@ -6395,6 +6454,146 @@ static int vram_sizes[] = 3 /*8 MB*/ }; +static void s3_reset(void *priv) +{ + s3_t *s3 = (s3_t *) priv; + svga_t *svga = &s3->svga; + + memset(svga->crtc, 0x00, sizeof(svga->crtc)); + svga->crtc[0] = 63; + svga->crtc[6] = 255; + svga->dispontime = 1000ull << 32; + svga->dispofftime = 1000ull << 32; + svga->bpp = 8; + + if (s3->pci) + svga->crtc[0x36] = 2 | (3 << 2) | (1 << 4); + else if (s3->vlb) + svga->crtc[0x36] = 1 | (3 << 2) | (1 << 4); + else + svga->crtc[0x36] = 3 | (1 << 4); + + if (s3->chip >= S3_86C928) + svga->crtc[0x36] |= (vram_sizes[s3->vram] << 5); + else + svga->crtc[0x36] |= ((s3->vram == 1) ? 0x00 : 0x20) | 0x80; + + svga->crtc[0x37] = 1 | (7 << 5); + + if (s3->chip >= S3_86C928) + svga->crtc[0x37] |= 0x04; + + s3_io_set(s3); + + memset(s3->pci_regs, 0x00, 256); + + s3->pci_regs[PCI_REG_COMMAND] = 7; + + s3->pci_regs[0x30] = 0x00; + s3->pci_regs[0x32] = 0x0c; + s3->pci_regs[0x33] = 0x00; + + switch(s3->card_type) { + case S3_MIROCRYSTAL8S_805: + case S3_MIROCRYSTAL10SD_805: + svga->crtc[0x5a] = 0x0a; + svga->getclock = sdac_getclock; + break; + + case S3_SPEA_MIRAGE_86C801: + case S3_SPEA_MIRAGE_86C805: + svga->crtc[0x5a] = 0x0a; + break; + + case S3_PHOENIX_86C801: + case S3_PHOENIX_86C805: + svga->crtc[0x5a] = 0x0a; + break; + + case S3_METHEUS_86C928: + svga->crtc[0x5a] = 0x0a; + break; + + case S3_PARADISE_BAHAMAS64: + case S3_PHOENIX_VISION864: + case S3_MIROCRYSTAL20SD_864: + svga->crtc[0x5a] = 0x0a; + break; + + case S3_DIAMOND_STEALTH64_964: + case S3_ELSAWIN2KPROX_964: + case S3_MIROCRYSTAL20SV_964: + svga->crtc[0x5a] = 0x0a; + break; + + case S3_ELSAWIN2KPROX: + case S3_SPEA_MERCURY_P64V: + case S3_MIROVIDEO40SV_ERGO_968: + case S3_PHOENIX_VISION968: + if (s3->pci) { + svga->crtc[0x53] = 0x18; + svga->crtc[0x58] = 0x10; + svga->crtc[0x59] = 0x70; + svga->crtc[0x5a] = 0x00; + svga->crtc[0x6c] = 1; + } else { + svga->crtc[0x53] = 0x00; + svga->crtc[0x59] = 0x00; + svga->crtc[0x5a] = 0x0a; + } + break; + + case S3_PHOENIX_VISION868: + if (s3->pci) { + svga->crtc[0x53] = 0x18; + svga->crtc[0x58] = 0x10; + svga->crtc[0x59] = 0x70; + svga->crtc[0x5a] = 0x00; + svga->crtc[0x6c] = 1; + } else { + svga->crtc[0x53] = 0x00; + svga->crtc[0x59] = 0x00; + svga->crtc[0x5a] = 0x0a; + } + break; + + case S3_PHOENIX_TRIO64: + case S3_PHOENIX_TRIO64_ONBOARD: + case S3_PHOENIX_TRIO64VPLUS: + case S3_PHOENIX_TRIO64VPLUS_ONBOARD: + case S3_DIAMOND_STEALTH64_764: + case S3_SPEA_MIRAGE_P64: + case S3_NUMBER9_9FX: + if (s3->card_type == S3_PHOENIX_TRIO64VPLUS || s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD) + svga->crtc[0x53] = 0x08; + break; + + case S3_TRIO64V2_DX: + svga->crtc[0x53] = 0x08; + svga->crtc[0x59] = 0x70; + svga->crtc[0x5a] = 0x00; + svga->crtc[0x6c] = 1; + s3->pci_regs[0x05] = 0; + s3->pci_regs[0x06] = 0; + s3->pci_regs[0x07] = 2; + s3->pci_regs[0x3d] = 1; + s3->pci_regs[0x3e] = 4; + s3->pci_regs[0x3f] = 0xff; + break; + } + + if (s3->has_bios) { + if (s3->pci) + mem_mapping_disable(&s3->bios_rom.mapping); + } + + s3_updatemapping(s3); + + mem_mapping_disable(&s3->mmio_mapping); + mem_mapping_disable(&s3->new_mmio_mapping); +} + + static void *s3_init(const device_t *info) { const char *bios_fn; @@ -6621,6 +6820,7 @@ static void *s3_init(const device_t *info) else vram_size = 512 << 10; s3->vram_mask = vram_size - 1; + s3->vram = vram; s3->has_bios = (bios_fn != NULL); if (s3->has_bios) { @@ -6726,8 +6926,10 @@ static void *s3_init(const device_t *info) if (chip >= S3_86C928) svga->crtc[0x36] |= (vram_sizes[vram] << 5); - else - svga->crtc[0x36] |= ((vram == 1) ? 0x00 : 0x20) | 0x80; + else { + svga->crtc[0x36] |= ((vram == 1) ? 0x00 : 0x20) | 0x98; + svga->crtc[0x41] = (vram == 1) ? 0x10 : 0x00; + } svga->crtc[0x37] = 1 | (7 << 5); @@ -6833,7 +7035,6 @@ static void *s3_init(const device_t *info) s3->id_ext_pci = 0; s3->packed_mmio = 0; svga->crtc[0x5a] = 0x0a; - svga->ramdac = device_add(&bt485_ramdac_device); svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; @@ -6843,14 +7044,14 @@ static void *s3_init(const device_t *info) case S3_PHOENIX_VISION864: case S3_MIROCRYSTAL20SD_864: svga->decode_mask = (8 << 20) - 1; - if (info->local == S3_PARADISE_BAHAMAS64) + if (info->local == S3_PARADISE_BAHAMAS64 || info->local == S3_MIROCRYSTAL20SD_864) stepping = 0xc0; /*Vision864*/ else stepping = 0xc1; /*Vision864P*/ s3->id = stepping; s3->id_ext = s3->id_ext_pci = stepping; s3->packed_mmio = 0; - + svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&sdac_ramdac_device); svga->clock_gen = svga->ramdac; svga->getclock = sdac_getclock; @@ -6965,7 +7166,7 @@ static void *s3_init(const device_t *info) case S3_TRIO64V2_DX: svga->decode_mask = (4 << 20) - 1; - s3->id = 0xe1; /*Trio64V2/DX*/ + s3->id = 0xe1; /*Trio64V2*/ s3->id_ext = s3->id_ext_pci = 0x01; s3->packed_mmio = 1; svga->crtc[0x53] = 0x08; @@ -6986,9 +7187,8 @@ static void *s3_init(const device_t *info) default: return NULL; } - - if (s3->chip >= S3_TRIO64V || s3->chip == S3_VISION868 || s3->chip == S3_VISION968) - svga->packed_chain4 = 1; + + svga->packed_chain4 = 1; if (s3->pci) s3->card = pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3); @@ -7296,7 +7496,7 @@ const device_t s3_orchid_86c911_isa_device = S3_ORCHID_86C911, s3_init, s3_close, - NULL, + s3_reset, { s3_orchid_86c911_available }, s3_speed_changed, s3_force_redraw, @@ -7310,7 +7510,7 @@ const device_t s3_diamond_stealth_vram_isa_device = S3_DIAMOND_STEALTH_VRAM, s3_init, s3_close, - NULL, + s3_reset, { s3_diamond_stealth_vram_available }, s3_speed_changed, s3_force_redraw, @@ -7324,7 +7524,7 @@ const device_t s3_ami_86c924_isa_device = S3_AMI_86C924, s3_init, s3_close, - NULL, + s3_reset, { s3_ami_86c924_available }, s3_speed_changed, s3_force_redraw, @@ -7338,7 +7538,7 @@ const device_t s3_spea_mirage_86c801_isa_device = S3_SPEA_MIRAGE_86C801, s3_init, s3_close, - NULL, + s3_reset, { s3_spea_mirage_86c801_available }, s3_speed_changed, s3_force_redraw, @@ -7352,7 +7552,7 @@ const device_t s3_spea_mirage_86c805_vlb_device = S3_SPEA_MIRAGE_86C805, s3_init, s3_close, - NULL, + s3_reset, { s3_spea_mirage_86c805_available }, s3_speed_changed, s3_force_redraw, @@ -7366,7 +7566,7 @@ const device_t s3_mirocrystal_8s_805_vlb_device = S3_MIROCRYSTAL8S_805, s3_init, s3_close, - NULL, + s3_reset, { s3_mirocrystal_8s_805_available }, s3_speed_changed, s3_force_redraw, @@ -7381,7 +7581,7 @@ const device_t s3_mirocrystal_10sd_805_vlb_device = S3_MIROCRYSTAL10SD_805, s3_init, s3_close, - NULL, + s3_reset, { s3_mirocrystal_10sd_805_available }, s3_speed_changed, s3_force_redraw, @@ -7395,7 +7595,7 @@ const device_t s3_phoenix_86c801_isa_device = S3_PHOENIX_86C801, s3_init, s3_close, - NULL, + s3_reset, { s3_phoenix_86c80x_available }, s3_speed_changed, s3_force_redraw, @@ -7409,7 +7609,7 @@ const device_t s3_phoenix_86c805_vlb_device = S3_PHOENIX_86C805, s3_init, s3_close, - NULL, + s3_reset, { s3_phoenix_86c80x_available }, s3_speed_changed, s3_force_redraw, @@ -7423,7 +7623,7 @@ const device_t s3_metheus_86c928_isa_device = S3_METHEUS_86C928, s3_init, s3_close, - NULL, + s3_reset, { s3_metheus_86c928_available }, s3_speed_changed, s3_force_redraw, @@ -7437,7 +7637,7 @@ const device_t s3_metheus_86c928_vlb_device = S3_METHEUS_86C928, s3_init, s3_close, - NULL, + s3_reset, { s3_metheus_86c928_available }, s3_speed_changed, s3_force_redraw, @@ -7451,7 +7651,7 @@ const device_t s3_mirocrystal_20sd_864_vlb_device = S3_MIROCRYSTAL20SD_864, s3_init, s3_close, - NULL, + s3_reset, { s3_mirocrystal_20sd_864_vlb_available }, s3_speed_changed, s3_force_redraw, @@ -7465,7 +7665,7 @@ const device_t s3_bahamas64_vlb_device = S3_PARADISE_BAHAMAS64, s3_init, s3_close, - NULL, + s3_reset, { s3_bahamas64_available }, s3_speed_changed, s3_force_redraw, @@ -7479,7 +7679,7 @@ const device_t s3_bahamas64_pci_device = S3_PARADISE_BAHAMAS64, s3_init, s3_close, - NULL, + s3_reset, { s3_bahamas64_available }, s3_speed_changed, s3_force_redraw, @@ -7493,7 +7693,7 @@ const device_t s3_mirocrystal_20sv_964_vlb_device = S3_MIROCRYSTAL20SV_964, s3_init, s3_close, - NULL, + s3_reset, { s3_mirocrystal_20sv_964_vlb_available }, s3_speed_changed, s3_force_redraw, @@ -7507,7 +7707,7 @@ const device_t s3_mirocrystal_20sv_964_pci_device = S3_MIROCRYSTAL20SV_964, s3_init, s3_close, - NULL, + s3_reset, { s3_mirocrystal_20sv_964_pci_available }, s3_speed_changed, s3_force_redraw, @@ -7522,7 +7722,7 @@ const device_t s3_diamond_stealth64_964_vlb_device = S3_DIAMOND_STEALTH64_964, s3_init, s3_close, - NULL, + s3_reset, { s3_diamond_stealth64_964_available }, s3_speed_changed, s3_force_redraw, @@ -7536,7 +7736,7 @@ const device_t s3_diamond_stealth64_964_pci_device = S3_DIAMOND_STEALTH64_964, s3_init, s3_close, - NULL, + s3_reset, { s3_diamond_stealth64_964_available }, s3_speed_changed, s3_force_redraw, @@ -7550,7 +7750,7 @@ const device_t s3_phoenix_vision968_pci_device = S3_PHOENIX_VISION968, s3_init, s3_close, - NULL, + s3_reset, { s3_phoenix_vision968_available }, s3_speed_changed, s3_force_redraw, @@ -7564,7 +7764,7 @@ const device_t s3_phoenix_vision968_vlb_device = S3_PHOENIX_VISION968, s3_init, s3_close, - NULL, + s3_reset, { s3_phoenix_vision968_available }, s3_speed_changed, s3_force_redraw, @@ -7578,7 +7778,7 @@ const device_t s3_mirovideo_40sv_ergo_968_pci_device = S3_MIROVIDEO40SV_ERGO_968, s3_init, s3_close, - NULL, + s3_reset, { s3_mirovideo_40sv_ergo_968_pci_available }, s3_speed_changed, s3_force_redraw, @@ -7592,7 +7792,7 @@ const device_t s3_spea_mercury_p64v_pci_device = S3_SPEA_MERCURY_P64V, s3_init, s3_close, - NULL, + s3_reset, { s3_spea_mercury_p64v_pci_available }, s3_speed_changed, s3_force_redraw, @@ -7606,7 +7806,7 @@ const device_t s3_9fx_vlb_device = S3_NUMBER9_9FX, s3_init, s3_close, - NULL, + s3_reset, { s3_9fx_available }, s3_speed_changed, s3_force_redraw, @@ -7620,7 +7820,7 @@ const device_t s3_9fx_pci_device = S3_NUMBER9_9FX, s3_init, s3_close, - NULL, + s3_reset, { s3_9fx_available }, s3_speed_changed, s3_force_redraw, @@ -7634,7 +7834,7 @@ const device_t s3_phoenix_trio32_vlb_device = S3_PHOENIX_TRIO32, s3_init, s3_close, - NULL, + s3_reset, { s3_phoenix_trio32_available }, s3_speed_changed, s3_force_redraw, @@ -7648,7 +7848,7 @@ const device_t s3_phoenix_trio32_pci_device = S3_PHOENIX_TRIO32, s3_init, s3_close, - NULL, + s3_reset, { s3_phoenix_trio32_available }, s3_speed_changed, s3_force_redraw, @@ -7662,7 +7862,7 @@ const device_t s3_diamond_stealth_se_vlb_device = S3_DIAMOND_STEALTH_SE, s3_init, s3_close, - NULL, + s3_reset, { s3_diamond_stealth_se_available }, s3_speed_changed, s3_force_redraw, @@ -7676,7 +7876,7 @@ const device_t s3_diamond_stealth_se_pci_device = S3_DIAMOND_STEALTH_SE, s3_init, s3_close, - NULL, + s3_reset, { s3_diamond_stealth_se_available }, s3_speed_changed, s3_force_redraw, @@ -7691,7 +7891,7 @@ const device_t s3_phoenix_trio64_vlb_device = S3_PHOENIX_TRIO64, s3_init, s3_close, - NULL, + s3_reset, { s3_phoenix_trio64_available }, s3_speed_changed, s3_force_redraw, @@ -7705,7 +7905,7 @@ const device_t s3_phoenix_trio64_onboard_pci_device = S3_PHOENIX_TRIO64_ONBOARD, s3_init, s3_close, - NULL, + s3_reset, { NULL }, s3_speed_changed, s3_force_redraw, @@ -7719,7 +7919,7 @@ const device_t s3_phoenix_trio64_pci_device = S3_PHOENIX_TRIO64, s3_init, s3_close, - NULL, + s3_reset, { s3_phoenix_trio64_available }, s3_speed_changed, s3_force_redraw, @@ -7733,7 +7933,7 @@ const device_t s3_phoenix_trio64vplus_onboard_pci_device = S3_PHOENIX_TRIO64VPLUS_ONBOARD, s3_init, s3_close, - NULL, + s3_reset, { NULL }, s3_speed_changed, s3_force_redraw, @@ -7747,7 +7947,7 @@ const device_t s3_phoenix_trio64vplus_pci_device = S3_PHOENIX_TRIO64VPLUS, s3_init, s3_close, - NULL, + s3_reset, { s3_phoenix_trio64vplus_available }, s3_speed_changed, s3_force_redraw, @@ -7761,7 +7961,7 @@ const device_t s3_phoenix_vision864_vlb_device = S3_PHOENIX_VISION864, s3_init, s3_close, - NULL, + s3_reset, { s3_phoenix_vision864_available }, s3_speed_changed, s3_force_redraw, @@ -7775,7 +7975,7 @@ const device_t s3_phoenix_vision864_pci_device = S3_PHOENIX_VISION864, s3_init, s3_close, - NULL, + s3_reset, { s3_phoenix_vision864_available }, s3_speed_changed, s3_force_redraw, @@ -7789,7 +7989,7 @@ const device_t s3_phoenix_vision868_vlb_device = S3_PHOENIX_VISION868, s3_init, s3_close, - NULL, + s3_reset, { s3_phoenix_vision868_available }, s3_speed_changed, s3_force_redraw, @@ -7803,7 +8003,7 @@ const device_t s3_phoenix_vision868_pci_device = S3_PHOENIX_VISION868, s3_init, s3_close, - NULL, + s3_reset, { s3_phoenix_vision868_available }, s3_speed_changed, s3_force_redraw, @@ -7817,7 +8017,7 @@ const device_t s3_diamond_stealth64_vlb_device = S3_DIAMOND_STEALTH64_764, s3_init, s3_close, - NULL, + s3_reset, { s3_diamond_stealth64_764_available }, s3_speed_changed, s3_force_redraw, @@ -7831,7 +8031,7 @@ const device_t s3_diamond_stealth64_pci_device = S3_DIAMOND_STEALTH64_764, s3_init, s3_close, - NULL, + s3_reset, { s3_diamond_stealth64_764_available }, s3_speed_changed, s3_force_redraw, @@ -7845,7 +8045,7 @@ const device_t s3_spea_mirage_p64_vlb_device = S3_SPEA_MIRAGE_P64, s3_init, s3_close, - NULL, + s3_reset, { s3_spea_mirage_p64_vlb_available }, s3_speed_changed, s3_force_redraw, @@ -7859,7 +8059,7 @@ const device_t s3_elsa_winner2000_pro_x_964_pci_device = S3_ELSAWIN2KPROX_964, s3_init, s3_close, - NULL, + s3_reset, { s3_elsa_winner2000_pro_x_964_available }, s3_speed_changed, s3_force_redraw, @@ -7873,7 +8073,7 @@ const device_t s3_elsa_winner2000_pro_x_pci_device = S3_ELSAWIN2KPROX, s3_init, s3_close, - NULL, + s3_reset, { s3_elsa_winner2000_pro_x_available }, s3_speed_changed, s3_force_redraw, @@ -7887,7 +8087,7 @@ const device_t s3_trio64v2_dx_pci_device = S3_TRIO64V2_DX, s3_init, s3_close, - NULL, + s3_reset, { s3_trio64v2_dx_available }, s3_speed_changed, s3_force_redraw, diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index e729f16d3..c43a1c55a 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -301,7 +301,7 @@ typedef struct virge_t fifo_entry_t fifo[FIFO_SIZE]; volatile int fifo_read_idx, fifo_write_idx; - int virge_busy; + int virge_busy, local; uint8_t subsys_stat, subsys_cntl, advfunc_cntl; @@ -3785,6 +3785,86 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) } } +static void s3_virge_reset(void *priv) +{ + virge_t *virge = (virge_t *) priv; + svga_t *svga = &virge->svga; + + memset(svga->crtc, 0x00, sizeof(svga->crtc)); + svga->crtc[0] = 63; + svga->crtc[6] = 255; + svga->dispontime = 1000ull << 32; + svga->dispofftime = 1000ull << 32; + svga->bpp = 8; + + io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); + io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); + + memset(virge->pci_regs, 0x00, 256); + + virge->pci_regs[PCI_REG_COMMAND] = 3; + virge->pci_regs[0x05] = 0; + virge->pci_regs[0x06] = 0; + virge->pci_regs[0x07] = 2; + virge->pci_regs[0x32] = 0x0c; + virge->pci_regs[0x3d] = 1; + virge->pci_regs[0x3e] = 4; + virge->pci_regs[0x3f] = 0xff; + + switch(virge->local) { + case S3_VIRGE_325: + case S3_DIAMOND_STEALTH3D_2000: + virge->svga.crtc[0x59] = 0x70; + break; + case S3_DIAMOND_STEALTH3D_3000: + virge->svga.crtc[0x59] = 0x70; + break; + case S3_VIRGE_GX2: + case S3_DIAMOND_STEALTH3D_4000: + virge->svga.crtc[0x6c] = 1; + virge->svga.crtc[0x59] = 0x70; + break; + + case S3_TRIO_3D2X: + virge->svga.crtc[0x6c] = 1; + virge->svga.crtc[0x59] = 0x70; + break; + + default: + virge->svga.crtc[0x6c] = 1; + virge->svga.crtc[0x59] = 0x70; + break; + } + + if (virge->chip >= S3_VIRGEGX2) + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); + else { + switch (virge->memory_size) { + case 2: + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5); + break; + case 8: + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (3 << 5); + break; + case 4: + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); + break; + } + } + + virge->svga.crtc[0x37] = 1 | (7 << 5); + virge->svga.crtc[0x53] = 8; + + mem_mapping_disable(&virge->bios_rom.mapping); + + memset(virge->dmabuffer, 0, 65536); + + s3_virge_updatemapping(virge); + + mem_mapping_disable(&virge->mmio_mapping); + mem_mapping_disable(&virge->new_mmio_mapping); +} + static void *s3_virge_init(const device_t *info) { const char *bios_fn; @@ -3976,7 +4056,7 @@ static void *s3_virge_init(const device_t *info) memset(virge->dmabuffer, 0, 65536); - virge->card = pci_add_card(PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge); + virge->card = pci_add_card((info->flags & DEVICE_AGP) ? PCI_ADD_AGP : PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge); virge->i2c = i2c_gpio_init("ddc_s3_virge"); virge->ddc = ddc_init(i2c_gpio_get_bus(virge->i2c)); @@ -3990,6 +4070,8 @@ static void *s3_virge_init(const device_t *info) virge->render_thread = thread_create(render_thread, virge); timer_add(&virge->tri_timer, s3_virge_tri_timer, virge, 0); + + virge->local = info->local; return virge; } @@ -4119,7 +4201,7 @@ const device_t s3_virge_325_pci_device = S3_VIRGE_325, s3_virge_init, s3_virge_close, - NULL, + s3_virge_reset, { s3_virge_325_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4133,7 +4215,7 @@ const device_t s3_diamond_stealth_2000_pci_device = S3_DIAMOND_STEALTH3D_2000, s3_virge_init, s3_virge_close, - NULL, + s3_virge_reset, { s3_virge_325_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4147,7 +4229,7 @@ const device_t s3_diamond_stealth_3000_pci_device = S3_DIAMOND_STEALTH3D_3000, s3_virge_init, s3_virge_close, - NULL, + s3_virge_reset, { s3_virge_988_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4161,7 +4243,7 @@ const device_t s3_virge_375_pci_device = S3_VIRGE_DX, s3_virge_init, s3_virge_close, - NULL, + s3_virge_reset, { s3_virge_375_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4175,7 +4257,7 @@ const device_t s3_diamond_stealth_2000pro_pci_device = S3_DIAMOND_STEALTH3D_2000PRO, s3_virge_init, s3_virge_close, - NULL, + s3_virge_reset, { s3_virge_375_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4189,7 +4271,7 @@ const device_t s3_virge_385_pci_device = S3_VIRGE_GX, s3_virge_init, s3_virge_close, - NULL, + s3_virge_reset, { s3_virge_385_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4203,7 +4285,7 @@ const device_t s3_virge_357_pci_device = S3_VIRGE_GX2, s3_virge_init, s3_virge_close, - NULL, + s3_virge_reset, { s3_virge_357_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4217,7 +4299,7 @@ const device_t s3_virge_357_agp_device = S3_VIRGE_GX2, s3_virge_init, s3_virge_close, - NULL, + s3_virge_reset, { s3_virge_357_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4231,7 +4313,7 @@ const device_t s3_diamond_stealth_4000_pci_device = S3_DIAMOND_STEALTH3D_4000, s3_virge_init, s3_virge_close, - NULL, + s3_virge_reset, { s3_virge_357_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4245,7 +4327,7 @@ const device_t s3_diamond_stealth_4000_agp_device = S3_DIAMOND_STEALTH3D_4000, s3_virge_init, s3_virge_close, - NULL, + s3_virge_reset, { s3_virge_357_diamond_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4259,7 +4341,7 @@ const device_t s3_trio3d2x_pci_device = S3_TRIO_3D2X, s3_virge_init, s3_virge_close, - NULL, + s3_virge_reset, { s3_trio3d2x_available }, s3_virge_speed_changed, s3_virge_force_redraw, @@ -4273,7 +4355,7 @@ const device_t s3_trio3d2x_agp_device = S3_TRIO_3D2X, s3_virge_init, s3_virge_close, - NULL, + s3_virge_reset, { s3_trio3d2x_available }, s3_virge_speed_changed, s3_virge_force_redraw, diff --git a/src/video/vid_sc1148x_ramdac.c b/src/video/vid_sc1148x_ramdac.c index 88f81d77c..d23d00efa 100644 --- a/src/video/vid_sc1148x_ramdac.c +++ b/src/video/vid_sc1148x_ramdac.c @@ -6,7 +6,7 @@ * * This file is part of the 86Box distribution. * - * Emulation of Sierra SC11483 and SC11487 RAMDACs. + * Emulation of Sierra SC1148x RAMDACs and clones (e.g.: Winbond). * * Used by the S3 911 and 924 chips. * @@ -33,6 +33,7 @@ typedef struct { int type; int state; + int rs2; uint8_t ctrl; } sc1148x_ramdac_t; @@ -42,63 +43,53 @@ sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) { sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) p; uint8_t rs = (addr & 0x03); - rs |= ((!!rs2) << 2); - - if (ramdac->type == 0 || ramdac->type == 3) { - switch (addr) { - case 0x3c6: - if (ramdac->state == 4) { + rs |= ((!!rs2) << 2); + int oldbpp = 0; + + switch (addr) { + case 0x3c6: + switch (ramdac->state) { + case 4: ramdac->state = 0; + if (val == 0xff) + break; ramdac->ctrl = val; - if (ramdac->ctrl & 0x80) { - svga->bpp = 15; - } else { - svga->bpp = 8; + ramdac->ctrl = (ramdac->ctrl & ~1) | ((((val >> 2) ^ val) & (val & 0x20)) >> 5); + oldbpp = svga->bpp; + switch (ramdac->type) { + case 0: /* Sierra Mark 2 (11483)*/ + case 2: /* Sierra Mark 2 (11484)*/ + case 3: /* Sierra Mark 1 (11486)*/ + if (val & 0xa0) { + svga->bpp = 15; + } else if (val == 0x00) + svga->bpp = 8; + break; + case 1: /* Sierra Mark 3 (11487)*/ + if (val & 0xa0) { + if (val & 0x40) + svga->bpp = 16; + else + svga->bpp = 15; + } else if (val == 0x00) + svga->bpp = 8; + break; } - svga_recalctimings(svga); + if (oldbpp != svga->bpp) + svga_recalctimings(svga); return; - } - ramdac->state = 0; - break; - - case 0x3c7: - case 0x3c8: - case 0x3c9: - ramdac->state = 0; - svga_out(addr, val, svga); - break; + default: + svga_out(addr, val, svga); + break; } - } else { - switch (rs) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x07: - svga_out(addr, val, svga); - ramdac->state = 0; - break; - case 0x06: - if (ramdac->state == 4) { - ramdac->state = 0; - ramdac->ctrl = val; - if (ramdac->ctrl & 0x80) { - if ((ramdac->ctrl & 0x40) && (ramdac->type == 1)) - svga->bpp = 16; - else - svga->bpp = 15; - } else { - svga->bpp = 8; - } - svga_recalctimings(svga); - return; - } - ramdac->state = 0; - break; - } - } + break; + + case 0x3c7: case 0x3c8: + case 0x3c9: + ramdac->state = 0; + svga_out(addr, val, svga); + break; + } } @@ -106,58 +97,37 @@ uint8_t sc1148x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) { sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) p; - uint8_t temp = 0xff; + uint8_t ret = 0xff; uint8_t rs = (addr & 0x03); - rs |= ((!!rs2) << 2); - - if (ramdac->type == 0 || ramdac->type == 3) { - switch (addr) { - case 0x3c6: - if (ramdac->state == 4) { - ramdac->state = 0; - temp = ramdac->ctrl; - return temp; - } - ramdac->state++; - break; - - case 0x3c7: - case 0x3c8: - case 0x3c9: - ramdac->state = 0; - temp = svga_in(addr, svga); - break; - } - } else { - switch (rs) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x07: - temp = svga_in(addr, svga); - ramdac->state = 0; - break; - case 0x06: - if (ramdac->state == 4) { - ramdac->state = 0; - temp = ramdac->ctrl; - if (ramdac->type == 1) { - if (((ramdac->ctrl >> 4) == 1) || ((ramdac->ctrl >> 4) == 3)) - temp |= 1; - else - temp &= ~1; - } - return temp; - } - ramdac->state++; - break; - } - } + rs |= ((!!rs2) << 2); - return temp; + switch (addr) { + case 0x3c6: + switch (ramdac->state) { + case 1: + case 2: case 3: + ret = 0x00; + ramdac->state++; + break; + case 4: + ret = ramdac->ctrl; + ret = (ret & ~0x18) | (svga->dac_mask & 0x18); + break; + default: + ret = svga_in(addr, svga); + ramdac->state++; + break; + } + break; + + case 0x3c7: case 0x3c8: + case 0x3c9: + ret = svga_in(addr, svga); + ramdac->state = 0; + break; + } + + return ret; } @@ -198,17 +168,17 @@ const device_t sc11487_ramdac_device = NULL, { NULL }, NULL, NULL }; -const device_t sc11484_ramdac_device = +const device_t sc11484_nors2_ramdac_device = { - "Sierra SC11484 RAMDAC", + "Sierra SC11484 RAMDAC (no RS2 signal)", 0, 2, sc1148x_ramdac_init, sc1148x_ramdac_close, NULL, { NULL }, NULL, NULL }; -const device_t sc11484_nors2_ramdac_device = +const device_t sc11486_ramdac_device = { - "Sierra SC11484 RAMDAC (no RS2 signal)", + "Sierra SC11486 RAMDAC", 0, 3, sc1148x_ramdac_init, sc1148x_ramdac_close, NULL, { NULL }, NULL, NULL diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index b38353701..b1d446829 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -192,6 +192,8 @@ svga_out(uint16_t addr, uint8_t val, void *p) svga->dac_addr = (val + (addr & 0x01)) & 255; break; case 0x3c9: + if (svga->adv_flags & FLAG_RAMDAC_SHIFT) + val <<= 2; svga->fullchange = changeframecount; switch (svga->dac_pos) { case 0: @@ -330,6 +332,8 @@ svga_in(uint16_t addr, void *p) ret = svga->vgapal[index].b & 0x3f; break; } + if (svga->adv_flags & FLAG_RAMDAC_SHIFT) + ret >>= 2; break; case 0x3cc: ret = svga->miscout; @@ -949,7 +953,7 @@ svga_init(const device_t *info, svga_t *svga, void *p, int memsize, svga->translate_address = NULL; svga->ksc5601_english_font_type = 0; - if ((info->flags & DEVICE_PCI) || (info->flags & DEVICE_VLB)) { + if ((info->flags & DEVICE_PCI) || (info->flags & DEVICE_VLB) || (info->flags & DEVICE_MCA)) { mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 72ca625d4..9b457326e 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -58,12 +58,13 @@ video_cards[] = { { "ati28800k", &ati28800k_device }, { "ati18800v", &ati18800_vga88_device }, { "ati28800", &ati28800_device }, + { "compaq_ati28800", &compaq_ati28800_device }, +#if defined(DEV_BRANCH) && defined(USE_XL24) + { "ati28800w", &ati28800_wonderxl24_device }, +#endif { "ati18800", &ati18800_device }, #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) { "ati18800w", &ati18800_wonder_device }, -#endif -#if defined(DEV_BRANCH) && defined(USE_XL24) - { "ati28800w", &ati28800_wonderxl24_device }, #endif { "cga", &cga_device }, { "superega", &sega_device }, @@ -74,7 +75,6 @@ video_cards[] = { { "cl_gd5428_isa", &gd5428_isa_device }, { "cl_gd5429_isa", &gd5429_isa_device }, { "cl_gd5434_isa", &gd5434_isa_device }, - { "compaq_ati28800", &compaq_ati28800_device }, { "compaq_cga", &compaq_cga_device }, { "compaq_cga_2", &compaq_cga_2_device }, { "compaq_ega", &cpqega_device }, diff --git a/src/video/video.c b/src/video/video.c index 1258b1824..5118b886f 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -114,6 +114,12 @@ static const video_timings_t *vid_timings; static uint32_t cga_2_table[16]; static uint8_t thread_run = 0; +#ifdef _WIN32 +void * __cdecl (*video_copy)(void *_Dst, const void *_Src, size_t _Size) = memcpy; +#else +void * (*video_copy)(void *__restrict, const void *__restrict, size_t); +#endif + PALETTE cgapal = { {0,0,0}, {0,42,0}, {42,0,0}, {42,21,0}, @@ -317,7 +323,7 @@ static png_infop info_ptr; static void -video_take_screenshot(const char *fn) +video_take_screenshot(const char *fn, uint32_t *buf, int start_x, int start_y, int row_len) { int i, x, y; png_bytep *b_rgb = NULL; @@ -363,10 +369,10 @@ video_take_screenshot(const char *fn) for (y = 0; y < blit_data.h; ++y) { b_rgb[y] = (png_byte *) malloc(png_get_rowbytes(png_ptr, info_ptr)); for (x = 0; x < blit_data.w; ++x) { - if (buffer32 == NULL) + if (buf == NULL) memset(&(b_rgb[y][x * 3]), 0x00, 3); else { - temp = buffer32->line[blit_data.y + y][blit_data.x + x]; + temp = buf[((start_y + y) * row_len) + start_x + x]; b_rgb[y][x * 3] = (temp >> 16) & 0xff; b_rgb[y][(x * 3) + 1] = (temp >> 8) & 0xff; b_rgb[y][(x * 3) + 2] = temp & 0xff; @@ -390,8 +396,8 @@ video_take_screenshot(const char *fn) } -static void -video_screenshot(void) +void +video_screenshot(uint32_t *buf, int start_x, int start_y, int row_len) { char path[1024], fn[128]; @@ -410,50 +416,47 @@ video_screenshot(void) video_log("taking screenshot to: %s\n", path); - video_take_screenshot((const char *) path); + video_take_screenshot((const char *) path, buf, start_x, start_y, row_len); png_destroy_write_struct(&png_ptr, &info_ptr); + + screenshots--; } -static void -video_transform_copy(uint32_t *dst, uint32_t *src, int len) +#ifdef _WIN32 +void * __cdecl +video_transform_copy(void *_Dst, const void *_Src, size_t _Size) +#else +void * +video_transform_copy(void *__restrict _Dst, const void *__restrict _Src, size_t _Size) +#endif { int i; + uint32_t *dest_ex = (uint32_t *) _Dst; + uint32_t *src_ex = (uint32_t *) _Src; - if ((dst != NULL) && (src != NULL)) { - for (i = 0; i < len; i++) { - *dst = video_color_transform(*src); - dst++; - src++; + _Size /= sizeof(uint32_t); + + if ((dest_ex != NULL) && (src_ex != NULL)) { + for (i = 0; i < _Size; i++) { + *dest_ex = video_color_transform(*src_ex); + dest_ex++; + src_ex++; } } + + return _Dst; } static void blit_thread(void *param) { - int yy; - while (thread_run) { thread_wait_event(blit_data.wake_blit_thread, -1); thread_reset_event(blit_data.wake_blit_thread); MTR_BEGIN("video", "blit_thread"); - if ((video_grayscale || invert_display) && (blit_data.h > 0)) { - for (yy = 0; yy < blit_data.h; yy++) { - if (((blit_data.y + yy) >= 0) && ((blit_data.y + yy) < buffer32->h)) { - video_transform_copy(&(buffer32->line[blit_data.y + yy][blit_data.x]), &(buffer32->line[blit_data.y + yy][blit_data.x]), blit_data.w); - } - } - } - - if (screenshots) { - video_screenshot(); - screenshots--; - video_log("screenshot taken, %i left\n", screenshots); - } - if (blit_func) blit_func(blit_data.x, blit_data.y, blit_data.w, blit_data.h); diff --git a/src/vnc.c b/src/vnc.c index 371e03803..440542652 100644 --- a/src/vnc.c +++ b/src/vnc.c @@ -179,8 +179,11 @@ vnc_blit(int x, int y, int w, int h) p = (uint32_t *)&(((uint32_t *)rfb->frameBuffer)[yy*VNC_MAX_X]); if ((y+yy) >= 0 && (y+yy) < VNC_MAX_Y) - memcpy(p, &(buffer32->line[yy]), w*sizeof(uint32_t)); + video_copy(p, &(buffer32->line[yy]), w*sizeof(uint32_t)); } + + if (screenshots) + video_screenshot((uint32_t *) rfb->frameBuffer, 0, 0, VNC_MAX_X); video_blit_complete(); diff --git a/src/win/86Box.rc b/src/win/86Box.rc index 9f98c9350..05990324f 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -825,12 +825,19 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. +// defining the icons depending on the build status #ifdef RELEASE_BUILD -/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png */ - 10 ICON DISCARDABLE ICON_PATH "icons/86Box-RB.ico" +/* Icon by OBattler and laciba96 (green for release builds)*/ + 10 ICON DISCARDABLE ICON_PATH "icons/86Box-green.ico" +#elif BETA_BUILD +/* Icon by OBattler and laciba96 (yellow for beta builds done by Jenkins)*/ + 10 ICON DISCARDABLE ICON_PATH "icons/86Box-yellow.ico" +#elif ALPHA_BUILD +/* Icon by OBattler and laciba96 (red for alpha builds done by Jenkins)*/ + 10 ICON DISCARDABLE ICON_PATH "icons/86Box-red.ico" #else -/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ - 10 ICON DISCARDABLE ICON_PATH "icons/86Box.ico" +/* Icon by OBattler and laciba96 (gray for builds of branches and from the git master)*/ + 10 ICON DISCARDABLE ICON_PATH "icons/86Box-gray.ico" #endif 16 ICON DISCARDABLE ICON_PATH "icons/floppy_525.ico" 17 ICON DISCARDABLE ICON_PATH "icons/floppy_525_active.ico" diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index f40ae87f7..90ef6136a 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -614,7 +614,7 @@ CHIPSETOBJ := 82c100.o acc2168.o cs8230.o ali1217.o ali1429.o ali1489.o et6000.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 sis_5598.o stpc.o opti283.o opti291.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 diff --git a/src/win/icons/86Box-gray.ico b/src/win/icons/86Box-gray.ico new file mode 100644 index 000000000..c9cbad17d Binary files /dev/null and b/src/win/icons/86Box-gray.ico differ diff --git a/src/win/icons/86Box-green.ico b/src/win/icons/86Box-green.ico new file mode 100644 index 000000000..5c783674d Binary files /dev/null and b/src/win/icons/86Box-green.ico differ diff --git a/src/win/icons/86Box-red.ico b/src/win/icons/86Box-red.ico new file mode 100644 index 000000000..6b4666c43 Binary files /dev/null and b/src/win/icons/86Box-red.ico differ diff --git a/src/win/icons/86Box-yellow.ico b/src/win/icons/86Box-yellow.ico new file mode 100644 index 000000000..c3822c89b Binary files /dev/null and b/src/win/icons/86Box-yellow.ico differ diff --git a/src/win/win.c b/src/win/win.c index 45d32bd8e..6e397b98f 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -728,7 +728,7 @@ plat_get_basename(const char *path) while (c > 0) { if (path[c] == '/' || path[c] == '\\') - return((char *)&path[c]); + return((char *)&path[c + 1]); c--; } @@ -858,6 +858,20 @@ plat_dir_create(char *path) } +void * +plat_mmap(size_t size, uint8_t executable) +{ + return VirtualAlloc(NULL, size, MEM_COMMIT, executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE); +} + + +void +plat_munmap(void *ptr, size_t size) +{ + VirtualFree(ptr, 0, MEM_RELEASE); +} + + uint64_t plat_timer_read(void) { diff --git a/src/win/win_opengl.c b/src/win/win_opengl.c index b2c338a31..69190b6b1 100644 --- a/src/win/win_opengl.c +++ b/src/win/win_opengl.c @@ -816,7 +816,10 @@ static void opengl_blit(int x, int y, int w, int h) return; } - memcpy(blit_info[write_pos].buffer, &(buffer32->line[y][x]), h * ROW_LENGTH * sizeof(uint32_t)); + video_copy(blit_info[write_pos].buffer, &(buffer32->line[y][x]), h * ROW_LENGTH * sizeof(uint32_t)); + + if (screenshots) + video_screenshot(blit_info[write_pos].buffer, 0, 0, ROW_LENGTH); video_blit_complete(); diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c index 62a77551b..e8bdd6e0d 100644 --- a/src/win/win_sdl.c +++ b/src/win/win_sdl.c @@ -232,7 +232,8 @@ static void sdl_blit(int x, int y, int w, int h) { SDL_Rect r_src; - int ret; + void *pixeldata; + int pitch, ret; if (!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) { video_blit_complete(); @@ -241,17 +242,21 @@ sdl_blit(int x, int y, int w, int h) SDL_LockMutex(sdl_mutex); - r_src.x = x; - r_src.y = y; - r_src.w = w; - r_src.h = h; - SDL_UpdateTexture(sdl_tex, &r_src, &(buffer32->line[y][x]), (2048 + 64) * sizeof(uint32_t)); + SDL_LockTexture(sdl_tex, 0, &pixeldata, &pitch); + + video_copy(pixeldata, &(buffer32->line[y][x]), h * (2048 + 64) * sizeof(uint32_t)); + + if (screenshots) + video_screenshot((uint32_t *) pixeldata, 0, 0, (2048 + 64)); + + SDL_UnlockTexture(sdl_tex); + video_blit_complete(); SDL_RenderClear(sdl_render); - r_src.x = x; - r_src.y = y; + r_src.x = 0; + r_src.y = 0; r_src.w = w; r_src.h = h; @@ -353,7 +358,7 @@ sdl_init_texture(void) sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE); sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, 2048, 2048); + SDL_TEXTUREACCESS_STREAMING, (2048 + 64), (2048 + 64)); } diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 7e90ef1ba..668487d00 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -807,7 +807,12 @@ win_settings_machine_recalc_machine(HWND hdlg) } else { /* MB granularity */ h = GetDlgItem(hdlg, IDC_MEMSPIN); - SendMessage(h, UDM_SETRANGE, 0, (machines[temp_machine].min_ram << 6) | machines[temp_machine].max_ram >> 10); +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) + i = MIN(machines[temp_machine].max_ram, 2097152); +#else + i = MIN(machines[temp_machine].max_ram, 3145728); +#endif + SendMessage(h, UDM_SETRANGE, 0, (machines[temp_machine].min_ram << 6) | (i >> 10)); accel.nSec = 0; accel.nInc = machines[temp_machine].ram_granularity >> 10; @@ -1375,12 +1380,15 @@ win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401); settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow()); settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401); + settings_enable_window(hdlg, IDC_CHECK_CMS, (machines[temp_machine].flags & MACHINE_BUS_ISA)); settings_set_check(hdlg, IDC_CHECK_CMS, temp_GAMEBLASTER); - settings_enable_window(hdlg, IDC_CONFIGURE_CMS, temp_GAMEBLASTER); + settings_enable_window(hdlg, IDC_CONFIGURE_CMS, (machines[temp_machine].flags & MACHINE_BUS_ISA) && temp_GAMEBLASTER); + settings_enable_window(hdlg, IDC_CHECK_GUS, (machines[temp_machine].flags & MACHINE_BUS_ISA16)); settings_set_check(hdlg, IDC_CHECK_GUS, temp_GUS); - settings_enable_window(hdlg, IDC_CONFIGURE_GUS, temp_GUS); + settings_enable_window(hdlg, IDC_CONFIGURE_GUS, (machines[temp_machine].flags & MACHINE_BUS_ISA16) && temp_GUS); + settings_enable_window(hdlg, IDC_CHECK_SSI, (machines[temp_machine].flags & MACHINE_BUS_ISA)); settings_set_check(hdlg, IDC_CHECK_SSI, temp_SSI2001); - settings_enable_window(hdlg, IDC_CONFIGURE_SSI, temp_SSI2001); + settings_enable_window(hdlg, IDC_CONFIGURE_SSI, (machines[temp_machine].flags & MACHINE_BUS_ISA) && temp_SSI2001); settings_set_check(hdlg, IDC_CHECK_FLOAT, temp_float); free(lptsTemp); diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 6a38045c9..a099489aa 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -822,6 +822,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_VID_INVERT: video_toggle_option(hmenu, &invert_display, IDM_VID_INVERT); + video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; break; case IDM_VID_OVERSCAN: @@ -854,6 +855,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_VID_GRAY_WHITE: CheckMenuItem(hmenu, IDM_VID_GRAY_RGB+video_grayscale, MF_UNCHECKED); video_grayscale = LOWORD(wParam) - IDM_VID_GRAY_RGB; + video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; CheckMenuItem(hmenu, IDM_VID_GRAY_RGB+video_grayscale, MF_CHECKED); device_force_redraw(); config_save(); @@ -1302,13 +1304,19 @@ ui_init(int nCmdShow) wincl.lpfnWndProc = MainWindowProcedure; wincl.style = CS_DBLCLKS; /* Catch double-clicks */ wincl.cbSize = sizeof(WNDCLASSEX); - wincl.hIcon = LoadIcon(hinstance, (LPCTSTR)10); - wincl.hIconSm = LoadIcon(hinstance, (LPCTSTR)10); + wincl.hIcon = NULL; + wincl.hIconSm = NULL; wincl.hCursor = NULL; wincl.lpszMenuName = NULL; wincl.cbClsExtra = 0; wincl.cbWndExtra = 0; wincl.hbrBackground = CreateSolidBrush(RGB(0,0,0)); + + /* Load proper icons */ + wchar_t path[MAX_PATH + 1] = {0}; + GetModuleFileNameW(hinstance, path, MAX_PATH); + ExtractIconExW(path, 0, &wincl.hIcon, &wincl.hIconSm, 1); + if (! RegisterClassEx(&wincl)) return(2); wincl.lpszClassName = SUB_CLASS_NAME;