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/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/opti495.c b/src/chipset/opti495.c index 47ee25582..c3fa1bda4 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,98 @@ 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))) { + 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; + } + + 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))) { + 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; + } + + mem_set_mem_state_both(base, 0x4000, shflags); + } + + flushmmucache(); +} + + static void opti495_write(uint16_t addr, uint8_t val, void *priv) { @@ -285,26 +131,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 +169,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 +202,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/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; diff --git a/src/chipset/opti895.c b/src/chipset/opti895.c new file mode 100644 index 000000000..8c1f050b4 --- /dev/null +++ b/src/chipset/opti895.c @@ -0,0 +1,296 @@ +/* + * 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. + * + * + * + * Authors: Tiseno100, + * Miran Grca, + * + * Copyright 2008-2020 Tiseno100. + * Copyright 2016-2020 Miran Grca. + */ +#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, 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) +{ + 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[0x23] & (1 << i)) { + 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; + } + + mem_set_mem_state_both(base, 0x4000, shflags); + } + + for (i = 0; i < 4; i++) { + base = 0xc0000 + (i << 14); + + if (dev->regs[0x26] & (1 << i)) { + 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; + } + + 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) +{ + opti895_t *dev = (opti895_t *) priv; + + switch (addr) { + case 0x22: + dev->idx = val; + break; + case 0x23: + 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 >= 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); + + 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; + break; + } + 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 0x23: + if (dev->idx == 0x01) + ret = dev->regs[dev->idx]; + break; + case 0x24: + 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: + 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, 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; + 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[0xe8] = 0x08; + dev->regs[0xe9] = 0x08; + 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; +} + + +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, + 0, + opti895_init, opti895_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c index 7fafa9607..0bec0232f 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, 0x48, 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/chipset/vl82c480.c b/src/chipset/vl82c480.c index d20eb4ba6..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,153 +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); - - return dev; + vl82c480_t *dev = (vl82c480_t *)malloc(sizeof(vl82c480_t)); + memset(dev, 0, sizeof(vl82c480_t)); + + dev->regs[0x00] = 0x90; + dev->regs[0x01] = 0xff; + dev->regs[0x02] = 0x8a; + dev->regs[0x03] = 0x88; + dev->regs[0x06] = 0x1b; + dev->regs[0x08] = 0x38; + + 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/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/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/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 6e11e85cb..3fa0752f1 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; @@ -189,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; @@ -358,6 +363,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); @@ -616,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*/ @@ -655,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*/ @@ -722,7 +728,7 @@ cpu_set(void) timing_jmp_pm = 27; timing_jmp_pm_gate = 45; break; - + case CPU_RAPIDCAD: #ifdef USE_DYNAREC @@ -2494,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; @@ -3044,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/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/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]; 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/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 e27b894df..9939a037a 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; } @@ -2918,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) { @@ -3015,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); } @@ -3055,7 +3054,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)) { diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 276da03c8..de25fca32 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; @@ -63,7 +60,10 @@ 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; extern const device_t opti5x7_device; /* C&T */ @@ -77,6 +77,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/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]; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index b0b4fa054..fc423786a 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 *); @@ -300,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/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/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/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..0f47126ee 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) @@ -385,16 +405,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 +424,13 @@ 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 +452,12 @@ 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 +478,21 @@ 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_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/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..651ef1d25 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); } @@ -558,6 +558,7 @@ machine_ps1_m2121_init(const machine_t *model) return ret; } + int machine_ps1_m2133_init(const machine_t *model) { @@ -570,9 +571,9 @@ 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); nmi_mask = 0x80; @@ -582,6 +583,7 @@ machine_ps1_m2133_init(const machine_t *model) return ret; } + const device_t * ps1_m2133_get_device(void) { 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; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 75a211944..8a0488c0d 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) @@ -221,9 +222,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 */ @@ -235,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/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_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/sio/sio_w83787f.c b/src/sio/sio_w83787f.c index bc1a4792c..8fe4f4bf7 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; @@ -186,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); } @@ -254,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) @@ -286,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); diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 84c31fb99..f497103fb 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 @@ -559,9 +569,9 @@ 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 \ + 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 @@ -595,7 +605,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