Merge branch 'master' of https://github.com/86Box/86Box
This commit is contained in:
@@ -321,7 +321,7 @@ ali6117_init(const device_t *info)
|
||||
ali6117_setup(dev);
|
||||
ali6117_reset(dev);
|
||||
|
||||
pci_elcr_io_disable();
|
||||
pic_elcr_io_handler(0);
|
||||
refresh_at_enable = 0;
|
||||
|
||||
return dev;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <86box/apm.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/pit.h>
|
||||
@@ -48,6 +49,8 @@ typedef struct
|
||||
uint16_t timer_base,
|
||||
timer_latch;
|
||||
|
||||
smram_t *smram;
|
||||
|
||||
double fast_off_period;
|
||||
|
||||
pc_timer_t timer, fast_off_timer;
|
||||
@@ -98,25 +101,11 @@ i420ex_map(uint32_t addr, uint32_t size, int state)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i420ex_smram_map(int smm, uint32_t addr, uint32_t size, int is_smram)
|
||||
{
|
||||
mem_set_mem_state_smram(smm, addr, size, is_smram);
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i420ex_smram_handler_phase0(void)
|
||||
{
|
||||
/* Disable low extended SMRAM. */
|
||||
if (smram[0].size != 0x00000000) {
|
||||
i420ex_smram_map(0, smram[0].host_base, smram[0].size, 0);
|
||||
i420ex_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]);
|
||||
}
|
||||
smram_disable_all();
|
||||
}
|
||||
|
||||
|
||||
@@ -125,58 +114,43 @@ i420ex_smram_handler_phase1(i420ex_t *dev)
|
||||
{
|
||||
uint8_t *regs = (uint8_t *) dev->regs;
|
||||
|
||||
uint32_t base = 0x000a0000;
|
||||
uint32_t host_base = 0x000a0000, ram_base = 0x000a0000;
|
||||
uint32_t size = 0x00010000;
|
||||
|
||||
switch (regs[0x70] & 0x07) {
|
||||
case 0: case 1:
|
||||
default:
|
||||
base = size = 0x00000000;
|
||||
host_base = ram_base = 0x00000000;
|
||||
size = 0x00000000;
|
||||
break;
|
||||
case 2:
|
||||
base = 0x000a0000;
|
||||
smram[0].host_base = 0x000a0000;
|
||||
smram[0].ram_base = 0x000a0000;
|
||||
host_base = 0x000a0000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 3:
|
||||
base = 0x000b0000;
|
||||
smram[0].host_base = 0x000b0000;
|
||||
smram[0].ram_base = 0x000b0000;
|
||||
host_base = 0x000b0000;
|
||||
ram_base = 0x000b0000;
|
||||
break;
|
||||
case 4:
|
||||
base = 0x000c0000;
|
||||
smram[0].host_base = 0x000c0000;
|
||||
smram[0].ram_base = 0x000a0000;
|
||||
host_base = 0x000c0000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 5:
|
||||
base = 0x000d0000;
|
||||
smram[0].host_base = 0x000d0000;
|
||||
smram[0].ram_base = 0x000a0000;
|
||||
host_base = 0x000d0000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 6:
|
||||
base = 0x000e0000;
|
||||
smram[0].host_base = 0x000e0000;
|
||||
smram[0].ram_base = 0x000a0000;
|
||||
host_base = 0x000e0000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 7:
|
||||
base = 0x000f0000;
|
||||
smram[0].host_base = 0x000f0000;
|
||||
smram[0].ram_base = 0x000a0000;
|
||||
host_base = 0x000f0000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
}
|
||||
|
||||
smram[0].size = size;
|
||||
|
||||
if (size != 0x00000000) {
|
||||
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);
|
||||
|
||||
/* If OSS = 1 and LSS = 0, extended SMRAM is visible outside SMM. */
|
||||
i420ex_smram_map(0, base, size, (regs[0x70] & 0x70) == 0x40);
|
||||
|
||||
/* If the register is set accordingly, disable the mapping also in SMM. */
|
||||
i420ex_smram_map(1, base, size, !(regs[0x70] & 0x20));
|
||||
}
|
||||
smram_enable(dev->smram, host_base, ram_base, size,
|
||||
(regs[0x70] & 0x70) == 0x40, !(regs[0x70] & 0x20));
|
||||
}
|
||||
|
||||
|
||||
@@ -496,6 +470,8 @@ i420ex_close(void *p)
|
||||
{
|
||||
i420ex_t *dev = (i420ex_t *)p;
|
||||
|
||||
smram_del(dev->smram);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
@@ -528,6 +504,8 @@ i420ex_init(const device_t *info)
|
||||
i420ex_t *dev = (i420ex_t *) malloc(sizeof(i420ex_t));
|
||||
memset(dev, 0, sizeof(i420ex_t));
|
||||
|
||||
dev->smram = smram_add();
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, i420ex_read, i420ex_write, dev);
|
||||
|
||||
dev->id = info->local;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/mem.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/device.h>
|
||||
@@ -57,6 +58,7 @@ typedef struct
|
||||
drb_unit, drb_default;
|
||||
uint8_t regs[256], regs_locked[256];
|
||||
int type;
|
||||
smram_t *smram_low, *smram_high;
|
||||
} i4x0_t;
|
||||
|
||||
|
||||
@@ -101,36 +103,18 @@ i4x0_map(uint32_t addr, uint32_t size, int state)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i4x0_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
|
||||
i4x0_smram_handler_phase0(i4x0_t *dev)
|
||||
{
|
||||
uint32_t tom = (mem_size << 10);
|
||||
|
||||
/* Disable any active mappings. */
|
||||
if (smram[0].size != 0x00000000) {
|
||||
i4x0_smram_map(0, smram[0].host_base, smram[0].size, 0);
|
||||
i4x0_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 ((dev->type >= INTEL_440BX) && (smram[1].size != 0x00000000)) {
|
||||
i4x0_smram_map(1, smram[1].host_base, smram[1].size, 0);
|
||||
|
||||
if ((dev->type >= INTEL_440BX) && smram_enabled(dev->smram_high)) {
|
||||
tom -= (1 << 20);
|
||||
mem_set_mem_state_smm(tom, (1 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
|
||||
memset(&smram[1], 0x00, sizeof(smram_t));
|
||||
mem_mapping_disable(&ram_smram_mapping[1]);
|
||||
}
|
||||
|
||||
/* Disable any active mappings. */
|
||||
smram_disable_all();
|
||||
}
|
||||
|
||||
|
||||
@@ -158,20 +142,9 @@ i4x0_smram_handler_phase1(i4x0_t *dev)
|
||||
}
|
||||
}
|
||||
|
||||
if (((regs[0x72] & 0x70) == 0x40) || ((regs[0x72] & 0x08) && !(regs[0x72] & 0x20))) {
|
||||
smram[0].host_base = base[0];
|
||||
smram[0].ram_base = base[0] & 0x000f0000;
|
||||
smram[0].size = size[0];
|
||||
|
||||
mem_mapping_set_addr(&ram_smram_mapping[0], smram[0].host_base, size[0]);
|
||||
mem_mapping_set_exec(&ram_smram_mapping[0], ram + smram[0].ram_base);
|
||||
|
||||
/* If D_OPEN = 1 and D_LCK = 0, extended SMRAM is visible outside SMM. */
|
||||
i4x0_smram_map(0, base[0], size[0], ((regs[0x72] & 0x70) == 0x40));
|
||||
|
||||
/* If the register is set accordingly, disable the mapping also in SMM. */
|
||||
i4x0_smram_map(1, base[0], size[0], ((regs[0x72] & 0x08) && !(regs[0x72] & 0x20)));
|
||||
}
|
||||
if (((regs[0x72] & 0x70) == 0x40) || ((regs[0x72] & 0x08) && !(regs[0x72] & 0x20)))
|
||||
smram_enable(dev->smram_low, base[0], base[0] & 0x000f0000, size[0],
|
||||
((regs[0x72] & 0x70) == 0x40), ((regs[0x72] & 0x08) && !(regs[0x72] & 0x20)));
|
||||
|
||||
/* TSEG mapping. */
|
||||
if (dev->type >= INTEL_440BX) {
|
||||
@@ -183,18 +156,10 @@ i4x0_smram_handler_phase1(i4x0_t *dev)
|
||||
base[1] = size[1] = 0x00000000;
|
||||
|
||||
if (size[1] != 0x00000000) {
|
||||
smram[1].host_base = base[1] + (1 << 28);
|
||||
smram[1].ram_base = base[1];
|
||||
smram[1].size = size[1];
|
||||
|
||||
mem_mapping_set_addr(&ram_smram_mapping[1], smram[1].host_base, smram[1].size);
|
||||
if (smram[1].ram_base < (1 << 30))
|
||||
mem_mapping_set_exec(&ram_smram_mapping[1], ram + smram[1].ram_base);
|
||||
else
|
||||
mem_mapping_set_exec(&ram_smram_mapping[1], ram2 + smram[1].ram_base - (1 << 30));
|
||||
smram_enable(dev->smram_high, base[1] + (1 << 28), base[1], size[1],
|
||||
0, 1);
|
||||
|
||||
mem_set_mem_state_smm(base[1], size[1], MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
i4x0_smram_map(1, smram[1].host_base, size[1], 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -220,18 +185,8 @@ i4x0_smram_handler_phase1(i4x0_t *dev)
|
||||
}
|
||||
|
||||
if (((((regs[0x72] & 0x38) == 0x20) || s) || (!(regs[0x72] & 0x10) || s)) && (size[0] != 0x00000000)) {
|
||||
smram[0].host_base = base[0];
|
||||
smram[0].ram_base = base[0];
|
||||
smram[0].size = size[0];
|
||||
|
||||
mem_mapping_set_addr(&ram_smram_mapping[0], smram[0].host_base, size[0]);
|
||||
mem_mapping_set_exec(&ram_smram_mapping[0], ram + smram[0].ram_base);
|
||||
|
||||
/* If OSS = 1 and LSS = 0, extended SMRAM is visible outside SMM. */
|
||||
i4x0_smram_map(0, base[0], size[0], (((regs[0x72] & 0x38) == 0x20) || s));
|
||||
|
||||
/* If the register is set accordingly, disable the mapping also in SMM. */
|
||||
i4x0_smram_map(0, base[0], size[0], (!(regs[0x72] & 0x10) || s));
|
||||
smram_enable(dev->smram_low, base[0], base[0], size[0],
|
||||
(((regs[0x72] & 0x38) == 0x20) || s), (!(regs[0x72] & 0x10) || s));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1306,9 +1261,12 @@ i4x0_reset(void *priv)
|
||||
static void
|
||||
i4x0_close(void *p)
|
||||
{
|
||||
i4x0_t *i4x0 = (i4x0_t *)p;
|
||||
i4x0_t *dev = (i4x0_t *)p;
|
||||
|
||||
free(i4x0);
|
||||
smram_del(dev->smram_high);
|
||||
smram_del(dev->smram_low);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -1320,6 +1278,9 @@ static void
|
||||
|
||||
memset(dev, 0, sizeof(i4x0_t));
|
||||
|
||||
dev->smram_low = smram_add();
|
||||
dev->smram_high = smram_add();
|
||||
|
||||
dev->type = info->local & 0xff;
|
||||
|
||||
regs = (uint8_t *) dev->regs;
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <86box/device.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/port_92.h>
|
||||
@@ -41,6 +42,8 @@ typedef struct
|
||||
uint8_t idx, forced_green,
|
||||
regs[256],
|
||||
scratch[2];
|
||||
|
||||
smram_t *smram;
|
||||
} opti895_t;
|
||||
|
||||
|
||||
@@ -123,13 +126,6 @@ opti895_recalc(opti895_t *dev)
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -164,7 +160,7 @@ opti895_write(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0x24:
|
||||
opti895_smram_map(0, smram[0].host_base, smram[0].size, !!(val & 0x80));
|
||||
smram_state_change(dev->smram, 0, !!(val & 0x80));
|
||||
break;
|
||||
|
||||
case 0xe0:
|
||||
@@ -225,6 +221,8 @@ opti895_close(void *priv)
|
||||
{
|
||||
opti895_t *dev = (opti895_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
@@ -262,15 +260,9 @@ opti895_init(const device_t *info)
|
||||
|
||||
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;
|
||||
dev->smram = smram_add();
|
||||
|
||||
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);
|
||||
smram_enable(dev->smram, 0x00030000, 0x000b0000, 0x00010000, 0, 1);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
@@ -1541,7 +1541,7 @@ scat_init(const device_t *info)
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
mem_mapping_add(&dev->high_mapping[i], (i << 14) + 0xfc0000, 0x04000,
|
||||
mem_read_bios, mem_read_biosw, mem_read_biosl,
|
||||
bios_read, bios_readw, bios_readl,
|
||||
mem_write_null, mem_write_nullw, mem_write_nulll,
|
||||
rom + ((i << 14) & biosmask), 0, NULL);
|
||||
mem_mapping_enable(&dev->high_mapping[i]);
|
||||
@@ -1561,7 +1561,7 @@ scat_init(const device_t *info)
|
||||
|
||||
for (i = (dev->regs[SCAT_VERSION] < 4 ? 0 : 8); i < 16; i++) {
|
||||
mem_mapping_add(&dev->high_mapping[i], (i << 14) + 0xfc0000, 0x04000,
|
||||
mem_read_bios, mem_read_biosw, mem_read_biosl,
|
||||
bios_read, bios_readw, bios_readl,
|
||||
mem_write_null, mem_write_nullw, mem_write_nulll,
|
||||
rom + ((i << 14) & biosmask), 0, NULL);
|
||||
mem_mapping_enable(&dev->high_mapping[i]);
|
||||
|
||||
@@ -1,293 +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.
|
||||
*
|
||||
* Emulation of the SiS 85c471 chip.
|
||||
*
|
||||
* SiS sis85c471 Super I/O Chip
|
||||
* Used by DTK PKM-0038S E-2
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: 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 "cpu.h"
|
||||
#include <86box/mem.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/lpt.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/serial.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t cur_reg,
|
||||
regs[39],
|
||||
scratch[2];
|
||||
port_92_t * port_92;
|
||||
} sis_85c471_t;
|
||||
|
||||
|
||||
static void
|
||||
sis_85c471_recalcmapping(sis_85c471_t *dev)
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t i, shflags = 0;
|
||||
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 0;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
base = 0xc0000 + (i << 15);
|
||||
|
||||
if ((i > 5) || (dev->regs[0x02] & (1 << i))) {
|
||||
shadowbios |= (base >= 0xe0000) && (dev->regs[0x02] & 0x80);
|
||||
shadowbios_write |= (base >= 0xe0000) && !(dev->regs[0x02] & 0x40);
|
||||
shflags = (dev->regs[0x02] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
shflags |= (dev->regs[0x02] & 0x40) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL;
|
||||
mem_set_mem_state(base, 0x8000, shflags);
|
||||
} else
|
||||
mem_set_mem_state(base, 0x8000, MEM_READ_EXTANY | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c471_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
sis_85c471_t *dev = (sis_85c471_t *) priv;
|
||||
uint8_t valxor = 0x00;
|
||||
|
||||
if (port == 0x22) {
|
||||
if ((val >= 0x50) && (val <= 0x76))
|
||||
dev->cur_reg = val;
|
||||
return;
|
||||
} else if (port == 0x23) {
|
||||
if ((dev->cur_reg < 0x50) || (dev->cur_reg > 0x76))
|
||||
return;
|
||||
valxor = val ^ dev->regs[dev->cur_reg - 0x50];
|
||||
dev->regs[dev->cur_reg - 0x50] = val;
|
||||
} else if ((port == 0xe1) || (port == 0xe2)) {
|
||||
dev->scratch[port - 0xe1] = val;
|
||||
return;
|
||||
}
|
||||
|
||||
switch(dev->cur_reg) {
|
||||
case 0x51:
|
||||
cpu_cache_ext_enabled = ((val & 0x84) == 0x84);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x52:
|
||||
sis_85c471_recalcmapping(dev);
|
||||
break;
|
||||
|
||||
case 0x57:
|
||||
if (valxor & 0x12)
|
||||
port_92_set_features(dev->port_92, !!(val & 0x10), !!(val & 0x02));
|
||||
|
||||
if (valxor & 0x08) {
|
||||
if (val & 0x08)
|
||||
port_92_set_period(dev->port_92, 6ULL * TIMER_USEC);
|
||||
else
|
||||
port_92_set_period(dev->port_92, 2ULL * TIMER_USEC);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x5b:
|
||||
if (valxor & 0x02) {
|
||||
if (val & 0x02)
|
||||
mem_remap_top(0);
|
||||
else
|
||||
mem_remap_top(256);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x63:
|
||||
if (valxor & 0x10) {
|
||||
if (dev->regs[0x13] & 0x10)
|
||||
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 0x72:
|
||||
if (valxor & 0x01) {
|
||||
port_92_remove(dev->port_92);
|
||||
if (val & 0x01)
|
||||
port_92_add(dev->port_92);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
dev->cur_reg = 0;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sis_85c471_read(uint16_t port, void *priv)
|
||||
{
|
||||
sis_85c471_t *dev = (sis_85c471_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (port == 0x22)
|
||||
ret = dev->cur_reg;
|
||||
else if (port == 0x23) {
|
||||
if ((dev->cur_reg >= 0x50) && (dev->cur_reg <= 0x76)) {
|
||||
ret = dev->regs[dev->cur_reg - 0x50];
|
||||
if (dev->cur_reg == 0x58)
|
||||
ret &= 0xf7;
|
||||
dev->cur_reg = 0;
|
||||
}
|
||||
} else if ((port == 0xe1) || (port == 0xe2))
|
||||
ret = dev->scratch[port - 0xe1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c471_close(void *priv)
|
||||
{
|
||||
sis_85c471_t *dev = (sis_85c471_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
sis_85c471_init(const device_t *info)
|
||||
{
|
||||
int mem_size_mb, i = 0;
|
||||
|
||||
sis_85c471_t *dev = (sis_85c471_t *) malloc(sizeof(sis_85c471_t));
|
||||
memset(dev, 0, sizeof(sis_85c471_t));
|
||||
|
||||
dev->cur_reg = 0;
|
||||
for (i = 0; i < 0x27; i++)
|
||||
dev->regs[i] = 0x00;
|
||||
|
||||
dev->regs[9] = 0x40;
|
||||
|
||||
mem_size_mb = mem_size >> 10;
|
||||
switch (mem_size_mb) {
|
||||
case 0: case 1:
|
||||
dev->regs[9] |= 0;
|
||||
break;
|
||||
case 2: case 3:
|
||||
dev->regs[9] |= 1;
|
||||
break;
|
||||
case 4:
|
||||
dev->regs[9] |= 2;
|
||||
break;
|
||||
case 5:
|
||||
dev->regs[9] |= 0x20;
|
||||
break;
|
||||
case 6: case 7:
|
||||
dev->regs[9] |= 9;
|
||||
break;
|
||||
case 8: case 9:
|
||||
dev->regs[9] |= 4;
|
||||
break;
|
||||
case 10: case 11:
|
||||
dev->regs[9] |= 5;
|
||||
break;
|
||||
case 12: case 13: case 14: case 15:
|
||||
dev->regs[9] |= 0xB;
|
||||
break;
|
||||
case 16:
|
||||
dev->regs[9] |= 0x13;
|
||||
break;
|
||||
case 17:
|
||||
dev->regs[9] |= 0x21;
|
||||
break;
|
||||
case 18: case 19:
|
||||
dev->regs[9] |= 6;
|
||||
break;
|
||||
case 20: case 21: case 22: case 23:
|
||||
dev->regs[9] |= 0xD;
|
||||
break;
|
||||
case 24: case 25: case 26: case 27:
|
||||
case 28: case 29: case 30: case 31:
|
||||
dev->regs[9] |= 0xE;
|
||||
break;
|
||||
case 32: case 33: case 34: case 35:
|
||||
dev->regs[9] |= 0x1B;
|
||||
break;
|
||||
case 36: case 37: case 38: case 39:
|
||||
dev->regs[9] |= 0xF;
|
||||
break;
|
||||
case 40: case 41: case 42: case 43:
|
||||
case 44: case 45: case 46: case 47:
|
||||
dev->regs[9] |= 0x17;
|
||||
break;
|
||||
case 48:
|
||||
dev->regs[9] |= 0x1E;
|
||||
break;
|
||||
default:
|
||||
if (mem_size_mb < 64)
|
||||
dev->regs[9] |= 0x1E;
|
||||
else if ((mem_size_mb >= 65) && (mem_size_mb < 68))
|
||||
dev->regs[9] |= 0x22;
|
||||
else
|
||||
dev->regs[9] |= 0x24;
|
||||
break;
|
||||
}
|
||||
|
||||
dev->regs[0x11] = 9;
|
||||
dev->regs[0x12] = 0xFF;
|
||||
dev->regs[0x1f] = 0x20; /* Video access enabled. */
|
||||
dev->regs[0x23] = 0xF0;
|
||||
dev->regs[0x26] = 1;
|
||||
|
||||
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed < 25000000)
|
||||
dev->regs[0x08] |= 0x80;
|
||||
|
||||
io_sethandler(0x0022, 0x0002,
|
||||
sis_85c471_read, NULL, NULL, sis_85c471_write, NULL, NULL, dev);
|
||||
|
||||
dev->scratch[0] = dev->scratch[1] = 0xff;
|
||||
|
||||
io_sethandler(0x00e1, 0x0002,
|
||||
sis_85c471_read, NULL, NULL, sis_85c471_write, NULL, NULL, dev);
|
||||
|
||||
dev->port_92 = device_add(&port_92_device);
|
||||
port_92_set_period(dev->port_92, 2ULL * TIMER_USEC);
|
||||
port_92_set_features(dev->port_92, 0, 0);
|
||||
|
||||
sis_85c471_recalcmapping(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
const device_t sis_85c471_device = {
|
||||
"SiS 85c471",
|
||||
0,
|
||||
0,
|
||||
sis_85c471_init, sis_85c471_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/mem.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/pci.h>
|
||||
@@ -45,6 +46,7 @@ typedef struct sis_85c496_t
|
||||
uint8_t cur_reg, rmsmiblk_count,
|
||||
regs[127],
|
||||
pci_conf[256];
|
||||
smram_t *smram;
|
||||
pc_timer_t rmsmiblk_timer;
|
||||
port_92_t * port_92;
|
||||
nvr_t * nvr;
|
||||
@@ -185,14 +187,6 @@ sis_85c496_ide_handler(sis_85c496_t *dev)
|
||||
}
|
||||
|
||||
|
||||
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_85c49x_pci_write(int func, int addr, uint8_t val, void *priv)
|
||||
@@ -200,6 +194,7 @@ sis_85c49x_pci_write(int func, int addr, uint8_t val, void *priv)
|
||||
sis_85c496_t *dev = (sis_85c496_t *) priv;
|
||||
uint8_t old, valxor;
|
||||
uint8_t smm_irq[4] = { 10, 11, 12, 15 };
|
||||
uint32_t host_base, ram_base, size;
|
||||
|
||||
old = dev->pci_conf[addr];
|
||||
valxor = (dev->pci_conf[addr]) ^ val;
|
||||
@@ -299,40 +294,33 @@ sis_85c49x_pci_write(int func, int addr, uint8_t val, void *priv)
|
||||
if (valxor & 0x3e) {
|
||||
unmask_a20_in_smm = !!(val & 0x20);
|
||||
|
||||
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]);
|
||||
}
|
||||
smram_disable_all();
|
||||
|
||||
if (val & 0x06) {
|
||||
smram[0].size = 0x00010000;
|
||||
host_base = 0x00060000;
|
||||
ram_base = 0x000a0000;
|
||||
size = 0x00010000;
|
||||
switch ((val >> 3) & 0x03) {
|
||||
case 0x00:
|
||||
smram[0].host_base = 0x00060000;
|
||||
smram[0].ram_base = 0x000a0000;
|
||||
host_base = 0x00060000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 0x01:
|
||||
smram[0].host_base = 0x00060000;
|
||||
smram[0].ram_base = 0x000b0000;
|
||||
host_base = 0x00060000;
|
||||
ram_base = 0x000b0000;
|
||||
break;
|
||||
case 0x02:
|
||||
smram[0].host_base = 0x000e0000;
|
||||
smram[0].ram_base = 0x000a0000;
|
||||
host_base = 0x000e0000;
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 0x03:
|
||||
smram[0].host_base = 0x000e0000;
|
||||
smram[0].ram_base = 0x000b0000;
|
||||
host_base = 0x000e0000;
|
||||
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));
|
||||
smram_enable(dev->smram, host_base, ram_base, size,
|
||||
((val & 0x06) == 0x06), (val & 0x02));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -562,9 +550,11 @@ sis_85c496_reset(void *priv)
|
||||
static void
|
||||
sis_85c496_close(void *p)
|
||||
{
|
||||
sis_85c496_t *sis_85c496 = (sis_85c496_t *)p;
|
||||
sis_85c496_t *dev = (sis_85c496_t *)p;
|
||||
|
||||
free(sis_85c496);
|
||||
smram_del(dev->smram);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -574,6 +564,8 @@ static void
|
||||
sis_85c496_t *dev = malloc(sizeof(sis_85c496_t));
|
||||
memset(dev, 0x00, sizeof(sis_85c496_t));
|
||||
|
||||
dev->smram = smram_add();
|
||||
|
||||
/* PCI Configuration Header Registers (00h ~ 3Fh) */
|
||||
dev->pci_conf[0x00] = 0x39; /* SiS */
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
|
||||
452
src/chipset/sis_85c4xx.c
Normal file
452
src/chipset/sis_85c4xx.c
Normal file
@@ -0,0 +1,452 @@
|
||||
/*
|
||||
* 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 SiS 85c401/85c402, 85c460, 85c461, and
|
||||
* 85c407/85c471 chipsets.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2019,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/timer.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t cur_reg, tries,
|
||||
reg_base, reg_last,
|
||||
is_471,
|
||||
regs[39], scratch[2];
|
||||
smram_t *smram;
|
||||
port_92_t *port_92;
|
||||
} sis_85c4xx_t;
|
||||
|
||||
|
||||
static void
|
||||
sis_85c4xx_recalcmapping(sis_85c4xx_t *dev)
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t i, shflags = 0;
|
||||
uint32_t readext, writeext;
|
||||
uint8_t romcs = 0xc0, cur_romcs;
|
||||
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 0;
|
||||
|
||||
if (dev->regs[0x03] & 0x40)
|
||||
romcs |= 0x01;
|
||||
if (dev->regs[0x03] & 0x80)
|
||||
romcs |= 0x30;
|
||||
if (dev->regs[0x08] & 0x04)
|
||||
romcs |= 0x02;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
base = 0xc0000 + (i << 15);
|
||||
cur_romcs = romcs & (1 << i);
|
||||
readext = cur_romcs ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
writeext = cur_romcs ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
|
||||
if ((i > 5) || (dev->regs[0x02] & (1 << i))) {
|
||||
shadowbios |= (base >= 0xe0000) && (dev->regs[0x02] & 0x80);
|
||||
shadowbios_write |= (base >= 0xe0000) && !(dev->regs[0x02] & 0x40);
|
||||
shflags = (dev->regs[0x02] & 0x80) ? MEM_READ_INTERNAL : readext;
|
||||
shflags |= (dev->regs[0x02] & 0x40) ? writeext : MEM_WRITE_INTERNAL;
|
||||
mem_set_mem_state(base, 0x8000, shflags);
|
||||
} else
|
||||
mem_set_mem_state(base, 0x8000, readext | writeext);
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c4xx_sw_smi_out(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
sis_85c4xx_t *dev = (sis_85c4xx_t *) priv;
|
||||
|
||||
if (dev->regs[0x18] & 0x02) {
|
||||
if (dev->regs[0x0b] & 0x10)
|
||||
smi_line = 1;
|
||||
else
|
||||
picint(1 << ((dev->regs[0x0b] & 0x08) ? 15 : 12));
|
||||
soft_reset_mask = 1;
|
||||
dev->regs[0x19] |= 0x02;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c4xx_sw_smi_handler(sis_85c4xx_t *dev)
|
||||
{
|
||||
uint16_t addr;
|
||||
|
||||
if (!dev->is_471)
|
||||
return;
|
||||
|
||||
addr = dev->regs[0x14] | (dev->regs[0x15] << 8);
|
||||
|
||||
io_handler((dev->regs[0x0b] & 0x80) && (dev->regs[0x18] & 0x02), addr, 0x0001,
|
||||
NULL, NULL, NULL, sis_85c4xx_sw_smi_out, NULL, NULL, dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c4xx_out(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
sis_85c4xx_t *dev = (sis_85c4xx_t *) priv;
|
||||
uint8_t rel_reg = dev->cur_reg - dev->reg_base;
|
||||
uint8_t valxor = 0x00;
|
||||
uint32_t host_base = 0x000e0000, ram_base = 0x000a0000;
|
||||
|
||||
switch (port) {
|
||||
case 0x22:
|
||||
dev->cur_reg = val;
|
||||
break;
|
||||
case 0x23:
|
||||
if ((dev->cur_reg >= dev->reg_base) && (dev->cur_reg <= dev->reg_last)) {
|
||||
valxor = val ^ dev->regs[rel_reg];
|
||||
if (rel_reg == 0x19)
|
||||
dev->regs[rel_reg] &= ~val;
|
||||
else
|
||||
dev->regs[rel_reg] = val;
|
||||
|
||||
switch (rel_reg) {
|
||||
case 0x01:
|
||||
cpu_cache_ext_enabled = ((val & 0x84) == 0x84);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x02: case 0x03:
|
||||
case 0x08:
|
||||
sis_85c4xx_recalcmapping(dev);
|
||||
break;
|
||||
|
||||
case 0x0b:
|
||||
sis_85c4xx_sw_smi_handler(dev);
|
||||
if (dev->is_471 && (valxor & 0x02)) {
|
||||
if (val & 0x02)
|
||||
mem_remap_top(0);
|
||||
else
|
||||
mem_remap_top(256);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x13:
|
||||
if (dev->is_471 && (valxor & 0xf0)) {
|
||||
smram_disable(dev->smram);
|
||||
host_base = (val & 0x80) ? 0x00060000 : 0x000e0000;
|
||||
switch ((val >> 5) & 0x03) {
|
||||
case 0x00:
|
||||
ram_base = 0x000a0000;
|
||||
break;
|
||||
case 0x01:
|
||||
ram_base = 0x000b0000;
|
||||
break;
|
||||
case 0x02:
|
||||
ram_base = (val & 0x80) ? 0x00000000 : 0x000e0000;
|
||||
break;
|
||||
default:
|
||||
ram_base = 0x00000000;
|
||||
break;
|
||||
}
|
||||
if (ram_base != 0x00000000)
|
||||
smram_enable(dev->smram, host_base, ram_base, 0x00010000, (val & 0x10), 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x14: case 0x15:
|
||||
case 0x18:
|
||||
sis_85c4xx_sw_smi_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x1c:
|
||||
if (dev->is_471)
|
||||
soft_reset_mask = 0;
|
||||
break;
|
||||
|
||||
case 0x22:
|
||||
if (dev->is_471 && (valxor & 0x01)) {
|
||||
port_92_remove(dev->port_92);
|
||||
if (val & 0x01)
|
||||
port_92_add(dev->port_92);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
dev->cur_reg = 0x00;
|
||||
break;
|
||||
|
||||
case 0xe1: case 0xe2:
|
||||
dev->scratch[port - 0xe1] = val;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sis_85c4xx_in(uint16_t port, void *priv)
|
||||
{
|
||||
sis_85c4xx_t *dev = (sis_85c4xx_t *) priv;
|
||||
uint8_t rel_reg = dev->cur_reg - dev->reg_base;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (port) {
|
||||
case 0x23:
|
||||
if (dev->is_471 && (dev->cur_reg == 0x1c))
|
||||
ret = inb(0x70);
|
||||
if ((dev->cur_reg >= dev->reg_base) && (dev->cur_reg <= dev->reg_last))
|
||||
ret = dev->regs[rel_reg];
|
||||
dev->cur_reg = 0x00;
|
||||
break;
|
||||
|
||||
case 0xe1: case 0xe2:
|
||||
ret = dev->scratch[port - 0xe1];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c4xx_close(void *priv)
|
||||
{
|
||||
sis_85c4xx_t *dev = (sis_85c4xx_t *) priv;
|
||||
|
||||
if (dev->is_471)
|
||||
smram_del(dev->smram);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
sis_85c4xx_init(const device_t *info)
|
||||
{
|
||||
int mem_size_mb;
|
||||
|
||||
sis_85c4xx_t *dev = (sis_85c4xx_t *) malloc(sizeof(sis_85c4xx_t));
|
||||
memset(dev, 0, sizeof(sis_85c4xx_t));
|
||||
|
||||
dev->is_471 = (info->local >> 8) & 0xff;
|
||||
|
||||
dev->reg_base = info->local & 0xff;
|
||||
|
||||
mem_size_mb = mem_size >> 10;
|
||||
|
||||
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed < 25000000)
|
||||
dev->regs[0x08] = 0x80;
|
||||
|
||||
if (dev->is_471) {
|
||||
dev->reg_last = dev->reg_base + 0x76;
|
||||
|
||||
dev->regs[0x09] = 0x40;
|
||||
switch (mem_size_mb) {
|
||||
case 0: case 1:
|
||||
dev->regs[0x09] |= 0x00;
|
||||
break;
|
||||
case 2: case 3:
|
||||
dev->regs[0x09] |= 0x01;
|
||||
break;
|
||||
case 4:
|
||||
dev->regs[0x09] |= 0x02;
|
||||
break;
|
||||
case 5:
|
||||
dev->regs[0x09] |= 0x20;
|
||||
break;
|
||||
case 6: case 7:
|
||||
dev->regs[0x09] |= 0x09;
|
||||
break;
|
||||
case 8: case 9:
|
||||
dev->regs[0x09] |= 0x04;
|
||||
break;
|
||||
case 10: case 11:
|
||||
dev->regs[0x09] |= 0x05;
|
||||
break;
|
||||
case 12: case 13: case 14: case 15:
|
||||
dev->regs[0x09] |= 0x0b;
|
||||
break;
|
||||
case 16:
|
||||
dev->regs[0x09] |= 0x13;
|
||||
break;
|
||||
case 17:
|
||||
dev->regs[0x09] |= 0x21;
|
||||
break;
|
||||
case 18: case 19:
|
||||
dev->regs[0x09] |= 0x06;
|
||||
break;
|
||||
case 20: case 21: case 22: case 23:
|
||||
dev->regs[0x09] |= 0x0d;
|
||||
break;
|
||||
case 24: case 25: case 26: case 27:
|
||||
case 28: case 29: case 30: case 31:
|
||||
dev->regs[0x09] |= 0x0e;
|
||||
break;
|
||||
case 32: case 33: case 34: case 35:
|
||||
dev->regs[0x09] |= 0x1b;
|
||||
break;
|
||||
case 36: case 37: case 38: case 39:
|
||||
dev->regs[0x09] |= 0x0f;
|
||||
break;
|
||||
case 40: case 41: case 42: case 43:
|
||||
case 44: case 45: case 46: case 47:
|
||||
dev->regs[0x09] |= 0x17;
|
||||
break;
|
||||
case 48:
|
||||
dev->regs[0x09] |= 0x1e;
|
||||
break;
|
||||
default:
|
||||
if (mem_size_mb < 64)
|
||||
dev->regs[0x09] |= 0x1e;
|
||||
else if ((mem_size_mb >= 65) && (mem_size_mb < 68))
|
||||
dev->regs[0x09] |= 0x22;
|
||||
else
|
||||
dev->regs[0x09] |= 0x24;
|
||||
break;
|
||||
}
|
||||
|
||||
dev->regs[0x11] = 0x09;
|
||||
dev->regs[0x12] = 0xff;
|
||||
dev->regs[0x1f] = 0x20; /* Video access enabled. */
|
||||
dev->regs[0x23] = 0xf0;
|
||||
dev->regs[0x26] = 0x01;
|
||||
|
||||
dev->smram = smram_add();
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x00010000, 0, 1);
|
||||
|
||||
dev->port_92 = device_add(&port_92_device);
|
||||
port_92_remove(dev->port_92);
|
||||
} else {
|
||||
dev->reg_last = dev->reg_base + 0x11;
|
||||
|
||||
switch (mem_size_mb) {
|
||||
case 1:
|
||||
default:
|
||||
dev->regs[0x00] = 0x00;
|
||||
break;
|
||||
case 2:
|
||||
dev->regs[0x00] = 0x01;
|
||||
break;
|
||||
case 4:
|
||||
dev->regs[0x00] = 0x02;
|
||||
break;
|
||||
case 6:
|
||||
dev->regs[0x00] = 0x03;
|
||||
break;
|
||||
case 8:
|
||||
dev->regs[0x00] = 0x04;
|
||||
break;
|
||||
case 10:
|
||||
dev->regs[0x00] = 0x05;
|
||||
break;
|
||||
case 12:
|
||||
dev->regs[0x00] = 0x0b;
|
||||
break;
|
||||
case 16:
|
||||
dev->regs[0x00] = 0x19;
|
||||
break;
|
||||
case 18:
|
||||
dev->regs[0x00] = 0x06;
|
||||
break;
|
||||
case 20:
|
||||
dev->regs[0x00] = 0x14;
|
||||
break;
|
||||
case 24:
|
||||
dev->regs[0x00] = 0x15;
|
||||
break;
|
||||
case 32:
|
||||
dev->regs[0x00] = 0x1b;
|
||||
break;
|
||||
case 36:
|
||||
dev->regs[0x00] = 0x16;
|
||||
break;
|
||||
case 40:
|
||||
dev->regs[0x00] = 0x17;
|
||||
break;
|
||||
case 48:
|
||||
dev->regs[0x00] = 0x1e;
|
||||
break;
|
||||
case 64:
|
||||
dev->regs[0x00] = 0x1f;
|
||||
break;
|
||||
}
|
||||
|
||||
dev->regs[0x11] = 0x01;
|
||||
}
|
||||
|
||||
io_sethandler(0x0022, 0x0002,
|
||||
sis_85c4xx_in, NULL, NULL, sis_85c4xx_out, NULL, NULL, dev);
|
||||
|
||||
dev->scratch[0] = dev->scratch[1] = 0xff;
|
||||
|
||||
io_sethandler(0x00e1, 0x0002,
|
||||
sis_85c4xx_in, NULL, NULL, sis_85c4xx_out, NULL, NULL, dev);
|
||||
|
||||
sis_85c4xx_recalcmapping(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
const device_t sis_85c401_device = {
|
||||
"SiS 85c401/85c402",
|
||||
0,
|
||||
0x060,
|
||||
sis_85c4xx_init, sis_85c4xx_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
const device_t sis_85c460_device = {
|
||||
"SiS 85c460",
|
||||
0,
|
||||
0x050,
|
||||
sis_85c4xx_init, sis_85c4xx_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* TODO: Log to make sure the registers are correct. */
|
||||
const device_t sis_85c461_device = {
|
||||
"SiS 85c461",
|
||||
0,
|
||||
0x050,
|
||||
sis_85c4xx_init, sis_85c4xx_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
const device_t sis_85c471_device = {
|
||||
"SiS 85c407/85c471",
|
||||
0,
|
||||
0x150,
|
||||
sis_85c4xx_init, sis_85c4xx_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -23,6 +23,7 @@
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/pci.h>
|
||||
@@ -67,6 +68,7 @@ typedef struct stpc_t
|
||||
|
||||
/* PCI devices */
|
||||
uint8_t pci_conf[4][256];
|
||||
smram_t *smram;
|
||||
usb_t *usb;
|
||||
int ide_slot;
|
||||
sff8038i_t *bm[2];
|
||||
@@ -155,13 +157,6 @@ stpc_recalcmapping(stpc_t *dev)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
stpc_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
|
||||
stpc_host_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
@@ -446,7 +441,7 @@ stpc_ide_read(int func, int addr, void *priv)
|
||||
uint8_t ret;
|
||||
|
||||
if (func > 0)
|
||||
ret = 0xff;
|
||||
ret = 0xff;
|
||||
else {
|
||||
ret = dev->pci_conf[2][addr];
|
||||
if (addr == 0x48) {
|
||||
@@ -467,8 +462,8 @@ stpc_isab_write(int func, int addr, uint8_t val, void *priv)
|
||||
stpc_t *dev = (stpc_t *) priv;
|
||||
|
||||
if (func == 1 && !(dev->local & STPC_IDE_ATLAS)) {
|
||||
stpc_ide_write(0, addr, val, priv);
|
||||
return;
|
||||
stpc_ide_write(0, addr, val, priv);
|
||||
return;
|
||||
}
|
||||
|
||||
stpc_log("STPC: isab_write(%d, %02X, %02X)\n", func, addr, val);
|
||||
@@ -498,11 +493,11 @@ stpc_isab_read(int func, int addr, void *priv)
|
||||
uint8_t ret;
|
||||
|
||||
if ((func == 1) && !(dev->local & STPC_IDE_ATLAS))
|
||||
ret = stpc_ide_read(0, addr, priv);
|
||||
ret = stpc_ide_read(0, addr, priv);
|
||||
else if (func > 0)
|
||||
ret = 0xff;
|
||||
ret = 0xff;
|
||||
else
|
||||
ret = dev->pci_conf[1][addr];
|
||||
ret = dev->pci_conf[1][addr];
|
||||
|
||||
stpc_log("STPC: isab_read(%d, %02X) = %02X\n", func, addr, ret);
|
||||
return ret;
|
||||
@@ -552,9 +547,9 @@ stpc_usb_read(int func, int addr, void *priv)
|
||||
uint8_t ret;
|
||||
|
||||
if (func > 0)
|
||||
ret = 0xff;
|
||||
ret = 0xff;
|
||||
else
|
||||
ret = dev->pci_conf[3][addr];
|
||||
ret = dev->pci_conf[3][addr];
|
||||
|
||||
stpc_log("STPC: usb_read(%d, %02X) = %02X\n", func, addr, ret);
|
||||
return ret;
|
||||
@@ -596,32 +591,32 @@ stpc_serial_handlers(uint8_t val)
|
||||
{
|
||||
stpc_serial_t *dev;
|
||||
if (!(dev = device_get_priv(&stpc_serial_device))) {
|
||||
stpc_log("STPC: Not remapping UARTs, disabled by strap (raw %02X)\n", val);
|
||||
return 0;
|
||||
stpc_log("STPC: Not remapping UARTs, disabled by strap (raw %02X)\n", val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t uart0_io = 0x3f8, uart0_irq = 4, uart1_io = 0x3f8, uart1_irq = 3;
|
||||
|
||||
if (val & 0x10)
|
||||
uart1_io -= 0x100;
|
||||
uart1_io -= 0x100;
|
||||
if (val & 0x20)
|
||||
uart1_io -= 0x10;
|
||||
if (val & 0x40)
|
||||
uart0_io -= 0x100;
|
||||
uart0_io -= 0x100;
|
||||
if (val & 0x80)
|
||||
uart0_io -= 0x10;
|
||||
|
||||
if (uart0_io == uart1_io) {
|
||||
/* Apply defaults if both UARTs are set to the same address. */
|
||||
stpc_log("STPC: Both UARTs set to %02X, resetting to defaults\n", uart0_io);
|
||||
uart0_io = 0x3f8;
|
||||
uart1_io = 0x2f8;
|
||||
/* Apply defaults if both UARTs are set to the same address. */
|
||||
stpc_log("STPC: Both UARTs set to %02X, resetting to defaults\n", uart0_io);
|
||||
uart0_io = 0x3f8;
|
||||
uart1_io = 0x2f8;
|
||||
}
|
||||
|
||||
if (uart0_io < 0x300) {
|
||||
/* The address for UART0 defines the IRQs for both ports. */
|
||||
uart0_irq = 3;
|
||||
uart1_irq = 4;
|
||||
/* The address for UART0 defines the IRQs for both ports. */
|
||||
uart0_irq = 3;
|
||||
uart1_irq = 4;
|
||||
}
|
||||
|
||||
stpc_log("STPC: Remapping UART0 to %04X %d and UART1 to %04X %d (raw %02X)\n", uart0_io, uart0_irq, uart1_io, uart1_irq, val);
|
||||
@@ -673,7 +668,7 @@ stpc_reg_write(uint16_t addr, uint8_t val, void *priv)
|
||||
case 0x25: case 0x26: case 0x27: case 0x28:
|
||||
if (dev->reg_offset == 0x28) {
|
||||
val &= 0xe3;
|
||||
stpc_smram_map(0, smram[0].host_base, smram[0].size, !!(val & 0x80));
|
||||
smram_state_change(dev->smram, 0, !!(val & 0x80));
|
||||
}
|
||||
dev->regs[dev->reg_offset] = val;
|
||||
stpc_recalcmapping(dev);
|
||||
@@ -694,7 +689,7 @@ stpc_reg_write(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0x56: case 0x57:
|
||||
elcr_write(dev->reg_offset, val, NULL);
|
||||
pic_elcr_write(dev->reg_offset, val, NULL);
|
||||
if (dev->reg_offset == 0x57)
|
||||
refresh_at_enable = (val & 0x01);
|
||||
break;
|
||||
@@ -719,10 +714,10 @@ stpc_reg_read(uint16_t addr, void *priv)
|
||||
if (addr == 0x22)
|
||||
ret = dev->reg_offset;
|
||||
else if (dev->reg_offset >= 0xc0)
|
||||
return 0xff; /* Cyrix CPU registers: let the CPU code handle these */
|
||||
return 0xff; /* Cyrix CPU registers: let the CPU code handle these */
|
||||
else if ((dev->reg_offset == 0x56) || (dev->reg_offset == 0x57)) {
|
||||
/* ELCR is in here, not in port 4D0h. */
|
||||
ret = elcr_read(dev->reg_offset, NULL);
|
||||
/* ELCR is in here, not in port 4D0h. */
|
||||
ret = pic_elcr_read(dev->reg_offset, NULL);
|
||||
if (dev->reg_offset == 0x57)
|
||||
ret |= (dev->regs[dev->reg_offset] & 0x01);
|
||||
} else
|
||||
@@ -743,9 +738,9 @@ stpc_reset(void *priv)
|
||||
memset(dev->regs, 0, sizeof(dev->regs));
|
||||
dev->regs[0x7b] = 0xff;
|
||||
if (device_get_priv(&stpc_lpt_device))
|
||||
dev->regs[0x4c] |= 0x80; /* LPT strap */
|
||||
dev->regs[0x4c] |= 0x80; /* LPT strap */
|
||||
if (stpc_serial_handlers(0x00))
|
||||
dev->regs[0x4c] |= 0x03; /* UART straps */
|
||||
dev->regs[0x4c] |= 0x03; /* UART straps */
|
||||
}
|
||||
|
||||
|
||||
@@ -830,11 +825,11 @@ stpc_setup(stpc_t *dev)
|
||||
}
|
||||
|
||||
if (dev->local & STPC_IDE_ATLAS) {
|
||||
dev->pci_conf[2][0x02] = 0x28;
|
||||
dev->pci_conf[2][0x03] = 0x02;
|
||||
dev->pci_conf[2][0x02] = 0x28;
|
||||
dev->pci_conf[2][0x03] = 0x02;
|
||||
} else {
|
||||
dev->pci_conf[2][0x02] = dev->pci_conf[1][0x02];
|
||||
dev->pci_conf[2][0x03] = dev->pci_conf[1][0x03];
|
||||
dev->pci_conf[2][0x02] = dev->pci_conf[1][0x02];
|
||||
dev->pci_conf[2][0x03] = dev->pci_conf[1][0x03];
|
||||
}
|
||||
|
||||
dev->pci_conf[2][0x06] = 0x80;
|
||||
@@ -866,22 +861,22 @@ stpc_setup(stpc_t *dev)
|
||||
|
||||
/* USB */
|
||||
if (dev->usb) {
|
||||
dev->pci_conf[3][0x00] = 0x4a;
|
||||
dev->pci_conf[3][0x01] = 0x10;
|
||||
dev->pci_conf[3][0x02] = 0x30;
|
||||
dev->pci_conf[3][0x03] = 0x02;
|
||||
dev->pci_conf[3][0x00] = 0x4a;
|
||||
dev->pci_conf[3][0x01] = 0x10;
|
||||
dev->pci_conf[3][0x02] = 0x30;
|
||||
dev->pci_conf[3][0x03] = 0x02;
|
||||
|
||||
dev->pci_conf[3][0x06] = 0x80;
|
||||
dev->pci_conf[3][0x07] = 0x02;
|
||||
dev->pci_conf[3][0x06] = 0x80;
|
||||
dev->pci_conf[3][0x07] = 0x02;
|
||||
|
||||
dev->pci_conf[3][0x09] = 0x10;
|
||||
dev->pci_conf[3][0x0a] = 0x03;
|
||||
dev->pci_conf[3][0x0b] = 0x0c;
|
||||
dev->pci_conf[3][0x09] = 0x10;
|
||||
dev->pci_conf[3][0x0a] = 0x03;
|
||||
dev->pci_conf[3][0x0b] = 0x0c;
|
||||
|
||||
/* NOTE: This is an erratum in the STPC Atlas programming manual, the programming manuals for the other
|
||||
STPC chipsets say 0x80, which is indeed multi-function (as the STPC Atlas programming manual
|
||||
indicates as well, and Windows 2000 also issues a 0x7B STOP error if it is 0x40. */
|
||||
dev->pci_conf[3][0x0e] = /*0x40*/ 0x80;
|
||||
dev->pci_conf[3][0x0e] = /*0x40*/ 0x80;
|
||||
}
|
||||
|
||||
/* PCI setup */
|
||||
@@ -899,8 +894,7 @@ stpc_close(void *priv)
|
||||
|
||||
stpc_log("STPC: close()\n");
|
||||
|
||||
io_removehandler(0x22, 2,
|
||||
stpc_reg_read, NULL, NULL, stpc_reg_write, NULL, NULL, dev);
|
||||
smram_del(dev->smram);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
@@ -919,10 +913,10 @@ stpc_init(const device_t *info)
|
||||
pci_add_card(0x0B, stpc_nb_read, stpc_nb_write, dev);
|
||||
dev->ide_slot = pci_add_card(0x0C, stpc_isab_read, stpc_isab_write, dev);
|
||||
if (dev->local & STPC_IDE_ATLAS)
|
||||
dev->ide_slot = pci_add_card(0x0D, stpc_ide_read, stpc_ide_write, dev);
|
||||
dev->ide_slot = pci_add_card(0x0D, stpc_ide_read, stpc_ide_write, dev);
|
||||
if (dev->local & STPC_USB) {
|
||||
dev->usb = device_add(&usb_device);
|
||||
pci_add_card(0x0E, stpc_usb_read, stpc_usb_write, dev);
|
||||
dev->usb = device_add(&usb_device);
|
||||
pci_add_card(0x0E, stpc_usb_read, stpc_usb_write, dev);
|
||||
}
|
||||
|
||||
dev->bm[0] = device_add_inst(&sff8038i_device, 1);
|
||||
@@ -937,19 +931,13 @@ stpc_init(const device_t *info)
|
||||
stpc_setup(dev);
|
||||
stpc_reset(dev);
|
||||
|
||||
smram[0].host_base = 0x000a0000;
|
||||
smram[0].ram_base = 0x000a0000;
|
||||
smram[0].size = 0x00020000;
|
||||
dev->smram = smram_add();
|
||||
|
||||
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);
|
||||
|
||||
stpc_smram_map(0, smram[0].host_base, smram[0].size, 0);
|
||||
stpc_smram_map(1, smram[0].host_base, smram[0].size, 1);
|
||||
smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x00020000, 0, 1);
|
||||
|
||||
device_add(&port_92_pci_device);
|
||||
|
||||
pci_elcr_io_disable();
|
||||
pic_elcr_io_handler(0);
|
||||
refresh_at_enable = 0;
|
||||
|
||||
return dev;
|
||||
@@ -990,38 +978,38 @@ stpc_lpt_handlers(stpc_lpt_t *dev, uint8_t val)
|
||||
uint8_t old_addr = (dev->reg1 & 0x03), new_addr = (val & 0x03);
|
||||
|
||||
switch (old_addr) {
|
||||
case 0x1:
|
||||
lpt3_remove();
|
||||
break;
|
||||
case 0x1:
|
||||
lpt3_remove();
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
lpt1_remove();
|
||||
break;
|
||||
case 0x2:
|
||||
lpt1_remove();
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
lpt2_remove();
|
||||
break;
|
||||
case 0x3:
|
||||
lpt2_remove();
|
||||
break;
|
||||
}
|
||||
|
||||
switch (new_addr) {
|
||||
case 0x1:
|
||||
stpc_log("STPC: Remapping parallel port to LPT3\n");
|
||||
lpt3_init(0x3bc);
|
||||
break;
|
||||
case 0x1:
|
||||
stpc_log("STPC: Remapping parallel port to LPT3\n");
|
||||
lpt3_init(0x3bc);
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
stpc_log("STPC: Remapping parallel port to LPT1\n");
|
||||
lpt1_init(0x378);
|
||||
break;
|
||||
case 0x2:
|
||||
stpc_log("STPC: Remapping parallel port to LPT1\n");
|
||||
lpt1_init(0x378);
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
stpc_log("STPC: Remapping parallel port to LPT2\n");
|
||||
lpt2_init(0x278);
|
||||
break;
|
||||
case 0x3:
|
||||
stpc_log("STPC: Remapping parallel port to LPT2\n");
|
||||
lpt2_init(0x278);
|
||||
break;
|
||||
|
||||
default:
|
||||
stpc_log("STPC: Disabling parallel port\n");
|
||||
break;
|
||||
default:
|
||||
stpc_log("STPC: Disabling parallel port\n");
|
||||
break;
|
||||
}
|
||||
|
||||
dev->reg1 = (val & 0x08);
|
||||
@@ -1036,22 +1024,22 @@ stpc_lpt_write(uint16_t addr, uint8_t val, void *priv)
|
||||
stpc_lpt_t *dev = (stpc_lpt_t *) priv;
|
||||
|
||||
if (dev->unlocked < 2) {
|
||||
/* Cheat a little bit: in reality, any write to any
|
||||
I/O port is supposed to reset the unlock counter. */
|
||||
if ((addr == 0x3f0) && (val == 0x55))
|
||||
dev->unlocked++;
|
||||
else
|
||||
dev->unlocked = 0;
|
||||
/* Cheat a little bit: in reality, any write to any
|
||||
I/O port is supposed to reset the unlock counter. */
|
||||
if ((addr == 0x3f0) && (val == 0x55))
|
||||
dev->unlocked++;
|
||||
else
|
||||
dev->unlocked = 0;
|
||||
} else if (addr == 0x3f0) {
|
||||
if (val == 0xaa)
|
||||
dev->unlocked = 0;
|
||||
else
|
||||
dev->offset = val;
|
||||
if (val == 0xaa)
|
||||
dev->unlocked = 0;
|
||||
else
|
||||
dev->offset = val;
|
||||
} else if (dev->offset == 1) {
|
||||
/* dev->reg1 is set by stpc_lpt_handlers */
|
||||
stpc_lpt_handlers(dev, val);
|
||||
/* dev->reg1 is set by stpc_lpt_handlers */
|
||||
stpc_lpt_handlers(dev, val);
|
||||
} else if (dev->offset == 4) {
|
||||
dev->reg4 = (val & 0x03);
|
||||
dev->reg4 = (val & 0x03);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1078,9 +1066,6 @@ stpc_lpt_close(void *priv)
|
||||
|
||||
stpc_log("STPC: lpt_close()\n");
|
||||
|
||||
io_removehandler(0x3f0, 2,
|
||||
NULL, NULL, NULL, stpc_lpt_write, NULL, NULL, dev);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/device.h>
|
||||
@@ -37,8 +38,10 @@
|
||||
|
||||
typedef struct via_apollo_t
|
||||
{
|
||||
uint16_t id;
|
||||
uint8_t pci_conf[256];
|
||||
uint16_t id;
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
smram_t *smram;
|
||||
} via_apollo_t;
|
||||
|
||||
|
||||
@@ -65,17 +68,12 @@ apollo_map(uint32_t addr, uint32_t size, int state)
|
||||
|
||||
|
||||
static void
|
||||
apollo_smram_map(int smm, uint32_t addr, uint32_t size, int is_smram)
|
||||
apollo_smram_map(via_apollo_t *dev, int smm, uint32_t host_base, uint32_t size, int is_smram)
|
||||
{
|
||||
if (((is_smram & 0x03) == 0x01) || ((is_smram & 0x03) == 0x02)) {
|
||||
smram[0].ram_base = 0x000a0000;
|
||||
smram[0].size = size;
|
||||
if (((is_smram & 0x03) == 0x01) || ((is_smram & 0x03) == 0x02))
|
||||
smram_enable(dev->smram, host_base, 0x000a0000, size, 0, 1);
|
||||
|
||||
mem_mapping_set_addr(&ram_smram_mapping[0], smram[0].host_base, size);
|
||||
mem_mapping_set_exec(&ram_smram_mapping[0], ram + smram[0].ram_base);
|
||||
}
|
||||
|
||||
mem_set_mem_state_smram_ex(smm, addr, size, is_smram & 0x03);
|
||||
mem_set_mem_state_smram_ex(smm, host_base, size, is_smram & 0x03);
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
@@ -249,64 +247,56 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
|
||||
if ((dev->pci_conf[0x63] ^ val) & 0xc0)
|
||||
apollo_map(0xe0000, 0x10000, (val & 0xc0) >> 6);
|
||||
dev->pci_conf[0x63] = val;
|
||||
if (smram[0].size != 0x00000000) {
|
||||
mem_set_mem_state_smram_ex(0, smram[0].host_base, smram[0].size, 0x00);
|
||||
mem_set_mem_state_smram_ex(1, smram[0].host_base, smram[0].size, 0x00);
|
||||
|
||||
memset(&smram[0], 0x00, sizeof(smram_t));
|
||||
mem_mapping_disable(&ram_smram_mapping[0]);
|
||||
flushmmucache();
|
||||
}
|
||||
smram_disable_all();
|
||||
if (dev->id == 0x0691) switch (val & 0x03) {
|
||||
case 0x00:
|
||||
default:
|
||||
apollo_smram_map(1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */
|
||||
apollo_smram_map(0, 0x000a0000, 0x00020000, 0); /* Non-SMM: Code PCI, Data PCI */
|
||||
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */
|
||||
apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 0); /* Non-SMM: Code PCI, Data PCI */
|
||||
break;
|
||||
case 0x01:
|
||||
apollo_smram_map(1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */
|
||||
apollo_smram_map(0, 0x000a0000, 0x00020000, 1); /* Non-SMM: Code DRAM, Data DRAM */
|
||||
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */
|
||||
apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 1); /* Non-SMM: Code DRAM, Data DRAM */
|
||||
break;
|
||||
case 0x02:
|
||||
apollo_smram_map(1, 0x000a0000, 0x00020000, 3); /* SMM: Code Invalid, Data Invalid */
|
||||
apollo_smram_map(0, 0x000a0000, 0x00020000, 2); /* Non-SMM: Code DRAM, Data PCI */
|
||||
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 3); /* SMM: Code Invalid, Data Invalid */
|
||||
apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 2); /* Non-SMM: Code DRAM, Data PCI */
|
||||
break;
|
||||
case 0x03:
|
||||
apollo_smram_map(1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */
|
||||
apollo_smram_map(0, 0x000a0000, 0x00020000, 3); /* Non-SMM: Code Invalid, Data Invalid */
|
||||
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */
|
||||
apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 3); /* Non-SMM: Code Invalid, Data Invalid */
|
||||
break;
|
||||
} else switch (val & 0x03) {
|
||||
case 0x00:
|
||||
default:
|
||||
/* Disable SMI Address Redirection (default) */
|
||||
apollo_smram_map(1, 0x000a0000, 0x00020000, 0);
|
||||
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 0);
|
||||
if (dev->id == 0x0597)
|
||||
apollo_smram_map(1, 0x00030000, 0x00020000, 1);
|
||||
apollo_smram_map(0, 0x000a0000, 0x00020000, 0);
|
||||
apollo_smram_map(dev, 1, 0x00030000, 0x00020000, 1);
|
||||
apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 0);
|
||||
break;
|
||||
case 0x01:
|
||||
/* Allow access to DRAM Axxxx-Bxxxx for both normal and SMI cycles */
|
||||
apollo_smram_map(1, 0x000a0000, 0x00020000, 1);
|
||||
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1);
|
||||
if (dev->id == 0x0597)
|
||||
apollo_smram_map(1, 0x00030000, 0x00020000, 1);
|
||||
apollo_smram_map(0, 0x000a0000, 0x00020000, 1);
|
||||
apollo_smram_map(dev, 1, 0x00030000, 0x00020000, 1);
|
||||
apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 1);
|
||||
break;
|
||||
case 0x02:
|
||||
/* Reserved */
|
||||
apollo_smram_map(1, 0x000a0000, 0x00020000, 3);
|
||||
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 3);
|
||||
if (dev->id == 0x0597) {
|
||||
/* SMI 3xxxx-4xxxx redirect to Axxxx-Bxxxx. */
|
||||
smram[0].host_base = 0x00030000;
|
||||
apollo_smram_map(1, 0x00030000, 0x00020000, 1);
|
||||
apollo_smram_map(dev, 1, 0x00030000, 0x00020000, 1);
|
||||
}
|
||||
apollo_smram_map(0, 0x000a0000, 0x00020000, 3);
|
||||
apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 3);
|
||||
break;
|
||||
case 0x03:
|
||||
/* Allow SMI Axxxx-Bxxxx DRAM access */
|
||||
apollo_smram_map(1, 0x000a0000, 0x00020000, 1);
|
||||
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1);
|
||||
if (dev->id == 0x0597)
|
||||
apollo_smram_map(1, 0x00030000, 0x00020000, 1);
|
||||
apollo_smram_map(0, 0x000a0000, 0x00020000, 0);
|
||||
apollo_smram_map(dev, 1, 0x00030000, 0x00020000, 1);
|
||||
apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -444,6 +434,9 @@ via_apollo_init(const device_t *info)
|
||||
via_apollo_t *dev = (via_apollo_t *) malloc(sizeof(via_apollo_t));
|
||||
memset(dev, 0, sizeof(via_apollo_t));
|
||||
|
||||
dev->smram = smram_add();
|
||||
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, via_apollo_read, via_apollo_write, dev);
|
||||
|
||||
dev->id = info->local;
|
||||
@@ -474,6 +467,8 @@ via_apollo_close(void *priv)
|
||||
{
|
||||
via_apollo_t *dev = (via_apollo_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -491,7 +491,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
|
||||
if (val & 0x01)
|
||||
trc_write(0x0047, (val & 0x80) ? 0x06 : 0x04, NULL);
|
||||
pic_set_shadow(!!(val & 0x10));
|
||||
pci_elcr_set_enabled(!!(val & 0x20));
|
||||
pic_elcr_set_enabled(!!(val & 0x20));
|
||||
dev->pci_isa_regs[0x47] = val & 0xfe;
|
||||
break;
|
||||
case 0x48:
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100
|
||||
*
|
||||
* Copyright 2020 Tiseno100
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2020 Tiseno100.
|
||||
* Copyright 2020 Miran Grca.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -30,15 +30,22 @@
|
||||
#include <86box/device.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t index,
|
||||
regs[256];
|
||||
uint8_t has_ide, index,
|
||||
regs[256];
|
||||
|
||||
smram_t *smram_smm, *smram_low,
|
||||
*smram_high;
|
||||
} vt82c49x_t;
|
||||
|
||||
#ifdef ENABLE_VT82C49X_LOG
|
||||
@@ -58,40 +65,100 @@ vt82c49x_log(const char *fmt, ...)
|
||||
#define vt82c49x_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void vt82c49x_shadow_recalc(vt82c49x_t *dev)
|
||||
|
||||
static void
|
||||
vt82c49x_recalc(vt82c49x_t *dev)
|
||||
{
|
||||
int i, state;
|
||||
int relocate;
|
||||
int wr_c0, wr_c8, wr_e8, wr_e0;
|
||||
int rr_c0, rr_c8, rr_e8, rr_e0;
|
||||
int wp_c0, wp_e0, wp_e8, wp_f;
|
||||
uint32_t base;
|
||||
|
||||
uint32_t wp_c, wp_e, wp_f;
|
||||
/* Register 33h */
|
||||
wr_c8 = (dev->regs[0x33] & 0x80) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
wr_c0 = (dev->regs[0x33] & 0x40) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
wr_e8 = (dev->regs[0x33] & 0x20) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
wr_e0 = (dev->regs[0x33] & 0x10) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
rr_c8 = (dev->regs[0x33] & 0x80) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
rr_c0 = (dev->regs[0x33] & 0x40) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
rr_e8 = (dev->regs[0x33] & 0x20) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
rr_e0 = (dev->regs[0x33] & 0x10) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
relocate = (dev->regs[0x33] >> 2) & 0x03;
|
||||
|
||||
/* Register 40h */
|
||||
wp_c = (dev->regs[0x40] & 0x80) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL;
|
||||
wp_f = (dev->regs[0x40] & 0x40) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL;
|
||||
wp_e = (dev->regs[0x40] & 0x20) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL;
|
||||
/* Register 40h */
|
||||
wp_c0 = (dev->regs[0x40] & 0x80) ? wr_c0 : MEM_WRITE_INTERNAL;
|
||||
wp_f = (dev->regs[0x40] & 0x40) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL;
|
||||
wp_e8 = (dev->regs[0x40] & 0x20) ? wr_e8 : MEM_WRITE_INTERNAL;
|
||||
wp_e0 = (dev->regs[0x40] & 0x20) ? wr_e0 : MEM_WRITE_INTERNAL;
|
||||
|
||||
/* Register 30h */
|
||||
mem_set_mem_state_both(0xc0000, 0x4000, ((dev->regs[0x30] & 0x02) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x30] & 0x01) ? wp_c : MEM_WRITE_EXTANY));
|
||||
mem_set_mem_state_both(0xc4000, 0x4000, ((dev->regs[0x30] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x30] & 0x04) ? wp_c : MEM_WRITE_EXTANY));
|
||||
mem_set_mem_state_both(0xc8000, 0x4000, ((dev->regs[0x30] & 0x20) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x30] & 0x10) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
|
||||
mem_set_mem_state_both(0xcc000, 0x4000, ((dev->regs[0x30] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x30] & 0x40) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
|
||||
/* Registers 30h-32h */
|
||||
if (relocate >= 2) {
|
||||
mem_set_mem_state_both(0xc8000, 0x8000, wr_c8 | rr_c8);
|
||||
mem_set_mem_state_both(0xc0000, 0x8000, wr_c0 | rr_c0);
|
||||
|
||||
/* Register 31h */
|
||||
mem_set_mem_state_both(0xd0000, 0x4000, ((dev->regs[0x31] & 0x02) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x31] & 0x01) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
|
||||
mem_set_mem_state_both(0xd4000, 0x4000, ((dev->regs[0x31] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x31] & 0x04) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
|
||||
mem_set_mem_state_both(0xd8000, 0x4000, ((dev->regs[0x31] & 0x20) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x31] & 0x10) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
|
||||
mem_set_mem_state_both(0xdc000, 0x4000, ((dev->regs[0x31] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x31] & 0x40) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
|
||||
mem_set_mem_state_both(0xd0000, 0x10000, MEM_WRITE_EXTERNAL | MEM_READ_EXTERNAL);
|
||||
} else for (i = 0; i < 8; i += 2) {
|
||||
base = 0xc0000 + (i << 13);
|
||||
if (base >= 0xc8000) {
|
||||
state = (dev->regs[0x30] & i) ? MEM_WRITE_INTERNAL : wr_c8;
|
||||
state |= (dev->regs[0x30] & (i + 1)) ? MEM_READ_INTERNAL : rr_c8;
|
||||
} else {
|
||||
state = (dev->regs[0x30] & i) ? wp_c0 : wr_c0;
|
||||
state |= (dev->regs[0x30] & (i + 1)) ? MEM_READ_INTERNAL : rr_c0;
|
||||
}
|
||||
mem_set_mem_state_both(base, 0x4000, state);
|
||||
|
||||
/* Register 32h */
|
||||
shadowbios = (dev->regs[0x40] & 0x20);
|
||||
shadowbios_write = (dev->regs[0x40] & 0x10);
|
||||
mem_set_mem_state_both(0xe0000, 0x10000, ((dev->regs[0x32] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x32] & 0x40) ? wp_e : MEM_WRITE_EXTANY));
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, ((dev->regs[0x32] & 0x20) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x32] & 0x10) ? wp_f : MEM_WRITE_EXTANY));
|
||||
base = 0xd0000 + (i << 13);
|
||||
state = (dev->regs[0x31] & i) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTERNAL;
|
||||
state |= (dev->regs[0x31] & (i + 1)) ? MEM_READ_INTERNAL : MEM_READ_EXTERNAL;
|
||||
mem_set_mem_state_both(base, 0x4000, state);
|
||||
}
|
||||
|
||||
state = (dev->regs[0x32] & 0x10) ? wp_f : MEM_WRITE_EXTANY;
|
||||
state |= (dev->regs[0x32] & 0x20) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
shadowbios_write = (dev->regs[0x32] & 0x10) ? ((wp_f == MEM_WRITE_INTERNAL) ? 1 : 0) : 0;
|
||||
shadowbios = (dev->regs[0x32] & 0x20) ? 1 : 0;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, state);
|
||||
|
||||
if (relocate == 3) {
|
||||
mem_set_mem_state_both(0xe8000, 0x8000, wr_e8 | rr_e8);
|
||||
mem_set_mem_state_both(0xe0000, 0x8000, wr_e0 | rr_e0);
|
||||
} else {
|
||||
state = (dev->regs[0x32] & 0x40) ? wp_e8 : wr_e8;
|
||||
state |= (dev->regs[0x32] & 0x80) ? MEM_READ_INTERNAL : rr_e8;
|
||||
shadowbios_write |= (dev->regs[0x32] & 0x40) ? ((wp_e8 == MEM_WRITE_INTERNAL) ? 1 : 0) : 0;
|
||||
shadowbios |= (dev->regs[0x32] & 0x80) ? 1 : 0;
|
||||
mem_set_mem_state_both(0xe8000, 0x8000, state);
|
||||
|
||||
state = (dev->regs[0x32] & 0x40) ? wp_e0 : wr_e0;
|
||||
state |= (dev->regs[0x32] & 0x80) ? MEM_READ_INTERNAL : rr_e0;
|
||||
shadowbios_write |= (dev->regs[0x32] & 0x40) ? ((wp_e0 == MEM_WRITE_INTERNAL) ? 1 : 0) : 0;
|
||||
shadowbios |= (dev->regs[0x32] & 0x80) ? 1 : 0;
|
||||
mem_set_mem_state_both(0xe0000, 0x8000, state);
|
||||
}
|
||||
|
||||
switch (relocate) {
|
||||
case 0x00:
|
||||
default:
|
||||
mem_remap_top(0);
|
||||
break;
|
||||
case 0x02:
|
||||
mem_remap_top(256);
|
||||
break;
|
||||
case 0x03:
|
||||
mem_remap_top(384);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vt82c49x_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
vt82c49x_t *dev = (vt82c49x_t *) priv;
|
||||
uint8_t valxor;
|
||||
|
||||
switch (addr) {
|
||||
case 0xa8:
|
||||
@@ -99,40 +166,80 @@ vt82c49x_write(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0xa9:
|
||||
dev->regs[dev->index] = val;
|
||||
valxor = (val ^ dev->regs[dev->index]);
|
||||
if (dev->index == 0x55)
|
||||
dev->regs[dev->index] &= ~val;
|
||||
else
|
||||
dev->regs[dev->index] = val;
|
||||
|
||||
vt82c49x_log("dev->regs[0x%02x] = %02x\n", dev->index, val);
|
||||
vt82c49x_log("dev->regs[0x%02x] = %02x\n", dev->index, val);
|
||||
|
||||
switch(dev->index){
|
||||
/* Wait States */
|
||||
case 0x03:
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
switch(dev->index) {
|
||||
/* Wait States */
|
||||
case 0x03:
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
/* Shadow RAM */
|
||||
case 0x30:
|
||||
case 0x31:
|
||||
case 0x32:
|
||||
case 0x40:
|
||||
vt82c49x_shadow_recalc(dev);
|
||||
break;
|
||||
/* Shadow RAM and top of RAM relocation */
|
||||
case 0x30:
|
||||
case 0x31:
|
||||
case 0x32:
|
||||
case 0x33:
|
||||
case 0x40:
|
||||
vt82c49x_recalc(dev);
|
||||
break;
|
||||
|
||||
/* External Cache Enable(Based on the 486-VC-HD BIOS) */
|
||||
case 0x50:
|
||||
cpu_cache_ext_enabled = (val & 0x84);
|
||||
break;
|
||||
/* External Cache Enable(Based on the 486-VC-HD BIOS) */
|
||||
case 0x50:
|
||||
cpu_cache_ext_enabled = (val & 0x84);
|
||||
break;
|
||||
|
||||
/* SMI/SMM(Not at all perfect or even functional :/) */
|
||||
case 0x5b:
|
||||
/* Software SMI */
|
||||
case 0x54:
|
||||
if ((dev->regs[0x5b] & 0x80) && (valxor & 0x01) && (val & 0x01)) {
|
||||
if (dev->regs[0x5b] & 0x20)
|
||||
smi_line = 1;
|
||||
else
|
||||
picint(1 << 15);
|
||||
dev->regs[0x55] = 0x01;
|
||||
}
|
||||
break;
|
||||
|
||||
if(val & 0x40)
|
||||
mem_set_mem_state_smram(1, 0x30000, 0x20000, 0);
|
||||
/* SMRAM */
|
||||
case 0x5b:
|
||||
smram_disable_all();
|
||||
|
||||
if(val & 0x20)
|
||||
smi_line = 1;
|
||||
if (val & 0x80) {
|
||||
smram_enable(dev->smram_smm, (val & 0x40) ? 0x00060000 : 0x00030000, 0x000a0000, 0x00020000,
|
||||
0, (val & 0x10));
|
||||
smram_enable(dev->smram_high, 0x000a0000, 0x000a0000, 0x00020000,
|
||||
(val & 0x08), (val & 0x08));
|
||||
smram_enable(dev->smram_low, 0x00030000, 0x000a0000, 0x00020000,
|
||||
(val & 0x02), 0);
|
||||
}
|
||||
break;
|
||||
|
||||
break;
|
||||
}
|
||||
/* Edge/Level IRQ Control */
|
||||
case 0x62: case 0x63:
|
||||
if (dev->index == 0x63)
|
||||
pic_elcr_write(dev->index, val & 0xde, NULL);
|
||||
else {
|
||||
pic_elcr_write(dev->index, val & 0xf8, NULL);
|
||||
pic_elcr_set_enabled(val & 0x01);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Local Bus IDE Controller */
|
||||
case 0x71:
|
||||
if (dev->has_ide) {
|
||||
ide_pri_disable();
|
||||
ide_set_base(0, (val & 0x40) ? 0x170 : 0x1f0);
|
||||
ide_set_side(0, (val & 0x40) ? 0x376 : 0x3f6);
|
||||
if (val & 0x01)
|
||||
ide_pri_enable();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -146,7 +253,12 @@ vt82c49x_read(uint16_t addr, void *priv)
|
||||
|
||||
switch (addr) {
|
||||
case 0xa9:
|
||||
ret = dev->regs[dev->index];
|
||||
if (dev->index == 0x63)
|
||||
ret = pic_elcr_read(dev->index, NULL) | (dev->regs[dev->index] & 0x01);
|
||||
else if (dev->index == 0x62)
|
||||
ret = pic_elcr_read(dev->index, NULL) | (dev->regs[dev->index] & 0x07);
|
||||
else
|
||||
ret = dev->regs[dev->index];
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -159,6 +271,10 @@ vt82c49x_close(void *priv)
|
||||
{
|
||||
vt82c49x_t *dev = (vt82c49x_t *) priv;
|
||||
|
||||
smram_del(dev->smram_high);
|
||||
smram_del(dev->smram_low);
|
||||
smram_del(dev->smram_smm);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
@@ -167,17 +283,24 @@ static void *
|
||||
vt82c49x_init(const device_t *info)
|
||||
{
|
||||
vt82c49x_t *dev = (vt82c49x_t *) malloc(sizeof(vt82c49x_t));
|
||||
memset(dev, 0, sizeof(vt82c49x_t));
|
||||
memset(dev, 0x00, sizeof(vt82c49x_t));
|
||||
|
||||
dev->smram_smm = smram_add();
|
||||
dev->smram_low = smram_add();
|
||||
dev->smram_high = smram_add();
|
||||
|
||||
dev->has_ide = info->local & 1;
|
||||
if (dev->has_ide)
|
||||
device_add(&ide_vlb_device);
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
io_sethandler(0x0a8, 0x0001, vt82c49x_read, NULL, NULL, vt82c49x_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0a9, 0x0001, vt82c49x_read, NULL, NULL, vt82c49x_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0a8, 0x0002, vt82c49x_read, NULL, NULL, vt82c49x_write, NULL, NULL, dev);
|
||||
|
||||
dev->regs[0x30] = 0x00;
|
||||
dev->regs[0x31] = 0x00;
|
||||
dev->regs[0x32] = 0x00;
|
||||
vt82c49x_shadow_recalc(dev);
|
||||
pic_elcr_io_handler(0);
|
||||
pic_elcr_set_enabled(1);
|
||||
|
||||
vt82c49x_recalc(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
@@ -191,3 +314,13 @@ const device_t via_vt82c49x_device = {
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
const device_t via_vt82c49x_ide_device = {
|
||||
"VIA VT82C49X (With IDE)",
|
||||
0,
|
||||
1,
|
||||
vt82c49x_init, vt82c49x_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100
|
||||
*
|
||||
* Copyright 2020 Tiseno100
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2020 Tiseno100.
|
||||
* Copyright 2020 Miran Grca.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
@@ -24,15 +24,18 @@
|
||||
#include <86box/86box.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
typedef struct vt82c505_t
|
||||
{
|
||||
uint8_t pci_conf[256];
|
||||
} vt82c505_t;
|
||||
|
||||
|
||||
static void
|
||||
vt82c505_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
@@ -40,55 +43,51 @@ vt82c505_write(int func, int addr, uint8_t val, void *priv)
|
||||
vt82c505_t *dev = (vt82c505_t *) priv;
|
||||
|
||||
/* Read-Only Registers */
|
||||
switch (addr)
|
||||
{
|
||||
case 0x00: case 0x01:
|
||||
case 0x02: case 0x03:
|
||||
return;
|
||||
switch (addr) {
|
||||
case 0x00: case 0x01:
|
||||
case 0x02: case 0x03:
|
||||
return;
|
||||
}
|
||||
|
||||
switch(addr)
|
||||
{
|
||||
switch(addr) {
|
||||
case 0x04:
|
||||
dev->pci_conf[0x04] = (dev->pci_conf[0x04] & ~0x07) | (val & 0x07);
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
dev->pci_conf[0x04] = (dev->pci_conf[0x04] & ~0x07) | (val & 0x07);
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->pci_conf[0x07] = (dev->pci_conf[0x07] & ~0x90) | (val & 0x90);
|
||||
break;
|
||||
case 0x07:
|
||||
dev->pci_conf[0x07] &= ~(val & 0x90);
|
||||
break;
|
||||
|
||||
case 0x90:
|
||||
if((dev->pci_conf[0x90] & 0x08) && ((val & 0x07) != 0))
|
||||
pci_set_irq_routing(PCI_INTC, val & 0x07);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
|
||||
if ((dev->pci_conf[0x90] & 0x08) && ((val & 0x07) != 0))
|
||||
pci_set_irq_routing(PCI_INTC, val & 0x07);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
|
||||
|
||||
if((dev->pci_conf[0x90] & 0x80) && (((val & 0x07) << 4) != 0))
|
||||
pci_set_irq_routing(PCI_INTD, ((val & 0x07) << 4));
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
|
||||
break;
|
||||
if ((dev->pci_conf[0x90] & 0x80) && (((val & 0x07) << 4) != 0))
|
||||
pci_set_irq_routing(PCI_INTD, ((val & 0x07) << 4));
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
|
||||
break;
|
||||
|
||||
case 0x91:
|
||||
if((dev->pci_conf[0x91] & 0x08) && ((val & 0x07) != 0))
|
||||
pci_set_irq_routing(PCI_INTA, val & 0x07);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
|
||||
|
||||
if((dev->pci_conf[0x91] & 0x80) && (((val & 0x07) << 4) != 0))
|
||||
pci_set_irq_routing(PCI_INTB, ((val & 0x07) << 4));
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
|
||||
break;
|
||||
case 0x91:
|
||||
if ((dev->pci_conf[0x91] & 0x08) && ((val & 0x07) != 0))
|
||||
pci_set_irq_routing(PCI_INTA, val & 0x07);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
|
||||
|
||||
if ((dev->pci_conf[0x91] & 0x80) && (((val & 0x07) << 4) != 0))
|
||||
pci_set_irq_routing(PCI_INTB, ((val & 0x07) << 4));
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
vt82c505_read(int func, int addr, void *priv)
|
||||
{
|
||||
|
||||
vt82c505_t *dev = (vt82c505_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
@@ -97,17 +96,19 @@ vt82c505_read(int func, int addr, void *priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vt82c505_reset(void *priv)
|
||||
{
|
||||
|
||||
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);
|
||||
|
||||
pic_reset();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vt82c505_close(void *priv)
|
||||
{
|
||||
@@ -116,10 +117,10 @@ vt82c505_close(void *priv)
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
vt82c505_init(const device_t *info)
|
||||
{
|
||||
|
||||
vt82c505_t *dev = (vt82c505_t *) malloc(sizeof(vt82c505_t));
|
||||
memset(dev, 0, sizeof(vt82c505_t));
|
||||
|
||||
@@ -132,21 +133,18 @@ vt82c505_init(const device_t *info)
|
||||
dev->pci_conf[0x03] = 0x05;
|
||||
|
||||
dev->pci_conf[0x04] = 0x07;
|
||||
dev->pci_conf[0x05] = 0x00;
|
||||
|
||||
dev->pci_conf[0x06] = 0x00;
|
||||
dev->pci_conf[0x07] = 0x90;
|
||||
|
||||
dev->pci_conf[0x81] = 0x01;
|
||||
dev->pci_conf[0x84] = 0x03;
|
||||
|
||||
dev->pci_conf[0x85] = 0x00;
|
||||
|
||||
dev->pci_conf[0x93] = 0x40;
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
const device_t via_vt82c505_device = {
|
||||
"VIA VT82C505",
|
||||
DEVICE_PCI,
|
||||
|
||||
Reference in New Issue
Block a user