From d9bc0756580b2cf03d24108d20a08e5290e37481 Mon Sep 17 00:00:00 2001 From: Daniel Gurney Date: Wed, 15 Apr 2020 13:04:02 +0300 Subject: [PATCH 1/5] Readme wording fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a51b889ee..9defdb0d2 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ guide: 6. Run `make -jN -f win/makefile.mingw` to start the actual compilation process. Substitute `N` with the number of threads you want to use for the compilation process. The optimal number depends entirely on your processor, and it is - up to you to determine the optimal number. A good starting point is the total + up to you to determine it. A good starting point is the total number of threads (AKA Logical Processors) you have available. 7. If the compilation succeeded (which it almost always should), you will find `86Box.exe` in the src directory. From cf581db7ab6f5cc08a36bfed732b1f0b7295ea7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Wed, 15 Apr 2020 23:42:20 +0200 Subject: [PATCH 2/5] prt_ps: Rewrite non-printable character processing Should fix hangs and slowdowns during printing. --- src/printer/prt_ps.c | 60 ++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index 1003907c3..ffbcdddff 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -246,45 +246,39 @@ ps_write_data(uint8_t val, void *p) dev->data = (char) val; } -static bool -process_nonprintable(ps_t *dev) -{ - switch (dev->data) { - case '\b': - dev->buffer_pos--; - break; - case '\r': - dev->buffer_pos = 0; - if (dev->autofeed) - write_buffer(dev, true); - break; - case '\v': - case '\f': - case '\n': - write_buffer(dev, true); - break; - case 0x04: // Ctrl+D - write_buffer(dev, false); - finish_document(dev); - break; - - /* Characters that should be written to the buffer as-is */ - case '\t': - return false; - } - - return true; -} - static void process_data(ps_t *dev) { + /* Check for non-printable characters */ if (dev->data < 0x20 || dev->data == 0x7F) { - if (process_nonprintable(dev)) - return; + switch (dev->data) { + /* The following characters are considered white-space + by the PostScript specification */ + case '\t': + case '\n': + case '\f': + case '\r': + break; + + /* Same with NUL, except we better change it to a space first */ + case '\0': + dev->data = ' '; + break; + + /* Ctrl+D (0x04) marks the end of the document */ + case '\4': + write_buffer(dev, false); + finish_document(dev); + return; + + /* Don't bother with the others */ + default: + return; + } } - if (dev->buffer_pos == POSTSCRIPT_BUFFER_LENGTH) { + /* Flush the buffer if we have run to its end */ + if (dev->buffer_pos == POSTSCRIPT_BUFFER_LENGTH - 1) { write_buffer(dev, false); dev->buffer_pos = 0; } From ef9fc196ed072bd205752b2c999c1e9d67c38168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Wed, 15 Apr 2020 23:46:11 +0200 Subject: [PATCH 3/5] prt_ps: Re-add error message for missing gsdll32 --- src/win/86Box.rc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/win/86Box.rc b/src/win/86Box.rc index f1416f3f9..30a8edfa2 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -915,6 +915,7 @@ BEGIN IDS_2120 "Unable to initialize SDL, SDL2.dll is required" IDS_2121 "Are you sure you want to hard reset the emulated machine?" IDS_2122 "Are you sure you want to quit 86Box?" + IDS_2123 "Unable to initialize Ghostscript, gsdll32.dll is required for automatic convertion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript files (.ps)." IDS_2124 "MO %i (%03i): %ls" IDS_2125 "MO images (*.IM?)\0*.IM?\0All files (*.*)\0*.*\0" END From 8b230b7371ecdaa68c65edf064b9aed37fa7041b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Wed, 15 Apr 2020 23:47:30 +0200 Subject: [PATCH 4/5] prt_ps: Fix two dots in PDF extension --- src/printer/prt_ps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index ffbcdddff..8057213eb 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -140,7 +140,7 @@ convert_to_pdf(ps_t *dev) output_fn[0] = 0; wcscat(output_fn, input_fn); - wcscpy(output_fn + wcslen(output_fn) - 3, L".pdf"); + wcscpy(output_fn + wcslen(output_fn) - 4, L".pdf"); gsargv[0] = L""; gsargv[1] = L"-dNOPAUSE"; From 275dd5a2f7cc13dff69719aac225499c4891f27b Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 16 Apr 2020 21:56:19 +0200 Subject: [PATCH 5/5] ACPI, SMM, and PIIX fixes, fixes quite a few boards, also fixed the Via Apollo series northbridge ID's, some CPU instructions on both 808x and 286+, and added SMM to 486's (Intel and AMD), WinChip and WinChip 2, and VIA Cyrix III, also removed the TC430HX and the Toshiba machine from the Dev branch. --- src/acpi.c | 139 +++++++++-------- src/chipset/via_apollo.c | 3 +- src/cpu_common/386.c | 4 + src/cpu_common/386_common.c | 32 +++- src/cpu_common/386_dynarec.c | 18 ++- src/cpu_common/386_dynarec_ops.c | 2 - src/cpu_common/808x.c | 73 +++++---- src/cpu_common/cpu.c | 14 +- src/cpu_common/cpu.h | 5 +- src/cpu_common/cpu_table.c | 20 +-- src/cpu_common/x86_ops_atomic.h | 42 ++--- src/cpu_common/x86_ops_bcd.h | 48 ++++-- src/disk/hdc_esdi_at.c | 55 ++++--- src/disk/hdc_ide.c | 65 ++++---- src/disk/hdc_st506_at.c | 54 ++++--- src/dma.c | 8 +- src/include/86box/acpi.h | 7 + src/include/86box/intel_flash.h | 3 - src/include/86box/machine.h | 6 +- src/include/86box/nvr.h | 1 + src/include/86box/pit.h | 2 +- src/include/86box/rom.h | 2 - src/intel_flash.c | 14 -- src/intel_piix.c | 169 ++++++++++++++++---- src/io.c | 257 ++++++++++++++++++------------- src/keyboard_at.c | 21 +++ src/machine/m_at_socket370.c | 5 +- src/machine/m_at_socket7_s7.c | 122 +++++++++++++-- src/machine/machine_table.c | 5 +- src/nvr_at.c | 20 ++- src/pci.c | 44 +++++- src/pic.c | 3 + src/pit.c | 6 +- src/rom.c | 2 - src/win/Makefile.mingw | 10 -- src/win/Makefile_ndr.mingw | 10 -- 36 files changed, 862 insertions(+), 429 deletions(-) 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