diff --git a/src/acpi.c b/src/acpi.c index d74cf20f4..26855a743 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -61,16 +61,16 @@ acpi_update_irq(void *priv) acpi_t *dev = (acpi_t *) priv; int sci_level; - sci_level = (dev->pmsts & dev->pmen) & (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN); + sci_level = (dev->regs.pmsts & dev->regs.pmen) & (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN); if (sci_level) { - if (dev->irq_mode == 1) - pci_set_irq(dev->slot, dev->irq_pin); + if (dev->regs.irq_mode == 1) + pci_set_irq(dev->regs.slot, dev->regs.irq_pin); else picintlevel(1 << 9); } else { - if (dev->irq_mode == 1) - pci_clear_irq(dev->slot, dev->irq_pin); + if (dev->regs.irq_mode == 1) + pci_clear_irq(dev->regs.slot, dev->regs.irq_pin); else picintc(1 << 9); } @@ -91,82 +91,80 @@ acpi_reg_read_common(int size, uint16_t addr, void *p) switch (addr) { case 0x00: case 0x01: /* PMSTS - Power Management Status Register (IO) */ - ret = (dev->pmsts >> shift16) & 0xff; + ret = (dev->regs.pmsts >> shift16) & 0xff; break; case 0x02: case 0x03: /* PMEN - Power Management Resume Enable Register (IO) */ - ret = (dev->pmen >> shift16) & 0xff; + ret = (dev->regs.pmen >> shift16) & 0xff; break; case 0x04: case 0x05: /* PMCNTRL - Power Management Control Register (IO) */ - ret = (dev->pmcntrl >> shift16) & 0xff; + ret = (dev->regs.pmcntrl >> shift16) & 0xff; break; case 0x08: case 0x09: case 0x0a: case 0x0b: /* PMTMR - Power Management Timer Register (IO) */ - ret = (dev->timer_val >> shift32) & 0xff; + ret = (dev->regs.timer_val >> shift32) & 0xff; break; case 0x0c: case 0x0d: /* GPSTS - General Purpose Status Register (IO) */ - ret = (dev->gpsts >> shift16) & 0xff; + ret = (dev->regs.gpsts >> shift16) & 0xff; break; case 0x0e: case 0x0f: /* GPEN - General Purpose Enable Register (IO) */ - ret = (dev->gpen >> shift16) & 0xff; + ret = (dev->regs.gpen >> shift16) & 0xff; break; case 0x10: case 0x11: case 0x12: case 0x13: /* PCNTRL - Processor Control Register (IO) */ - ret = (dev->pcntrl >> shift32) & 0xff; + ret = (dev->regs.pcntrl >> shift32) & 0xff; break; case 0x14: /* PLVL2 - Processor Level 2 Register (IO) */ if (size == 1) - ret = dev->plvl2; + ret = dev->regs.plvl2; break; case 0x15: /* PLVL3 - Processor Level 3 Register (IO) */ if (size == 1) - ret = dev->plvl3; + ret = dev->regs.plvl3; break; case 0x18: case 0x19: /* GLBSTS - Global Status Register (IO) */ - ret = (dev->glbsts >> shift16) & 0xff; + ret = (dev->regs.glbsts >> shift16) & 0xff; if (addr == 0x18) { - ret &= 0x05; - if (dev->gpsts != 0x0000) + ret &= 0x25; + if (dev->regs.gpsts != 0x0000) ret |= 0x80; - if (dev->pmsts != 0x0000) + if (dev->regs.pmsts != 0x0000) ret |= 0x40; - if (in_smm) - ret |= 0x20; - if (dev->devsts != 0x00000000) + if (dev->regs.devsts != 0x00000000) ret |= 0x10; } break; case 0x1c: case 0x1d: case 0x1e: case 0x1f: /* DEVSTS - Device Status Register (IO) */ - ret = ((dev->devsts | 0x10000000) >> shift32) & 0xff; + ret = (dev->regs.devsts >> shift32) & 0xff; break; case 0x20: case 0x21: /* GLBEN - Global Enable Register (IO) */ - ret = (dev->glben >> shift16) & 0xff; + ret = (dev->regs.glben >> shift16) & 0xff; break; case 0x28: case 0x29: case 0x2a: case 0x2b: /* GLBCTL - Global Control Register (IO) */ - ret = (dev->glbctl >> shift32) & 0xff; + ret = (dev->regs.glbctl >> shift32) & 0xff; break; case 0x2c: case 0x2d: case 0x2e: case 0x2f: /* DEVCTL - Device Control Register (IO) */ - ret = (dev->devctl >> shift32) & 0xff; + ret = (dev->regs.devctl >> shift32) & 0xff; break; case 0x30: case 0x31: case 0x32: /* GPIREG - General Purpose Input Register (IO) */ if (size == 1) - ret = dev->gpireg[addr & 3]; + ret = dev->regs.gpireg[addr & 3]; break; case 0x34: case 0x35: case 0x36: case 0x37: /* GPOREG - General Purpose Output Register (IO) */ if (size == 1) - ret = dev->gporeg[addr & 3]; + ret = dev->regs.gporeg[addr & 3]; break; } @@ -190,19 +188,19 @@ acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *p) switch (addr) { case 0x00: case 0x01: /* PMSTS - Power Management Status Register (IO) */ - dev->pmsts &= ~((val << shift16) & 0x8d31); + dev->regs.pmsts &= ~((val << shift16) & 0x8d31); acpi_update_irq(dev); break; case 0x02: case 0x03: /* PMEN - Power Management Resume Enable Register (IO) */ - dev->pmen = ((dev->pmen & ~(0xff << shift16)) | (val << shift16)) & 0x0521; + dev->regs.pmen = ((dev->regs.pmen & ~(0xff << shift16)) | (val << shift16)) & 0x0521; acpi_update_irq(dev); break; case 0x04: case 0x05: /* PMCNTRL - Power Management Control Register (IO) */ - dev->pmcntrl = ((dev->pmcntrl & ~(0xff << shift16)) | (val << shift16)) & 0x3c07; - if (dev->pmcntrl & 0x2000) { - sus_typ = (dev->pmcntrl >> 10) & 7; + dev->regs.pmcntrl = ((dev->regs.pmcntrl & ~(0xff << shift16)) | (val << shift16)) & 0x3c07; + if (dev->regs.pmcntrl & 0x2000) { + sus_typ = (dev->regs.pmcntrl >> 10) & 7; switch (sus_typ) { case 0: /* Soft power off. */ @@ -232,51 +230,51 @@ acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *p) break; case 0x0c: case 0x0d: /* GPSTS - General Purpose Status Register (IO) */ - dev->gpsts &= ~((val << shift16) & 0x0f81); + dev->regs.gpsts &= ~((val << shift16) & 0x0f81); break; case 0x0e: case 0x0f: /* GPEN - General Purpose Enable Register (IO) */ - dev->gpen = ((dev->gpen & ~(0xff << shift16)) | (val << shift16)) & 0x0f01; + dev->regs.gpen = ((dev->regs.gpen & ~(0xff << shift16)) | (val << shift16)) & 0x0f01; break; case 0x10: case 0x11: case 0x12: case 0x13: /* PCNTRL - Processor Control Register (IO) */ - dev->pcntrl = ((dev->pcntrl & ~(0xff << shift32)) | (val << shift32)) & 0x00023e1e; + dev->regs.pcntrl = ((dev->regs.pcntrl & ~(0xff << shift32)) | (val << shift32)) & 0x00023e1e; break; case 0x14: /* PLVL2 - Processor Level 2 Register (IO) */ if (size == 1) - dev->plvl2 = val; + dev->regs.plvl2 = val; break; case 0x15: /* PLVL3 - Processor Level 3 Register (IO) */ if (size == 1) - dev->plvl3 = val; + dev->regs.plvl3 = val; break; case 0x18: case 0x19: /* GLBSTS - Global Status Register (IO) */ - dev->glbsts &= ~((val << shift16) & 0x0df7); + dev->regs.glbsts &= ~((val << shift16) & 0x0df7); break; case 0x1c: case 0x1d: case 0x1e: case 0x1f: /* DEVSTS - Device Status Register (IO) */ - dev->devsts &= ~((val << shift32) & 0x3fff0fff); + dev->regs.devsts &= ~((val << shift32) & 0x3fff0fff); break; case 0x20: case 0x21: /* GLBEN - Global Enable Register (IO) */ - dev->glben = ((dev->glben & ~(0xff << shift16)) | (val << shift16)) & 0x8d1f; + dev->regs.glben = ((dev->regs.glben & ~(0xff << shift16)) | (val << shift16)) & 0x8d1f; break; case 0x28: case 0x29: case 0x2a: case 0x2b: /* GLBCTL - Global Control Register (IO) */ - // dev->glbctl = ((dev->glbctl & ~(0xff << shift32)) | (val << shift32)) & 0x0701ff07; - dev->glbctl = ((dev->glbctl & ~(0xff << shift32)) | (val << shift32)) & 0x0700ff07; + // dev->regs.glbctl = ((dev->regs.glbctl & ~(0xff << shift32)) | (val << shift32)) & 0x0701ff07; + dev->regs.glbctl = ((dev->regs.glbctl & ~(0xff << shift32)) | (val << shift32)) & 0x0700ff07; break; case 0x2c: case 0x2d: case 0x2e: case 0x2f: /* DEVCTL - Device Control Register (IO) */ - dev->devctl = ((dev->devctl & ~(0xff << shift32)) | (val << shift32)) & 0x0fffffff; + dev->regs.devctl = ((dev->regs.devctl & ~(0xff << shift32)) | (val << shift32)) & 0x0fffffff; break; case 0x34: case 0x35: case 0x36: case 0x37: /* GPOREG - General Purpose Output Register (IO) */ if (size == 1) - dev->gporeg[addr & 3] = val; + dev->regs.gporeg[addr & 3] = val; break; } } @@ -351,16 +349,16 @@ acpi_reg_write(uint16_t addr, uint8_t val, void *p) void acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en) { - if (dev->io_base != 0x0000) { - io_removehandler(dev->io_base, 0x40, + if (dev->regs.io_base != 0x0000) { + io_removehandler(dev->regs.io_base, 0x40, acpi_reg_read, acpi_reg_readw, acpi_reg_readl, acpi_reg_write, acpi_reg_writew, acpi_reg_writel, dev); } - dev->io_base = base; + dev->regs.io_base = base; - if (chipset_en && (dev->io_base != 0x0000)) { - io_sethandler(dev->io_base, 0x40, + if (chipset_en && (dev->regs.io_base != 0x0000)) { + io_sethandler(dev->regs.io_base, 0x40, acpi_reg_read, acpi_reg_readw, acpi_reg_readl, acpi_reg_write, acpi_reg_writew, acpi_reg_writel, dev); } @@ -374,18 +372,18 @@ acpi_timer_count(void *priv) int overflow; uint32_t old; - old = dev->timer_val; - dev->timer_val++; + old = dev->regs.timer_val; + dev->regs.timer_val++; - if (dev->timer32) - overflow = (old ^ dev->timer_val) & 0x80000000; + if (dev->regs.timer32) + overflow = (old ^ dev->regs.timer_val) & 0x80000000; else { - dev->timer_val &= 0x00ffffff; - overflow = (old ^ dev->timer_val) & 0x00800000; + dev->regs.timer_val &= 0x00ffffff; + overflow = (old ^ dev->regs.timer_val) & 0x00800000; } if (overflow) { - dev->pmsts |= TMROF_EN; + dev->regs.pmsts |= TMROF_EN; acpi_update_irq(dev); } @@ -396,42 +394,42 @@ acpi_timer_count(void *priv) void acpi_init_gporeg(acpi_t *dev, uint8_t val0, uint8_t val1, uint8_t val2, uint8_t val3) { - dev->gporeg[0] = val0; - dev->gporeg[1] = val1; - dev->gporeg[2] = val2; - dev->gporeg[3] = val3; - acpi_log("acpi_init_gporeg(): %02X %02X %02X %02X\n", dev->gporeg[0], dev->gporeg[1], dev->gporeg[2], dev->gporeg[3]); + dev->regs.gporeg[0] = dev->gporeg_default[0] = val0; + dev->regs.gporeg[1] = dev->gporeg_default[1] = val1; + dev->regs.gporeg[2] = dev->gporeg_default[2] = val2; + dev->regs.gporeg[3] = dev->gporeg_default[3] = val3; + acpi_log("acpi_init_gporeg(): %02X %02X %02X %02X\n", dev->regs.gporeg[0], dev->regs.gporeg[1], dev->regs.gporeg[2], dev->regs.gporeg[3]); } void acpi_set_timer32(acpi_t *dev, uint8_t timer32) { - dev->timer32 = timer32; + dev->regs.timer32 = timer32; - if (!dev->timer32) - dev->timer_val &= 0x00ffffff; + if (!dev->regs.timer32) + dev->regs.timer_val &= 0x00ffffff; } void acpi_set_slot(acpi_t *dev, int slot) { - dev->slot = slot; + dev->regs.slot = slot; } void acpi_set_irq_mode(acpi_t *dev, int irq_mode) { - dev->irq_mode = irq_mode; + dev->regs.irq_mode = irq_mode; } void acpi_set_irq_pin(acpi_t *dev, int irq_pin) { - dev->irq_pin = irq_pin; + dev->regs.irq_pin = irq_pin; } @@ -446,8 +444,11 @@ static void acpi_reset(void *priv) { acpi_t *dev = (acpi_t *) priv; + int i; - dev->timer_val = 0; + memset(&dev->regs, 0x00, sizeof(acpi_regs_t)); + for (i = 0; i < 4; i++) + dev->regs.gporeg[i] = dev->gporeg_default[i]; } @@ -484,8 +485,6 @@ acpi_init(const device_t *info) timer_add(&dev->timer, acpi_timer_count, dev, 0); timer_set_delay_u64(&dev->timer, ACPICONST); - dev->pmsts |= 0x0100; - return dev; } diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index e7bb52993..6122f2761 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -85,8 +85,6 @@ apollo_smram_map(int smm, uint32_t addr, uint32_t size, int ram) static void via_apollo_setup(via_apollo_t *dev) { - memset(dev, 0, sizeof(via_apollo_t)); - /* Host Bridge */ dev->pci_conf[0][0x00] = 0x06; /*VIA*/ dev->pci_conf[0][0x01] = 0x11; @@ -525,6 +523,7 @@ static void * via_apollo_init(const device_t *info) { via_apollo_t *dev = (via_apollo_t *) malloc(sizeof(via_apollo_t)); + memset(dev, 0, sizeof(via_apollo_t)); pci_add_card(PCI_ADD_NORTHBRIDGE, via_apollo_read, via_apollo_write, dev); diff --git a/src/cpu_common/386.c b/src/cpu_common/386.c index 4884474c3..e5d65dbf1 100644 --- a/src/cpu_common/386.c +++ b/src/cpu_common/386.c @@ -21,6 +21,7 @@ #include <86box/pit.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/machine.h> #include "386_common.h" #ifdef USE_NEW_DYNAREC #include "codegen.h" @@ -303,6 +304,9 @@ exec386(int cycs) loadcs(readmemw(0, addr + 2)); } } else if (nmi && nmi_enable && nmi_mask) { + if (AT && (cpu_fast_off_flags & 0x20000000)) + cpu_fast_off_count = cpu_fast_off_val + 1; + cpu_state.oldpc = cpu_state.pc; x86_int(2); nmi_enable = 0; diff --git a/src/cpu_common/386_common.c b/src/cpu_common/386_common.c index 0c38818a7..d11257cce 100644 --- a/src/cpu_common/386_common.c +++ b/src/cpu_common/386_common.c @@ -147,6 +147,11 @@ enum SMMRAM_Fields_386_To_P5 { SMRAM_FIELD_P5_AUTOHALT_RESTART, /* 100 */ SMRAM_FIELD_P5_SMM_REVISION_ID, /* 0FC */ SMRAM_FIELD_P5_SMBASE_OFFSET, /* 0F8 */ + SMRAM_FIELD_AM486_CR2, /* 0F4 */ + SMRAM_FIELD_AM486_DR0, /* 0F0 */ + SMRAM_FIELD_AM486_DR1, /* 0EC */ + SMRAM_FIELD_AM486_DR2, /* 0E8 */ + SMRAM_FIELD_AM486_DR3, /* 0E4 */ SMRAM_FIELD_P5_LAST }; @@ -459,6 +464,15 @@ smram_save_state_p5(uint32_t *saved_state, int in_hlt) saved_state[SMRAM_FIELD_P5_GS_BASE] = cpu_state.seg_gs.base; saved_state[SMRAM_FIELD_P5_GS_LIMIT] = cpu_state.seg_gs.limit; saved_state[SMRAM_FIELD_P5_GS_ACCESS] = (cpu_state.seg_gs.ar_high << 16) | (cpu_state.seg_gs.access << 8); + + /* Am486/5x86 stuff */ + if (!is_pentium) { + saved_state[SMRAM_FIELD_AM486_CR2] = cr2; + saved_state[SMRAM_FIELD_AM486_DR0] = dr[0]; + saved_state[SMRAM_FIELD_AM486_DR1] = dr[1]; + saved_state[SMRAM_FIELD_AM486_DR2] = dr[2]; + saved_state[SMRAM_FIELD_AM486_DR3] = dr[3]; + } } @@ -564,6 +578,15 @@ smram_restore_state_p5(uint32_t *saved_state) if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION) smbase = saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET]; + + /* Am486/5x86 stuff */ + if (!is_pentium) { + cr2 = saved_state[SMRAM_FIELD_AM486_CR2]; + dr[0] = saved_state[SMRAM_FIELD_AM486_DR0]; + dr[1] = saved_state[SMRAM_FIELD_AM486_DR1]; + dr[2] = saved_state[SMRAM_FIELD_AM486_DR2]; + dr[3] = saved_state[SMRAM_FIELD_AM486_DR3]; + } } @@ -1014,7 +1037,7 @@ enter_smm(int in_hlt) memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t)); - if (is_pentium) /* Intel P5 (Pentium) */ + if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ smram_save_state_p5(saved_state, in_hlt); else if (is_k5 || is_k6) /* AMD K5 and K6 */ smram_save_state_amd_k(saved_state, in_hlt); @@ -1086,6 +1109,9 @@ enter_smm(int in_hlt) void enter_smm_check(int in_hlt) { + if (smi_line && (cpu_fast_off_flags & 0x80000000)) + cpu_fast_off_count = cpu_fast_off_val + 1; + if ((in_smm == 0) && smi_line) { #ifdef ENABLE_386_COMMON_LOG x386_common_log("SMI while not in SMM\n"); @@ -1136,8 +1162,8 @@ leave_smm(void) smram_restore_state_p6(saved_state); /* Maybe we need this? */ - if (smbase == 0x00030000) - smbase = 0x000a0000; + // if (smbase == 0x00030000) + // smbase = 0x000a0000; in_smm = 0; mem_mapping_recalc(0x00030000, 0x00020000); diff --git a/src/cpu_common/386_dynarec.c b/src/cpu_common/386_dynarec.c index 7a08e4cee..70df8e8a3 100644 --- a/src/cpu_common/386_dynarec.c +++ b/src/cpu_common/386_dynarec.c @@ -22,6 +22,7 @@ #include <86box/timer.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/machine.h> #ifdef USE_DYNAREC #include "codegen.h" #ifdef USE_NEW_DYNAREC @@ -39,8 +40,6 @@ int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks; int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched; -#define SYSENTER_LOG 1 -#define ENABLE_386_DYNAREC_LOG 1 #ifdef ENABLE_386_DYNAREC_LOG int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG; @@ -324,6 +323,10 @@ void exec386_dynarec(int cycs) cpu_state.ssegs = 0; fetchdat = fastreadl(cs + cpu_state.pc); +#ifdef ENABLE_386_DYNAREC_LOG + if (in_smm) + x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); +#endif if (!cpu_state.abrt) { @@ -539,6 +542,10 @@ void exec386_dynarec(int cycs) cpu_state.ssegs = 0; fetchdat = fastreadl(cs + cpu_state.pc); +#ifdef ENABLE_386_DYNAREC_LOG + if (in_smm) + x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); +#endif if (!cpu_state.abrt) { @@ -627,6 +634,10 @@ void exec386_dynarec(int cycs) codegen_endpc = (cs + cpu_state.pc) + 8; fetchdat = fastreadl(cs + cpu_state.pc); +#ifdef ENABLE_386_DYNAREC_LOG + if (in_smm) + x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); +#endif if (!cpu_state.abrt) { @@ -744,6 +755,9 @@ void exec386_dynarec(int cycs) } else if (nmi && nmi_enable && nmi_mask) { + if (AT && (cpu_fast_off_flags & 0x20000000)) + cpu_fast_off_count = cpu_fast_off_val + 1; + CPU_BLOCK_END(); #ifndef USE_NEW_DYNAREC oldcs = CS; diff --git a/src/cpu_common/386_dynarec_ops.c b/src/cpu_common/386_dynarec_ops.c index 626a8381e..9965efdff 100644 --- a/src/cpu_common/386_dynarec_ops.c +++ b/src/cpu_common/386_dynarec_ops.c @@ -26,8 +26,6 @@ #include "386_common.h" -#define SYSENTER_LOG 1 - static __inline void fetch_ea_32_long(uint32_t rmdat) { eal_r = eal_w = NULL; diff --git a/src/cpu_common/808x.c b/src/cpu_common/808x.c index d3a576172..9bd0818bc 100644 --- a/src/cpu_common/808x.c +++ b/src/cpu_common/808x.c @@ -899,6 +899,10 @@ makeznptable(void) static void reset_common(int hard) { + /* Make sure to gracefully leave SMM. */ + if (in_smm) + leave_smm(); + biu_cycles = 0; in_rep = 0; in_lock = 0; @@ -1681,14 +1685,6 @@ stos(int bits) } -static void -da(void) -{ - set_pzs(8); - wait(2, 0); -} - - static void aa(void) { @@ -1875,58 +1871,81 @@ execx86(int cycs) break; case 0x27: /*DAA*/ - wait(1, 0); + cpu_dest = AL; + set_of(0); + temp = !!(cpu_state.flags & A_FLAG); if ((cpu_state.flags & A_FLAG) || (AL & 0x0f) > 9) { - cpu_data = AL + 6; - AL = (uint8_t) cpu_data; + cpu_src = 6; + cpu_data = cpu_dest + cpu_src; + set_of_add(8); + cpu_dest = cpu_data; set_af(1); - if ((cpu_data & 0x100) != 0) - set_cf(1); } - if ((cpu_state.flags & C_FLAG) || AL > 0x9f) { - AL += 0x60; + if ((cpu_state.flags & C_FLAG) || AL > (temp ? 0x9f : 0x99)) { + cpu_src = 0x60; + cpu_data = cpu_dest + cpu_src; + set_of_add(8); + cpu_dest = cpu_data; set_cf(1); } - da(); + AL = cpu_dest; + set_pzs(8); + wait(3, 0); break; case 0x2F: /*DAS*/ - wait(1, 0); - temp = AL; + cpu_dest = AL; + set_of(0); + temp = !!(cpu_state.flags & A_FLAG); if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) { - cpu_data = AL - 6; - AL = (uint8_t) cpu_data; + cpu_src = 6; + cpu_data = cpu_dest + cpu_src; + set_of_sub(8); + cpu_dest = cpu_data; set_af(1); - if ((cpu_data & 0x100) != 0) - set_cf(1); } - if ((cpu_state.flags & C_FLAG) || temp > 0x9f) { - AL -= 0x60; + if ((cpu_state.flags & C_FLAG) || AL > (temp ? 0x9f : 0x99)) { + cpu_src = 0x60; + cpu_data = cpu_dest - cpu_src; + set_of_sub(8); + cpu_dest = cpu_data; set_cf(1); } - da(); + AL = cpu_dest; + set_pzs(8); + wait(3, 0); break; case 0x37: /*AAA*/ wait(1, 0); if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) { - AL += 6; + cpu_src = 6; ++AH; set_ca(); } else { + cpu_src = 0; clear_ca(); wait(1, 0); } + cpu_dest = AL; + cpu_data = cpu_dest + cpu_src; + AL = cpu_data; + set_of_add(8); aa(); break; case 0x3F: /*AAS*/ wait(1, 0); if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) { - AL -= 6; + cpu_src = 6; --AH; set_ca(); } else { + cpu_src = 0; clear_ca(); wait(1, 0); } + cpu_dest = AL; + cpu_data = cpu_dest - cpu_src; + AL = cpu_data; + set_of_sub(8); aa(); break; diff --git a/src/cpu_common/cpu.c b/src/cpu_common/cpu.c index f8a39ca67..5005fd5e4 100644 --- a/src/cpu_common/cpu.c +++ b/src/cpu_common/cpu.c @@ -154,6 +154,8 @@ int cpu_prefetch_cycles, cpu_prefetch_width, int cpu_waitstates; int cpu_cache_int_enabled, cpu_cache_ext_enabled; int cpu_pci_speed, cpu_alt_reset; +uint16_t cpu_fast_off_count, cpu_fast_off_val; +uint32_t cpu_fast_off_flags; uint32_t cpu_features; @@ -165,7 +167,7 @@ int is286, hascache, isibm486, israpidcad, - is_pentium, is_k5, is_k6, is_p6; + is_am486, is_pentium, is_k5, is_k6, is_p6; int hasfpu; @@ -298,14 +300,20 @@ cpu_set(void) is286 = (cpu_s->cpu_type >= CPU_286); is386 = (cpu_s->cpu_type >= CPU_386SX); israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD); - isibm486 = (cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL); + isibm486 = (cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL); is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_RAPIDCAD); is486sx = (cpu_s->cpu_type >= CPU_i486SX) && (cpu_s->cpu_type < CPU_i486SX2); is486sx2 = (cpu_s->cpu_type >= CPU_i486SX2) && (cpu_s->cpu_type < CPU_i486DX); is486dx = (cpu_s->cpu_type >= CPU_i486DX) && (cpu_s->cpu_type < CPU_i486DX2); is486dx2 = (cpu_s->cpu_type >= CPU_i486DX2) && (cpu_s->cpu_type < CPU_iDX4); isdx4 = (cpu_s->cpu_type >= CPU_iDX4) && (cpu_s->cpu_type < CPU_WINCHIP); + is_am486 = (cpu_s->cpu_type == CPU_Am486SX) || (cpu_s->cpu_type == CPU_Am486SX2) || (cpu_s->cpu_type == CPU_Am486DX) || + (cpu_s->cpu_type == CPU_Am486DX2) || (cpu_s->cpu_type == CPU_Am486DX4) || (cpu_s->cpu_type == CPU_Am5x86); is_pentium = (cpu_s->cpu_type == CPU_PENTIUM) || (cpu_s->cpu_type == CPU_PENTIUMMMX); + /* Not Pentiums, but they share the same SMM save state table layout. */ + is_pentium |= (cpu_s->cpu_type == CPU_i486DX2) || (cpu_s->cpu_type == CPU_iDX4); + /* The WinChip datasheet claims these are Pentium-compatible. */ + is_pentium |= (cpu_s->cpu_type == CPU_WINCHIP) || (cpu_s->cpu_type == CPU_WINCHIP2); #if defined(DEV_BRANCH) && defined(USE_AMD_K5) is_k5 = (cpu_s->cpu_type == CPU_K5) || (cpu_s->cpu_type == CPU_5K86); #else @@ -317,6 +325,8 @@ cpu_set(void) (cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P); is_p6 = (cpu_s->cpu_type == CPU_PENTIUMPRO) || (cpu_s->cpu_type == CPU_PENTIUM2) || (cpu_s->cpu_type == CPU_PENTIUM2D); + /* The Samuel 2 datasheet claims it's Celeron-compatible. */ + is_p6 |= (cpu_s->cpu_type == CPU_CYRIX3S); hasfpu = (cpu_s->cpu_type >= CPU_i486DX) || (cpu_s->cpu_type == CPU_RAPIDCAD); hascache = (cpu_s->cpu_type >= CPU_486SLC) || (cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL); #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) diff --git a/src/cpu_common/cpu.h b/src/cpu_common/cpu.h index 3f54e9680..a722eceee 100644 --- a/src/cpu_common/cpu.h +++ b/src/cpu_common/cpu.h @@ -376,7 +376,7 @@ extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment penalties when crossing 8-byte boundaries*/ extern int is8086, is286, is386, is486, is486sx, is486dx, is486sx2, is486dx2, isdx4; -extern int is_pentium, is_k5, is_k6, is_p6; +extern int is_am486, is_pentium, is_k5, is_k6, is_p6; extern int hascache; extern int isibm486; extern int is_rapidcad; @@ -479,6 +479,9 @@ extern int timing_misaligned; extern int in_sys; +extern uint16_t cpu_fast_off_count, cpu_fast_off_val; +extern uint32_t cpu_fast_off_flags; + extern CPU cpus_pcjr[]; // FIXME: should be in machine file! extern CPU cpus_europc[]; // FIXME: should be in machine file! extern CPU cpus_pc1512[]; // FIXME: should be in machine file! diff --git a/src/cpu_common/cpu_table.c b/src/cpu_common/cpu_table.c index 230ac5191..edd9fb84d 100644 --- a/src/cpu_common/cpu_table.c +++ b/src/cpu_common/cpu_table.c @@ -232,14 +232,14 @@ CPU cpus_i486S1[] = { {"i486SX/20", CPU_i486SX, 20000000, 1, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, {"i486SX/25", CPU_i486SX, 25000000, 1, 0x422, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, {"i486SX/33", CPU_i486SX, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, - {"i486SX2/50", CPU_i486SX, 50000000, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, - {"i486SX2/66 (Q0569)", CPU_i486SX, 66666666, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8}, + {"i486SX2/50", CPU_i486SX2, 50000000, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, + {"i486SX2/66 (Q0569)", CPU_i486SX2, 66666666, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8}, {"i486DX/25", CPU_i486DX, 25000000, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, {"i486DX/33", CPU_i486DX, 33333333, 1, 0x414, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, {"i486DX/50", CPU_i486DX, 50000000, 1, 0x411, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6}, - {"i486DX2/40", CPU_i486DX, 40000000, 2, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5}, - {"i486DX2/50", CPU_i486DX, 50000000, 2, 0x433, 0x433, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, - {"i486DX2/66", CPU_i486DX, 66666666, 2, 0x435, 0x435, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, + {"i486DX2/40", CPU_i486DX2, 40000000, 2, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5}, + {"i486DX2/50", CPU_i486DX2, 50000000, 2, 0x433, 0x433, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, + {"i486DX2/66", CPU_i486DX2, 66666666, 2, 0x435, 0x435, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, {"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*Only added the DX4 OverDrive as the others would be redundant*/ {"iDX4 OverDrive 100", CPU_iDX4, 100000000, 3, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0} @@ -276,14 +276,14 @@ CPU cpus_i486[] = { {"i486SX/20", CPU_i486SX, 20000000, 1.0, 0x420, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, {"i486SX/25", CPU_i486SX, 25000000, 1.0, 0x422, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, {"i486SX/33", CPU_i486SX, 33333333, 1.0, 0x42a, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"i486SX2/50", CPU_i486SX, 50000000, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, - {"i486SX2/66 (Q0569)", CPU_i486SX, 66666666, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 8}, + {"i486SX2/50", CPU_i486SX2, 50000000, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, + {"i486SX2/66 (Q0569)", CPU_i486SX2, 66666666, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 8}, {"i486DX/25", CPU_i486DX, 25000000, 1.0, 0x404, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, {"i486DX/33", CPU_i486DX, 33333333, 1.0, 0x414, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, {"i486DX/50", CPU_i486DX, 50000000, 1.0, 0x411, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 6}, - {"i486DX2/40", CPU_i486DX, 40000000, 2.0, 0x430, 0x430, 0x0000, CPU_SUPPORTS_DYNAREC, 7, 7, 6, 6, 5}, - {"i486DX2/50", CPU_i486DX, 50000000, 2.0, 0x433, 0x433, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, - {"i486DX2/66", CPU_i486DX, 66666666, 2.0, 0x435, 0x435, 0x0000, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"i486DX2/40", CPU_i486DX2, 40000000, 2.0, 0x430, 0x430, 0x0000, CPU_SUPPORTS_DYNAREC, 7, 7, 6, 6, 5}, + {"i486DX2/50", CPU_i486DX2, 50000000, 2.0, 0x433, 0x433, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, + {"i486DX2/66", CPU_i486DX2, 66666666, 2.0, 0x435, 0x435, 0x0000, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, {"iDX4/75", CPU_iDX4, 75000000, 3.0, 0x480, 0x480, 0x0000, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9}, /*CPUID available on DX4, >= 75 MHz*/ {"iDX4/100", CPU_iDX4, 100000000, 3.0, 0x483, 0x483, 0x0000, CPU_SUPPORTS_DYNAREC, 18,18, 9, 9, 12}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ {"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3.0, 0x1480, 0x1480, 0x0000, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9}, diff --git a/src/cpu_common/x86_ops_atomic.h b/src/cpu_common/x86_ops_atomic.h index fca1c244a..54725d316 100644 --- a/src/cpu_common/x86_ops_atomic.h +++ b/src/cpu_common/x86_ops_atomic.h @@ -134,75 +134,81 @@ static int opCMPXCHG8B_a32(uint32_t fetchdat) static int opXADD_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp, temp2; fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; - seteab(temp + getr8(cpu_reg)); if (cpu_state.abrt) return 1; - setadd8(temp, getr8(cpu_reg)); + temp2 = getr8(cpu_reg); setr8(cpu_reg, temp); + seteab(temp + temp2); if (cpu_state.abrt) return 1; + setadd8(temp, temp2); CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); return 0; } static int opXADD_b_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp, temp2; fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; - seteab(temp + getr8(cpu_reg)); if (cpu_state.abrt) return 1; - setadd8(temp, getr8(cpu_reg)); + temp2 = getr8(cpu_reg); setr8(cpu_reg, temp); + seteab(temp + temp2); if (cpu_state.abrt) return 1; + setadd8(temp, temp2); CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); return 0; } static int opXADD_w_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp, temp2; fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; - seteaw(temp + cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1; - setadd16(temp, cpu_state.regs[cpu_reg].w); + temp2 = cpu_state.regs[cpu_reg].w; cpu_state.regs[cpu_reg].w = temp; + seteaw(temp + temp2); if (cpu_state.abrt) return 1; + setadd16(temp, temp2); CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); return 0; } static int opXADD_w_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp, temp2; fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; - seteaw(temp + cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1; - setadd16(temp, cpu_state.regs[cpu_reg].w); + temp2 = cpu_state.regs[cpu_reg].w; cpu_state.regs[cpu_reg].w = temp; + seteaw(temp + temp2); if (cpu_state.abrt) return 1; + setadd16(temp, temp2); CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); return 0; } static int opXADD_l_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp, temp2; fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; - seteal(temp + cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1; - setadd32(temp, cpu_state.regs[cpu_reg].l); + temp2 = cpu_state.regs[cpu_reg].l; cpu_state.regs[cpu_reg].l = temp; + seteal(temp + temp2); if (cpu_state.abrt) return 1; + setadd32(temp, temp2); CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); return 0; } static int opXADD_l_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp, temp2; fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; - seteal(temp + cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1; - setadd32(temp, cpu_state.regs[cpu_reg].l); + temp2 = cpu_state.regs[cpu_reg].l; cpu_state.regs[cpu_reg].l = temp; + seteal(temp + temp2); if (cpu_state.abrt) return 1; + setadd32(temp, temp2); CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); return 0; } diff --git a/src/cpu_common/x86_ops_bcd.h b/src/cpu_common/x86_ops_bcd.h index cd29b1405..de9a49cd7 100644 --- a/src/cpu_common/x86_ops_bcd.h +++ b/src/cpu_common/x86_ops_bcd.h @@ -3,7 +3,8 @@ static int opAAA(uint32_t fetchdat) flags_rebuild(); if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { - AL += 6; + /* On 286, it's indeed AX - behavior difference from 808x. */ + AX += 6; AH++; cpu_state.flags |= (A_FLAG | C_FLAG); } @@ -44,7 +45,8 @@ static int opAAS(uint32_t fetchdat) flags_rebuild(); if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { - AL -= 6; + /* On 286, it's indeed AX - behavior difference from 808x. */ + AX -= 6; AH--; cpu_state.flags |= (A_FLAG | C_FLAG); } @@ -58,26 +60,33 @@ static int opAAS(uint32_t fetchdat) static int opDAA(uint32_t fetchdat) { - uint16_t tempw; + uint16_t tempw, old_AL, old_CF; flags_rebuild(); - if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) - { + old_AL = AL; + old_CF = cpu_state.flags & C_FLAG; + cpu_state.flags &= ~C_FLAG; + + if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG)) { int tempi = ((uint16_t)AL) + 6; AL += 6; + if (old_CF || (tempi & 0x100)) + cpu_state.flags |= C_FLAG; cpu_state.flags |= A_FLAG; - if (tempi & 0x100) cpu_state.flags |= C_FLAG; - } - if ((cpu_state.flags & C_FLAG) || (AL > 0x9f)) + } else + cpu_state.flags &= ~A_FLAG; + + if ((old_AL > 0x99) || old_CF) { AL += 0x60; cpu_state.flags |= C_FLAG; - } + } else + cpu_state.flags &= ~C_FLAG; tempw = cpu_state.flags & (C_FLAG | A_FLAG); setznp8(AL); flags_rebuild(); - cpu_state.flags |= tempw; + cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0); @@ -86,17 +95,24 @@ static int opDAA(uint32_t fetchdat) static int opDAS(uint32_t fetchdat) { - uint16_t tempw; + uint16_t tempw, old_AL, old_CF; flags_rebuild(); - if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) + old_AL = AL; + old_CF = cpu_state.flags & C_FLAG; + cpu_state.flags &= ~C_FLAG; + + if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG)) { int tempi = ((uint16_t)AL) - 6; AL -= 6; + if (old_CF || (tempi & 0x100)) + cpu_state.flags |= C_FLAG; cpu_state.flags |= A_FLAG; - if (tempi & 0x100) cpu_state.flags |= C_FLAG; - } - if ((cpu_state.flags & C_FLAG) || (AL > 0x9f)) + } else + cpu_state.flags &= ~A_FLAG; + + if ((old_AL > 0x99) || old_CF) { AL -= 0x60; cpu_state.flags |= C_FLAG; @@ -105,7 +121,7 @@ static int opDAS(uint32_t fetchdat) tempw = cpu_state.flags & (C_FLAG | A_FLAG); setznp8(AL); flags_rebuild(); - cpu_state.flags |= tempw; + cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0); diff --git a/src/disk/hdc_esdi_at.c b/src/disk/hdc_esdi_at.c index b1c202377..ad1135117 100644 --- a/src/disk/hdc_esdi_at.c +++ b/src/disk/hdc_esdi_at.c @@ -106,6 +106,10 @@ typedef struct { } esdi_t; +static uint8_t esdi_read(uint16_t port, void *priv); +static void esdi_write(uint16_t port, uint8_t val, void *priv); + + #ifdef ENABLE_ESDI_AT_LOG int esdi_at_do_log = ENABLE_ESDI_AT_LOG; @@ -217,14 +221,19 @@ esdi_writew(uint16_t port, uint16_t val, void *priv) { esdi_t *esdi = (esdi_t *)priv; - esdi->buffer[esdi->pos >> 1] = val; - esdi->pos += 2; + if (port > 0x01f0) { + esdi_write(port, val & 0xff, priv); + esdi_write(port + 1, (val >> 8) & 0xff, priv); + } else { + esdi->buffer[esdi->pos >> 1] = val; + esdi->pos += 2; - if (esdi->pos >= 512) { - esdi->pos = 0; - esdi->status = STAT_BUSY; - /* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */ - timer_set_delay_u64(&esdi->callback_timer, (3125 * TIMER_USEC) / 8); + if (esdi->pos >= 512) { + esdi->pos = 0; + esdi->status = STAT_BUSY; + /* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */ + timer_set_delay_u64(&esdi->callback_timer, (3125 * TIMER_USEC) / 8); + } } } @@ -386,21 +395,25 @@ esdi_readw(uint16_t port, void *priv) esdi_t *esdi = (esdi_t *)priv; uint16_t temp; - temp = esdi->buffer[esdi->pos >> 1]; - esdi->pos += 2; + if (port > 0x01f0) { + temp = esdi_read(port, priv); + temp |= (esdi_read(port + 1, priv) << 8); + } else { + temp = esdi->buffer[esdi->pos >> 1]; + esdi->pos += 2; - if (esdi->pos >= 512) { - esdi->pos=0; - esdi->status = STAT_READY | STAT_DSC; - if (esdi->command == CMD_READ || esdi->command == 0xa0) { - esdi->secount = (esdi->secount - 1) & 0xff; - if (esdi->secount) { - next_sector(esdi); - esdi->status = STAT_BUSY; - /* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */ - timer_set_delay_u64(&esdi->callback_timer, (3125 * TIMER_USEC) / 8); - } else { - ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); + if (esdi->pos >= 512) { + esdi->pos=0; + esdi->status = STAT_READY | STAT_DSC; + if (esdi->command == CMD_READ || esdi->command == 0xa0) { + esdi->secount = (esdi->secount - 1) & 0xff; + if (esdi->secount) { + next_sector(esdi); + esdi->status = STAT_BUSY; + /* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */ + timer_set_delay_u64(&esdi->callback_timer, (3125 * TIMER_USEC) / 8); + } else + ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0); } } } diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 77480f91f..ea8f05566 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -1194,6 +1194,10 @@ ide_writew(uint16_t addr, uint16_t val, void *priv) case 0x0: /* Data */ ide_write_data(ide, val, 2); break; + default: + ide_writeb(addr, val & 0xff, priv); + ide_writeb(addr + 1, (val >> 8) & 0xff, priv); + break; } } @@ -1219,7 +1223,14 @@ ide_writel(uint16_t addr, uint32_t val, void *priv) switch (addr) { case 0x0: /* Data */ ide_write_data(ide, val & 0xffff, 2); - ide_write_data(ide, val >> 16, 2); + if (dev->bit32) + ide_write_data(ide, val >> 16, 2); + else + ide_writew(addr + 2, (val >> 16) & 0xffff, priv); + break; + default: + ide_writew(addr, val & 0xffff, priv); + ide_writew(addr + 2, (val >> 16) & 0xffff, priv); break; } } @@ -1880,6 +1891,9 @@ ide_readw(uint16_t addr, void *priv) case 0x0: /* Data */ temp = ide_read_data(ide, 2); break; + default: + temp = ide_readb(addr, priv) | (ide_readb(addr + 1, priv) << 8); + break; } /* ide_log("ide_readw(%04X, %08X) = %04X\n", addr, priv, temp); */ @@ -1904,7 +1918,13 @@ ide_readl(uint16_t addr, void *priv) switch (addr & 0x7) { case 0x0: /* Data */ temp2 = ide_read_data(ide, 2); - temp = temp2 | (ide_read_data(ide, 2) << 16); + if (dev->bit32) + temp = temp2 | (ide_read_data(ide, 2) << 16); + else + temp = temp2 | (ide_readw(addr + 2, priv) << 16); + break; + default: + temp = ide_readw(addr, priv) | (ide_readw(addr + 2, priv) << 16); break; } @@ -2347,22 +2367,16 @@ ide_set_handlers(uint8_t board) return; if (ide_boards[board]->base_main) { - if (ide_boards[board]->bit32) { - io_sethandler(ide_boards[board]->base_main, 1, - ide_readb, ide_readw, ide_readl, - ide_writeb, ide_writew, ide_writel, - ide_boards[board]); - } else { - io_sethandler(ide_boards[board]->base_main, 1, - ide_readb, ide_readw, NULL, - ide_writeb, ide_writew, NULL, - ide_boards[board]); - } + io_sethandler(ide_boards[board]->base_main, 1, + ide_readb, ide_readw, ide_readl, + ide_writeb, ide_writew, ide_writel, + ide_boards[board]); io_sethandler(ide_boards[board]->base_main + 1, 7, - ide_readb, NULL, NULL, - ide_writeb, NULL, NULL, + ide_readb, ide_readw, ide_readl, + ide_writeb, ide_writew, ide_writel, ide_boards[board]); } + if (ide_boards[board]->side_main) { io_sethandler(ide_boards[board]->side_main, 1, ide_read_alt_status, NULL, NULL, @@ -2379,21 +2393,14 @@ ide_remove_handlers(uint8_t board) return; if (ide_boards[board]->base_main) { - if (ide_boards[board]->bit32) { - io_removehandler(ide_boards[board]->base_main, 1, - ide_readb, ide_readw, ide_readl, - ide_writeb, ide_writew, ide_writel, - ide_boards[board]); - } else { - io_removehandler(ide_boards[board]->base_main, 1, - ide_readb, ide_readw, NULL, - ide_writeb, ide_writew, NULL, - ide_boards[board]); - } + io_removehandler(ide_boards[board]->base_main, 1, + ide_readb, ide_readw, ide_readl, + ide_writeb, ide_writew, ide_writel, + ide_boards[board]); io_removehandler(ide_boards[board]->base_main + 1, 7, - ide_readb, NULL, NULL, - ide_writeb, NULL, NULL, - ide_boards[board]); + ide_readb, ide_readw, ide_readl, + ide_writeb, ide_writew, ide_writel, + ide_boards[board]); } if (ide_boards[board]->side_main) { io_removehandler(ide_boards[board]->side_main, 1, diff --git a/src/disk/hdc_st506_at.c b/src/disk/hdc_st506_at.c index 6a317db6b..879200424 100644 --- a/src/disk/hdc_st506_at.c +++ b/src/disk/hdc_st506_at.c @@ -120,6 +120,10 @@ typedef struct { } mfm_t; +static uint8_t mfm_read(uint16_t port, void *priv); +static void mfm_write(uint16_t port, uint8_t val, void *priv); + + #ifdef ENABLE_ST506_AT_LOG int mfm_at_do_log = ENABLE_ST506_AT_LOG; @@ -372,13 +376,18 @@ mfm_writew(uint16_t port, uint16_t val, void *priv) { mfm_t *mfm = (mfm_t *)priv; - mfm->buffer[mfm->pos >> 1] = val; - mfm->pos += 2; + if (port > 0x01f0) { + mfm_write(port, val & 0xff, priv); + mfm_write(port + 1, (val >> 8) & 0xff, priv); + } else { + mfm->buffer[mfm->pos >> 1] = val; + mfm->pos += 2; - if (mfm->pos >= 512) { - mfm->pos = 0; - mfm->status = STAT_BUSY; - timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME); + if (mfm->pos >= 512) { + mfm->pos = 0; + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME); + } } } @@ -454,19 +463,24 @@ mfm_readw(uint16_t port, void *priv) mfm_t *mfm = (mfm_t *)priv; uint16_t ret; - ret = mfm->buffer[mfm->pos >> 1]; - mfm->pos += 2; - if (mfm->pos >= 512) { - mfm->pos = 0; - mfm->status = STAT_READY|STAT_DSC; - if (mfm->command == CMD_READ) { - mfm->secount = (mfm->secount - 1) & 0xff; - if (mfm->secount) { - next_sector(mfm); - mfm->status = STAT_BUSY | STAT_READY | STAT_DSC; - timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME); - } else - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0); + if (port > 0x01f0) { + ret = mfm_read(port, priv); + ret |= (mfm_read(port + 1, priv) << 8); + } else { + ret = mfm->buffer[mfm->pos >> 1]; + mfm->pos += 2; + if (mfm->pos >= 512) { + mfm->pos = 0; + mfm->status = STAT_READY|STAT_DSC; + if (mfm->command == CMD_READ) { + mfm->secount = (mfm->secount - 1) & 0xff; + if (mfm->secount) { + next_sector(mfm); + mfm->status = STAT_BUSY | STAT_READY | STAT_DSC; + timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME); + } else + ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0); + } } } @@ -720,7 +734,7 @@ mfm_init(const device_t *info) io_sethandler(0x01f0, 1, mfm_read, mfm_readw, NULL, mfm_write, mfm_writew, NULL, mfm); io_sethandler(0x01f1, 7, - mfm_read, NULL, NULL, mfm_write, NULL, NULL, mfm); + mfm_read, mfm_readw, NULL, mfm_write, mfm_writew, NULL, mfm); io_sethandler(0x03f6, 1, NULL, NULL, NULL, mfm_write, NULL, NULL, mfm); diff --git a/src/dma.c b/src/dma.c index ae85f3332..d55972449 100644 --- a/src/dma.c +++ b/src/dma.c @@ -662,7 +662,9 @@ dma16_init(void) void dma_alias_set(void) { - io_sethandler(0x0090, 16, + io_sethandler(0x0090, 2, + dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); + io_sethandler(0x0093, 13, dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); } @@ -684,7 +686,9 @@ dma_alias_set_piix(void) void dma_alias_remove(void) { - io_removehandler(0x0090, 16, + io_removehandler(0x0090, 2, + dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); + io_removehandler(0x0093, 13, dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); } diff --git a/src/include/86box/acpi.h b/src/include/86box/acpi.h index dd8598002..ca0cb3b93 100644 --- a/src/include/86box/acpi.h +++ b/src/include/86box/acpi.h @@ -62,6 +62,13 @@ typedef struct glbctl, devctl, timer_val; uint64_t tmr_overflow_time; +} acpi_regs_t; + + +typedef struct +{ + acpi_regs_t regs; + uint8_t gporeg_default[4]; pc_timer_t timer; nvr_t *nvr; } acpi_t; diff --git a/src/include/86box/intel_flash.h b/src/include/86box/intel_flash.h index 60eaeacd8..fd14f03f5 100644 --- a/src/include/86box/intel_flash.h +++ b/src/include/86box/intel_flash.h @@ -17,8 +17,5 @@ */ extern const device_t intel_flash_bxt_ami_device; -#if defined(DEV_BRANCH) && defined(USE_TC430HX) -extern const device_t intel_flash_bxtw_ami_device; -#endif extern const device_t intel_flash_bxt_device; extern const device_t intel_flash_bxb_device; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index de7f0d82d..de429ef3e 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -285,10 +285,9 @@ extern int machine_at_acerv35n_init(const machine_t *); extern int machine_at_ap53_init(const machine_t *); extern int machine_at_p55t2p4_init(const machine_t *); extern int machine_at_p55t2s_init(const machine_t *); -#if defined(DEV_BRANCH) && defined(USE_TC430HX) extern int machine_at_tc430hx_init(const machine_t *); -extern int machine_at_equium5200_init(const machine_t *); //Toshiba branded CU430HX. Presents same issues as the TC430HX. -#endif //Other than that, works as intended(No need to set an MPU too). +extern int machine_at_equium5200_init(const machine_t *); /* Toshiba branded CU430HX. + Works as intended (No need to set an MPU too). */ extern int machine_at_p55tvp4_init(const machine_t *); extern int machine_at_i430vx_init(const machine_t *); @@ -301,6 +300,7 @@ extern int machine_at_tx97_init(const machine_t *); extern int machine_at_ym430tx_init(const machine_t *); extern int machine_at_586t2_init(const machine_t *); extern int machine_at_807ds_init(const machine_t *); +extern int machine_at_p5mms98_init(const machine_t *); extern int machine_at_mvp3_init(const machine_t *); diff --git a/src/include/86box/nvr.h b/src/include/86box/nvr.h index 9c0413f09..1b0088f0b 100644 --- a/src/include/86box/nvr.h +++ b/src/include/86box/nvr.h @@ -115,6 +115,7 @@ extern void nvr_time_set(struct tm *); extern void nvr_reg_write(uint16_t reg, uint8_t val, void *priv); 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_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/pit.h b/src/include/86box/pit.h index 3ec389cf1..4684c9632 100644 --- a/src/include/86box/pit.h +++ b/src/include/86box/pit.h @@ -49,7 +49,7 @@ typedef struct PIT { extern pit_t *pit, *pit2; -extern double SYSCLK; +extern double SYSCLK, PCICLK; extern uint64_t PITCONST, ISACONST, CGACONST, diff --git a/src/include/86box/rom.h b/src/include/86box/rom.h index f837d2b68..d102d210d 100644 --- a/src/include/86box/rom.h +++ b/src/include/86box/rom.h @@ -58,11 +58,9 @@ extern int bios_load(wchar_t *fn1, wchar_t *fn2, uint32_t addr, int sz, int off, int flags); extern int bios_load_linear_combined(wchar_t *fn1, wchar_t *fn2, int sz, int off); -#if defined(DEV_BRANCH) && defined(USE_TC430HX) extern int bios_load_linear_combined2(wchar_t *fn1, wchar_t *fn2, wchar_t *fn3, wchar_t *fn4, wchar_t *fn5, int sz, int off); -#endif extern int rom_init(rom_t *rom, wchar_t *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags); diff --git a/src/intel_flash.c b/src/intel_flash.c index f0b5e9c0b..28ea1e8d4 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -480,20 +480,6 @@ const device_t intel_flash_bxt_ami_device = }; -#if defined(DEV_BRANCH) && defined(USE_TC430HX) -const device_t intel_flash_bxtw_ami_device = -{ - "Intel 28F100BXT/28F200BXT Flash BIOS", - DEVICE_PCI, - FLAG_INV_A16 | FLAG_WORD, - intel_flash_init, - intel_flash_close, - intel_flash_reset, - NULL, NULL, NULL, NULL -}; -#endif - - const device_t intel_flash_bxt_device = { "Intel 28F001BXT/28F002BXT Flash BIOS", diff --git a/src/intel_piix.c b/src/intel_piix.c index 85f9ea125..95c592e0e 100644 --- a/src/intel_piix.c +++ b/src/intel_piix.c @@ -42,6 +42,7 @@ #include <86box/acpi.h> #include <86box/pci.h> #include <86box/pic.h> +#include <86box/pit.h> #include <86box/port_92.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> @@ -66,9 +67,9 @@ typedef struct max_func, pci_slot, regs[4][256], readout_regs[256], board_config[2]; - uint16_t func0_id, - nvr_io_base, + uint16_t func0_id, nvr_io_base, usb_io_base, acpi_io_base; + double fast_off_period; uint8_t *usb_smsc_mmio; mem_mapping_t usb_smsc_mmio_mapping; sff8038i_t *bm[2]; @@ -78,6 +79,7 @@ typedef struct nvr_t * nvr; acpi_t * acpi; port_92_t * port_92; + pc_timer_t fast_off_timer; } piix_t; @@ -448,9 +450,8 @@ smbus_update_io_mapping(piix_t *dev) static void nvr_update_io_mapping(piix_t *dev) { - int enabled2 = 1; - if (dev->nvr_io_base != 0x0000) { + piix_log("Removing NVR at %04X...\n", dev->nvr_io_base); nvr_at_handler(0, dev->nvr_io_base, dev->nvr); nvr_at_handler(0, dev->nvr_io_base + 0x0002, dev->nvr); nvr_at_handler(0, dev->nvr_io_base + 0x0004, dev->nvr); @@ -462,15 +463,15 @@ nvr_update_io_mapping(piix_t *dev) dev->nvr_io_base = 0x70; piix_log("New NVR I/O base: %04X\n", dev->nvr_io_base); - /* if (dev->type == 4) - enabled2 = (dev->regs[2][0xff] & 0x10); */ - - if ((dev->regs[0][0xcb] & 0x01) && enabled2) { + if (dev->regs[0][0xcb] & 0x01) { + piix_log("Adding low NVR at %04X...\n", dev->nvr_io_base); nvr_at_handler(1, dev->nvr_io_base, dev->nvr); nvr_at_handler(1, dev->nvr_io_base + 0x0004, dev->nvr); } - if (dev->regs[0][0xcb] & 0x04) + if (dev->regs[0][0xcb] & 0x04) { + piix_log("Adding high NVR at %04X...\n", dev->nvr_io_base + 0x0002); nvr_at_handler(1, dev->nvr_io_base + 0x0002, dev->nvr); + } } @@ -518,12 +519,11 @@ piix_write(int func, int addr, uint8_t val, void *priv) break; case 0x4c: fregs[0x4c] = val; - if (val & 0x80) { - if (dev->type > 1) - dma_alias_remove(); - else - dma_alias_remove_piix(); - } else { + if (dev->type > 1) + dma_alias_remove(); + else + dma_alias_remove_piix(); + if (!(val & 0x80)) { if (dev->type > 1) dma_alias_set(); else @@ -585,6 +585,9 @@ piix_write(int func, int addr, uint8_t val, void *priv) case 4: fregs[0x6a] = val & 0x80; break; + case 5: + /* This case is needed so it doesn't behave the PIIX way on the SMSC. */ + break; } break; case 0x6b: @@ -650,6 +653,25 @@ piix_write(int func, int addr, uint8_t val, void *priv) if (dev->type < 4) { fregs[addr] = val & 0x1f; apm_set_do_smi(dev->apm, (val & 0x01) | (fregs[0xa2] & 0x80)); + switch ((val & 0x18) >> 3) { + case 0x00: + dev->fast_off_period = PCICLK * 32768.0 * 60000.0; + break; + case 0x01: + default: + dev->fast_off_period = 0.0; + break; + case 0x02: + dev->fast_off_period = PCICLK; + break; + case 0x03: + dev->fast_off_period = PCICLK * 32768.0; + break; + } + cpu_fast_off_count = fregs[0xa8] + 1; + timer_disable(&dev->fast_off_timer); + if (dev->fast_off_period != 0.0) + timer_on_auto(&dev->fast_off_timer, dev->fast_off_period); } break; case 0xa2: @@ -658,7 +680,6 @@ piix_write(int func, int addr, uint8_t val, void *priv) apm_set_do_smi(dev->apm, (fregs[0xa0] & 0x01) | (val & 0x80)); } break; - case 0xa5: case 0xa6: case 0xa8: case 0xaa: case 0xac: case 0xae: if (dev->type < 4) fregs[addr] = val & 0xff; @@ -668,14 +689,40 @@ piix_write(int func, int addr, uint8_t val, void *priv) fregs[addr] = val & 0x01; break; case 0xa4: - if (dev->type < 4) + if (dev->type < 4) { fregs[addr] = val & 0xfb; + cpu_fast_off_flags = (cpu_fast_off_flags & 0xffffff00) | fregs[addr]; + } + break; + case 0xa5: + if (dev->type < 4) { + fregs[addr] = val & 0xff; + cpu_fast_off_flags = (cpu_fast_off_flags & 0xffff00ff) | (fregs[addr] << 8); + } + break; + case 0xa6: + if (dev->type < 4) { + fregs[addr] = val & 0xff; + cpu_fast_off_flags = (cpu_fast_off_flags & 0xff00ffff) | (fregs[addr] << 16); + } break; case 0xa7: if (dev->type == 3) fregs[addr] = val & 0xef; else if (dev->type < 3) fregs[addr] = val; + if (dev->type < 4) + cpu_fast_off_flags = (cpu_fast_off_flags & 0x00ffffff) | (fregs[addr] << 24); + break; + case 0xa8: + if (dev->type < 3) { + fregs[addr] = val & 0xff; + cpu_fast_off_val = val; + cpu_fast_off_count = val + 1; + timer_disable(&dev->fast_off_timer); + if (dev->fast_off_period != 0.0) + timer_on_auto(&dev->fast_off_timer, dev->fast_off_period); + } break; case 0xb0: if (dev->type > 3) @@ -922,9 +969,7 @@ piix_write(int func, int addr, uint8_t val, void *priv) case 0xff: if (dev->type == 4) { fregs[addr] = val & 0x10; - nvr_at_handler(0, 0x0070, dev->nvr); - if ((dev->regs[0][0xcb] & 0x01) && (dev->regs[2][0xff] & 0x10)) - nvr_at_handler(1, 0x0070, dev->nvr); + nvr_read_addr_set(!!(val & 0x10), dev->nvr); } break; } else if (func == 3) switch(addr) { /* Power Management */ @@ -1209,9 +1254,11 @@ piix_reset_hard(piix_t *dev) fregs[0x20] = 0x01; fregs[0x3d] = 0x04; fregs[0x60] = (dev->type > 3) ? 0x10: 0x00; - fregs[0x6a] = (dev->type == 3) ? 0x01 : 0x00; - fregs[0xc1] = 0x20; - fregs[0xff] = (dev->type > 3) ? 0x10 : 0x00; + if (dev->type < 5) { + fregs[0x6a] = (dev->type == 3) ? 0x01 : 0x00; + fregs[0xc1] = 0x20; + fregs[0xff] = (dev->type > 3) ? 0x10 : 0x00; + } dev->max_func = 1; /* It starts with USB disabled, then enables it. */ /* SMSC OHCI memory-mapped registers */ @@ -1258,6 +1305,57 @@ piix_reset_hard(piix_t *dev) } +static void +piix_apm_out(uint16_t port, uint8_t val, void *p) +{ + piix_t *dev = (piix_t *) p; + + if (dev->apm->do_smi) { + if (dev->type > 3) + dev->acpi->regs.glbsts |= 0x20; + else + dev->regs[0][0xaa] |= 0x80; + } +} + + +static void +piix_fast_off_count(void *priv) +{ + piix_t *dev = (piix_t *) priv; + + cpu_fast_off_count--; + + if (cpu_fast_off_count == 0) { + smi_line = 1; + dev->regs[0][0xaa] |= 0x20; + cpu_fast_off_count = dev->regs[0][0xa8] + 1; + } + + timer_on_auto(&dev->fast_off_timer, dev->fast_off_period); +} + + +static void +piix_reset(void *p) +{ + piix_t *dev = (piix_t *)p; + + if (dev->type > 3) { + piix_write(3, 0x04, 0x00, p); + piix_write(3, 0x5b, 0x00, p); + } else { + piix_write(0, 0xa0, 0x08, p); + piix_write(0, 0xa2, 0x00, p); + piix_write(0, 0xa4, 0x00, p); + piix_write(0, 0xa5, 0x00, p); + piix_write(0, 0xa6, 0x00, p); + piix_write(0, 0xa7, 0x00, p); + piix_write(0, 0xa8, 0x0f, p); + } +} + + static void piix_close(void *p) { @@ -1283,6 +1381,7 @@ static void dev->pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, piix_read, piix_write, dev); piix_log("PIIX%i: Added to slot: %02X\n", dev->type, dev->pci_slot); + piix_log("PIIX%i: Added to slot: %02X\n", dev->type, dev->pci_slot); dev->bm[0] = device_add_inst(&sff8038i_device, 1); dev->bm[1] = device_add_inst(&sff8038i_device, 2); @@ -1294,9 +1393,10 @@ static void dev->acpi = device_add(&acpi_device); acpi_set_slot(dev->acpi, dev->pci_slot); acpi_set_nvr(dev->acpi, dev->nvr); - } + } else + timer_add(&dev->fast_off_timer, piix_fast_off_count, dev, 0); - if (dev->type == 5) { + if (dev->type > 4) { dev->usb_smsc_mmio = (uint8_t *) malloc(4096); memset(dev->usb_smsc_mmio, 0x00, 4096); @@ -1308,8 +1408,17 @@ static void } piix_reset_hard(dev); + piix_log("Maximum function: %i\n", dev->max_func); + cpu_fast_off_flags = 0x00000000; + if (dev->type < 4) { + cpu_fast_off_val = dev->regs[0][0xa8]; + cpu_fast_off_count = cpu_fast_off_val + 1; + } else + cpu_fast_off_val = cpu_fast_off_count = 0; dev->apm = device_add(&apm_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); dev->port_92 = device_add(&port_92_pci_device); dma_alias_set(); @@ -1392,7 +1501,7 @@ const device_t piix_device = 0x122e0101, piix_init, piix_close, - NULL, + piix_reset, NULL, NULL, NULL, @@ -1406,7 +1515,7 @@ const device_t piix3_device = 0x70000403, piix_init, piix_close, - NULL, + piix_reset, NULL, NULL, NULL, @@ -1420,7 +1529,7 @@ const device_t piix4_device = 0x71100004, piix_init, piix_close, - NULL, + piix_reset, NULL, NULL, NULL, @@ -1434,7 +1543,7 @@ const device_t piix4e_device = 0x71100094, piix_init, piix_close, - NULL, + piix_reset, NULL, NULL, NULL, @@ -1448,7 +1557,7 @@ const device_t slc90e66_device = 0x94600005, piix_init, piix_close, - NULL, + piix_reset, NULL, NULL, NULL, diff --git a/src/io.c b/src/io.c index 9714e6bd2..5896a54de 100644 --- a/src/io.c +++ b/src/io.c @@ -71,16 +71,6 @@ io_log(const char *fmt, ...) #endif -#ifdef ENABLE_IO_LOG -static uint8_t null_inb(uint16_t addr, void *priv) { io_log("IO: read(%04x)\n"); return(0xff); } -static uint16_t null_inw(uint16_t addr, void *priv) { io_log("IO: readw(%04x)\n"); return(0xffff); } -static uint32_t null_inl(uint16_t addr, void *priv) { io_log("IO: readl(%04x)\n"); return(0xffffffff); } -static void null_outb(uint16_t addr, uint8_t val, void *priv) { io_log("IO: write(%04x, %02x)\n", val); } -static void null_outw(uint16_t addr, uint16_t val, void *priv) { io_log("IO: writew(%04x, %04x)\n", val); } -static void null_outl(uint16_t addr, uint32_t val, void *priv) { io_log("IO: writel(%04x, %08lx)\n", val); } -#endif - - void io_init(void) { @@ -106,24 +96,8 @@ io_init(void) p = NULL; } -#ifdef ENABLE_IO_LOG - /* io[c] should be the only handler, pointing at the NULL catch handler. */ - p = (io_t *) malloc(sizeof(io_t)); - memset(p, 0, sizeof(io_t)); - io[c] = io_last[c] = p; - p->next = NULL; - p->prev = NULL; - p->inb = null_inb; - p->outb = null_outb; - p->inw = null_inw; - p->outw = null_outw; - p->inl = null_inl; - p->outl = null_outl; - p->priv = NULL; -#else /* io[c] should be NULL. */ io[c] = io_last[c] = NULL; -#endif } } @@ -309,16 +283,16 @@ inb(uint16_t port) uint8_t ret = 0xff; io_t *p; int found = 0; + int qfound = 0; p = io[port]; - if (p) { - while(p) { - if (p->inb) { - ret &= p->inb(port, p->priv); - found++; - } - p = p->next; + while(p) { + if (p->inb) { + ret &= p->inb(port, p->priv); + found |= 1; + qfound++; } + p = p->next; } if (port & 0x80) @@ -328,34 +302,10 @@ inb(uint16_t port) else amstrad_latch = AMSTRAD_SW9; -#ifdef ENABLE_IO_LOG - if (CS == IO_TRACE) - io_log("IOTRACE(%04X): inb(%04x)=%02x\n", IO_TRACE, port, ret); -#endif - - /* if (port == 0x386) { - ret = 0x00; - found = 1; - } - - if (port == 0x406) { - ret = 0x00; - found = 1; - } - - if (port == 0xf87) { - ret = 0x00; - found = 1; - } */ - if (!found) sub_cycles(io_delay); - // if (!found) - // pclog("inb(%04X) = %02X\n", port, ret); - - // if (in_smm) - // pclog("inb(%04X) = %02X\n", port, ret); + io_log("(%i, %i, %04i) in b(%04X) = %02X\n", in_smm, found, qfound, port, ret); return(ret); } @@ -366,31 +316,22 @@ outb(uint16_t port, uint8_t val) { io_t *p; int found = 0; + int qfound = 0; - // if (in_smm) - // pclog("outb(%04X, %02X)\n", port, val); - - if (io[port]) { - p = io[port]; - while(p) { - if (p->outb) { - p->outb(port, val, p->priv); - found++; - } - p = p->next; + p = io[port]; + while(p) { + if (p->outb) { + p->outb(port, val, p->priv); + found |= 1; + qfound++; } + p = p->next; } -#ifdef ENABLE_IO_LOG - if (CS == IO_TRACE) - io_log("IOTRACE(%04X): outb(%04x,%02x)\n", IO_TRACE, port, val); -#endif - if (!found) sub_cycles(io_delay); - // if (!found) - // pclog("outb(%04X, %02X)\n", port, val); + io_log("(%i, %i, %04i) outb(%04X, %02X)\n", in_smm, found, qfound, port, val); return; } @@ -402,23 +343,46 @@ inw(uint16_t port) io_t *p; uint16_t ret = 0xffff; int found = 0; + int qfound = 0; + uint8_t ret8[2]; + int i = 0; p = io[port]; - if (p) { + while(p) { + if (p->inw) { + ret &= p->inw(port, p->priv); + found |= 2; + qfound++; + } + p = p->next; + } + + ret8[0] = ret & 0xff; + ret8[1] = (ret >> 8) & 0xff; + for (i = 0; i < 2; i++) { + p = io[port + i]; while(p) { - if (p->inw) { - ret = p->inw(port, p->priv); - found = 1; + if (p->inb && !p->inw) { + ret8[i] &= p->inb(port + i, p->priv); + found |= 1; + qfound++; } p = p->next; } } + ret = (ret8[1] << 8) | ret8[0]; + + if (port & 0x80) + amstrad_latch = AMSTRAD_NOLATCH; + else if (port & 0x4000) + amstrad_latch = AMSTRAD_SW10; + else + amstrad_latch = AMSTRAD_SW9; if (!found) - ret = (inb(port) | (inb(port + 1) << 8)); + sub_cycles(io_delay); - // if (in_smm) - // pclog("inw(%04X) = %04X\n", port, ret); + io_log("(%i, %i, %04i) in w(%04X) = %04X\n", in_smm, found, qfound, port, ret); return ret; } @@ -428,23 +392,36 @@ void outw(uint16_t port, uint16_t val) { io_t *p; - - // if (in_smm) - // pclog("outw(%04X, %04X)\n", port, val); + int found = 0; + int qfound = 0; + int i = 0; p = io[port]; - if (p) { + while(p) { + if (p->outw) { + p->outw(port, val, p->priv); + found |= 2; + qfound++; + } + p = p->next; + } + + for (i = 0; i < 2; i++) { + p = io[port + i]; while(p) { - if (p->outw) { - p->outw(port, val, p->priv); - return; + if (p->outb && !p->outw) { + p->outb(port + i, val >> (i << 3), p->priv); + found |= 1; + qfound++; } p = p->next; } } - outb(port,val); - outb(port+1,val>>8); + if (!found) + sub_cycles(io_delay); + + io_log("(%i, %i, %04i) outw(%04X, %04X)\n", in_smm, found, qfound, port, val); return; } @@ -455,24 +432,66 @@ inl(uint16_t port) { io_t *p; uint32_t ret = 0xffffffff; + uint16_t ret16[2]; + uint8_t ret8[4]; int found = 0; + int qfound = 0; + int i = 0; p = io[port]; - if (p) { + while(p) { + if (p->inl) { + ret &= p->inl(port, p->priv); + found |= 4; + qfound++; + } + p = p->next; + } + + ret16[0] = ret & 0xffff; + ret16[1] = (ret >> 16) & 0xffff; + for (i = 0; i < 4; i += 2) { + p = io[port + i]; while(p) { - if (p->inl) { - ret = p->inl(port, p->priv); - found = 1; + if (p->inw && !p->inl) { + ret16[i >> 1] &= p->inw(port + i, p->priv); + found |= 2; + qfound++; } p = p->next; } } + ret = (ret16[1] << 16) | ret16[0]; + + ret8[0] = ret & 0xff; + ret8[1] = (ret >> 8) & 0xff; + ret8[2] = (ret >> 16) & 0xff; + ret8[3] = (ret >> 24) & 0xff; + for (i = 0; i < 4; i++) { + p = io[port + i]; + while(p) { + if (p->inb && !p->inw && !p->inl) { + ret8[i] &= p->inb(port + i, p->priv); + found |= 1; + qfound++; + } + p = p->next; + } + } + ret = (ret8[3] << 24) | (ret8[2] << 16) | (ret8[1] << 8) | ret8[0]; + + if (port & 0x80) + amstrad_latch = AMSTRAD_NOLATCH; + else if (port & 0x4000) + amstrad_latch = AMSTRAD_SW10; + else + amstrad_latch = AMSTRAD_SW9; if (!found) - ret = (inw(port) | (inw(port + 2) << 16)); + sub_cycles(io_delay); - // if (in_smm) - // pclog("inl(%04X) = %08X\n", port, ret); + if (in_smm) + io_log("(%i, %i, %04i) in l(%04X) = %08X\n", in_smm, found, qfound, port, ret); return ret; } @@ -482,23 +501,51 @@ void outl(uint16_t port, uint32_t val) { io_t *p; - - // if (in_smm) - // pclog("outl(%04X, %08X)\n", port, val); + int found = 0; + int qfound = 0; + int i = 0; p = io[port]; if (p) { while(p) { if (p->outl) { p->outl(port, val, p->priv); - return; + found |= 4; + qfound++; + // return; } p = p->next; } } - outw(port, val); - outw(port + 2, val >> 16); + for (i = 0; i < 4; i += 2) { + p = io[port + i]; + while(p) { + if (p->outw && !p->outl) { + p->outw(port + i, val >> (i << 3), p->priv); + found |= 2; + qfound++; + } + p = p->next; + } + } + + for (i = 0; i < 4; i++) { + p = io[port + i]; + while(p) { + if (p->outb && !p->outw && !p->outl) { + p->outb(port + i, val >> (i << 3), p->priv); + found |= 1; + qfound++; + } + p = p->next; + } + } + + if (!found) + sub_cycles(io_delay); + + io_log("(%i, %i, %04i) outl(%04X, %08X)\n", in_smm, found, qfound, port, val); return; } diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 7afd45a9c..a24c1fea2 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -630,6 +630,11 @@ kbd_poll(void *priv) timer_advance_u64(&dev->send_delay_timer, (100ULL * TIMER_USEC)); +#ifdef ENABLE_KEYBOARD_AT_LOG + kbd_log("ATkbd[B]: out_new = %i, out_delayed = %i, STAT_OFULL = %i, qs = %i, qe = %i, last_irq = %08X\n", + dev->out_new, dev->out_delayed, !!(dev->status & STAT_OFULL), key_ctrl_queue_start, key_ctrl_queue_end, dev->last_irq); +#endif + if ((dev->out_new != -1) && !dev->last_irq) { dev->wantirq = 0; if (dev->out_new & 0x100) { @@ -662,6 +667,11 @@ kbd_poll(void *priv) } } +#ifdef ENABLE_KEYBOARD_AT_LOG + kbd_log("ATkbd[A]: out_new = %i, out_delayed = %i, STAT_OFULL = %i, qs = %i, qe = %i, last_irq = %08X\n", + dev->out_new, dev->out_delayed, !!(dev->status & STAT_OFULL), key_ctrl_queue_start, key_ctrl_queue_end, dev->last_irq); +#endif + if (dev->out_new == -1 && !(dev->status & STAT_OFULL) && key_ctrl_queue_start != key_ctrl_queue_end) { dev->out_new = key_ctrl_queue[key_ctrl_queue_start] | 0x200; key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0xf; @@ -692,10 +702,16 @@ kbd_poll(void *priv) static void add_data(atkbd_t *dev, uint8_t val) { +#ifdef ENABLE_KEYBOARD_AT_LOG + kbd_log("ATkbd: add to queue\n"); +#endif key_ctrl_queue[key_ctrl_queue_end] = val; key_ctrl_queue_end = (key_ctrl_queue_end + 1) & 0xf; if (! (dev->out_new & 0x300)) { +#ifdef ENABLE_KEYBOARD_AT_LOG + kbd_log("ATkbd: delay\n"); +#endif dev->out_delayed = dev->out_new; dev->out_new = -1; } @@ -2069,9 +2085,14 @@ do_command: if ((dev->flags & KBC_VEN_MASK) == KBC_VEN_TOSHIBA) dev->status |= STAT_IFULL; if (! dev->initialized) { +#ifdef ENABLE_KEYBOARD_AT_LOG + kbd_log("ATkbd: self-test reinitialization\n"); +#endif dev->initialized = 1; key_ctrl_queue_start = key_ctrl_queue_end = 0; dev->status &= ~STAT_OFULL; + dev->last_irq = 0; + dev->out_new = dev->out_delayed = -1; } dev->status |= STAT_SYSFLAG; dev->mem[0] |= 0x04; diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index e7d302a2a..d53f65170 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -73,6 +73,7 @@ machine_at_atc7020bxii_init(const machine_t *model) return ret; } + int machine_at_63a_init(const machine_t *model) { @@ -108,6 +109,7 @@ machine_at_63a_init(const machine_t *model) return ret; } + int machine_at_apas3_init(const machine_t *model) { @@ -132,13 +134,14 @@ machine_at_apas3_init(const machine_t *model) device_add(&via_apro_device); device_add(&via_vt82c586b_device); device_add(&fdc37c669_device); - device_add(&keyboard_ps2_pci_device); + device_add(&keyboard_ps2_pci_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); return ret; } + #if defined(DEV_BRANCH) && defined(USE_596B) int machine_at_bx98_init(const machine_t *model) diff --git a/src/machine/m_at_socket7_s7.c b/src/machine/m_at_socket7_s7.c index 0a42bab88..beaf13b98 100644 --- a/src/machine/m_at_socket7_s7.c +++ b/src/machine/m_at_socket7_s7.c @@ -302,7 +302,6 @@ machine_at_p55t2s_init(const machine_t *model) } -#if defined(DEV_BRANCH) && defined(USE_TC430HX) int machine_at_tc430hx_init(const machine_t *model) { @@ -367,13 +366,11 @@ machine_at_equium5200_init(const machine_t *model) // Information about that mac device_add(&piix3_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&pc87306_device); - device_add(&intel_flash_bxtw_ami_device); + device_add(&intel_flash_bxt_ami_device); return ret; } -#endif - int machine_at_p55tvp4_init(const machine_t *model) @@ -506,17 +503,17 @@ machine_at_mb520n_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_pci_device); + device_add(&keyboard_ps2_ami_pci_device); device_add(&fdc37c669_device); - device_add(&sst_flash_29ee010_device); + device_add(&intel_flash_bxt_device); return ret; } @@ -705,6 +702,7 @@ machine_at_586t2_init(const machine_t *model) return ret; } + int machine_at_807ds_init(const machine_t *model) { @@ -720,17 +718,117 @@ machine_at_807ds_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(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); /* PIIX4 */ + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i430tx_device); device_add(&piix4_device); - device_add(&keyboard_ps2_pci_device); + device_add(&keyboard_ps2_ami_pci_device); device_add(&um8669f_device); /*Placeholder for ITE 8679*/ device_add(&intel_flash_bxt_device); + hwm_values_t machine_hwm = { + { /* fan speeds */ + 3000, /* Chassis */ + 3000, /* CPU */ + 3000, /* Power */ + 0 + }, { /* temperatures */ + 30, /* MB */ + 0, /* unused */ + 27, /* CPU */ + 0 + }, { /* voltages */ + 3300, /* VCORE (3.3V by default) */ + 0, /* unused */ + 3300, /* +3.3V */ + RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */ + RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */ + RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */ + RESISTOR_DIVIDER(5000, 1, 2), /* -5V (divider values bruteforced) */ + 0 + } + }; + /* Pentium, Pentium OverDrive MMX, Pentium Mobile MMX: 3.3V (real Pentium Mobile MMX is 2.45V). + Pentium MMX: 2.8 V. + AMD K6 Model 6: 2.9 V for 166/200, 3.2 V for 233. + AMD K6 Model 7: 2.2 V. */ + if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUMMMX) + machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Pentium MMX */ + else if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_K6) + machine_hwm.voltages[0] = 2200; /* set higher VCORE (2.8V) for Pentium MMX */ + else if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_K6_2) + machine_hwm.voltages[0] = 2200; /* set higher VCORE (2.8V) for Pentium MMX */ + hwm_set_values(machine_hwm); + device_add(&w83781d_device); + + return ret; +} + + +int +machine_at_p5mms98_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/p5mms98/s981182.rom", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); /* PIIX4 */ + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&i430tx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83977tf_device); + device_add(&intel_flash_bxt_device); + + hwm_values_t machine_hwm = { + { /* fan speeds */ + 3000, /* Chassis */ + 3000, /* CPU */ + 3000, /* Power */ + 0 + }, { /* temperatures */ + 30, /* MB */ + 0, /* unused */ + 27, /* CPU */ + 0 + }, { /* voltages */ + 3300, /* VCORE (3.3V by default) */ + 0, /* unused */ + 3300, /* +3.3V */ + RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */ + RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */ + RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */ + RESISTOR_DIVIDER(5000, 1, 2), /* -5V (divider values bruteforced) */ + 0 + } + }; + /* Pentium, Pentium OverDrive MMX, Pentium Mobile MMX: 3.3V (real Pentium Mobile MMX is 2.45V). + Pentium MMX: 2.8 V. + AMD K6 Model 6: 2.9 V for 166/200, 3.2 V for 233. + AMD K6 Model 7: 2.2 V. */ + if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUMMMX) + machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Pentium MMX */ + else if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_K6) + machine_hwm.voltages[0] = 2200; /* set higher VCORE (2.8V) for Pentium MMX */ + else if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_K6_2) + machine_hwm.voltages[0] = 2200; /* set higher VCORE (2.8V) for Pentium MMX */ + hwm_set_values(machine_hwm); + device_add(&w83781d_device); + return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 5cb5300f2..f0aa632d7 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -219,10 +219,8 @@ const machine_t machines[] = { { "[Socket 7 HX] Acer V35n", "acerv35n", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerv35n_init, NULL }, { "[Socket 7 HX] ASUS P/I-P55T2P4", "p55t2p4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 127, machine_at_p55t2p4_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_TC430HX) { "[Socket 7 HX] TC430HX", "tc430hx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 255, machine_at_tc430hx_init, NULL }, - { "[Socket 7 HX] Toshiba Equium 5200D", "equium5200", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_equium5200_init, NULL }, -#endif + { "[Socket 7 HX] Toshiba Equium 5200D", "equium5200", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_equium5200_init, NULL }, { "[Socket 7 VX] ASUS P/I-P55TVP4", "p55tvp4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55tvp4_init, NULL }, { "[Socket 7 VX] Epox P55-VA", "p55va", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55va_init, NULL }, @@ -235,6 +233,7 @@ const machine_t machines[] = { { "[Socket 7 TX] Intel YM430TX", "ym430tx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_ym430tx_init, NULL }, { "[Socket 7 TX] Iwill P55XB2", "p55xb2", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_p55xb2_init, NULL }, { "[Socket 7 TX] PC Partner TXA807DS", "807ds", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_807ds_init, NULL }, + { "[Socket 7 TX] SuperMicro P5MMS98", "p5mms98", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_p5mms98_init, NULL }, { "[Super 7 MVP3] FIC VA-503+", "ficva503p", MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_mvp3_init, NULL }, diff --git a/src/nvr_at.c b/src/nvr_at.c index 37c8f2ec0..d95a6d7c0 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -293,8 +293,8 @@ typedef struct { int8_t stat; - uint8_t cent; - uint8_t def, flags; + uint8_t cent, def, + flags, read_addr; uint8_t addr[8], wp[2], bank[8], *lock; @@ -707,8 +707,11 @@ nvr_read(uint16_t addr, void *priv) default: ret = nvr->regs[local->addr[addr_id]]; break; - } else + } else { ret = local->addr[addr_id]; + if (!local->read_addr) + ret &= 0x80; + } return(ret); } @@ -816,6 +819,15 @@ nvr_at_sec_handler(int set, uint16_t base, nvr_t *nvr) } +void +nvr_read_addr_set(int set, nvr_t *nvr) +{ + local_t *local = (local_t *) nvr->data; + + local->read_addr = set; +} + + void nvr_wp_set(int set, int h, nvr_t *nvr) { @@ -906,6 +918,8 @@ nvr_at_init(const device_t *info) break; } + local->read_addr = 1; + /* Set up any local handlers here. */ nvr->reset = nvr_reset; nvr->start = nvr_start; diff --git a/src/pci.c b/src/pci.c index a90c8fd5b..f0b411d71 100644 --- a/src/pci.c +++ b/src/pci.c @@ -94,6 +94,7 @@ pci_log(const char *fmt, ...) static void pci_cf8_write(uint16_t port, uint32_t val, void *priv) { + pci_log("cf8 write: %08X\n", val); pci_index = val & 0xff; pci_func = (val >> 8) & 7; pci_card = (val >> 11) & 31; @@ -115,11 +116,15 @@ pci_write(uint16_t port, uint8_t val, void *priv) { uint8_t slot = 0; + if (in_smm) + pci_log("(%i) %03x write: %02X\n", pci_enable, port, val); + switch (port) { case 0xcfc: case 0xcfd: case 0xcfe: case 0xcff: if (! pci_enable) return; + pci_log("Writing %02X to PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", val, pci_bus, pci_card, slot, pci_func, pci_index); if (! pci_bus) { slot = pci_card_to_slot_mapping[pci_card]; if (slot != 0xff) { @@ -147,6 +152,10 @@ static uint8_t pci_read(uint16_t port, void *priv) { uint8_t slot = 0; + uint8_t ret = 0xff; + + if (in_smm) + pci_log("(%i) %03x read\n", pci_enable, port); switch (port) { case 0xcfc: case 0xcfd: case 0xcfe: case 0xcff: @@ -157,7 +166,7 @@ pci_read(uint16_t port, void *priv) slot = pci_card_to_slot_mapping[pci_card]; if (slot != 0xff) { if (pci_cards[slot].read) - return pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); + ret = pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); #ifdef ENABLE_PCI_LOG else pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); @@ -169,10 +178,10 @@ pci_read(uint16_t port, void *priv) #endif } - return 0xff; + pci_log("Reading %02X, from PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", ret, pci_bus, pci_card, slot, pci_func, pci_index); } - return 0xff; + return ret; } @@ -643,6 +652,20 @@ pci_slots_clear(void) } +uint32_t +trc_readl(uint16_t port, void *priv) +{ + return 0xffffffff; +} + + +uint16_t +trc_readw(uint16_t port, void *priv) +{ + return 0xffff; +} + + uint8_t trc_read(uint16_t port, void *priv) { @@ -671,10 +694,23 @@ trc_reset(uint8_t val) } +void +trc_writel(uint16_t port, uint32_t val, void *priv) +{ +} + + +void +trc_writew(uint16_t port, uint16_t val, void *priv) +{ +} + + void trc_write(uint16_t port, uint8_t val, void *priv) { pci_log("TRC Write: %02X\n", val); + pci_log("TRC Write: %02X\n", val); if (!(trc_reg & 4) && (val & 4)) trc_reset(val); @@ -692,7 +728,7 @@ trc_init(void) trc_reg = 0; io_sethandler(0x0cf9, 0x0001, - trc_read, NULL, NULL, trc_write, NULL, NULL, NULL); + trc_read, trc_readw, trc_readl, trc_write, trc_writew, trc_writel, NULL); } diff --git a/src/pic.c b/src/pic.c index dd0fe83b0..b740406ed 100644 --- a/src/pic.c +++ b/src/pic.c @@ -467,6 +467,9 @@ picint_common(uint16_t num, int level) if (level) pic_current |= num; + if (AT && (cpu_fast_off_flags & num)) + cpu_fast_off_count = cpu_fast_off_val + 1; + if (num>0xFF) { if (!AT) return; diff --git a/src/pit.c b/src/pit.c index d07b38c72..91691d5bc 100644 --- a/src/pit.c +++ b/src/pit.c @@ -44,7 +44,8 @@ pit_t *pit, *pit2; double cpuclock, PITCONSTD, SYSCLK, isa_timing, - bus_timing, pci_timing; + bus_timing, pci_timing, + PCICLK; uint64_t PITCONST, ISACONST, CGACONST, @@ -1030,6 +1031,9 @@ pit_set_clock(int clock) bus_timing = (cpuclock / (double)cpu_busspeed); pci_timing = (cpuclock / (double)cpu_pci_speed); + /* PCICLK in us for use with timer_on_auto(). */ + PCICLK = pci_timing / (cpuclock / 1000000.0); + if (cpu_busspeed >= 30000000) SYSCLK = bus_timing * 4.0; else diff --git a/src/rom.c b/src/rom.c index bea052b7f..f8c4586ce 100644 --- a/src/rom.c +++ b/src/rom.c @@ -377,7 +377,6 @@ bios_load_linear_combined(wchar_t *fn1, wchar_t *fn2, int sz, int off) } -#if defined(DEV_BRANCH) && defined(USE_TC430HX) int bios_load_linear_combined2(wchar_t *fn1, wchar_t *fn2, wchar_t *fn3, wchar_t *fn4, wchar_t *fn5, int sz, int off) { @@ -391,7 +390,6 @@ bios_load_linear_combined2(wchar_t *fn1, wchar_t *fn2, wchar_t *fn3, wchar_t *fn return ret; } -#endif int diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index d92d028ec..5ddd38b7c 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -74,9 +74,6 @@ ifeq ($(DEV_BUILD), y) ifndef TI TI := y endif - ifndef TC430HX - TC430HX := y - endif ifndef VECTRA54 VECTRA54 := y endif @@ -141,9 +138,6 @@ else ifndef TI TI := n endif - ifndef TC430HX - TC430HX := n - endif ifndef VECTRA54 VECTRA54 := n endif @@ -493,10 +487,6 @@ ifeq ($(TI), y) OPTS += -DUSE_TI endif -ifeq ($(TC430HX), y) -OPTS += -DUSE_TC430HX -endif - ifeq ($(VECTRA54), y) OPTS += -DUSE_VECTRA54 endif diff --git a/src/win/Makefile_ndr.mingw b/src/win/Makefile_ndr.mingw index ccc00515c..5f4c8b6d7 100644 --- a/src/win/Makefile_ndr.mingw +++ b/src/win/Makefile_ndr.mingw @@ -74,9 +74,6 @@ ifeq ($(DEV_BUILD), y) ifndef TI TI := y endif - ifndef TC430HX - TC430HX := y - endif ifndef VECTRA54 VECTRA54 := y endif @@ -141,9 +138,6 @@ else ifndef TI TI := n endif - ifndef TC430HX - TC430HX := n - endif ifndef VECTRA54 VECTRA54 := n endif @@ -502,10 +496,6 @@ ifeq ($(TI), y) OPTS += -DUSE_TI endif -ifeq ($(TC430HX), y) -OPTS += -DUSE_TC430HX -endif - ifeq ($(VECTRA54), y) OPTS += -DUSE_VECTRA54 endif