PIC rewrite, proper SMRAM API, complete SiS 471 rewrite and addition of 40x, 460, and 461, changes to mem.c/h, disabled Voodoo memory dumping on exit, bumped SDL Hardware scale quality to 2, bumped IDE/ATAPI drives to ATA-6, finally bumped emulator version to 3.0, redid the bus type ID's to allow for planned ATAPI hard disks, made SST flash set its high mappings to the correct address if the CPU is 16-bit, and added the SiS 401 AMI 486 Clone, AOpen Vi15G, and the Soyo 4SA2 (486 with SiS 496/497 that can boot from CD-ROM), assorted 286+ protected mode fixes (for slightly more accuracy), and fixes to 808x emulation (MS Word 1.0 and 1.10 for DOS now work correctly from floppy).
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