mirror of
https://github.com/86Box/86Box.git
synced 2026-02-23 18:08:20 -07:00
Merge branch 'master' of github.com:86Box/86Box into tc1995
This commit is contained in:
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -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!
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -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
38
.github/workflows/c-cpp.yml
vendored
Normal 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
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -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;
|
||||
|
||||
@@ -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
175
src/chipset/opti283.c
Normal 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
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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
296
src/chipset/opti895.c
Normal 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
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
278
src/device/hwm_gl518sm.c
Normal 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
|
||||
};
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
52
src/dma.c
52
src/dma.c
@@ -485,9 +485,9 @@ dma_write(uint16_t addr, uint8_t val, void *priv)
|
||||
case 6: /*Address registers*/
|
||||
dma_wp[0] ^= 1;
|
||||
if (dma_wp[0])
|
||||
dma[channel].ab = (dma[channel].ab & 0xffff00) | val;
|
||||
dma[channel].ab = (dma[channel].ab & 0xffffff00 & dma_mask) | val;
|
||||
else
|
||||
dma[channel].ab = (dma[channel].ab & 0xff00ff) | (val << 8);
|
||||
dma[channel].ab = (dma[channel].ab & 0xffff00ff & dma_mask) | (val << 8);
|
||||
dma[channel].ac = dma[channel].ab;
|
||||
return;
|
||||
|
||||
@@ -778,14 +778,14 @@ dma16_write(uint16_t addr, uint8_t val, void *priv)
|
||||
dma_wp[1] ^= 1;
|
||||
if (dma_ps2.is_ps2) {
|
||||
if (dma_wp[1])
|
||||
dma[channel].ab = (dma[channel].ab & 0xffff00) | val;
|
||||
dma[channel].ab = (dma[channel].ab & 0xffffff00 & dma_mask) | val;
|
||||
else
|
||||
dma[channel].ab = (dma[channel].ab & 0xff00ff) | (val << 8);
|
||||
dma[channel].ab = (dma[channel].ab & 0xffff00ff & dma_mask) | (val << 8);
|
||||
} else {
|
||||
if (dma_wp[1])
|
||||
dma[channel].ab = (dma[channel].ab & 0xfffe00) | (val << 1);
|
||||
dma[channel].ab = (dma[channel].ab & 0xfffffe00 & dma_mask) | (val << 1);
|
||||
else
|
||||
dma[channel].ab = (dma[channel].ab & 0xfe01ff) | (val << 9);
|
||||
dma[channel].ab = (dma[channel].ab & 0xfffe01ff & dma_mask) | (val << 9);
|
||||
}
|
||||
dma[channel].ac = dma[channel].ab;
|
||||
return;
|
||||
@@ -878,12 +878,12 @@ dma_page_write(uint16_t addr, uint8_t val, void *priv)
|
||||
|
||||
if (addr > 4) {
|
||||
dma[addr].page = val & 0xfe;
|
||||
dma[addr].ab = (dma[addr].ab & 0x1ffff) | (dma[addr].page << 16);
|
||||
dma[addr].ac = (dma[addr].ac & 0x1ffff) | (dma[addr].page << 16);
|
||||
dma[addr].ab = (dma[addr].ab & 0xff01ffff & dma_mask) | (dma[addr].page << 16);
|
||||
dma[addr].ac = (dma[addr].ac & 0xff01ffff & dma_mask) | (dma[addr].page << 16);
|
||||
} else {
|
||||
dma[addr].page = (AT) ? val : val & 0xf;
|
||||
dma[addr].ab = (dma[addr].ab & 0xffff) | (dma[addr].page << 16);
|
||||
dma[addr].ac = (dma[addr].ac & 0xffff) | (dma[addr].page << 16);
|
||||
dma[addr].ab = (dma[addr].ab & 0xff00ffff & dma_mask) | (dma[addr].page << 16);
|
||||
dma[addr].ac = (dma[addr].ac & 0xff00ffff & dma_mask) | (dma[addr].page << 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -959,6 +959,20 @@ dma_set_params(uint8_t advanced, uint32_t mask)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dma_set_mask(uint32_t mask)
|
||||
{
|
||||
int i;
|
||||
|
||||
dma_mask = mask;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
dma[i].ab &= mask;
|
||||
dma[i].ac &= mask;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dma_reset(void)
|
||||
{
|
||||
@@ -1355,14 +1369,14 @@ dma_channel_read(int channel)
|
||||
else if (dma_advanced)
|
||||
dma_retreat(dma_c);
|
||||
else
|
||||
dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac - 1) & 0xffff);
|
||||
dma_c->ac = (dma_c->ac & 0xffff0000 & dma_mask) | ((dma_c->ac - 1) & 0xffff);
|
||||
} else {
|
||||
if (dma_ps2.is_ps2)
|
||||
dma_c->ac++;
|
||||
else if (dma_advanced)
|
||||
dma_advance(dma_c);
|
||||
else
|
||||
dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac + 1) & 0xffff);
|
||||
dma_c->ac = (dma_c->ac & 0xffff0000 & dma_mask) | ((dma_c->ac + 1) & 0xffff);
|
||||
}
|
||||
} else {
|
||||
temp = _dma_readw(dma_c->ac, dma_c);
|
||||
@@ -1373,14 +1387,14 @@ dma_channel_read(int channel)
|
||||
else if (dma_advanced)
|
||||
dma_retreat(dma_c);
|
||||
else
|
||||
dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac - 2) & 0x1ffff);
|
||||
dma_c->ac = (dma_c->ac & 0xfffe0000 & dma_mask) | ((dma_c->ac - 2) & 0x1ffff);
|
||||
} else {
|
||||
if (dma_ps2.is_ps2)
|
||||
dma_c->ac += 2;
|
||||
else if (dma_advanced)
|
||||
dma_advance(dma_c);
|
||||
else
|
||||
dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac + 2) & 0x1ffff);
|
||||
dma_c->ac = (dma_c->ac & 0xfffe0000 & dma_mask) | ((dma_c->ac + 2) & 0x1ffff);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1443,14 +1457,14 @@ dma_channel_write(int channel, uint16_t val)
|
||||
else if (dma_advanced)
|
||||
dma_retreat(dma_c);
|
||||
else
|
||||
dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac - 1) & 0xffff);
|
||||
dma_c->ac = (dma_c->ac & 0xffff0000 & dma_mask) | ((dma_c->ac - 1) & 0xffff);
|
||||
} else {
|
||||
if (dma_ps2.is_ps2)
|
||||
dma_c->ac++;
|
||||
else if (dma_advanced)
|
||||
dma_advance(dma_c);
|
||||
else
|
||||
dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac + 1) & 0xffff);
|
||||
dma_c->ac = (dma_c->ac & 0xffff0000 & dma_mask) | ((dma_c->ac + 1) & 0xffff);
|
||||
}
|
||||
} else {
|
||||
_dma_writew(dma_c->ac, val, dma_c);
|
||||
@@ -1461,15 +1475,15 @@ dma_channel_write(int channel, uint16_t val)
|
||||
else if (dma_advanced)
|
||||
dma_retreat(dma_c);
|
||||
else
|
||||
dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac - 2) & 0x1ffff);
|
||||
dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac - 2) & 0x1ffff);
|
||||
dma_c->ac = (dma_c->ac & 0xfffe0000 & dma_mask) | ((dma_c->ac - 2) & 0x1ffff);
|
||||
dma_c->ac = (dma_c->ac & 0xfffe0000 & dma_mask) | ((dma_c->ac - 2) & 0x1ffff);
|
||||
} else {
|
||||
if (dma_ps2.is_ps2)
|
||||
dma_c->ac += 2;
|
||||
else if (dma_advanced)
|
||||
dma_advance(dma_c);
|
||||
else
|
||||
dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac + 2) & 0x1ffff);
|
||||
dma_c->ac = (dma_c->ac & 0xfffe0000 & dma_mask) | ((dma_c->ac + 2) & 0x1ffff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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*/
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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*/
|
||||
|
||||
13
src/io.c
13
src/io.c
@@ -367,7 +367,7 @@ inw(uint16_t port)
|
||||
ret8[0] = ret & 0xff;
|
||||
ret8[1] = (ret >> 8) & 0xff;
|
||||
for (i = 0; i < 2; i++) {
|
||||
p = io[port + i];
|
||||
p = io[(port + i) & 0xffff];
|
||||
while(p) {
|
||||
if (p->inb && !p->inw) {
|
||||
ret8[i] &= p->inb(port + i, p->priv);
|
||||
@@ -414,7 +414,7 @@ outw(uint16_t port, uint16_t val)
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
p = io[port + i];
|
||||
p = io[(port + i) & 0xffff];
|
||||
while(p) {
|
||||
if (p->outb && !p->outw) {
|
||||
p->outb(port + i, val >> (i << 3), p->priv);
|
||||
@@ -463,7 +463,7 @@ inl(uint16_t port)
|
||||
ret16[0] = ret & 0xffff;
|
||||
ret16[1] = (ret >> 16) & 0xffff;
|
||||
for (i = 0; i < 4; i += 2) {
|
||||
p = io[port + i];
|
||||
p = io[(port + i) & 0xffff];
|
||||
while(p) {
|
||||
if (p->inw && !p->inl) {
|
||||
ret16[i >> 1] &= p->inw(port + i, p->priv);
|
||||
@@ -480,7 +480,7 @@ inl(uint16_t port)
|
||||
ret8[2] = (ret >> 16) & 0xff;
|
||||
ret8[3] = (ret >> 24) & 0xff;
|
||||
for (i = 0; i < 4; i++) {
|
||||
p = io[port + i];
|
||||
p = io[(port + i) & 0xffff];
|
||||
while(p) {
|
||||
if (p->inb && !p->inw && !p->inl) {
|
||||
ret8[i] &= p->inb(port + i, p->priv);
|
||||
@@ -523,14 +523,13 @@ outl(uint16_t port, uint32_t val)
|
||||
p->outl(port, val, p->priv);
|
||||
found |= 4;
|
||||
qfound++;
|
||||
// return;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i += 2) {
|
||||
p = io[port + i];
|
||||
p = io[(port + i) & 0xffff];
|
||||
while(p) {
|
||||
if (p->outw && !p->outl) {
|
||||
p->outw(port + i, val >> (i << 3), p->priv);
|
||||
@@ -542,7 +541,7 @@ outl(uint16_t port, uint32_t val)
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
p = io[port + i];
|
||||
p = io[(port + i) & 0xffff];
|
||||
while(p) {
|
||||
if (p->outb && !p->outw && !p->outl) {
|
||||
p->outb(port + i, val >> (i << 3), p->priv);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 }
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
160
src/mem/spd.c
160
src/mem/spd.c
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(). */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -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);
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user