Merge branch 'master' of github.com:86Box/86Box into tc1995

This commit is contained in:
TC1995
2020-07-03 12:44:11 +02:00
57 changed files with 2367 additions and 1096 deletions

View File

@@ -25,8 +25,8 @@ If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. Windows 10]
- Version [e.g. v2.06 build 2007]
- Build type [i.e. regular, optimized, or dev]
- 86Box version: [e.g. v2.06 build 2007]
- Build type: [i.e. regular, optimized, or dev]
**Additional context**
Add any other context about the problem here. If you are using an Optimized build, make sure to try the regular build too before filing a bug report!

View File

@@ -2,7 +2,7 @@
name: Feature request
about: Suggest an idea for this project
title: ''
labels: feature request
labels: feature
assignees: ''
---

38
.github/workflows/c-cpp.yml vendored Normal file
View File

@@ -0,0 +1,38 @@
name: C/C++ CI
on:
push:
paths:
- src/**
- .github/workflows/**
pull_request:
paths:
- src/**
- .github/workflows/**
jobs:
build:
runs-on: windows-latest
defaults:
run:
shell: msys2 {0}
strategy:
matrix:
dev-build: ['y', 'n']
new-dynarec: ['y', 'n']
steps:
- uses: msys2/setup-msys2@v1
with:
update: true
msystem: MINGW32
install: 'make mingw-w64-i686-toolchain mingw-w64-i686-openal mingw-w64-i686-freetype mingw-w64-i686-SDL2 mingw-w64-i686-zlib mingw-w64-i686-libpng mingw-w64-i686-libvncserver'
- uses: actions/checkout@v2
- name: make
run: make -fwin/makefile.mingw DEV_BUILD=${{ matrix.dev-build }} NEW_DYNAREC=${{ matrix.new-dynarec }} VNC=n
working-directory: ./src

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

@@ -32,6 +32,7 @@
#include <86box/hdc.h>
#include <86box/machine.h>
#include <86box/chipset.h>
#include <86box/spd.h>
#define MEM_STATE_SHADOW_R 0x01
@@ -232,8 +233,6 @@ i420ex_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x4c: case 0x51:
case 0x57:
case 0x60: case 0x61: case 0x62: case 0x63:
case 0x64:
case 0x68: case 0x69:
dev->regs[addr] = val;
if (addr == 0x4c) {
@@ -306,6 +305,9 @@ i420ex_write(int func, int addr, uint8_t val, void *priv)
i420ex_map(0xec000, 0x04000, val >> 4);
dev->regs[0x5f] = val;
break;
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64:
spd_write_drbs(dev->regs, 0x60, 0x64, 1);
break;
case 0x66: case 0x67:
i420ex_log("Set IRQ routing: INT %c -> %02X\n", 0x41 + (addr & 0x01), val);
dev->regs[addr] = val & 0x8f;

View File

@@ -6,7 +6,7 @@
*
* This file is part of the 86Box distribution.
*
* Implementation of the Intel PCISet chips from 420TX to 440BX.
* Implementation of the Intel PCISet chips from 420TX to 440GX.
*
*
*
@@ -28,6 +28,7 @@
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/chipset.h>
#include <86box/spd.h>
enum
@@ -52,12 +53,32 @@ typedef struct
{
uint8_t pm2_cntrl, max_func,
smram_locked, max_drb,
drb_default;
drb_unit, drb_default;
uint8_t regs[2][256], regs_locked[2][256];
int type;
} i4x0_t;
#ifdef ENABLE_I4X0_LOG
int i4x0_do_log = ENABLE_I4X0_LOG;
static void
i4x0_log(const char *fmt, ...)
{
va_list ap;
if (i4x0_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define i4x0_log(fmt, ...)
#endif
static void
i4x0_map(uint32_t addr, uint32_t size, int state)
{
@@ -491,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;
@@ -502,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;
@@ -628,6 +659,10 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
regs[0x5f] = val & 0x77;
break;
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64:
if ((addr & 0x7) <= dev->max_drb) {
spd_write_drbs(regs, 0x60, 0x60 + dev->max_drb, dev->drb_unit);
break;
}
switch (dev->type) {
case INTEL_420TX: case INTEL_420ZX:
case INTEL_430LX: case INTEL_430NX:
@@ -647,6 +682,10 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
}
break;
case 0x65:
if ((addr & 0x7) <= dev->max_drb) {
spd_write_drbs(regs, 0x60, 0x60 + dev->max_drb, dev->drb_unit);
break;
}
switch (dev->type) {
case INTEL_420TX: case INTEL_420ZX:
case INTEL_430LX: case INTEL_430NX:
@@ -666,6 +705,10 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
}
break;
case 0x66:
if ((addr & 0x7) <= dev->max_drb) {
spd_write_drbs(regs, 0x60, 0x60 + dev->max_drb, dev->drb_unit);
break;
}
switch (dev->type) {
case INTEL_430NX: case INTEL_430HX:
case INTEL_440FX: case INTEL_440LX:
@@ -676,12 +719,16 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
}
break;
case 0x67:
if ((addr & 0x7) <= dev->max_drb) {
spd_write_drbs(regs, 0x60, 0x60 + dev->max_drb, dev->drb_unit);
break;
}
switch (dev->type) {
case INTEL_430NX: case INTEL_430HX:
case INTEL_440FX: case INTEL_440LX:
case INTEL_440EX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
case INTEL_440ZX:
regs[addr] = val;
break;
case INTEL_430VX:
@@ -1284,28 +1331,33 @@ 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;
dev->max_drb = 5;
dev->drb_unit = 4;
dev->drb_default = 0x02;
break;
case INTEL_430LX:
@@ -1324,6 +1376,7 @@ static void
regs[0x59] = 0x0f;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02;
dev->max_drb = 5;
dev->drb_unit = 4;
dev->drb_default = 0x02;
break;
case INTEL_430NX:
@@ -1344,6 +1397,7 @@ static void
regs[0x59] = 0x0f;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02;
dev->max_drb = 7;
dev->drb_unit = 4;
dev->drb_default = 0x02;
break;
case INTEL_430FX:
@@ -1359,6 +1413,7 @@ static void
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = 0x02;
regs[0x72] = 0x02;
dev->max_drb = 4;
dev->drb_unit = 4;
dev->drb_default = 0x02;
break;
case INTEL_430HX:
@@ -1373,6 +1428,7 @@ static void
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02;
regs[0x72] = 0x02;
dev->max_drb = 7;
dev->drb_unit = 4;
dev->drb_default = 0x02;
break;
case INTEL_430VX:
@@ -1394,6 +1450,7 @@ static void
regs[0x74] = 0x0e;
regs[0x78] = 0x23;
dev->max_drb = 4;
dev->drb_unit = 4;
dev->drb_default = 0x02;
break;
case INTEL_430TX:
@@ -1411,6 +1468,7 @@ static void
regs[0x70] = 0x20;
regs[0x72] = 0x02;
dev->max_drb = 5;
dev->drb_unit = 4;
dev->drb_default = 0x02;
break;
case INTEL_440FX:
@@ -1427,6 +1485,7 @@ static void
regs[0x71] = 0x10;
regs[0x72] = 0x02;
dev->max_drb = 7;
dev->drb_unit = 8;
dev->drb_default = 0x02;
break;
case INTEL_440LX:
@@ -1451,12 +1510,13 @@ static void
regs[0xa5] = 0x02;
regs[0xa7] = 0x1f;
dev->max_drb = 7;
dev->drb_unit = 8;
dev->drb_default = 0x01;
break;
case INTEL_440EX:
dev->max_func = 1;
regs[0x02] = 0x80; regs[0x03] = 0x71; /* 82443EX. Same Vendor ID as 440LX*/
regs[0x02] = 0x80; regs[0x03] = 0x71; /* 82443EX. Same Vendor ID as 440LX */
regs[0x06] = 0x90;
regs[0x10] = 0x08;
regs[0x34] = 0xa0;
@@ -1475,6 +1535,7 @@ static void
regs[0xa5] = 0x02;
regs[0xa7] = 0x1f;
dev->max_drb = 7;
dev->drb_unit = 8;
dev->drb_default = 0x01;
break;
case INTEL_440BX: case INTEL_440ZX:
@@ -1503,6 +1564,7 @@ static void
regs[0xa5] = 0x02;
regs[0xa7] = 0x1f;
dev->max_drb = 7;
dev->drb_unit = 8;
dev->drb_default = 0x01;
break;
case INTEL_440GX:
@@ -1528,6 +1590,7 @@ static void
regs[0xa5] = 0x02;
regs[0xa7] = 0x1f;
dev->max_drb = 7;
dev->drb_unit = 8;
dev->drb_default = 0x01;
break;
}

175
src/chipset/opti283.c Normal file
View File

@@ -0,0 +1,175 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of the OPTi 82C283 chipset.
*
*
*
* Authors: Tiseno100
*
* Copyright 2020 Tiseno100
*
*/
#include <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 index,
regs[256];
} opti283_t;
static void opti283_shadow_recalc(opti283_t *dev)
{
uint32_t base;
uint32_t shflags, i = 0;
shadowbios = 0;
shadowbios_write = 0;
/* F0000 - FFFFF segmentation */
if(!(dev->regs[0x11] & 0x80)){
shadowbios = 1;
shadowbios_write = 0;
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
} else {
shadowbios = 0;
shadowbios_write = 1;
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
}
/* C0000 - CFFFF segmentation */
for(i = 4; i < 8; i++){
base = 0xc0000 + ((i-4) << 14);
if((dev->regs[0x13] & (1 << i)) & (dev->regs[0x11] & 0x10)){
shflags = MEM_READ_INTERNAL;
shflags |= (!(dev->regs[0x11] & 0x01)) ? MEM_WRITE_INTERNAL : MEM_WRITE_DISABLED;
mem_set_mem_state_both(base, 0x4000, shflags);
} else {
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
}
}
/* D0000 - DFFFF segmentation */
for(i = 0; i < 4; i++){
base = 0xd0000 + (i << 14);
if((dev->regs[0x12] & (1 << i)) & (dev->regs[0x11] & 0x20)){
shflags = MEM_READ_INTERNAL;
shflags |= (!(dev->regs[0x11] & 0x02)) ? MEM_WRITE_INTERNAL : MEM_WRITE_DISABLED;
mem_set_mem_state(base, 0x4000, shflags);
} else mem_set_mem_state(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
}
/* E0000 - EFFFF segmentation */
for(i = 4; i < 8; i++){
base = 0xe0000 + ((i-4) << 14);
if((dev->regs[0x12] & (1 << i)) & (dev->regs[0x11] & 0x40)){
shflags = MEM_READ_INTERNAL;
shflags |= (!(dev->regs[0x11] & 0x04)) ? MEM_WRITE_INTERNAL : MEM_WRITE_DISABLED;
mem_set_mem_state(base, 0x4000, shflags);
} else mem_set_mem_state(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
}
}
static void
opti283_write(uint16_t addr, uint8_t val, void *priv)
{
opti283_t *dev = (opti283_t *) priv;
switch (addr) {
case 0x22:
dev->index = val;
break;
case 0x24:
/*pclog("OPTi 283: dev->regs[%02x] = %02x\n", dev->index, val);*/
dev->regs[dev->index] = val;
switch(dev->index){
case 0x10:
cpu_update_waitstates();
case 0x11:
case 0x12:
case 0x13:
opti283_shadow_recalc(dev);
break;
}
break;
}
}
static uint8_t
opti283_read(uint16_t addr, void *priv)
{
uint8_t ret = 0xff;
opti283_t *dev = (opti283_t *) priv;
switch (addr) {
case 0x24:
ret = dev->regs[dev->index];
break;
}
return ret;
}
static void
opti283_close(void *priv)
{
opti283_t *dev = (opti283_t *) priv;
free(dev);
}
static void *
opti283_init(const device_t *info)
{
opti283_t *dev = (opti283_t *) malloc(sizeof(opti283_t));
memset(dev, 0, sizeof(opti283_t));
io_sethandler(0x022, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev);
io_sethandler(0x024, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev);
dev->regs[0x10] = 0x3f;
dev->regs[0x11] = 0xf0;
opti283_shadow_recalc(dev);
return dev;
}
const device_t opti283_device = {
"OPTi 82C283",
0,
0,
opti283_init, opti283_close, NULL,
NULL, NULL, NULL,
NULL
};

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

@@ -32,6 +32,7 @@
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/chipset.h>
#include <86box/spd.h>
typedef struct via_apollo_t
@@ -226,6 +227,13 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
dev->pci_conf[0][0x53] = (dev->pci_conf[0][0x53] & ~0xf0) | (val & 0xf0);
break;
case 0x56: case 0x57: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: /* DRAM Row Ending Address */
if (dev->id >= 0x0691)
spd_write_drbs(dev->pci_conf[0], 0x5a, 0x56, 8);
else if (addr >= 0x5a)
spd_write_drbs(dev->pci_conf[0], 0x5a, 0x5f, 8);
break;
case 0x58:
if (dev->id == 0x0597)
dev->pci_conf[0][0x58] = (dev->pci_conf[0][0x58] & ~0xee) | (val & 0xee);

View File

@@ -35,6 +35,7 @@
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/chipset.h>
#include <86box/spd.h>
typedef struct via_vpx_t
{
@@ -94,6 +95,10 @@ via_vpx_t *dev = (via_vpx_t *) priv;
dev->pci_conf[0x07] &= ~(val & 0xb0);
break;
case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: // Bank Ending
spd_write_drbs(dev->pci_conf, 0x5a, 0x5f, 4);
break;
case 0x61: // Shadow RAM control 1
if ((dev->pci_conf[0x61] ^ val) & 0x03)
vpx_map(0xc0000, 0x04000, val & 0x03);
@@ -201,6 +206,7 @@ via_vpx_init(const device_t *info)
dev->pci_conf[0x5e] = 1; // Bank 4 Ending
dev->pci_conf[0x5f] = 1; // Bank 5 Ending
dev->pci_conf[0x60] = 0x3f; // DRAM type
dev->pci_conf[0x64] = 0xab; // DRAM reference timing
return dev;

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,13 +363,14 @@ 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);
is286 = (cpu_s->cpu_type >= CPU_286);
is386 = (cpu_s->cpu_type >= CPU_386SX);
israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD);
isibm486 = (cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL);
israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD);
isibm486 = (cpu_s->cpu_type == CPU_IBM386SLC) || (cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL);
is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_RAPIDCAD);
is486sx = (cpu_s->cpu_type >= CPU_i486SX) && (cpu_s->cpu_type < CPU_i486SX2);
is486sx2 = (cpu_s->cpu_type >= CPU_i486SX2) && (cpu_s->cpu_type < CPU_i486DX);
@@ -616,12 +622,13 @@ 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);
x86_setopcodes(ops_386, ops_ibm486_0f);
#endif
case CPU_IBM386SLC:
cpu_features = CPU_FEATURE_MSR;
case CPU_386SX:
timing_rr = 2; /*register dest - register src*/
timing_rm = 6; /*register dest - memory src*/
@@ -655,10 +662,11 @@ 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
cpu_features = CPU_FEATURE_MSR;
case CPU_386DX:
if (fpu_type == FPU_287) /*In case we get Deskpro 386 emulation*/
{
@@ -722,7 +730,7 @@ cpu_set(void)
timing_jmp_pm = 27;
timing_jmp_pm_gate = 45;
break;
case CPU_RAPIDCAD:
#ifdef USE_DYNAREC
@@ -2494,6 +2502,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 +3082,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];

278
src/device/hwm_gl518sm.c Normal file
View File

@@ -0,0 +1,278 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Emulation of the Genesys Logic GL518SM hardware monitoring chip.
*
*
*
* Author: RichardG, <richardg867@gmail.com>
*
* Copyright 2020 RichardG.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#define HAVE_STDARG_H
#include <wchar.h>
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/io.h>
#include "cpu.h"
#include <86box/smbus.h>
#include <86box/hwm.h>
#define CLAMP(a, min, max) (((a)< (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
#define GL518SM_RPM_TO_REG(r, d) ((r) ? CLAMP(480000 / (r * d), 1, 255) : 0)
#define GL518SM_VOLTAGE_TO_REG(v) (((v) / 19) & 0xff)
#define GL518SM_VDD_TO_REG(v) ((((v) * 4) / 95) & 0xff)
typedef struct {
uint32_t local;
hwm_values_t *values;
uint16_t regs[32];
uint8_t addr_register;
uint8_t smbus_addr;
} gl518sm_t;
static uint8_t gl518sm_smbus_read_byte(uint8_t addr, void *priv);
static uint8_t gl518sm_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv);
static uint16_t gl518sm_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv);
static uint16_t gl518sm_read(gl518sm_t *dev, uint8_t reg);
static void gl518sm_smbus_write_byte(uint8_t addr, uint8_t val, void *priv);
static void gl518sm_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv);
static void gl518sm_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv);
static uint8_t gl518sm_write(gl518sm_t *dev, uint8_t reg, uint16_t val);
static void gl518sm_reset(gl518sm_t *dev);
#ifdef ENABLE_GL518SM_LOG
int gl518sm_do_log = ENABLE_GL518SM_LOG;
static void
gl518sm_log(const char *fmt, ...)
{
va_list ap;
if (gl518sm_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define gl518sm_log(fmt, ...)
#endif
static void
gl518sm_remap(gl518sm_t *dev, uint8_t addr)
{
gl518sm_log("GL518SM: remapping to SMBus %02Xh\n", addr);
smbus_removehandler(dev->smbus_addr, 1,
gl518sm_smbus_read_byte, gl518sm_smbus_read_byte_cmd, gl518sm_smbus_read_word_cmd, NULL,
gl518sm_smbus_write_byte, gl518sm_smbus_write_byte_cmd, gl518sm_smbus_write_word_cmd, NULL,
dev);
if (addr < 0x80) smbus_sethandler(addr, 1,
gl518sm_smbus_read_byte, gl518sm_smbus_read_byte_cmd, gl518sm_smbus_read_word_cmd, NULL,
gl518sm_smbus_write_byte, gl518sm_smbus_write_byte_cmd, gl518sm_smbus_write_word_cmd, NULL,
dev);
dev->smbus_addr = addr;
}
static uint8_t
gl518sm_smbus_read_byte(uint8_t addr, void *priv)
{
gl518sm_t *dev = (gl518sm_t *) priv;
return gl518sm_read(dev, dev->addr_register);
}
static uint8_t
gl518sm_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv)
{
gl518sm_t *dev = (gl518sm_t *) priv;
return gl518sm_read(dev, cmd);
}
static uint16_t
gl518sm_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv)
{
gl518sm_t *dev = (gl518sm_t *) priv;
return gl518sm_read(dev, cmd);
}
static uint16_t
gl518sm_read(gl518sm_t *dev, uint8_t reg)
{
uint16_t ret = dev->regs[reg & 0x1f];
switch (reg) {
case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c:
/* two-byte registers: leave as-is */
break;
default:
/* single-byte registers: duplicate low byte to high byte (real hardware behavior unknown) */
ret |= (ret << 8);
break;
}
gl518sm_log("GL518SM: read(%02X) = %04X\n", reg, ret);
return ret;
}
static void
gl518sm_smbus_write_byte(uint8_t addr, uint8_t val, void *priv)
{
gl518sm_t *dev = (gl518sm_t *) priv;
dev->addr_register = val;
}
static void
gl518sm_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv)
{
gl518sm_t *dev = (gl518sm_t *) priv;
gl518sm_write(dev, cmd, val);
}
static void
gl518sm_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv)
{
gl518sm_t *dev = (gl518sm_t *) priv;
gl518sm_write(dev, cmd, val);
}
static uint8_t
gl518sm_write(gl518sm_t *dev, uint8_t reg, uint16_t val)
{
gl518sm_log("GL518SM: write(%02X, %04X)\n", reg, val);
switch (reg) {
case 0x00: case 0x01: case 0x04: case 0x07: case 0x0d: case 0x12: case 0x13: case 0x14: case 0x15:
/* read-only registers */
return 0;
case 0x0a:
dev->regs[0x13] = (val & 0xff);
break;
case 0x03:
dev->regs[reg] = (val & 0xfc);
if (val & 0x80) /* Init */
gl518sm_reset(dev);
break;
case 0x0f:
dev->regs[reg] = (val & 0xf8);
/* update fan values to match the new divisor */
dev->regs[0x07] = (GL518SM_RPM_TO_REG(dev->values->fans[0], 1 << ((dev->regs[0x0f] >> 6) & 0x3)) << 8);
dev->regs[0x07] |= GL518SM_RPM_TO_REG(dev->values->fans[1], 1 << ((dev->regs[0x0f] >> 4) & 0x3));
break;
case 0x11:
dev->regs[reg] = (val & 0x7f);
break;
default:
dev->regs[reg] = val;
break;
}
return 1;
}
static void
gl518sm_reset(gl518sm_t *dev)
{
memset(dev->regs, 0, sizeof(dev->regs));
dev->regs[0x00] = 0x80;
dev->regs[0x01] = 0x80; /* revision 0x80 can read all voltages */
dev->regs[0x04] = ((dev->values->temperatures[0] + 119) & 0xff);
dev->regs[0x05] = 0xc7;
dev->regs[0x06] = 0xc2;
dev->regs[0x07] = ((GL518SM_RPM_TO_REG(dev->values->fans[0], 8) << 8) | GL518SM_RPM_TO_REG(dev->values->fans[1], 8));
dev->regs[0x08] = 0x6464;
dev->regs[0x09] = 0xdac5;
dev->regs[0x0a] = 0xdac5;
dev->regs[0x0b] = 0xdac5;
dev->regs[0x0c] = 0xdac5;
/* AOpen System Monitor requires an approximate voltage offset of 13 at least on 3.3V (voltages[2]) */
dev->regs[0x0d] = 13 + GL518SM_VOLTAGE_TO_REG(dev->values->voltages[2]);
dev->regs[0x0f] = 0xf8;
dev->regs[0x13] = 13 + GL518SM_VOLTAGE_TO_REG(dev->values->voltages[1]);
dev->regs[0x14] = 13 + GL518SM_VOLTAGE_TO_REG(dev->values->voltages[0]);
dev->regs[0x15] = 13 + GL518SM_VDD_TO_REG(5000);
}
static void
gl518sm_close(void *priv)
{
gl518sm_t *dev = (gl518sm_t *) priv;
gl518sm_remap(dev, 0);
free(dev);
}
static void *
gl518sm_init(const device_t *info)
{
gl518sm_t *dev = (gl518sm_t *) malloc(sizeof(gl518sm_t));
memset(dev, 0, sizeof(gl518sm_t));
dev->local = info->local;
dev->values = hwm_get_values();
gl518sm_reset(dev);
gl518sm_remap(dev, dev->local & 0x7f);
return dev;
}
const device_t gl518sm_2c_device = {
"Genesys Logic GL518SM Hardware Monitor",
DEVICE_ISA,
0x2c,
gl518sm_init, gl518sm_close, NULL,
NULL, NULL, NULL,
NULL
};
const device_t gl518sm_2d_device = {
"Genesys Logic GL518SM Hardware Monitor",
DEVICE_ISA,
0x2d,
gl518sm_init, gl518sm_close, NULL,
NULL, NULL, NULL,
NULL
};

View File

@@ -60,19 +60,21 @@ lm75_log(const char *fmt, ...)
void
lm75_remap(lm75_t *dev)
lm75_remap(lm75_t *dev, uint8_t addr)
{
lm75_log("LM75: remapping to SMBus %02Xh\n", dev->smbus_addr);
lm75_log("LM75: remapping to SMBus %02Xh\n", addr);
smbus_removehandler(dev->smbus_addr, 1,
lm75_smbus_read_byte, lm75_smbus_read_byte_cmd, lm75_smbus_read_word_cmd, NULL,
lm75_smbus_write_byte, lm75_smbus_write_byte_cmd, lm75_smbus_write_word_cmd, NULL,
dev);
if (dev->smbus_addr) smbus_sethandler(dev->smbus_addr, 1,
if (addr < 0x80) smbus_sethandler(addr, 1,
lm75_smbus_read_byte, lm75_smbus_read_byte_cmd, lm75_smbus_read_word_cmd, NULL,
lm75_smbus_write_byte, lm75_smbus_write_byte_cmd, lm75_smbus_write_word_cmd, NULL,
dev);
dev->smbus_addr = addr;
}
@@ -128,7 +130,7 @@ lm75_read(lm75_t *dev, uint8_t reg)
/* The AS99127F hardware monitor uses the addresses of its LM75 devices
to access some of its proprietary registers. Pass this operation on to
the main monitor address through an internal SMBus call, if necessary. */
if ((reg > 0x7) && ((reg & 0xf8) != 0x50) && (dev->as99127f_smbus_addr))
if ((reg > 0x7) && ((reg & 0xf8) != 0x50) && (dev->as99127f_smbus_addr < 0x80))
ret = smbus_read_byte_cmd(dev->as99127f_smbus_addr, reg);
else
ret = dev->regs[reg & 0x7];
@@ -191,7 +193,7 @@ lm75_write(lm75_t *dev, uint8_t reg, uint8_t val)
/* The AS99127F hardware monitor uses the addresses of its LM75 devices
to access some of its proprietary registers. Pass this operation on to
the main monitor address through an internal SMBus call, if necessary. */
if ((reg > 0x7) && ((reg & 0xf8) != 0x50) && (dev->as99127f_smbus_addr)) {
if ((reg > 0x7) && ((reg & 0xf8) != 0x50) && (dev->as99127f_smbus_addr < 0x80)) {
smbus_write_byte_cmd(dev->as99127f_smbus_addr, reg, val);
return 1;
}
@@ -216,7 +218,7 @@ lm75_reset(lm75_t *dev)
dev->regs[0x3] = 0x4b;
dev->regs[0x5] = 0x50;
lm75_remap(dev);
lm75_remap(dev, dev->local & 0x7f);
}
@@ -224,6 +226,9 @@ static void
lm75_close(void *priv)
{
lm75_t *dev = (lm75_t *) priv;
lm75_remap(dev, 0);
free(dev);
}
@@ -237,8 +242,7 @@ lm75_init(const device_t *info)
dev->local = info->local;
dev->values = hwm_get_values();
dev->smbus_addr = dev->local;
dev->as99127f_smbus_addr = 0x00;
dev->as99127f_smbus_addr = 0x80;
lm75_reset(dev);

View File

@@ -91,24 +91,26 @@ lm78_log(const char *fmt, ...)
static void
lm78_remap(lm78_t *dev)
lm78_remap(lm78_t *dev, uint8_t addr)
{
lm75_t *lm75;
if (!(dev->local & LM78_SMBUS)) return;
lm78_log("LM78: remapping to SMBus %02Xh\n", dev->smbus_addr);
lm78_log("LM78: remapping to SMBus %02Xh\n", addr);
smbus_removehandler(dev->smbus_addr, 1,
lm78_smbus_read_byte, lm78_smbus_read_byte_cmd, lm78_smbus_read_word_cmd, NULL,
lm78_smbus_write_byte, lm78_smbus_write_byte_cmd, lm78_smbus_write_word_cmd, NULL,
dev);
if (dev->smbus_addr) smbus_sethandler(dev->smbus_addr, 1,
if (addr < 0x80) smbus_sethandler(addr, 1,
lm78_smbus_read_byte, lm78_smbus_read_byte_cmd, lm78_smbus_read_word_cmd, NULL,
lm78_smbus_write_byte, lm78_smbus_write_byte_cmd, lm78_smbus_write_word_cmd, NULL,
dev);
dev->smbus_addr = addr;
if (dev->local & LM78_AS99127F) {
/* Store the main SMBus address on the LM75 devices to ensure reads/writes
to the AS99127F's proprietary registers are passed through to this side. */
@@ -291,10 +293,8 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank)
switch (reg) {
case 0x40:
if (val & 0x80) {
/* INITIALIZATION bit resets all registers except main SMBus address */
if (val & 0x80) /* INITIALIZATION bit resets all registers except main SMBus address */
lm78_reset(dev, 1);
}
break;
case 0x47:
/* update FAN1/FAN2 values to match the new divisor */
@@ -303,19 +303,15 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank)
break;
case 0x48:
/* set main SMBus address */
if (dev->local & LM78_SMBUS) {
dev->smbus_addr = (dev->regs[0x48] & 0x7f);
lm78_remap(dev);
}
if (dev->local & LM78_SMBUS)
lm78_remap(dev, dev->regs[0x48] & 0x7f);
break;
case 0x49:
if (!(dev->local & LM78_WINBOND)) {
if (val & 0x20) {
/* Chip Reset bit (LM78 only) resets all registers */
if (val & 0x20) /* Chip Reset bit (LM78 only) resets all registers */
lm78_reset(dev, 0);
} else {
else
dev->regs[0x49] = 0x40;
}
} else {
dev->regs[0x49] &= 0x01;
}
@@ -328,10 +324,9 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank)
if (!lm75)
continue;
if (dev->regs[0x4a] & (0x08 * (0x10 * i))) /* DIS_T2 and DIS_T3 bit disable those interfaces */
lm75->smbus_addr = 0x00;
lm75_remap(lm75, 0x80);
else
lm75->smbus_addr = (0x48 + ((dev->regs[0x4a] >> (i * 4)) & 0x7));
lm75_remap(lm75);
lm75_remap(lm75, 0x48 + ((dev->regs[0x4a] >> (i * 4)) & 0x7));
}
}
break;
@@ -428,7 +423,7 @@ lm78_reset(lm78_t *dev, uint8_t initialization)
dev->regs[0x49] = 0x40;
}
lm78_remap(dev);
lm78_remap(dev, dev->smbus_addr);
}

View File

@@ -102,9 +102,9 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv)
switch (addr - dev->io_base) {
case 0x00:
/* some status bits are reset by writing 1 to them */
for (smbus_addr = 0x02; smbus_addr <= 0x10; smbus_addr = smbus_addr << 1) {
for (smbus_addr = 0x02; smbus_addr <= 0x10; smbus_addr <<= 1) {
if (val & smbus_addr)
dev->stat = dev->stat & ~smbus_addr;
dev->stat &= ~smbus_addr;
}
break;
case 0x02:
@@ -150,7 +150,7 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv)
dev->data0 = (temp & 0xFF);
dev->data1 = (temp >> 8);
} else {
temp = (dev->data1 << 8) | dev->data0;
temp = ((dev->data1 << 8) | dev->data0);
smbus_write_word_cmd(smbus_addr, dev->cmd, temp);
}
dev->next_stat = 0x2;
@@ -216,7 +216,7 @@ smbus_piix4_remap(smbus_piix4_t *dev, uint16_t new_io_base, uint8_t enable)
dev->io_base = new_io_base;
smbus_piix4_log("SMBus PIIX4: remap to %04Xh\n", dev->io_base);
if (enable && (dev->io_base != 0x0000))
if ((enable) && (dev->io_base != 0x0000))
io_sethandler(dev->io_base, 0x10, smbus_piix4_read, NULL, NULL, smbus_piix4_write, NULL, NULL, dev);
}

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;
@@ -1902,7 +1905,8 @@ void
fdc_sector_finishcompare(fdc_t *fdc, int satisfying)
{
fdc->stat = 0x10;
fdc->satisfying_sectors++;
if (satisfying)
fdc->satisfying_sectors++;
fdc->inread = 0;
fdc_callback(fdc);
}

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

@@ -103,10 +103,6 @@ enum {
/* 1 11 01 ??? */
STATE_0D_SPIN_TO_INDEX = 0xE8, /* FORMAT TRACK */
STATE_0D_FORMAT_TRACK,
/* 1 11 11 ??? */
STATE_0D_NOP_SPIN_TO_INDEX = 0xF8, /* FORMAT TRACK */
STATE_0D_NOP_FORMAT_TRACK
};
enum {
@@ -138,9 +134,9 @@ typedef struct {
} sliding_buffer_t;
typedef struct {
uint32_t sync_marks;
uint32_t bits_obtained;
uint32_t bytes_obtained;
uint16_t bytes_obtained;
uint16_t sync_marks;
uint32_t sync_pos;
} find_t;
@@ -181,47 +177,35 @@ typedef struct {
*/
typedef struct {
FILE *f;
uint16_t version;
uint16_t disk_flags;
int32_t extra_bit_cells[2];
uint8_t state, fill, sector_count, format_state,
error_condition, id_found;
uint16_t version, disk_flags, satisfying_bytes, turbo_pos;
uint16_t cur_track;
uint16_t track_encoded_data[2][53048];
uint16_t *track_surface_data[2];
uint16_t thin_track_encoded_data[2][2][53048];
uint16_t *thin_track_surface_data[2][2];
uint16_t side_flags[2];
uint16_t preceding_bit[2];
uint16_t current_byte[2];
uint16_t current_bit[2];
uint16_t last_word[2];
#ifdef D86F_COMPRESS
int is_compressed;
#endif
int32_t extra_bit_cells[2];
uint32_t file_size, index_count, track_pos, datac,
id_pos, dma_over;
uint32_t index_hole_pos[2];
uint32_t track_offset[512];
uint32_t file_size;
sector_id_t last_sector;
sector_id_t req_sector;
uint32_t index_count;
uint8_t state;
uint8_t fill;
uint32_t track_pos;
uint32_t datac;
uint32_t id_pos;
uint16_t last_word[2];
find_t id_find;
find_t data_find;
crc_t calc_crc;
crc_t track_crc;
uint8_t sector_count;
uint8_t format_state;
uint16_t satisfying_bytes;
uint16_t preceding_bit[2];
uint16_t current_byte[2];
uint16_t current_bit[2];
int cur_track;
uint32_t error_condition;
#ifdef D86F_COMPRESS
int is_compressed;
#endif
int id_found;
wchar_t original_file_name[2048];
uint8_t *filebuf;
uint8_t *outbuf;
uint32_t dma_over;
int turbo_pos;
uint8_t *filebuf, *outbuf;
sector_t *last_side_sector[2];
} d86f_t;
@@ -833,16 +817,14 @@ uint32_t
d86f_get_data_len(int drive)
{
d86f_t *dev = d86f[drive];
uint32_t i, ret = 128;
if (dev->req_sector.id.n) {
if (dev->req_sector.id.n == 8) return 32768;
return (128 << ((uint32_t) dev->req_sector.id.n));
} else {
if (fdc_get_dtl(d86f_fdc) < 128)
return fdc_get_dtl(d86f_fdc);
else
return (128 << ((uint32_t) dev->req_sector.id.n));
}
if (dev->req_sector.id.n)
ret = (uint32_t)128 << dev->req_sector.id.n;
else if ((i = fdc_get_dtl(d86f_fdc)) < 128)
ret = i;
return ret;
}
@@ -973,7 +955,8 @@ d86f_encode_byte(int drive, int sync, decoded_t b, decoded_t prev_b)
uint8_t bits3210 = b.nibbles.nibble0;
uint16_t encoded_7654, encoded_3210, result;
if (encoding > 1) return 0xff;
if (encoding > 1)
return 0xffff;
if (sync) {
result = d86f_encode_get_data(b.byte);
@@ -1475,7 +1458,7 @@ d86f_read_sector_id(int drive, int side, int match)
} else {
/* CRC is valid. */
dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = 0;
dev->id_found++;
dev->id_found |= 1;
if ((dev->last_sector.dword == dev->req_sector.dword) || !match) {
d86f_handler[drive].set_sector(drive, side, dev->last_sector.id.c, dev->last_sector.id.h, dev->last_sector.id.r, dev->last_sector.id.n);
if (dev->state == STATE_02_READ_ID) {
@@ -1729,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;
}
@@ -1780,7 +1762,7 @@ d86f_spin_to_index(int drive, int side)
d86f_advance_bit(drive, side);
if (dev->track_pos == d86f_handler[drive].index_hole_pos(drive, side)) {
if ((dev->state == STATE_0D_SPIN_TO_INDEX) || (dev->state == STATE_0D_NOP_SPIN_TO_INDEX)) {
if (dev->state == STATE_0D_SPIN_TO_INDEX) {
/* When starting format, reset format state to the beginning. */
dev->preceding_bit[side] = 1;
dev->format_state = FMT_PRETRK_GAP0;
@@ -2100,22 +2082,6 @@ d86f_format_track(int drive, int side, int do_write)
}
void
d86f_format_track_normal(int drive, int side)
{
d86f_t *dev = d86f[drive];
d86f_format_track(drive, side, (dev->version == D86FVER));
}
void
d86f_format_track_nop(int drive, int side)
{
d86f_format_track(drive, side, 0);
}
void
d86f_initialize_last_sector_id(int drive, int c, int h, int r, int n)
{
@@ -2317,7 +2283,6 @@ d86f_turbo_poll(int drive, int side)
switch(dev->state) {
case STATE_0D_SPIN_TO_INDEX:
case STATE_0D_NOP_SPIN_TO_INDEX:
dev->sector_count = 0;
dev->datac = 5;
/*FALLTHROUGH*/
@@ -2412,11 +2377,7 @@ d86f_turbo_poll(int drive, int side)
break;
case STATE_0D_FORMAT_TRACK:
d86f_turbo_format(drive, side, 0);
return;
case STATE_0D_NOP_FORMAT_TRACK:
d86f_turbo_format(drive, side, 1);
d86f_turbo_format(drive, side, (side && (d86f_get_sides(drive) != 2)));
return;
case STATE_IDLE:
@@ -2460,7 +2421,6 @@ d86f_poll(int drive)
switch(dev->state) {
case STATE_02_SPIN_TO_INDEX:
case STATE_0D_SPIN_TO_INDEX:
case STATE_0D_NOP_SPIN_TO_INDEX:
d86f_spin_to_index(drive, side);
return;
@@ -2547,12 +2507,7 @@ d86f_poll(int drive)
case STATE_0D_FORMAT_TRACK:
if (! (dev->track_pos & 15))
d86f_format_track_normal(drive, side);
return;
case STATE_0D_NOP_FORMAT_TRACK:
if (! (dev->track_pos & 15))
d86f_format_track_nop(drive, side);
d86f_format_track(drive, side, (!side || (d86f_get_sides(drive) == 2)) && (dev->version == D86FVER));
return;
case STATE_IDLE:
@@ -2962,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) {
@@ -3059,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);
}
@@ -3099,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)) {
@@ -3432,10 +3387,7 @@ d86f_common_format(int drive, int side, int rate, uint8_t fill, int proxy)
dev->index_count = dev->error_condition = dev->satisfying_bytes = dev->sector_count = 0;
dev->dma_over = 0;
if (!side || (d86f_get_sides(drive) == 2))
dev->state = STATE_0D_SPIN_TO_INDEX;
else
dev->state = STATE_0D_NOP_SPIN_TO_INDEX;
dev->state = STATE_0D_SPIN_TO_INDEX;
}

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,11 @@ extern const device_t slc90e66_device;
extern const device_t ioapic_device;
/* OPTi */
extern const device_t opti283_device;
extern const device_t opti493_device;
extern const device_t opti495_device;
extern const device_t opti802g_device;
extern const device_t opti895_device;
extern const device_t opti5x7_device;
/* C&T */
@@ -77,6 +78,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

@@ -43,7 +43,7 @@ typedef struct {
extern void hwm_set_values(hwm_values_t new_values);
extern hwm_values_t* hwm_get_values();
extern void lm75_remap(lm75_t *dev);
extern void lm75_remap(lm75_t *dev, uint8_t addr);
extern uint8_t lm75_read(lm75_t *dev, uint8_t reg);
extern uint8_t lm75_write(lm75_t *dev, uint8_t reg, uint8_t val);
@@ -56,5 +56,8 @@ extern const device_t w83781d_device;
extern const device_t as99127f_device;
extern const device_t as99127f_rev2_device;
extern const device_t gl518sm_2c_device;
extern const device_t gl518sm_2d_device;
#endif /*EMU_HWM_H*/

View File

@@ -252,6 +252,8 @@ extern int machine_at_asus386_init(const machine_t *);
extern int machine_at_ecs386_init(const machine_t *);
extern int machine_at_micronics386_init(const machine_t *);
extern int machine_at_rycleopardlx_init(const machine_t *);
extern int machine_at_pb410a_init(const machine_t *);
extern int machine_at_acera1g_init(const machine_t *);
@@ -262,6 +264,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 +304,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

@@ -100,10 +100,8 @@ typedef struct _spd_sdram_ {
} spd_sdram_t;
extern spd_t *spd_devices[SPD_MAX_SLOTS];
extern void spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size);
extern void spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit);
#endif /*EMU_SPD_H*/

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

@@ -102,6 +102,25 @@ machine_at_ecs386_init(const machine_t *model)
return ret;
}
int
machine_at_rycleopardlx_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/rycleopardlx/486-RYC-Leopard-LX.BIN",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&opti283_device);
device_add(&keyboard_at_ami_device);
device_add(&fdc_at_device);
return ret;
}
int
machine_at_pb410a_init(const machine_t *model)
@@ -272,6 +291,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 +424,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 +443,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 +471,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 +497,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

@@ -365,13 +365,30 @@ machine_at_ax6bc_init(const machine_t *model)
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add(&keyboard_ps2_pci_device);
device_add(&w83977tf_device);
device_add(&sst_flash_29ee020_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
hwm_values_t machine_hwm = {
{ /* fan speeds */
3000, /* System */
3000 /* CPU */
}, { /* temperatures */
30 /* CPU */
}, { /* voltages */
2050, /* VCORE (2.05V by default) */
RESISTOR_DIVIDER(12000, 150, 47), /* +12V (15K/4.7K divider suggested in the GL518SM datasheet) */
3300 /* +3.3V */
}
};
if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUM2)
machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Klamath */
hwm_set_values(machine_hwm);
device_add(&gl518sm_2d_device);
return ret;
}

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);
@@ -983,6 +981,7 @@ machine_at_ficva502_init(const machine_t *model)
device_add(&keyboard_ps2_pci_device);
device_add(&fdc37c669_device);
device_add(&sst_flash_29ee010_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 256);
return ret;
}
@@ -1013,6 +1012,7 @@ machine_at_ficpa2012_init(const machine_t *model)
device_add(&keyboard_ps2_pci_device);
device_add(&w83877f_device);
device_add(&sst_flash_39sf010_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 512);
return ret;
}

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

@@ -67,7 +67,7 @@ machine_at_ax59pro_init(const machine_t *model)
device_add(&keyboard_ps2_pci_device);
device_add(&w83877tf_device);
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0xF, 256);
spd_register(SPD_TYPE_SDRAM, 0x7, 512);
return ret;
}
@@ -90,7 +90,7 @@ machine_at_mvp3_init(const machine_t *model)
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0a, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
device_add(&via_mvp3_device);
@@ -98,6 +98,7 @@ machine_at_mvp3_init(const machine_t *model)
device_add(&keyboard_ps2_pci_device);
device_add(&w83877tf_device);
device_add(&sst_flash_39sf010_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 512);
return ret;
}

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

@@ -197,9 +197,11 @@ const machine_t machines[] = {
{ "[ACC 2168] Packard Bell PB410A", "pb410a", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 4, 36, 1, 127, machine_at_pb410a_init, NULL },
/* 486 machines */
{ "[OPTi 283] RYC Leopard LX", "rycleopardlx", MACHINE_TYPE_486, {{"IBM", cpus_IBM486SLC}, {"", NULL}, {"", NULL},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 16, 1, 127, machine_at_rycleopardlx_init, NULL },
{ "[OPTi 495] Award 486 clone", "award486", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL },
{ "[OPTi 495] MR 486 clone", "mr486", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL },
{ "[OPTi 495] Dataexpert SX495 (486)", "ami486", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL },
{ "[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 +223,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 +237,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 */
@@ -297,12 +303,12 @@ const machine_t machines[] = {
{ "[VIA VPX] FIC VA-502", "ficva502", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_ficva502_init, NULL },
/* Apollo VP3 */
{ "[VIA VP3] FIC PA-2012", "ficpa2012", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_ficpa2012_init, NULL },
{ "[VIA VP3] FIC PA-2012", "ficpa2012", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_ficpa2012_init, NULL },
/* Super Socket 7 machines */
/* Apollo MVP3 */
{ "[VIA MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_ax59pro_init, NULL },
{ "[VIA MVP3] FIC VA-503+", "ficva503p", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_mvp3_init, NULL },
{ "[VIA MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_ax59pro_init, NULL },
{ "[VIA MVP3] FIC VA-503+", "ficva503p", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_mvp3_init, NULL },
/* Socket 8 machines */
/* 440FX */
@@ -348,13 +354,13 @@ const machine_t machines[] = {
/* 440BX */
{ "[i440BX] ASUS CUBX", "cubx", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_cubx_init, NULL },
{ "[i440BX] A-Trend ATC7020BXII", "atc7020bxii", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_atc7020bxii_init, NULL },
{ "[i440BX] AmazePC AM-BX133", "ambx133", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_ambx133_init, NULL },
{ "[i440BX] AmazePC AM-BX133", "ambx133", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_ambx133_init, NULL },
/* 440ZX */
{ "[i440ZX] Soltek SL-63A1", "63a", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_63a_init, NULL },
/* VIA Apollo Pro */
{ "[VIA Apollo Pro] PC Partner APAS3", "apas3", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_apas3_init, NULL },
{ "[VIA Apollo Pro] PC Partner APAS3", "apas3", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_apas3_init, NULL },
{ NULL, NULL, MACHINE_TYPE_NONE, {{"", 0}, {"", 0}, {"", 0}, {"", 0}, {"", 0}}, 0, 0, 0, 0, 0, NULL, NULL }
};

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

@@ -26,12 +26,14 @@
#include <86box/smbus.h>
#include <86box/spd.h>
#include <86box/version.h>
#include <86box/machine.h>
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define SPD_ROLLUP(x) ((x) >= 16 ? ((x) - 15) : (x))
int spd_present = 0;
spd_t *spd_devices[SPD_MAX_SLOTS];
uint8_t spd_data[SPD_MAX_SLOTS][SPD_DATA_SIZE];
@@ -117,6 +119,8 @@ spd_close(void *priv)
spd_write_byte, NULL, NULL, NULL,
dev);
spd_present = 0;
free(dev);
}
@@ -133,6 +137,8 @@ spd_init(const device_t *info)
spd_write_byte, NULL, NULL, NULL,
dev);
spd_present = 1;
return dev;
}
@@ -157,41 +163,13 @@ comp_ui16_rev(const void *elem1, const void *elem2)
void
spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size)
spd_populate(uint16_t *vslots, uint8_t slot_count, uint16_t total_size, uint16_t min_module_size, uint16_t max_module_size, uint8_t enable_asym)
{
uint8_t slot, slot_count, vslot, next_empty_vslot, i, split;
uint16_t min_module_size, total_size, vslots[SPD_MAX_SLOTS], asym;
device_t *info;
spd_edo_t *edo_data;
spd_sdram_t *sdram_data;
/* determine the minimum module size for this RAM type */
switch (ram_type) {
case SPD_TYPE_FPM:
case SPD_TYPE_EDO:
min_module_size = SPD_MIN_SIZE_EDO;
break;
case SPD_TYPE_SDRAM:
min_module_size = SPD_MIN_SIZE_SDRAM;
break;
default:
spd_log("SPD: unknown RAM type 0x%02X\n", ram_type);
return;
}
/* count how many (real) slots are enabled */
slot_count = 0;
for (slot = 0; slot < SPD_MAX_SLOTS; slot++) {
vslots[slot] = 0;
if (slot_mask & (1 << slot)) {
slot_count++;
}
}
uint8_t vslot, next_empty_vslot, split, i;
uint16_t asym;
/* populate vslots with modules in power-of-2 capacities */
total_size = (mem_size >> 10);
memset(vslots, 0x00, SPD_MAX_SLOTS << 1);
for (vslot = 0; vslot < slot_count && total_size; vslot++) {
/* populate slot */
vslots[vslot] = (1 << log2_ui16(MIN(total_size, max_module_size)));
@@ -206,15 +184,17 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size)
/* did we populate all the RAM? */
if (total_size) {
/* work backwards to add the missing RAM as asymmetric modules */
vslot = slot_count - 1;
do {
asym = (1 << log2_ui16(MIN(total_size, vslots[vslot])));
if (vslots[vslot] + asym <= max_module_size) {
vslots[vslot] += asym;
total_size -= asym;
}
} while (vslot-- > 0 && total_size);
/* work backwards to add the missing RAM as asymmetric modules if possible */
if (enable_asym) {
vslot = slot_count - 1;
do {
asym = (1 << log2_ui16(MIN(total_size, vslots[vslot])));
if (vslots[vslot] + asym <= max_module_size) {
vslots[vslot] += asym;
total_size -= asym;
}
} while ((vslot-- > 0) && total_size);
}
if (total_size) /* still not enough */
spd_log("SPD: not enough RAM slots (%d) to cover memory (%d MB short)\n", slot_count, total_size);
@@ -242,12 +222,52 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size)
spd_log("SPD: splitting vslot %d (%d MB) into %d and %d (%d MB each)\n", vslot, vslots[vslot], vslot, next_empty_vslot, (vslots[vslot] >> 1));
vslots[vslot] = vslots[next_empty_vslot] = (vslots[vslot] >> 1);
split = 1;
break;
}
/* re-sort vslots by descending capacity if any modules were split */
/* sort vslots by descending capacity if any were split */
if (split)
qsort(vslots, slot_count, sizeof(uint16_t), comp_ui16_rev);
}
}
void
spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size)
{
uint8_t slot, slot_count, vslot, i;
uint16_t min_module_size, vslots[SPD_MAX_SLOTS], asym;
device_t *info;
spd_edo_t *edo_data;
spd_sdram_t *sdram_data;
/* determine the minimum module size for this RAM type */
switch (ram_type) {
case SPD_TYPE_FPM:
case SPD_TYPE_EDO:
min_module_size = SPD_MIN_SIZE_EDO;
break;
case SPD_TYPE_SDRAM:
min_module_size = SPD_MIN_SIZE_SDRAM;
break;
default:
spd_log("SPD: unknown RAM type 0x%02X\n", ram_type);
return;
}
/* count how many (real) slots are enabled */
slot_count = 0;
for (slot = 0; slot < SPD_MAX_SLOTS; slot++) {
vslots[slot] = 0;
if (slot_mask & (1 << slot)) {
slot_count++;
}
}
/* populate vslots */
spd_populate(vslots, slot_count, (mem_size >> 10), min_module_size, max_module_size, 1);
/* register SPD devices and populate their data according to the vslots */
vslot = 0;
@@ -382,3 +402,59 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size)
vslot++;
}
}
void
spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit)
{
uint8_t row, dimm, drb, apollo = 0;
uint16_t size, vslots[SPD_MAX_SLOTS];
/* Special case for VIA Apollo Pro family, which jumps from 5F to 56. */
if (reg_max < reg_min) {
apollo = reg_max;
reg_max = reg_min + 7;
}
/* No SPD: split SIMMs into pairs as if they were "DIMM"s. */
if (!spd_present) {
dimm = ((reg_max - reg_min) + 1) >> 1; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */
spd_populate(vslots, dimm, (mem_size >> 10), drb_unit, 1 << (log2_ui16(machines[machine].max_ram / dimm)), 0);
}
/* Write DRBs for each row. */
spd_log("Writing DRBs... regs=[%02X:%02X] unit=%d\n", reg_min, reg_max, drb_unit);
for (row = 0; row <= (reg_max - reg_min); row++) {
dimm = (row >> 1);
size = 0;
if (spd_present) {
/* SPD enabled: use SPD info for this slot, if present. */
if (spd_devices[dimm]) {
if (spd_devices[dimm]->row1 < drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */
size = ((row & 1) ? 0 : drb_unit);
else
size = ((row & 1) ? spd_devices[dimm]->row2 : spd_devices[dimm]->row1);
}
} else {
/* No SPD: use the values calculated above. */
size = (vslots[dimm] >> 1);
}
/* Determine the DRB register to write. */
drb = reg_min + row;
if ((apollo) && ((drb & 0xf) < 0xa))
drb = apollo + (drb & 0xf);
/* Write DRB register, adding the previous DRB's value. */
if (row == 0)
regs[drb] = 0;
else if ((apollo) && (drb == apollo))
regs[drb] = regs[drb | 0xf]; /* 5F comes before 56 */
else
regs[drb] = regs[drb - 1];
if (size)
regs[drb] += (size / drb_unit); /* this will intentionally overflow on 440GX with 2 GB */
spd_log("DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[drb]);
}
}

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

@@ -702,7 +702,7 @@ gd54xx_in(uint16_t addr, void *p)
case 0x17:
ret = svga->gdcreg[0x17] & ~(7 << 3);
if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) {
if (svga->crtc[0x27] == CIRRUS_ID_CLGD5428) {
if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5428) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5426)) {
if (gd54xx->vlb)
ret |= (CL_GD5428_SYSTEM_BUS_VESA << 3);
else if (gd54xx->mca)
@@ -3023,9 +3023,9 @@ static void
#endif
case CIRRUS_ID_CLGD5426:
if (info->local & 0x200) {
if (info->local & 0x200)
romfn = NULL;
} else
else
romfn = BIOS_GD5426_PATH;
break;
@@ -3082,15 +3082,18 @@ static void
vram = 1;
gd54xx->vram_size = 1 << 20;
} else {
if (id >= CIRRUS_ID_CLGD5420)
vram = device_get_config_int("memory");
else
vram = 0;
if (id >= CIRRUS_ID_CLGD5420) {
if ((id == CIRRUS_ID_CLGD5426) && (info->local & 0x200))
vram = 1;
else
vram = device_get_config_int("memory");
} else
vram = 0;
if (vram)
gd54xx->vram_size = vram << 20;
gd54xx->vram_size = vram << 20;
else
gd54xx->vram_size = 1 << 19;
gd54xx->vram_size = 1 << 19;
}
gd54xx->vram_mask = gd54xx->vram_size - 1;
@@ -3556,7 +3559,7 @@ const device_t gd5426_onboard_device =
NULL,
gd54xx_speed_changed,
gd54xx_force_redraw,
gd5428_config
NULL
};
const device_t gd5428_isa_device =

View File

@@ -8,8 +8,6 @@
*
* Application resource script for Windows.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
* David Hrdlička, <hrdlickadavid@outlook.com>
@@ -164,7 +162,7 @@ BEGIN
#endif
POPUP "&Help"
BEGIN
MENUITEM "&About " EMU_NAME "...", IDM_ABOUT
MENUITEM "&About 86Box...", IDM_ABOUT
END
END
@@ -319,7 +317,7 @@ END
DLG_CONFIG DIALOG DISCARDABLE 0, 0, 366, 251
STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION EMU_NAME " Settings"
CAPTION "86Box Settings"
FONT 9, "Segoe UI"
BEGIN
DEFPUSHBUTTON "OK",IDOK,246,230,50,14
@@ -878,7 +876,7 @@ END
STRINGTABLE DISCARDABLE
BEGIN
2048 EMU_NAME
2048 "86Box"
IDS_2049 "Error"
IDS_2050 "Fatal error"
IDS_2051 "Are you sure you want to save the settings?"
@@ -886,7 +884,7 @@ BEGIN
IDS_2053 "Speed"
IDS_2054 "ZIP %03i %i (%s): %ls"
IDS_2055 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0"
IDS_2056 EMU_NAME " could not find any usable ROM images.\n\nPlease download a ROM set from <a href=""" EMU_ROMS_URL """>" EMU_ROMS_URL "</a> and extract it into the ""roms"" directory."
IDS_2056 "86Box could not find any usable ROM images.\n\nPlease <a href=""https://github.com/86Box/roms/releases/latest"">download</a> a ROM set and extract it into the ""roms"" directory."
IDS_2057 "(empty)"
IDS_2058 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0All files (*.*)\0*.*\0"
IDS_2059 "Turbo"
@@ -951,19 +949,19 @@ BEGIN
IDS_2110 "Unable to initialize FreeType"
IDS_2111 "Unable to initialize SDL, SDL2.dll is required"
IDS_2112 "Are you sure you want to hard reset the emulated machine?"
IDS_2113 "Are you sure you want to exit " EMU_NAME "?"
IDS_2113 "Are you sure you want to exit 86Box?"
IDS_2114 "Unable to initialize Ghostscript"
IDS_2115 "MO %i (%03i): %ls"
IDS_2116 "MO images (*.IM?)\0*.IM?\0All files (*.*)\0*.*\0"
IDS_2117 "Welcome to " EMU_NAME "!"
IDS_2117 "Welcome to 86Box!"
IDS_2118 "Internal controller"
IDS_2119 "Exit"
IDS_2120 "No ROMs found"
IDS_2121 "Save changes\nThis will hard reset the emulated machine."
IDS_2122 "Discard changes\nAll changes made to the settings will be lost."
IDS_2123 "Cancel\nGo back to the Settings window."
IDS_2124 "About " EMU_NAME
IDS_2125 EMU_NAME " v" EMU_VERSION
IDS_2124 "About 86Box"
IDS_2125 "86Box v2.10"
IDS_2126 "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information."
IDS_2127 "OK"
IDS_2128 "Hardware not available"
@@ -1104,9 +1102,9 @@ BEGIN
VALUE "FileDescription", EMU_NAME "\0"
VALUE "FileVersion", EMU_VERSION "\0"
VALUE "InternalName", EMU_NAME "\0"
VALUE "LegalCopyright", "Copyright © 2007-" COPYRIGHT_YEAR " " EMU_NAME " contributors\0"
VALUE "OriginalFilename", EMU_NAME ".exe\0"
VALUE "ProductName", EMU_NAME " Emulator\0"
VALUE "LegalCopyright", "Copyright © 2007-2020 " EMU_NAME " contributors\0"
VALUE "OriginalFilename", "86box.exe\0"
VALUE "ProductName", EMU_NAME "\0"
VALUE "ProductVersion", EMU_VERSION "\0"
END
END

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,10 +569,10 @@ CPUOBJ := cpu.o cpu_table.o \
x86seg.o x87.o x87_timings.o \
$(DYNARECOBJ)
CHIPSETOBJ := acc2168.o acer_m3a.o cs8230.o ali1429.o headland.o i82335.o \
CHIPSETOBJ := acc2168.o cs8230.o ali1429.o headland.o i82335.o \
intel_420ex.o intel_4x0.o intel_sio.o intel_piix.o ioapic.o \
neat.o opti495.o opti5x7.o scamp.o scat.o \
sis_85c310.o sis_85c471.o sis_85c496.o \
neat.o opti495.o opti895.o opti5x7.o scamp.o scat.o \
sis_85c310.o sis_85c471.o sis_85c496.o opti283.o \
via_apollo.o via_vpx.o via_vt82c586b.o via_vt82c596b.o wd76c10.o vl82c480.o \
amd640.o
@@ -582,7 +592,7 @@ MCHOBJ := machine.o machine_table.o \
m_at_socket4_5.o m_at_socket7_s7.o m_at_sockets7.o \
m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o
DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o serial.o \
DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o serial.o \
smbus.o smbus_piix4.o \
keyboard.o \
keyboard_xt.o keyboard_at.o \
@@ -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