diff --git a/src/chipset/scat.c b/src/chipset/scat.c index 731ceec08..9825dc057 100644 --- a/src/chipset/scat.c +++ b/src/chipset/scat.c @@ -80,7 +80,6 @@ typedef struct scat_t { ems_page_t null_page, page[32]; mem_mapping_t low_mapping[32]; - mem_mapping_t high_mapping[16]; mem_mapping_t remap_mapping[6]; mem_mapping_t efff_mapping[44]; mem_mapping_t ems_mapping[32]; @@ -117,35 +116,30 @@ shadow_state_update(scat_t *dev) { int i, val; - uint32_t base, bit, romcs, wp, shflags = 0; + uint32_t base, bit, romcs, shflags = 0; shadowbios = shadowbios_write = 0; for (i = 0; i < 24; i++) { - val = (dev->regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1; + if ((dev->regs[SCAT_DRAM_CONFIGURATION] & 0xf) < 4) + val = 0; + else + val = (dev->regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1; base = 0xa0000 + (i << 14); bit = (base - 0xc0000) >> 15; romcs = 0; - wp = 0; - if (base >= 0xc0000) { + if (base >= 0xc0000) romcs = dev->regs[SCAT_ROM_ENABLE] & (1 << bit); - wp = dev->regs[SCAT_RAM_WRITE_PROTECT] & (1 << bit); - } - if (base >= 0xe0000) { shadowbios |= val; shadowbios_write |= val; } shflags = val ? MEM_READ_INTERNAL : (romcs ? MEM_READ_EXTANY : MEM_READ_EXTERNAL); - - if (wp) - shflags |= MEM_WRITE_DISABLED; - else - shflags |= (val ? MEM_WRITE_INTERNAL : (romcs ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL)); + shflags |= (val ? MEM_WRITE_INTERNAL : (romcs ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL)); mem_set_mem_state(base, 0x4000, shflags); } @@ -257,9 +251,9 @@ set_xms_bound(scat_t *dev, uint8_t val) if (dev->regs[SCAT_VERSION] & 0xf0) { for (i = 0; i < 8; i++) { if (val & 0x10) - mem_mapping_disable(&dev->high_mapping[i]); + mem_mapping_disable(&bios_high_mapping); else - mem_mapping_enable(&dev->high_mapping[i]); + mem_mapping_enable(&bios_high_mapping); } } } @@ -946,21 +940,21 @@ memmap_state_update(scat_t *dev) int i; for (i = (((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? 0 : 16); i < 44; i++) { - addr = get_addr(dev, 0x40000 + (i << 14), NULL); + addr = get_addr(dev, 0x40000 + (i << 14), &dev->null_page); mem_mapping_set_exec(&dev->efff_mapping[i], addr < ((uint32_t)mem_size << 10) ? ram + addr : NULL); } - addr = get_addr(dev, 0, NULL); + addr = get_addr(dev, 0, &dev->null_page); mem_mapping_set_exec(&dev->low_mapping[0], addr < ((uint32_t)mem_size << 10) ? ram + addr : NULL); - addr = get_addr(dev, 0xf0000, NULL); + addr = get_addr(dev, 0xf0000, &dev->null_page); mem_mapping_set_exec(&dev->low_mapping[1], addr < ((uint32_t)mem_size << 10) ? ram + addr : NULL); for (i = 2; i < 32; i++) { - addr = get_addr(dev, i << 19, NULL); + addr = get_addr(dev, i << 19, &dev->null_page); mem_mapping_set_exec(&dev->low_mapping[i], addr < ((uint32_t)mem_size << 10) ? ram + addr : NULL); } @@ -1002,7 +996,7 @@ memmap_state_update(scat_t *dev) mem_mapping_disable(&dev->low_mapping[2]); for (i = 0; i < 6; i++) { - addr = get_addr(dev, 0x100000 + (i << 16), NULL); + addr = get_addr(dev, 0x100000 + (i << 16), &dev->null_page); mem_mapping_set_exec(&dev->remap_mapping[i], addr < ((uint32_t)mem_size << 10) ? ram + addr : NULL); mem_mapping_enable(&dev->remap_mapping[i]); @@ -1333,23 +1327,13 @@ static void mem_write_scatb(uint32_t addr, uint8_t val, void *priv) { ems_page_t *page = (ems_page_t *)priv; - scat_t *dev; + scat_t *dev = (scat_t *)page->scat; uint32_t oldaddr = addr, chkaddr; - if (page == NULL) - dev = NULL; - else - dev = (scat_t *)page->scat; - - if (dev == NULL) - chkaddr = oldaddr; - else { - addr = get_addr(dev, addr, page); - chkaddr = addr; - } - - if (chkaddr >= 0xc0000 && chkaddr < 0x100000) { - if ((dev == NULL) || (dev->regs[SCAT_RAM_WRITE_PROTECT] & (1 << ((chkaddr - 0xc0000) >> 15)))) + addr = get_addr(dev, addr, page); + chkaddr = page->valid ? addr : oldaddr; + if ((chkaddr >= 0xc0000) && (chkaddr < 0x100000)) { + if (dev->regs[SCAT_RAM_WRITE_PROTECT] & (1 << ((chkaddr - 0xc0000) >> 15))) return; } @@ -1362,23 +1346,13 @@ static void mem_write_scatw(uint32_t addr, uint16_t val, void *priv) { ems_page_t *page = (ems_page_t *)priv; - scat_t *dev; + scat_t *dev = (scat_t *)page->scat; uint32_t oldaddr = addr, chkaddr; - if (page == NULL) - dev = NULL; - else - dev = (scat_t *)page->scat; - - if (dev == NULL) - chkaddr = oldaddr; - else { - addr = get_addr(dev, addr, page); - chkaddr = addr; - } - - if (chkaddr >= 0xc0000 && chkaddr < 0x100000) { - if (dev != NULL && (dev->regs[SCAT_RAM_WRITE_PROTECT] & (1 << ((chkaddr - 0xc0000) >> 15)))) + addr = get_addr(dev, addr, page); + chkaddr = page->valid ? addr : oldaddr; + if ((chkaddr >= 0xc0000) && (chkaddr < 0x100000)) { + if (dev->regs[SCAT_RAM_WRITE_PROTECT] & (1 << ((chkaddr - 0xc0000) >> 15))) return; } @@ -1391,23 +1365,13 @@ static void mem_write_scatl(uint32_t addr, uint32_t val, void *priv) { ems_page_t *page = (ems_page_t *)priv; - scat_t *dev; + scat_t *dev = (scat_t *)page->scat; uint32_t oldaddr = addr, chkaddr; - if (page == NULL) - dev = NULL; - else - dev = (scat_t *)page->scat; - - if (dev == NULL) - chkaddr = oldaddr; - else { - addr = get_addr(dev, addr, page); - chkaddr = addr; - } - - if (chkaddr >= 0xc0000 && chkaddr < 0x100000) { - if (dev != NULL && (dev->regs[SCAT_RAM_WRITE_PROTECT] & (1 << ((chkaddr - 0xc0000) >> 15)))) + addr = get_addr(dev, addr, page); + chkaddr = page->valid ? addr : oldaddr; + if ((chkaddr >= 0xc0000) && (chkaddr < 0x100000)) { + if (dev->regs[SCAT_RAM_WRITE_PROTECT] & (1 << ((chkaddr - 0xc0000) >> 15))) return; } @@ -1481,9 +1445,6 @@ scat_init(const device_t *info) if (! sx) mem_mapping_disable(&ram_mid_mapping); mem_mapping_disable(&ram_high_mapping); -#if 0 - mem_mapping_disable(&bios_mapping); -#endif k = (sx) ? 0x80000 : 0x40000; @@ -1541,14 +1502,6 @@ scat_init(const device_t *info) ram + ((i + 28) << 14), 0, &dev->page[i]); mem_mapping_disable(&dev->ems_mapping[i]); } - - for (i = 0; i < 16; i++) { - mem_mapping_add(&dev->high_mapping[i], (i << 14) + 0xfc0000, 0x04000, - bios_read, bios_readw, bios_readl, - NULL, NULL, NULL, - rom + ((i << 14) & biosmask), 0, NULL); - mem_mapping_enable(&dev->high_mapping[i]); - } } else { for (i = 0; i < 32; i++) { dev->page[i].valid = 1; @@ -1561,21 +1514,13 @@ scat_init(const device_t *info) ram + ((i + (i >= 24 ? 28 : 16)) << 14), 0, &dev->page[i]); } - - for (i = (dev->regs[SCAT_VERSION] < 4 ? 0 : 8); i < 16; i++) { - mem_mapping_add(&dev->high_mapping[i], (i << 14) + 0xfc0000, 0x04000, - bios_read, bios_readw, bios_readl, - NULL, NULL, NULL, - rom + ((i << 14) & biosmask), 0, NULL); - mem_mapping_enable(&dev->high_mapping[i]); - } } for (i = 0; i < 6; i++) { mem_mapping_add(&dev->remap_mapping[i], 0x100000 + (i << 16), 0x10000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, - mem_size >= 1024 ? ram + get_addr(dev, 0x100000 + (i << 16), NULL) : NULL, + mem_size >= 1024 ? ram + get_addr(dev, 0x100000 + (i << 16), &dev->null_page) : NULL, MEM_MAPPING_INTERNAL, &dev->null_page); } diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index de8c5a028..379606c25 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -119,7 +119,6 @@ int isa_cycles, cpu_inited, timing_iret_pm_outer, timing_call_rm, timing_call_pm, timing_call_pm_gate, timing_call_pm_gate_inner, timing_retf_rm, timing_retf_pm, timing_retf_pm_outer, timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate, timing_misaligned; - uint32_t cpu_features, cpu_fast_off_flags; uint64_t cpu_CR4_mask, tsc = 0; @@ -143,7 +142,8 @@ void (*cpu_exec)(int cycs); static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6; -static int cyrix_addr; +static int cyrix_addr, cpu_rom_read_cycles = 4; +static uint64_t rom_read_timing_ns = 150; static void cpu_write(uint16_t addr, uint8_t val, void *priv); @@ -407,10 +407,7 @@ cpu_set(void) isa_cycles = cpu_s->atclk_div; - if (cpu_s->rspeed <= 8000000) - cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; - else - cpu_rom_prefetch_cycles = cpu_s->rspeed / 1000000; + cpu_rom_prefetch_cycles = (cpu_rom_read_cycles * cpu_s->rspeed * rom_read_timing_ns + 999999999ULL) / 1000000000ULL; cpu_set_isa_pci_div(0); cpu_set_pci_speed(0); @@ -3072,6 +3069,5 @@ cpu_update_waitstates(void) cpu_mem_prefetch_cycles = cpu_prefetch_cycles; - if (cpu_s->rspeed <= 8000000) - cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; + cpu_rom_prefetch_cycles = (cpu_rom_read_cycles * cpu_s->rspeed * rom_read_timing_ns + 999999999ULL) / 1000000000ULL; } diff --git a/src/cpu/x86.c b/src/cpu/x86.c index 9ab8ce169..539cea550 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -251,11 +251,12 @@ reset_common(int hard) } } idt.base = 0; - idt.limit = is386 ? 0x03FF : 0xFFFF; cpu_state.flags = 2; trap = 0; - EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; + idt.limit = is386 ? 0x03ff : 0xffff; + if (is386 || hard) + EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; if (hard) { makeznptable(); diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 59b08de59..b00a53c36 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -97,8 +97,8 @@ typedef struct { uint8_t command, status, old_status, out, old_out, secr_phase, mem_addr, input_port, output_port, old_output_port, - key_command, output_locked, ami_stat, initialized, - want60, wantirq, key_wantdata, refresh, first_write; + key_command, output_locked, ami_stat, want60, + wantirq, key_wantdata, refresh, first_write; uint8_t mem[0x100]; @@ -1031,8 +1031,12 @@ add_data_kbd(uint16_t val) static void write_output(atkbd_t *dev, uint8_t val) { + uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; kbd_log("ATkbc: write output port: %02X (old: %02X)\n", val, dev->output_port); + if ((kbc_ven == KBC_VEN_AMI) || ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)) + val |= ((dev->mem[0] << 4) & 0x30); + if ((dev->output_port ^ val) & 0x20) { /*IRQ 12*/ if (val & 0x20) picint(1 << 12); @@ -1066,9 +1070,8 @@ write_output(atkbd_t *dev, uint8_t val) static void write_cmd(atkbd_t *dev, uint8_t val) { + uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; kbd_log("ATkbc: write command byte: %02X (old: %02X)\n", val, dev->mem[0]); - uint8_t kbc_ven = 0x0; - kbc_ven = dev->flags & KBC_VEN_MASK; if ((val & 1) && (dev->status & STAT_OFULL)) dev->wantirq = 1; @@ -1093,11 +1096,15 @@ write_cmd(atkbd_t *dev, uint8_t val) if ((kbc_ven == KBC_VEN_AMI) || ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)) { keyboard_mode &= ~CCB_PCMODE; + /* Update the output port to mirror the KBD DIS and AUX DIS bits, if active. */ + write_output(dev, dev->output_port); kbd_log("ATkbc: mouse interrupt is now %s\n", (val & 0x02) ? "enabled" : "disabled"); } kbd_log("Command byte now: %02X (%02X)\n", dev->mem[0], val); + + dev->status = (dev->status & ~STAT_SYSFLAG) | (val & STAT_SYSFLAG); } @@ -1665,12 +1672,9 @@ static void kbd_write(uint16_t port, uint8_t val, void *priv) { atkbd_t *dev = (atkbd_t *)priv; - int i = 0; - int bad = 1; - uint8_t mask; - uint8_t kbc_ven = 0x0; - kbc_ven = dev->flags & KBC_VEN_MASK; - + int i = 0, bad = 1; + uint8_t mask, kbc_ven = 0x0; + kbc_ven = dev->flags & KBC_VEN_MASK; if ((kbc_ven == KBC_VEN_XI8088) && (port == 0x63)) port = 0x61; @@ -1986,23 +1990,22 @@ kbd_write(uint16_t port, uint8_t val, void *priv) kbd_log("ATkbc: self-test\n"); if ((kbc_ven == KBC_VEN_TOSHIBA) || (kbc_ven == KBC_VEN_SAMSUNG)) dev->status |= STAT_IFULL; - if (! dev->initialized) { - kbd_log("ATkbc: self-test reinitialization\n"); - dev->initialized = 1; - dev->out_new = dev->out_delayed = -1; - for (i = 0; i < 3; i++) - kbc_queue_reset(i); - kbd_last_scan_code = 0x00; - dev->status &= ~STAT_OFULL; - dev->last_irq = dev->old_last_irq = 0; - } - dev->status |= STAT_SYSFLAG; - dev->mem[0] |= 0x04; - keyboard_mode |= 0x04; - set_enable_kbd(dev, 1); + write_output(dev, ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 0x4b : 0xcf); + + /* Always reinitialize all queues - the real hardware pulls keyboard and mouse + clocks high, which stops keyboard scanning. */ + kbd_log("ATkbc: self-test reinitialization\n"); + dev->out_new = dev->out_delayed = -1; + for (i = 0; i < 3; i++) + kbc_queue_reset(i); + kbd_last_scan_code = 0x00; + dev->status &= ~STAT_OFULL; + dev->last_irq = dev->old_last_irq = 0; + if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) - set_enable_mouse(dev, 1); - write_output(dev, 0xcf); + write_cmd(dev, 0x30 | STAT_SYSFLAG); + else + write_cmd(dev, 0x10 | STAT_SYSFLAG); add_data(dev, 0x55); break; @@ -2206,7 +2209,6 @@ kbd_reset(void *priv) uint8_t kbc_ven = 0x0; kbc_ven = dev->flags & KBC_VEN_MASK; - dev->initialized = 0; dev->first_write = 1; // dev->status = STAT_UNLOCKED | STAT_CD; dev->status = STAT_UNLOCKED;