This commit is contained in:
RichardG867
2020-07-02 21:42:52 -03:00
39 changed files with 1535 additions and 896 deletions

View File

@@ -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:

View File

@@ -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, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2019 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#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
};

View File

@@ -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;

View File

@@ -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, <mgrca8@gmail.com>
*
* Copyright 2008-2020 Tiseno100.
* Copyright 2016-2020 Miran Grca.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -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
};

View File

@@ -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, <mgrca8@gmail.com>
*
* Copyright 2020 plant/nerd73.
* Copyright 2020 Miran Grca.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -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;

296
src/chipset/opti895.c Normal file
View File

@@ -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, <mgrca8@gmail.com>
*
* Copyright 2008-2020 Tiseno100.
* Copyright 2016-2020 Miran Grca.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#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
};

View File

@@ -10,17 +10,17 @@
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2019 Sarah Walker.
* Copyright 2019 Miran Grca.
* Copyright 2019,2020 Miran Grca.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#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
};

View File

@@ -8,9 +8,9 @@
*
* Implementation of the VLSI VL82c480 chipset.
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2020 Sarah Walker.
* Copyright 2020 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
@@ -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,

View File

@@ -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);

View File

@@ -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,

View File

@@ -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;

View File

@@ -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)

View File

@@ -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;

View File

@@ -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];

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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)) {

View File

@@ -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

View File

@@ -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);

View File

@@ -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];

View File

@@ -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 *);

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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)
{

View File

@@ -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);

View File

@@ -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;

View File

@@ -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)
{

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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();
}

View File

@@ -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(). */

View File

@@ -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);

View File

@@ -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
};

View File

@@ -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, <http://pcem-emulator.co.uk/>
*
* Copyright 2020 Sarah Walker.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#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
};

View File

@@ -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);

View File

@@ -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