diff --git a/src/86box.c b/src/86box.c index b51fb4763..3f9517e04 100644 --- a/src/86box.c +++ b/src/86box.c @@ -921,7 +921,8 @@ pc_close(thread_t *ptr) /* Terminate the main thread. */ if (ptr != NULL) { - thread_kill(ptr); + is_quit = 1; + thread_wait(ptr, -1); /* Wait some more. */ plat_delay_ms(200); diff --git a/src/acpi.c b/src/acpi.c index cf81b83b4..0f28bd8af 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -480,7 +480,7 @@ acpi_reg_read_via(int size, uint16_t addr, void *p) case 0x42: /* GPIO port Output Value */ if (size == 1) - ret = dev->regs.gpio_val & 0xff; + ret = dev->regs.gpio_val & 0x13; break; case 0x44: /* GPIO port Input Value */ @@ -529,6 +529,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; + break; case 0x44: case 0x45: /* External SMI Input Value */ ret = (dev->regs.extsmi_val >> shift16) & 0xff; @@ -539,7 +544,7 @@ acpi_reg_read_via_596b(int size, uint16_t addr, void *p) break; case 0x4c: case 0x4d: case 0x4e: case 0x4f: /* GPO Port Output Value */ - ret = (dev->regs.gpi_val >> shift32) & 0xff; + ret = (dev->regs.gpo_val >> shift32) & 0xff; break; default: ret = acpi_reg_read_via_common(size, addr, p); @@ -1032,7 +1037,7 @@ acpi_reg_write_via(int size, uint16_t addr, uint8_t val, void *p) case 0x42: /* GPIO port Output Value */ if (size == 1) { - dev->regs.gpio_val = val & 0x1f; + dev->regs.gpio_val = val & 0x13; acpi_i2c_set(dev); } break; @@ -1058,8 +1063,14 @@ acpi_reg_write_via_596b(int size, uint16_t addr, uint8_t val, void *p) shift32 = (addr & 3) << 3; switch (addr) { + case 0x42: + /* GPIO port Output Value */ + if (size == 1) + dev->regs.gpio_val = val & 0x13; + break; case 0x4c: case 0x4d: case 0x4e: case 0x4f: /* GPO Port Output Value */ + pclog("Write %02X to %02X\n", val, addr); dev->regs.gpo_val = ((dev->regs.gpo_val & ~(0xff << shift32)) | (val << shift32)) & 0x7fffffff; break; default: @@ -1569,6 +1580,10 @@ acpi_reset(void *priv) dev->regs.gpi_val = 0xffff7fc1; if (!strcmp(machines[machine].internal_name, "ficva503a")) 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. */ diff --git a/src/chipset/sis_85c4xx.c b/src/chipset/sis_85c4xx.c index 0ae00f827..0a2bf34af 100644 --- a/src/chipset/sis_85c4xx.c +++ b/src/chipset/sis_85c4xx.c @@ -37,7 +37,7 @@ typedef struct { uint8_t cur_reg, tries, reg_base, reg_last, - is_471, + reg_00, is_471, regs[39], scratch[2]; smram_t *smram; port_92_t *port_92; @@ -78,7 +78,7 @@ sis_85c4xx_recalcmapping(sis_85c4xx_t *dev) mem_set_mem_state(base, 0x8000, readext | writeext); } - flushmmucache(); + flushmmucache_nopc(); } @@ -195,7 +195,8 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv) } break; } - } + } else if ((dev->reg_base == 0x60) && (dev->cur_reg == 0x00)) + dev->reg_00 = val; dev->cur_reg = 0x00; break; @@ -217,9 +218,15 @@ sis_85c4xx_in(uint16_t port, void *priv) case 0x23: if (dev->is_471 && (dev->cur_reg == 0x1c)) ret = inb(0x70); - if ((dev->cur_reg >= dev->reg_base) && (dev->cur_reg <= dev->reg_last)) + /* On the SiS 40x, the shadow RAM read and write enable bits are write-only! */ + if ((dev->reg_base == 0x60) && (dev->cur_reg == 0x62)) + ret = dev->regs[rel_reg] & 0x3f; + else if ((dev->cur_reg >= dev->reg_base) && (dev->cur_reg <= dev->reg_last)) ret = dev->regs[rel_reg]; - dev->cur_reg = 0x00; + else if ((dev->reg_base == 0x60) && (dev->cur_reg == 0x00)) + ret = dev->reg_00; + if (dev->reg_base != 0x60) + dev->cur_reg = 0x00; break; case 0xe1: case 0xe2: @@ -341,6 +348,10 @@ sis_85c4xx_init(const device_t *info) } else { dev->reg_last = dev->reg_base + 0x11; + /* Bits 6 and 7 must be clear on the SiS 40x. */ + if (dev->reg_base == 0x60) + dev->reg_00 = 0x24; + switch (mem_size_mb) { case 1: default: diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index 22de563c8..e2adf3657 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -341,37 +341,36 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) break; case 0x61: /* Shadow RAM Control 1 */ - if ((dev->pci_conf[0x61] ^ val) & 0x03) - apollo_map(0xc0000, 0x04000, val & 0x03); - if ((dev->pci_conf[0x61] ^ val) & 0x0c) - apollo_map(0xc4000, 0x04000, (val & 0x0c) >> 2); - if ((dev->pci_conf[0x61] ^ val) & 0x30) - apollo_map(0xc8000, 0x04000, (val & 0x30) >> 4); - if ((dev->pci_conf[0x61] ^ val) & 0xc0) - apollo_map(0xcc000, 0x04000, (val & 0xc0) >> 6); + apollo_map(0xc0000, 0x04000, val & 0x03); + apollo_map(0xc4000, 0x04000, (val & 0x0c) >> 2); + apollo_map(0xc8000, 0x04000, (val & 0x30) >> 4); + apollo_map(0xcc000, 0x04000, (val & 0xc0) >> 6); + dev->pci_conf[0x61] = val; break; case 0x62: /* Shadow RAM Control 2 */ - if ((dev->pci_conf[0x62] ^ val) & 0x03) - apollo_map(0xd0000, 0x04000, val & 0x03); - if ((dev->pci_conf[0x62] ^ val) & 0x0c) - apollo_map(0xd4000, 0x04000, (val & 0x0c) >> 2); - if ((dev->pci_conf[0x62] ^ val) & 0x30) - apollo_map(0xd8000, 0x04000, (val & 0x30) >> 4); - if ((dev->pci_conf[0x62] ^ val) & 0xc0) - apollo_map(0xdc000, 0x04000, (val & 0xc0) >> 6); + apollo_map(0xd0000, 0x04000, val & 0x03); + apollo_map(0xd4000, 0x04000, (val & 0x0c) >> 2); + apollo_map(0xd8000, 0x04000, (val & 0x30) >> 4); + apollo_map(0xdc000, 0x04000, (val & 0xc0) >> 6); + dev->pci_conf[0x62] = val; break; case 0x63: /* Shadow RAM Control 3 */ - if ((dev->pci_conf[0x63] ^ val) & 0x30) { - apollo_map(0xf0000, 0x10000, (val & 0x30) >> 4); - shadowbios = (((val & 0x30) >> 4) & 0x02); - } - if ((dev->pci_conf[0x63] ^ val) & 0xc0) - apollo_map(0xe0000, 0x10000, (val & 0xc0) >> 6); + shadowbios = 0; + shadowbios_write = 0; + + apollo_map(0xf0000, 0x10000, (val & 0x30) >> 4); + shadowbios = (((val & 0x30) >> 4) & 0x02); + shadowbios_write = (((val & 0x30) >> 4) & 0x01); + + apollo_map(0xe0000, 0x10000, (val & 0xc0) >> 6); + shadowbios |= (((val & 0xc0) >> 6) & 0x02); + shadowbios_write |= (((val & 0xc0) >> 6) & 0x01); + dev->pci_conf[0x63] = val; smram_disable_all(); - if (dev->id >= VIA_691) switch (val & 0x03) { + if (dev->id >= VIA_691) switch (val & 0x03) { case 0x00: default: apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */ @@ -680,7 +679,8 @@ via_apollo_init(const device_t *info) memset(dev, 0, sizeof(via_apollo_t)); dev->smram = smram_add(); - apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */ + if (dev->id != VIA_8601) + apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */ pci_add_card(PCI_ADD_NORTHBRIDGE, via_apollo_read, via_apollo_write, dev); diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index 95e900b5e..d0fbdfa63 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -296,7 +296,7 @@ pipc_reset_hard(void *priv) dev->power_regs[0x34] = 0x68; dev->power_regs[0x40] = 0x20; - dev->power_regs[0x42] = 0xd0; + dev->power_regs[0x42] = 0x50; dev->power_regs[0x48] = 0x01; if (dev->local == VIA_PIPC_686B) { @@ -380,6 +380,9 @@ pipc_reset_hard(void *priv) ide_pri_disable(); ide_sec_disable(); + + nvr_via_wp_set(0x00, 0x32, dev->nvr); + nvr_via_wp_set(0x00, 0x0d, dev->nvr); } @@ -600,7 +603,7 @@ nvr_update_io_mapping(pipc_t *dev) if (dev->nvr_enabled) nvr_at_handler(0, 0x0074, dev->nvr); - if ((dev->pci_isa_regs[0x5b] & 0x02) && (dev->pci_isa_regs[0x48] & 0x08)) + if ((dev->pci_isa_regs[0x5b] & 0x02) || (dev->pci_isa_regs[0x48] & 0x08)) nvr_at_handler(1, 0x0074, dev->nvr); } @@ -780,6 +783,8 @@ pipc_write(int func, int addr, uint8_t val, void *priv) case 0x77: if (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: @@ -1024,8 +1029,8 @@ pipc_write(int func, int addr, uint8_t val, void *priv) break; case 0x42: - dev->power_regs[addr] &= ~0x0f; - dev->power_regs[addr] |= val & 0x0f; + dev->power_regs[addr] &= ~0x2f; + dev->power_regs[addr] |= val & 0x2f; acpi_set_irq_line(dev->acpi, dev->power_regs[addr]); break; @@ -1175,6 +1180,8 @@ pipc_reset(void *p) pipc_write(1, 0x40, 0x04, p); else pipc_write(1, 0x40, 0x00, p); + + pipc_write(0, 0x77, 0x00, p); } diff --git a/src/include/86box/nvr.h b/src/include/86box/nvr.h index 3df78de6e..ceb1bc459 100644 --- a/src/include/86box/nvr.h +++ b/src/include/86box/nvr.h @@ -118,6 +118,7 @@ extern void nvr_at_handler(int set, uint16_t base, nvr_t *nvr); extern void nvr_at_sec_handler(int set, uint16_t base, nvr_t *nvr); extern void nvr_read_addr_set(int set, nvr_t *nvr); extern void nvr_wp_set(int set, int h, nvr_t *nvr); +extern void nvr_via_wp_set(int set, int reg, nvr_t *nvr); extern void nvr_bank_set(int base, uint8_t bank, nvr_t *nvr); extern void nvr_lock_set(int base, int size, int lock, nvr_t *nvr); diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 09be0c1de..a44f4924c 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -150,7 +150,6 @@ typedef void event_t; typedef void mutex_t; extern thread_t *thread_create(void (*thread_func)(void *param), void *param); -extern void thread_kill(thread_t *arg); extern int thread_wait(thread_t *arg, int timeout); extern event_t *thread_create_event(void); extern void thread_set_event(event_t *arg); diff --git a/src/include/86box/vid_voodoo_common.h b/src/include/86box/vid_voodoo_common.h index 3d04a2d44..8000f30c9 100644 --- a/src/include/86box/vid_voodoo_common.h +++ b/src/include/86box/vid_voodoo_common.h @@ -500,8 +500,9 @@ typedef struct voodoo_t void *codegen_data; struct voodoo_set_t *set; - - + + uint8_t fifo_thread_run, render_thread_run[4]; + uint8_t *vram, *changedvram; void *p; diff --git a/src/include/86box/video.h b/src/include/86box/video.h index a28aecffb..311c707df 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -377,6 +377,7 @@ extern const device_t sigma_device; extern const device_t tgui9400cxi_device; extern const device_t tgui9440_vlb_device; extern const device_t tgui9440_pci_device; +extern const device_t tgui9660_pci_device; extern const device_t tgui9680_pci_device; /* IBM PS/1 (S)VGA */ diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index ddddc6705..c4ace48f0 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -2441,6 +2441,8 @@ machine_amstrad_init(const machine_t *model, int type) ams->language = 7; + video_reset(gfxcard); + if (gfxcard == VID_INTERNAL) switch(type) { case AMS_PC1512: loadfont("roms/machines/pc1512/40078", 8); diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 3d691c159..10de113f6 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -323,7 +323,10 @@ machine_at_gw286ct_init(const machine_t *model) device_add(&f82c710_device); - machine_at_scat_init(model, 1); + machine_at_common_init(model); + device_add(&keyboard_at_device); + + device_add(&scat_4_device); device_add(&ide_isa_device); diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 62212c405..e0aef82ef 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -823,6 +823,8 @@ machine_at_compaq_init(const machine_t *model, int type) write_ram, write_ramw, write_raml, 0xa0000+ram, MEM_MAPPING_INTERNAL, NULL); + video_reset(gfxcard); + switch(type) { case COMPAQ_PORTABLEII: break; diff --git a/src/machine/m_at_t3100e.c b/src/machine/m_at_t3100e.c index 7e5750d3a..6e84a5832 100644 --- a/src/machine/m_at_t3100e.c +++ b/src/machine/m_at_t3100e.c @@ -365,6 +365,7 @@ void t3100e_map_ram(uint8_t val) int n; int32_t upper_len; +#ifdef ENABLE_T3100E_LOG t3100e_log("OUT 0x8084, %02x [ set memory mapping :", val | 0x40); if (val & 1) t3100e_log("ENABLE_EMS "); if (val & 2) t3100e_log("ENABLE_XMS "); @@ -372,6 +373,7 @@ void t3100e_map_ram(uint8_t val) if (val & 8) t3100e_log("X8X "); if (val & 16) t3100e_log("UPPER_IS_XMS "); t3100e_log("\n"); +#endif /* Bit 2 controls size of conventional memory */ if (val & 4) @@ -632,7 +634,7 @@ static uint16_t ems_read_ramw(uint32_t addr, void *priv) struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; int pg = addr_to_page(addr); - if (pg < 0) return 0xFF; + if (pg < 0) return 0xFFFF; //t3100e_log("ems_read_ramw addr=%05x ", addr); addr = regs->page_exec[pg] + (addr & 0x3FFF); //t3100e_log("-> %06x val=%04x\n", addr, *(uint16_t *)&ram[addr]); @@ -645,7 +647,7 @@ static uint32_t ems_read_raml(uint32_t addr, void *priv) struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; int pg = addr_to_page(addr); - if (pg < 0) return 0xFF; + if (pg < 0) return 0xFFFFFFFF; addr = regs->page_exec[pg] + (addr & 0x3FFF); return *(uint32_t *)&ram[addr]; } diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index 8a399115f..5b468d2f6 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -824,6 +824,7 @@ machine_pcjr_init(const machine_t *model) cpu_set(); /* Initialize the video controller. */ + video_reset(gfxcard); loadfont("roms/video/mda/mda.rom", 0); mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000, vid_read, NULL, NULL, diff --git a/src/machine/m_tandy.c b/src/machine/m_tandy.c index c09ca21c8..ab01241a0 100644 --- a/src/machine/m_tandy.c +++ b/src/machine/m_tandy.c @@ -1509,6 +1509,8 @@ machine_tandy1k_init(const machine_t *model, int type) if (fdc_type == FDC_INTERNAL) device_add(&fdc_xt_tandy_device); + video_reset(gfxcard); + switch(type) { case TYPE_TANDY: keyboard_set_table(scancode_tandy); diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index bc9edb672..efff2a9c0 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -98,6 +98,9 @@ static int key_queue_start = 0, video_timings_t timing_m19_vid = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; +const device_t m19_vid_device; + + #ifdef ENABLE_M24VID_LOG int m24vid_do_log = ENABLE_M24VID_LOG; @@ -529,6 +532,8 @@ m19_vid_speed_changed(void *priv) static void m19_vid_init(m19_vid_t *vid) { + device_context(&m19_vid_device); + /* int display_type; */ vid->mode = OLIVETTI_OGC_MODE; @@ -540,23 +545,23 @@ m19_vid_init(m19_vid_t *vid) loadfont_ex("roms/machines/m19/BIOS.BIN", 1, 90); /* composite is not working yet */ vid->ogc.cga.composite = 0; // (display_type != CGA_RGB); - /* vid->ogc.cga.snow_enabled = device_get_config_int("snow_enabled"); */ + vid->ogc.cga.revision = device_get_config_int("composite_type"); + vid->ogc.cga.snow_enabled = device_get_config_int("snow_enabled"); vid->ogc.cga.vram = malloc(0x8000); /* cga_comp_init(vid->ogc.cga.revision); */ - /* vid->ogc.cga.rgb_type = device_get_config_int("rgb_type"); */ - /* cga_palette = (vid->ogc.cga.rgb_type << 1); */ - cga_palette = 0; + vid->ogc.cga.rgb_type = device_get_config_int("rgb_type"); + cga_palette = (vid->ogc.cga.rgb_type << 1); cgapal_rebuild(); ogc_mdaattr_rebuild(); /* color display */ - /* if (device_get_config_int("rgb_type")==0 || device_get_config_int("rgb_type") == 4) */ - vid->ogc.mono_display = 1; - /* else */ - /* vid->ogc.mono_display = 1; */ + if (device_get_config_int("rgb_type")==0 || device_get_config_int("rgb_type") == 4) + vid->ogc.mono_display = 0; + else + vid->ogc.mono_display = 1; /* OGC emulation part end */ /* Plantronics emulation part begin*/ @@ -576,6 +581,8 @@ m19_vid_init(m19_vid_t *vid) io_sethandler(0x03d0, 0x0010, m19_vid_in, NULL, NULL, m19_vid_out, NULL, NULL, vid); vid->mode = OLIVETTI_OGC_MODE; + + device_context_restore(); } @@ -589,6 +596,37 @@ const device_t m24_kbd_device = { { NULL }, NULL, NULL }; +const device_config_t m19_vid_config[] = +{ + { + /* Olivetti / ATT compatible displays */ + "rgb_type", "RGB type", CONFIG_SELECTION, "", CGA_RGB, "", { 0 }, + { + { + "Color", 0 + }, + { + "Green Monochrome", 1 + }, + { + "Amber Monochrome", 2 + }, + { + "Gray Monochrome", 3 + }, + { + "" + } + } + }, + { + "snow_enabled", "Snow emulation", CONFIG_BINARY, "", 1, + }, + { + "", "", -1 + } +}; + const device_t m19_vid_device = { "Olivetti M19 graphics card", 0, 0, @@ -596,7 +634,7 @@ const device_t m19_vid_device = { { NULL }, m19_vid_speed_changed, NULL, - NULL + m19_vid_config }; const device_t * @@ -707,6 +745,7 @@ int machine_xt_m24_init(const machine_t *model) { int ret; + m24_kbd_t *m24_kbd; ret = bios_load_interleaved("roms/machines/m24/olivetti_m24_version_1.43_low.bin", "roms/machines/m24/olivetti_m24_version_1.43_high.bin", @@ -715,11 +754,6 @@ machine_xt_m24_init(const machine_t *model) if (bios_only || !ret) return ret; - if (gfxcard == VID_INTERNAL) - device_add(&ogc_m24_device); - - m24_kbd_t *m24_kbd; - m24_kbd = (m24_kbd_t *) malloc(sizeof(m24_kbd_t)); memset(m24_kbd, 0x00, sizeof(m24_kbd_t)); @@ -732,9 +766,6 @@ machine_xt_m24_init(const machine_t *model) /* Address 66-67 = mainboard dip-switch settings */ io_sethandler(0x0066, 2, m24_read, NULL, NULL, NULL, NULL, NULL, NULL); - m24_kbd_init(m24_kbd); - device_add_ex(&m24_kbd_device, m24_kbd); - /* FIXME: make sure this is correct?? */ device_add(&at_nvr_device); @@ -742,6 +773,14 @@ machine_xt_m24_init(const machine_t *model) nmi_init(); + video_reset(gfxcard); + + if (gfxcard == VID_INTERNAL) + device_add(&ogc_m24_device); + + m24_kbd_init(m24_kbd); + device_add_ex(&m24_kbd_device, m24_kbd); + return ret; } @@ -813,16 +852,21 @@ machine_xt_m19_init(const machine_t *model) machine_common_init(model); + pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt); + /* On-board FDC cannot be disabled */ device_add(&fdc_xt_device); + nmi_init(); + + video_reset(gfxcard); + m19_vid_init(vid); device_add_ex(&m19_vid_device, vid); device_add(&keyboard_xt_olivetti_device); - nmi_init(); + pit_set_clock(14318184.0); return ret; - } diff --git a/src/machine/machine.c b/src/machine/machine.c index ae731e522..6c453812c 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -82,6 +82,9 @@ machine_init_ex(int m) AT = IS_AT(machine); PCI = IS_ARCH(machine, MACHINE_BUS_PCI); + cpu_set(); + pc_speed_changed(); + /* Reset the memory state. */ mem_reset(); smbase = is_am486dxl ? 0x00060000 : 0x00030000; @@ -132,7 +135,5 @@ machine_common_init(const machine_t *model) pic_init(); dma_init(); - cpu_set(); - pit_common_init(!!AT, pit_irq0_timer, NULL); } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index c60982831..ede7707fe 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -75,7 +75,7 @@ const machine_t machines[] = { { "[8088] Juko XT clone", "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-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, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 256, 640, 256, 0, machine_xt_m19_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 }, { "[8088] OpenXT", "openxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_openxt_init, NULL }, { "[8088] Philips P3105/NMS9100", "p3105", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_XTA, 256, 768, 256, 0, machine_xt_p3105_init, NULL }, { "[8088] Phoenix XT clone", "pxxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_pxxt_init, NULL }, diff --git a/src/mem/sst_flash.c b/src/mem/sst_flash.c index 8318c3a0f..1a0bb0550 100644 --- a/src/mem/sst_flash.c +++ b/src/mem/sst_flash.c @@ -175,13 +175,14 @@ static uint8_t sst_read_id(uint32_t addr, void *p) { sst_t *dev = (sst_t *) p; + uint8_t ret = 0xff; if ((addr & 0xffff) == 0) - return SST_ID_MANUFACTURER; /* SST */ + ret = SST_ID_MANUFACTURER; /* SST */ else if ((addr & 0xffff) == 1) - return dev->id; - else - return 0xff; + ret = dev->id; + + return ret; } @@ -237,7 +238,10 @@ sst_write(uint32_t addr, uint8_t val, void *p) case 2: case 5: /* 3rd and 6th Bus Write Cycle */ - if ((addr & 0x7fff) == 0x5555) + if ((dev->command_state == 5) && (val == SST_SECTOR_ERASE)) { + /* Sector erase - can be on any address. */ + sst_new_command(dev, addr, val); + } else if ((addr & 0x7fff) == 0x5555) sst_new_command(dev, addr, val); else dev->command_state = 0; diff --git a/src/nvr_at.c b/src/nvr_at.c index 419da7c79..3b4fc7957 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -299,7 +299,9 @@ typedef struct { int8_t stat; uint8_t cent, def, - flags, read_addr; + flags, read_addr, + wp_0d, wp_32, + pad, pad0; uint8_t addr[8], wp[2], bank[8], *lock; @@ -587,14 +589,6 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv) break; case RTC_REGD: /* R/O */ - /* VT82C686A/B have an ACPI register bit controlled by 0D bit 7. - This is overwritten on read, but testing shows BIOSes will - immediately check the ACPI register after writing to this. */ - if (local->cent == RTC_CENTURY_VIA) { - nvr->regs[RTC_REGD] &= ~0x80; - if (val & 0x80) - nvr->regs[RTC_REGD] |= 0x80; - } break; case 0x2e: @@ -609,6 +603,11 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv) } /*FALLTHROUGH*/ + case 0x32: + if ((local->cent == RTC_CENTURY_VIA) && local->wp_32) + break; + /* FALLTHROUGH */ + default: /* non-RTC registers are just NVRAM */ if ((reg == 0x2c) && (local->flags & FLAG_LS_HACK)) nvr->new = 0; @@ -686,13 +685,16 @@ nvr_read(uint16_t addr, void *priv) cycles -= ISA_CYCLES(8); if (local->bank[addr_id] == 0xff) - return 0xff; - - if (addr & 1) switch(local->addr[addr_id]) { + ret = 0xff; + else if (addr & 1) switch(local->addr[addr_id]) { case RTC_REGA: ret = (nvr->regs[RTC_REGA] & 0x7f) | local->stat; break; + case RTC_REGB: + ret = nvr->regs[local->addr[addr_id]] | 0x40; + break; + case RTC_REGC: picintc(1 << nvr->irq); ret = nvr->regs[RTC_REGC]; @@ -700,8 +702,9 @@ nvr_read(uint16_t addr, void *priv) break; case RTC_REGD: - nvr->regs[RTC_REGD] |= REGD_VRT; - ret = nvr->regs[RTC_REGD]; + /* Bits 6-0 of this register always read 0. Bit 7 is battery state, + we should always return it set, as that means the battery is OK. */ + ret = REGD_VRT; break; case 0x2c: @@ -886,6 +889,18 @@ nvr_wp_set(int set, int h, nvr_t *nvr) } +void +nvr_via_wp_set(int set, int reg, nvr_t *nvr) +{ + local_t *local = (local_t *) nvr->data; + + if (reg == 0x0d) + local->wp_0d = set; + else + local->wp_32 = set; +} + + void nvr_bank_set(int base, uint8_t bank, nvr_t *nvr) { @@ -906,6 +921,17 @@ nvr_lock_set(int base, int size, int lock, nvr_t *nvr) } +static void +nvr_at_reset(void *priv) +{ + nvr_t *nvr = (nvr_t *) priv; + + /* These bits are reset on reset. */ + nvr->regs[RTC_REGB] &= ~(REGB_PIE | REGB_AIE | REGB_UIE | REGB_SQWE); + nvr->regs[RTC_REGC] &= ~(REGC_PF | REGC_AF | REGC_UF | REGC_IRQF); +} + + static void * nvr_at_init(const device_t *info) { @@ -990,6 +1016,10 @@ nvr_at_init(const device_t *info) timer_add(&local->update_timer, timer_update, nvr, 0); timer_add(&local->rtc_timer, timer_intr, nvr, 0); + /* On power on, if the oscillator is disabled, it's reenabled. */ + if ((nvr->regs[RTC_REGA] & 0x70) == 0x00) + nvr->regs[RTC_REGA] = (nvr->regs[RTC_REGA] & 0x8f) | 0x20; + nvr_at_reset(nvr); timer_load_count(nvr); timer_set_delay_u64(&local->rtc_timer, RTCCONST); @@ -1039,7 +1069,7 @@ const device_t at_nvr_old_device = { "PC/AT NVRAM (No century)", DEVICE_ISA | DEVICE_AT, 0, - nvr_at_init, nvr_at_close, NULL, + nvr_at_init, nvr_at_close, nvr_at_reset, { NULL }, nvr_at_speed_changed, NULL }; @@ -1048,7 +1078,7 @@ const device_t at_nvr_device = { "PC/AT NVRAM", DEVICE_ISA | DEVICE_AT, 1, - nvr_at_init, nvr_at_close, NULL, + nvr_at_init, nvr_at_close, nvr_at_reset, { NULL }, nvr_at_speed_changed, NULL }; @@ -1057,7 +1087,7 @@ const device_t ps_nvr_device = { "PS/1 or PS/2 NVRAM", DEVICE_PS2, 2, - nvr_at_init, nvr_at_close, NULL, + nvr_at_init, nvr_at_close, nvr_at_reset, { NULL }, nvr_at_speed_changed, NULL }; @@ -1066,7 +1096,7 @@ const device_t amstrad_nvr_device = { "Amstrad NVRAM", DEVICE_ISA | DEVICE_AT, 3, - nvr_at_init, nvr_at_close, NULL, + nvr_at_init, nvr_at_close, nvr_at_reset, { NULL }, nvr_at_speed_changed, NULL }; @@ -1075,7 +1105,7 @@ const device_t ibmat_nvr_device = { "IBM AT NVRAM", DEVICE_ISA | DEVICE_AT, 4, - nvr_at_init, nvr_at_close, NULL, + nvr_at_init, nvr_at_close, nvr_at_reset, { NULL }, nvr_at_speed_changed, NULL }; @@ -1084,7 +1114,7 @@ const device_t piix4_nvr_device = { "Intel PIIX4 PC/AT NVRAM", DEVICE_ISA | DEVICE_AT, 9, - nvr_at_init, nvr_at_close, NULL, + nvr_at_init, nvr_at_close, nvr_at_reset, { NULL }, nvr_at_speed_changed, NULL }; @@ -1093,7 +1123,7 @@ const device_t ls486e_nvr_device = { "Lucky Star LS-486E PC/AT NVRAM", DEVICE_ISA | DEVICE_AT, 13, - nvr_at_init, nvr_at_close, NULL, + nvr_at_init, nvr_at_close, nvr_at_reset, { NULL }, nvr_at_speed_changed, NULL }; @@ -1102,7 +1132,7 @@ const device_t ami_apollo_nvr_device = { "AMI Apollo PC/AT NVRAM", DEVICE_ISA | DEVICE_AT, 14, - nvr_at_init, nvr_at_close, NULL, + nvr_at_init, nvr_at_close, nvr_at_reset, { NULL }, nvr_at_speed_changed, NULL }; @@ -1111,7 +1141,7 @@ const device_t via_nvr_device = { "VIA PC/AT NVRAM", DEVICE_ISA | DEVICE_AT, 15, - nvr_at_init, nvr_at_close, NULL, + nvr_at_init, nvr_at_close, nvr_at_reset, { NULL }, nvr_at_speed_changed, NULL }; diff --git a/src/random.c b/src/random.c index 4f7168c4b..fb1fead52 100644 --- a/src/random.c +++ b/src/random.c @@ -82,7 +82,7 @@ static void random_twist(uint32_t *val) uint8_t random_generate(void) { uint16_t r = 0; - r = (rand() ^ ROTATE_LEFT(preconst, rand() % 32)) % 256; + r = (RDTSC() ^ ROTATE_LEFT(preconst, rand() % 32)) % 256; random_twist(&preconst); return (r & 0xff); } diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index c6cb987e1..d5c7a2bbd 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -116,8 +116,13 @@ static void ati18800_out(uint16_t addr, uint8_t val, void *p) { if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + 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); + } } } break; diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 6ceae881e..d6630ccf8 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -199,12 +199,19 @@ ati28800_out(uint16_t addr, uint8_t val, void *p) old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } + if (old != val) + { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) + { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + 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); + } + } + } break; } svga_out(addr, val, svga); diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 0d816ba7f..0701df498 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -253,6 +253,7 @@ typedef struct mach64_t int overlay_v_acc; + uint8_t thread_run; void *i2c, *ddc; } mach64_t; @@ -418,12 +419,17 @@ void mach64_out(uint16_t addr, uint8_t val, void *p) old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; - if (old!=val) + if (old != val) { if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + 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); + } } } break; @@ -926,7 +932,7 @@ static void fifo_thread(void *param) { mach64_t *mach64 = (mach64_t *)param; - while (1) + while (mach64->thread_run) { thread_set_event(mach64->fifo_not_full_event); thread_wait_event(mach64->wake_fifo_thread, -1); @@ -3359,6 +3365,7 @@ static void *mach64_common_init(const device_t *info) mach64->wake_fifo_thread = thread_create_event(); mach64->fifo_not_full_event = thread_create_event(); + mach64->thread_run = 1; mach64->fifo_thread = thread_create(fifo_thread, mach64); mach64->i2c = i2c_gpio_init("ddc_ati_mach64"); @@ -3450,7 +3457,9 @@ void mach64_close(void *p) svga_close(&mach64->svga); - thread_kill(mach64->fifo_thread); + mach64->thread_run = 0; + thread_set_event(mach64->wake_fifo_thread); + thread_wait(mach64->fifo_thread, -1); thread_destroy_event(mach64->wake_fifo_thread); thread_destroy_event(mach64->fifo_not_full_event); diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 155253610..c1eb9ac2d 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1142,10 +1142,16 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) break; } - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) + { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + 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); + } + } } break; } @@ -1597,7 +1603,7 @@ gd54xx_recalctimings(svga_t *svga) uint8_t clocksel, rdmask; uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp; - svga->rowoffset = (svga->crtc[0x13]) | ((svga->crtc[0x1b] & 0x10) << 4); + svga->rowoffset = (svga->crtc[0x13]) | (((int) (uint32_t) (svga->crtc[0x1b] & 0x10)) << 4); svga->interlace = (svga->crtc[0x1a] & 0x01); diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 92f0e8ef4..570a676d3 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -224,8 +224,13 @@ ega_out(uint16_t addr, uint8_t val, void *p) ega->crtc[ega->crtcreg] = val; if (old != val) { if (ega->crtcreg < 0xe || ega->crtcreg > 0x10) { - fullchange = changeframecount; - ega_recalctimings(ega); + if ((ega->crtcreg == 0xc) || (ega->crtcreg == 0xd)) { + fullchange = 3; + ega->ma_latch = ((ega->crtc[0xc] << 8) | ega->crtc[0xd]) + ((ega->crtc[8] & 0x60) >> 5); + } else { + fullchange = changeframecount; + ega_recalctimings(ega); + } } } break; diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index d22a6e6af..740be207e 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -281,10 +281,16 @@ et4000_out(uint16_t addr, uint8_t val, void *priv) } if (old != val) { - if (svga->crtcreg < 0x0e || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) + { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + 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); + } + } } break; } diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 1652615af..36f8b67fb 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -231,10 +231,16 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p) svga->write_bank = svga->read_bank = 0; } if (old != val) { - if ((svga->crtcreg < 0xe) || (svga->crtcreg > 0x10)) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) + { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + 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); + } + } } if (svga->crtcreg == 0x30) { if (et4000->pci) diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index ab1a86814..eafc7400c 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -414,10 +414,16 @@ ht216_out(uint16_t addr, uint8_t val, void *p) svga->crtc[svga->crtcreg] = val; if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) + { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + 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; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 8ac16f2d6..3d9102b7c 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -502,6 +502,8 @@ typedef struct mystique_t mutex_t *lock; } dma; + uint8_t thread_run; + void *i2c, *i2c_ddc, *ddc; } mystique_t; @@ -674,8 +676,13 @@ mystique_out(uint16_t addr, uint8_t val, void *p) svga->crtc[svga->crtcreg & 0x3f] = val; if (old != val) { if ((svga->crtcreg & 0x3f) < 0xE || (svga->crtcreg & 0x3f) > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); + if (((svga->crtcreg & 0x3f) == 0xc) || ((svga->crtcreg & 0x3f) == 0xd)) { + 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); + } } if (svga->crtcreg == 0x11) { if (!(val & 0x10)) @@ -2349,7 +2356,7 @@ fifo_thread(void *p) { mystique_t *mystique = (mystique_t *)p; - while (1) { + while (mystique->thread_run) { thread_set_event(mystique->fifo_not_full_event); thread_wait_event(mystique->wake_fifo_thread, -1); thread_reset_event(mystique->wake_fifo_thread); @@ -5003,6 +5010,7 @@ mystique_init(const device_t *info) mystique->wake_fifo_thread = thread_create_event(); mystique->fifo_not_full_event = thread_create_event(); + mystique->thread_run = 1; mystique->fifo_thread = thread_create(fifo_thread, mystique); mystique->dma.lock = thread_create_mutex(); @@ -5026,7 +5034,9 @@ mystique_close(void *p) { mystique_t *mystique = (mystique_t *)p; - thread_kill(mystique->fifo_thread); + mystique->thread_run = 0; + thread_set_event(mystique->wake_fifo_thread); + thread_wait(mystique->fifo_thread, -1); thread_destroy_event(mystique->wake_fifo_thread); thread_destroy_event(mystique->fifo_not_full_event); thread_close_mutex(mystique->dma.lock); diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index cd7d4e26e..892967837 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -107,8 +107,13 @@ oti_out(uint16_t addr, uint8_t val, void *p) svga->crtc[idx] = val; if (old != val) { if ((idx < 0x0e) || (idx > 0x10)) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); + if (idx == 0x0c || idx == 0x0d) { + 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); + } } } break; diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 567d7fd4c..f79b93407 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -151,10 +151,15 @@ void paradise_out(uint16_t addr, uint8_t val, void *p) if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(¶dise->svga); + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + 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); + } } } diff --git a/src/video/vid_rtg310x.c b/src/video/vid_rtg310x.c index 55509352f..4442af6ef 100644 --- a/src/video/vid_rtg310x.c +++ b/src/video/vid_rtg310x.c @@ -169,10 +169,16 @@ rtg_out(uint16_t addr, uint8_t val, void *priv) } if (old != val) { - if (svga->crtcreg < 0x0e || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) + { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + 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); + } + } } break; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index ed2d4b648..cb1c4043a 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -234,6 +234,7 @@ typedef struct s3_t uint32_t dat_buf; int dat_count; int b2e8_pix, temp_cnt; + uint8_t cur_x_bit12, cur_y_bit12; } accel; struct { @@ -318,7 +319,7 @@ typedef struct s3_t int enable_8514; volatile int busy, force_busy; - uint8_t serialport; + uint8_t thread_run, serialport; void *i2c, *ddc; } s3_t; @@ -541,6 +542,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x8149: case 0x82e9: s3->accel.cur_y_bitres = (s3->accel.cur_y_bitres & 0xff) | (val << 8); s3->accel.cur_y = (s3->accel.cur_y & 0xff) | ((val & 0x0f) << 8); + s3->accel.cur_y_bit12 = val & 0x10; s3->accel.poly_cy = s3->accel.cur_y; break; case 0x814a: case 0x82ea: @@ -561,6 +563,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x8549: case 0x86e9: s3->accel.cur_x_bitres = (s3->accel.cur_x_bitres & 0xff) | (val << 8); s3->accel.cur_x = (s3->accel.cur_x & 0xff) | ((val & 0x0f) << 8); + s3->accel.cur_x_bit12 = val & 0x10; s3->accel.poly_cx = s3->accel.poly_x = s3->accel.cur_x << 20; s3->accel.poly_x = s3->accel.poly_cx >> 20; break; @@ -1506,7 +1509,7 @@ fifo_thread(void *param) { s3_t *s3 = (s3_t *)param; - while (1) + while (s3->thread_run) { thread_set_event(s3->fifo_not_full_event); thread_wait_event(s3->wake_fifo_thread, -1); @@ -2031,7 +2034,7 @@ s3_io_set_alt(s3_t *s3) io_sethandler(0x4148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0x4548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0x4948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - if (s3->chip == S3_TRIO64 || s3->chip >= S3_TRIO64V || s3->chip == S3_VISION968) + if (s3->chip == S3_TRIO64 || s3->chip >= S3_TRIO64V || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) { io_sethandler(0x8148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0x8548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -2411,16 +2414,21 @@ s3_out(uint16_t addr, uint8_t val, void *p) default: svga->bpp = 8; break; } } - break; - } - if (old != val) - { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } + break; } + if (old != val) + { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) + { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + 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); + } + } + } break; } svga_out(addr, val, svga); @@ -4506,9 +4514,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 1: /*Draw line*/ if (!cpu_input) { s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; + if (s3->accel.cur_x_bit12) s3->accel.cx |= ~0xfff; s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; + if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; s3->accel.sy = s3->accel.maj_axis_pcnt; @@ -4672,14 +4680,14 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cx = s3->accel.cur_x; s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_x & 0x1000) { + if (s3->accel.cur_x_bit12) { if (s3->accel.cx <= 0x7ff) { s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; } else { s3->accel.cx |= ~0xfff; } } - if (s3->accel.cur_y & 0x1000) { + if (s3->accel.cur_y_bit12) { if (s3->accel.cy <= 0x7ff) { s3->accel.cy = s3->accel.cur_y_bitres & 0xfff; } else { @@ -4915,7 +4923,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->accel.dx >= 0xfffff000) { /* avoid overflow */ s3->accel.dx = s3->accel.destx_distp & 0xfff; - if (s3->accel.cur_x & 0x1000) { + if (s3->accel.cur_x_bit12) { if (s3->accel.cx <= 0x7ff) { s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; } else { @@ -4925,14 +4933,14 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->accel.cur_y_bitres > 0xfff) s3->accel.cy = s3->accel.cur_y_bitres; } else { - if (s3->accel.cur_x & 0x1000) { + if (s3->accel.cur_x_bit12) { if (s3->accel.cx <= 0x7ff) { /* overlap x */ s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; } else { /* x end is negative */ s3->accel.cx |= ~0xfff; } } - if (s3->accel.cur_y & 0x1000) { + if (s3->accel.cur_y_bit12) { if (s3->accel.cy <= 0x7ff) { /* overlap y */ s3->accel.cy = s3->accel.cur_y_bitres & 0xfff; } else { /* y end is negative */ @@ -5097,9 +5105,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->accel.desty_axstp & 0x1000) s3->accel.dy |= ~0xfff; s3->accel.cx = s3->accel.cur_x & 0xfff; - if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; + if (s3->accel.cur_x_bit12) s3->accel.cx |= ~0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; + if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; /*Align source with destination*/ s3->accel.pattern = (s3->accel.cy * s3->width) + s3->accel.cx; @@ -5219,10 +5227,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dy |= ~0xfff; s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x & 0x1000) + if (s3->accel.cur_x_bit12) s3->accel.cx |= ~0xfff; s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y & 0x1000) + if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; } @@ -5406,9 +5414,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->accel.desty_axstp & 0x1000) s3->accel.dy |= ~0xfff; s3->accel.cx = s3->accel.cur_x & 0xfff; - if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; + if (s3->accel.cur_x_bit12) s3->accel.cx |= ~0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; + if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; s3->accel.px = s3->accel.pat_x & 0xfff; if (s3->accel.pat_x & 0x1000) s3->accel.px |= ~0xfff; @@ -6205,6 +6213,7 @@ static void *s3_init(const device_t *info) s3->wake_fifo_thread = thread_create_event(); s3->fifo_not_full_event = thread_create_event(); + s3->thread_run = 1; s3->fifo_thread = thread_create(fifo_thread, s3); return s3; @@ -6311,7 +6320,9 @@ static void s3_close(void *p) svga_close(&s3->svga); - thread_kill(s3->fifo_thread); + s3->thread_run = 0; + thread_set_event(s3->wake_fifo_thread); + thread_wait(s3->fifo_thread, -1); thread_destroy_event(s3->wake_fifo_thread); thread_destroy_event(s3->fifo_not_full_event); diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 4bd38a5bb..156947652 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -288,6 +288,8 @@ typedef struct virge_t uint8_t subsys_stat, subsys_cntl, advfunc_cntl; + uint8_t render_thread_run, fifo_thread_run; + uint8_t serialport; void *i2c, *ddc; @@ -581,8 +583,13 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) { if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + 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); + } } } break; @@ -1117,7 +1124,7 @@ static void fifo_thread(void *param) { virge_t *virge = (virge_t *)param; - while (1) + while (virge->fifo_thread_run) { thread_set_event(virge->fifo_not_full_event); thread_wait_event(virge->wake_fifo_thread, -1); @@ -3230,7 +3237,7 @@ static void render_thread(void *param) { virge_t *virge = (virge_t *)param; - while (1) + while (virge->render_thread_run) { thread_wait_event(virge->wake_render_thread, -1); thread_reset_event(virge->wake_render_thread); @@ -3892,10 +3899,12 @@ static void *s3_virge_init(const device_t *info) virge->wake_render_thread = thread_create_event(); virge->wake_main_thread = thread_create_event(); virge->not_full_event = thread_create_event(); + virge->render_thread_run = 1; virge->render_thread = thread_create(render_thread, virge); virge->wake_fifo_thread = thread_create_event(); virge->fifo_not_full_event = thread_create_event(); + virge->fifo_thread_run = 1; virge->fifo_thread = thread_create(fifo_thread, virge); virge->i2c = i2c_gpio_init("ddc_s3_virge"); @@ -3910,12 +3919,16 @@ static void s3_virge_close(void *p) { virge_t *virge = (virge_t *)p; - thread_kill(virge->render_thread); + virge->render_thread_run = 0; + thread_set_event(virge->wake_render_thread); + thread_wait(virge->render_thread, -1); thread_destroy_event(virge->not_full_event); thread_destroy_event(virge->wake_main_thread); thread_destroy_event(virge->wake_render_thread); - thread_kill(virge->fifo_thread); + virge->fifo_thread_run = 0; + thread_set_event(virge->wake_fifo_thread); + thread_wait(virge->fifo_thread, -1); thread_destroy_event(virge->wake_fifo_thread); thread_destroy_event(virge->fifo_not_full_event); diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 3a929fe73..d683bb74f 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -160,6 +160,7 @@ video_cards[] = { { "virge375_vbe20_pci", &s3_virge_375_4_pci_device }, { "cl_gd5446_stb_pci", &gd5446_stb_pci_device }, { "tgui9440_pci", &tgui9440_pci_device }, + { "tgui9660_pci", &tgui9660_pci_device }, { "tgui9680_pci", &tgui9680_pci_device }, { "voodoo_banshee_pci", &voodoo_banshee_device }, { "voodoo3_2k_pci", &voodoo_3_2000_device }, diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index 2429f52b1..eff0e093d 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -70,12 +70,14 @@ #include "cpu.h" #include <86box/plat.h> #include <86box/video.h> +#include <86box/i2c.h> +#include <86box/vid_ddc.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> #define ROM_TGUI_9400CXI "roms/video/tgui9440/9400CXI.vbi" #define ROM_TGUI_9440 "roms/video/tgui9440/BIOS.BIN" -#define ROM_TGUI_9680 "roms/video/tgui9660/Union.VBI" +#define ROM_TGUI_96xx "roms/video/tgui9660/Union.VBI" #define EXT_CTRL_16BIT 0x01 #define EXT_CTRL_MONO_EXPANSION 0x02 @@ -86,6 +88,7 @@ enum { TGUI_9400CXI = 0, TGUI_9440, + TGUI_9660, TGUI_9680 }; @@ -100,7 +103,7 @@ typedef struct tgui_t svga_t svga; int pci; - int type; + int type, card; uint8_t int_line; uint8_t pci_regs[256]; @@ -156,6 +159,7 @@ typedef struct tgui_t uint32_t vram_size, vram_mask; volatile int write_blitter; + void *i2c, *ddc; } tgui_t; video_timings_t timing_tgui_vlb = {VIDEO_BUS, 4, 8, 16, 4, 8, 16}; @@ -208,6 +212,19 @@ dword_remap(svga_t *svga, uint32_t in_addr) (in_addr & ~0x3fffc); } +static void +tgui_update_irqs(tgui_t *tgui) +{ + if (!tgui->pci) + return; + + if (!(tgui->oldctrl1 & 0x40)) { + pci_set_irq(tgui->card, PCI_INTA); + } else { + pci_clear_irq(tgui->card, PCI_INTA); + } +} + static void tgui_remove_io(tgui_t *tgui) { @@ -275,7 +292,9 @@ tgui_out(uint16_t addr, uint8_t val, void *p) { tgui_t *tgui = (tgui_t *)p; svga_t *svga = &tgui->svga; - uint8_t old; + uint8_t old, mask; + + mask = (tgui->type >= TGUI_9660) ? 0x3f : 0x1f; if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -289,7 +308,7 @@ tgui_out(uint16_t addr, uint8_t val, void *p) break; case 0xC: if (svga->seqregs[0xe] & 0x80) - svga->seqregs[0xc] = val; + svga->seqregs[0xc] = val; break; case 0xd: if (tgui->oldmode) @@ -298,12 +317,12 @@ tgui_out(uint16_t addr, uint8_t val, void *p) tgui->newctrl2 = val; break; case 0xE: - if (tgui->oldmode) - tgui->oldctrl1 = val; - else - { - svga->seqregs[0xe] = val ^ 2; - svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536; + if (tgui->oldmode) { + tgui->oldctrl1 = val; + tgui_update_irqs(tgui); + } else { + svga->seqregs[0xe] = (val ^ 2); + svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536; if (!(svga->gdcreg[0xf] & 1)) svga->read_bank = svga->write_bank; } @@ -330,7 +349,7 @@ tgui_out(uint16_t addr, uint8_t val, void *p) svga->bpp = 16; break; case 0xd0: - svga->bpp = ((svga->crtc[0x38] & 0x08) == 0x08 && tgui->type == TGUI_9440) ? 24 : 32; + svga->bpp = ((svga->crtc[0x38] & 0x08) == 0x08 && (tgui->type == TGUI_9440)) ? 24 : 32; break; default: svga->bpp = 8; @@ -387,7 +406,7 @@ tgui_out(uint16_t addr, uint8_t val, void *p) } break; case 0x3D4: - svga->crtcreg = val & 0x7f; + svga->crtcreg = val; return; case 0x3D5: if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) @@ -399,10 +418,15 @@ tgui_out(uint16_t addr, uint8_t val, void *p) if (old != val) { - if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + 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); + } } } switch (svga->crtcreg) { @@ -423,14 +447,20 @@ tgui_out(uint16_t addr, uint8_t val, void *p) case 0x34: case 0x35: - tgui->ge_base = ((svga->crtc[0x35] << 0x18) | (svga->crtc[0x34] << 0x10)); - tgui_recalcmapping(tgui); + if (tgui->type >= TGUI_9440) { + tgui->ge_base = ((svga->crtc[0x35] << 0x18) | (svga->crtc[0x34] << 0x10)); + tgui_recalcmapping(tgui); + } break; case 0x36: case 0x39: - if (tgui->type >= TGUI_9440) - tgui_recalcmapping(tgui); + tgui_recalcmapping(tgui); + break; + + case 0x37: + if (tgui->type >= TGUI_9660) + i2c_gpio_set(tgui->i2c, !!(val & 0x02), (val & 0x01)); break; case 0x40: case 0x41: case 0x42: case 0x43: @@ -438,7 +468,7 @@ tgui_out(uint16_t addr, uint8_t val, void *p) if (tgui->type >= TGUI_9440) { svga->hwcursor.x = (svga->crtc[0x40] | (svga->crtc[0x41] << 8)) & 0x7ff; svga->hwcursor.y = (svga->crtc[0x42] | (svga->crtc[0x43] << 8)) & 0x7ff; - if (tgui->type == TGUI_9680 && (tgui->accel.ger22 & 0xff) == 8) { + if (tgui->type >= TGUI_9660 && (tgui->accel.ger22 & 0xff) == 8) { svga->hwcursor.x <<= 1; } svga->hwcursor.xoff = svga->crtc[0x46] & 0x3f; @@ -457,19 +487,18 @@ tgui_out(uint16_t addr, uint8_t val, void *p) return; case 0x3D8: - tgui->tgui_3d8 = val; - if (svga->gdcreg[0xf] & 4) - { - svga->write_bank = (val & 0x1f) * 65536; - if (!(svga->gdcreg[0xf] & 1)) - svga->read_bank = (val & 0x1f) * 65536; - } - return; + tgui->tgui_3d8 = val; + if (svga->gdcreg[0xf] & 4) { + svga->write_bank = (val & mask) * 65536; + if (!(svga->gdcreg[0xf] & 1)) + svga->read_bank = (val & mask) * 65536; + } + return; case 0x3D9: - tgui->tgui_3d9 = val; - if ((svga->gdcreg[0xf] & 5) == 5) - svga->read_bank = (val & 0x1F) * 65536; - return; + tgui->tgui_3d9 = val; + if ((svga->gdcreg[0xf] & 5) == 5) + svga->read_bank = (val & mask) * 65536; + return; case 0x43c8: tgui->clock_n = val & 0x7f; @@ -497,7 +526,7 @@ tgui_in(uint16_t addr, void *p) case 0x3C5: if ((svga->seqaddr & 0xf) == 9) { if (tgui->type == TGUI_9680) - return 1; /*TGUI9680*/ + return 0x01; /*TGUI9680XGi*/ } if ((svga->seqaddr & 0xf) == 0xb) { @@ -508,6 +537,7 @@ tgui_in(uint16_t addr, void *p) return 0x93; /*TGUI9400CXi*/ case TGUI_9440: return 0xe3; /*TGUI9440AGi*/ + case TGUI_9660: case TGUI_9680: return 0xd3; /*TGUI9660XGi*/ } @@ -546,7 +576,15 @@ tgui_in(uint16_t addr, void *p) case 0x3D4: return svga->crtcreg; case 0x3D5: - temp = svga->crtc[svga->crtcreg]; + temp = svga->crtc[svga->crtcreg]; + if (svga->crtcreg == 0x37) { + if (tgui->type >= TGUI_9660) { + if ((svga->crtc[0x37] & 0x02) && i2c_gpio_get_scl(tgui->i2c)) + temp |= 0x02; + if ((svga->crtc[0x37] & 0x01) && i2c_gpio_get_sda(tgui->i2c)) + temp |= 0x01; + } + } return temp; case 0x3d8: return tgui->tgui_3d8; @@ -649,10 +687,10 @@ void tgui_recalctimings(svga_t *svga) { case 8: svga->render = svga_render_8bpp_highres; - if (tgui->type >= TGUI_9680) { + if (tgui->type >= TGUI_9660) { if (svga->dispend == 512) svga->hdisp = 1280; - else if (svga->dispend == 1200) + else if (svga->dispend == 600 && svga->hdisp == 800 && svga->vtotal == 651) svga->hdisp = 1600; } break; @@ -857,7 +895,7 @@ uint8_t tgui_pci_read(int func, int addr, void *p) case 0x08: return 0; /*Revision ID*/ case 0x09: return 0; /*Programming interface*/ - case 0x0a: return 0x01; /*Supports VGA interface*/ + case 0x0a: return 0x01; /*Supports VGA interface, XGA compatible*/ case 0x0b: return 0x03; case 0x10: return 0x00; /*Linear frame buffer address*/ @@ -874,6 +912,9 @@ uint8_t tgui_pci_read(int func, int addr, void *p) case 0x31: return 0x00; case 0x32: return tgui->pci_regs[0x32]; case 0x33: return tgui->pci_regs[0x33]; + + case 0x3c: return tgui->int_line; + case 0x3d: return PCI_INTA; } return 0; } @@ -895,7 +936,7 @@ void tgui_pci_write(int func, int addr, uint8_t val, void *p) break; case 0x12: - if (tgui->type == TGUI_9680) + if (tgui->type >= TGUI_9660) tgui->linear_base = (tgui->linear_base & 0xff000000) | ((val & 0xc0) << 16); else tgui->linear_base = (tgui->linear_base & 0xff000000) | ((val & 0xe0) << 16); @@ -905,7 +946,7 @@ void tgui_pci_write(int func, int addr, uint8_t val, void *p) tgui_recalcmapping(tgui); break; case 0x13: - if (tgui->type == TGUI_9680) + if (tgui->type >= TGUI_9660) tgui->linear_base = (tgui->linear_base & 0xc00000) | (val << 24); else tgui->linear_base = (tgui->linear_base & 0xe00000) | (val << 24); @@ -916,11 +957,17 @@ void tgui_pci_write(int func, int addr, uint8_t val, void *p) break; case 0x16: - tgui->mmio_base = (tgui->mmio_base & 0xff000000) | ((val & 0xe0) << 16); + if (tgui->type >= TGUI_9660) + tgui->mmio_base = (tgui->mmio_base & 0xff000000) | ((val & 0xc0) << 16); + else + tgui->mmio_base = (tgui->mmio_base & 0xff000000) | ((val & 0xe0) << 16); tgui_recalcmapping(tgui); break; case 0x17: - tgui->mmio_base = (tgui->mmio_base & 0x00e00000) | (val << 24); + if (tgui->type >= TGUI_9660) + tgui->mmio_base = (tgui->mmio_base & 0x00c00000) | (val << 24); + else + tgui->mmio_base = (tgui->mmio_base & 0x00e00000) | (val << 24); tgui_recalcmapping(tgui); break; @@ -936,6 +983,10 @@ void tgui_pci_write(int func, int addr, uint8_t val, void *p) mem_mapping_disable(&tgui->bios_rom.mapping); } return; + + case 0x3c: + tgui->int_line = val; + return; } } @@ -1269,17 +1320,18 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } pattern_data = tgui->accel.pattern_16; } else { - for (y = 0; y < 8; y++) + for (y = 0; y < 4; y++) { for (x = 0; x < 8; x++) { tgui->accel.pattern_32[(y*8) + (7 - x)] = tgui->accel.pattern[x*4 + y*32] | (tgui->accel.pattern[x*4 + y*32 + 1] << 8) | (tgui->accel.pattern[x*4 + y*32 + 2] << 16) | (tgui->accel.pattern[x*4 + y*32 + 3] << 24); + tgui->accel.pattern_32[((y+4)*8) + (7 - x)] = tgui->accel.pattern[x*4 + y*32] | (tgui->accel.pattern[x*4 + y*32 + 1] << 8) | (tgui->accel.pattern[x*4 + y*32 + 2] << 16) | (tgui->accel.pattern[x*4 + y*32 + 3] << 24); } } pattern_data = tgui->accel.pattern_32; } } - + switch (tgui->accel.command) { case TGUI_BITBLT: @@ -1322,7 +1374,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) count >>= 3; while (count) { - if ((tgui->type == TGUI_9440) || (tgui->type >= TGUI_9680 && tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && + if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom)) { if (tgui->accel.bpp == 0) { src_dat = cpu_dat >> 24; @@ -1347,7 +1399,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) pat_dat &= 0xffff; if ((((tgui->accel.flags & (TGUI_PATMONO|TGUI_TRANSENA)) == (TGUI_TRANSENA|TGUI_PATMONO)) && (pat_dat != trans_col)) || !(tgui->accel.flags & TGUI_PATMONO) || - ((tgui->accel.flags & (TGUI_PATMONO|TGUI_TRANSENA)) == TGUI_PATMONO)) { + ((tgui->accel.flags & (TGUI_PATMONO|TGUI_TRANSENA)) == TGUI_PATMONO) || (tgui->accel.ger22 & 0x200)) { MIX(); WRITE(tgui->accel.dst, out); @@ -1357,7 +1409,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) tgui->accel.src += xdir; tgui->accel.dst += xdir; tgui->accel.pat_x += xdir; - if (tgui->type >= TGUI_9680) + if (tgui->type >= TGUI_9660) tgui->accel.dx += xdir; tgui->accel.x++; @@ -1367,7 +1419,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) tgui->accel.pat_x = tgui->accel.dst_x; tgui->accel.pat_y += ydir; - if (tgui->type >= TGUI_9680) { + if (tgui->type >= TGUI_9660) { tgui->accel.dx = tgui->accel.dst_x & 0xfff; tgui->accel.dy += ydir; } @@ -1594,7 +1646,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ if (steep) { - if ((tgui->type == TGUI_9440) || (tgui->type >= TGUI_9680 && dx >= tgui->accel.left && dx <= tgui->accel.right && + if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dx >= tgui->accel.left && dx <= tgui->accel.right && dy >= tgui->accel.top && dy <= tgui->accel.bottom)) { READ(dx + (dy * tgui->accel.pitch), dst_dat); @@ -1610,7 +1662,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) WRITE(dx + (dy * tgui->accel.pitch), out); } } else { - if ((tgui->type == TGUI_9440) || (tgui->type >= TGUI_9680 && dy >= tgui->accel.left && dy <= tgui->accel.right && + if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dy >= tgui->accel.left && dy <= tgui->accel.right && dx >= tgui->accel.top && dx <= tgui->accel.bottom)) { READ(dy + (dx * tgui->accel.pitch), dst_dat); @@ -1653,7 +1705,7 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *p) { case 0x2122: tgui->accel.ger22 = (tgui->accel.ger22 & 0xff00) | val; - switch (val) { + switch (val & 0xff) { case 4: tgui->accel.pitch = 1024; tgui->accel.bpp = 0; @@ -1661,14 +1713,14 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *p) case 8: tgui->accel.pitch = 2048; - if (tgui->type == TGUI_9680) + if (tgui->type >= TGUI_9660) tgui->accel.pitch = 1280; tgui->accel.bpp = 0; break; case 9: tgui->accel.pitch = 1024; - if (tgui->type == TGUI_9680) { + if (tgui->type >= TGUI_9660) { tgui->accel.pitch = tgui->svga.hdisp; if (tgui->svga.hdisp == 800) tgui->accel.pitch = 832; @@ -2108,7 +2160,7 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *p) if ((svga->crtc[0x36] & 0x03) == 0x02) { if ((addr & ~0xff) != 0xbff00) return; - } else if ((svga->crtc[0x36] & 0x03) == 0x01) { + } else if ((svga->crtc[0x36] & 0x03) == 0x01) { if ((addr & ~0xff) != 0xb7f00) return; } @@ -2117,7 +2169,7 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *p) { case 0x22: tgui->accel.ger22 = (tgui->accel.ger22 & 0xff00) | val; - switch (val) { + switch (val & 0xff) { case 4: tgui->accel.pitch = 1024; tgui->accel.bpp = 0; @@ -2125,14 +2177,14 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *p) case 8: tgui->accel.pitch = 2048; - if (tgui->type == TGUI_9680) + if (tgui->type >= TGUI_9660) tgui->accel.pitch = 1280; tgui->accel.bpp = 0; break; case 9: tgui->accel.pitch = 1024; - if (tgui->type == TGUI_9680) { + if (tgui->type >= TGUI_9660) { tgui->accel.pitch = tgui->svga.hdisp; if (tgui->svga.hdisp == 800) tgui->accel.pitch = 832; @@ -2695,7 +2747,7 @@ static uint16_t tgui_mmio_read_w(uint32_t addr, void *p) { tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; + svga_t *svga = &tgui->svga; uint16_t ret = 0xffff; addr &= 0x0000ffff; @@ -2736,6 +2788,7 @@ static void *tgui_init(const device_t *info) int type = info->local; tgui_t *tgui = malloc(sizeof(tgui_t)); + svga_t *svga = &tgui->svga; memset(tgui, 0, sizeof(tgui_t)); tgui->vram_size = device_get_config_int("memory") << 20; @@ -2745,15 +2798,16 @@ static void *tgui_init(const device_t *info) tgui->pci = !!(info->flags & DEVICE_PCI); - switch(info->local) { + switch(tgui->type) { case TGUI_9400CXI: bios_fn = ROM_TGUI_9400CXI; break; case TGUI_9440: bios_fn = ROM_TGUI_9440; break; + case TGUI_9660: case TGUI_9680: - bios_fn = ROM_TGUI_9680; + bios_fn = ROM_TGUI_96xx; break; default: free(tgui); @@ -2762,21 +2816,21 @@ static void *tgui_init(const device_t *info) rom_init(&tgui->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - if (info->flags & DEVICE_PCI) + if (tgui->pci) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tgui_pci); else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tgui_vlb); - svga_init(info, &tgui->svga, tgui, tgui->vram_size, + svga_init(info, svga, tgui, tgui->vram_size, tgui_recalctimings, tgui_in, tgui_out, tgui_hwcursor_draw, NULL); if (tgui->type == TGUI_9400CXI) - tgui->svga.ramdac = device_add(&tkd8001_ramdac_device); + svga->ramdac = device_add(&tkd8001_ramdac_device); - mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, tgui_accel_write_fb_b, tgui_accel_write_fb_w, tgui_accel_write_fb_l, NULL, MEM_MAPPING_EXTERNAL, &tgui->svga); + mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, tgui_accel_write_fb_b, tgui_accel_write_fb_w, tgui_accel_write_fb_l, NULL, MEM_MAPPING_EXTERNAL, svga); mem_mapping_add(&tgui->accel_mapping, 0, 0, tgui_accel_read, tgui_accel_read_w, tgui_accel_read_l, tgui_accel_write, tgui_accel_write_w, tgui_accel_write_l, NULL, MEM_MAPPING_EXTERNAL, tgui); if (tgui->type >= TGUI_9440) mem_mapping_add(&tgui->mmio_mapping, 0, 0, tgui_mmio_read, tgui_mmio_read_w, tgui_mmio_read_l, tgui_mmio_write, tgui_mmio_write_w, tgui_mmio_write_l, NULL, MEM_MAPPING_EXTERNAL, tgui); @@ -2786,7 +2840,7 @@ static void *tgui_init(const device_t *info) tgui_set_io(tgui); if (tgui->pci && (tgui->type >= TGUI_9440)) - pci_add_card(PCI_ADD_VIDEO, tgui_pci_read, tgui_pci_write, tgui); + tgui->card = pci_add_card(PCI_ADD_VIDEO, tgui_pci_read, tgui_pci_write, tgui); tgui->pci_regs[PCI_REG_COMMAND] = 3; @@ -2794,10 +2848,13 @@ static void *tgui_init(const device_t *info) tgui->pci_regs[0x32] = 0x0c; tgui->pci_regs[0x33] = 0x00; - tgui->int_line = 0; - if (tgui->type >= TGUI_9440) - tgui->svga.packed_chain4 = 1; + svga->packed_chain4 = 1; + + if (tgui->type >= TGUI_9660) { + tgui->i2c = i2c_gpio_init("ddc_tgui"); + tgui->ddc = ddc_init(i2c_gpio_get_bus(tgui->i2c)); + } return tgui; } @@ -2814,7 +2871,7 @@ static int tgui9440_available(void) static int tgui96xx_available(void) { - return rom_present(ROM_TGUI_9680); + return rom_present(ROM_TGUI_96xx); } void tgui_close(void *p) @@ -2823,6 +2880,11 @@ void tgui_close(void *p) svga_close(&tgui->svga); + if (tgui->type >= TGUI_9660) { + ddc_close(tgui->ddc); + i2c_gpio_close(tgui->i2c); + } + free(tgui); } @@ -2941,6 +3003,20 @@ const device_t tgui9440_pci_device = tgui9440_config }; +const device_t tgui9660_pci_device = +{ + "Trident TGUI 9660XGi PCI", + DEVICE_PCI, + TGUI_9660, + tgui_init, + tgui_close, + NULL, + { tgui96xx_available }, + tgui_speed_changed, + tgui_force_redraw, + tgui96xx_config +}; + const device_t tgui9680_pci_device = { "Trident TGUI 9680XGi PCI", diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index ad89b88e8..36420aeab 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -159,9 +159,15 @@ void tvga_out(uint16_t addr, uint8_t val, void *p) val &= crtc_mask[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; if (old != val) { - if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) + { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + 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); + } } } switch (svga->crtcreg) { diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index ad45fbb1c..519b86923 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -976,12 +976,18 @@ void *voodoo_card_init() voodoo->render_not_full_event[1] = thread_create_event(); voodoo->render_not_full_event[2] = thread_create_event(); voodoo->render_not_full_event[3] = thread_create_event(); + voodoo->fifo_thread_run = 1; voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo); + voodoo->render_thread_run[0] = 1; voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo); - if (voodoo->render_threads >= 2) + if (voodoo->render_threads >= 2) { + voodoo->render_thread_run[1] = 1; voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo); + } if (voodoo->render_threads == 4) { + voodoo->render_thread_run[2] = 1; voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo); + voodoo->render_thread_run[3] = 1; voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo); } voodoo->swap_mutex = thread_create_mutex(); @@ -1094,12 +1100,18 @@ void *voodoo_2d3d_card_init(int type) voodoo->render_not_full_event[1] = thread_create_event(); voodoo->render_not_full_event[2] = thread_create_event(); voodoo->render_not_full_event[3] = thread_create_event(); + voodoo->fifo_thread_run = 1; voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo); + voodoo->render_thread_run[0] = 1; voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo); - if (voodoo->render_threads >= 2) + if (voodoo->render_threads >= 2) { + voodoo->render_thread_run[1] = 1; voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo); + } if (voodoo->render_threads == 4) { + voodoo->render_thread_run[2] = 1; voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo); + voodoo->render_thread_run[3] = 1; voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo); } voodoo->swap_mutex = thread_create_mutex(); @@ -1243,13 +1255,24 @@ void voodoo_card_close(voodoo_t *voodoo) #endif */ - thread_kill(voodoo->fifo_thread); - thread_kill(voodoo->render_thread[0]); - if (voodoo->render_threads >= 2) - thread_kill(voodoo->render_thread[1]); + voodoo->fifo_thread_run = 0; + thread_set_event(voodoo->wake_fifo_thread); + thread_wait(voodoo->fifo_thread, -1); + voodoo->render_thread_run[0] = 0; + thread_set_event(voodoo->wake_render_thread[0]); + thread_wait(voodoo->render_thread[0], -1); + if (voodoo->render_threads >= 2) { + voodoo->render_thread_run[1] = 0; + thread_set_event(voodoo->wake_render_thread[1]); + thread_wait(voodoo->render_thread[1], -1); + } if (voodoo->render_threads == 4) { - thread_kill(voodoo->render_thread[2]); - thread_kill(voodoo->render_thread[3]); + voodoo->render_thread_run[2] = 0; + thread_set_event(voodoo->wake_render_thread[2]); + thread_wait(voodoo->render_thread[2], -1); + voodoo->render_thread_run[3] = 0; + thread_set_event(voodoo->wake_render_thread[3]); + thread_wait(voodoo->render_thread[3], -1); } thread_destroy_event(voodoo->fifo_not_full_event); thread_destroy_event(voodoo->wake_main_thread); diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 8a3808322..55ff77909 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -329,8 +329,13 @@ static void banshee_out(uint16_t addr, uint8_t val, void *p) } if (svga->crtcreg < 0xe || svga->crtcreg > 0x11 || (svga->crtcreg == 0x11 && old != val)) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + 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); + } } } break; diff --git a/src/video/vid_voodoo_fifo.c b/src/video/vid_voodoo_fifo.c index 9e1f9c61f..f36bd18d4 100644 --- a/src/video/vid_voodoo_fifo.c +++ b/src/video/vid_voodoo_fifo.c @@ -204,7 +204,7 @@ void voodoo_fifo_thread(void *param) { voodoo_t *voodoo = (voodoo_t *)param; - while (1) + while (voodoo->fifo_thread_run) { thread_set_event(voodoo->fifo_not_full_event); thread_wait_event(voodoo->wake_fifo_thread, -1); diff --git a/src/video/vid_voodoo_render.c b/src/video/vid_voodoo_render.c index c37956853..751c91d09 100644 --- a/src/video/vid_voodoo_render.c +++ b/src/video/vid_voodoo_render.c @@ -1605,7 +1605,7 @@ static void render_thread(void *param, int odd_even) { voodoo_t *voodoo = (voodoo_t *)param; - while (1) + while (voodoo->render_thread_run[odd_even]) { thread_set_event(voodoo->render_not_full_event[odd_even]); thread_wait_event(voodoo->wake_render_thread[odd_even], -1); diff --git a/src/video/video.c b/src/video/video.c index b484d14d6..be8963706 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -113,6 +113,7 @@ int video_graytype = 0; static int vid_type; static const video_timings_t *vid_timings; static uint32_t cga_2_table[16]; +static uint8_t thread_run = 0; PALETTE cgapal = { @@ -430,7 +431,7 @@ void blit_thread(void *param) { int yy; - while (1) { + 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"); @@ -880,6 +881,7 @@ video_init(void) blit_data.wake_blit_thread = thread_create_event(); blit_data.blit_complete = thread_create_event(); blit_data.buffer_not_in_use = thread_create_event(); + thread_run = 1; blit_data.blit_thread = thread_create(blit_thread, NULL); } @@ -887,7 +889,9 @@ video_init(void) void video_close(void) { - thread_kill(blit_data.blit_thread); + thread_run = 0; + thread_set_event(blit_data.wake_blit_thread); + thread_wait(blit_data.blit_thread, -1); thread_destroy_event(blit_data.buffer_not_in_use); thread_destroy_event(blit_data.blit_complete); thread_destroy_event(blit_data.wake_blit_thread); diff --git a/src/win/win_discord.c b/src/win/win_discord.c index 27a75eedf..73d15855d 100644 --- a/src/win/win_discord.c +++ b/src/win/win_discord.c @@ -68,7 +68,8 @@ void discord_update_activity(int paused) { struct DiscordActivity activity; - char config_name[1024]; + char config_name[1024], cpufamily[1024]; + char *paren; if(discord_activities == NULL) return; @@ -78,15 +79,21 @@ discord_update_activity(int paused) memset(&activity, 0x00, sizeof(activity)); plat_get_dirname(config_name, usr_path); + + strncpy(cpufamily, cpu_f->name, sizeof(cpufamily) - 1); + paren = strchr(cpufamily, '('); + if (paren) + *(paren - 1) = '\0'; + if (strlen(plat_get_filename(config_name)) < 100) { sprintf_s(activity.details, sizeof(activity.details), "Running \"%s\"", plat_get_filename(config_name)); - sprintf_s(activity.state, sizeof(activity.state), "%s (%s)", strchr(machine_getname(), ']') + 2, cpu_s->name); + sprintf_s(activity.state, sizeof(activity.state), "%s (%s/%s)", strchr(machine_getname(), ']') + 2, cpufamily, cpu_s->name); } else { strncpy(activity.details, strchr(machine_getname(), ']') + 2, sizeof(activity.details) - 1); - strncpy(activity.state, cpu_s->name, sizeof(activity.state) - 1); + sprintf_s(activity.state, sizeof(activity.state), "%s/%s", cpufamily, cpu_s->name); } activity.timestamps.start = time(NULL); diff --git a/src/win/win_thread.c b/src/win/win_thread.c index 1d4ae0d32..f8d81fa86 100644 --- a/src/win/win_thread.c +++ b/src/win/win_thread.c @@ -44,15 +44,6 @@ thread_create(void (*func)(void *param), void *param) } -void -thread_kill(void *arg) -{ - if (arg == NULL) return; - - TerminateThread(arg, 0); -} - - int thread_wait(thread_t *arg, int timeout) { diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 0c74499a9..3773d369c 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -1032,10 +1032,21 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) MoveWindow(hwndRender, 0, 0, rect.right, rect.bottom - sbar_height, TRUE); GetClientRect(hwndRender, &rect); - if (rect.right != scrnsz_x || rect.bottom != scrnsz_y) { - scrnsz_x = rect.right; - scrnsz_y = rect.bottom; - doresize = 1; + if (dpi_scale) { + temp_x = MulDiv(rect.right, 96, dpi); + temp_y = MulDiv(rect.bottom, 96, dpi); + + if (temp_x != scrnsz_x || temp_y != scrnsz_y) { + scrnsz_x = temp_x; + scrnsz_y = temp_y; + doresize = 1; + } + } else { + if (rect.right != scrnsz_x || rect.bottom != scrnsz_y) { + scrnsz_x = rect.right; + scrnsz_y = rect.bottom; + doresize = 1; + } } plat_vidsize(rect.right, rect.bottom);