From 332dfd97433c7c93819beeb5bf2d5c0c356b32ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Fri, 26 Jun 2020 22:12:15 +0200 Subject: [PATCH 01/54] win: Fix MSVC build --- src/win/86Box.rc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/win/86Box.rc b/src/win/86Box.rc index 9b0d829eb..62031c373 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -164,7 +164,7 @@ BEGIN #endif POPUP "&Help" BEGIN - MENUITEM "&About " EMU_NAME "...", IDM_ABOUT + MENUITEM "&About 86Box...", IDM_ABOUT END END @@ -319,7 +319,7 @@ END DLG_CONFIG DIALOG DISCARDABLE 0, 0, 366, 251 STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION EMU_NAME " Settings" +CAPTION "86Box Settings" FONT 9, "Segoe UI" BEGIN DEFPUSHBUTTON "OK",IDOK,246,230,50,14 @@ -878,7 +878,7 @@ END STRINGTABLE DISCARDABLE BEGIN - 2048 EMU_NAME + 2048 "86Box" IDS_2049 "Error" IDS_2050 "Fatal error" IDS_2051 "Are you sure you want to save the settings?" @@ -886,7 +886,7 @@ BEGIN IDS_2053 "Speed" IDS_2054 "ZIP %03i %i (%s): %ls" IDS_2055 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 EMU_NAME " could not find any usable ROM images.\n\nPlease download a ROM set from " EMU_ROMS_URL " and extract it into the ""roms"" directory." + IDS_2056 "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the ""roms"" directory." IDS_2057 "(empty)" IDS_2058 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0All files (*.*)\0*.*\0" IDS_2059 "Turbo" @@ -951,19 +951,19 @@ BEGIN IDS_2110 "Unable to initialize FreeType" IDS_2111 "Unable to initialize SDL, SDL2.dll is required" IDS_2112 "Are you sure you want to hard reset the emulated machine?" - IDS_2113 "Are you sure you want to exit " EMU_NAME "?" + IDS_2113 "Are you sure you want to exit 86Box?" IDS_2114 "Unable to initialize Ghostscript" IDS_2115 "MO %i (%03i): %ls" IDS_2116 "MO images (*.IM?)\0*.IM?\0All files (*.*)\0*.*\0" - IDS_2117 "Welcome to " EMU_NAME "!" + IDS_2117 "Welcome to 86Box!" IDS_2118 "Internal controller" IDS_2119 "Exit" IDS_2120 "No ROMs found" IDS_2121 "Save changes\nThis will hard reset the emulated machine." IDS_2122 "Discard changes\nAll changes made to the settings will be lost." IDS_2123 "Cancel\nGo back to the Settings window." - IDS_2124 "About " EMU_NAME - IDS_2125 EMU_NAME " v" EMU_VERSION + IDS_2124 "About 86Box" + IDS_2125 "86Box v2.10" IDS_2126 "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information." IDS_2127 "OK" IDS_2128 "Hardware not available" @@ -1104,9 +1104,9 @@ BEGIN VALUE "FileDescription", EMU_NAME "\0" VALUE "FileVersion", EMU_VERSION "\0" VALUE "InternalName", EMU_NAME "\0" - VALUE "LegalCopyright", "Copyright © 2007-" COPYRIGHT_YEAR " " EMU_NAME " contributors\0" - VALUE "OriginalFilename", EMU_NAME ".exe\0" - VALUE "ProductName", EMU_NAME " Emulator\0" + VALUE "LegalCopyright", "Copyright © 2007-2020 " EMU_NAME " contributors\0" + VALUE "OriginalFilename", "86box.exe\0" + VALUE "ProductName", EMU_NAME "\0" VALUE "ProductVersion", EMU_VERSION "\0" END END From 5115214d01398150e01d1cf4e0ebc75f66e86ea9 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 18:05:27 -0300 Subject: [PATCH 02/54] DRB locking implementation --- src/chipset/intel_420ex.c | 33 +++++++++++- src/chipset/intel_4x0.c | 103 +++++++++++++++++++++++++++++++++++--- src/include/86box/spd.h | 3 ++ src/mem/spd.c | 103 ++++++++++++++++++++++---------------- 4 files changed, 191 insertions(+), 51 deletions(-) diff --git a/src/chipset/intel_420ex.c b/src/chipset/intel_420ex.c index ca872599d..9aa41adad 100644 --- a/src/chipset/intel_420ex.c +++ b/src/chipset/intel_420ex.c @@ -32,6 +32,7 @@ #include <86box/hdc.h> #include <86box/machine.h> #include <86box/chipset.h> +#include <86box/spd.h> #define MEM_STATE_SHADOW_R 0x01 @@ -179,6 +180,33 @@ i420ex_smram_handler_phase1(i420ex_t *dev) } +static void +i420ex_write_drbs(i420ex_t *dev) +{ + uint8_t row, dimm; + uint16_t size, vslots[SPD_MAX_SLOTS]; + + /* No SPD: let the SPD code split SIMMs into pairs as if they were "DIMM"s. */ + dimm = (4 + 1) >> 1; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */ + spd_populate(vslots, dimm, (mem_size >> 10), 1, 1 << (log2_ui16(machines[machine].max_ram / dimm)), 0); + + /* Write DRBs for each row. */ + i420ex_log("Writing DRBs...\n"); + for (row = 0; row <= 4; row++) { + dimm = (row >> 1); + + /* No SPD: use the values calculated above. */ + size = (vslots[dimm] >> 1); + + /* Populate DRB register, adding the previous DRB's value.. */ + dev->regs[0x60 | row] = ((row > 0) ? dev->regs[0x60 | (row - 1)] : 0); + if (size) + dev->regs[0x60 | row] += size; + i420ex_log("DRB[%d] = %d MB (%02Xh raw)\n", row, size, dev->regs[0x60 | row]); + } +} + + static void i420ex_write(int func, int addr, uint8_t val, void *priv) { @@ -232,8 +260,6 @@ i420ex_write(int func, int addr, uint8_t val, void *priv) break; case 0x4c: case 0x51: case 0x57: - case 0x60: case 0x61: case 0x62: case 0x63: - case 0x64: case 0x68: case 0x69: dev->regs[addr] = val; if (addr == 0x4c) { @@ -306,6 +332,9 @@ i420ex_write(int func, int addr, uint8_t val, void *priv) i420ex_map(0xec000, 0x04000, val >> 4); dev->regs[0x5f] = val; break; + case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: + i420ex_write_drbs(dev); + break; case 0x66: case 0x67: i420ex_log("Set IRQ routing: INT %c -> %02X\n", 0x41 + (addr & 0x01), val); dev->regs[addr] = val & 0x8f; diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index a65e06dd3..e6009107d 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -6,7 +6,7 @@ * * This file is part of the 86Box distribution. * - * Implementation of the Intel PCISet chips from 420TX to 440BX. + * Implementation of the Intel PCISet chips from 420TX to 440GX. * * * @@ -28,6 +28,8 @@ #include <86box/device.h> #include <86box/keyboard.h> #include <86box/chipset.h> +#include <86box/spd.h> +#include <86box/machine.h> enum @@ -52,12 +54,32 @@ typedef struct { uint8_t pm2_cntrl, max_func, smram_locked, max_drb, - drb_default; + drb_unit, drb_default; uint8_t regs[2][256], regs_locked[2][256]; int type; } i4x0_t; +#ifdef ENABLE_I4X0_LOG +int i4x0_do_log = ENABLE_I4X0_LOG; + + +static void +i4x0_log(const char *fmt, ...) +{ + va_list ap; + + if (i4x0_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define i4x0_log(fmt, ...) +#endif + + static void i4x0_map(uint32_t addr, uint32_t size, int state) { @@ -247,6 +269,47 @@ pm2_cntrl_write(uint16_t addr, uint8_t val, void *p) } +static void +i4x0_write_drbs(i4x0_t *dev) +{ + uint8_t row, dimm; + uint16_t size, vslots[SPD_MAX_SLOTS]; + + /* No SPD: let the SPD code split SIMMs into pairs as if they were "DIMM"s. */ + if (!spd_present) { + dimm = (dev->max_drb + 1) >> 1; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */ + spd_populate(vslots, dimm, (mem_size >> 10), dev->drb_unit, 1 << (log2_ui16(machines[machine].max_ram / dimm)), 0); + } + + /* Write DRBs for each row. */ + i4x0_log("Writing DRBs... unit=%d max=%d\n", dev->drb_unit, dev->max_drb); + for (row = 0; row <= dev->max_drb; row++) { + dimm = (row >> 1); + size = 0; + + if (spd_present) { + /* SPD enabled: use SPD info for this slot, if present. */ + if (spd_devices[dimm]) { + if (spd_devices[dimm]->row1 < dev->drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */ + size = ((row & 1) ? 0 : dev->drb_unit); + else + size = ((row & 1) ? spd_devices[dimm]->row2 : spd_devices[dimm]->row1); + } + } else { + /* No SPD: use the values calculated above. */ + size = (vslots[dimm] >> 1); + } + + /* Populate DRB register, adding the previous DRB's value. + This will intentionally overflow on 440GX with 2 GB. */ + dev->regs[0][0x60 | row] = ((row > 0) ? dev->regs[0][0x60 | (row - 1)] : 0); + if (size) + dev->regs[0][0x60 | row] += (size / dev->drb_unit); + i4x0_log("DRB[%d] = %d MB (%02Xh raw)\n", row, size, dev->regs[0][0x60 | row]); + } +} + + static void i4x0_write(int func, int addr, uint8_t val, void *priv) { @@ -627,13 +690,17 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) regs[0x5f] = val & 0x77; break; case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: + if ((addr & 0x7) <= dev->max_drb) { + i4x0_write_drbs(dev); + break; + } switch (dev->type) { case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: case INTEL_430HX: case INTEL_440FX: case INTEL_440LX: case INTEL_440EX: - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440ZX: default: regs[addr] = val; break; @@ -646,13 +713,17 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) } break; case 0x65: + if ((addr & 0x7) <= dev->max_drb) { + i4x0_write_drbs(dev); + break; + } switch (dev->type) { case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: case INTEL_430HX: case INTEL_440FX: case INTEL_440LX: case INTEL_440EX: - case INTEL_440GX: + case INTEL_440GX: case INTEL_440BX: case INTEL_440ZX: regs[addr] = val; break; @@ -665,6 +736,10 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) } break; case 0x66: + if ((addr & 0x7) <= dev->max_drb) { + i4x0_write_drbs(dev); + break; + } switch (dev->type) { case INTEL_430NX: case INTEL_430HX: case INTEL_440FX: case INTEL_440LX: @@ -675,12 +750,16 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) } break; case 0x67: + if ((addr & 0x7) <= dev->max_drb) { + i4x0_write_drbs(dev); + break; + } switch (dev->type) { case INTEL_430NX: case INTEL_430HX: case INTEL_440FX: case INTEL_440LX: case INTEL_440EX: case INTEL_440BX: case INTEL_440GX: - case INTEL_440ZX: + case INTEL_440ZX: regs[addr] = val; break; case INTEL_430VX: @@ -1305,6 +1384,7 @@ static void regs[0x59] = 0x0f; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02; dev->max_drb = 5; + dev->drb_unit = 4; dev->drb_default = 0x02; break; case INTEL_430LX: @@ -1323,6 +1403,7 @@ static void regs[0x59] = 0x0f; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02; dev->max_drb = 5; + dev->drb_unit = 4; dev->drb_default = 0x02; break; case INTEL_430NX: @@ -1343,6 +1424,7 @@ static void regs[0x59] = 0x0f; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; dev->max_drb = 7; + dev->drb_unit = 4; dev->drb_default = 0x02; break; case INTEL_430FX: @@ -1358,6 +1440,7 @@ static void regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = 0x02; regs[0x72] = 0x02; dev->max_drb = 4; + dev->drb_unit = 4; dev->drb_default = 0x02; break; case INTEL_430HX: @@ -1372,6 +1455,7 @@ static void regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; regs[0x72] = 0x02; dev->max_drb = 7; + dev->drb_unit = 4; dev->drb_default = 0x02; break; case INTEL_430VX: @@ -1393,6 +1477,7 @@ static void regs[0x74] = 0x0e; regs[0x78] = 0x23; dev->max_drb = 4; + dev->drb_unit = 4; dev->drb_default = 0x02; break; case INTEL_430TX: @@ -1410,6 +1495,7 @@ static void regs[0x70] = 0x20; regs[0x72] = 0x02; dev->max_drb = 5; + dev->drb_unit = 4; dev->drb_default = 0x02; break; case INTEL_440FX: @@ -1426,6 +1512,7 @@ static void regs[0x71] = 0x10; regs[0x72] = 0x02; dev->max_drb = 7; + dev->drb_unit = 8; dev->drb_default = 0x02; break; case INTEL_440LX: @@ -1450,12 +1537,13 @@ static void regs[0xa5] = 0x02; regs[0xa7] = 0x1f; dev->max_drb = 7; + dev->drb_unit = 8; dev->drb_default = 0x01; break; case INTEL_440EX: dev->max_func = 1; - regs[0x02] = 0x80; regs[0x03] = 0x71; /* 82443EX. Same Vendor ID as 440LX*/ + regs[0x02] = 0x80; regs[0x03] = 0x71; /* 82443EX. Same Vendor ID as 440LX */ regs[0x06] = 0x90; regs[0x10] = 0x08; regs[0x34] = 0xa0; @@ -1474,6 +1562,7 @@ static void regs[0xa5] = 0x02; regs[0xa7] = 0x1f; dev->max_drb = 7; + dev->drb_unit = 8; dev->drb_default = 0x01; break; case INTEL_440BX: case INTEL_440ZX: @@ -1502,6 +1591,7 @@ static void regs[0xa5] = 0x02; regs[0xa7] = 0x1f; dev->max_drb = 7; + dev->drb_unit = 8; dev->drb_default = 0x01; break; case INTEL_440GX: @@ -1527,6 +1617,7 @@ static void regs[0xa5] = 0x02; regs[0xa7] = 0x1f; dev->max_drb = 7; + dev->drb_unit = 8; dev->drb_default = 0x01; break; } diff --git a/src/include/86box/spd.h b/src/include/86box/spd.h index 098fb3ed7..cec4e9c18 100644 --- a/src/include/86box/spd.h +++ b/src/include/86box/spd.h @@ -100,9 +100,12 @@ typedef struct _spd_sdram_ { } spd_sdram_t; +extern int spd_present; extern spd_t *spd_devices[SPD_MAX_SLOTS]; +extern uint8_t log2_ui16(uint16_t i); +extern void spd_populate(uint16_t *vslots, uint8_t slot_count, uint16_t total_size, uint16_t min_module_size, uint16_t max_module_size, uint8_t enable_asym); extern void spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size); diff --git a/src/mem/spd.c b/src/mem/spd.c index 84ba3eb84..5d26d7364 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -31,6 +31,7 @@ #define SPD_ROLLUP(x) ((x) >= 16 ? ((x) - 15) : (x)) +int spd_present = 0; spd_t *spd_devices[SPD_MAX_SLOTS]; uint8_t spd_data[SPD_MAX_SLOTS][SPD_DATA_SIZE]; @@ -156,41 +157,13 @@ comp_ui16_rev(const void *elem1, const void *elem2) void -spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) +spd_populate(uint16_t *vslots, uint8_t slot_count, uint16_t total_size, uint16_t min_module_size, uint16_t max_module_size, uint8_t enable_asym) { - uint8_t slot, slot_count, vslot, next_empty_vslot, i, split; - uint16_t min_module_size, total_size, vslots[SPD_MAX_SLOTS], asym; - device_t *info; - spd_edo_t *edo_data; - spd_sdram_t *sdram_data; - - /* determine the minimum module size for this RAM type */ - switch (ram_type) { - case SPD_TYPE_FPM: - case SPD_TYPE_EDO: - min_module_size = SPD_MIN_SIZE_EDO; - break; - - case SPD_TYPE_SDRAM: - min_module_size = SPD_MIN_SIZE_SDRAM; - break; - - default: - spd_log("SPD: unknown RAM type 0x%02X\n", ram_type); - return; - } - - /* count how many (real) slots are enabled */ - slot_count = 0; - for (slot = 0; slot < SPD_MAX_SLOTS; slot++) { - vslots[slot] = 0; - if (slot_mask & (1 << slot)) { - slot_count++; - } - } + uint8_t vslot, next_empty_vslot, split, i; + uint16_t asym; /* populate vslots with modules in power-of-2 capacities */ - total_size = (mem_size >> 10); + memset(vslots, 0x00, SPD_MAX_SLOTS << 1); for (vslot = 0; vslot < slot_count && total_size; vslot++) { /* populate slot */ vslots[vslot] = (1 << log2_ui16(MIN(total_size, max_module_size))); @@ -205,15 +178,17 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) /* did we populate all the RAM? */ if (total_size) { - /* work backwards to add the missing RAM as asymmetric modules */ - vslot = slot_count - 1; - do { - asym = (1 << log2_ui16(MIN(total_size, vslots[vslot]))); - if (vslots[vslot] + asym <= max_module_size) { - vslots[vslot] += asym; - total_size -= asym; - } - } while (vslot-- > 0 && total_size); + /* work backwards to add the missing RAM as asymmetric modules if possible */ + if (enable_asym) { + vslot = slot_count - 1; + do { + asym = (1 << log2_ui16(MIN(total_size, vslots[vslot]))); + if (vslots[vslot] + asym <= max_module_size) { + vslots[vslot] += asym; + total_size -= asym; + } + } while ((vslot-- > 0) && total_size); + } if (total_size) /* still not enough */ spd_log("SPD: not enough RAM slots (%d) to cover memory (%d MB short)\n", slot_count, total_size); @@ -241,12 +216,52 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) spd_log("SPD: splitting vslot %d (%d MB) into %d and %d (%d MB each)\n", vslot, vslots[vslot], vslot, next_empty_vslot, (vslots[vslot] >> 1)); vslots[vslot] = vslots[next_empty_vslot] = (vslots[vslot] >> 1); split = 1; + break; } - /* re-sort vslots by descending capacity if any modules were split */ + /* sort vslots by descending capacity if any were split */ if (split) qsort(vslots, slot_count, sizeof(uint16_t), comp_ui16_rev); } +} + + +void +spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) +{ + uint8_t slot, slot_count, vslot, i; + uint16_t min_module_size, vslots[SPD_MAX_SLOTS], asym; + device_t *info; + spd_edo_t *edo_data; + spd_sdram_t *sdram_data; + + /* determine the minimum module size for this RAM type */ + switch (ram_type) { + case SPD_TYPE_FPM: + case SPD_TYPE_EDO: + min_module_size = SPD_MIN_SIZE_EDO; + break; + + case SPD_TYPE_SDRAM: + min_module_size = SPD_MIN_SIZE_SDRAM; + break; + + default: + spd_log("SPD: unknown RAM type 0x%02X\n", ram_type); + return; + } + + /* count how many (real) slots are enabled */ + slot_count = 0; + for (slot = 0; slot < SPD_MAX_SLOTS; slot++) { + vslots[slot] = 0; + if (slot_mask & (1 << slot)) { + slot_count++; + } + } + + /* populate vslots */ + spd_populate(vslots, slot_count, (mem_size >> 10), min_module_size, max_module_size, 1); /* register SPD devices and populate their data according to the vslots */ vslot = 0; @@ -377,7 +392,9 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) break; } - device_add(info); + //device_add(info); vslot++; } + + spd_present = 1; } From 84e378695a67940c6225676dfe525868942b6ae9 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 18:24:15 -0300 Subject: [PATCH 03/54] Fix SPD presence detection --- src/mem/spd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mem/spd.c b/src/mem/spd.c index ae81c5d67..244441712 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -118,6 +118,8 @@ spd_close(void *priv) spd_write_byte, NULL, NULL, NULL, dev); + spd_present = 0; + free(dev); } @@ -134,6 +136,8 @@ spd_init(const device_t *info) spd_write_byte, NULL, NULL, NULL, dev); + spd_present = 1; + return dev; } @@ -396,6 +400,4 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) //device_add(info); vslot++; } - - spd_present = 1; } From 2553dbce8f43bb9d5f6c6f7538e873d6af414017 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 21:03:46 -0300 Subject: [PATCH 04/54] Unified DRB locking logic, added DRB locking to VIA VPX, and fixed SPD --- src/chipset/intel_420ex.c | 29 +------------------- src/chipset/intel_4x0.c | 50 +++-------------------------------- src/chipset/via_vpx.c | 6 +++++ src/include/86box/spd.h | 7 +---- src/machine/m_at_socket7_s7.c | 1 + src/mem/spd.c | 48 +++++++++++++++++++++++++++++++-- 6 files changed, 59 insertions(+), 82 deletions(-) diff --git a/src/chipset/intel_420ex.c b/src/chipset/intel_420ex.c index 9aa41adad..2c475c08b 100644 --- a/src/chipset/intel_420ex.c +++ b/src/chipset/intel_420ex.c @@ -180,33 +180,6 @@ i420ex_smram_handler_phase1(i420ex_t *dev) } -static void -i420ex_write_drbs(i420ex_t *dev) -{ - uint8_t row, dimm; - uint16_t size, vslots[SPD_MAX_SLOTS]; - - /* No SPD: let the SPD code split SIMMs into pairs as if they were "DIMM"s. */ - dimm = (4 + 1) >> 1; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */ - spd_populate(vslots, dimm, (mem_size >> 10), 1, 1 << (log2_ui16(machines[machine].max_ram / dimm)), 0); - - /* Write DRBs for each row. */ - i420ex_log("Writing DRBs...\n"); - for (row = 0; row <= 4; row++) { - dimm = (row >> 1); - - /* No SPD: use the values calculated above. */ - size = (vslots[dimm] >> 1); - - /* Populate DRB register, adding the previous DRB's value.. */ - dev->regs[0x60 | row] = ((row > 0) ? dev->regs[0x60 | (row - 1)] : 0); - if (size) - dev->regs[0x60 | row] += size; - i420ex_log("DRB[%d] = %d MB (%02Xh raw)\n", row, size, dev->regs[0x60 | row]); - } -} - - static void i420ex_write(int func, int addr, uint8_t val, void *priv) { @@ -333,7 +306,7 @@ i420ex_write(int func, int addr, uint8_t val, void *priv) dev->regs[0x5f] = val; break; case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: - i420ex_write_drbs(dev); + spd_write_drbs(dev->regs, 0x60, 0x64, 1); break; case 0x66: case 0x67: i420ex_log("Set IRQ routing: INT %c -> %02X\n", 0x41 + (addr & 0x01), val); diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index a9d38d553..5c4f5662f 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -29,7 +29,6 @@ #include <86box/keyboard.h> #include <86box/chipset.h> #include <86box/spd.h> -#include <86box/machine.h> enum @@ -269,47 +268,6 @@ pm2_cntrl_write(uint16_t addr, uint8_t val, void *p) } -static void -i4x0_write_drbs(i4x0_t *dev) -{ - uint8_t row, dimm; - uint16_t size, vslots[SPD_MAX_SLOTS]; - - /* No SPD: let the SPD code split SIMMs into pairs as if they were "DIMM"s. */ - if (!spd_present) { - dimm = (dev->max_drb + 1) >> 1; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */ - spd_populate(vslots, dimm, (mem_size >> 10), dev->drb_unit, 1 << (log2_ui16(machines[machine].max_ram / dimm)), 0); - } - - /* Write DRBs for each row. */ - i4x0_log("Writing DRBs... unit=%d max=%d\n", dev->drb_unit, dev->max_drb); - for (row = 0; row <= dev->max_drb; row++) { - dimm = (row >> 1); - size = 0; - - if (spd_present) { - /* SPD enabled: use SPD info for this slot, if present. */ - if (spd_devices[dimm]) { - if (spd_devices[dimm]->row1 < dev->drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */ - size = ((row & 1) ? 0 : dev->drb_unit); - else - size = ((row & 1) ? spd_devices[dimm]->row2 : spd_devices[dimm]->row1); - } - } else { - /* No SPD: use the values calculated above. */ - size = (vslots[dimm] >> 1); - } - - /* Populate DRB register, adding the previous DRB's value. - This will intentionally overflow on 440GX with 2 GB. */ - dev->regs[0][0x60 | row] = ((row > 0) ? dev->regs[0][0x60 | (row - 1)] : 0); - if (size) - dev->regs[0][0x60 | row] += (size / dev->drb_unit); - i4x0_log("DRB[%d] = %d MB (%02Xh raw)\n", row, size, dev->regs[0][0x60 | row]); - } -} - - static void i4x0_write(int func, int addr, uint8_t val, void *priv) { @@ -692,7 +650,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: if ((addr & 0x7) <= dev->max_drb) { - i4x0_write_drbs(dev); + spd_write_drbs(regs, 0x60, 0x60 + dev->max_drb, dev->drb_unit); break; } switch (dev->type) { @@ -715,7 +673,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0x65: if ((addr & 0x7) <= dev->max_drb) { - i4x0_write_drbs(dev); + spd_write_drbs(regs, 0x60, 0x60 + dev->max_drb, dev->drb_unit); break; } switch (dev->type) { @@ -738,7 +696,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0x66: if ((addr & 0x7) <= dev->max_drb) { - i4x0_write_drbs(dev); + spd_write_drbs(regs, 0x60, 0x60 + dev->max_drb, dev->drb_unit); break; } switch (dev->type) { @@ -752,7 +710,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0x67: if ((addr & 0x7) <= dev->max_drb) { - i4x0_write_drbs(dev); + spd_write_drbs(regs, 0x60, 0x60 + dev->max_drb, dev->drb_unit); break; } switch (dev->type) { diff --git a/src/chipset/via_vpx.c b/src/chipset/via_vpx.c index c9798e319..87f7e94e6 100644 --- a/src/chipset/via_vpx.c +++ b/src/chipset/via_vpx.c @@ -35,6 +35,7 @@ #include <86box/device.h> #include <86box/keyboard.h> #include <86box/chipset.h> +#include <86box/spd.h> typedef struct via_vpx_t { @@ -94,6 +95,10 @@ via_vpx_t *dev = (via_vpx_t *) priv; dev->pci_conf[0x07] &= ~(val & 0xb0); break; + case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: // Bank Ending + spd_write_drbs(dev->pci_conf, 0x5a, 0x5f, 4); + break; + case 0x61: // Shadow RAM control 1 if ((dev->pci_conf[0x61] ^ val) & 0x03) vpx_map(0xc0000, 0x04000, val & 0x03); @@ -201,6 +206,7 @@ via_vpx_init(const device_t *info) dev->pci_conf[0x5e] = 1; // Bank 4 Ending dev->pci_conf[0x5f] = 1; // Bank 5 Ending + dev->pci_conf[0x60] = 0x3f; // DRAM type dev->pci_conf[0x64] = 0xab; // DRAM reference timing return dev; diff --git a/src/include/86box/spd.h b/src/include/86box/spd.h index cec4e9c18..4acce679d 100644 --- a/src/include/86box/spd.h +++ b/src/include/86box/spd.h @@ -100,13 +100,8 @@ typedef struct _spd_sdram_ { } spd_sdram_t; -extern int spd_present; -extern spd_t *spd_devices[SPD_MAX_SLOTS]; - - -extern uint8_t log2_ui16(uint16_t i); -extern void spd_populate(uint16_t *vslots, uint8_t slot_count, uint16_t total_size, uint16_t min_module_size, uint16_t max_module_size, uint8_t enable_asym); extern void spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size); +extern void spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit); #endif /*EMU_SPD_H*/ diff --git a/src/machine/m_at_socket7_s7.c b/src/machine/m_at_socket7_s7.c index a2fa0cceb..cfff668b9 100644 --- a/src/machine/m_at_socket7_s7.c +++ b/src/machine/m_at_socket7_s7.c @@ -983,6 +983,7 @@ machine_at_ficva502_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&fdc37c669_device); device_add(&sst_flash_29ee010_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); return ret; } diff --git a/src/mem/spd.c b/src/mem/spd.c index 244441712..6399fd1f0 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -26,6 +26,7 @@ #include <86box/smbus.h> #include <86box/spd.h> #include <86box/version.h> +#include <86box/machine.h> #define MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -41,7 +42,7 @@ static uint8_t spd_read_byte(uint8_t addr, void *priv); static uint8_t spd_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv); static void spd_write_byte(uint8_t addr, uint8_t val, void *priv); - +#define ENABLE_SPD_LOG 1 #ifdef ENABLE_SPD_LOG int spd_do_log = ENABLE_SPD_LOG; @@ -397,7 +398,50 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) break; } - //device_add(info); + device_add(info); vslot++; } } + + +void +spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit) +{ + uint8_t row, dimm; + uint16_t size, vslots[SPD_MAX_SLOTS]; + + spd_log("DRB write begin\n"); + + /* No SPD: split SIMMs into pairs as if they were "DIMM"s. */ + if (!spd_present) { + dimm = ((reg_max - reg_min) + 1) >> 1; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */ + spd_populate(vslots, dimm, (mem_size >> 10), drb_unit, 1 << (log2_ui16(machines[machine].max_ram / dimm)), 0); + } + + /* Write DRBs for each row. */ + spd_log("Writing DRBs... regs=[%02X:%02X] unit=%d\n", reg_min, reg_max, drb_unit); + for (row = 0; row <= (reg_max - reg_min); row++) { + dimm = (row >> 1); + size = 0; + + if (spd_present) { + /* SPD enabled: use SPD info for this slot, if present. */ + if (spd_devices[dimm]) { + if (spd_devices[dimm]->row1 < drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */ + size = ((row & 1) ? 0 : drb_unit); + else + size = ((row & 1) ? spd_devices[dimm]->row2 : spd_devices[dimm]->row1); + } + } else { + /* No SPD: use the values calculated above. */ + size = (vslots[dimm] >> 1); + } + + /* Populate DRB register, adding the previous DRB's value. + This will intentionally overflow on 440GX with 2 GB. */ + regs[reg_min + row] = ((row > 0) ? regs[reg_min + row - 1] : 0); + if (size) + regs[reg_min + row] += (size / drb_unit); + spd_log("DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[reg_min + row]); + } +} From 41c1f18c2f2c750e73dcbb7ca47977770237a796 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 21:28:52 -0300 Subject: [PATCH 05/54] Fix PA-2012 maximum RAM --- src/machine/machine_table.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 063612dad..fcfa808bf 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -297,12 +297,12 @@ const machine_t machines[] = { { "[VIA VPX] FIC VA-502", "ficva502", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_ficva502_init, NULL }, /* Apollo VP3 */ - { "[VIA VP3] FIC PA-2012", "ficpa2012", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_ficpa2012_init, NULL }, + { "[VIA VP3] FIC PA-2012", "ficpa2012", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_ficpa2012_init, NULL }, /* Super Socket 7 machines */ /* Apollo MVP3 */ - { "[VIA MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_ax59pro_init, NULL }, - { "[VIA MVP3] FIC VA-503+", "ficva503p", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_mvp3_init, NULL }, + { "[VIA MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_ax59pro_init, NULL }, + { "[VIA MVP3] FIC VA-503+", "ficva503p", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_mvp3_init, NULL }, /* Socket 8 machines */ /* 440FX */ @@ -348,7 +348,7 @@ const machine_t machines[] = { /* 440BX */ { "[i440BX] ASUS CUBX", "cubx", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_cubx_init, NULL }, { "[i440BX] A-Trend ATC7020BXII", "atc7020bxii", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_atc7020bxii_init, NULL }, - { "[i440BX] AmazePC AM-BX133", "ambx133", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_ambx133_init, NULL }, + { "[i440BX] AmazePC AM-BX133", "ambx133", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_ambx133_init, NULL }, /* 440ZX */ { "[i440ZX] Soltek SL-63A1", "63a", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_63a_init, NULL }, From 5a3c3a1c93e45cd88bb00094b45ab0ece69c632e Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 21:32:24 -0300 Subject: [PATCH 06/54] Fix VA-503+ maximum RAM --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index fcfa808bf..ab98c7536 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -302,7 +302,7 @@ const machine_t machines[] = { /* Super Socket 7 machines */ /* Apollo MVP3 */ { "[VIA MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_ax59pro_init, NULL }, - { "[VIA MVP3] FIC VA-503+", "ficva503p", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_mvp3_init, NULL }, + { "[VIA MVP3] FIC VA-503+", "ficva503p", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_mvp3_init, NULL }, /* Socket 8 machines */ /* 440FX */ From 0b871b56c0947f671c50a5283b31475dd8153f38 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 22:02:13 -0300 Subject: [PATCH 07/54] Actually fix the Apollo SS7 maximum RAM amounts, based on the DRAM bank configurations defined in the board manuals --- src/machine/m_at_socket7_s7.c | 3 ++- src/machine/m_at_sockets7.c | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/machine/m_at_socket7_s7.c b/src/machine/m_at_socket7_s7.c index cfff668b9..f997105d2 100644 --- a/src/machine/m_at_socket7_s7.c +++ b/src/machine/m_at_socket7_s7.c @@ -983,7 +983,7 @@ machine_at_ficva502_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&fdc37c669_device); device_add(&sst_flash_29ee010_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 256); + spd_register(SPD_TYPE_SDRAM, 0x3, 256); return ret; } @@ -1014,6 +1014,7 @@ machine_at_ficpa2012_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&w83877f_device); device_add(&sst_flash_39sf010_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 512); return ret; } diff --git a/src/machine/m_at_sockets7.c b/src/machine/m_at_sockets7.c index f66a29353..e2687986b 100644 --- a/src/machine/m_at_sockets7.c +++ b/src/machine/m_at_sockets7.c @@ -67,7 +67,7 @@ machine_at_ax59pro_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&w83877tf_device); device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 256); + spd_register(SPD_TYPE_SDRAM, 0x7, 512); return ret; } @@ -90,7 +90,7 @@ machine_at_mvp3_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0a, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); device_add(&via_mvp3_device); @@ -98,6 +98,7 @@ machine_at_mvp3_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&w83877tf_device); device_add(&sst_flash_39sf010_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 512); return ret; } From aea5461255e7ef5f0c0eb0cb3aeb7a4a33025387 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 22:05:32 -0300 Subject: [PATCH 08/54] Implement DRB locking for VIA Apollo chipsets --- src/chipset/via_apollo.c | 8 ++++++++ src/mem/spd.c | 21 +++++++++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index a3200669a..929759fe0 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -32,6 +32,7 @@ #include <86box/device.h> #include <86box/keyboard.h> #include <86box/chipset.h> +#include <86box/spd.h> typedef struct via_apollo_t @@ -226,6 +227,13 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[0][0x53] = (dev->pci_conf[0][0x53] & ~0xf0) | (val & 0xf0); break; + case 0x56: case 0x57: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: /* DRAM Row Ending Address */ + if (dev->id >= 0x0691) + spd_write_drbs(dev->pci_conf[0], 0x5a, 0x56, 8); + else if (addr >= 0x5a) + spd_write_drbs(dev->pci_conf[0], 0x5a, 0x5f, 8); + break; + case 0x58: if (dev->id == 0x0597) dev->pci_conf[0][0x58] = (dev->pci_conf[0][0x58] & ~0xee) | (val & 0xee); diff --git a/src/mem/spd.c b/src/mem/spd.c index 6399fd1f0..d9dc5c370 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -407,10 +407,14 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) void spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit) { - uint8_t row, dimm; + uint8_t row, dimm, drb, apollo = 0; uint16_t size, vslots[SPD_MAX_SLOTS]; - spd_log("DRB write begin\n"); + /* Special case for VIA Apollo Pro family, which jumps from 5F to 56. */ + if (reg_max < reg_min) { + apollo = reg_max; + reg_max = reg_min + 8; + } /* No SPD: split SIMMs into pairs as if they were "DIMM"s. */ if (!spd_present) { @@ -437,11 +441,16 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit size = (vslots[dimm] >> 1); } - /* Populate DRB register, adding the previous DRB's value. + /* Determine the DRB register to write. */ + drb = reg_min + row; + if ((apollo) && ((drb & 0xf) < 0x8)) + drb = apollo + (drb & 0xf); + + /* Write DRB register, adding the previous DRB's value. This will intentionally overflow on 440GX with 2 GB. */ - regs[reg_min + row] = ((row > 0) ? regs[reg_min + row - 1] : 0); + regs[drb] = ((row > 0) ? regs[drb - 1] : 0); if (size) - regs[reg_min + row] += (size / drb_unit); - spd_log("DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[reg_min + row]); + regs[drb] += (size / drb_unit); + spd_log("DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[drb]); } } From 3a9408eadc2ff0aa7e6d05bc1c1b58c8ff8e456d Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 22:14:22 -0300 Subject: [PATCH 09/54] APAS3 only has 3 slots --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index ab98c7536..75a211944 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -354,7 +354,7 @@ const machine_t machines[] = { { "[i440ZX] Soltek SL-63A1", "63a", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_63a_init, NULL }, /* VIA Apollo Pro */ - { "[VIA Apollo Pro] PC Partner APAS3", "apas3", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_apas3_init, NULL }, + { "[VIA Apollo Pro] PC Partner APAS3", "apas3", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_apas3_init, NULL }, { NULL, NULL, MACHINE_TYPE_NONE, {{"", 0}, {"", 0}, {"", 0}, {"", 0}, {"", 0}}, 0, 0, 0, 0, 0, NULL, NULL } }; From 012f01cc9f2860df8e974c60c2c4960a51be49d5 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 22:15:21 -0300 Subject: [PATCH 10/54] Fix Apollo DRB wraparound --- src/mem/spd.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/mem/spd.c b/src/mem/spd.c index d9dc5c370..a3cb7732f 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -413,7 +413,7 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit /* Special case for VIA Apollo Pro family, which jumps from 5F to 56. */ if (reg_max < reg_min) { apollo = reg_max; - reg_max = reg_min + 8; + reg_max = reg_min + 7; } /* No SPD: split SIMMs into pairs as if they were "DIMM"s. */ @@ -443,14 +443,21 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit /* Determine the DRB register to write. */ drb = reg_min + row; - if ((apollo) && ((drb & 0xf) < 0x8)) - drb = apollo + (drb & 0xf); - /* Write DRB register, adding the previous DRB's value. - This will intentionally overflow on 440GX with 2 GB. */ - regs[drb] = ((row > 0) ? regs[drb - 1] : 0); + spd_log("want drb reg %02x", drb); + if ((apollo) && ((drb & 0xf) < 0xa)) + drb = apollo + (drb & 0xf); + spd_log(" got %02x\n", drb); + + /* Write DRB register, adding the previous DRB's value. */ + if (row == 0) + regs[drb] = 0; + else if ((apollo) && (drb == apollo)) + regs[drb] = regs[drb | 0xf]; /* 5F comes before 56 */ + else + regs[drb] = regs[drb - 1]; if (size) - regs[drb] += (size / drb_unit); + regs[drb] += (size / drb_unit); /* this will intentionally overflow on 440GX with 2 GB */ spd_log("DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[drb]); } } From 7775e52c0ed38d36a9ac44f89d036cdc594c601a Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 22:15:36 -0300 Subject: [PATCH 11/54] Disable SPD logging --- src/mem/spd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mem/spd.c b/src/mem/spd.c index a3cb7732f..2b6559c42 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -42,7 +42,7 @@ static uint8_t spd_read_byte(uint8_t addr, void *priv); static uint8_t spd_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv); static void spd_write_byte(uint8_t addr, uint8_t val, void *priv); -#define ENABLE_SPD_LOG 1 + #ifdef ENABLE_SPD_LOG int spd_do_log = ENABLE_SPD_LOG; From 9cecbfa33ad2a30390fab8cf79613c9774bcd24c Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 26 Jun 2020 22:16:56 -0300 Subject: [PATCH 12/54] Remove extraneous logging lines --- src/mem/spd.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/mem/spd.c b/src/mem/spd.c index 2b6559c42..f65417f9f 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -443,11 +443,8 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit /* Determine the DRB register to write. */ drb = reg_min + row; - - spd_log("want drb reg %02x", drb); if ((apollo) && ((drb & 0xf) < 0xa)) drb = apollo + (drb & 0xf); - spd_log(" got %02x\n", drb); /* Write DRB register, adding the previous DRB's value. */ if (row == 0) From 86183affed9f81ac320691d6d542ee00e6eb38a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Sat, 27 Jun 2020 12:37:02 +0200 Subject: [PATCH 13/54] update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 4 ++-- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 0e3472957..c2ca3446f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -25,8 +25,8 @@ If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - OS: [e.g. Windows 10] - - Version [e.g. v2.06 build 2007] - - Build type [i.e. regular, optimized, or dev] + - 86Box version: [e.g. v2.06 build 2007] + - Build type: [i.e. regular, optimized, or dev] **Additional context** Add any other context about the problem here. If you are using an Optimized build, make sure to try the regular build too before filing a bug report! diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index e301d68ce..4fe86d5ec 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -2,7 +2,7 @@ name: Feature request about: Suggest an idea for this project title: '' -labels: feature request +labels: feature assignees: '' --- From d66d62452fdb0025701042131650277c1abd02d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Sat, 27 Jun 2020 15:17:53 +0200 Subject: [PATCH 14/54] Add GitHub CI --- .github/workflows/c-cpp.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/workflows/c-cpp.yml diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml new file mode 100644 index 000000000..df3ace7ba --- /dev/null +++ b/.github/workflows/c-cpp.yml @@ -0,0 +1,32 @@ +name: C/C++ CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: windows-latest + + defaults: + run: + shell: msys2 {0} + + strategy: + matrix: + dev-build: ['y', 'n'] + new-dynarec: ['y', 'n'] + + steps: + - uses: msys2/setup-msys2@v1 + with: + update: true + msystem: MINGW32 + install: 'make mingw-w64-i686-toolchain mingw-w64-i686-openal mingw-w64-i686-freetype mingw-w64-i686-SDL2 mingw-w64-i686-zlib mingw-w64-i686-libpng' + - uses: actions/checkout@v2 + - name: make + run: make -fwin/makefile.mingw DEV_BUILD=${{ matrix.dev-build }} NEW_DYNAREC=${{ matrix.new-dynarec }} + working-directory: ./src From 6d059eb7e00694ebfa826658cd5e367e351d711f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Sat, 27 Jun 2020 15:22:17 +0200 Subject: [PATCH 15/54] Add vncserver to installed packages --- .github/workflows/c-cpp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index df3ace7ba..0517237c2 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -25,7 +25,7 @@ jobs: with: update: true msystem: MINGW32 - install: 'make mingw-w64-i686-toolchain mingw-w64-i686-openal mingw-w64-i686-freetype mingw-w64-i686-SDL2 mingw-w64-i686-zlib mingw-w64-i686-libpng' + install: 'make mingw-w64-i686-toolchain mingw-w64-i686-openal mingw-w64-i686-freetype mingw-w64-i686-SDL2 mingw-w64-i686-zlib mingw-w64-i686-libpng mingw-w64-i686-libvncserver' - uses: actions/checkout@v2 - name: make run: make -fwin/makefile.mingw DEV_BUILD=${{ matrix.dev-build }} NEW_DYNAREC=${{ matrix.new-dynarec }} From 1a3753377f0bba891228a5363a7fceae66689fa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Sat, 27 Jun 2020 15:46:10 +0200 Subject: [PATCH 16/54] Disable VNC in Workflows for now. --- .github/workflows/c-cpp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 0517237c2..12961de12 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -28,5 +28,5 @@ jobs: install: 'make mingw-w64-i686-toolchain mingw-w64-i686-openal mingw-w64-i686-freetype mingw-w64-i686-SDL2 mingw-w64-i686-zlib mingw-w64-i686-libpng mingw-w64-i686-libvncserver' - uses: actions/checkout@v2 - name: make - run: make -fwin/makefile.mingw DEV_BUILD=${{ matrix.dev-build }} NEW_DYNAREC=${{ matrix.new-dynarec }} + run: make -fwin/makefile.mingw DEV_BUILD=${{ matrix.dev-build }} NEW_DYNAREC=${{ matrix.new-dynarec }} VNC=n working-directory: ./src From 45b93ba4e461ba1c4b96c72eef6ab971367669a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Sat, 27 Jun 2020 17:44:46 +0200 Subject: [PATCH 17/54] Clarify the build names --- .github/workflows/c-cpp.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 12961de12..3c0e75eb8 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -17,8 +17,8 @@ jobs: strategy: matrix: - dev-build: ['y', 'n'] - new-dynarec: ['y', 'n'] + dev-build: ['DEV_BUILD=y', 'DEV_BUILD=n'] + new-dynarec: ['NEW_DYNAREC=y', 'NEW_DYNAREC=n'] steps: - uses: msys2/setup-msys2@v1 @@ -28,5 +28,5 @@ jobs: install: 'make mingw-w64-i686-toolchain mingw-w64-i686-openal mingw-w64-i686-freetype mingw-w64-i686-SDL2 mingw-w64-i686-zlib mingw-w64-i686-libpng mingw-w64-i686-libvncserver' - uses: actions/checkout@v2 - name: make - run: make -fwin/makefile.mingw DEV_BUILD=${{ matrix.dev-build }} NEW_DYNAREC=${{ matrix.new-dynarec }} VNC=n + run: make -fwin/makefile.mingw ${{ matrix.dev-build }} ${{ matrix.new-dynarec }} VNC=n working-directory: ./src From bdad12326e758c457aa3bcf49bc715095a31e56c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Sat, 27 Jun 2020 17:56:02 +0200 Subject: [PATCH 18/54] nah --- .github/workflows/c-cpp.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 3c0e75eb8..12961de12 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -17,8 +17,8 @@ jobs: strategy: matrix: - dev-build: ['DEV_BUILD=y', 'DEV_BUILD=n'] - new-dynarec: ['NEW_DYNAREC=y', 'NEW_DYNAREC=n'] + dev-build: ['y', 'n'] + new-dynarec: ['y', 'n'] steps: - uses: msys2/setup-msys2@v1 @@ -28,5 +28,5 @@ jobs: install: 'make mingw-w64-i686-toolchain mingw-w64-i686-openal mingw-w64-i686-freetype mingw-w64-i686-SDL2 mingw-w64-i686-zlib mingw-w64-i686-libpng mingw-w64-i686-libvncserver' - uses: actions/checkout@v2 - name: make - run: make -fwin/makefile.mingw ${{ matrix.dev-build }} ${{ matrix.new-dynarec }} VNC=n + run: make -fwin/makefile.mingw DEV_BUILD=${{ matrix.dev-build }} NEW_DYNAREC=${{ matrix.new-dynarec }} VNC=n working-directory: ./src From d5f43204c914d24a32748231de38b3df8cd1a7e4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 27 Jun 2020 23:27:19 +0200 Subject: [PATCH 19/54] Some minor changes to fdd_d86f.c. --- src/floppy/fdd_86f.c | 51 +++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 26463da34..641039ae8 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -138,9 +138,9 @@ typedef struct { } sliding_buffer_t; typedef struct { - uint32_t sync_marks; uint32_t bits_obtained; - uint32_t bytes_obtained; + uint16_t bytes_obtained; + uint16_t sync_marks; uint32_t sync_pos; } find_t; @@ -181,47 +181,35 @@ typedef struct { */ typedef struct { FILE *f; - uint16_t version; - uint16_t disk_flags; - int32_t extra_bit_cells[2]; + uint8_t state, fill, sector_count, format_state, + error_condition, id_found; + uint16_t version, disk_flags, satisfying_bytes, turbo_pos; + uint16_t cur_track; uint16_t track_encoded_data[2][53048]; uint16_t *track_surface_data[2]; uint16_t thin_track_encoded_data[2][2][53048]; uint16_t *thin_track_surface_data[2][2]; uint16_t side_flags[2]; + uint16_t preceding_bit[2]; + uint16_t current_byte[2]; + uint16_t current_bit[2]; + uint16_t last_word[2]; +#ifdef D86F_COMPRESS + int is_compressed; +#endif + int32_t extra_bit_cells[2]; + uint32_t file_size, index_count, track_pos, datac, + id_pos, dma_over; uint32_t index_hole_pos[2]; uint32_t track_offset[512]; - uint32_t file_size; sector_id_t last_sector; sector_id_t req_sector; - uint32_t index_count; - uint8_t state; - uint8_t fill; - uint32_t track_pos; - uint32_t datac; - uint32_t id_pos; - uint16_t last_word[2]; find_t id_find; find_t data_find; crc_t calc_crc; crc_t track_crc; - uint8_t sector_count; - uint8_t format_state; - uint16_t satisfying_bytes; - uint16_t preceding_bit[2]; - uint16_t current_byte[2]; - uint16_t current_bit[2]; - int cur_track; - uint32_t error_condition; -#ifdef D86F_COMPRESS - int is_compressed; -#endif - int id_found; wchar_t original_file_name[2048]; - uint8_t *filebuf; - uint8_t *outbuf; - uint32_t dma_over; - int turbo_pos; + uint8_t *filebuf, *outbuf; sector_t *last_side_sector[2]; } d86f_t; @@ -973,7 +961,8 @@ d86f_encode_byte(int drive, int sync, decoded_t b, decoded_t prev_b) uint8_t bits3210 = b.nibbles.nibble0; uint16_t encoded_7654, encoded_3210, result; - if (encoding > 1) return 0xff; + if (encoding > 1) + return 0xffff; if (sync) { result = d86f_encode_get_data(b.byte); @@ -1475,7 +1464,7 @@ d86f_read_sector_id(int drive, int side, int match) } else { /* CRC is valid. */ dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = 0; - dev->id_found++; + dev->id_found |= 1; if ((dev->last_sector.dword == dev->req_sector.dword) || !match) { d86f_handler[drive].set_sector(drive, side, dev->last_sector.id.c, dev->last_sector.id.h, dev->last_sector.id.r, dev->last_sector.id.n); if (dev->state == STATE_02_READ_ID) { From 926ed407410f2ba9e76611ff0de07230a8159bb9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 28 Jun 2020 04:46:32 +0200 Subject: [PATCH 20/54] Sanitized some stuff in fdd_86f.c. --- src/floppy/fdd_86f.c | 58 +++++++++----------------------------------- 1 file changed, 11 insertions(+), 47 deletions(-) diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 641039ae8..e27b894df 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -103,10 +103,6 @@ enum { /* 1 11 01 ??? */ STATE_0D_SPIN_TO_INDEX = 0xE8, /* FORMAT TRACK */ STATE_0D_FORMAT_TRACK, - - /* 1 11 11 ??? */ - STATE_0D_NOP_SPIN_TO_INDEX = 0xF8, /* FORMAT TRACK */ - STATE_0D_NOP_FORMAT_TRACK }; enum { @@ -821,16 +817,14 @@ uint32_t d86f_get_data_len(int drive) { d86f_t *dev = d86f[drive]; + uint32_t i, ret = 128; - if (dev->req_sector.id.n) { - if (dev->req_sector.id.n == 8) return 32768; - return (128 << ((uint32_t) dev->req_sector.id.n)); - } else { - if (fdc_get_dtl(d86f_fdc) < 128) - return fdc_get_dtl(d86f_fdc); - else - return (128 << ((uint32_t) dev->req_sector.id.n)); - } + if (dev->req_sector.id.n) + ret = (uint32_t)128 << dev->req_sector.id.n; + else if ((i = fdc_get_dtl(d86f_fdc)) < 128) + ret = i; + + return ret; } @@ -1769,7 +1763,7 @@ d86f_spin_to_index(int drive, int side) d86f_advance_bit(drive, side); if (dev->track_pos == d86f_handler[drive].index_hole_pos(drive, side)) { - if ((dev->state == STATE_0D_SPIN_TO_INDEX) || (dev->state == STATE_0D_NOP_SPIN_TO_INDEX)) { + if (dev->state == STATE_0D_SPIN_TO_INDEX) { /* When starting format, reset format state to the beginning. */ dev->preceding_bit[side] = 1; dev->format_state = FMT_PRETRK_GAP0; @@ -2089,22 +2083,6 @@ d86f_format_track(int drive, int side, int do_write) } -void -d86f_format_track_normal(int drive, int side) -{ - d86f_t *dev = d86f[drive]; - - d86f_format_track(drive, side, (dev->version == D86FVER)); -} - - -void -d86f_format_track_nop(int drive, int side) -{ - d86f_format_track(drive, side, 0); -} - - void d86f_initialize_last_sector_id(int drive, int c, int h, int r, int n) { @@ -2306,7 +2284,6 @@ d86f_turbo_poll(int drive, int side) switch(dev->state) { case STATE_0D_SPIN_TO_INDEX: - case STATE_0D_NOP_SPIN_TO_INDEX: dev->sector_count = 0; dev->datac = 5; /*FALLTHROUGH*/ @@ -2401,11 +2378,7 @@ d86f_turbo_poll(int drive, int side) break; case STATE_0D_FORMAT_TRACK: - d86f_turbo_format(drive, side, 0); - return; - - case STATE_0D_NOP_FORMAT_TRACK: - d86f_turbo_format(drive, side, 1); + d86f_turbo_format(drive, side, (side && (d86f_get_sides(drive) != 2))); return; case STATE_IDLE: @@ -2449,7 +2422,6 @@ d86f_poll(int drive) switch(dev->state) { case STATE_02_SPIN_TO_INDEX: case STATE_0D_SPIN_TO_INDEX: - case STATE_0D_NOP_SPIN_TO_INDEX: d86f_spin_to_index(drive, side); return; @@ -2536,12 +2508,7 @@ d86f_poll(int drive) case STATE_0D_FORMAT_TRACK: if (! (dev->track_pos & 15)) - d86f_format_track_normal(drive, side); - return; - - case STATE_0D_NOP_FORMAT_TRACK: - if (! (dev->track_pos & 15)) - d86f_format_track_nop(drive, side); + d86f_format_track(drive, side, (!side || (d86f_get_sides(drive) == 2)) && (dev->version == D86FVER)); return; case STATE_IDLE: @@ -3421,10 +3388,7 @@ d86f_common_format(int drive, int side, int rate, uint8_t fill, int proxy) dev->index_count = dev->error_condition = dev->satisfying_bytes = dev->sector_count = 0; dev->dma_over = 0; - if (!side || (d86f_get_sides(drive) == 2)) - dev->state = STATE_0D_SPIN_TO_INDEX; - else - dev->state = STATE_0D_NOP_SPIN_TO_INDEX; + dev->state = STATE_0D_SPIN_TO_INDEX; } From 645f1d42f325cac071688125ca59c8c26352084e Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 28 Jun 2020 13:39:29 +0200 Subject: [PATCH 21/54] Fixed FDC sector compare finish. --- src/floppy/fdc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 5184bbe5f..2667727b6 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -1902,7 +1902,8 @@ void fdc_sector_finishcompare(fdc_t *fdc, int satisfying) { fdc->stat = 0x10; - fdc->satisfying_sectors++; + if (satisfying) + fdc->satisfying_sectors++; fdc->inread = 0; fdc_callback(fdc); } From 4012659fd7ab7c2d08904e73797d1beba8515dc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Sun, 28 Jun 2020 16:39:09 +0200 Subject: [PATCH 22/54] Cache the environment --- .github/workflows/c-cpp.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 12961de12..a01060c93 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -24,6 +24,7 @@ jobs: - uses: msys2/setup-msys2@v1 with: update: true + cache: true msystem: MINGW32 install: 'make mingw-w64-i686-toolchain mingw-w64-i686-openal mingw-w64-i686-freetype mingw-w64-i686-SDL2 mingw-w64-i686-zlib mingw-w64-i686-libpng mingw-w64-i686-libvncserver' - uses: actions/checkout@v2 From 5d5b9598b2e60b239a4ddf70681c7d5a27a8cde5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Sun, 28 Jun 2020 17:18:14 +0200 Subject: [PATCH 23/54] Jenkins test --- src/win/86Box.rc | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/win/86Box.rc b/src/win/86Box.rc index 62031c373..1265799cf 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -8,8 +8,6 @@ * * Application resource script for Windows. * - * - * * Authors: Miran Grca, * Fred N. van Kempen, * David Hrdlička, From af26e19b83d48724c90d4db43efb7ecf1ec4d83f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Sun, 28 Jun 2020 17:55:20 +0200 Subject: [PATCH 24/54] workflows: disable cache, build all branches --- .github/workflows/c-cpp.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index a01060c93..e9c8d3013 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -1,10 +1,16 @@ name: C/C++ CI on: + push: - branches: [ master ] + paths: + - src/** + - .github/workflows/** + pull_request: - branches: [ master ] + paths: + - src/** + - .github/workflows/** jobs: build: @@ -24,7 +30,6 @@ jobs: - uses: msys2/setup-msys2@v1 with: update: true - cache: true msystem: MINGW32 install: 'make mingw-w64-i686-toolchain mingw-w64-i686-openal mingw-w64-i686-freetype mingw-w64-i686-SDL2 mingw-w64-i686-zlib mingw-w64-i686-libpng mingw-w64-i686-libvncserver' - uses: actions/checkout@v2 From e3d7c07aa9f5e4aa2a36b1cc1811a531dd3fba1f Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 28 Jun 2020 15:43:55 -0300 Subject: [PATCH 25/54] Cosmetic changes to SMBus code --- src/device/smbus_piix4.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/device/smbus_piix4.c b/src/device/smbus_piix4.c index ad8ff64d0..947a536de 100644 --- a/src/device/smbus_piix4.c +++ b/src/device/smbus_piix4.c @@ -102,9 +102,9 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv) switch (addr - dev->io_base) { case 0x00: /* some status bits are reset by writing 1 to them */ - for (smbus_addr = 0x02; smbus_addr <= 0x10; smbus_addr = smbus_addr << 1) { + for (smbus_addr = 0x02; smbus_addr <= 0x10; smbus_addr <<= 1) { if (val & smbus_addr) - dev->stat = dev->stat & ~smbus_addr; + dev->stat &= ~smbus_addr; } break; case 0x02: @@ -150,7 +150,7 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv) dev->data0 = (temp & 0xFF); dev->data1 = (temp >> 8); } else { - temp = (dev->data1 << 8) | dev->data0; + temp = ((dev->data1 << 8) | dev->data0); smbus_write_word_cmd(smbus_addr, dev->cmd, temp); } dev->next_stat = 0x2; @@ -216,7 +216,7 @@ smbus_piix4_remap(smbus_piix4_t *dev, uint16_t new_io_base, uint8_t enable) dev->io_base = new_io_base; smbus_piix4_log("SMBus PIIX4: remap to %04Xh\n", dev->io_base); - if (enable && (dev->io_base != 0x0000)) + if ((enable) && (dev->io_base != 0x0000)) io_sethandler(dev->io_base, 0x10, smbus_piix4_read, NULL, NULL, smbus_piix4_write, NULL, NULL, dev); } From ed2d8f99691108e95899b3e1a7cce96f1e2dcd97 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 29 Jun 2020 00:53:51 +0200 Subject: [PATCH 26/54] A minor fix in floppy/fdd_86f.c . --- src/floppy/fdd_86f.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index e27b894df..131f1658f 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -3055,7 +3055,7 @@ d86f_write_tracks(int drive, FILE **f, uint32_t *track_table) fdd_side = fdd_get_head(drive); sides = d86f_get_sides(drive); - if (track_table) + if (track_table != NULL) tbl = track_table; if (!fdd_doublestep_40(drive)) { From 96228bc41d40aea238e8ddc6dba90324456c2633 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 29 Jun 2020 01:10:20 +0200 Subject: [PATCH 27/54] Overhauled the SiS 496/497 chipset emulation (and added the DRB locking to it) (later Zida Tomato 4DPS BIOS'es now work, and we now use the actual 1.72), fixed the W83787F and FDC37C932FR Super I/O chips, removed the no longer needed Acer M3A registers (that's now correctly handled as FDC37C932FR GPIO), and a number of bugfixes here and there. --- src/chipset/acer_m3a.c | 97 ------ src/chipset/intel_4x0.c | 30 +- src/chipset/sis_85c496.c | 574 ++++++++++++++++++++++++++-------- src/cpu/386_common.c | 16 +- src/cpu/808x.c | 1 + src/cpu/cpu.c | 2 + src/cpu/cpu.h | 4 +- src/dma.c | 52 +-- src/include/86box/chipset.h | 4 +- src/include/86box/dma.h | 3 +- src/include/86box/mem.h | 8 +- src/io.c | 13 +- src/machine/m_at_386dx_486.c | 28 +- src/machine/m_at_socket7_s7.c | 2 - src/machine/m_at_socket8.c | 1 - src/machine/m_ps1.c | 2 +- src/machine/machine_table.c | 6 +- src/mem/mem.c | 15 +- src/pit.c | 4 +- src/sio/sio_fdc37c93x.c | 12 +- src/sio/sio_w83787f.c | 17 +- src/win/Makefile.mingw | 2 +- 22 files changed, 578 insertions(+), 315 deletions(-) delete mode 100644 src/chipset/acer_m3a.c diff --git a/src/chipset/acer_m3a.c b/src/chipset/acer_m3a.c deleted file mode 100644 index fc7717a11..000000000 --- a/src/chipset/acer_m3a.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of the Acer M3A and V35N ports EAh and EBh. - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2019 Miran Grca. - */ -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/mem.h> -#include <86box/io.h> -#include <86box/rom.h> -#include <86box/pci.h> -#include <86box/device.h> -#include <86box/keyboard.h> -#include <86box/chipset.h> - - -typedef struct -{ - int index; -} acerm3a_t; - - -static void -acerm3a_out(uint16_t port, uint8_t val, void *p) -{ - acerm3a_t *dev = (acerm3a_t *) p; - - if (port == 0xea) - dev->index = val; -} - - -static uint8_t -acerm3a_in(uint16_t port, void *p) -{ - acerm3a_t *dev = (acerm3a_t *) p; - - if (port == 0xeb) { - switch (dev->index) { - case 2: - return 0xfd; - } - } - return 0xff; -} - - -static void -acerm3a_close(void *p) -{ - acerm3a_t *dev = (acerm3a_t *)p; - - free(dev); -} - - -static void -*acerm3a_init(const device_t *info) -{ - acerm3a_t *acerm3a = (acerm3a_t *) malloc(sizeof(acerm3a_t)); - memset(acerm3a, 0, sizeof(acerm3a_t)); - - io_sethandler(0x00ea, 0x0002, acerm3a_in, NULL, NULL, acerm3a_out, NULL, NULL, acerm3a); - - return acerm3a; -} - - -const device_t acerm3a_device = -{ - "Acer M3A Register", - 0, - 0, - acerm3a_init, - acerm3a_close, - NULL, - NULL, - NULL, - NULL, - NULL -}; diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 5c4f5662f..7d5c6f43c 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -512,6 +512,11 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0x55: switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + /* According to the FreeBSD 3.x source code, the 420TX/ZX chipset has + this register. The mask is unknown, so write all bits. */ + regs[0x55] = val; + break; case INTEL_430VX: case INTEL_430TX: regs[0x55] = val & 0x01; break; @@ -523,6 +528,11 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0x56: switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + /* According to the FreeBSD 3.x source code, the 420TX/ZX chipset has + this register. The mask is unknown, so write all bits. */ + regs[0x56] = val; + break; case INTEL_430HX: regs[0x56] = val & 0x1f; break; @@ -1321,24 +1331,28 @@ static void regs[0x06] = 0x40; regs[0x08] = (dev->type == INTEL_420ZX) ? 0x01 : 0x00; regs[0x0d] = 0x20; + /* According to information from FreeBSD 3.x source code: + 0x00 = 486DX, 0x20 = 486SX, 0x40 = 486DX2 or 486DX4, 0x80 = Pentium OverDrive. */ if (is486sx) regs[0x50] = 0x20; else if (is486sx2) regs[0x50] = 0x60; /* Guess based on the SX, DX, and DX2 values. */ - else if (is486dx || isdx4) + else if (is486dx) regs[0x50] = 0x00; - else if (is486dx2) + else if (is486dx2 || isdx4) regs[0x50] = 0x40; else regs[0x50] = 0x80; /* Pentium OverDrive. */ - if (cpu_busspeed <= 25000000) + /* According to information from FreeBSD 3.x source code: + 00 = 25 MHz, 01 = 33 MHz. */ + if (cpu_busspeed > 25000000) regs[0x50] |= 0x01; - else if ((cpu_busspeed > 25000000) && (cpu_busspeed <= 30000000)) - regs[0x50] |= 0x02; - else if ((cpu_busspeed > 30000000) && (cpu_busspeed <= 33333333)) - regs[0x50] |= 0x03; regs[0x51] = 0x80; - regs[0x52] = 0xea; /* 512 kB burst cache, set to 0xaa for 256 kB */ + /* According to information from FreeBSD 3.x source code: + 0x00 = None, 0x01 = 64 kB, 0x41 = 128 kB, 0x81 = 256 kB, 0xc1 = 512 kB, + If bit 0 is set, then if bit 2 is also set, the cache is write back, + otherwise it's write through. */ + regs[0x52] = 0xc3; /* 512 kB writeback cache */ regs[0x57] = 0x31; regs[0x59] = 0x0f; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02; diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c index 7fafa9607..978f5d29e 100644 --- a/src/chipset/sis_85c496.c +++ b/src/chipset/sis_85c496.c @@ -10,17 +10,17 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2019 Miran Grca. + * Copyright 2019,2020 Miran Grca. */ +#include #include #include #include #include #include +#define HAVE_STDARG_H #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> @@ -30,54 +30,93 @@ #include <86box/device.h> #include <86box/keyboard.h> #include <86box/timer.h> +#include <86box/dma.h> +#include <86box/nvr.h> +#include <86box/pic.h> #include <86box/port_92.h> #include <86box/hdc_ide.h> #include <86box/machine.h> #include <86box/chipset.h> +#include <86box/spd.h> typedef struct sis_85c496_t { - uint8_t cur_reg, + uint8_t cur_reg, rmsmiblk_count, regs[127], pci_conf[256]; + pc_timer_t rmsmiblk_timer; port_92_t * port_92; + nvr_t * nvr; } sis_85c496_t; +#ifdef ENABLE_SIS_85C496_LOG +int sis_85c496_do_log = ENABLE_SIS_85C496_LOG; + + +void +sis_85c496_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_85c496_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define sis_85c496_log(fmt, ...) +#endif + + static void -sis_85c497_write(uint16_t port, uint8_t val, void *priv) +sis_85c497_isa_write(uint16_t port, uint8_t val, void *priv) { sis_85c496_t *dev = (sis_85c496_t *) priv; - uint8_t index = (port & 1) ? 0 : 1; - if (index) { - if ((val != 0x01) || ((val >= 0x70) && (val <= 0x76))) - dev->cur_reg = val; - } else { - if (((dev->cur_reg < 0x70) && (dev->cur_reg != 0x01)) || (dev->cur_reg > 0x76)) - return; - dev->regs[dev->cur_reg] = val; - dev->cur_reg = 0; + sis_85c496_log("[%04X:%08X] ISA Write %02X to %04X\n", CS, cpu_state.pc, val, port); + + if (port == 0x22) + dev->cur_reg = val; + else if (port == 0x23) switch (dev->cur_reg) { + case 0x01: /* Built-in 206 Timing Control */ + dev->regs[dev->cur_reg] = val; + break; + case 0x70: /* ISA Bus Clock Selection */ + dev->regs[dev->cur_reg] = val & 0xc0; + break; + case 0x71: /* ISA Bus Timing Control */ + dev->regs[dev->cur_reg] = val & 0xf6; + break; + case 0x72: case 0x76: /* SMOUT */ + case 0x74: /* BIOS Timer */ + dev->regs[dev->cur_reg] = val; + break; + case 0x73: /* BIOS Timer */ + dev->regs[dev->cur_reg] = val & 0xfd; + break; + case 0x75: /* DMA / Deturbo Control */ + dev->regs[dev->cur_reg] = val & 0xfc; + dma_set_mask((val & 0x80) ? 0xffffffff : 0x00ffffff); + break; } } static uint8_t -sis_85c497_read(uint16_t port, void *priv) +sis_85c497_isa_read(uint16_t port, void *priv) { sis_85c496_t *dev = (sis_85c496_t *) priv; - uint8_t index = (port & 1) ? 0 : 1; uint8_t ret = 0xff; - if (index) - ret = dev->cur_reg; - else { - if ((dev->cur_reg != 0x01) || ((dev->cur_reg >= 0x70) && (dev->cur_reg <= 0x76))) { - ret = dev->regs[dev->cur_reg]; - dev->cur_reg = 0; - } - } + if (port == 0x23) + ret = dev->regs[dev->cur_reg]; + else if (port == 0x33) + ret = 0x3c /*random_generate()*/; + + sis_85c496_log("[%04X:%08X] ISA Read %02X from %04X\n", CS, cpu_state.pc, ret, port); return ret; } @@ -100,170 +139,379 @@ sis_85c496_recalcmapping(sis_85c496_t *dev) shadowbios_write |= (base >= 0xe0000) && !(dev->pci_conf[0x45] & 0x01); shflags = (dev->pci_conf[0x45] & 0x02) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; shflags |= (dev->pci_conf[0x45] & 0x01) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL; - mem_set_mem_state(base, 0x8000, shflags); + mem_set_mem_state_both(base, 0x8000, shflags); } else - mem_set_mem_state(base, 0x8000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + mem_set_mem_state_both(base, 0x8000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); } +} + +static void +sis_85c496_ide_handler(sis_85c496_t *dev) +{ + uint8_t ide_cfg[2]; + + ide_cfg[0] = dev->pci_conf[0x58]; + ide_cfg[1] = dev->pci_conf[0x59]; + + ide_pri_disable(); + ide_sec_disable(); + + if (ide_cfg[1] & 0x02) { + ide_set_base(0, 0x0170); + ide_set_side(0, 0x0376); + ide_set_base(1, 0x01f0); + ide_set_side(1, 0x03f6); + + if (ide_cfg[1] & 0x01) { + if (!(ide_cfg[0] & 0x40)) + ide_pri_enable(); + if (!(ide_cfg[0] & 0x80)) + ide_sec_enable(); + } + } else { + ide_set_base(0, 0x01f0); + ide_set_side(0, 0x03f6); + ide_set_base(1, 0x0170); + ide_set_side(1, 0x0376); + + if (ide_cfg[1] & 0x01) { + if (!(ide_cfg[0] & 0x40)) + ide_sec_enable(); + if (!(ide_cfg[0] & 0x80)) + ide_pri_enable(); + } + } +} + + +static void +sis_85c496_smram_map(int smm, uint32_t addr, uint32_t size, int is_smram) +{ + mem_set_mem_state_smram(smm, addr, size, is_smram); flushmmucache(); } /* 00 - 3F = PCI Configuration, 40 - 7F = 85C496, 80 - FF = 85C497 */ static void -sis_85c496_write(int func, int addr, uint8_t val, void *priv) +sis_85c49x_pci_write(int func, int addr, uint8_t val, void *priv) { sis_85c496_t *dev = (sis_85c496_t *) priv; - uint8_t old = dev->pci_conf[addr]; - uint8_t valxor; + uint8_t old, valxor; + uint8_t smm_irq[4] = { 10, 11, 12, 15 }; - if ((addr >= 4 && addr < 8) || addr >= 0x40) - dev->pci_conf[addr] = val; + old = dev->pci_conf[addr]; + valxor = (dev->pci_conf[addr]) ^ val; - valxor = old ^ val; + sis_85c496_log("[%04X:%08X] PCI Write %02X to %02X:%02X\n", CS, cpu_state.pc, val, func, addr); switch (addr) { - case 0x42: /*Cache configure*/ + /* PCI Configuration Header Registers (00h ~ 3Fh) */ + case 0x04: /* PCI Device Command */ + dev->pci_conf[addr] = val & 0x40; + break; + case 0x05: /* PCI Device Command */ + dev->pci_conf[addr] = val & 0x03; + break; + case 0x07: /* Device Status */ + dev->pci_conf[addr] &= ~(val & 0xf1); + break; + + /* 86C496 Specific Registers (40h ~ 7Fh) */ + case 0x40: /* CPU Configuration */ + dev->pci_conf[addr] = val & 0x7f; + break; + case 0x41: /* DRAM Configuration */ + dev->pci_conf[addr] = val; + break; + case 0x42: /* Cache Configure */ + dev->pci_conf[addr] = val; cpu_cache_ext_enabled = (val & 0x01); cpu_update_waitstates(); break; - - case 0x44: /*Shadow configure*/ - if (valxor & 0xff) - sis_85c496_recalcmapping(dev); + case 0x43: /* Cache Configure */ + dev->pci_conf[addr] = val & 0x8f; break; - case 0x45: /*Shadow configure*/ - if (valxor & 0x03) + case 0x44: /* Shadow Configure */ + dev->pci_conf[addr] = val; + if (valxor & 0xff) { sis_85c496_recalcmapping(dev); + if (((old & 0xf0) == 0xf0) && ((val & 0xf0) == 0x30)) + flushmmucache_nopc(); + else + flushmmucache(); + } break; - - case 0x56: + case 0x45: /* Shadow Configure */ + dev->pci_conf[addr] = val & 0x0f; + if (valxor & 0x03) { + sis_85c496_recalcmapping(dev); + flushmmucache(); + } + break; + case 0x46: /* Cacheable Control */ + dev->pci_conf[addr] = val; + break; + case 0x47: /* 85C496 Address Decoder */ + dev->pci_conf[addr] = val & 0x1f; + break; + case 0x48: case 0x49: case 0x4a: case 0x4b: /* DRAM Boundary */ + case 0x4c: case 0x4d: case 0x4e: case 0x4f: + // dev->pci_conf[addr] = val; + spd_write_drbs(dev->pci_conf, 0x40, 0x4f, 1); + break; + case 0x50: case 0x51: /* Exclusive Area 0 Setup */ + dev->pci_conf[addr] = val; + break; + case 0x52: case 0x53: /* Exclusive Area 1 Setup */ + dev->pci_conf[addr] = val; + break; + case 0x54: /* Exclusive Area 2 Setup */ + dev->pci_conf[addr] = val; + break; + case 0x55: /* Exclusive Area 3 Setup */ + dev->pci_conf[addr] = val & 0xf0; + break; + case 0x56: /* PCI / Keyboard Configure */ + dev->pci_conf[addr] = val; if (valxor & 0x02) { port_92_remove(dev->port_92); if (val & 0x02) port_92_add(dev->port_92); } break; + case 0x57: /* Output Pin Configuration */ + dev->pci_conf[addr] = val; + break; + case 0x58: /* Build-in IDE Controller / VESA Bus Configuration */ + dev->pci_conf[addr] = val & 0xd7; + if (valxor & 0xc0) + sis_85c496_ide_handler(dev); + break; + case 0x59: /* Build-in IDE Controller / VESA Bus Configuration */ + dev->pci_conf[addr] = val; + if (valxor & 0x03) + sis_85c496_ide_handler(dev); + break; + case 0x5a: /* SMRAM Remapping Configuration */ + dev->pci_conf[addr] = val & 0xbe; + if (valxor & 0x3e) { + unmask_a20_in_smm = !!(val & 0x20); - case 0x59: - if (valxor & 0x02) { - if (val & 0x02) { - ide_set_base(0, 0x0170); - ide_set_side(0, 0x0376); - ide_set_base(1, 0x01f0); - ide_set_side(1, 0x03f6); - } else { - ide_set_base(0, 0x01f0); - ide_set_side(0, 0x03f6); - ide_set_base(1, 0x0170); - ide_set_side(1, 0x0376); + if (smram[0].size != 0x00000000) { + sis_85c496_smram_map(0, smram[0].host_base, smram[0].size, 0); + sis_85c496_smram_map(1, smram[0].host_base, smram[0].size, 0); + + memset(&smram[0], 0x00, sizeof(smram_t)); + mem_mapping_disable(&ram_smram_mapping[0]); + } + + if (val & 0x06) { + smram[0].size = 0x00010000; + switch ((val >> 3) & 0x03) { + case 0x00: + smram[0].host_base = 0x00060000; + smram[0].ram_base = 0x000a0000; + break; + case 0x01: + smram[0].host_base = 0x00060000; + smram[0].ram_base = 0x000b0000; + break; + case 0x02: + smram[0].host_base = 0x000e0000; + smram[0].ram_base = 0x000a0000; + break; + case 0x03: + smram[0].host_base = 0x000e0000; + smram[0].ram_base = 0x000b0000; + break; + } + + mem_mapping_set_addr(&ram_smram_mapping[0], smram[0].host_base, 0x00010000); + mem_mapping_set_exec(&ram_smram_mapping[0], ram + smram[0].ram_base); + + sis_85c496_smram_map(0, smram[0].host_base, smram[0].size, ((val & 0x06) == 0x06)); + sis_85c496_smram_map(1, smram[0].host_base, smram[0].size, (val & 0x02)); } } break; - - case 0x58: - if (valxor & 0x80) { - if (dev->pci_conf[0x59] & 0x02) { - ide_sec_disable(); - if (val & 0x80) - ide_sec_enable(); - } else { - ide_pri_disable(); - if (val & 0x80) - ide_pri_enable(); - } - } - if (valxor & 0x40) { - if (dev->pci_conf[0x59] & 0x02) { - ide_pri_disable(); - if (val & 0x40) - ide_pri_enable(); - } else { - ide_sec_disable(); - if (val & 0x40) - ide_sec_enable(); - } - } + case 0x5b: /* Programmable I/O Traps Configure */ + case 0x5c: case 0x5d: /* Programmable I/O Trap 0 Base */ + case 0x5e: case 0x5f: /* Programmable I/O Trap 0 Base */ + case 0x60: case 0x61: /* IDE Controller Channel 0 Configuration */ + case 0x62: case 0x63: /* IDE Controller Channel 1 Configuration */ + case 0x64: case 0x65: /* Exclusive Area 3 Setup */ + case 0x66: /* EDO DRAM Configuration */ + case 0x68: case 0x69: /* Asymmetry DRAM Configuration */ + dev->pci_conf[addr] = val; break; - - case 0x5a: - if (valxor & 0x04) { - if (val & 0x04) - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - else - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - } - break; - - case 0x67: + case 0x67: /* Miscellaneous Control */ + dev->pci_conf[addr] = val & 0xf9; if (valxor & 0x60) port_92_set_features(dev->port_92, !!(val & 0x20), !!(val & 0x40)); break; - case 0x82: - sis_85c497_write(0x22, val, priv); + /* 86C497 Specific Registers (80h ~ FFh) */ + case 0x80: /* PMU Configuration */ + case 0x85: /* STPCLK# Event Control */ + case 0x86: case 0x87: /* STPCLK# Deassertion IRQ Selection */ + case 0x89: /* Fast Timer Count */ + case 0x8a: /* Generic Timer Count */ + case 0x8b: /* Slow Timer Count */ + case 0x8e: /* Clock Throttling On Timer Count */ + case 0x8f: /* Clock Throttling Off Timer Count */ + case 0x90: /* Clock Throttling On Timer Reload Condition */ + case 0x92: /* Fast Timer Reload Condition */ + case 0x94: /* Generic Timer Reload Condition */ + case 0x96: /* Slow Timer Reload Condition */ + case 0x98: case 0x99: /* Fast Timer Reload IRQ Selection */ + case 0x9a: case 0x9b: /* Generic Timer Reload IRQ Selection */ + case 0x9c: case 0x9d: /* Slow Timer Reload IRQ Selection */ + case 0xa2: /* SMI Request Status Selection */ + case 0xa4: case 0xa5: /* SMI Request IRQ Selection */ + case 0xa6: case 0xa7: /* Clock Throttlign On Timer Reload IRQ Selection */ + case 0xa8: /* GPIO Control */ + case 0xaa: /* GPIO DeBounce Count */ + case 0xd2: /* Exclusive Area 2 Base Address */ + dev->pci_conf[addr] = val; break; - - case 0xc0: - if (val & 0x80) - pci_set_irq_routing(PCI_INTA, val & 0xf); - else - pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + case 0x81: /* PMU CPU Type Configuration */ + dev->pci_conf[addr] = val & 0x9f; break; - case 0xc1: - if (val & 0x80) - pci_set_irq_routing(PCI_INTB, val & 0xf); - else - pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + case 0x88: /* Timer Control */ + dev->pci_conf[addr] = val & 0x3f; break; - case 0xc2: - if (val & 0x80) - pci_set_irq_routing(PCI_INTC, val & 0xf); - else - pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + case 0x8d: /* RMSMIBLK Timer Count */ + dev->pci_conf[addr] = val; + dev->rmsmiblk_count = val; + timer_stop(&dev->rmsmiblk_timer); + if (val >= 0x02) + timer_on_auto(&dev->rmsmiblk_timer, 35.0); break; - case 0xc3: + case 0x91: /* Clock Throttling On Timer Reload Condition */ + case 0x93: /* Fast Timer Reload Condition */ + case 0x95: /* Generic Timer Reload Condition */ + dev->pci_conf[addr] = val & 0x03; + break; + case 0x97: /* Slow Timer Reload Condition */ + dev->pci_conf[addr] = val & 0xc3; + break; + case 0x9e: /* Soft-SMI Generation / RMSMIBLK Trigger */ + if (!smi_block && (val & 0x01) && (dev->pci_conf[0x80] & 0x80) && (dev->pci_conf[0xa2] & 0x10)) { + if (dev->pci_conf[0x80] & 0x10) + picint(1 << smm_irq[dev->pci_conf[0x81] & 0x03]); + else + smi_line = 1; + smi_block = 1; + dev->pci_conf[0xa0] |= 0x10; + } + if (val & 0x02) { + timer_stop(&dev->rmsmiblk_timer); + if (dev->rmsmiblk_count >= 0x02) + timer_on_auto(&dev->rmsmiblk_timer, 35.0); + } + break; + case 0xa0: case 0xa1: /* SMI Request Status */ + dev->pci_conf[addr] &= ~val; + break; + case 0xa3: /* SMI Request Status Selection */ + dev->pci_conf[addr] = val & 0x7f; + break; + case 0xa9: /* GPIO SMI Request Status */ + dev->pci_conf[addr] = ~(val & 0x03); + break; + case 0xc0: /* PCI INTA# -to-IRQ Link */ + case 0xc1: /* PCI INTB# -to-IRQ Link */ + case 0xc2: /* PCI INTC# -to-IRQ Link */ + case 0xc3: /* PCI INTD# -to-IRQ Link */ + dev->pci_conf[addr] = val & 0x8f; if (val & 0x80) - pci_set_irq_routing(PCI_INTD, val & 0xf); + pci_set_irq_routing(PCI_INTA + (addr & 0x03), val & 0xf); else - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTA + (addr & 0x03), PCI_IRQ_DISABLED); + break; + case 0xc6: /* 85C497 Post / INIT Configuration */ + dev->pci_conf[addr] = val & 0x0f; + break; + case 0xc8: case 0xc9: case 0xca: case 0xcb: /* Mail Box */ + dev->pci_conf[addr] = val; + break; + case 0xd0: /* ISA BIOS Configuration */ + dev->pci_conf[addr] = val & 0xfb; + break; + case 0xd1: /* ISA Address Decoder */ + if (dev->pci_conf[0xd0] & 0x01) + dev->pci_conf[addr] = val; + break; + case 0xd3: /* Exclusive Area 2 Base Address */ + dev->pci_conf[addr] = val & 0xf0; + break; + case 0xd4: /* Miscellaneous Configuration */ + dev->pci_conf[addr] = val & 0x6e; + nvr_bank_set(0, !!(val & 0x40), dev->nvr); break; } } static uint8_t -sis_85c496_read(int func, int addr, void *priv) +sis_85c49x_pci_read(int func, int addr, void *priv) { sis_85c496_t *dev = (sis_85c496_t *) priv; uint8_t ret = dev->pci_conf[addr]; switch (addr) { case 0x82: /*Port 22h Mirror*/ - ret = inb(0x22); + ret = dev->cur_reg; break; - case 0x70: /*Port 70h Mirror*/ + case 0x83: /*Port 70h Mirror*/ ret = inb(0x70); break; } + sis_85c496_log("[%04X:%08X] PCI Read %02X from %02X:%02X\n", CS, cpu_state.pc, ret, func, addr); + return ret; } static void -sis_85c497_reset(sis_85c496_t *dev) +sis_85c496_rmsmiblk_count(void *priv) +{ + sis_85c496_t *dev = (sis_85c496_t *) priv; + + dev->rmsmiblk_count--; + + if (dev->rmsmiblk_count == 1) { + smi_block = 0; + dev->rmsmiblk_count = 0; + timer_stop(&dev->rmsmiblk_timer); + } else + timer_on_auto(&dev->rmsmiblk_timer, 35.0); +} + + +static void +sis_85c497_isa_reset(sis_85c496_t *dev) { memset(dev->regs, 0, sizeof(dev->regs)); dev->regs[0x01] = 0xc0; dev->regs[0x71] = 0x01; dev->regs[0x72] = 0xff; + dev->regs[0x76] = 0xff; + + dma_set_mask(0x00ffffff); io_removehandler(0x0022, 0x0002, - sis_85c497_read, NULL, NULL, sis_85c497_write, NULL, NULL, dev); + sis_85c497_isa_read, NULL, NULL, sis_85c497_isa_write, NULL, NULL, dev); + io_removehandler(0x0033, 0x0001, + sis_85c497_isa_read, NULL, NULL, sis_85c497_isa_write, NULL, NULL, dev); io_sethandler(0x0022, 0x0002, - sis_85c497_read, NULL, NULL, sis_85c497_write, NULL, NULL, dev); + sis_85c497_isa_read, NULL, NULL, sis_85c497_isa_write, NULL, NULL, dev); + io_sethandler(0x0033, 0x0001, + sis_85c497_isa_read, NULL, NULL, sis_85c497_isa_write, NULL, NULL, dev); } @@ -271,8 +519,43 @@ static void sis_85c496_reset(void *priv) { sis_85c496_t *dev = (sis_85c496_t *) priv; + int i; - sis_85c497_reset(dev); + sis_85c49x_pci_write(0, 0x44, 0x00, dev); + sis_85c49x_pci_write(0, 0x45, 0x00, dev); + sis_85c49x_pci_write(0, 0x58, 0x00, dev); + sis_85c49x_pci_write(0, 0x59, 0x00, dev); + sis_85c49x_pci_write(0, 0x5a, 0x00, dev); + + for (i = 0; i < 8; i++) + sis_85c49x_pci_write(0, 0x48 + i, 0x00, dev); + + sis_85c49x_pci_write(0, 0x80, 0x00, dev); + sis_85c49x_pci_write(0, 0x81, 0x00, dev); + sis_85c49x_pci_write(0, 0x9e, 0x00, dev); + sis_85c49x_pci_write(0, 0x8d, 0x00, dev); + sis_85c49x_pci_write(0, 0xa0, 0xff, dev); + sis_85c49x_pci_write(0, 0xa1, 0xff, dev); + sis_85c49x_pci_write(0, 0xc0, 0x00, dev); + sis_85c49x_pci_write(0, 0xc1, 0x00, dev); + sis_85c49x_pci_write(0, 0xc2, 0x00, dev); + sis_85c49x_pci_write(0, 0xc3, 0x00, dev); + sis_85c49x_pci_write(0, 0xc8, 0x00, dev); + sis_85c49x_pci_write(0, 0xc9, 0x00, dev); + sis_85c49x_pci_write(0, 0xca, 0x00, dev); + sis_85c49x_pci_write(0, 0xcb, 0x00, dev); + + sis_85c49x_pci_write(0, 0xd0, 0x79, dev); + sis_85c49x_pci_write(0, 0xd1, 0xff, dev); + sis_85c49x_pci_write(0, 0xd0, 0x78, dev); + sis_85c49x_pci_write(0, 0xd4, 0x00, dev); + + ide_pri_disable(); + ide_sec_disable(); + + nvr_bank_set(0, 0, dev->nvr); + + sis_85c497_isa_reset(dev); } @@ -289,33 +572,29 @@ static void *sis_85c496_init(const device_t *info) { sis_85c496_t *dev = malloc(sizeof(sis_85c496_t)); - memset(dev, 0, sizeof(sis_85c496_t)); - - dev->pci_conf[0x00] = 0x39; /*SiS*/ - dev->pci_conf[0x01] = 0x10; - dev->pci_conf[0x02] = 0x96; /*496/497*/ - dev->pci_conf[0x03] = 0x04; - - dev->pci_conf[0x04] = 7; - dev->pci_conf[0x05] = 0; + memset(dev, 0x00, sizeof(sis_85c496_t)); + /* PCI Configuration Header Registers (00h ~ 3Fh) */ + dev->pci_conf[0x00] = 0x39; /* SiS */ + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x96; /* 496/497 */ + dev->pci_conf[0x03] = 0x04; + dev->pci_conf[0x04] = 0x07; dev->pci_conf[0x06] = 0x80; dev->pci_conf[0x07] = 0x02; - - dev->pci_conf[0x08] = 2; /*Device revision*/ - - dev->pci_conf[0x09] = 0x00; /*Device class (PCI bridge)*/ - dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x08] = 0x02; /* Device revision */ + dev->pci_conf[0x09] = 0x00; /* Device class (PCI bridge) */ dev->pci_conf[0x0b] = 0x06; - dev->pci_conf[0x0e] = 0x00; /*Single function device*/ + /* 86C496 Specific Registers (40h ~ 7Fh) */ + /* 86C497 Specific Registers (80h ~ FFh) */ dev->pci_conf[0xd0] = 0x78; /* ROM at E0000-FFFFF, Flash enable. */ dev->pci_conf[0xd1] = 0xff; - pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c496_read, sis_85c496_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c49x_pci_read, sis_85c49x_pci_write, dev); - sis_85c497_reset(dev); + sis_85c497_isa_reset(dev); dev->port_92 = device_add(&port_92_device); port_92_set_period(dev->port_92, 2ULL * TIMER_USEC); @@ -323,6 +602,18 @@ static void sis_85c496_recalcmapping(dev); + ide_pri_disable(); + ide_sec_disable(); + + if (info->local) + dev->nvr = device_add(&ls486e_nvr_device); + else + dev->nvr = device_add(&at_nvr_device); + + dma_high_page_init(); + + timer_add(&dev->rmsmiblk_timer, sis_85c496_rmsmiblk_count, dev, 0); + return dev; } @@ -340,3 +631,18 @@ const device_t sis_85c496_device = NULL, NULL }; + + +const device_t sis_85c496_ls486e_device = +{ + "SiS 85c496/85c497 (Lucky Star LS-486E)", + DEVICE_PCI, + 1, + sis_85c496_init, + sis_85c496_close, + sis_85c496_reset, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 1bda39a95..3bfc3ccbc 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -61,7 +61,8 @@ extern int optype; extern uint32_t pccache; -int in_sys = 0; +int in_sys = 0, unmask_a20_in_smm = 0; +uint32_t old_rammask = 0xffffffff; smram_t temp_smram[2]; @@ -1100,6 +1101,13 @@ enter_smm(int in_hlt) smm_in_hlt = in_hlt; + if (unmask_a20_in_smm) { + old_rammask = rammask; + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; + + flushmmucache(); + } + CPU_BLOCK_END(); } @@ -1151,6 +1159,12 @@ leave_smm(void) x386_common_log("Reading %08X from memory at %08X to array element %i\n", saved_state[n], smram_state, n); } + if (unmask_a20_in_smm) { + rammask = old_rammask; + + flushmmucache(); + } + x386_common_log("New SMBASE: %08X (%08X)\n", saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET], saved_state[66]); if (is_pentium) /* Intel P5 (Pentium) */ smram_restore_state_p5(saved_state); diff --git a/src/cpu/808x.c b/src/cpu/808x.c index a712e6830..2cde6d9c5 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -977,6 +977,7 @@ reset_common(int hard) in_smm = smi_latched = 0; smi_line = smm_in_hlt = 0; + smi_block = 0; if (hard) { smbase = 0x00030000; diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index c958158fc..90e8e0dc9 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -137,6 +137,7 @@ const OpFn *x86_opcodes_REPNE; const OpFn *x86_opcodes_3DNOW; int in_smm = 0, smi_line = 0, smi_latched = 0, smm_in_hlt = 0; +int smi_block = 0; uint32_t smbase = 0x30000; CPU *cpu_s; @@ -358,6 +359,7 @@ cpu_set(void) cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective]; cpu_alt_reset = 0; + unmask_a20_in_smm = 0; CPUID = cpu_s->cpuid_model; is8086 = (cpu_s->cpu_type > CPU_8088); diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 567b40fc0..cf99c0ae1 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -412,6 +412,7 @@ extern int hasfpu; extern uint32_t cpu_features; extern int in_smm, smi_line, smi_latched, smm_in_hlt; +extern int smi_block; extern uint32_t smbase; #ifdef USE_NEW_DYNAREC @@ -497,7 +498,8 @@ extern int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer; extern int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate; extern int timing_misaligned; -extern int in_sys; +extern int in_sys, unmask_a20_in_smm; +extern uint32_t old_rammask; extern uint16_t cpu_fast_off_count, cpu_fast_off_val; extern uint32_t cpu_fast_off_flags; diff --git a/src/dma.c b/src/dma.c index bbfdf2118..3e7ac0152 100644 --- a/src/dma.c +++ b/src/dma.c @@ -485,9 +485,9 @@ dma_write(uint16_t addr, uint8_t val, void *priv) case 6: /*Address registers*/ dma_wp[0] ^= 1; if (dma_wp[0]) - dma[channel].ab = (dma[channel].ab & 0xffff00) | val; + dma[channel].ab = (dma[channel].ab & 0xffffff00 & dma_mask) | val; else - dma[channel].ab = (dma[channel].ab & 0xff00ff) | (val << 8); + dma[channel].ab = (dma[channel].ab & 0xffff00ff & dma_mask) | (val << 8); dma[channel].ac = dma[channel].ab; return; @@ -778,14 +778,14 @@ dma16_write(uint16_t addr, uint8_t val, void *priv) dma_wp[1] ^= 1; if (dma_ps2.is_ps2) { if (dma_wp[1]) - dma[channel].ab = (dma[channel].ab & 0xffff00) | val; + dma[channel].ab = (dma[channel].ab & 0xffffff00 & dma_mask) | val; else - dma[channel].ab = (dma[channel].ab & 0xff00ff) | (val << 8); + dma[channel].ab = (dma[channel].ab & 0xffff00ff & dma_mask) | (val << 8); } else { if (dma_wp[1]) - dma[channel].ab = (dma[channel].ab & 0xfffe00) | (val << 1); + dma[channel].ab = (dma[channel].ab & 0xfffffe00 & dma_mask) | (val << 1); else - dma[channel].ab = (dma[channel].ab & 0xfe01ff) | (val << 9); + dma[channel].ab = (dma[channel].ab & 0xfffe01ff & dma_mask) | (val << 9); } dma[channel].ac = dma[channel].ab; return; @@ -878,12 +878,12 @@ dma_page_write(uint16_t addr, uint8_t val, void *priv) if (addr > 4) { dma[addr].page = val & 0xfe; - dma[addr].ab = (dma[addr].ab & 0x1ffff) | (dma[addr].page << 16); - dma[addr].ac = (dma[addr].ac & 0x1ffff) | (dma[addr].page << 16); + dma[addr].ab = (dma[addr].ab & 0xff01ffff & dma_mask) | (dma[addr].page << 16); + dma[addr].ac = (dma[addr].ac & 0xff01ffff & dma_mask) | (dma[addr].page << 16); } else { dma[addr].page = (AT) ? val : val & 0xf; - dma[addr].ab = (dma[addr].ab & 0xffff) | (dma[addr].page << 16); - dma[addr].ac = (dma[addr].ac & 0xffff) | (dma[addr].page << 16); + dma[addr].ab = (dma[addr].ab & 0xff00ffff & dma_mask) | (dma[addr].page << 16); + dma[addr].ac = (dma[addr].ac & 0xff00ffff & dma_mask) | (dma[addr].page << 16); } } } @@ -959,6 +959,20 @@ dma_set_params(uint8_t advanced, uint32_t mask) } +void +dma_set_mask(uint32_t mask) +{ + int i; + + dma_mask = mask; + + for (i = 0; i < 8; i++) { + dma[i].ab &= mask; + dma[i].ac &= mask; + } +} + + void dma_reset(void) { @@ -1355,14 +1369,14 @@ dma_channel_read(int channel) else if (dma_advanced) dma_retreat(dma_c); else - dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac - 1) & 0xffff); + dma_c->ac = (dma_c->ac & 0xffff0000 & dma_mask) | ((dma_c->ac - 1) & 0xffff); } else { if (dma_ps2.is_ps2) dma_c->ac++; else if (dma_advanced) dma_advance(dma_c); else - dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac + 1) & 0xffff); + dma_c->ac = (dma_c->ac & 0xffff0000 & dma_mask) | ((dma_c->ac + 1) & 0xffff); } } else { temp = _dma_readw(dma_c->ac, dma_c); @@ -1373,14 +1387,14 @@ dma_channel_read(int channel) else if (dma_advanced) dma_retreat(dma_c); else - dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac - 2) & 0x1ffff); + dma_c->ac = (dma_c->ac & 0xfffe0000 & dma_mask) | ((dma_c->ac - 2) & 0x1ffff); } else { if (dma_ps2.is_ps2) dma_c->ac += 2; else if (dma_advanced) dma_advance(dma_c); else - dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac + 2) & 0x1ffff); + dma_c->ac = (dma_c->ac & 0xfffe0000 & dma_mask) | ((dma_c->ac + 2) & 0x1ffff); } } @@ -1443,14 +1457,14 @@ dma_channel_write(int channel, uint16_t val) else if (dma_advanced) dma_retreat(dma_c); else - dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac - 1) & 0xffff); + dma_c->ac = (dma_c->ac & 0xffff0000 & dma_mask) | ((dma_c->ac - 1) & 0xffff); } else { if (dma_ps2.is_ps2) dma_c->ac++; else if (dma_advanced) dma_advance(dma_c); else - dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac + 1) & 0xffff); + dma_c->ac = (dma_c->ac & 0xffff0000 & dma_mask) | ((dma_c->ac + 1) & 0xffff); } } else { _dma_writew(dma_c->ac, val, dma_c); @@ -1461,15 +1475,15 @@ dma_channel_write(int channel, uint16_t val) else if (dma_advanced) dma_retreat(dma_c); else - dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac - 2) & 0x1ffff); - dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac - 2) & 0x1ffff); + dma_c->ac = (dma_c->ac & 0xfffe0000 & dma_mask) | ((dma_c->ac - 2) & 0x1ffff); + dma_c->ac = (dma_c->ac & 0xfffe0000 & dma_mask) | ((dma_c->ac - 2) & 0x1ffff); } else { if (dma_ps2.is_ps2) dma_c->ac += 2; else if (dma_advanced) dma_advance(dma_c); else - dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac + 2) & 0x1ffff); + dma_c->ac = (dma_c->ac & 0xfffe0000 & dma_mask) | ((dma_c->ac + 2) & 0x1ffff); } } diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 276da03c8..defc595ae 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -21,9 +21,6 @@ /* ACC */ extern const device_t acc2168_device; -/* Acer M3A and V35N */ -extern const device_t acerm3a_device; - /* ALi */ extern const device_t ali1429_device; @@ -77,6 +74,7 @@ extern const device_t cs8230_device; extern const device_t rabbit_device; extern const device_t sis_85c471_device; extern const device_t sis_85c496_device; +extern const device_t sis_85c496_ls486e_device; #if defined(DEV_BRANCH) && defined(USE_SIS_85C50X) extern const device_t sis_85c50x_device; #endif diff --git a/src/include/86box/dma.h b/src/include/86box/dma.h index d5ee9fcb3..bc09bac97 100644 --- a/src/include/86box/dma.h +++ b/src/include/86box/dma.h @@ -96,8 +96,9 @@ extern void dma_bm_read(uint32_t PhysAddress, uint8_t *DataRead, uint32_t TotalS extern void dma_bm_write(uint32_t PhysAddress, const uint8_t *DataWrite, uint32_t TotalSize, int TransferSize); void dma_set_params(uint8_t advanced, uint32_t mask); -void dma_ext_mode_init(void); +void dma_set_mask(uint32_t mask); +void dma_ext_mode_init(void); void dma_high_page_init(void); void dma_remove_sg(void); diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 4104c4fa0..e0ff655ba 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -39,10 +39,10 @@ Bits 24 -31: SMM read */ -#define MEM_READ_ANY 0x0000 +#define MEM_READ_DISABLED 0x0000 #define MEM_READ_INTERNAL 0x0100 #define MEM_READ_EXTERNAL 0x0200 -#define MEM_READ_DISABLED 0x0300 +#define MEM_READ_ANY 0x0300 #define MEM_READ_NORMAL 0x0400 /* SMM only - means use the non-SMM state */ #define MEM_READ_EXTERNAL_EX 0x0500 /* External but with internal exec - needed by the VIA Apollo Pro */ #define MEM_READ_ROMCS 0x0600 /* EXTERNAL type + ROMC flag */ @@ -52,10 +52,10 @@ #define MEM_READ_DISABLED_EX 0x4000 #define MEM_READ_MASK 0xff00 -#define MEM_WRITE_ANY 0x0000 +#define MEM_WRITE_DISABLED 0x0000 #define MEM_WRITE_INTERNAL 0x0001 #define MEM_WRITE_EXTERNAL 0x0002 -#define MEM_WRITE_DISABLED 0x0003 +#define MEM_WRITE_ANY 0x0003 #define MEM_WRITE_NORMAL 0x0004 /* SMM only - means use the non-SMM state */ #define MEM_WRITE_EXTERNAL_EX 0x0005 #define MEM_WRITE_ROMCS 0x0006 /* EXTERNAL type + ROMC flag */ diff --git a/src/io.c b/src/io.c index b09624064..f78dc268e 100644 --- a/src/io.c +++ b/src/io.c @@ -367,7 +367,7 @@ inw(uint16_t port) ret8[0] = ret & 0xff; ret8[1] = (ret >> 8) & 0xff; for (i = 0; i < 2; i++) { - p = io[port + i]; + p = io[(port + i) & 0xffff]; while(p) { if (p->inb && !p->inw) { ret8[i] &= p->inb(port + i, p->priv); @@ -414,7 +414,7 @@ outw(uint16_t port, uint16_t val) } for (i = 0; i < 2; i++) { - p = io[port + i]; + p = io[(port + i) & 0xffff]; while(p) { if (p->outb && !p->outw) { p->outb(port + i, val >> (i << 3), p->priv); @@ -463,7 +463,7 @@ inl(uint16_t port) ret16[0] = ret & 0xffff; ret16[1] = (ret >> 16) & 0xffff; for (i = 0; i < 4; i += 2) { - p = io[port + i]; + p = io[(port + i) & 0xffff]; while(p) { if (p->inw && !p->inl) { ret16[i >> 1] &= p->inw(port + i, p->priv); @@ -480,7 +480,7 @@ inl(uint16_t port) ret8[2] = (ret >> 16) & 0xff; ret8[3] = (ret >> 24) & 0xff; for (i = 0; i < 4; i++) { - p = io[port + i]; + p = io[(port + i) & 0xffff]; while(p) { if (p->inb && !p->inw && !p->inl) { ret8[i] &= p->inb(port + i, p->priv); @@ -523,14 +523,13 @@ outl(uint16_t port, uint32_t val) p->outl(port, val, p->priv); found |= 4; qfound++; - // return; } p = p->next; } } for (i = 0; i < 4; i += 2) { - p = io[port + i]; + p = io[(port + i) & 0xffff]; while(p) { if (p->outw && !p->outl) { p->outw(port + i, val >> (i << 3), p->priv); @@ -542,7 +541,7 @@ outl(uint16_t port, uint32_t val) } for (i = 0; i < 4; i++) { - p = io[port + i]; + p = io[(port + i) & 0xffff]; while(p) { if (p->outb && !p->outw && !p->outl) { p->outb(port + i, val >> (i << 3), p->priv); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index cdf86fee8..6946dffa2 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -385,16 +385,11 @@ machine_at_sis_85c496_common_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - - device_add(&sis_85c496_device); } @@ -409,9 +404,12 @@ machine_at_r418_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); - + machine_at_common_init_ex(model, 2); machine_at_sis_85c496_common_init(model); + device_add(&sis_85c496_device); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&fdc37c665_device); @@ -433,9 +431,11 @@ machine_at_ls486e_init(const machine_t *model) return ret; machine_at_common_init_ex(model, 2); - device_add(&ls486e_nvr_device); - machine_at_sis_85c496_common_init(model); + device_add(&sis_85c496_ls486e_device); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&fdc37c665_device); @@ -456,14 +456,20 @@ machine_at_4dps_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); - + machine_at_common_init_ex(model, 2); machine_at_sis_85c496_common_init(model); + device_add(&sis_85c496_device); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&w83787f_device); device_add(&keyboard_ps2_pci_device); + // device_add(&sst_flash_29ee010_device); + device_add(&intel_flash_bxt_device); + return ret; } diff --git a/src/machine/m_at_socket7_s7.c b/src/machine/m_at_socket7_s7.c index f997105d2..a029b717c 100644 --- a/src/machine/m_at_socket7_s7.c +++ b/src/machine/m_at_socket7_s7.c @@ -238,7 +238,6 @@ machine_at_acerm3a_init(const machine_t *model) device_add(&piix3_device); device_add(&keyboard_ps2_pci_device); device_add(&fdc37c932fr_device); - device_add(&acerm3a_device); device_add(&sst_flash_29ee010_device); @@ -271,7 +270,6 @@ machine_at_acerv35n_init(const machine_t *model) device_add(&piix3_device); device_add(&keyboard_ps2_pci_device); device_add(&fdc37c932fr_device); - device_add(&acerm3a_device); device_add(&sst_flash_29ee010_device); diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index 04fcffd1f..41904d191 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -121,7 +121,6 @@ machine_at_v60n_init(const machine_t *model) device_add(&piix3_device); device_add(&keyboard_ps2_pci_device); device_add(&fdc37c935_device); - device_add(&acerm3a_device); device_add(&sst_flash_29ee010_device); return ret; diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index 52ac3a523..b971d502d 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -495,7 +495,7 @@ ps1_setup(int model) /* Enable the PS/1 VGA controller. */ if (model == 2011) device_add(&ps1vga_device); - else + else if (model == 2021) device_add(&ibm_ps1_2121_device); } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 75a211944..5c89a6eb1 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -221,9 +221,9 @@ const machine_t machines[] = { { "[i420EX] ASUS PVI-486AP4", "486ap4", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_486ap4_init, NULL }, { "[i420ZX] ASUS PCI/I-486SP3G", "486sp3g", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_486sp3g_init, NULL }, { "[i420TX] Intel Classic/PCI", "alfredo", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_alfredo_init, NULL }, - { "[SiS 496] Lucky Star LS-486E", "ls486e", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_ls486e_init, NULL }, - { "[SiS 496] Rise Computer R418", "r418", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_r418_init, NULL }, - { "[SiS 496] Zida Tomato 4DP", "4dps", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_4dps_init, NULL }, + { "[SiS 496] Lucky Star LS-486E", "ls486e", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 255, machine_at_ls486e_init, NULL }, + { "[SiS 496] Rise Computer R418", "r418", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 255, machine_at_r418_init, NULL }, + { "[SiS 496] Zida Tomato 4DP", "4dps", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 255, machine_at_4dps_init, NULL }, /* Socket 4 machines */ /* OPTi 596/597 */ diff --git a/src/mem/mem.c b/src/mem/mem.c index 572c5878a..29d67d1a1 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -2520,6 +2520,11 @@ mem_reset(void) { uint32_t c, m, m2; +#if FIXME + memset(ff_array, 0xff, sizeof(ff_array)); +#endif + memset(page_ff, 0xff, sizeof(page_ff)); + m = 1024UL * mem_size; if (ram != NULL) { free(ram); @@ -2654,6 +2659,9 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); #endif } + memset(read_mapping, 0x00, sizeof(read_mapping)); + memset(write_mapping, 0x00, sizeof(write_mapping)); + memset(_mem_exec, 0x00, sizeof(_mem_exec)); memset(&base_mapping, 0x00, sizeof(base_mapping)); @@ -2664,6 +2672,8 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); mem_set_mem_state_both(0x0a0000, 0x60000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + mem_set_mem_state_both((mem_size << 10), (uint32_t) (0x100000000ULL - (mem_size << 10)), + MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); mem_mapping_add(&ram_low_mapping, 0x00000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, @@ -2765,11 +2775,6 @@ mem_init(void) writelookup2 = malloc((1<<20)*sizeof(uintptr_t)); #endif -#if FIXME - memset(ff_array, 0xff, sizeof(ff_array)); -#endif - memset(page_ff, 0xff, sizeof(page_ff)); - /* Reset the memory state. */ mem_reset(); } diff --git a/src/pit.c b/src/pit.c index b33adbc1a..fec976d79 100644 --- a/src/pit.c +++ b/src/pit.c @@ -1030,9 +1030,9 @@ pit_set_clock(int clock) isa_timing = (cpuclock / (double)8000000.0); if (cpu_64bitbus) - bus_timing = (cpuclock / ((double)cpu_busspeed / 2)); + bus_timing = (cpuclock / ((double)cpu_busspeed / 2)); else - bus_timing = (cpuclock / (double)cpu_busspeed); + bus_timing = (cpuclock / (double)cpu_busspeed); pci_timing = (cpuclock / (double)cpu_pci_speed); /* PCICLK in us for use with timer_on_auto(). */ diff --git a/src/sio/sio_fdc37c93x.c b/src/sio/sio_fdc37c93x.c index 7e08ab373..2f6a4a61b 100644 --- a/src/sio/sio_fdc37c93x.c +++ b/src/sio/sio_fdc37c93x.c @@ -108,8 +108,11 @@ static uint8_t fdc37c93x_gpio_read(uint16_t port, void *priv) { fdc37c93x_t *dev = (fdc37c93x_t *) priv; + uint8_t ret = 0xff; - return dev->gpio_regs[port & 1]; + ret = dev->gpio_regs[port & 1]; + + return ret; } @@ -118,7 +121,8 @@ fdc37c93x_gpio_write(uint16_t port, uint8_t val, void *priv) { fdc37c93x_t *dev = (fdc37c93x_t *) priv; - dev->gpio_regs[port & 1] = val; + if (!(port & 1)) + dev->gpio_regs[0] = (dev->gpio_regs[0] & 0xfc) | (val & 0x03); } @@ -756,8 +760,8 @@ fdc37c93x_init(const device_t *info) dev->chip_id = info->local; - dev->gpio_regs[0] = 0xFD; - dev->gpio_regs[1] = 0xFF; + dev->gpio_regs[0] = 0xff; + dev->gpio_regs[1] = 0xfd; if (dev->chip_id == 0x30) { dev->nvr = device_add(&at_nvr_device); diff --git a/src/sio/sio_w83787f.c b/src/sio/sio_w83787f.c index bc1a4792c..f1a6e51d8 100644 --- a/src/sio/sio_w83787f.c +++ b/src/sio/sio_w83787f.c @@ -145,27 +145,24 @@ w83787f_serial_handler(w83787f_t *dev, int uart) static void w83787f_lpt_handler(w83787f_t *dev) { - int ptrs0 = !!(dev->regs[1] & 4); - int ptrs1 = !!(dev->regs[1] & 5); - int ptrs, irq = 7; + int ptras = (dev->regs[1] >> 4) & 0x03; + int irq = 7; uint16_t addr = 0x378, enable = 1; - ptrs = (ptrs1 << 1) | ptrs0; - - switch (ptrs) { - case 0: + switch (ptras) { + case 0x00: addr = 0x3bc; irq = 7; break; - case 1: + case 0x01: addr = 0x278; irq = 5; break; - case 2: + case 0x02: addr = 0x378; irq = 7; break; - case 3: + case 0x03: default: enable = 0; break; diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 2334fa603..cea2187e3 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -559,7 +559,7 @@ CPUOBJ := cpu.o cpu_table.o \ x86seg.o x87.o x87_timings.o \ $(DYNARECOBJ) -CHIPSETOBJ := acc2168.o acer_m3a.o cs8230.o ali1429.o headland.o i82335.o \ +CHIPSETOBJ := acc2168.o cs8230.o ali1429.o headland.o i82335.o \ intel_420ex.o intel_4x0.o intel_sio.o intel_piix.o ioapic.o \ neat.o opti495.o opti5x7.o scamp.o scat.o \ sis_85c310.o sis_85c471.o sis_85c496.o \ From 616a8501b56ad1a098ca02a42fd843c441c790bc Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 29 Jun 2020 02:19:05 +0200 Subject: [PATCH 28/54] Moved floppy writeback call to fdc_poll_readwrite_finish(), in order to have the track written less often (no need to write it on every sector). --- src/floppy/fdc.c | 3 +++ src/floppy/fdd.c | 7 +++++++ src/floppy/fdd_86f.c | 1 - src/include/86box/fdd.h | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 2667727b6..3be66cf0f 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -1468,6 +1468,9 @@ fdc_poll_common_finish(fdc_t *fdc, int compare, int st5) static void fdc_poll_readwrite_finish(fdc_t *fdc, int compare) { + if ((fdc->interrupt == 5) || (fdc->interrupt == 9)) + fdd_do_writeback(real_drive(fdc, fdc->drive)); + fdc->inread = 0; fdc->interrupt = -2; diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 791c82abd..7e1b21452 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -719,3 +719,10 @@ fdd_init(void) fdd_load(2, floppyfns[2]); fdd_load(3, floppyfns[3]); } + + +void +fdd_do_writeback(int drive) +{ + d86f_handler[drive].writeback(drive); +} diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 131f1658f..fe61eae2a 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -1712,7 +1712,6 @@ d86f_write_sector_data(int drive, int side, int mfm, uint16_t am) dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; dev->error_condition = 0; dev->state = STATE_IDLE; - d86f_handler[drive].writeback(drive); fdc_sector_finishread(d86f_fdc); return; } diff --git a/src/include/86box/fdd.h b/src/include/86box/fdd.h index b486b617d..4a7de7c21 100644 --- a/src/include/86box/fdd.h +++ b/src/include/86box/fdd.h @@ -112,6 +112,7 @@ extern void fdd_readaddress(int drive, int side, int density); extern void fdd_format(int drive, int side, int density, uint8_t fill); extern int fdd_hole(int drive); extern void fdd_stop(int drive); +extern void fdd_do_writeback(int drive); extern int motorspin; extern uint64_t motoron[FDD_NUM]; From 53afbfcd49949fd8f40ea438fc104e6d8373429d Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 29 Jun 2020 03:14:16 +0200 Subject: [PATCH 29/54] Changed the writing of the 86f surface array to be in accordance with the pecification. --- src/floppy/fdd_86f.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index fe61eae2a..9939a037a 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -2917,9 +2917,9 @@ d86f_read_track(int drive, int track, int thin_track, int side, uint16_t *da, ui } else fseek(dev->f, dev->track_offset[logical_track] + d86f_track_header_size(drive), SEEK_SET); array_size = d86f_get_array_size(drive, side, 0); + fread(da, 1, array_size, dev->f); if (d86f_has_surface_desc(drive)) fread(sa, 1, array_size, dev->f); - fread(da, 1, array_size, dev->f); } else { if (! thin_track) { switch((dev->disk_flags >> 1) & 3) { @@ -3014,10 +3014,10 @@ d86f_write_track(int drive, FILE **f, int side, uint16_t *da0, uint16_t *sa0) fwrite(&index_hole_pos, 1, 4, *f); + fwrite(da0, 1, array_size, *f); + if (d86f_has_surface_desc(drive)) fwrite(sa0, 1, array_size, *f); - - fwrite(da0, 1, array_size, *f); } From 014552f235b6a5175dd74b9db8a13ffe0c9927e5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 29 Jun 2020 04:32:30 +0200 Subject: [PATCH 30/54] Fixes to SiS 496/497 and W83787F. --- src/chipset/sis_85c496.c | 2 +- src/sio/sio_w83787f.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c index 978f5d29e..0bec0232f 100644 --- a/src/chipset/sis_85c496.c +++ b/src/chipset/sis_85c496.c @@ -259,7 +259,7 @@ sis_85c49x_pci_write(int func, int addr, uint8_t val, void *priv) case 0x48: case 0x49: case 0x4a: case 0x4b: /* DRAM Boundary */ case 0x4c: case 0x4d: case 0x4e: case 0x4f: // dev->pci_conf[addr] = val; - spd_write_drbs(dev->pci_conf, 0x40, 0x4f, 1); + spd_write_drbs(dev->pci_conf, 0x48, 0x4f, 1); break; case 0x50: case 0x51: /* Exclusive Area 0 Setup */ dev->pci_conf[addr] = val; diff --git a/src/sio/sio_w83787f.c b/src/sio/sio_w83787f.c index f1a6e51d8..8fe4f4bf7 100644 --- a/src/sio/sio_w83787f.c +++ b/src/sio/sio_w83787f.c @@ -183,7 +183,7 @@ static void w83787f_fdc_handler(w83787f_t *dev) { fdc_remove(dev->fdc); - if (!(dev->regs[0] & 0x20)) + if (!(dev->regs[0] & 0x20) && !(dev->regs[6] & 0x08)) fdc_set_base(dev->fdc, (dev->regs[0] & 0x10) ? 0x03f0 : 0x0370); } @@ -251,11 +251,8 @@ w83787f_write(uint16_t port, uint8_t val, void *priv) w83787f_lpt_handler(dev); break; case 6: - if (valxor & 0x08) { - fdc_remove(dev->fdc); - if (!(dev->regs[6] & 0x08)) - fdc_set_base(dev->fdc, 0x03f0); - } + if (valxor & 0x08) + w83787f_fdc_handler(dev); break; case 7: if (valxor & 0x03) @@ -283,6 +280,9 @@ w83787f_write(uint16_t port, uint8_t val, void *priv) if (valxor & 0x80) w83787f_lpt_handler(dev); break; + case 0xB: + pclog("Writing %02X to CRB\n", val); + break; case 0xC: if (valxor & 0x20) w83787f_remap(dev); From 5c1f94712272e7991f4bba567c0f3627738a5113 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 29 Jun 2020 14:33:12 +0200 Subject: [PATCH 31/54] The VLSI VL82C480 chipset now has Port 92h, fixes the IBM PS/1 model 2133. --- src/chipset/vl82c480.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/chipset/vl82c480.c b/src/chipset/vl82c480.c index d20eb4ba6..51cffb4a3 100644 --- a/src/chipset/vl82c480.c +++ b/src/chipset/vl82c480.c @@ -171,7 +171,9 @@ vl82c480_init(const device_t *info) dev->cfg_regs[CFG_ID] = ID_VL82C480; io_sethandler(0x00ec, 0x0004, vl82c480_read, NULL, NULL, vl82c480_write, NULL, NULL, dev); - + + device_add(&port_92_device); + return dev; } From 388825377c31f7462418514c7cbba635ac19693f Mon Sep 17 00:00:00 2001 From: tiseno100 <58827426+tiseno100@users.noreply.github.com> Date: Mon, 29 Jun 2020 16:26:18 +0300 Subject: [PATCH 32/54] Implemented the OPTi 895 Similar the OPTi 495 & 802G. It's a 486 ISA/VLB chipset used by many known boards. One being the PB450. --- src/chipset/opti895.c | 184 +++++++++++++++++++++++++++++++++++ src/include/86box/chipset.h | 1 + src/include/86box/machine.h | 2 + src/machine/m_at_386dx_486.c | 25 ++++- src/machine/machine_table.c | 1 + 5 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 src/chipset/opti895.c diff --git a/src/chipset/opti895.c b/src/chipset/opti895.c new file mode 100644 index 000000000..0b5548f72 --- /dev/null +++ b/src/chipset/opti895.c @@ -0,0 +1,184 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the OPTi 82C802G/82C895 chipset. + * + * + * Note: The shadowing of the chipset is enough to get the current machine + * to work. Getting anything other to work will require excessive amount + * of rewrites and improvements. Also, considering the similarities with the + * 82C495XLC & 82C802G it can be merged with opti495.c and also get 82C802G + * implemented. + * + * Copyright 2020 Tiseno100. + */ + +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/keyboard.h> +#include <86box/mem.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/port_92.h> +#include <86box/chipset.h> + + +typedef struct +{ + uint8_t idx, + regs[256], + scratch[2]; +} opti895_t; + +static void +opti895_recalc(opti895_t *dev) +{ + uint32_t base; + uint32_t i, shflags = 0; + + shadowbios = 0; + shadowbios_write = 0; + + for (i = 0; i < 8; i++) { + if(dev->regs[0x22] & (i << 8) && (i==7)){ + shadowbios = 1; + shadowbios_write = 1; + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + } + else if(!(dev->regs[0x22] & (i << 8)) && (i==7)) { + shadowbios = 0; + shadowbios_write = 0; + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + + /* + We'll ignore it for now + base = 0xc0000 + (i << 14); + if (dev->regs[0x26] & (1 << i) && (i<=3)) { + shflags = (dev->regs[0x26] & 0x20) ? (MEM_READ_INTERNAL | MEM_WRITE_DISABLED) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state(base, 0x4000, shflags); + } else mem_set_mem_state(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + */ + + base = 0xd0000 + (i << 14); + if (dev->regs[0x23] & (1 << i)) { + if(base < 0xe0000) + shflags = (dev->regs[0x22] & 0x10) ? (MEM_READ_INTERNAL | MEM_WRITE_DISABLED) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + else + shflags = (dev->regs[0x22] & 0x08) ? (MEM_READ_INTERNAL | MEM_WRITE_DISABLED) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state(base, 0x4000, shflags); + } else mem_set_mem_state(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + } + + flushmmucache(); +} + +static void +opti895_write(uint16_t addr, uint8_t val, void *priv) +{ + opti895_t *dev = (opti895_t *) priv; + + switch (addr) { + case 0x22: + dev->idx = val; + break; + case 0x24: + dev->regs[dev->idx] = val; + pclog("dev->regs[%04x] = %08x\n", dev->idx, val); + switch(dev->idx){ + case 0x21: + if(dev->regs[0x21] & 0x10){ + cpu_cache_ext_enabled = 1; + cpu_update_waitstates(); + } + break; + + case 0x22: + case 0x23: + case 0x26: + opti895_recalc(dev); + break; + + } + + break; + + case 0xe1: + case 0xe2: + dev->scratch[addr] = val; + break; + } +} + + +static uint8_t +opti895_read(uint16_t addr, void *priv) +{ + uint8_t ret = 0xff; + opti895_t *dev = (opti895_t *) priv; + + switch (addr) { + case 0x24: + ret = dev->regs[dev->idx]; + break; + case 0xe1: + case 0xe2: + ret = dev->scratch[addr]; + break; + } + + return ret; +} + + +static void +opti895_close(void *priv) +{ + opti895_t *dev = (opti895_t *) priv; + + free(dev); +} + + +static void * +opti895_init(const device_t *info) +{ + opti895_t *dev = (opti895_t *) malloc(sizeof(opti895_t)); + memset(dev, 0, sizeof(opti895_t)); + + device_add(&port_92_device); + + io_sethandler(0x0022, 0x0001, opti895_read, NULL, NULL, opti895_write, NULL, NULL, dev); + io_sethandler(0x0024, 0x0001, opti895_read, NULL, NULL, opti895_write, NULL, NULL, dev); + + dev->scratch[0] = dev->scratch[1] = 0xff; + + io_sethandler(0x00e1, 0x0002, opti895_read, NULL, NULL, opti895_write, NULL, NULL, dev); + + return dev; +} + + +const device_t opti895_device = { + "OPTi 82C895", + 0, + 0, + opti895_init, opti895_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index defc595ae..2a0d00f1a 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -61,6 +61,7 @@ extern const device_t ioapic_device; /* OPTi */ extern const device_t opti495_device; +extern const device_t opti895_device; extern const device_t opti5x7_device; /* C&T */ diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index b0b4fa054..360ed7cda 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -262,6 +262,8 @@ extern int machine_at_opti495_init(const machine_t *); extern int machine_at_opti495_ami_init(const machine_t *); extern int machine_at_opti495_mr_init(const machine_t *); +extern int machine_at_403tg_init(const machine_t *); + extern int machine_at_vli486sv2g_init(const machine_t *); extern int machine_at_ami471_init(const machine_t *); extern int machine_at_dtk486_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 6946dffa2..43cd7ca16 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -272,6 +272,26 @@ machine_at_opti495_mr_init(const machine_t *model) return ret; } +int +machine_at_403tg_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/403tg/403TG.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_ide_init(model); + + device_add(&opti895_device); + + device_add(&keyboard_at_device); + device_add(&fdc_at_device); + + return ret; +} static void machine_at_sis_85c471_common_init(const machine_t *model) @@ -404,7 +424,8 @@ machine_at_r418_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init_ex(model, 2); + machine_at_common_init_ex(model, 2) + machine_at_sis_85c496_common_init(model); device_add(&sis_85c496_device); pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); @@ -431,6 +452,7 @@ machine_at_ls486e_init(const machine_t *model) return ret; machine_at_common_init_ex(model, 2); + machine_at_sis_85c496_common_init(model); device_add(&sis_85c496_ls486e_device); pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); @@ -457,6 +479,7 @@ machine_at_4dps_init(const machine_t *model) return ret; machine_at_common_init_ex(model, 2); + machine_at_sis_85c496_common_init(model); device_add(&sis_85c496_device); pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 5c89a6eb1..e81c33071 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -200,6 +200,7 @@ const machine_t machines[] = { { "[OPTi 495] Award 486 clone", "award486", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, { "[OPTi 495] MR 486 clone", "mr486", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, { "[OPTi 495] Dataexpert SX495 (486)", "ami486", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, + { "[OPTi 895] Jetway J-403TG", "403tg", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT, 1, 64, 1, 127, machine_at_403tg_init, NULL }, { "[SiS 471] ASUS VL/I-486SV2G (GX4)", "vli486sv2g", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_vli486sv2g_init, NULL }, { "[SiS 471] AMI 486 Clone", "ami471", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_ami471_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_WIN471) From 0b17c4ef315eee2955a0f614e5abb588e51a32f2 Mon Sep 17 00:00:00 2001 From: tiseno100 <58827426+tiseno100@users.noreply.github.com> Date: Mon, 29 Jun 2020 16:28:22 +0300 Subject: [PATCH 33/54] Fixed a small inconsistency --- src/machine/m_at_386dx_486.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 43cd7ca16..0f47126ee 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -424,7 +424,7 @@ machine_at_r418_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init_ex(model, 2) + machine_at_common_init_ex(model, 2); machine_at_sis_85c496_common_init(model); device_add(&sis_85c496_device); From cd840c4c02b9d73bc23ad885ca8ac0e20e06f7f8 Mon Sep 17 00:00:00 2001 From: tiseno100 <58827426+tiseno100@users.noreply.github.com> Date: Mon, 29 Jun 2020 16:38:26 +0300 Subject: [PATCH 34/54] Added the OPTi 895 in Makefile --- src/win/Makefile.mingw | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index cea2187e3..b21ecfd44 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -559,9 +559,9 @@ CPUOBJ := cpu.o cpu_table.o \ x86seg.o x87.o x87_timings.o \ $(DYNARECOBJ) -CHIPSETOBJ := acc2168.o cs8230.o ali1429.o headland.o i82335.o \ +CHIPSETOBJ := acc2168.o acer_m3a.o cs8230.o ali1429.o headland.o i82335.o \ intel_420ex.o intel_4x0.o intel_sio.o intel_piix.o ioapic.o \ - neat.o opti495.o opti5x7.o scamp.o scat.o \ + neat.o opti495.o opti895.o opti5x7.o scamp.o scat.o \ sis_85c310.o sis_85c471.o sis_85c496.o \ via_apollo.o via_vpx.o via_vt82c586b.o via_vt82c596b.o wd76c10.o vl82c480.o \ amd640.o From 672b0bbef70a9c11d48a00a35fa1a9055be029a1 Mon Sep 17 00:00:00 2001 From: tiseno100 <58827426+tiseno100@users.noreply.github.com> Date: Mon, 29 Jun 2020 16:39:30 +0300 Subject: [PATCH 35/54] Deleted the Acer off the Makefile It's not needed anymore. --- src/win/Makefile.mingw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index b21ecfd44..7e5479f8b 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -559,7 +559,7 @@ CPUOBJ := cpu.o cpu_table.o \ x86seg.o x87.o x87_timings.o \ $(DYNARECOBJ) -CHIPSETOBJ := acc2168.o acer_m3a.o cs8230.o ali1429.o headland.o i82335.o \ +CHIPSETOBJ := acc2168.o cs8230.o ali1429.o headland.o i82335.o \ intel_420ex.o intel_4x0.o intel_sio.o intel_piix.o ioapic.o \ neat.o opti495.o opti895.o opti5x7.o scamp.o scat.o \ sis_85c310.o sis_85c471.o sis_85c496.o \ From 4a8aa601b61c4549b5b3a7e70ce0c0ab0c9a5938 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 29 Jun 2020 18:13:14 +0200 Subject: [PATCH 36/54] Fixed (and improved) the OPTi 895 chipset implementation. --- src/chipset/opti895.c | 172 +++++++++++++++++++++++++++++++----------- 1 file changed, 130 insertions(+), 42 deletions(-) diff --git a/src/chipset/opti895.c b/src/chipset/opti895.c index 0b5548f72..bcdd43f38 100644 --- a/src/chipset/opti895.c +++ b/src/chipset/opti895.c @@ -15,9 +15,14 @@ * 82C495XLC & 82C802G it can be merged with opti495.c and also get 82C802G * implemented. * - * Copyright 2020 Tiseno100. + * + * + * Authors: Tiseno100, + * Miran Grca, + * + * Copyright 2008-2020 Tiseno100. + * Copyright 2016-2020 Miran Grca. */ - #include #include #include @@ -40,11 +45,32 @@ typedef struct { - uint8_t idx, + uint8_t idx, forced_green, regs[256], scratch[2]; } opti895_t; + +#ifdef ENABLE_OPTI895_LOG +int opti895_do_log = ENABLE_OPTI895_LOG; + + +static void +opti895_log(const char *fmt, ...) +{ + va_list ap; + + if (opti895_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define opti895_log(fmt, ...) +#endif + + static void opti895_recalc(opti895_t *dev) { @@ -54,40 +80,61 @@ opti895_recalc(opti895_t *dev) shadowbios = 0; shadowbios_write = 0; + if (dev->regs[0x22] & 0x80) { + shadowbios = 1; + shadowbios_write = 0; + shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL; + } else { + shadowbios = 0; + shadowbios_write = 1; + shflags = MEM_READ_INTERNAL | MEM_WRITE_DISABLED; + } + + mem_set_mem_state_both(0xf0000, 0x10000, shflags); + for (i = 0; i < 8; i++) { - if(dev->regs[0x22] & (i << 8) && (i==7)){ - shadowbios = 1; - shadowbios_write = 1; - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); - } - else if(!(dev->regs[0x22] & (i << 8)) && (i==7)) { - shadowbios = 0; - shadowbios_write = 0; - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - } - - /* - We'll ignore it for now - base = 0xc0000 + (i << 14); - if (dev->regs[0x26] & (1 << i) && (i<=3)) { - shflags = (dev->regs[0x26] & 0x20) ? (MEM_READ_INTERNAL | MEM_WRITE_DISABLED) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_set_mem_state(base, 0x4000, shflags); - } else mem_set_mem_state(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - */ - base = 0xd0000 + (i << 14); + if (dev->regs[0x23] & (1 << i)) { - if(base < 0xe0000) - shflags = (dev->regs[0x22] & 0x10) ? (MEM_READ_INTERNAL | MEM_WRITE_DISABLED) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - else - shflags = (dev->regs[0x22] & 0x08) ? (MEM_READ_INTERNAL | MEM_WRITE_DISABLED) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_set_mem_state(base, 0x4000, shflags); - } else mem_set_mem_state(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + if (dev->regs[0x26] & 0x40) + shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL; + else { + shflags = MEM_READ_INTERNAL; + shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; + } + } else + shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY; + + mem_set_mem_state_both(base, 0x4000, shflags); + } + + for (i = 0; i < 4; i++) { + base = 0xc0000 + (i << 14); + + if (dev->regs[0x26] & (1 << i)) { + if (dev->regs[0x26] & 0x40) + shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL; + else { + shflags = MEM_READ_INTERNAL; + shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; + } + } else + shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY; + + mem_set_mem_state_both(base, 0x4000, shflags); } flushmmucache(); } + +static void +opti895_smram_map(int smm, uint32_t addr, uint32_t size, int is_smram) +{ + mem_set_mem_state_smram(smm, addr, size, is_smram); +} + + static void opti895_write(uint16_t addr, uint8_t val, void *priv) { @@ -98,24 +145,38 @@ opti895_write(uint16_t addr, uint8_t val, void *priv) dev->idx = val; break; case 0x24: - dev->regs[dev->idx] = val; - pclog("dev->regs[%04x] = %08x\n", dev->idx, val); - switch(dev->idx){ - case 0x21: - if(dev->regs[0x21] & 0x10){ - cpu_cache_ext_enabled = 1; + dev->regs[dev->idx] = val; + opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val); + + switch(dev->idx) { + case 0x21: + cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10); cpu_update_waitstates(); - } break; - case 0x22: - case 0x23: - case 0x26: + case 0x22: + case 0x23: + case 0x26: opti895_recalc(dev); break; - } + case 0x24: + opti895_smram_map(0, smram[0].host_base, smram[0].size, !!(val & 0x80)); + break; + case 0xe0: + if (!(val & 0x01)) + dev->forced_green = 0; + break; + + case 0xe1: + if ((val & 0x08) && (dev->regs[0xe0] & 0x01)) { + smi_line = 1; + dev->forced_green = 1; + break; + } + break; + } break; case 0xe1: @@ -135,6 +196,8 @@ opti895_read(uint16_t addr, void *priv) switch (addr) { case 0x24: ret = dev->regs[dev->idx]; + if (dev->idx == 0xe0) + ret = (ret & 0xf6) | (in_smm ? 0x00 : 0x08) | !!dev->forced_green; break; case 0xe1: case 0xe2: @@ -161,15 +224,40 @@ opti895_init(const device_t *info) opti895_t *dev = (opti895_t *) malloc(sizeof(opti895_t)); memset(dev, 0, sizeof(opti895_t)); - device_add(&port_92_device); - + device_add(&port_92_device); + io_sethandler(0x0022, 0x0001, opti895_read, NULL, NULL, opti895_write, NULL, NULL, dev); io_sethandler(0x0024, 0x0001, opti895_read, NULL, NULL, opti895_write, NULL, NULL, dev); dev->scratch[0] = dev->scratch[1] = 0xff; + dev->regs[0x22] = 0xc4; + dev->regs[0x25] = 0x7c; + dev->regs[0x26] = 0x10; + dev->regs[0x27] = 0xde; + dev->regs[0x28] = 0xf8; + dev->regs[0x29] = 0x10; + dev->regs[0x2a] = 0xe0; + dev->regs[0x2b] = 0x10; + dev->regs[0x2d] = 0xc0; + + dev->regs[0xeb] = 0xff; + dev->regs[0xef] = 0x40; + + opti895_recalc(dev); + io_sethandler(0x00e1, 0x0002, opti895_read, NULL, NULL, opti895_write, NULL, NULL, dev); + smram[0].host_base = 0x00030000; + smram[0].ram_base = 0x000b0000; + smram[0].size = 0x00010000; + + mem_mapping_set_addr(&ram_smram_mapping[0], smram[0].host_base, smram[0].size); + mem_mapping_set_exec(&ram_smram_mapping[0], ram + smram[0].ram_base); + + opti895_smram_map(0, smram[0].host_base, smram[0].size, 0); + opti895_smram_map(1, smram[0].host_base, smram[0].size, 1); + return dev; } From a4301708dac41d681b79cfd9702aa567ce59429e Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 29 Jun 2020 18:44:20 +0200 Subject: [PATCH 37/54] Added the OPTi 802G device (the 802G and 895 are register-identical), and added port 23h to the OPTi 8xx'es. --- src/chipset/opti895.c | 36 ++++++++++++++++++++++++++++++++++-- src/include/86box/chipset.h | 1 + 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/chipset/opti895.c b/src/chipset/opti895.c index bcdd43f38..32fd30bac 100644 --- a/src/chipset/opti895.c +++ b/src/chipset/opti895.c @@ -144,7 +144,17 @@ opti895_write(uint16_t addr, uint8_t val, void *priv) case 0x22: dev->idx = val; break; + case 0x23: + if (dev->idx != 0x01) + break; + + dev->regs[dev->idx] = val; + opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val); + break; case 0x24: + if (dev->idx == 0x01) + break; + dev->regs[dev->idx] = val; opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val); @@ -194,7 +204,16 @@ opti895_read(uint16_t addr, void *priv) opti895_t *dev = (opti895_t *) priv; switch (addr) { + case 0x23: + if (dev->idx != 0x01) + break; + + ret = dev->regs[dev->idx]; + break; case 0x24: + if (dev->idx == 0x01) + break; + ret = dev->regs[dev->idx]; if (dev->idx == 0xe0) ret = (ret & 0xf6) | (in_smm ? 0x00 : 0x08) | !!dev->forced_green; @@ -226,11 +245,12 @@ opti895_init(const device_t *info) device_add(&port_92_device); - io_sethandler(0x0022, 0x0001, opti895_read, NULL, NULL, opti895_write, NULL, NULL, dev); - io_sethandler(0x0024, 0x0001, opti895_read, NULL, NULL, opti895_write, NULL, NULL, dev); + io_sethandler(0x0022, 0x0003, opti895_read, NULL, NULL, opti895_write, NULL, NULL, dev); dev->scratch[0] = dev->scratch[1] = 0xff; + dev->regs[0x01] = 0xc0; + dev->regs[0x22] = 0xc4; dev->regs[0x25] = 0x7c; dev->regs[0x26] = 0x10; @@ -241,6 +261,8 @@ opti895_init(const device_t *info) dev->regs[0x2b] = 0x10; dev->regs[0x2d] = 0xc0; + dev->regs[0xe8] = 0x08; + dev->regs[0xe9] = 0x08; dev->regs[0xeb] = 0xff; dev->regs[0xef] = 0x40; @@ -262,6 +284,16 @@ opti895_init(const device_t *info) } +const device_t opti802g_device = { + "OPTi 82C802G", + 0, + 0, + opti895_init, opti895_close, NULL, + NULL, NULL, NULL, + NULL +}; + + const device_t opti895_device = { "OPTi 82C895", 0, diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 2a0d00f1a..84661e3cb 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -61,6 +61,7 @@ extern const device_t ioapic_device; /* OPTi */ extern const device_t opti495_device; +extern const device_t opti802g_device; extern const device_t opti895_device; extern const device_t opti5x7_device; From 9402f98a3ba88dfa7cf6513b430fcefd284a4ce1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 30 Jun 2020 00:34:49 +0200 Subject: [PATCH 38/54] Rewrote the OPTi 82C495 emulation, added the OPTi 82C493, did some changes to the 82C8xx, and updated Makefile.local. --- src/Makefile.local | 3 + src/chipset/opti495.c | 432 +++++++++++++----------------------- src/chipset/opti895.c | 98 ++++---- src/include/86box/chipset.h | 1 + 4 files changed, 205 insertions(+), 329 deletions(-) diff --git a/src/Makefile.local b/src/Makefile.local index 8b528ff28..095b60024 100644 --- a/src/Makefile.local +++ b/src/Makefile.local @@ -74,8 +74,11 @@ STUFF := # chipset/ logging: # -DENABLE_I420EX_LOG=N sets logging level at N. # -DENABLE_NEAT_LOG=N sets logging level at N. +# -DENABLE_OPTI495_LOG=N sets logging level at N. +# -DENABLE_OPTI895_LOG=N sets logging level at N. # -DENABLE_PIIX_LOG=N sets logging level at N. # -DENABLE_SIO_LOG=N sets logging level at N. +# -DENABLE_SIS_85C496_LOG=N sets logging level at N. # codegen/, codegen_new/, cpu/ logging: # -DENABLE_X86SEG_LOG=N sets logging level at N. # cpu/ logging: diff --git a/src/chipset/opti495.c b/src/chipset/opti495.c index 47ee25582..c192062a7 100644 --- a/src/chipset/opti495.c +++ b/src/chipset/opti495.c @@ -1,256 +1,21 @@ -/*OPTi 82C495 emulation - This is the chipset used in the AMI386 model - - Details for the chipset from Ralph Brown's interrupt list - This describes the OPTi 82C493, the 82C495 seems similar except there is one - more register (2C) - -----------P00220024-------------------------- -PORT 0022-0024 - OPTi 82C493 System Controller (SYSC) - CONFIGURATION REGISTERS -Desc: The OPTi 486SXWB contains three chips and is designed for systems - running at 20, 25 and 33MHz. The chipset includes an 82C493 System - Controller (SYSC), the 82C392 Data Buffer Controller, and the - 82C206 Integrated peripheral Controller (IPC). -Note: every access to PORT 0024h must be preceded by a write to PORT 0022h, - even if the same register is being accessed a second time -SeeAlso: PORT 0022h"82C206" - -0022 ?W configuration register index (see #P0178) -0024 RW configuration register data - -(Table P0178) -Values for OPTi 82C493 System Controller configuration register index: - 20h Control Register 1 (see #P0179) - 21h Control Register 2 (see #P0180) - 22h Shadow RAM Control Register 1 (see #P0181) - 23h Shadow RAM Control Register 2 (see #P0182) - 24h DRAM Control Register 1 (see #P0183) - 25h DRAM Control Register 2 (see #P0184) - 26h Shadow RAM Control Register 3 (see #P0185) - 27h Control Register 3 (see #P0186) - 28h Non-cachable Block 1 Register 1 (see #P0187) - 29h Non-cachable Block 1 Register 2 (see #P0188) - 2Ah Non-cachable Block 2 Register 1 (see #P0187) - 2Bh Non-cachable Block 2 Register 2 (see #P0188) - -Bitfields for OPTi-82C493 Control Register 1: -Bit(s) Description (Table P0179) - 7-6 Revision of 82C493 (readonly) (default=01) - 5 Burst wait state control - 1 = Secondary cache read hit cycle is 3-2-2-2 or 2-2-2-2 - 0 = Secondary cache read hit cycle is 3-1-1-1 or 2-1-1-1 (default) - (if bit 5 is set to 1, bit 4 must be set to 0) - 4 Cache memory data buffer output enable control - 0 = disable (default) - 1 = enable - (must be disabled for frequency <= 33Mhz) - 3 Single Address Latch Enable (ALE) - 0 = disable (default) - 1 = enable - (if enabled, SYSC will activate single ALE rather than multiples - during bus conversion cycles) - 2 enable Extra AT Cycle Wait State (default is 0 = disabled) - 1 Emulation keyboard Reset Control - 0 = disable (default) - 1 = enable - Note: This bit must be enabled in BIOS default value; enabling this - bit requires HALT instruction to be executed before SYSC - generates processor reset (CPURST) - 0 enable Alternative Fast Reset (default is 0 = disabled) -SeeAlso: #P0180,#P0186 - -Bitfields for OPTi-82C493 Control Register 2: -Bit(s) Description (Table P0180) - 7 Master Mode Byte Swap Enable - 0 = disable (default) - 1 = enable - 6 Emulation Keyboard Reset Delay Control - 0 = Generate reset pulse 2us later (default) - 1 = Generate reset pulse immediately - 5 disable Parity Check (default is 0 = enabled) - 4 Cache Enable - 0 = Cache disabled and DRAM burst mode enabled (default) - 1 = Cache enabled and DRAM burst mode disabled - 3-2 Cache Size - 00 64KB (default) - 01 128KB - 10 256KB - 11 512KB - 1 Secondary Cache Read Burst Cycles Control - 0 = 3-1-1-1 cycle (default) - 1 = 2-1-1-1 cycle - 0 Cache Write Wait State Control - 0 = 1 wait state (default) - 1 = 0 wait state -SeeAlso: #P0179,#P0186 - -Bitfields for OPTi-82C493 Shadow RAM Control Register 1: -Bit(s) Description (Table P0181) - 7 ROM(F0000h - FFFFFh) Enable - 0 = read/write on write-protected DRAM - 1 = read from ROM, write to DRAM (default) - 6 Shadow RAM at D0000h - EFFFFh Area - 0 = disable (default) - 1 = enable - 5 Shadow RAM at E0000h - EFFFFh Area - 0 = disable shadow RAM (default) - E0000h - EFFFFh ROM is defaulted to reside on XD bus - 1 = enable shadow RAM - 4 enable write-protect for Shadow RAM at D0000h - DFFFFh Area - 0 = disable (default) - 1 = enable - 3 enable write-protect for Shadow RAM at E0000h - EFFFFh Area - 0 = disable (default) - 1 = enable - 2 Hidden refresh enable (with holding CPU) - (Hidden refresh must be disabled if 4Mx1 or 1M x4 bit DRAM are used) - 1 = disable (default) - 0 = enable - 1 unused - 0 enable Slow Refresh (four times slower than normal refresh) - (default is 0 = disable) -SeeAlso: #P0182 - -Bitfields for OPTi-82C493 Shadow RAM Control Register 2: -Bit(s) Description (Table P0182) - 7 enable Shadow RAM at EC000h - EFFFFh area - 6 enable Shadow RAM at E8000h - EBFFFh area - 5 enable Shadow RAM at E4000h - E7FFFh area - 4 enable Shadow RAM at E0000h - E3FFFh area - 3 enable Shadow RAM at DC000h - DFFFFh area - 2 enable Shadow RAM at D8000h - DBFFFh area - 1 enable Shadow RAM at D4000h - D7FFFh area - 0 enable Shadow RAM at D0000h - D3FFFh area -Note: the default is disabled (0) for all areas - -Bitfields for OPTi-82C493 DRAM Control Register 1: -Bit(s) Description (Table P0183) - 7 DRAM size - 0 = 256K DRAM mode - 1 = 1M and 4M DRAM mode - 6-4 DRAM types used for bank0 and bank1 - bits 7-4 Bank0 Bank1 - 0000 256K x - 0001 256K 256K - 0010 256K 1M - 0011 x x - 01xx x x - 1000 1M x (default) - 1001 1M 1M - 1010 1M 4M - 1011 4M 1M - 1100 4M x - 1101 4M 4M - 111x x x - 3 unused - 2-0 DRAM types used for bank2 and bank3 - bits 7,2-0 Bank2 Bank3 - x000 1M x - x001 1M 1M - x010 x x - x011 4M 1M - x100 4M x - x101 4M 4M - x11x x x (default) -SeeAlso: #P0184 - -Bitfields for OPTi-82C493 DRAM Control Register 2: -Bit(s) Description (Table P0184) - 7-6 Read cycle additional wait states - 00 not used - 01 = 0 - 10 = 1 - 11 = 2 (default) - 5-4 Write cycle additional wait states - 00 = 0 - 01 = 1 - 10 = 2 - 11 = 3 (default) - 3 Fast decode enable - 0 = disable fast decode. DRAM base wait states not changed (default) - 1 = enable fast decode. DRAM base wait state is decreased by 1 - Note: This function may be enabled in 20/25Mhz operation to speed up - DRAM access. If bit 4 of index register 21h (cache enable - bit) is enabled, this bit is automatically disabled--even if - set to 1 - 2 unused - 1-0 ATCLK selection - 00 ATCLK = CLKI/6 (default) - 01 ATCLK = CLKI/4 (default) - 10 ATCLK = CLKI/3 - 11 ATCLK = CLK2I/5 (CLKI * 2 /5) - Note: bit 0 will reflect the BCLKS (pin 142) status and bit 1 will be - set to 0 when 82C493 is reset. -SeeAlso: #P0183,#P0185 - -Bitfields for OPTi-82C493 Shadow RAM Control Register 3: -Bit(s) Description (Table P0185) - 7 unused - 6 Shadow RAM copy enable for address C0000h - CFFFFh - 0 = Read/write at AT bus (default) - 1 = Read from AT bus and write into shadow RAM - 5 Shadow write protect at address C0000h - CFFFFh - 0 = Write protect disable (default) - 1 = Write protect enable - 4 enable Shadow RAM at C0000h - CFFFFh - 3 enable Shadow RAM at CC000h - CFFFFh - 2 enable Shadow RAM at C8000h - CBFFFh - 1 enable Shadow RAM at C4000h - C7FFFh - 0 enable Shadow RAM at C0000h - C3FFFh -Note: the default is disabled (0) for bits 4-0 -SeeAlso: #P0183,#P0184 - -Bitfields for OPTi-82C493 Control Register 3: -Bit(s) Description (Table P0186) - 7 enable NCA# pin to low state (default is 1 = enabled) - 6-5 unused - 4 Video BIOS at C0000h - C8000h non-cacheable - 0 = cacheable - 1 = non-cacheable (default) - 3-0 Cacheable address range for local memory - 0000 0 - 64MB - 0001 0 - 4MB (default) - 0010 0 - 8MB - 0011 0 - 12MB - 0100 0 - 16MB - 0101 0 - 20MB - 0110 0 - 24MB - 0111 0 - 28MB - 1000 0 - 32MB - 1001 0 - 36MB - 1010 0 - 40MB - 1011 0 - 44MB - 1100 0 - 48MB - 1101 0 - 52MB - 1110 0 - 56MB - 1111 0 - 60MB - Note: If total memory is 1MB or 2MB the cacheable range is 0-1 MB or - 0-2 MB and independent of the value of bits 3-0 -SeeAlso: #P0179,#P0180 - -Bitfields for OPTi-82C493 Non-cacheable Block Register 1: -Bit(s) Description (Table P0187) - 7-5 Size of non-cachable memory block - 000 64K - 001 128K - 010 256K - 011 512K - 1xx disabled (default) - 4-2 unused - 1-0 Address bits 25 and 24 of non-cachable memory block (default = 00) -Note: this register is used together with configuration register 29h - (non-cacheable block 1) or register 2Bh (block 2) (see #P0188) to - define a non-cacheable block. The starting address must be a - multiple of the block size -SeeAlso: #P0178,#P0188 - -Bitfields for OPTi-82C493 Non-cacheable Block Register 2: -Bit(s) Description (Table P0188) - 7-0 Address bits 23-16 of non-cachable memory block (default = 0001xxxx) -Note: the block address is forced to be a multiple of the block size by - ignoring the appropriate number of the least-significant bits -SeeAlso: #P0178,#P0187 -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the OPTi 82C493/82C495 chipset. + * + * + * + * Authors: Tiseno100, + * Miran Grca, + * + * Copyright 2008-2020 Tiseno100. + * Copyright 2016-2020 Miran Grca. + */ #include #include #include @@ -267,17 +32,96 @@ SeeAlso: #P0178,#P0187 #include <86box/mem.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/port_92.h> #include <86box/chipset.h> typedef struct { - uint8_t cur_reg, - regs[16], + uint8_t idx, + regs[256], scratch[2]; } opti495_t; +#ifdef ENABLE_OPTI495_LOG +int opti495_do_log = ENABLE_OPTI495_LOG; + + +static void +opti495_log(const char *fmt, ...) +{ + va_list ap; + + if (opti495_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define opti495_log(fmt, ...) +#endif + + +static void +opti495_recalc(opti495_t *dev) +{ + uint32_t base; + uint32_t i, shflags = 0; + + shadowbios = 0; + shadowbios_write = 0; + + if (dev->regs[0x22] & 0x80) { + shadowbios = 1; + shadowbios_write = 0; + shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL; + } else { + shadowbios = 0; + shadowbios_write = 1; + shflags = MEM_READ_INTERNAL | MEM_WRITE_DISABLED; + } + + mem_set_mem_state_both(0xf0000, 0x10000, shflags); + + for (i = 0; i < 8; i++) { + base = 0xd0000 + (i << 14); + + if ((dev->regs[0x22] & ((base >= 0xe0000) ? 0x20 : 0x40)) && + (dev->regs[0x23] & (1 << i))) { + if (dev->regs[0x26] & 0x40) + shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL; + else { + shflags = MEM_READ_INTERNAL; + shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; + } + } else + shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY; + + mem_set_mem_state_both(base, 0x4000, shflags); + } + + for (i = 0; i < 4; i++) { + base = 0xc0000 + (i << 14); + + if ((dev->regs[0x26] & 0x10) && (dev->regs[0x26] & (1 << i))) { + if (dev->regs[0x26] & 0x40) + shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL; + else { + shflags = MEM_READ_INTERNAL; + shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; + } + } else + shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY; + + mem_set_mem_state_both(base, 0x4000, shflags); + } + + flushmmucache(); +} + + static void opti495_write(uint16_t addr, uint8_t val, void *priv) { @@ -285,26 +129,31 @@ opti495_write(uint16_t addr, uint8_t val, void *priv) switch (addr) { case 0x22: - dev->cur_reg = val; + dev->idx = val; break; case 0x24: - if ((dev->cur_reg >= 0x20) && (dev->cur_reg <= 0x2C)) { - dev->regs[dev->cur_reg - 0x20] = val; - if (dev->cur_reg == 0x21) { - cpu_cache_ext_enabled = val & 0x10; - cpu_update_waitstates(); - } - if (dev->cur_reg == 0x22) { - if (!(val & 0x80)) - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); - else - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + if ((dev->idx >= 0x20) && (dev->idx <= 0x2c)) { + dev->regs[dev->idx] = val; + opti495_log("dev->regs[%04x] = %08x\n", dev->idx, val); + + switch(dev->idx) { + case 0x21: + cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10); + cpu_update_waitstates(); + break; + + case 0x22: + case 0x23: + case 0x26: + opti495_recalc(dev); + break; } } break; + case 0xe1: case 0xe2: - dev->scratch[addr - 0xe1] = val; + dev->scratch[addr] = val; break; } } @@ -318,12 +167,12 @@ opti495_read(uint16_t addr, void *priv) switch (addr) { case 0x24: - if ((dev->cur_reg >= 0x20) && (dev->cur_reg <= 0x2C)) - ret = dev->regs[dev->cur_reg - 0x20]; + if ((dev->idx >= 0x20) && (dev->idx <= 0x2c)) + ret = dev->regs[dev->idx]; break; case 0xe1: case 0xe2: - ret = dev->scratch[addr - 0xe1]; + ret = dev->scratch[addr]; break; } @@ -351,19 +200,52 @@ opti495_init(const device_t *info) dev->scratch[0] = dev->scratch[1] = 0xff; - io_sethandler(0x00e1, 0x0002, opti495_read, NULL, NULL, opti495_write, NULL, NULL, dev); + if (info->local == 1) { + /* 85C495 */ + dev->regs[0x20] = 0x02; + dev->regs[0x21] = 0x20; + dev->regs[0x22] = 0xe4; + dev->regs[0x25] = 0xf0; + dev->regs[0x26] = 0x80; + dev->regs[0x27] = 0xb1; + dev->regs[0x28] = 0x80; + dev->regs[0x29] = 0x10; + } else { + /* 85C493 */ + dev->regs[0x20] = 0x40; + dev->regs[0x22] = 0x84; + dev->regs[0x24] = 0x87; + dev->regs[0x25] = 0xf1; /* Note: 0xf0 is also valid default. */ + dev->regs[0x27] = 0x91; + dev->regs[0x28] = 0x80; + dev->regs[0x29] = 0x10; + dev->regs[0x2a] = 0x80; + dev->regs[0x2b] = 0x10; + } - dev->regs[0x22 - 0x20] = 0x80; + opti495_recalc(dev); + + io_sethandler(0x00e1, 0x0002, opti495_read, NULL, NULL, opti495_write, NULL, NULL, dev); return dev; } -const device_t opti495_device = { - "OPTi 82C495", +const device_t opti493_device = { + "OPTi 82C493", 0, 0, opti495_init, opti495_close, NULL, NULL, NULL, NULL, NULL }; + + +const device_t opti495_device = { + "OPTi 82C495", + 0, + 1, + opti495_init, opti495_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/chipset/opti895.c b/src/chipset/opti895.c index 32fd30bac..a01bf099d 100644 --- a/src/chipset/opti895.c +++ b/src/chipset/opti895.c @@ -9,13 +9,6 @@ * Implementation of the OPTi 82C802G/82C895 chipset. * * - * Note: The shadowing of the chipset is enough to get the current machine - * to work. Getting anything other to work will require excessive amount - * of rewrites and improvements. Also, considering the similarities with the - * 82C495XLC & 82C802G it can be merged with opti495.c and also get 82C802G - * implemented. - * - * * * Authors: Tiseno100, * Miran Grca, @@ -145,47 +138,46 @@ opti895_write(uint16_t addr, uint8_t val, void *priv) dev->idx = val; break; case 0x23: - if (dev->idx != 0x01) - break; - - dev->regs[dev->idx] = val; - opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val); + if (dev->idx == 0x01) { + dev->regs[dev->idx] = val; + opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val); + } break; case 0x24: - if (dev->idx == 0x01) - break; + if (((dev->idx >= 0x20) && (dev->idx <= 0x2c)) || + ((dev->idx >= 0xe0) && (dev->idx <= 0xef))) { + dev->regs[dev->idx] = val; + opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val); - dev->regs[dev->idx] = val; - opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val); - - switch(dev->idx) { - case 0x21: - cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10); - cpu_update_waitstates(); - break; - - case 0x22: - case 0x23: - case 0x26: - opti895_recalc(dev); - break; - - case 0x24: - opti895_smram_map(0, smram[0].host_base, smram[0].size, !!(val & 0x80)); - break; - - case 0xe0: - if (!(val & 0x01)) - dev->forced_green = 0; - break; - - case 0xe1: - if ((val & 0x08) && (dev->regs[0xe0] & 0x01)) { - smi_line = 1; - dev->forced_green = 1; + switch(dev->idx) { + case 0x21: + cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10); + cpu_update_waitstates(); break; - } - break; + + case 0x22: + case 0x23: + case 0x26: + opti895_recalc(dev); + break; + + case 0x24: + opti895_smram_map(0, smram[0].host_base, smram[0].size, !!(val & 0x80)); + break; + + case 0xe0: + if (!(val & 0x01)) + dev->forced_green = 0; + break; + + case 0xe1: + if ((val & 0x08) && (dev->regs[0xe0] & 0x01)) { + smi_line = 1; + dev->forced_green = 1; + break; + } + break; + } } break; @@ -205,18 +197,16 @@ opti895_read(uint16_t addr, void *priv) switch (addr) { case 0x23: - if (dev->idx != 0x01) - break; - - ret = dev->regs[dev->idx]; + if (dev->idx == 0x01) + ret = dev->regs[dev->idx]; break; case 0x24: - if (dev->idx == 0x01) - break; - - ret = dev->regs[dev->idx]; - if (dev->idx == 0xe0) - ret = (ret & 0xf6) | (in_smm ? 0x00 : 0x08) | !!dev->forced_green; + if (((dev->idx >= 0x20) && (dev->idx <= 0x2c)) || + ((dev->idx >= 0xe0) && (dev->idx <= 0xef))) { + ret = dev->regs[dev->idx]; + if (dev->idx == 0xe0) + ret = (ret & 0xf6) | (in_smm ? 0x00 : 0x08) | !!dev->forced_green; + } break; case 0xe1: case 0xe2: diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 84661e3cb..de25fca32 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -60,6 +60,7 @@ extern const device_t slc90e66_device; extern const device_t ioapic_device; /* OPTi */ +extern const device_t opti493_device; extern const device_t opti495_device; extern const device_t opti802g_device; extern const device_t opti895_device; From 13e8d9c923ef3198c91aa942aaf8af865968a396 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 30 Jun 2020 03:24:06 +0200 Subject: [PATCH 39/54] Fixed Shadow RAM handling for all OPTi 486 chipsets. --- src/chipset/opti495.c | 30 ++++++++++++++++-------------- src/chipset/opti895.c | 30 ++++++++++++++++-------------- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/chipset/opti495.c b/src/chipset/opti495.c index c192062a7..c3fa1bda4 100644 --- a/src/chipset/opti495.c +++ b/src/chipset/opti495.c @@ -90,14 +90,15 @@ opti495_recalc(opti495_t *dev) if ((dev->regs[0x22] & ((base >= 0xe0000) ? 0x20 : 0x40)) && (dev->regs[0x23] & (1 << i))) { - if (dev->regs[0x26] & 0x40) - shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL; - else { - shflags = MEM_READ_INTERNAL; + shflags = MEM_READ_INTERNAL; + shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; + } else { + if (dev->regs[0x26] & 0x40) { + shflags = MEM_READ_EXTANY; shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; - } - } else - shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY; + } else + shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY; + } mem_set_mem_state_both(base, 0x4000, shflags); } @@ -106,14 +107,15 @@ opti495_recalc(opti495_t *dev) base = 0xc0000 + (i << 14); if ((dev->regs[0x26] & 0x10) && (dev->regs[0x26] & (1 << i))) { - if (dev->regs[0x26] & 0x40) - shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL; - else { - shflags = MEM_READ_INTERNAL; + shflags = MEM_READ_INTERNAL; + shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; + } else { + if (dev->regs[0x26] & 0x40) { + shflags = MEM_READ_EXTANY; shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; - } - } else - shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY; + } else + shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY; + } mem_set_mem_state_both(base, 0x4000, shflags); } diff --git a/src/chipset/opti895.c b/src/chipset/opti895.c index a01bf099d..8c1f050b4 100644 --- a/src/chipset/opti895.c +++ b/src/chipset/opti895.c @@ -89,14 +89,15 @@ opti895_recalc(opti895_t *dev) base = 0xd0000 + (i << 14); if (dev->regs[0x23] & (1 << i)) { - if (dev->regs[0x26] & 0x40) - shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL; - else { - shflags = MEM_READ_INTERNAL; + shflags = MEM_READ_INTERNAL; + shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; + } else { + if (dev->regs[0x26] & 0x40) { + shflags = MEM_READ_EXTANY; shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; - } - } else - shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY; + } else + shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY; + } mem_set_mem_state_both(base, 0x4000, shflags); } @@ -105,14 +106,15 @@ opti895_recalc(opti895_t *dev) base = 0xc0000 + (i << 14); if (dev->regs[0x26] & (1 << i)) { - if (dev->regs[0x26] & 0x40) - shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL; - else { - shflags = MEM_READ_INTERNAL; + shflags = MEM_READ_INTERNAL; + shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; + } else { + if (dev->regs[0x26] & 0x40) { + shflags = MEM_READ_EXTANY; shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; - } - } else - shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY; + } else + shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY; + } mem_set_mem_state_both(base, 0x4000, shflags); } From 546f0a83e7d81f7e6b51824bbabca0694890e095 Mon Sep 17 00:00:00 2001 From: nerd73 Date: Mon, 29 Jun 2020 22:06:27 -0600 Subject: [PATCH 40/54] Implement C0000-DFFFF shadowing on the OPTi 5x7 chipset --- src/chipset/opti5x7.c | 80 ++++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 24 deletions(-) diff --git a/src/chipset/opti5x7.c b/src/chipset/opti5x7.c index 6f13edccf..ef43b5343 100644 --- a/src/chipset/opti5x7.c +++ b/src/chipset/opti5x7.c @@ -1,5 +1,19 @@ -/*Based off the OPTI 82C546/82C547 datasheet. -The earlier 596/597 appears to be register compatible with the 546/547 from testing.*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the OPTi 82C546/82C547 & 82C596/82C597 chipsets. + + * Authors: plant/nerd73 + * Miran Grca, + * + * Copyright 2020 plant/nerd73. + * Copyright 2020 Miran Grca. + */ #include #include #include @@ -22,29 +36,40 @@ The earlier 596/597 appears to be register compatible with the 546/547 from test typedef struct { - uint8_t cur_reg, + uint8_t idx, regs[16]; - port_92_t *port_92; + port_92_t *port_92; } opti5x7_t; static void -opti5x7_recalcmapping(opti5x7_t *dev) +opti5x7_recalc(opti5x7_t *dev) { - uint32_t shflags = 0; + uint32_t base; + uint32_t i, j, shflags = 0; + uint32_t reg, lowest_bit; + uint32_t write = 0; - shadowbios = 0; - shadowbios_write = 0; - - - shadowbios |= !!(dev->regs[0x06] & 0x05); - shadowbios_write |= !!(dev->regs[0x06] & 0x0a); + for (i = 0; i < 8; i++) { + j = i / 2.01; /*Probably not a great way of doing this, but it does work*/ + base = 0xc0000 + (j << 14); + + lowest_bit = j * 2; + reg = 0x04 + ((base >> 16) & 0x01); + + shflags = (dev->regs[reg] & (1 << lowest_bit)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + shflags |= (dev->regs[reg] & (1 << (lowest_bit + 1))) ? MEM_WRITE_INTERNAL : write; + write = (dev->regs[reg] & (1 << lowest_bit)) ? MEM_WRITE_DISABLED : MEM_WRITE_EXTANY; + mem_set_mem_state(base, 0x4000, shflags); + } shflags = (dev->regs[0x06] & 0x01) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - shflags |= (dev->regs[0x06] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + shflags |= (dev->regs[0x06] & 0x02) ? MEM_WRITE_INTERNAL : write; + write = (dev->regs[0x06] & 0x01) ? MEM_WRITE_DISABLED : MEM_WRITE_EXTANY; mem_set_mem_state(0xe0000, 0x10000, shflags); shflags = (dev->regs[0x06] & 0x04) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - shflags |= (dev->regs[0x06] & 0x08) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + shflags |= (dev->regs[0x06] & 0x08) ? MEM_WRITE_INTERNAL : write; + write = (dev->regs[0x06] & 0x04) ? MEM_WRITE_DISABLED : MEM_WRITE_EXTANY; mem_set_mem_state(0xf0000, 0x10000, shflags); flushmmucache(); @@ -53,18 +78,25 @@ static void opti5x7_write(uint16_t addr, uint8_t val, void *priv) { opti5x7_t *dev = (opti5x7_t *) priv; -// pclog("Write %02x to OPTi 5x7 address %02x\n", val, addr); + pclog("Write %02x to OPTi 5x7 address %02x\n", val, addr); switch (addr) { case 0x22: - dev->cur_reg = val; + dev->idx = val; break; case 0x24: - dev->regs[dev->cur_reg] = val; - if (dev->regs[0x02] & 0x0c) - cpu_cache_ext_enabled = 1; - if (dev->cur_reg == 0x06) - opti5x7_recalcmapping(dev); + dev->regs[dev->idx] = val; + switch(dev->idx) { + case 0x02: + cpu_cache_ext_enabled = !!(dev->regs[0x02] & 0x04 & 0x08); + break; + + case 0x04: + case 0x05: + case 0x06: + opti5x7_recalc(dev); + break; + } break; } } @@ -78,8 +110,8 @@ opti5x7_read(uint16_t addr, void *priv) switch (addr) { case 0x24: -// pclog("Read from OPTI 5x7 register %02x\n", dev->cur_reg); - ret = dev->regs[dev->cur_reg]; + pclog("Read from OPTi 5x7 register %02x\n", dev->idx); + ret = dev->regs[dev->idx]; break; } @@ -107,7 +139,7 @@ opti5x7_init(const device_t *info) dev->port_92 = device_add(&port_92_device); // pclog("OPTi 5x7 init\n"); - opti5x7_recalcmapping(dev); + opti5x7_recalc(dev); return dev; From 57d7982a5326ce536904087ee38f9ed597a943c4 Mon Sep 17 00:00:00 2001 From: Gey Cunt <38372778+SauceJustSauce@users.noreply.github.com> Date: Tue, 30 Jun 2020 16:15:48 +0300 Subject: [PATCH 41/54] Added various Dell machines --- src/include/86box/machine.h | 4 +++ src/machine/m_at_socket4_5.c | 63 +++++++++++++++++++++++++++++++++++- src/machine/machine_table.c | 6 +++- src/win/Makefile.mingw | 10 ++++++ 4 files changed, 81 insertions(+), 2 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 360ed7cda..fc423786a 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -302,6 +302,10 @@ extern int machine_at_ambradp60_init(const machine_t *); #if defined(DEV_BRANCH) && defined(USE_VPP60) extern int machine_at_valuepointp60_init(const machine_t *); #endif +extern int machine_at_opti560l_init(const machine_t *); +#if defined(DEV_BRANCH) && defined(USE_DELLXP60) +extern int machine_at_dellxp60_init(const machine_t *); +#endif extern int machine_at_p5mp3_init(const machine_t *); extern int machine_at_586mc1_init(const machine_t *); diff --git a/src/machine/m_at_socket4_5.c b/src/machine/m_at_socket4_5.c index 0f21ca67a..5fa8c341c 100644 --- a/src/machine/m_at_socket4_5.c +++ b/src/machine/m_at_socket4_5.c @@ -39,6 +39,7 @@ #include <86box/sio.h> #include <86box/video.h> #include <86box/machine.h> + int machine_at_excalibur_init(const machine_t *model) { @@ -159,6 +160,67 @@ machine_at_valuepointp60_init(const machine_t *model) } #endif +int +machine_at_opti560l_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/opti560l/560L_A06.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&ide_pci_2ch_device); + + pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&i430lx_device); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&sio_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + +#if defined(DEV_BRANCH) && defined(USE_DELLXP60) +int +machine_at_dellxp60_init(const machine_t *model) // Doesn't like the regular SMC 665 +{ + int ret; + + ret = bios_load_linear(L"roms/machines/dellxp60/XP60-A08.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&ide_pci_2ch_device); + + pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&i430lx_device); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&sio_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} +#endif int machine_at_p5mp3_init(const machine_t *model) @@ -190,7 +252,6 @@ machine_at_p5mp3_init(const machine_t *model) return ret; } - int machine_at_586mc1_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index e81c33071..8a0488c0d 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -236,7 +236,11 @@ const machine_t machines[] = { { "[i430LX] IBM PS/ValuePoint P60", "valuepointp60", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_valuepointp60_init, NULL }, #endif { "[i430LX] Intel Premiere/PCI", "revenge", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_batman_init, NULL }, - { "[i430LX] ASUS P/I-P5MP3", "p5mp3", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 192, 2, 127, machine_at_p5mp3_init, NULL }, + { "[i430LX] Dell OptiPlex 560L", "opti560l", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_opti560l_init, NULL }, +#if defined(DEV_BRANCH) && defined(USE_VPP60) + { "[i430LX] Dell Dimension XPS P60", "dellxp60", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_dellxp60_init, NULL }, +#endif + { "[i430LX] ASUS P/I-P5MP3", "p5mp3", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 192, 2, 127, machine_at_p5mp3_init, NULL }, { "[i430LX] Micro Star 586MC1", "586mc1", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_586mc1_init, NULL }, /* Socket 5 machines */ diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 7e5479f8b..3ff345b38 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -87,6 +87,9 @@ ifeq ($(DEV_BUILD), y) ifndef GUSMAX GUSMAX := y endif + ifndef DELLXP60 + DELLXP60 := y + endif else ifndef DEBUG DEBUG := n @@ -148,6 +151,9 @@ else ifndef GUSMAX GUSMAX := n endif + ifndef DELLXP60 + DELLXP60 := n + endif endif # Defaults for several build options (possibly defined in a chained file.) @@ -530,6 +536,10 @@ ifeq ($(GUSMAX), y) OPTS += -DUSE_GUSMAX endif +ifeq ($(DELLXP60), y) +OPTS += -DUSE_DELLXP60 +endif + endif From 81d178e9f676fffb3876798def9963bccb7a220d Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 30 Jun 2020 15:37:07 +0200 Subject: [PATCH 42/54] Rewrote the VLSI 82C480 chipset emuluation and gave the PS/1 Model 2133 its Super I/O chip. --- src/chipset/vl82c480.c | 217 +++++++++++++++++++++-------------------- src/machine/m_ps1.c | 3 + 2 files changed, 112 insertions(+), 108 deletions(-) diff --git a/src/chipset/vl82c480.c b/src/chipset/vl82c480.c index 51cffb4a3..a55cf846c 100644 --- a/src/chipset/vl82c480.c +++ b/src/chipset/vl82c480.c @@ -8,9 +8,9 @@ * * Implementation of the VLSI VL82c480 chipset. * - * Authors: Sarah Walker, + * Authors: Miran Grca, * - * Copyright 2020 Sarah Walker. + * Copyright 2020 Miran Grca. */ #include #include @@ -28,155 +28,156 @@ #include <86box/chipset.h> typedef struct { - int cfg_index; - uint8_t cfg_regs[256]; + uint8_t idx, + regs[256]; } vl82c480_t; -#define CFG_ID 0x00 -#define CFG_AAXS 0x0d -#define CFG_BAXS 0x0e -#define CFG_CAXS 0x0f -#define CFG_DAXS 0x10 -#define CFG_EAXS 0x11 -#define CFG_FAXS 0x12 -#define ID_VL82C480 0x90 +static int +vl82c480_shflags(uint8_t access) +{ + int ret = MEM_READ_EXTANY | MEM_WRITE_EXTANY; + + switch (access) { + case 0x00: + default: + ret = MEM_READ_EXTANY | MEM_WRITE_EXTANY; + break; + case 0x01: + ret = MEM_READ_EXTANY | MEM_WRITE_INTERNAL; + break; + case 0x02: + ret = MEM_READ_INTERNAL | MEM_WRITE_EXTANY; + break; + case 0x03: + ret = MEM_READ_INTERNAL | MEM_WRITE_INTERNAL; + break; + } + + return ret; +} + static void -shadow_control(uint32_t addr, uint32_t size, int state) +vl82c480_recalc(vl82c480_t *dev) { -/* pclog("shadow_control: addr=%08x size=%04x state=%i\n", addr, size, state); */ - switch (state) { - case 0: - mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - break; - case 1: - mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); - break; - case 2: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); - break; - case 3: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; + int i, j; + uint32_t base; + uint8_t access; + + shadowbios = 0; + shadowbios_write = 0; + + for (i = 0; i < 8; i += 2) { + for (j = 0; j < 6; j++) { + base = 0x000a0000 + (i << 13) + (j << 16); + access = dev->regs[0x0d + j] & (3 << i); + mem_set_mem_state(base, 0x4000, vl82c480_shflags(access)); + shadowbios |= ((base >= 0xe0000) && (access & 0x02)); + shadowbios_write |= ((base >= 0xe0000) && (access & 0x01)); } - flushmmucache_nopc(); + } + + flushmmucache(); } + static void vl82c480_write(uint16_t addr, uint8_t val, void *p) { - vl82c480_t *dev = (vl82c480_t *)p; - - switch (addr) { - case 0xec: - dev->cfg_index = val; - break; + vl82c480_t *dev = (vl82c480_t *)p; - case 0xed: - if (dev->cfg_index >= 0x01 && dev->cfg_index <= 0x24) { - dev->cfg_regs[dev->cfg_index] = val; - switch (dev->cfg_index) { - case CFG_AAXS: - shadow_control(0xa0000, 0x4000, val & 3); - shadow_control(0xa4000, 0x4000, (val >> 2) & 3); - shadow_control(0xa8000, 0x4000, (val >> 4) & 3); - shadow_control(0xac000, 0x4000, (val >> 6) & 3); + switch (addr) { + case 0xec: + dev->idx = val; + break; + + case 0xed: + if (dev->idx >= 0x01 && dev->idx <= 0x24) { + switch (dev->idx) { + default: + dev->regs[dev->idx] = val; break; - case CFG_BAXS: - shadow_control(0xb0000, 0x4000, val & 3); - shadow_control(0xb4000, 0x4000, (val >> 2) & 3); - shadow_control(0xb8000, 0x4000, (val >> 4) & 3); - shadow_control(0xbc000, 0x4000, (val >> 6) & 3); + case 0x05: + dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x10) | (val & 0xef); break; - case CFG_CAXS: - shadow_control(0xc0000, 0x4000, val & 3); - shadow_control(0xc4000, 0x4000, (val >> 2) & 3); - shadow_control(0xc8000, 0x4000, (val >> 4) & 3); - shadow_control(0xcc000, 0x4000, (val >> 6) & 3); - break; - case CFG_DAXS: - shadow_control(0xd0000, 0x4000, val & 3); - shadow_control(0xd4000, 0x4000, (val >> 2) & 3); - shadow_control(0xd8000, 0x4000, (val >> 4) & 3); - shadow_control(0xdc000, 0x4000, (val >> 6) & 3); - break; - case CFG_EAXS: - shadow_control(0xe0000, 0x4000, val & 3); - shadow_control(0xe4000, 0x4000, (val >> 2) & 3); - shadow_control(0xe8000, 0x4000, (val >> 4) & 3); - shadow_control(0xec000, 0x4000, (val >> 6) & 3); - break; - case CFG_FAXS: - shadow_control(0xf0000, 0x4000, val & 3); - shadow_control(0xf4000, 0x4000, (val >> 2) & 3); - shadow_control(0xf8000, 0x4000, (val >> 4) & 3); - shadow_control(0xfc000, 0x4000, (val >> 6) & 3); + case 0x0d: case 0x0e: case 0x0f: case 0x10: + case 0x11: case 0x12: + dev->regs[dev->idx] = val; + vl82c480_recalc(dev); break; } } break; - case 0xee: - if (mem_a20_alt) - outb(0x92, inb(0x92) & ~2); - break; - } + case 0xee: + if (mem_a20_alt) + outb(0x92, inb(0x92) & ~2); + break; + } } + static uint8_t vl82c480_read(uint16_t addr, void *p) { - vl82c480_t *dev = (vl82c480_t *)p; - uint8_t ret = 0xff; + vl82c480_t *dev = (vl82c480_t *)p; + uint8_t ret = 0xff; - switch (addr) { - case 0xec: - ret = dev->cfg_index; - break; - - case 0xed: - ret = dev->cfg_regs[dev->cfg_index]; - break; - - case 0xee: - if (!mem_a20_alt) - outb(0x92, inb(0x92) | 2); - break; - - case 0xef: - softresetx86(); - cpu_set_edx(); - break; - } + switch (addr) { + case 0xec: + ret = dev->idx; + break; - return ret; + case 0xed: + ret = dev->regs[dev->idx]; + break; + + case 0xee: + if (!mem_a20_alt) + outb(0x92, inb(0x92) | 2); + break; + + case 0xef: + softresetx86(); + cpu_set_edx(); + break; + } + + return ret; } + static void vl82c480_close(void *p) { - vl82c480_t *dev = (vl82c480_t *)p; + vl82c480_t *dev = (vl82c480_t *)p; - free(dev); + free(dev); } static void * vl82c480_init(const device_t *info) { - vl82c480_t *dev = (vl82c480_t *)malloc(sizeof(vl82c480_t)); - memset(dev, 0, sizeof(vl82c480_t)); - - dev->cfg_regs[CFG_ID] = ID_VL82C480; - - io_sethandler(0x00ec, 0x0004, vl82c480_read, NULL, NULL, vl82c480_write, NULL, NULL, dev); + vl82c480_t *dev = (vl82c480_t *)malloc(sizeof(vl82c480_t)); + memset(dev, 0, sizeof(vl82c480_t)); - device_add(&port_92_device); + dev->regs[0x00] = 0x90; + dev->regs[0x01] = 0xff; + dev->regs[0x02] = 0x8a; + dev->regs[0x03] = 0x88; + dev->regs[0x06] = 0x1b; + dev->regs[0x08] = 0x38; - return dev; + io_sethandler(0x00ec, 0x0004, vl82c480_read, NULL, NULL, vl82c480_write, NULL, NULL, dev); + + device_add(&port_92_device); + + return dev; } + const device_t vl82c480_device = { "VLSI VL82c480", 0, diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index b971d502d..35866ba13 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -558,6 +558,7 @@ machine_ps1_m2121_init(const machine_t *model) return ret; } + int machine_ps1_m2133_init(const machine_t *model) { @@ -573,6 +574,7 @@ machine_ps1_m2133_init(const machine_t *model) device_add(&fdc_at_device); device_add(&ide_isa_device); device_add(&vl82c480_device); + device_add(&ps1_m2133_sio); nmi_mask = 0x80; @@ -582,6 +584,7 @@ machine_ps1_m2133_init(const machine_t *model) return ret; } + const device_t * ps1_m2133_get_device(void) { From 33a0cf53c4c567be1f22252994bf3cf118b18813 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 30 Jun 2020 15:49:47 +0200 Subject: [PATCH 43/54] Removed the "PS/1 Model 2133" Super I/O chip as it has been identified as a National Semiconductors PC87332 on a different set of ports, the PS/1 Model 2133 now uses that. --- src/include/86box/sio.h | 1 + src/machine/m_ps1.c | 2 +- src/sio/sio_pc87332.c | 22 ++++-- src/sio/sio_ps1_m2133.c | 148 ---------------------------------------- src/win/Makefile.mingw | 1 - 5 files changed, 19 insertions(+), 155 deletions(-) delete mode 100644 src/sio/sio_ps1_m2133.c diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index c2bc5aeae..cb38a9e53 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -29,6 +29,7 @@ extern const device_t pc87306_device; extern const device_t pc87307_device; extern const device_t pc87309_device; extern const device_t pc87332_device; +extern const device_t pc87332_ps1_device; extern const device_t pc97307_device; extern const device_t ps1_m2133_sio; extern const device_t sio_detect_device; diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index 35866ba13..26e24e0ac 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -574,7 +574,7 @@ machine_ps1_m2133_init(const machine_t *model) device_add(&fdc_at_device); device_add(&ide_isa_device); device_add(&vl82c480_device); - device_add(&ps1_m2133_sio); + device_add(&pc87332_ps1_device); nmi_mask = 0x80; diff --git a/src/sio/sio_pc87332.c b/src/sio/sio_pc87332.c index 3a9b04785..03cbcf823 100644 --- a/src/sio/sio_pc87332.c +++ b/src/sio/sio_pc87332.c @@ -41,7 +41,6 @@ typedef struct { int cur_reg; fdc_t *fdc; serial_t *uart[2]; - nvr_t *nvr; } pc87332_t; @@ -292,12 +291,15 @@ pc87332_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); - // dev->nvr = device_add(&piix4_nvr_device); - pc87332_reset(dev); - io_sethandler(0x02e, 0x0002, - pc87332_read, NULL, NULL, pc87332_write, NULL, NULL, dev); + if (info->local == 1) { + io_sethandler(0x398, 0x0002, + pc87332_read, NULL, NULL, pc87332_write, NULL, NULL, dev); + } else { + io_sethandler(0x02e, 0x0002, + pc87332_read, NULL, NULL, pc87332_write, NULL, NULL, dev); + } return dev; } @@ -311,3 +313,13 @@ const device_t pc87332_device = { NULL, NULL, NULL, NULL }; + + +const device_t pc87332_ps1_device = { + "National Semiconductor PC87332 Super I/O (IBM PS/1 Model 2133 EMEA 451)", + 0, + 1, + pc87332_init, pc87332_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/sio/sio_ps1_m2133.c b/src/sio/sio_ps1_m2133.c deleted file mode 100644 index 264dd78c7..000000000 --- a/src/sio/sio_ps1_m2133.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of the chipset used by the IBM PS/1 Model 2133 EMEA 451 - * whose name is currently unknown. - * - * Authors: Sarah Walker, - * - * Copyright 2020 Sarah Walker. - */ -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/io.h> -#include <86box/timer.h> -#include <86box/device.h> -#include <86box/lpt.h> -#include <86box/serial.h> -#include <86box/sio.h> - - -typedef struct ps1_m2133_sio_t -{ - int idx; - uint8_t regs[3]; - serial_t *uart[2]; -} ps1_m2133_sio_t; - -static uint16_t ps1_lpt_io[4] = {0x378, 0x3bc, 0x278, 0x378}; -static uint16_t ps1_com_io[4] = {0x3f8, 0x2f8, 0x3e8, 0x2e8}; - -static uint8_t -ps1_m2133_read(uint16_t port, void *p) -{ - ps1_m2133_sio_t *dev = (ps1_m2133_sio_t *)p; - uint8_t ret = 0xff; - - switch (port) { - case 0x398: - ret = dev->idx; - break; - - case 0x399: - if (dev->idx < 3) - ret = dev->regs[dev->idx]; - break; - } - return ret; -} - -static void -ps1_m2133_write(uint16_t port, uint8_t val, void *p) -{ - ps1_m2133_sio_t *dev = (ps1_m2133_sio_t *)p; - uint16_t lpt_addr; - - switch (port) { - case 0x398: - dev->idx = val; - break; - - case 0x399: - if (dev->idx < 3) { - dev->regs[dev->idx] = val; - - lpt1_remove(); - lpt2_remove(); - serial_remove(dev->uart[0]); - serial_remove(dev->uart[1]); - - if (dev->regs[0] & 1) { - lpt_addr = ps1_lpt_io[dev->regs[1] & 3]; - - lpt1_init(lpt_addr); - if ((lpt_addr == 0x378) || (lpt_addr == 0x3bc)) { - if (((dev->regs[1] & 3) == 3) && (lpt_addr == 0x378)) { - lpt1_irq(5); - } else { - lpt1_irq(7); - } - } else if (lpt_addr == 0x278) { - lpt1_irq(5); - } - } - - if (dev->regs[0] & 2) - serial_setup(dev->uart[0], ps1_com_io[(dev->regs[1] >> 2) & 3], 4); - if (dev->regs[0] & 4) - serial_setup(dev->uart[1], ps1_com_io[(dev->regs[1] >> 4) & 3], 3); - } - break; - } -} - -static void -ps1_m2133_reset(ps1_m2133_sio_t *dev) -{ - serial_remove(dev->uart[0]); - serial_setup(dev->uart[0], SERIAL1_ADDR, SERIAL1_IRQ); - - serial_remove(dev->uart[1]); - serial_setup(dev->uart[1], SERIAL2_ADDR, SERIAL2_IRQ); - - lpt1_remove(); - lpt1_init(0x378); - lpt1_irq(7); -} - -static void * -ps1_m2133_init(const device_t *info) -{ - ps1_m2133_sio_t *dev = (ps1_m2133_sio_t *) malloc(sizeof(ps1_m2133_sio_t)); - memset(dev, 0, sizeof(ps1_m2133_sio_t)); - - dev->uart[0] = device_add_inst(&ns16450_device, 1); - dev->uart[1] = device_add_inst(&ns16450_device, 2); - - io_sethandler(0x0398, 0x0002, ps1_m2133_read, NULL, NULL, ps1_m2133_write, NULL, NULL, dev); - - ps1_m2133_reset(dev); - - return dev; -} - -static void -ps1_m2133_close(void *p) -{ - ps1_m2133_sio_t *dev = (ps1_m2133_sio_t *)p; - - free(dev); -} - -const device_t ps1_m2133_sio = { - "IBM PS/1 Model 2133 EMEA 451 Super I/O", - 0, - 0, - ps1_m2133_init, ps1_m2133_close, NULL, - NULL, NULL, NULL, - NULL -}; diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 7e5479f8b..351ba7ba0 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -595,7 +595,6 @@ SIOOBJ := sio_acc3221.o \ sio_fdc37c661.o sio_fdc37c66x.o sio_fdc37c669.o \ sio_fdc37c93x.o \ sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87332.o \ - sio_ps1_m2133.o \ sio_w83787f.o \ sio_w83877f.o sio_w83977f.o \ sio_um8669f.o From 602cadf8630af35a8f4ff76aa011671c6c4fe092 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 30 Jun 2020 15:52:47 +0200 Subject: [PATCH 44/54] Removed the fdc_at_device adding from the PS/1 Model 2133, as the FDC is now correctly added by the Super I/O chip. --- src/machine/m_ps1.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index 26e24e0ac..651ef1d25 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -571,7 +571,6 @@ machine_ps1_m2133_init(const machine_t *model) return ret; ps1_common_init(model); - device_add(&fdc_at_device); device_add(&ide_isa_device); device_add(&vl82c480_device); device_add(&pc87332_ps1_device); From 808fa292f6a6127d195b9d81c5b1e15bc8166f28 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Jul 2020 00:21:46 +0200 Subject: [PATCH 45/54] Fixed memory state for PS/2 split mapping on models 70 and 80 (broken by recent mem.c changes). --- src/machine/m_ps2_mca.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index 5a1bf3fd5..3295fc884 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -964,6 +964,11 @@ static void ps2_mca_board_model_55sx_init() static void mem_encoding_update() { mem_mapping_disable(&ps2.split_mapping); + + if (ps2.split_size > 0) + mem_set_mem_state(ps2.split_addr, ps2.split_size << 10, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + if (((mem_size << 10) - (1 << 20)) > 0) + mem_set_mem_state(1 << 20, (mem_size << 10) - (1 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); ps2.split_addr = ((uint32_t) (ps2.mem_regs[0] & 0xf)) << 20; @@ -993,12 +998,15 @@ static void mem_encoding_update() ps2.split_phys = 0xa0000; } + mem_set_mem_state(ps2.split_addr, ps2.split_size << 10, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); mem_mapping_set_exec(&ps2.split_mapping, &ram[ps2.split_phys]); mem_mapping_set_addr(&ps2.split_mapping, ps2.split_addr, ps2.split_size << 10); ps2_mca_log("PS/2 Model 80-111: Split memory block enabled at %08X\n", ps2.split_addr); - } else + } else { + ps2.split_size = 0; ps2_mca_log("PS/2 Model 80-111: Split memory block disabled\n"); + } } static uint8_t mem_encoding_read(uint16_t addr, void *p) @@ -1242,6 +1250,8 @@ static void ps2_mca_board_model_80_type2_init(int is486) if (gfxcard == VID_INTERNAL) device_add(&ps1vga_mca_device); + + ps2.split_size = 0; } From a9e0dd247a3e92c9ec79c4fd813ba3b8da4431b9 Mon Sep 17 00:00:00 2001 From: nerd73 Date: Thu, 2 Jul 2020 10:09:55 -0600 Subject: [PATCH 46/54] Implement IBM 486 MSRs Implement the MSRs supported by the IBM 386SLC/486SLC/486BL. --- src/cpu/386_ops.h | 90 +++++++++++++++++++++++++++++++++++++++++++++++ src/cpu/cpu.c | 86 ++++++++++++++++++++++++++++++++++++++++---- src/cpu/x86_ops.h | 2 ++ 3 files changed, 171 insertions(+), 7 deletions(-) diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index 674186337..439c70acb 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -527,6 +527,96 @@ const OpFn OP_TABLE(486_0f)[1024] = /*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, /*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, +/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; +const OpFn OP_TABLE(ibm486_0f)[1024] = +{ + /*16-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, ILLEGAL, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, + +/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*32-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, ILLEGAL, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, + +/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*16-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, ILLEGAL, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, + +/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*32-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, ILLEGAL, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, + /*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 90e8e0dc9..89c43063b 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -190,6 +190,10 @@ uint64_t mtrr_fix16k_a000_msr = 0; uint64_t mtrr_fix4k_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint64_t mtrr_deftype_msr = 0; +uint64_t ibm_por_msr = 0; /*Processor Operation Register*/ +uint64_t ibm_crcr_msr = 0; /*Cache Region Control Register*/ +uint64_t ibm_por2_msr = 0; /*Processor Operation Register*/ + uint16_t cs_msr = 0; uint32_t esp_msr = 0; uint32_t eip_msr = 0; @@ -618,12 +622,12 @@ cpu_set(void) break; case CPU_IBM486SLC: + case CPU_IBM386SLC: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); + x86_setopcodes(ops_386, ops_ibm486_0f, dynarec_ops_386, dynarec_ops_ibm486_0f); #else - x86_setopcodes(ops_386, ops_486_0f); -#endif - case CPU_IBM386SLC: + x86_setopcodes(ops_386, ops_ibm486_0f); +#endif case CPU_386SX: timing_rr = 2; /*register dest - register src*/ timing_rm = 6; /*register dest - memory src*/ @@ -657,9 +661,9 @@ cpu_set(void) case CPU_IBM486BL: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); + x86_setopcodes(ops_386, ops_ibm486_0f, dynarec_ops_386, dynarec_ops_ibm486_0f); #else - x86_setopcodes(ops_386, ops_486_0f); + x86_setopcodes(ops_386, ops_ibm486_0f); #endif case CPU_386DX: if (fpu_type == FPU_287) /*In case we get Deskpro 386 emulation*/ @@ -724,7 +728,7 @@ cpu_set(void) timing_jmp_pm = 27; timing_jmp_pm_gate = 45; break; - + case CPU_RAPIDCAD: #ifdef USE_DYNAREC @@ -2496,6 +2500,36 @@ void cpu_RDMSR() { switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { + case CPU_IBM386SLC: + EAX = EDX = 0; + switch (ECX) + { + case 0x1000: + EAX = ibm_por_msr & 0xfeff; + + case 0x1001: + EAX = ibm_crcr_msr & 0xffffffffff; + } + break; + + case CPU_IBM486SLC: + case CPU_IBM486BL: + EAX = EDX = 0; + switch (ECX) + { + case 0x1000: + EAX = ibm_por_msr & 0xffeff; + + case 0x1001: + EAX = ibm_crcr_msr & 0xffffffffff; + + if (cpu_s->multi) { + case 0x1002: + EAX = ibm_por2_msr & 0x3f000000; + } + } + break; + case CPU_WINCHIP: case CPU_WINCHIP2: EAX = EDX = 0; @@ -3046,6 +3080,44 @@ void cpu_WRMSR() cpu_log("WRMSR %08X %08X%08X\n", ECX, EDX, EAX); switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { + case CPU_IBM386SLC: + switch (ECX) + { + case 0x1000: + ibm_por_msr = EAX & 0xfeff; + if (EAX & (1 << 7)) + cpu_cache_int_enabled = 1; + else + cpu_cache_int_enabled = 0; + break; + case 0x1001: + ibm_crcr_msr = EAX & 0xffffffffff; + break; + } + break; + + case CPU_IBM486BL: + case CPU_IBM486SLC: + switch (ECX) + { + case 0x1000: + ibm_por_msr = EAX & 0xffeff; + if (EAX & (1 << 7)) + cpu_cache_int_enabled = 1; + else + cpu_cache_int_enabled = 0; + break; + case 0x1001: + ibm_crcr_msr = EAX & 0xffffffffff; + break; + if (cpu_s->multi) { + case 0x1002: + ibm_por2_msr = EAX & 0x3f000000; + } + break; + } + break; + case CPU_WINCHIP: case CPU_WINCHIP2: switch (ECX) diff --git a/src/cpu/x86_ops.h b/src/cpu/x86_ops.h index f66e2392d..6ee001b0b 100644 --- a/src/cpu/x86_ops.h +++ b/src/cpu/x86_ops.h @@ -79,6 +79,7 @@ extern const OpFn dynarec_ops_386[1024]; extern const OpFn dynarec_ops_386_0f[1024]; extern const OpFn dynarec_ops_486_0f[1024]; +extern const OpFn dynarec_ops_ibm486_0f[1024]; extern const OpFn dynarec_ops_winchip_0f[1024]; extern const OpFn dynarec_ops_winchip2_0f[1024]; @@ -174,6 +175,7 @@ extern const OpFn ops_386[1024]; extern const OpFn ops_386_0f[1024]; extern const OpFn ops_486_0f[1024]; +extern const OpFn ops_ibm486_0f[1024]; extern const OpFn ops_winchip_0f[1024]; extern const OpFn ops_winchip2_0f[1024]; From 525a6f027802b3b05b256a41f3cf0d6576abc4d2 Mon Sep 17 00:00:00 2001 From: tiseno100 <58827426+tiseno100@users.noreply.github.com> Date: Thu, 2 Jul 2020 22:10:36 +0300 Subject: [PATCH 47/54] Added the RYC Leopard LX An interesting kind of 386DXish/486 kind of board. Uses the IBM 486SLC(only!) which is commonly found in PS/2 & PS/1 286 & 386 computers as an "upgrade" chip --- src/chipset/opti283.c | 175 +++++++++++++++++++++++++++++++++++ src/include/86box/chipset.h | 1 + src/include/86box/machine.h | 2 + src/machine/m_at_386dx_486.c | 19 ++++ src/machine/machine_table.c | 1 + src/win/Makefile.mingw | 2 +- 6 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 src/chipset/opti283.c diff --git a/src/chipset/opti283.c b/src/chipset/opti283.c new file mode 100644 index 000000000..a4dad3d29 --- /dev/null +++ b/src/chipset/opti283.c @@ -0,0 +1,175 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the OPTi 82C283 chipset. + * + * + * + * Authors: Tiseno100 + * + * Copyright 2020 Tiseno100 + * + */ + +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/keyboard.h> +#include <86box/mem.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/port_92.h> +#include <86box/chipset.h> + +typedef struct +{ + uint8_t index, + regs[256]; +} opti283_t; + +static void opti283_shadow_recalc(opti283_t *dev) +{ +uint32_t base; +uint32_t shflags, i = 0; + +shadowbios = 0; +shadowbios_write = 0; + + /* F0000 - FFFFF segmentation */ +if(!(dev->regs[0x11] & 0x80)){ + shadowbios = 1; + shadowbios_write = 0; + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); +} else { + shadowbios = 0; + shadowbios_write = 1; + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); +} + + /* C0000 - CFFFF segmentation */ +for(i = 4; i < 8; i++){ + base = 0xc0000 + ((i-4) << 14); + + if((dev->regs[0x13] & (1 << i)) & (dev->regs[0x11] & 0x10)){ + shflags = MEM_READ_INTERNAL; + shflags |= (!(dev->regs[0x11] & 0x01)) ? MEM_WRITE_INTERNAL : MEM_WRITE_DISABLED; + mem_set_mem_state_both(base, 0x4000, shflags); + } else { + mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); +} +} + + /* D0000 - DFFFF segmentation */ +for(i = 0; i < 4; i++){ + base = 0xd0000 + (i << 14); + if((dev->regs[0x12] & (1 << i)) & (dev->regs[0x11] & 0x20)){ + shflags = MEM_READ_INTERNAL; + shflags |= (!(dev->regs[0x11] & 0x02)) ? MEM_WRITE_INTERNAL : MEM_WRITE_DISABLED; + mem_set_mem_state(base, 0x4000, shflags); + } else mem_set_mem_state(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); +} + + /* E0000 - EFFFF segmentation */ +for(i = 4; i < 8; i++){ + base = 0xe0000 + ((i-4) << 14); + if((dev->regs[0x12] & (1 << i)) & (dev->regs[0x11] & 0x40)){ + shflags = MEM_READ_INTERNAL; + shflags |= (!(dev->regs[0x11] & 0x04)) ? MEM_WRITE_INTERNAL : MEM_WRITE_DISABLED; + mem_set_mem_state(base, 0x4000, shflags); + } else mem_set_mem_state(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); +} + +} + +static void +opti283_write(uint16_t addr, uint8_t val, void *priv) +{ + opti283_t *dev = (opti283_t *) priv; + + switch (addr) { + case 0x22: + dev->index = val; + break; + case 0x24: + /*pclog("OPTi 283: dev->regs[%02x] = %02x\n", dev->index, val);*/ + dev->regs[dev->index] = val; + + switch(dev->index){ + case 0x10: + cpu_update_waitstates(); + + case 0x11: + case 0x12: + case 0x13: + opti283_shadow_recalc(dev); + break; + } + break; + } +} + + +static uint8_t +opti283_read(uint16_t addr, void *priv) +{ + uint8_t ret = 0xff; + opti283_t *dev = (opti283_t *) priv; + + switch (addr) { + case 0x24: + ret = dev->regs[dev->index]; + break; + } + + return ret; +} + + +static void +opti283_close(void *priv) +{ + opti283_t *dev = (opti283_t *) priv; + + free(dev); +} + + +static void * +opti283_init(const device_t *info) +{ + opti283_t *dev = (opti283_t *) malloc(sizeof(opti283_t)); + memset(dev, 0, sizeof(opti283_t)); + + io_sethandler(0x022, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev); + io_sethandler(0x024, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev); + + dev->regs[0x10] = 0x3f; + dev->regs[0x11] = 0xf0; + opti283_shadow_recalc(dev); + + return dev; +} + + +const device_t opti283_device = { + "OPTi 82C283", + 0, + 0, + opti283_init, opti283_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index de25fca32..c2e4b8fe0 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -60,6 +60,7 @@ extern const device_t slc90e66_device; extern const device_t ioapic_device; /* OPTi */ +extern const device_t opti283_device; extern const device_t opti493_device; extern const device_t opti495_device; extern const device_t opti802g_device; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index fc423786a..055679bac 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -252,6 +252,8 @@ extern int machine_at_asus386_init(const machine_t *); extern int machine_at_ecs386_init(const machine_t *); extern int machine_at_micronics386_init(const machine_t *); +extern int machine_at_rycleopardlx_init(const machine_t *); + extern int machine_at_pb410a_init(const machine_t *); extern int machine_at_acera1g_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 0f47126ee..9876fd498 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -102,6 +102,25 @@ machine_at_ecs386_init(const machine_t *model) return ret; } +int +machine_at_rycleopardlx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/rycleopardlx/486-RYC-Leopard-LX.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&opti283_device); + device_add(&keyboard_at_ami_device); + device_add(&fdc_at_device); + + return ret; +} int machine_at_pb410a_init(const machine_t *model) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 8a0488c0d..80828826d 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -197,6 +197,7 @@ const machine_t machines[] = { { "[ACC 2168] Packard Bell PB410A", "pb410a", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 4, 36, 1, 127, machine_at_pb410a_init, NULL }, /* 486 machines */ + { "[OPTi 283] RYC Leopard LX", "rycleopardlx", MACHINE_TYPE_486, {{"IBM", cpus_IBM486SLC}, {"", NULL}, {"", NULL},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 16, 1, 127, machine_at_rycleopardlx_init, NULL }, { "[OPTi 495] Award 486 clone", "award486", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, { "[OPTi 495] MR 486 clone", "mr486", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, { "[OPTi 495] Dataexpert SX495 (486)", "ami486", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 316ce0c1c..8c6df56a6 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -572,7 +572,7 @@ CPUOBJ := cpu.o cpu_table.o \ CHIPSETOBJ := acc2168.o cs8230.o ali1429.o headland.o i82335.o \ intel_420ex.o intel_4x0.o intel_sio.o intel_piix.o ioapic.o \ neat.o opti495.o opti895.o opti5x7.o scamp.o scat.o \ - sis_85c310.o sis_85c471.o sis_85c496.o \ + sis_85c310.o sis_85c471.o sis_85c496.o opti283.o \ via_apollo.o via_vpx.o via_vt82c586b.o via_vt82c596b.o wd76c10.o vl82c480.o \ amd640.o From b043f1867b653586fcf0bf374883ea741b7a423a Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 2 Jul 2020 21:42:31 -0300 Subject: [PATCH 48/54] Genesys Logic GL518SM hardware monitor --- src/cpu/cpu.c | 6 +- src/device/hwm_gl518sm.c | 278 +++++++++++++++++++++++++++++++++++ src/device/hwm_lm75.c | 20 ++- src/device/hwm_lm78.c | 31 ++-- src/device/serial.c | 8 + src/include/86box/hwm.h | 5 +- src/machine/m_at_slot1.c | 21 ++- src/machine/m_at_socket370.c | 2 +- src/win/Makefile.mingw | 2 +- 9 files changed, 339 insertions(+), 34 deletions(-) create mode 100644 src/device/hwm_gl518sm.c diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index c958158fc..6e11e85cb 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -61,7 +61,7 @@ #endif #include "x87_timings.h" -/*#define ENABLE_CPU_LOG 1*/ +#define ENABLE_CPU_LOG 1 static void cpu_write(uint16_t addr, uint8_t val, void *priv); static uint8_t cpu_read(uint16_t addr, void *priv); @@ -3334,7 +3334,7 @@ void cpu_WRMSR() break; case 0x8B: cpu_log("WRMSR: Invalid MSR: 0x8B\n"); - x86gpf(NULL, 0); /*Needed for Vista to correctly break on Pentium*/ + //x86gpf(NULL, 0); /*Needed for Vista to correctly break on Pentium*/ break; } break; @@ -3467,7 +3467,7 @@ void cpu_WRMSR() default: i686_invalid_wrmsr: cpu_log("WRMSR: Invalid MSR: %08X\n", ECX); - x86gpf(NULL, 0); + //x86gpf(NULL, 0); break; } break; diff --git a/src/device/hwm_gl518sm.c b/src/device/hwm_gl518sm.c new file mode 100644 index 000000000..250c34a42 --- /dev/null +++ b/src/device/hwm_gl518sm.c @@ -0,0 +1,278 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the Genesys Logic GL518SM hardware monitoring chip. + * + * + * + * Author: RichardG, + * + * Copyright 2020 RichardG. + */ +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include "cpu.h" +#include <86box/smbus.h> +#include <86box/hwm.h> + + +#define CLAMP(a, min, max) (((a)< (min)) ? (min) : (((a) > (max)) ? (max) : (a))) +#define GL518SM_RPM_TO_REG(r, d) ((r) ? CLAMP(480000 / (r * d), 1, 255) : 0) +#define GL518SM_VOLTAGE_TO_REG(v) (((v) / 19) & 0xff) +#define GL518SM_VDD_TO_REG(v) ((((v) * 4) / 95) & 0xff) + + +typedef struct { + uint32_t local; + hwm_values_t *values; + + uint16_t regs[32]; + uint8_t addr_register; + + uint8_t smbus_addr; +} gl518sm_t; + + +static uint8_t gl518sm_smbus_read_byte(uint8_t addr, void *priv); +static uint8_t gl518sm_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv); +static uint16_t gl518sm_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv); +static uint16_t gl518sm_read(gl518sm_t *dev, uint8_t reg); +static void gl518sm_smbus_write_byte(uint8_t addr, uint8_t val, void *priv); +static void gl518sm_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv); +static void gl518sm_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv); +static uint8_t gl518sm_write(gl518sm_t *dev, uint8_t reg, uint16_t val); +static void gl518sm_reset(gl518sm_t *dev); + +#define ENABLE_GL518SM_LOG 1 +#ifdef ENABLE_GL518SM_LOG +int gl518sm_do_log = ENABLE_GL518SM_LOG; + + +static void +gl518sm_log(const char *fmt, ...) +{ + va_list ap; + + if (gl518sm_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define gl518sm_log(fmt, ...) +#endif + + +static void +gl518sm_remap(gl518sm_t *dev, uint8_t addr) +{ + gl518sm_log("GL518SM: remapping to SMBus %02Xh\n", addr); + + smbus_removehandler(dev->smbus_addr, 1, + gl518sm_smbus_read_byte, gl518sm_smbus_read_byte_cmd, gl518sm_smbus_read_word_cmd, NULL, + gl518sm_smbus_write_byte, gl518sm_smbus_write_byte_cmd, gl518sm_smbus_write_word_cmd, NULL, + dev); + + if (addr < 0x80) smbus_sethandler(addr, 1, + gl518sm_smbus_read_byte, gl518sm_smbus_read_byte_cmd, gl518sm_smbus_read_word_cmd, NULL, + gl518sm_smbus_write_byte, gl518sm_smbus_write_byte_cmd, gl518sm_smbus_write_word_cmd, NULL, + dev); + + dev->smbus_addr = addr; +} + + +static uint8_t +gl518sm_smbus_read_byte(uint8_t addr, void *priv) +{ + gl518sm_t *dev = (gl518sm_t *) priv; + return gl518sm_read(dev, dev->addr_register); +} + + +static uint8_t +gl518sm_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv) +{ + gl518sm_t *dev = (gl518sm_t *) priv; + return gl518sm_read(dev, cmd); +} + + +static uint16_t +gl518sm_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv) +{ + gl518sm_t *dev = (gl518sm_t *) priv; + return gl518sm_read(dev, cmd); +} + + +static uint16_t +gl518sm_read(gl518sm_t *dev, uint8_t reg) +{ + uint16_t ret = dev->regs[reg & 0x1f]; + + switch (reg) { + case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: + /* two-byte registers: leave as-is */ + break; + default: + /* single-byte registers: duplicate low byte to high byte (real hardware behavior unknown) */ + ret |= (ret << 8); + break; + } + + gl518sm_log("GL518SM: read(%02X) = %04X\n", reg, ret); + + return ret; +} + + +static void +gl518sm_smbus_write_byte(uint8_t addr, uint8_t val, void *priv) +{ + gl518sm_t *dev = (gl518sm_t *) priv; + dev->addr_register = val; +} + + +static void +gl518sm_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv) +{ + gl518sm_t *dev = (gl518sm_t *) priv; + gl518sm_write(dev, cmd, val); +} + + +static void +gl518sm_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv) +{ + gl518sm_t *dev = (gl518sm_t *) priv; + gl518sm_write(dev, cmd, val); +} + + +static uint8_t +gl518sm_write(gl518sm_t *dev, uint8_t reg, uint16_t val) +{ + gl518sm_log("GL518SM: write(%02X, %04X)\n", reg, val); + + switch (reg) { + case 0x00: case 0x01: case 0x04: case 0x07: case 0x0d: case 0x12: case 0x13: case 0x14: case 0x15: + /* read-only registers */ + return 0; + + case 0x0a: + dev->regs[0x13] = (val & 0xff); + break; + + case 0x03: + dev->regs[reg] = (val & 0xfc); + + if (val & 0x80) /* Init */ + gl518sm_reset(dev); + break; + + case 0x0f: + dev->regs[reg] = (val & 0xf8); + + /* update fan values to match the new divisor */ + dev->regs[0x07] = (GL518SM_RPM_TO_REG(dev->values->fans[0], 1 << ((dev->regs[0x0f] >> 6) & 0x3)) << 8); + dev->regs[0x07] |= GL518SM_RPM_TO_REG(dev->values->fans[1], 1 << ((dev->regs[0x0f] >> 4) & 0x3)); + break; + + case 0x11: + dev->regs[reg] = (val & 0x7f); + break; + + default: + dev->regs[reg] = val; + break; + } + + return 1; +} + + +static void +gl518sm_reset(gl518sm_t *dev) +{ + memset(dev->regs, 0, sizeof(dev->regs)); + + dev->regs[0x00] = 0x80; + dev->regs[0x01] = 0x80; /* revision 0x80 can read all voltages */ + dev->regs[0x04] = ((dev->values->temperatures[0] + 119) & 0xff); + dev->regs[0x05] = 0xc7; + dev->regs[0x06] = 0xc2; + dev->regs[0x07] = ((GL518SM_RPM_TO_REG(dev->values->fans[0], 8) << 8) | GL518SM_RPM_TO_REG(dev->values->fans[1], 8)); + dev->regs[0x08] = 0x6464; + dev->regs[0x09] = 0xdac5; + dev->regs[0x0a] = 0xdac5; + dev->regs[0x0b] = 0xdac5; + dev->regs[0x0c] = 0xdac5; + /* AOpen System Monitor requires an approximate voltage offset of 13 at least on 3.3V (voltages[2]) */ + dev->regs[0x0d] = 13 + GL518SM_VOLTAGE_TO_REG(dev->values->voltages[2]); + dev->regs[0x0f] = 0xf8; + dev->regs[0x13] = 13 + GL518SM_VOLTAGE_TO_REG(dev->values->voltages[1]); + dev->regs[0x14] = 13 + GL518SM_VOLTAGE_TO_REG(dev->values->voltages[0]); + dev->regs[0x15] = 13 + GL518SM_VDD_TO_REG(5000); +} + + +static void +gl518sm_close(void *priv) +{ + gl518sm_t *dev = (gl518sm_t *) priv; + + gl518sm_remap(dev, 0); + + free(dev); +} + + +static void * +gl518sm_init(const device_t *info) +{ + gl518sm_t *dev = (gl518sm_t *) malloc(sizeof(gl518sm_t)); + memset(dev, 0, sizeof(gl518sm_t)); + + dev->local = info->local; + dev->values = hwm_get_values(); + + gl518sm_reset(dev); + gl518sm_remap(dev, dev->local & 0x7f); + + return dev; +} + + +const device_t gl518sm_2c_device = { + "Genesys Logic GL518SM Hardware Monitor", + DEVICE_ISA, + 0x2c, + gl518sm_init, gl518sm_close, NULL, + NULL, NULL, NULL, + NULL +}; + +const device_t gl518sm_2d_device = { + "Genesys Logic GL518SM Hardware Monitor", + DEVICE_ISA, + 0x2d, + gl518sm_init, gl518sm_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/device/hwm_lm75.c b/src/device/hwm_lm75.c index 097b62e8e..c7a057ff4 100644 --- a/src/device/hwm_lm75.c +++ b/src/device/hwm_lm75.c @@ -60,19 +60,21 @@ lm75_log(const char *fmt, ...) void -lm75_remap(lm75_t *dev) +lm75_remap(lm75_t *dev, uint8_t addr) { - lm75_log("LM75: remapping to SMBus %02Xh\n", dev->smbus_addr); + lm75_log("LM75: remapping to SMBus %02Xh\n", addr); smbus_removehandler(dev->smbus_addr, 1, lm75_smbus_read_byte, lm75_smbus_read_byte_cmd, lm75_smbus_read_word_cmd, NULL, lm75_smbus_write_byte, lm75_smbus_write_byte_cmd, lm75_smbus_write_word_cmd, NULL, dev); - if (dev->smbus_addr) smbus_sethandler(dev->smbus_addr, 1, + if (addr < 0x80) smbus_sethandler(addr, 1, lm75_smbus_read_byte, lm75_smbus_read_byte_cmd, lm75_smbus_read_word_cmd, NULL, lm75_smbus_write_byte, lm75_smbus_write_byte_cmd, lm75_smbus_write_word_cmd, NULL, dev); + + dev->smbus_addr = addr; } @@ -128,7 +130,7 @@ lm75_read(lm75_t *dev, uint8_t reg) /* The AS99127F hardware monitor uses the addresses of its LM75 devices to access some of its proprietary registers. Pass this operation on to the main monitor address through an internal SMBus call, if necessary. */ - if ((reg > 0x7) && ((reg & 0xf8) != 0x50) && (dev->as99127f_smbus_addr)) + if ((reg > 0x7) && ((reg & 0xf8) != 0x50) && (dev->as99127f_smbus_addr < 0x80)) ret = smbus_read_byte_cmd(dev->as99127f_smbus_addr, reg); else ret = dev->regs[reg & 0x7]; @@ -191,7 +193,7 @@ lm75_write(lm75_t *dev, uint8_t reg, uint8_t val) /* The AS99127F hardware monitor uses the addresses of its LM75 devices to access some of its proprietary registers. Pass this operation on to the main monitor address through an internal SMBus call, if necessary. */ - if ((reg > 0x7) && ((reg & 0xf8) != 0x50) && (dev->as99127f_smbus_addr)) { + if ((reg > 0x7) && ((reg & 0xf8) != 0x50) && (dev->as99127f_smbus_addr < 0x80)) { smbus_write_byte_cmd(dev->as99127f_smbus_addr, reg, val); return 1; } @@ -216,7 +218,7 @@ lm75_reset(lm75_t *dev) dev->regs[0x3] = 0x4b; dev->regs[0x5] = 0x50; - lm75_remap(dev); + lm75_remap(dev, dev->local & 0x7f); } @@ -224,6 +226,9 @@ static void lm75_close(void *priv) { lm75_t *dev = (lm75_t *) priv; + + lm75_remap(dev, 0); + free(dev); } @@ -237,8 +242,7 @@ lm75_init(const device_t *info) dev->local = info->local; dev->values = hwm_get_values(); - dev->smbus_addr = dev->local; - dev->as99127f_smbus_addr = 0x00; + dev->as99127f_smbus_addr = 0x80; lm75_reset(dev); diff --git a/src/device/hwm_lm78.c b/src/device/hwm_lm78.c index bf474db9e..829e323ce 100644 --- a/src/device/hwm_lm78.c +++ b/src/device/hwm_lm78.c @@ -91,24 +91,26 @@ lm78_log(const char *fmt, ...) static void -lm78_remap(lm78_t *dev) +lm78_remap(lm78_t *dev, uint8_t addr) { lm75_t *lm75; if (!(dev->local & LM78_SMBUS)) return; - lm78_log("LM78: remapping to SMBus %02Xh\n", dev->smbus_addr); + lm78_log("LM78: remapping to SMBus %02Xh\n", addr); smbus_removehandler(dev->smbus_addr, 1, lm78_smbus_read_byte, lm78_smbus_read_byte_cmd, lm78_smbus_read_word_cmd, NULL, lm78_smbus_write_byte, lm78_smbus_write_byte_cmd, lm78_smbus_write_word_cmd, NULL, dev); - if (dev->smbus_addr) smbus_sethandler(dev->smbus_addr, 1, + if (addr < 0x80) smbus_sethandler(addr, 1, lm78_smbus_read_byte, lm78_smbus_read_byte_cmd, lm78_smbus_read_word_cmd, NULL, lm78_smbus_write_byte, lm78_smbus_write_byte_cmd, lm78_smbus_write_word_cmd, NULL, dev); + dev->smbus_addr = addr; + if (dev->local & LM78_AS99127F) { /* Store the main SMBus address on the LM75 devices to ensure reads/writes to the AS99127F's proprietary registers are passed through to this side. */ @@ -291,10 +293,8 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) switch (reg) { case 0x40: - if (val & 0x80) { - /* INITIALIZATION bit resets all registers except main SMBus address */ + if (val & 0x80) /* INITIALIZATION bit resets all registers except main SMBus address */ lm78_reset(dev, 1); - } break; case 0x47: /* update FAN1/FAN2 values to match the new divisor */ @@ -303,19 +303,15 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) break; case 0x48: /* set main SMBus address */ - if (dev->local & LM78_SMBUS) { - dev->smbus_addr = (dev->regs[0x48] & 0x7f); - lm78_remap(dev); - } + if (dev->local & LM78_SMBUS) + lm78_remap(dev, dev->regs[0x48] & 0x7f); break; case 0x49: if (!(dev->local & LM78_WINBOND)) { - if (val & 0x20) { - /* Chip Reset bit (LM78 only) resets all registers */ + if (val & 0x20) /* Chip Reset bit (LM78 only) resets all registers */ lm78_reset(dev, 0); - } else { + else dev->regs[0x49] = 0x40; - } } else { dev->regs[0x49] &= 0x01; } @@ -328,10 +324,9 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) if (!lm75) continue; if (dev->regs[0x4a] & (0x08 * (0x10 * i))) /* DIS_T2 and DIS_T3 bit disable those interfaces */ - lm75->smbus_addr = 0x00; + lm75_remap(lm75, 0x80); else - lm75->smbus_addr = (0x48 + ((dev->regs[0x4a] >> (i * 4)) & 0x7)); - lm75_remap(lm75); + lm75_remap(lm75, 0x48 + ((dev->regs[0x4a] >> (i * 4)) & 0x7)); } } break; @@ -428,7 +423,7 @@ lm78_reset(lm78_t *dev, uint8_t initialization) dev->regs[0x49] = 0x40; } - lm78_remap(dev); + lm78_remap(dev, dev->smbus_addr); } diff --git a/src/device/serial.c b/src/device/serial.c index e5490d763..2d1aad6b3 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -203,6 +203,14 @@ serial_transmit(serial_t *dev, uint8_t val) write_fifo(dev, val); else if (dev->sd->dev_write) dev->sd->dev_write(dev, dev->sd->priv, val); + + if ((val >= ' ' && val <= '~') || val == '\r' || val == '\n') { + fputc(val, stdout); + if (val == '\n') + fflush(stdout); + } else { + fprintf(stdout, "[%02X]", val); + } } diff --git a/src/include/86box/hwm.h b/src/include/86box/hwm.h index 0cae77dbb..53d69500b 100644 --- a/src/include/86box/hwm.h +++ b/src/include/86box/hwm.h @@ -43,7 +43,7 @@ typedef struct { extern void hwm_set_values(hwm_values_t new_values); extern hwm_values_t* hwm_get_values(); -extern void lm75_remap(lm75_t *dev); +extern void lm75_remap(lm75_t *dev, uint8_t addr); extern uint8_t lm75_read(lm75_t *dev, uint8_t reg); extern uint8_t lm75_write(lm75_t *dev, uint8_t reg, uint8_t val); @@ -56,5 +56,8 @@ extern const device_t w83781d_device; extern const device_t as99127f_device; extern const device_t as99127f_rev2_device; +extern const device_t gl518sm_2c_device; +extern const device_t gl518sm_2d_device; + #endif /*EMU_HWM_H*/ diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 3ddc77186..9236b459e 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -365,13 +365,30 @@ machine_at_ax6bc_init(const machine_t *model) pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); device_add(&keyboard_ps2_pci_device); device_add(&w83977tf_device); device_add(&sst_flash_29ee020_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 256); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + + hwm_values_t machine_hwm = { + { /* fan speeds */ + 3000, /* System */ + 3000 /* CPU */ + }, { /* temperatures */ + 30 /* CPU */ + }, { /* voltages */ + 2050, /* VCORE (2.05V by default) */ + RESISTOR_DIVIDER(12000, 150, 47), /* +12V (15K/4.7K divider suggested in the GL518SM datasheet) */ + 3300 /* +3.3V */ + } + }; + if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUM2) + machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Klamath */ + hwm_set_values(machine_hwm); + device_add(&gl518sm_2d_device); return ret; } diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index c41737b5e..f555de30c 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -217,7 +217,7 @@ machine_at_63a_init(const machine_t *model) { int ret; - ret = bios_load_linear(L"roms/machines/63a1/63a-q3.bin", + ret = bios_load_linear(L"roms/machines/63a1/6ZX82.BIN", 0x000c0000, 262144, 0); if (bios_only || !ret) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 2334fa603..84c31fb99 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -582,7 +582,7 @@ MCHOBJ := machine.o machine_table.o \ m_at_socket4_5.o m_at_socket7_s7.o m_at_sockets7.o \ m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o -DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o serial.o \ +DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o serial.o \ smbus.o smbus_piix4.o \ keyboard.o \ keyboard_xt.o keyboard_at.o \ From f565362a412aa684f5bbdbbe75ea819f63de95ef Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 2 Jul 2020 21:44:28 -0300 Subject: [PATCH 49/54] Undo local changes to cpu.c --- src/cpu/cpu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 3fa0752f1..89c43063b 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -61,7 +61,7 @@ #endif #include "x87_timings.h" -#define ENABLE_CPU_LOG 1 +/*#define ENABLE_CPU_LOG 1*/ static void cpu_write(uint16_t addr, uint8_t val, void *priv); static uint8_t cpu_read(uint16_t addr, void *priv); @@ -3408,7 +3408,7 @@ void cpu_WRMSR() break; case 0x8B: cpu_log("WRMSR: Invalid MSR: 0x8B\n"); - //x86gpf(NULL, 0); /*Needed for Vista to correctly break on Pentium*/ + x86gpf(NULL, 0); /*Needed for Vista to correctly break on Pentium*/ break; } break; @@ -3541,7 +3541,7 @@ void cpu_WRMSR() default: i686_invalid_wrmsr: cpu_log("WRMSR: Invalid MSR: %08X\n", ECX); - //x86gpf(NULL, 0); + x86gpf(NULL, 0); break; } break; From f809bf65024c58e96e19d1268ebf3e3dc7a2297d Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 2 Jul 2020 21:45:00 -0300 Subject: [PATCH 50/54] Undo local changes to serial.c --- src/device/serial.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/device/serial.c b/src/device/serial.c index 2d1aad6b3..e5490d763 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -203,14 +203,6 @@ serial_transmit(serial_t *dev, uint8_t val) write_fifo(dev, val); else if (dev->sd->dev_write) dev->sd->dev_write(dev, dev->sd->priv, val); - - if ((val >= ' ' && val <= '~') || val == '\r' || val == '\n') { - fputc(val, stdout); - if (val == '\n') - fflush(stdout); - } else { - fprintf(stdout, "[%02X]", val); - } } From aec8285849ac26a110aafe930587aae240ccae72 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 2 Jul 2020 21:45:46 -0300 Subject: [PATCH 51/54] Undo local changes to m_at_socket370.c --- src/machine/m_at_socket370.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index f555de30c..c41737b5e 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -217,7 +217,7 @@ machine_at_63a_init(const machine_t *model) { int ret; - ret = bios_load_linear(L"roms/machines/63a1/6ZX82.BIN", + ret = bios_load_linear(L"roms/machines/63a1/63a-q3.bin", 0x000c0000, 262144, 0); if (bios_only || !ret) From 02c43a1be6830e58ad184fc2e3e8356fe33f4ca3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Jul 2020 03:25:46 +0200 Subject: [PATCH 52/54] Some CL-GD 54xx fixes. --- src/video/vid_cl54xx.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index c169253b0..478edd8f4 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -702,7 +702,7 @@ gd54xx_in(uint16_t addr, void *p) case 0x17: ret = svga->gdcreg[0x17] & ~(7 << 3); if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) { - if (svga->crtc[0x27] == CIRRUS_ID_CLGD5428) { + if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5428) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5426)) { if (gd54xx->vlb) ret |= (CL_GD5428_SYSTEM_BUS_VESA << 3); else if (gd54xx->mca) @@ -3023,9 +3023,9 @@ static void #endif case CIRRUS_ID_CLGD5426: - if (info->local & 0x200) { + if (info->local & 0x200) romfn = NULL; - } else + else romfn = BIOS_GD5426_PATH; break; @@ -3082,15 +3082,18 @@ static void vram = 1; gd54xx->vram_size = 1 << 20; } else { - if (id >= CIRRUS_ID_CLGD5420) - vram = device_get_config_int("memory"); - else - vram = 0; - + if (id >= CIRRUS_ID_CLGD5420) { + if ((id == CIRRUS_ID_CLGD5426) && (info->local & 0x200)) + vram = 1; + else + vram = device_get_config_int("memory"); + } else + vram = 0; + if (vram) - gd54xx->vram_size = vram << 20; + gd54xx->vram_size = vram << 20; else - gd54xx->vram_size = 1 << 19; + gd54xx->vram_size = 1 << 19; } gd54xx->vram_mask = gd54xx->vram_size - 1; @@ -3556,7 +3559,7 @@ const device_t gd5426_onboard_device = NULL, gd54xx_speed_changed, gd54xx_force_redraw, - gd5428_config + NULL }; const device_t gd5428_isa_device = From 042f743a3580bc605803fa0dd08f8b2beb878042 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 2 Jul 2020 23:26:04 -0300 Subject: [PATCH 53/54] Disable GL518SM logging --- src/device/hwm_gl518sm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/hwm_gl518sm.c b/src/device/hwm_gl518sm.c index 250c34a42..e09c29443 100644 --- a/src/device/hwm_gl518sm.c +++ b/src/device/hwm_gl518sm.c @@ -56,7 +56,7 @@ static void gl518sm_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val static uint8_t gl518sm_write(gl518sm_t *dev, uint8_t reg, uint16_t val); static void gl518sm_reset(gl518sm_t *dev); -#define ENABLE_GL518SM_LOG 1 + #ifdef ENABLE_GL518SM_LOG int gl518sm_do_log = ENABLE_GL518SM_LOG; From 064acae3fcae931032331cbffa5a00748042e4da Mon Sep 17 00:00:00 2001 From: nerd73 Date: Thu, 2 Jul 2020 20:34:18 -0600 Subject: [PATCH 54/54] Fix MSRs on the IBM 386/486 CPUs Also give the IBM 386SLC 'isibm486' as it is believed to identify as a 486 to software. --- src/cpu/cpu.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 89c43063b..7cdd36ed4 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -369,8 +369,8 @@ cpu_set(void) is8086 = (cpu_s->cpu_type > CPU_8088); 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); + israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD); + isibm486 = (cpu_s->cpu_type == CPU_IBM386SLC) || (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); @@ -627,7 +627,8 @@ cpu_set(void) x86_setopcodes(ops_386, ops_ibm486_0f, dynarec_ops_386, dynarec_ops_ibm486_0f); #else x86_setopcodes(ops_386, ops_ibm486_0f); -#endif +#endif + cpu_features = CPU_FEATURE_MSR; case CPU_386SX: timing_rr = 2; /*register dest - register src*/ timing_rm = 6; /*register dest - memory src*/ @@ -665,6 +666,7 @@ cpu_set(void) #else x86_setopcodes(ops_386, ops_ibm486_0f); #endif + cpu_features = CPU_FEATURE_MSR; case CPU_386DX: if (fpu_type == FPU_287) /*In case we get Deskpro 386 emulation*/ {