mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 01:25:33 -07:00
Merge branch 'master' into translation_hu-HU
This commit is contained in:
20
src/86box.c
20
src/86box.c
@@ -749,6 +749,26 @@ pc_init_modules(void)
|
||||
wchar_t temp[512];
|
||||
char tempc[512];
|
||||
|
||||
c = m = 0;
|
||||
while (machine_get_internal_name_ex(c) != NULL) {
|
||||
m = machine_available(c);
|
||||
if (!m)
|
||||
pclog("Missing machine: %s\n", machine_getname_ex(c));
|
||||
c++;
|
||||
}
|
||||
|
||||
c = m = 0;
|
||||
while (video_get_internal_name(c) != NULL) {
|
||||
memset(tempc, 0, sizeof(tempc));
|
||||
device_get_name(video_card_getdevice(c), 0, tempc);
|
||||
if ((c > 1) && !(tempc[0]))
|
||||
break;
|
||||
m = video_card_available(c);
|
||||
if (!m)
|
||||
pclog("Missing video card: %s\n", tempc);
|
||||
c++;
|
||||
}
|
||||
|
||||
pc_log("Scanning for ROM images:\n");
|
||||
c = m = 0;
|
||||
while (machine_get_internal_name_ex(m) != NULL) {
|
||||
|
||||
@@ -31,8 +31,8 @@ set_source_files_properties(${APP_ICON_MACOSX} PROPERTIES
|
||||
|
||||
# WIN32 marks us as a GUI app on Windows
|
||||
# MACOSX_BUNDLE prepares a macOS application bundle including with the app icon
|
||||
add_executable(86Box WIN32 MACOSX_BUNDLE 86box.c config.c random.c timer.c io.c acpi.c apm.c
|
||||
dma.c ddma.c nmi.c pic.c pit.c port_92.c ppi.c pci.c mca.c usb.c
|
||||
add_executable(86Box WIN32 MACOSX_BUNDLE 86box.c config.c log.c random.c timer.c io.c acpi.c apm.c
|
||||
dma.c ddma.c nmi.c pic.c pit.c port_6x.c port_92.c ppi.c pci.c mca.c usb.c
|
||||
device.c nvr.c nvr_at.c nvr_ps2.c ${APP_ICON_MACOSX})
|
||||
|
||||
if(NEW_DYNAREC)
|
||||
|
||||
186
src/acpi.c
186
src/acpi.c
@@ -72,11 +72,15 @@ acpi_update_irq(acpi_t *dev)
|
||||
if (sci_level) {
|
||||
if (dev->irq_mode == 1)
|
||||
pci_set_irq(dev->slot, dev->irq_pin);
|
||||
else if (dev->irq_mode == 2)
|
||||
pci_set_mirq(5, dev->mirq_is_level);
|
||||
else
|
||||
pci_set_mirq(0xf0 | dev->irq_line, 1);
|
||||
} else {
|
||||
if (dev->irq_mode == 1)
|
||||
pci_clear_irq(dev->slot, dev->irq_pin);
|
||||
else if (dev->irq_mode == 2)
|
||||
pci_clear_mirq(5, dev->mirq_is_level);
|
||||
else
|
||||
pci_clear_mirq(0xf0 | dev->irq_line, 1);
|
||||
}
|
||||
@@ -84,20 +88,29 @@ acpi_update_irq(acpi_t *dev)
|
||||
|
||||
|
||||
void
|
||||
acpi_raise_smi(acpi_t *dev)
|
||||
acpi_raise_smi(void *priv, int do_smi)
|
||||
{
|
||||
acpi_t *dev = (acpi_t *) priv;
|
||||
|
||||
if (dev->regs.glbctl & 0x01) {
|
||||
if ((dev->vendor == VEN_VIA) || (dev->vendor == VEN_VIA_596B)) {
|
||||
if ((!dev->regs.smi_lock || !dev->regs.smi_active)) {
|
||||
smi_line = 1;
|
||||
if ((!dev->regs.smi_lock || !dev->regs.smi_active)) {
|
||||
if (do_smi)
|
||||
smi_line = 1;
|
||||
dev->regs.smi_active = 1;
|
||||
}
|
||||
} else if ((dev->vendor == VEN_INTEL) || (dev->vendor == VEN_ALI)) {
|
||||
smi_line = 1;
|
||||
if (do_smi)
|
||||
smi_line = 1;
|
||||
/* Clear bit 16 of GLBCTL. */
|
||||
dev->regs.glbctl &= ~0x00010000;
|
||||
} else if (dev->vendor == VEN_SMC)
|
||||
smi_line = 1;
|
||||
if (dev->vendor == VEN_INTEL)
|
||||
dev->regs.glbctl &= ~0x00010000;
|
||||
else
|
||||
dev->regs.ali_soft_smi = 1;
|
||||
} else if (dev->vendor == VEN_SMC) {
|
||||
if (do_smi)
|
||||
smi_line = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,8 +172,7 @@ acpi_reg_read_ali(int size, uint16_t addr, void *p)
|
||||
shift16 = (addr & 1) << 3;
|
||||
shift32 = (addr & 3) << 3;
|
||||
|
||||
switch(addr)
|
||||
{
|
||||
switch(addr) {
|
||||
case 0x10: case 0x11: case 0x12: case 0x13:
|
||||
/* PCNTRL - Processor Control Register (IO) */
|
||||
ret = (dev->regs.pcntrl >> shift16) & 0xff;
|
||||
@@ -175,39 +187,33 @@ acpi_reg_read_ali(int size, uint16_t addr, void *p)
|
||||
break;
|
||||
case 0x18: case 0x19:
|
||||
/* GPE0_STS - General Purpose Event0 Status Register */
|
||||
ret = (dev->regs.gpsts >> shift16) & 0xff;
|
||||
break;
|
||||
ret = (dev->regs.gpsts >> shift16) & 0xff;
|
||||
break;
|
||||
case 0x1a: case 0x1b:
|
||||
/* GPE0_EN - General Purpose Event0 Enable Register */
|
||||
ret = (dev->regs.gpen >> shift16) & 0xff;
|
||||
break;
|
||||
ret = (dev->regs.gpen >> shift16) & 0xff;
|
||||
break;
|
||||
case 0x1d: case 0x1c:
|
||||
/* GPE1_STS - General Purpose Event1 Status Register */
|
||||
ret = (dev->regs.gpsts >> shift16) & 0xff;
|
||||
break;
|
||||
ret = (dev->regs.gpsts1 >> shift16) & 0xff;
|
||||
break;
|
||||
case 0x1f: case 0x1e:
|
||||
/* GPE1_EN - General Purpose Event1 Enable Register */
|
||||
ret = (dev->regs.gpen1 >> shift16) & 0xff;
|
||||
break;
|
||||
case 0x20:
|
||||
case 0x21:
|
||||
case 0x22:
|
||||
case 0x23:
|
||||
case 0x24:
|
||||
case 0x25:
|
||||
case 0x26:
|
||||
case 0x27:
|
||||
ret = (dev->regs.gpen1 >> shift16) & 0xff;
|
||||
break;
|
||||
case 0x20 ... 0x27:
|
||||
/* GPE1_CTL - General Purpose Event1 Control Register */
|
||||
ret = (dev->regs.gpcntrl >> shift32) & 0xff;
|
||||
break;
|
||||
ret = (dev->regs.gpcntrl >> shift32) & 0xff;
|
||||
break;
|
||||
case 0x30:
|
||||
/* PM2_CNTRL - Power Management 2 Control Register( */
|
||||
ret = dev->regs.pmcntrl;
|
||||
break;
|
||||
ret = dev->regs.pmcntrl;
|
||||
break;
|
||||
default:
|
||||
ret = acpi_reg_read_common_regs(size, addr, p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ACPI_LOG
|
||||
if (size != 1)
|
||||
acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret);
|
||||
@@ -291,6 +297,7 @@ acpi_reg_read_intel(int size, uint16_t addr, void *p)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
acpi_reg_read_sis(int size, uint16_t addr, void *p)
|
||||
{
|
||||
@@ -714,44 +721,37 @@ acpi_reg_write_ali(int size, uint16_t addr, uint8_t val, void *p)
|
||||
break;
|
||||
case 0x18: case 0x19:
|
||||
/* GPE0_STS - General Purpose Event0 Status Register */
|
||||
dev->regs.gpsts &= ~((val << shift16) & 0x0d07);
|
||||
break;
|
||||
dev->regs.gpsts &= ~((val << shift16) & 0x0d07);
|
||||
break;
|
||||
case 0x1a: case 0x1b:
|
||||
/* GPE0_EN - General Purpose Event0 Enable Register */
|
||||
dev->regs.gpen = ((dev->regs.gpen & ~(0xff << shift16)) | (val << shift16)) & 0x0d07;
|
||||
break;
|
||||
dev->regs.gpen = ((dev->regs.gpen & ~(0xff << shift16)) | (val << shift16)) & 0x0d07;
|
||||
break;
|
||||
case 0x1d: case 0x1c:
|
||||
/* GPE1_STS - General Purpose Event1 Status Register */
|
||||
dev->regs.gpsts &= ~((val << shift16) & 0x0c01);
|
||||
break;
|
||||
dev->regs.gpsts1 &= ~((val << shift16) & 0x0c01);
|
||||
break;
|
||||
case 0x1f: case 0x1e:
|
||||
/* GPE1_EN - General Purpose Event1 Enable Register */
|
||||
dev->regs.gpen = ((dev->regs.gpen & ~(0xff << shift16)) | (val << shift16)) & 0x0c01;
|
||||
break;
|
||||
case 0x20:
|
||||
case 0x21:
|
||||
case 0x22:
|
||||
case 0x23:
|
||||
case 0x24:
|
||||
case 0x25:
|
||||
case 0x26:
|
||||
case 0x27:
|
||||
dev->regs.gpen1 = ((dev->regs.gpen & ~(0xff << shift16)) | (val << shift16)) & 0x0c01;
|
||||
break;
|
||||
case 0x20 ... 0x27:
|
||||
/* GPE1_CTL - General Purpose Event1 Control Register */
|
||||
dev->regs.gpcntrl = ((dev->regs.gpcntrl & ~(0xff << shift32)) | (val << shift32)) & 0x00000001;
|
||||
break;
|
||||
dev->regs.gpcntrl = ((dev->regs.gpcntrl & ~(0xff << shift32)) | (val << shift32)) & 0x00000001;
|
||||
break;
|
||||
case 0x30:
|
||||
/* PM2_CNTRL - Power Management 2 Control Register( */
|
||||
dev->regs.pmcntrl = val & 1;
|
||||
break;
|
||||
dev->regs.pmcntrl = val & 1;
|
||||
break;
|
||||
default:
|
||||
acpi_reg_write_common_regs(size, addr, val, p);
|
||||
/* Setting GBL_RLS also sets BIOS_STS and generates SMI. */
|
||||
if ((addr == 0x00) && !(dev->regs.pmsts & 0x20))
|
||||
dev->regs.glbctl &= ~0x0002;
|
||||
dev->regs.gpcntrl &= ~0x0002;
|
||||
else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) {
|
||||
dev->regs.glbsts |= 0x01;
|
||||
if (dev->regs.glben & 0x02)
|
||||
acpi_raise_smi(dev);
|
||||
dev->regs.gpsts1 |= 0x01;
|
||||
if (dev->regs.gpen1 & 0x01)
|
||||
acpi_raise_smi(dev, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -829,7 +829,7 @@ acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p)
|
||||
else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) {
|
||||
dev->regs.glbsts |= 0x01;
|
||||
if (dev->regs.glben & 0x02)
|
||||
acpi_raise_smi(dev);
|
||||
acpi_raise_smi(dev, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -978,7 +978,7 @@ acpi_reg_write_via_common(int size, uint16_t addr, uint8_t val, void *p)
|
||||
dev->regs.smicmd = val & 0xff;
|
||||
dev->regs.glbsts |= 0x40;
|
||||
if (dev->regs.glben & 0x40)
|
||||
acpi_raise_smi(dev);
|
||||
acpi_raise_smi(dev, 1);
|
||||
}
|
||||
break;
|
||||
case 0x38: case 0x39: case 0x3a: case 0x3b:
|
||||
@@ -993,7 +993,7 @@ acpi_reg_write_via_common(int size, uint16_t addr, uint8_t val, void *p)
|
||||
else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) {
|
||||
dev->regs.glbsts |= 0x20;
|
||||
if (dev->regs.glben & 0x20)
|
||||
acpi_raise_smi(dev);
|
||||
acpi_raise_smi(dev, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1125,7 +1125,7 @@ acpi_reg_write_smc(int size, uint16_t addr, uint8_t val, void *p)
|
||||
else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) {
|
||||
dev->regs.glbsts |= 0x01;
|
||||
if (dev->regs.glben & 0x01)
|
||||
acpi_raise_smi(dev);
|
||||
acpi_raise_smi(dev, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1554,6 +1554,13 @@ acpi_set_irq_line(acpi_t *dev, int irq_line)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
acpi_set_mirq_is_level(acpi_t *dev, int mirq_is_level)
|
||||
{
|
||||
dev->mirq_is_level = mirq_is_level;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
acpi_set_gpireg2_default(acpi_t *dev, uint8_t gpireg2_default)
|
||||
{
|
||||
@@ -1577,6 +1584,20 @@ acpi_set_trap_update(acpi_t *dev, void (*update)(void *priv), void *priv)
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
acpi_ali_soft_smi_status_read(acpi_t *dev)
|
||||
{
|
||||
return dev->regs.ali_soft_smi = 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
acpi_ali_soft_smi_status_write(acpi_t *dev, uint8_t soft_smi)
|
||||
{
|
||||
dev->regs.ali_soft_smi = soft_smi;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
acpi_apm_out(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
@@ -1586,15 +1607,25 @@ acpi_apm_out(uint16_t port, uint8_t val, void *p)
|
||||
|
||||
port &= 0x0001;
|
||||
|
||||
if (port == 0x0000) {
|
||||
dev->apm->cmd = val;
|
||||
if (dev->apm->do_smi) {
|
||||
if ((dev->vendor == VEN_INTEL) || (dev->vendor == VEN_ALI))
|
||||
if (dev->vendor == VEN_ALI) {
|
||||
if (port == 0x0001) {
|
||||
acpi_log("ALi SOFT SMI# status set (%i)\n", dev->apm->do_smi);
|
||||
dev->apm->cmd = val;
|
||||
// acpi_raise_smi(dev, dev->apm->do_smi);
|
||||
if (dev->apm->do_smi)
|
||||
smi_line = 1;
|
||||
dev->regs.ali_soft_smi = 1;
|
||||
} else if (port == 0x0003)
|
||||
dev->apm->stat = val;
|
||||
} else {
|
||||
if (port == 0x0000) {
|
||||
dev->apm->cmd = val;
|
||||
if (dev->vendor == VEN_INTEL)
|
||||
dev->regs.glbsts |= 0x20;
|
||||
acpi_raise_smi(dev);
|
||||
}
|
||||
} else
|
||||
dev->apm->stat = val;
|
||||
acpi_raise_smi(dev, dev->apm->do_smi);
|
||||
} else
|
||||
dev->apm->stat = val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1606,10 +1637,17 @@ acpi_apm_in(uint16_t port, void *p)
|
||||
|
||||
port &= 0x0001;
|
||||
|
||||
if (port == 0x0000)
|
||||
ret = dev->apm->cmd;
|
||||
else
|
||||
ret = dev->apm->stat;
|
||||
if (dev->vendor == VEN_ALI) {
|
||||
if (port == 0x0001)
|
||||
ret = dev->apm->cmd;
|
||||
else if (port == 0x0003)
|
||||
ret = dev->apm->stat;
|
||||
} else {
|
||||
if (port == 0x0000)
|
||||
ret = dev->apm->cmd;
|
||||
else
|
||||
ret = dev->apm->stat;
|
||||
}
|
||||
|
||||
acpi_log("[%04X:%08X] APM read: %04X = %02X\n", CS, cpu_state.pc, port, ret);
|
||||
|
||||
@@ -1705,8 +1743,14 @@ acpi_init(const device_t *info)
|
||||
dev->irq_line = 9;
|
||||
|
||||
if ((dev->vendor == VEN_INTEL) || (dev->vendor == VEN_ALI)) {
|
||||
if (dev->vendor == VEN_ALI)
|
||||
dev->irq_mode = 2;
|
||||
dev->apm = device_add(&apm_pci_acpi_device);
|
||||
io_sethandler(0x00b2, 0x0002, acpi_apm_in, NULL, NULL, acpi_apm_out, NULL, NULL, dev);
|
||||
if (dev->vendor == VEN_ALI) {
|
||||
acpi_log("Setting I/O handler at port B1\n");
|
||||
io_sethandler(0x00b1, 0x0003, acpi_apm_in, NULL, NULL, acpi_apm_out, NULL, NULL, dev);
|
||||
} else
|
||||
io_sethandler(0x00b2, 0x0002, acpi_apm_in, NULL, NULL, acpi_apm_out, NULL, NULL, dev);
|
||||
} else if (dev->vendor == VEN_VIA) {
|
||||
dev->i2c = i2c_gpio_init("smbus_vt82c586b");
|
||||
i2c_smbus = i2c_gpio_get_bus(dev->i2c);
|
||||
|
||||
@@ -13,28 +13,13 @@
|
||||
# Copyright 2020,2021 David Hrdlička.
|
||||
#
|
||||
|
||||
add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1217.c ali1429.c ali1489.c et6000.c headland.c
|
||||
intel_82335.c cs4031.c intel_420ex.c intel_4x0.c intel_sio.c intel_piix.c ../ioapic.c
|
||||
neat.c opti283.c opti291.c opti495.c opti822.c opti895.c opti5x7.c scamp.c scat.c
|
||||
sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c
|
||||
umc_8886.c umc_8890.c umc_hb4.c
|
||||
via_vt82c49x.c via_vt82c505.c sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c
|
||||
gc100.c stpc.c
|
||||
via_apollo.c via_pipc.c wd76c10.c
|
||||
vl82c480.c)
|
||||
|
||||
if(I450KX)
|
||||
target_sources(chipset PRIVATE intel_i450kx.c)
|
||||
endif()
|
||||
|
||||
if(M154X)
|
||||
target_sources(chipset PRIVATE ali1531.c)
|
||||
target_sources(chipset PRIVATE ali1543.c)
|
||||
endif()
|
||||
|
||||
if(M6117)
|
||||
target_sources(chipset PRIVATE ali6117.c)
|
||||
endif()
|
||||
add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1489.c ali1531.c ali1541.c ali1543.c
|
||||
ali1621.c ali6117.c headland.c intel_82335.c contaq_82c59x.c cs4031.c intel_420ex.c
|
||||
intel_4x0.c intel_i450kx.c intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c
|
||||
opti495.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c
|
||||
sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c sis_85c310.c
|
||||
sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c umc_hb4.c via_apollo.c
|
||||
via_pipc.c vl82c480.c wd76c10.c)
|
||||
|
||||
if(OLIVETTI)
|
||||
target_sources(chipset PRIVATE olivetti_eva.c)
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the ALi M1217 chipset.
|
||||
*
|
||||
* Note: This chipset has no datasheet, everything were done via
|
||||
* reverse engineering the BIOS of various machines using it.
|
||||
*
|
||||
* Authors: Tiseno100
|
||||
*
|
||||
* Copyright 2021 Tiseno100
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
#ifdef ENABLE_ALI1217_LOG
|
||||
int ali1217_do_log = ENABLE_ALI1217_LOG;
|
||||
static void
|
||||
ali1217_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (ali1217_do_log)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define ali1217_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t index, regs[256];
|
||||
int cfg_locked;
|
||||
} ali1217_t;
|
||||
|
||||
static void ali1217_shadow_recalc(int reg_15, ali1217_t *dev)
|
||||
{
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
mem_set_mem_state_both((reg_15 ? 0xe0000 : 0xc0000) + (i << 15), 0x8000, ((dev->regs[0x14 + reg_15] & (1 << (i * 2))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x14 + reg_15] & (1 << ((i * 2) + 1))) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
ali1217_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
ali1217_t *dev = (ali1217_t *)priv;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
case 0x23:
|
||||
if (dev->index != 0x13)
|
||||
ali1217_log("ALi M1217: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
else
|
||||
dev->cfg_locked = !(val == 0xc5);
|
||||
|
||||
if (!dev->cfg_locked)
|
||||
{
|
||||
dev->regs[dev->index] = val;
|
||||
|
||||
if ((dev->index == 0x14) || (dev->index == 0x15))
|
||||
ali1217_shadow_recalc(dev->index & 1, dev);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
ali1217_read(uint16_t addr, void *priv)
|
||||
{
|
||||
ali1217_t *dev = (ali1217_t *)priv;
|
||||
|
||||
return (addr == 0x23) ? dev->regs[dev->index] : 0xff;
|
||||
}
|
||||
|
||||
static void
|
||||
ali1217_close(void *priv)
|
||||
{
|
||||
ali1217_t *dev = (ali1217_t *)priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
ali1217_init(const device_t *info)
|
||||
{
|
||||
ali1217_t *dev = (ali1217_t *)malloc(sizeof(ali1217_t));
|
||||
memset(dev, 0, sizeof(ali1217_t));
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
dev->cfg_locked = 1;
|
||||
|
||||
/*
|
||||
|
||||
ALi M1217 Ports
|
||||
|
||||
22h Index Port
|
||||
23h Data Port
|
||||
|
||||
*/
|
||||
io_sethandler(0x0022, 0x0002, ali1217_read, NULL, NULL, ali1217_write, NULL, NULL, dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t ali1217_device = {
|
||||
"ALi M1217",
|
||||
0,
|
||||
0,
|
||||
ali1217_init,
|
||||
ali1217_close,
|
||||
NULL,
|
||||
{NULL},
|
||||
NULL,
|
||||
NULL,
|
||||
NULL};
|
||||
@@ -8,15 +8,71 @@
|
||||
*
|
||||
* Implementation of the ALi M1429 chipset.
|
||||
*
|
||||
* Note: This chipset has no datasheet, everything were done via
|
||||
* reverse engineering the BIOS of various machines using it.
|
||||
* Note: This chipset has no datasheet, everything were done via
|
||||
* reverse engineering the BIOS of various machines using it.
|
||||
*
|
||||
* Authors: Tiseno100
|
||||
*
|
||||
* Copyright 2020 Tiseno100
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2020,2021 Tiseno100.
|
||||
* Copyright 2021,2021 Miran Grca.
|
||||
*/
|
||||
|
||||
/*
|
||||
ALi M1429/M1429G Configuration Registers
|
||||
|
||||
Notes: Incorporated sometimes with a M1435 PCI-to-VLB Bridge
|
||||
M1429G is just a 1429 with Green Functionality
|
||||
SMM in it's entirety needs more research
|
||||
|
||||
Warning: Register documentation may be inaccurate!
|
||||
|
||||
Register 03h: Write C5h to unlock the configuration registers
|
||||
|
||||
Register 10h & 11h: DRAM Bank Configuration
|
||||
|
||||
Register 12h:
|
||||
Bit 2: Memory Remapping Enable (128KB)
|
||||
|
||||
Register 13h:
|
||||
Bit 7: Shadow RAM Enable for F8000-FFFFF
|
||||
Bit 6: Shadow RAM Enable for F0000-F7FFF
|
||||
Bit 5: Shadow RAM Enable for E8000-FFFFF
|
||||
Bit 4: Shadow RAM Enable for E0000-F7FFF
|
||||
Bit 3: Shadow RAM Enable for D8000-FFFFF
|
||||
Bit 2: Shadow RAM Enable for D0000-F7FFF
|
||||
Bit 1: Shadow RAM Enable for C8000-FFFFF
|
||||
Bit 0: Shadow RAM Enable for C0000-F7FFF
|
||||
|
||||
Register 14h:
|
||||
Bit 1: Shadow RAM Write for Enabled Segments
|
||||
Bit 0: Shadow RAM Read for Enabled Segments
|
||||
|
||||
Register 18h:
|
||||
Bit 6-5-4 (Cache Size)
|
||||
0 0 0 32KB
|
||||
0 0 1 128KB
|
||||
0 1 0 256KB
|
||||
0 1 1 512KB
|
||||
1 0 0 64KB
|
||||
1 0 1 256KB
|
||||
1 1 0 512KB
|
||||
1 1 1 1MB
|
||||
|
||||
Bit 1: L2 Cache Enable
|
||||
|
||||
Register 20h:
|
||||
Bits 2-1-0: Bus Clock Speed
|
||||
0 0 0: 7.1519Mhz (ATCLK2)
|
||||
0 0 1: CLK2IN/4
|
||||
0 1 0: CLK2IN/5
|
||||
0 1 1: CLK2IN/6
|
||||
1 0 0: CLK2IN/8
|
||||
1 0 1: CLK2IN/10
|
||||
1 1 0: CLK2IN/12
|
||||
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -38,17 +94,19 @@
|
||||
#include <86box/smram.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#define disabled_shadow (MEM_READ_EXTANY | MEM_WRITE_EXTANY)
|
||||
#define GREEN dev->is_g /* Is G Variant */
|
||||
|
||||
|
||||
#ifdef ENABLE_ALI1429_LOG
|
||||
int ali1429_do_log = ENABLE_ALI1429_LOG;
|
||||
|
||||
|
||||
static void
|
||||
ali1429_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (ali1429_do_log)
|
||||
{
|
||||
if (ali1429_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
@@ -58,17 +116,17 @@ ali1429_log(const char *fmt, ...)
|
||||
#define ali1429_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t index, cfg_locked,
|
||||
regs[256];
|
||||
|
||||
smram_t *smram;
|
||||
uint8_t is_g, index, cfg_locked, reg_57h,
|
||||
regs[90];
|
||||
} ali1429_t;
|
||||
|
||||
static void ali1429_shadow_recalc(ali1429_t *dev)
|
||||
{
|
||||
|
||||
static void
|
||||
ali1429_shadow_recalc(ali1429_t *dev)
|
||||
{
|
||||
uint32_t base, i, can_write, can_read;
|
||||
|
||||
shadowbios = (dev->regs[0x13] & 0x40) && (dev->regs[0x14] & 0x01);
|
||||
@@ -77,66 +135,150 @@ static void ali1429_shadow_recalc(ali1429_t *dev)
|
||||
can_write = (dev->regs[0x14] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
can_read = (dev->regs[0x14] & 0x01) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
for (i = 0; i < 8; i++) {
|
||||
base = 0xc0000 + (i << 15);
|
||||
|
||||
if (dev->regs[0x13] & (1 << i))
|
||||
mem_set_mem_state_both(base, 0x8000, can_read | can_write);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x8000, disabled_shadow);
|
||||
mem_set_mem_state_both(base, 0x8000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1429_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
ali1429_t *dev = (ali1429_t *)priv;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
|
||||
case 0x23:
|
||||
if (dev->index != 0x03)
|
||||
ali1429_log("M1429: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
case 0x23:
|
||||
#ifdef ENABLE_ALI1429_LOG
|
||||
if (dev->index != 0x03)
|
||||
ali1429_log("M1429: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
#endif
|
||||
|
||||
if (dev->index == 0x03)
|
||||
dev->cfg_locked = !(val == 0xc5);
|
||||
if (dev->index == 0x03)
|
||||
dev->cfg_locked = !(val == 0xc5);
|
||||
|
||||
if (!dev->cfg_locked)
|
||||
{
|
||||
dev->regs[dev->index] = val;
|
||||
if (!dev->cfg_locked) {
|
||||
/* Common M1429 Registers */
|
||||
switch (dev->index) {
|
||||
case 0x10: case 0x11:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
switch (dev->index)
|
||||
{
|
||||
case 0x13:
|
||||
case 0x14:
|
||||
ali1429_shadow_recalc(dev);
|
||||
break;
|
||||
case 0x12:
|
||||
dev->regs[dev->index] = val;
|
||||
if(val & 4)
|
||||
mem_remap_top(128);
|
||||
else
|
||||
mem_remap_top(0);
|
||||
break;
|
||||
|
||||
case 0x18:
|
||||
cpu_cache_ext_enabled = !!(val & 2);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 0x13: case 0x14:
|
||||
dev->regs[dev->index] = val;
|
||||
ali1429_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
break;
|
||||
case 0x15: case 0x16:
|
||||
case 0x17:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x18:
|
||||
dev->regs[dev->index] = (val & 0x8f) | 0x20;
|
||||
cpu_cache_ext_enabled = !!(val & 2);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x19: case 0x1a:
|
||||
case 0x1e:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x20:
|
||||
dev->regs[dev->index] = val;
|
||||
|
||||
switch(val & 7) {
|
||||
case 0: case 7: /* Illegal */
|
||||
cpu_set_isa_speed(7159091);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
cpu_set_isa_speed(cpu_busspeed / 4);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
cpu_set_isa_speed(cpu_busspeed / 5);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
cpu_set_isa_speed(cpu_busspeed / 6);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
cpu_set_isa_speed(cpu_busspeed / 8);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
cpu_set_isa_speed(cpu_busspeed / 10);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
cpu_set_isa_speed(cpu_busspeed / 12);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x21 ... 0x27:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
}
|
||||
|
||||
/* M1429G Only Registers */
|
||||
if (GREEN) {
|
||||
switch (dev->index) {
|
||||
case 0x30 ... 0x41:
|
||||
case 0x43: case 0x45:
|
||||
case 0x4a:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x57:
|
||||
dev->reg_57h = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ali1429_read(uint16_t addr, void *priv)
|
||||
{
|
||||
ali1429_t *dev = (ali1429_t *)priv;
|
||||
return (addr == 0x23) ? dev->regs[dev->index] : 0xff;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if ((addr == 0x23) && (dev->index >= 0x10) && (dev->index <= 0x4a))
|
||||
ret = dev->regs[dev->index];
|
||||
else if ((addr == 0x23) && (dev->index == 0x57))
|
||||
ret = dev->reg_57h;
|
||||
else if (addr == 0x22)
|
||||
ret = dev->index;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1429_close(void *priv)
|
||||
{
|
||||
@@ -145,24 +287,53 @@ ali1429_close(void *priv)
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1429_defaults(ali1429_t *dev)
|
||||
{
|
||||
/* M1429 Defaults */
|
||||
dev->regs[0x10] = 0xf0;
|
||||
dev->regs[0x11] = 0xff;
|
||||
dev->regs[0x12] = 0x10;
|
||||
dev->regs[0x14] = 0x48;
|
||||
dev->regs[0x15] = 0x40;
|
||||
dev->regs[0x17] = 0x7a;
|
||||
dev->regs[0x1a] = 0x80;
|
||||
dev->regs[0x22] = 0x80;
|
||||
dev->regs[0x23] = 0x57;
|
||||
dev->regs[0x25] = 0xc0;
|
||||
dev->regs[0x27] = 0x30;
|
||||
|
||||
/* M1429G Default Registers */
|
||||
if (GREEN) {
|
||||
dev->regs[0x31] = 0x88;
|
||||
dev->regs[0x32] = 0xc0;
|
||||
dev->regs[0x38] = 0xe5;
|
||||
dev->regs[0x40] = 0xe3;
|
||||
dev->regs[0x41] = 2;
|
||||
dev->regs[0x45] = 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ali1429_init(const device_t *info)
|
||||
{
|
||||
ali1429_t *dev = (ali1429_t *)malloc(sizeof(ali1429_t));
|
||||
memset(dev, 0, sizeof(ali1429_t));
|
||||
|
||||
/*
|
||||
M1429 Ports:
|
||||
22h Index Port
|
||||
23h Data Port
|
||||
dev->cfg_locked = 1;
|
||||
GREEN = info->local;
|
||||
|
||||
/* M1429 Ports:
|
||||
22h Index Port
|
||||
23h Data Port
|
||||
*/
|
||||
io_sethandler(0x0022, 0x0002, ali1429_read, NULL, NULL, ali1429_write, NULL, NULL, dev);
|
||||
|
||||
dev->cfg_locked = 1;
|
||||
|
||||
device_add(&apm_device);
|
||||
device_add(&port_92_device);
|
||||
/* dev->smram = smram_add(); */
|
||||
|
||||
ali1429_defaults(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
@@ -171,10 +342,16 @@ const device_t ali1429_device = {
|
||||
"ALi M1429",
|
||||
0,
|
||||
0,
|
||||
ali1429_init,
|
||||
ali1429_close,
|
||||
NULL,
|
||||
{NULL},
|
||||
NULL,
|
||||
NULL,
|
||||
NULL};
|
||||
ali1429_init, ali1429_close, NULL,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
const device_t ali1429g_device = {
|
||||
"ALi M1429G",
|
||||
0,
|
||||
1,
|
||||
ali1429_init, ali1429_close, NULL,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
typedef struct ali1531_t
|
||||
{
|
||||
uint8_t pci_conf[256];
|
||||
@@ -41,201 +42,270 @@ typedef struct ali1531_t
|
||||
smram_t *smram;
|
||||
} ali1531_t;
|
||||
|
||||
void ali1531_shadow_recalc(int cur_reg, ali1531_t *dev)
|
||||
{
|
||||
for (uint32_t i = 0; i < 8; i++)
|
||||
mem_set_mem_state_both(0xc0000 + ((cur_reg & 1) << 17) + (i << 14), 0x4000, (((dev->pci_conf[0x4c + (cur_reg & 1)] >> i) & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | (((dev->pci_conf[0x4e + (cur_reg & 1)] >> i) & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
|
||||
|
||||
flushmmucache_nopc();
|
||||
#ifdef ENABLE_ALI1531_LOG
|
||||
int ali1531_do_log = ENABLE_ALI1531_LOG;
|
||||
static void
|
||||
ali1531_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (ali1531_do_log)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define ali1531_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
void ali1531_smm_recalc(uint8_t smm_state, ali1531_t *dev)
|
||||
|
||||
static void
|
||||
ali1531_smram_recalc(uint8_t val, ali1531_t *dev)
|
||||
{
|
||||
|
||||
smram_disable_all();
|
||||
|
||||
if (dev->pci_conf[0x48] & 1)
|
||||
{
|
||||
switch (smm_state)
|
||||
{
|
||||
case 0:
|
||||
smram_enable(dev->smram, 0xd0000, 0xb0000, 0x10000, 0, 1);
|
||||
smram_map(1, 0xd0000, 0x10000, 1);
|
||||
break;
|
||||
case 1:
|
||||
smram_enable(dev->smram, 0xd0000, 0xb0000, 0x10000, 1, 1);
|
||||
smram_map(1, 0xd0000, 0x10000, 1);
|
||||
break;
|
||||
case 2:
|
||||
smram_enable(dev->smram, 0xa0000, 0xa0000, 0x20000, 0, 1);
|
||||
smram_map(1, 0xa0000, 0x20000, (dev->pci_conf[0x48] & 0x10) ? 2 : 1);
|
||||
break;
|
||||
case 3:
|
||||
smram_enable(dev->smram, 0xa0000, 0xa0000, 0x20000, 1, 1);
|
||||
smram_map(1, 0xa0000, 0x20000, (dev->pci_conf[0x48] & 0x10) ? 2 : 1);
|
||||
break;
|
||||
case 4:
|
||||
smram_enable(dev->smram, 0x30000, 0xb0000, 0x10000, 0, 1);
|
||||
smram_map(1, 0x30000, 0x10000, 1);
|
||||
break;
|
||||
case 5:
|
||||
smram_enable(dev->smram, 0x30000, 0xb0000, 0x10000, 1, 1);
|
||||
smram_map(1, 0x30000, 0x10000, 1);
|
||||
break;
|
||||
}
|
||||
if (val & 1) {
|
||||
switch (val & 0x0c) {
|
||||
case 0x00:
|
||||
ali1531_log("SMRAM: D0000 -> B0000 (%i)\n", val & 2);
|
||||
smram_enable(dev->smram, 0xd0000, 0xb0000, 0x10000, val & 2, 1);
|
||||
if (val & 0x10)
|
||||
mem_set_mem_state_smram_ex(1, 0xd0000, 0x10000, 0x02);
|
||||
break;
|
||||
case 0x04:
|
||||
ali1531_log("SMRAM: A0000 -> A0000 (%i)\n", val & 2);
|
||||
smram_enable(dev->smram, 0xa0000, 0xa0000, 0x20000, val & 2, 1);
|
||||
if (val & 0x10)
|
||||
mem_set_mem_state_smram_ex(1, 0xa0000, 0x20000, 0x02);
|
||||
break;
|
||||
case 0x08:
|
||||
ali1531_log("SMRAM: 30000 -> B0000 (%i)\n", val & 2);
|
||||
smram_enable(dev->smram, 0x30000, 0xb0000, 0x10000, val & 2, 1);
|
||||
if (val & 0x10)
|
||||
mem_set_mem_state_smram_ex(1, 0x30000, 0x10000, 0x02);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1531_shadow_recalc(int cur_reg, ali1531_t *dev)
|
||||
{
|
||||
int i, bit, r_reg, w_reg;
|
||||
uint32_t base, flags = 0;
|
||||
|
||||
shadowbios = shadowbios_write = 0;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
base = 0x000c0000 + (i << 14);
|
||||
bit = i & 7;
|
||||
r_reg = 0x4c + (i >> 3);
|
||||
w_reg = 0x4e + (i >> 3);
|
||||
|
||||
flags = (dev->pci_conf[r_reg] & (1 << bit)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
flags |= ((dev->pci_conf[w_reg] & (1 << bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY);
|
||||
|
||||
if (base >= 0x000e0000) {
|
||||
if (dev->pci_conf[r_reg] & (1 << bit))
|
||||
shadowbios |= 1;
|
||||
if (dev->pci_conf[w_reg] & (1 << bit))
|
||||
shadowbios_write |= 1;
|
||||
}
|
||||
|
||||
ali1531_log("%08X-%08X shadow: R%c, W%c\n", base, base + 0x00003fff,
|
||||
(dev->pci_conf[r_reg] & (1 << bit)) ? 'I' : 'E', (dev->pci_conf[w_reg] & (1 << bit)) ? 'I' : 'E');
|
||||
mem_set_mem_state_both(base, 0x00004000, flags);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1531_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
ali1531_t *dev = (ali1531_t *)priv;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x05:
|
||||
dev->pci_conf[addr] = val & 1;
|
||||
break;
|
||||
switch (addr) {
|
||||
case 0x04:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x05:
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
case 0x07:
|
||||
dev->pci_conf[addr] &= ~(val & 0xf8);
|
||||
break;
|
||||
|
||||
case 0x0d:
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
case 0x0d:
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
dev->pci_conf[addr] = val & 0xf1;
|
||||
break;
|
||||
case 0x2c: /* Subsystem Vendor ID */
|
||||
case 0x2d:
|
||||
case 0x2e:
|
||||
case 0x2f:
|
||||
if (dev->pci_conf[0x70] & 0x08)
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x41:
|
||||
dev->pci_conf[addr] = val & 0xdf;
|
||||
break;
|
||||
case 0x40:
|
||||
dev->pci_conf[addr] = val & 0xf1;
|
||||
break;
|
||||
|
||||
case 0x42: /* L2 Cache */
|
||||
dev->pci_conf[addr] = val & 0xf7;
|
||||
cpu_cache_ext_enabled = !!(val & 1);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case 0x41:
|
||||
dev->pci_conf[addr] = (val & 0xd6) | 0x08;
|
||||
break;
|
||||
|
||||
case 0x43: /* L1 Cache */
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_int_enabled = !!(val & 1);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case 0x42: /* L2 Cache */
|
||||
dev->pci_conf[addr] = val & 0xf7;
|
||||
cpu_cache_ext_enabled = !!(val & 1);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x47:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
case 0x43: /* L1 Cache */
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_int_enabled = !!(val & 1);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
if (mem_size > 0xe00000)
|
||||
mem_set_mem_state_both(0xe00000, 0x100000, !(val & 0x20) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
case 0x44:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x45:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
if (mem_size > 0xf00000)
|
||||
mem_set_mem_state_both(0xf00000, 0x100000, !(val & 0x10) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
case 0x46:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
mem_set_mem_state_both(0xa0000, 0x20000, (val & 8) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
mem_set_mem_state_both(0x80000, 0x20000, (val & 4) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
break;
|
||||
case 0x47:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
|
||||
case 0x48: /* SMRAM */
|
||||
dev->pci_conf[addr] = val;
|
||||
ali1531_smm_recalc((val >> 1) & 7, dev);
|
||||
break;
|
||||
if (mem_size > 0xe00000)
|
||||
mem_set_mem_state_both(0xe00000, 0x100000, (val & 0x20) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL));
|
||||
|
||||
case 0x49:
|
||||
dev->pci_conf[addr] = val & 0x73;
|
||||
break;
|
||||
if (mem_size > 0xf00000)
|
||||
mem_set_mem_state_both(0xf00000, 0x100000, (val & 0x10) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL));
|
||||
|
||||
case 0x4c: /* Shadow RAM */
|
||||
case 0x4d:
|
||||
case 0x4e:
|
||||
case 0x4f:
|
||||
dev->pci_conf[addr] = val;
|
||||
ali1531_shadow_recalc(addr, dev);
|
||||
break;
|
||||
mem_set_mem_state_both(0xa0000, 0x20000, (val & 8) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
mem_set_mem_state_both(0x80000, 0x20000, (val & 4) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL));
|
||||
|
||||
case 0x57: /* H2PO */
|
||||
dev->pci_conf[addr] = val & 0x60;
|
||||
if (!(val & 0x20))
|
||||
outb(0x92, 0x01);
|
||||
break;
|
||||
flushmmucache_nopc();
|
||||
break;
|
||||
|
||||
case 0x58:
|
||||
dev->pci_conf[addr] = val & 0x83;
|
||||
break;
|
||||
case 0x48: /* SMRAM */
|
||||
dev->pci_conf[addr] = val;
|
||||
ali1531_smram_recalc(val, dev);
|
||||
break;
|
||||
|
||||
case 0x5b:
|
||||
dev->pci_conf[addr] = val & 0x4f;
|
||||
break;
|
||||
case 0x49:
|
||||
dev->pci_conf[addr] = val & 0x73;
|
||||
break;
|
||||
|
||||
case 0x5d:
|
||||
dev->pci_conf[addr] = val & 0x53;
|
||||
break;
|
||||
case 0x4a:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5f:
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
case 0x4c ... 0x4f: /* Shadow RAM */
|
||||
dev->pci_conf[addr] = val;
|
||||
ali1531_shadow_recalc(val, dev);
|
||||
break;
|
||||
|
||||
case 0x60: /* DRB's */
|
||||
case 0x61:
|
||||
case 0x62:
|
||||
case 0x63:
|
||||
case 0x64:
|
||||
case 0x65:
|
||||
case 0x66:
|
||||
case 0x67:
|
||||
case 0x68:
|
||||
case 0x69:
|
||||
case 0x6a:
|
||||
case 0x6b:
|
||||
case 0x6c:
|
||||
case 0x6d:
|
||||
case 0x6e:
|
||||
case 0x6f:
|
||||
dev->pci_conf[addr] = val;
|
||||
spd_write_drbs(dev->pci_conf, 0x60, 0x6f, 1);
|
||||
break;
|
||||
case 0x50: case 0x51: case 0x52: case 0x54:
|
||||
case 0x55: case 0x56:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x72:
|
||||
dev->pci_conf[addr] = val & 0xf;
|
||||
break;
|
||||
case 0x57: /* H2PO */
|
||||
dev->pci_conf[addr] = val & 0x60;
|
||||
/* Find where the Shut-down Special cycle is initiated. */
|
||||
// if (!(val & 0x20))
|
||||
// outb(0x92, 0x01);
|
||||
break;
|
||||
|
||||
case 0x74:
|
||||
dev->pci_conf[addr] = val & 0x2b;
|
||||
break;
|
||||
case 0x58:
|
||||
dev->pci_conf[addr] = val & 0x86;
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
dev->pci_conf[addr] = val & 0x84;
|
||||
break;
|
||||
case 0x59: case 0x5a:
|
||||
case 0x5c:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x81:
|
||||
dev->pci_conf[addr] = val & 0x81;
|
||||
break;
|
||||
case 0x5b:
|
||||
dev->pci_conf[addr] = val & 0x4f;
|
||||
break;
|
||||
|
||||
case 0x83:
|
||||
dev->pci_conf[addr] = val & 0x10;
|
||||
break;
|
||||
case 0x5d:
|
||||
dev->pci_conf[addr] = val & 0x53;
|
||||
break;
|
||||
|
||||
default:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x5f:
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x60 ... 0x6f: /* DRB's */
|
||||
dev->pci_conf[addr] = val;
|
||||
spd_write_drbs_interleaved(dev->pci_conf, 0x60, 0x6f, 1);
|
||||
break;
|
||||
|
||||
case 0x70: case 0x71:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x72:
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x74:
|
||||
dev->pci_conf[addr] = val & 0x2b;
|
||||
break;
|
||||
|
||||
case 0x76: case 0x77:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
dev->pci_conf[addr] = val & 0x84;
|
||||
break;
|
||||
|
||||
case 0x81:
|
||||
dev->pci_conf[addr] = val & 0x81;
|
||||
break;
|
||||
|
||||
case 0x83:
|
||||
dev->pci_conf[addr] = val & 0x10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ali1531_read(int func, int addr, void *priv)
|
||||
{
|
||||
ali1531_t *dev = (ali1531_t *)priv;
|
||||
return dev->pci_conf[addr];
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1531_reset(void *priv)
|
||||
{
|
||||
ali1531_t *dev = (ali1531_t *)priv;
|
||||
int i;
|
||||
|
||||
/* Default Registers */
|
||||
dev->pci_conf[0x00] = 0xb9;
|
||||
@@ -267,11 +337,20 @@ ali1531_reset(void *priv)
|
||||
|
||||
ali1531_write(0, 0x42, 0x00, dev);
|
||||
ali1531_write(0, 0x43, 0x00, dev);
|
||||
|
||||
ali1531_write(0, 0x47, 0x00, dev);
|
||||
ali1531_write(0, 0x60, 0x08, dev);
|
||||
ali1531_write(0, 0x61, 0x40, dev);
|
||||
ali1531_write(0, 0x48, 0x00, dev);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
ali1531_write(0, 0x4c + i, 0x00, dev);
|
||||
|
||||
for (i = 0; i < 16; i += 2) {
|
||||
ali1531_write(0, 0x60 + i, 0x08, dev);
|
||||
ali1531_write(0, 0x61 + i, 0x40, dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1531_close(void *priv)
|
||||
{
|
||||
@@ -281,6 +360,7 @@ ali1531_close(void *priv)
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ali1531_init(const device_t *info)
|
||||
{
|
||||
@@ -296,6 +376,7 @@ ali1531_init(const device_t *info)
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
const device_t ali1531_device = {
|
||||
"ALi M1531 CPU-to-PCI Bridge",
|
||||
DEVICE_PCI,
|
||||
@@ -306,4 +387,5 @@ const device_t ali1531_device = {
|
||||
{NULL},
|
||||
NULL,
|
||||
NULL,
|
||||
NULL};
|
||||
NULL
|
||||
};
|
||||
|
||||
656
src/chipset/ali1541.c
Normal file
656
src/chipset/ali1541.c
Normal file
@@ -0,0 +1,656 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the ALi M1541/2 CPU-to-PCI Bridge.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 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 <86box/timer.h>
|
||||
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
typedef struct ali1541_t
|
||||
{
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
smram_t * smram;
|
||||
void * agp_bridge;
|
||||
} ali1541_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_ALI1541_LOG
|
||||
int ali1541_do_log = ENABLE_ALI1541_LOG;
|
||||
static void
|
||||
ali1541_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (ali1541_do_log)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define ali1541_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
ali1541_smram_recalc(uint8_t val, ali1541_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
|
||||
if (val & 1) {
|
||||
switch (val & 0x0c) {
|
||||
case 0x00:
|
||||
ali1541_log("SMRAM: D0000 -> B0000 (%i)\n", val & 2);
|
||||
smram_enable(dev->smram, 0xd0000, 0xb0000, 0x10000, val & 2, 1);
|
||||
if (val & 0x10)
|
||||
mem_set_mem_state_smram_ex(1, 0xd0000, 0x10000, 0x02);
|
||||
break;
|
||||
case 0x04:
|
||||
ali1541_log("SMRAM: A0000 -> A0000 (%i)\n", val & 2);
|
||||
smram_enable(dev->smram, 0xa0000, 0xa0000, 0x20000, val & 2, 1);
|
||||
if (val & 0x10)
|
||||
mem_set_mem_state_smram_ex(1, 0xa0000, 0x20000, 0x02);
|
||||
break;
|
||||
case 0x08:
|
||||
ali1541_log("SMRAM: 30000 -> B0000 (%i)\n", val & 2);
|
||||
smram_enable(dev->smram, 0x30000, 0xb0000, 0x10000, val & 2, 1);
|
||||
if (val & 0x10)
|
||||
mem_set_mem_state_smram_ex(1, 0x30000, 0x10000, 0x02);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1541_shadow_recalc(int cur_reg, ali1541_t *dev)
|
||||
{
|
||||
int i, bit, r_reg, w_reg;
|
||||
uint32_t base, flags = 0;
|
||||
|
||||
shadowbios = shadowbios_write = 0;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
base = 0x000c0000 + (i << 14);
|
||||
bit = i & 7;
|
||||
r_reg = 0x56 + (i >> 3);
|
||||
w_reg = 0x58 + (i >> 3);
|
||||
|
||||
flags = (dev->pci_conf[r_reg] & (1 << bit)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
flags |= ((dev->pci_conf[w_reg] & (1 << bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY);
|
||||
|
||||
if (base >= 0x000e0000) {
|
||||
if (dev->pci_conf[r_reg] & (1 << bit))
|
||||
shadowbios |= 1;
|
||||
if (dev->pci_conf[w_reg] & (1 << bit))
|
||||
shadowbios_write |= 1;
|
||||
}
|
||||
|
||||
ali1541_log("%08X-%08X shadow: R%c, W%c\n", base, base + 0x00003fff,
|
||||
(dev->pci_conf[r_reg] & (1 << bit)) ? 'I' : 'E', (dev->pci_conf[w_reg] & (1 << bit)) ? 'I' : 'E');
|
||||
mem_set_mem_state_both(base, 0x00004000, flags);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1541_mask_bar(ali1541_t *dev)
|
||||
{
|
||||
uint32_t bar, mask;
|
||||
|
||||
switch (dev->pci_conf[0xbc] & 0x0f) {
|
||||
case 0x00:
|
||||
default:
|
||||
mask = 0x00000000;
|
||||
break;
|
||||
case 0x01:
|
||||
mask = 0xfff00000;
|
||||
break;
|
||||
case 0x02:
|
||||
mask = 0xffe00000;
|
||||
break;
|
||||
case 0x03:
|
||||
mask = 0xffc00000;
|
||||
break;
|
||||
case 0x04:
|
||||
mask = 0xff800000;
|
||||
break;
|
||||
case 0x06:
|
||||
mask = 0xff000000;
|
||||
break;
|
||||
case 0x07:
|
||||
mask = 0xfe000000;
|
||||
break;
|
||||
case 0x08:
|
||||
mask = 0xfc000000;
|
||||
break;
|
||||
case 0x09:
|
||||
mask = 0xf8000000;
|
||||
break;
|
||||
case 0x0a:
|
||||
mask = 0xf0000000;
|
||||
break;
|
||||
}
|
||||
|
||||
bar = ((dev->pci_conf[0x13] << 24) | (dev->pci_conf[0x12] << 16)) & mask;
|
||||
dev->pci_conf[0x12] = (bar >> 16) & 0xff;
|
||||
dev->pci_conf[0x13] = (bar >> 24) & 0xff;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1541_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
ali1541_t *dev = (ali1541_t *)priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x04:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x05:
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->pci_conf[addr] &= ~(val & 0xf8);
|
||||
break;
|
||||
|
||||
case 0x0d:
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
dev->pci_conf[0x12] = (val & 0xc0);
|
||||
ali1541_mask_bar(dev);
|
||||
break;
|
||||
case 0x13:
|
||||
dev->pci_conf[0x13] = val;
|
||||
ali1541_mask_bar(dev);
|
||||
break;
|
||||
|
||||
case 0x2c: /* Subsystem Vendor ID */
|
||||
case 0x2d:
|
||||
case 0x2e:
|
||||
case 0x2f:
|
||||
if (dev->pci_conf[0x90] & 0x01)
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x34:
|
||||
if (dev->pci_conf[0x90] & 0x02)
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x41:
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x42: /* L2 Cache */
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_ext_enabled = !!(val & 1);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x43: /* PLCTL-Pipe Line Control */
|
||||
dev->pci_conf[addr] = val & 0xf7;
|
||||
break;
|
||||
|
||||
case 0x44:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x45:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x46:
|
||||
dev->pci_conf[addr] = val & 0xf0;
|
||||
break;
|
||||
case 0x47:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x48:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x49:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x4a:
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x4b:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x4c:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x4d:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x4e:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x4f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
dev->pci_conf[addr] = val & 0x71;
|
||||
break;
|
||||
|
||||
case 0x51:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x52:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x53:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x54:
|
||||
dev->pci_conf[addr] = val & 0x3c;
|
||||
|
||||
if (mem_size > 0xe00000)
|
||||
mem_set_mem_state_both(0xe00000, 0x100000, (val & 0x20) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL));
|
||||
|
||||
if (mem_size > 0xf00000)
|
||||
mem_set_mem_state_both(0xf00000, 0x100000, (val & 0x10) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL));
|
||||
|
||||
mem_set_mem_state_both(0xa0000, 0x20000, (val & 8) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
mem_set_mem_state_both(0x80000, 0x20000, (val & 4) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL));
|
||||
|
||||
flushmmucache_nopc();
|
||||
break;
|
||||
|
||||
case 0x55: /* SMRAM */
|
||||
dev->pci_conf[addr] = val & 0x1f;
|
||||
ali1541_smram_recalc(val, dev);
|
||||
break;
|
||||
|
||||
case 0x56 ... 0x59: /* Shadow RAM */
|
||||
dev->pci_conf[addr] = val;
|
||||
ali1541_shadow_recalc(val, dev);
|
||||
break;
|
||||
|
||||
case 0x5a: case 0x5b:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5c:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5d:
|
||||
dev->pci_conf[addr] = val & 0x17;
|
||||
break;
|
||||
|
||||
case 0x5e:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5f:
|
||||
dev->pci_conf[addr] = val & 0xc1;
|
||||
break;
|
||||
|
||||
case 0x60 ... 0x6f: /* DRB's */
|
||||
dev->pci_conf[addr] = val;
|
||||
spd_write_drbs_interleaved(dev->pci_conf, 0x60, 0x6f, 1);
|
||||
break;
|
||||
|
||||
case 0x70:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x71:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x72:
|
||||
dev->pci_conf[addr] = val & 0xc7;
|
||||
break;
|
||||
|
||||
case 0x73:
|
||||
dev->pci_conf[addr] = val & 0x1f;
|
||||
break;
|
||||
|
||||
case 0x84: case 0x85:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x86:
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x87: /* H2PO */
|
||||
dev->pci_conf[addr] = val;
|
||||
/* Find where the Shut-down Special cycle is initiated. */
|
||||
// if (!(val & 0x20))
|
||||
// outb(0x92, 0x01);
|
||||
break;
|
||||
|
||||
case 0x88:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x89:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x8a:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x8b:
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x8c:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x8d:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x8e:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x8f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x90:
|
||||
dev->pci_conf[addr] = val;
|
||||
pci_bridge_set_ctl(dev->agp_bridge, val);
|
||||
break;
|
||||
|
||||
case 0x91:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xb4:
|
||||
if (dev->pci_conf[0x90] & 0x01)
|
||||
dev->pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
case 0xb5:
|
||||
if (dev->pci_conf[0x90] & 0x01)
|
||||
dev->pci_conf[addr] = val & 0x02;
|
||||
break;
|
||||
case 0xb7:
|
||||
if (dev->pci_conf[0x90] & 0x01)
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xb8:
|
||||
dev->pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
case 0xb9:
|
||||
dev->pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
case 0xbb:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xbc:
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
ali1541_mask_bar(dev);
|
||||
break;
|
||||
case 0xbd:
|
||||
dev->pci_conf[addr] = val & 0xf0;
|
||||
break;
|
||||
case 0xbe: case 0xbf:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xc0:
|
||||
dev->pci_conf[addr] = val & 0x90;
|
||||
break;
|
||||
case 0xc1: case 0xc2:
|
||||
case 0xc3:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xc8: case 0xc9:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xd1:
|
||||
dev->pci_conf[addr] = val & 0xf1;
|
||||
break;
|
||||
case 0xd2: case 0xd3:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xe0: case 0xe1:
|
||||
if (dev->pci_conf[0x90] & 0x20)
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0xe2:
|
||||
if (dev->pci_conf[0x90] & 0x20)
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
break;
|
||||
case 0xe3:
|
||||
if (dev->pci_conf[0x90] & 0x20)
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0xe4:
|
||||
if (dev->pci_conf[0x90] & 0x20)
|
||||
dev->pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
case 0xe5:
|
||||
if (dev->pci_conf[0x90] & 0x20)
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xe6:
|
||||
if (dev->pci_conf[0x90] & 0x20)
|
||||
dev->pci_conf[addr] = val & 0xc0;
|
||||
break;
|
||||
|
||||
case 0xe7:
|
||||
if (dev->pci_conf[0x90] & 0x20)
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xe8: case 0xe9:
|
||||
if (dev->pci_conf[0x90] & 0x04)
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xea:
|
||||
dev->pci_conf[addr] = val & 0xcf;
|
||||
break;
|
||||
|
||||
case 0xeb:
|
||||
dev->pci_conf[addr] = val & 0xcf;
|
||||
break;
|
||||
|
||||
case 0xec:
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0xed:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xee:
|
||||
dev->pci_conf[addr] = val & 0x3e;
|
||||
break;
|
||||
case 0xef:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xf3:
|
||||
dev->pci_conf[addr] = val & 0x08;
|
||||
break;
|
||||
|
||||
case 0xf5:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xf6:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xf7:
|
||||
dev->pci_conf[addr] = val & 0x43;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ali1541_read(int func, int addr, void *priv)
|
||||
{
|
||||
ali1541_t *dev = (ali1541_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1541_reset(void *priv)
|
||||
{
|
||||
ali1541_t *dev = (ali1541_t *)priv;
|
||||
int i;
|
||||
|
||||
/* Default Registers */
|
||||
dev->pci_conf[0x00] = 0xb9;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x41;
|
||||
dev->pci_conf[0x03] = 0x15;
|
||||
dev->pci_conf[0x04] = 0x06;
|
||||
dev->pci_conf[0x05] = 0x00;
|
||||
dev->pci_conf[0x06] = 0x10;
|
||||
dev->pci_conf[0x07] = 0x04;
|
||||
dev->pci_conf[0x08] = 0x00;
|
||||
dev->pci_conf[0x09] = 0x00;
|
||||
dev->pci_conf[0x0a] = 0x00;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
dev->pci_conf[0x0c] = 0x00;
|
||||
dev->pci_conf[0x0d] = 0x20;
|
||||
dev->pci_conf[0x0e] = 0x00;
|
||||
dev->pci_conf[0x0f] = 0x00;
|
||||
dev->pci_conf[0x2c] = 0xb9;
|
||||
dev->pci_conf[0x2d] = 0x10;
|
||||
dev->pci_conf[0x2e] = 0x41;
|
||||
dev->pci_conf[0x2f] = 0x15;
|
||||
dev->pci_conf[0x34] = 0xb0;
|
||||
dev->pci_conf[0x89] = 0x20;
|
||||
dev->pci_conf[0x8a] = 0x20;
|
||||
dev->pci_conf[0x91] = 0x13;
|
||||
dev->pci_conf[0xb0] = 0x02;
|
||||
dev->pci_conf[0xb1] = 0xe0;
|
||||
dev->pci_conf[0xb2] = 0x10;
|
||||
dev->pci_conf[0xb4] = 0x03;
|
||||
dev->pci_conf[0xb5] = 0x02;
|
||||
dev->pci_conf[0xb7] = 0x1c;
|
||||
dev->pci_conf[0xc8] = 0xbf;
|
||||
dev->pci_conf[0xc9] = 0x0a;
|
||||
dev->pci_conf[0xe0] = 0x01;
|
||||
|
||||
cpu_cache_int_enabled = 1;
|
||||
ali1541_write(0, 0x42, 0x00, dev);
|
||||
|
||||
ali1541_write(0, 0x54, 0x00, dev);
|
||||
ali1541_write(0, 0x55, 0x00, dev);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
ali1541_write(0, 0x56 + i, 0x00, dev);
|
||||
|
||||
ali1541_write(0, 0x60 + i, 0x07, dev);
|
||||
ali1541_write(0, 0x61 + i, 0x40, dev);
|
||||
for (i = 0; i < 14; i += 2) {
|
||||
ali1541_write(0, 0x62 + i, 0x00, dev);
|
||||
ali1541_write(0, 0x63 + i, 0x00, dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1541_close(void *priv)
|
||||
{
|
||||
ali1541_t *dev = (ali1541_t *)priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ali1541_init(const device_t *info)
|
||||
{
|
||||
ali1541_t *dev = (ali1541_t *)malloc(sizeof(ali1541_t));
|
||||
memset(dev, 0, sizeof(ali1541_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1541_read, ali1541_write, dev);
|
||||
|
||||
dev->smram = smram_add();
|
||||
|
||||
ali1541_reset(dev);
|
||||
|
||||
dev->agp_bridge = device_add(&ali5243_agp_device);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
const device_t ali1541_device = {
|
||||
"ALi M1541 CPU-to-PCI Bridge",
|
||||
DEVICE_PCI,
|
||||
0,
|
||||
ali1541_init,
|
||||
ali1541_close,
|
||||
ali1541_reset,
|
||||
{NULL},
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
685
src/chipset/ali1621.c
Normal file
685
src/chipset/ali1621.c
Normal file
@@ -0,0 +1,685 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the ALi M1621/2 CPU-to-PCI Bridge.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 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 <86box/timer.h>
|
||||
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
typedef struct ali1621_t
|
||||
{
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
smram_t * smram[2];
|
||||
} ali1621_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_ALI1621_LOG
|
||||
int ali1621_do_log = ENABLE_ALI1621_LOG;
|
||||
static void
|
||||
ali1621_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (ali1621_do_log)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define ali1621_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
/* Table translated to a more sensible format:
|
||||
Read cycles:
|
||||
SMREN SMM Mode Code Data
|
||||
0 X X PCI PCI
|
||||
1 0 Close PCI PCI
|
||||
1 0 Lock PCI PCI
|
||||
1 0 Protect PCI PCI
|
||||
1 0 Open DRAM DRAM
|
||||
1 1 Open DRAM DRAM
|
||||
1 1 Protect DRAM DRAM
|
||||
1 1 Close DRAM PCI
|
||||
1 1 Lock DRAM PCI
|
||||
|
||||
Write cycles:
|
||||
SMWEN SMM Mode Data
|
||||
0 X X PCI
|
||||
1 0 Close PCI
|
||||
1 0 Lock PCI
|
||||
1 0 Protect PCI
|
||||
1 0 Open DRAM
|
||||
1 1 Open DRAM
|
||||
1 1 Protect DRAM
|
||||
1 1 Close PCI
|
||||
1 1 Lock PCI
|
||||
|
||||
Explanation of the modes based above:
|
||||
If SM*EN = 0, SMRAM is entirely disabled, otherwise:
|
||||
If mode is Close or Lock, then SMRAM always goes to PCI outside SMM,
|
||||
and data to PCI, code to DRAM in SMM;
|
||||
If mode is Protect, then SMRAM always goes to PCI outside SMM and
|
||||
DRAM in SMM;
|
||||
If mode is Open, then SMRAM always goes to DRAM.
|
||||
Read and write are enabled separately.
|
||||
*/
|
||||
static void
|
||||
ali1621_smram_recalc(uint8_t val, ali1621_t *dev)
|
||||
{
|
||||
uint16_t access_smm = 0x0000, access_normal = 0x0000;
|
||||
|
||||
smram_disable_all();
|
||||
|
||||
if (val & 0xc0) {
|
||||
/* SMRAM 0: A0000-BFFFF */
|
||||
if (val & 0x80) {
|
||||
access_smm = ACCESS_SMRAM_X;
|
||||
|
||||
switch (val & 0x30) {
|
||||
case 0x10: /* Open. */
|
||||
access_normal = ACCESS_SMRAM_RX;
|
||||
/* FALLTHROUGH */
|
||||
case 0x30: /* Protect. */
|
||||
access_smm |= ACCESS_SMRAM_R;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (val & 0x40) switch (val & 0x30) {
|
||||
case 0x10: /* Open. */
|
||||
access_normal |= ACCESS_SMRAM_W;
|
||||
/* FALLTHROUGH */
|
||||
case 0x30: /* Protect. */
|
||||
access_smm |= ACCESS_SMRAM_W;
|
||||
break;
|
||||
}
|
||||
|
||||
smram_enable(dev->smram[0], 0xa0000, 0xa0000, 0x20000, ((val & 0x30) == 0x10), (val & 0x30));
|
||||
|
||||
mem_set_access(ACCESS_NORMAL, 3, 0xa0000, 0x20000, access_normal);
|
||||
mem_set_access(ACCESS_SMM, 3, 0xa0000, 0x20000, access_smm);
|
||||
}
|
||||
|
||||
if (val & 0x08)
|
||||
smram_enable(dev->smram[1], 0x38000, 0xa8000, 0x08000, 0, 1);
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1621_shadow_recalc(int cur_reg, ali1621_t *dev)
|
||||
{
|
||||
int i, r_bit, w_bit, reg;
|
||||
uint32_t base, flags = 0;
|
||||
|
||||
shadowbios = shadowbios_write = 0;
|
||||
|
||||
/* C0000-EFFFF */
|
||||
for (i = 0; i < 12; i++) {
|
||||
base = 0x000c0000 + (i << 14);
|
||||
r_bit = (i << 1) + 4;
|
||||
reg = 0x84;
|
||||
if (r_bit > 23) {
|
||||
r_bit &= 7;
|
||||
reg += 3;
|
||||
} else if (r_bit > 15) {
|
||||
r_bit &= 7;
|
||||
reg += 2;
|
||||
} else if (r_bit > 7) {
|
||||
r_bit &= 7;
|
||||
reg++;
|
||||
}
|
||||
w_bit = r_bit + 1;
|
||||
|
||||
flags = (dev->pci_conf[reg] & (1 << r_bit)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
flags |= ((dev->pci_conf[reg] & (1 << w_bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY);
|
||||
|
||||
if (base >= 0x000e0000) {
|
||||
if (dev->pci_conf[reg] & (1 << r_bit))
|
||||
shadowbios |= 1;
|
||||
if (dev->pci_conf[reg] & (1 << r_bit))
|
||||
shadowbios_write |= 1;
|
||||
}
|
||||
|
||||
ali1621_log("%08X-%08X shadow: R%c, W%c\n", base, base + 0x00003fff,
|
||||
(dev->pci_conf[reg] & (1 << r_bit)) ? 'I' : 'E', (dev->pci_conf[reg] & (1 << w_bit)) ? 'I' : 'E');
|
||||
mem_set_mem_state_both(base, 0x00004000, flags);
|
||||
}
|
||||
|
||||
/* F0000-FFFFF */
|
||||
base = 0x000f0000;
|
||||
r_bit = 4;
|
||||
w_bit = 5;
|
||||
reg = 0x87;
|
||||
|
||||
flags = (dev->pci_conf[reg] & (1 << r_bit)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
flags |= ((dev->pci_conf[reg] & (1 << w_bit)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY);
|
||||
|
||||
if (dev->pci_conf[reg] & (1 << r_bit))
|
||||
shadowbios |= 1;
|
||||
if (dev->pci_conf[reg] & (1 << r_bit))
|
||||
shadowbios_write |= 1;
|
||||
|
||||
ali1621_log("%08X-%08X shadow: R%c, W%c\n", base, base + 0x0000ffff,
|
||||
(dev->pci_conf[reg] & (1 << r_bit)) ? 'I' : 'E', (dev->pci_conf[reg] & (1 << w_bit)) ? 'I' : 'E');
|
||||
mem_set_mem_state_both(base, 0x00010000, flags);
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1621_mask_bar(ali1621_t *dev)
|
||||
{
|
||||
uint32_t bar, mask;
|
||||
|
||||
switch (dev->pci_conf[0xbc] & 0x0f) {
|
||||
case 0x00:
|
||||
default:
|
||||
mask = 0x00000000;
|
||||
break;
|
||||
case 0x01:
|
||||
mask = 0xfff00000;
|
||||
break;
|
||||
case 0x02:
|
||||
mask = 0xffe00000;
|
||||
break;
|
||||
case 0x03:
|
||||
mask = 0xffc00000;
|
||||
break;
|
||||
case 0x04:
|
||||
mask = 0xff800000;
|
||||
break;
|
||||
case 0x06:
|
||||
mask = 0xff000000;
|
||||
break;
|
||||
case 0x07:
|
||||
mask = 0xfe000000;
|
||||
break;
|
||||
case 0x08:
|
||||
mask = 0xfc000000;
|
||||
break;
|
||||
case 0x09:
|
||||
mask = 0xf8000000;
|
||||
break;
|
||||
case 0x0a:
|
||||
mask = 0xf0000000;
|
||||
break;
|
||||
}
|
||||
|
||||
bar = ((dev->pci_conf[0x13] << 24) | (dev->pci_conf[0x12] << 16)) & mask;
|
||||
dev->pci_conf[0x12] = (bar >> 16) & 0xff;
|
||||
dev->pci_conf[0x13] = (bar >> 24) & 0xff;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1621_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
ali1621_t *dev = (ali1621_t *)priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x04:
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
case 0x05:
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->pci_conf[addr] &= ~(val & 0xf0);
|
||||
break;
|
||||
|
||||
case 0x0d:
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
dev->pci_conf[0x12] = (val & 0xc0);
|
||||
ali1621_mask_bar(dev);
|
||||
break;
|
||||
case 0x13:
|
||||
dev->pci_conf[0x13] = val;
|
||||
ali1621_mask_bar(dev);
|
||||
break;
|
||||
|
||||
case 0x34:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x41:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x42:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x43:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x44:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x45:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x46:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x47:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x48:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x49:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x4a:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x4b:
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x4c:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x4d:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x4e:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x4f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
dev->pci_conf[addr] = val & 0xef;
|
||||
break;
|
||||
|
||||
case 0x51:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x52:
|
||||
dev->pci_conf[addr] = val & 0x9f;
|
||||
break;
|
||||
|
||||
case 0x53:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x54:
|
||||
dev->pci_conf[addr] = val & 0xb4;
|
||||
break;
|
||||
case 0x55:
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
|
||||
case 0x56:
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x57:
|
||||
dev->pci_conf[addr] = val & 0x08;
|
||||
break;
|
||||
|
||||
case 0x58:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x59:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5a:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5c:
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x61:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x62:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x63:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x64:
|
||||
dev->pci_conf[addr] = val & 0xb7;
|
||||
break;
|
||||
case 0x65:
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
|
||||
case 0x66:
|
||||
dev->pci_conf[addr] &= ~(val & 0x33);
|
||||
break;
|
||||
|
||||
case 0x67:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x68:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x69:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x6c ... 0x7b:
|
||||
/* Bits 22:20 = DRAM Row size:
|
||||
- 000: 4 MB;
|
||||
- 001: 8 MB;
|
||||
- 010: 16 MB;
|
||||
- 011: 32 MB;
|
||||
- 100: 64 MB;
|
||||
- 101: 128 MB;
|
||||
- 110: 256 MB;
|
||||
- 111: Reserved. */
|
||||
dev->pci_conf[addr] = val;
|
||||
spd_write_drbs_ali1621(dev->pci_conf, 0x6c, 0x7b);
|
||||
break;
|
||||
|
||||
case 0x7c ... 0x7f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x81:
|
||||
dev->pci_conf[addr] = val & 0xdf;
|
||||
break;
|
||||
|
||||
case 0x82:
|
||||
dev->pci_conf[addr] = val & 0xf7;
|
||||
break;
|
||||
|
||||
case 0x83:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
ali1621_smram_recalc(val & 0xfc, dev);
|
||||
break;
|
||||
|
||||
case 0x84 ... 0x87:
|
||||
if (addr == 0x87)
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
else
|
||||
dev->pci_conf[addr] = val;
|
||||
ali1621_shadow_recalc(val, dev);
|
||||
break;
|
||||
|
||||
case 0x88: case 0x89:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x8a:
|
||||
dev->pci_conf[addr] = val & 0xc5;
|
||||
break;
|
||||
case 0x8b:
|
||||
dev->pci_conf[addr] = val & 0xbf;
|
||||
break;
|
||||
|
||||
case 0x8c ... 0x8f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x90:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x91:
|
||||
dev->pci_conf[addr] = val & 0x07;
|
||||
break;
|
||||
|
||||
case 0x94 ... 0x97:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x98 ... 0x9b:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x9c ... 0x9f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xa0: case 0xa1:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xbc:
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
ali1621_mask_bar(dev);
|
||||
break;
|
||||
case 0xbd:
|
||||
dev->pci_conf[addr] = val & 0xf0;
|
||||
break;
|
||||
case 0xbe: case 0xbf:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xc0:
|
||||
dev->pci_conf[addr] = val & 0xb1;
|
||||
break;
|
||||
|
||||
case 0xc4 ... 0xc7:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xc8:
|
||||
dev->pci_conf[addr] = val & 0x8c;
|
||||
break;
|
||||
case 0xc9:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0xca:
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
case 0xcb:
|
||||
dev->pci_conf[addr] = val & 0x87;
|
||||
break;
|
||||
|
||||
case 0xcc ... 0xcf:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xd0:
|
||||
dev->pci_conf[addr] = val & 0x80;
|
||||
break;
|
||||
case 0xd2:
|
||||
dev->pci_conf[addr] = val & 0x40;
|
||||
break;
|
||||
case 0xd3:
|
||||
dev->pci_conf[addr] = val & 0xb0;
|
||||
break;
|
||||
|
||||
case 0xd4:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0xd5:
|
||||
dev->pci_conf[addr] = val & 0xef;
|
||||
break;
|
||||
case 0xd6: case 0xd7:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xf0 ... 0xff:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ali1621_read(int func, int addr, void *priv)
|
||||
{
|
||||
ali1621_t *dev = (ali1621_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1621_reset(void *priv)
|
||||
{
|
||||
ali1621_t *dev = (ali1621_t *)priv;
|
||||
int i;
|
||||
|
||||
/* Default Registers */
|
||||
dev->pci_conf[0x00] = 0xb9;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x21;
|
||||
dev->pci_conf[0x03] = 0x16;
|
||||
dev->pci_conf[0x04] = 0x06;
|
||||
dev->pci_conf[0x05] = 0x00;
|
||||
dev->pci_conf[0x06] = 0x10;
|
||||
dev->pci_conf[0x07] = 0x04;
|
||||
dev->pci_conf[0x08] = 0x01;
|
||||
dev->pci_conf[0x09] = 0x00;
|
||||
dev->pci_conf[0x0a] = 0x00;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
dev->pci_conf[0x10] = 0x08;
|
||||
dev->pci_conf[0x34] = 0xb0;
|
||||
dev->pci_conf[0x40] = 0x0c;
|
||||
dev->pci_conf[0x41] = 0x0c;
|
||||
dev->pci_conf[0x4c] = 0x04;
|
||||
dev->pci_conf[0x4d] = 0x04;
|
||||
dev->pci_conf[0x4e] = 0x7f;
|
||||
dev->pci_conf[0x4f] = 0x7f;
|
||||
dev->pci_conf[0x50] = 0x0c;
|
||||
dev->pci_conf[0x53] = 0x02;
|
||||
dev->pci_conf[0x5a] = 0x02;
|
||||
dev->pci_conf[0x63] = 0x02;
|
||||
dev->pci_conf[0x6c] = dev->pci_conf[0x70] = dev->pci_conf[0x74] = dev->pci_conf[0x78] = 0xff;
|
||||
dev->pci_conf[0x6d] = dev->pci_conf[0x71] = dev->pci_conf[0x75] = dev->pci_conf[0x79] = 0xff;
|
||||
dev->pci_conf[0x6e] = dev->pci_conf[0x72] = dev->pci_conf[0x76] = dev->pci_conf[0x7a] = 0x00;
|
||||
dev->pci_conf[0x6f] = dev->pci_conf[0x73] = dev->pci_conf[0x77] = dev->pci_conf[0x7b] = 0xe0;
|
||||
dev->pci_conf[0x6f] |= 0x06;
|
||||
dev->pci_conf[0x7c] = 0x11;
|
||||
dev->pci_conf[0x7d] = 0xc4;
|
||||
dev->pci_conf[0x7e] = 0xc7;
|
||||
dev->pci_conf[0x80] = 0x01;
|
||||
dev->pci_conf[0x81] = 0xc0;
|
||||
dev->pci_conf[0x8e] = 0x01;
|
||||
dev->pci_conf[0xa0] = 0x20;
|
||||
dev->pci_conf[0xb0] = 0x02;
|
||||
dev->pci_conf[0xb2] = 0x10;
|
||||
dev->pci_conf[0xb4] = 0x03;
|
||||
dev->pci_conf[0xb5] = 0x02;
|
||||
dev->pci_conf[0xb7] = 0x20;
|
||||
dev->pci_conf[0xc0] = 0x80;
|
||||
dev->pci_conf[0xc9] = 0x28;
|
||||
dev->pci_conf[0xd4] = 0x10;
|
||||
dev->pci_conf[0xd5] = 0x01;
|
||||
dev->pci_conf[0xf0] = dev->pci_conf[0xf4] = dev->pci_conf[0xf8] = dev->pci_conf[0xfc] = 0x20;
|
||||
dev->pci_conf[0xf1] = dev->pci_conf[0xf5] = dev->pci_conf[0xf9] = dev->pci_conf[0xfd] = 0x43;
|
||||
dev->pci_conf[0xf2] = dev->pci_conf[0xf6] = dev->pci_conf[0xfa] = dev->pci_conf[0xfe] = 0x21;
|
||||
dev->pci_conf[0xf3] = dev->pci_conf[0xf7] = dev->pci_conf[0xfb] = dev->pci_conf[0xff] = 0x43;
|
||||
|
||||
ali1621_write(0, 0x83, 0x08, dev);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
ali1621_write(0, 0x84 + i, 0x00, dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1621_close(void *priv)
|
||||
{
|
||||
ali1621_t *dev = (ali1621_t *)priv;
|
||||
|
||||
smram_del(dev->smram[1]);
|
||||
smram_del(dev->smram[0]);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ali1621_init(const device_t *info)
|
||||
{
|
||||
ali1621_t *dev = (ali1621_t *)malloc(sizeof(ali1621_t));
|
||||
memset(dev, 0, sizeof(ali1621_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1621_read, ali1621_write, dev);
|
||||
|
||||
dev->smram[0] = smram_add();
|
||||
dev->smram[1] = smram_add();
|
||||
|
||||
ali1621_reset(dev);
|
||||
|
||||
device_add(&ali5247_agp_device);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
const device_t ali1621_device = {
|
||||
"ALi M1621 CPU-to-PCI Bridge",
|
||||
DEVICE_PCI,
|
||||
0,
|
||||
ali1621_init,
|
||||
ali1621_close,
|
||||
ali1621_reset,
|
||||
{NULL},
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -109,7 +109,7 @@ ali6117_recalcmapping(ali6117_t *dev)
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
@@ -127,12 +127,16 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv)
|
||||
else if (dev->unlocked) {
|
||||
ali6117_log("ALI6117: regs[%02X] = %02X\n", dev->reg_offset, val);
|
||||
|
||||
switch (dev->reg_offset) {
|
||||
if (!(dev->local & 0x08) || (dev->reg_offset < 0x30)) switch (dev->reg_offset) {
|
||||
case 0x30: case 0x34: case 0x35: case 0x3e:
|
||||
case 0x3f: case 0x46: case 0x4c: case 0x6a:
|
||||
case 0x73:
|
||||
return; /* read-only registers */
|
||||
|
||||
case 0x10:
|
||||
refresh_at_enable = !(val & 0x02) || !!(dev->regs[0x20] & 0x80);
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
val &= 0xf7;
|
||||
/* FALL-THROUGH */
|
||||
@@ -184,7 +188,7 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv)
|
||||
|
||||
case 0x20:
|
||||
val &= 0xbf;
|
||||
refresh_at_enable = !!(val & 0x80);
|
||||
refresh_at_enable = !(dev->regs[0x10] & 0x02) || !!(val & 0x80);
|
||||
break;
|
||||
|
||||
case 0x31:
|
||||
@@ -311,13 +315,17 @@ ali6117_reset(void *priv)
|
||||
dev->regs[0x1b] = 0xf0;
|
||||
dev->regs[0x1d] = 0xff;
|
||||
dev->regs[0x20] = 0x80;
|
||||
dev->regs[0x30] = 0x08;
|
||||
dev->regs[0x31] = 0x01;
|
||||
dev->regs[0x34] = 0x04; /* enable internal RTC */
|
||||
dev->regs[0x35] = 0x20; /* enable internal KBC */
|
||||
dev->regs[0x36] = dev->local & 0x4; /* M6117D ID */
|
||||
if (dev->local & 0x08) {
|
||||
dev->regs[0x30] = 0x08;
|
||||
dev->regs[0x31] = 0x01;
|
||||
dev->regs[0x34] = 0x04; /* enable internal RTC */
|
||||
dev->regs[0x35] = 0x20; /* enable internal KBC */
|
||||
dev->regs[0x36] = dev->local & 0x07; /* M6117D ID */
|
||||
}
|
||||
|
||||
cpu_set_isa_speed(7159091);
|
||||
|
||||
refresh_at_enable = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -361,13 +369,28 @@ ali6117_init(const device_t *info)
|
||||
ali6117_setup(dev);
|
||||
ali6117_reset(dev);
|
||||
|
||||
pic_elcr_io_handler(0);
|
||||
refresh_at_enable = 0;
|
||||
if (!(dev->local & 0x08))
|
||||
pic_elcr_io_handler(0);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
const device_t ali1217_device =
|
||||
{
|
||||
"ALi M1217",
|
||||
DEVICE_AT,
|
||||
0x8,
|
||||
ali6117_init,
|
||||
ali6117_close,
|
||||
ali6117_reset,
|
||||
{ NULL },
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
const device_t ali6117d_device =
|
||||
{
|
||||
"ALi M6117D",
|
||||
|
||||
375
src/chipset/contaq_82c59x.c
Normal file
375
src/chipset/contaq_82c59x.c
Normal file
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the Contaq/Cypress 82C596(A) and 597 chipsets.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 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/mem.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
#ifdef ENABLE_CONTAQ_82C59X_LOG
|
||||
int contaq_82c59x_do_log = ENABLE_CONTAQ_82C59X_LOG;
|
||||
|
||||
static void
|
||||
contaq_82c59x_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (contaq_82c59x_do_log)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define contaq_82c59x_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t phys, virt;
|
||||
} mem_remapping_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t index, green,
|
||||
smi_status_set,
|
||||
regs[256], smi_status[2];
|
||||
|
||||
smram_t *smram[2];
|
||||
} contaq_82c59x_t;
|
||||
|
||||
|
||||
static void
|
||||
contaq_82c59x_isa_speed_recalc(contaq_82c59x_t *dev)
|
||||
{
|
||||
if (dev->regs[0x1c] & 0x02)
|
||||
cpu_set_isa_speed(7159091);
|
||||
else {
|
||||
/* TODO: ISA clock dividers for 386 and alt. 486. */
|
||||
switch (dev->regs[0x10] & 0x03) {
|
||||
case 0x00:
|
||||
cpu_set_isa_speed(cpu_busspeed / 4);
|
||||
break;
|
||||
case 0x01:
|
||||
cpu_set_isa_speed(cpu_busspeed / 6);
|
||||
break;
|
||||
case 0x02:
|
||||
cpu_set_isa_speed(cpu_busspeed / 8);
|
||||
break;
|
||||
case 0x03:
|
||||
cpu_set_isa_speed(cpu_busspeed / 5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
contaq_82c59x_shadow_recalc(contaq_82c59x_t *dev)
|
||||
{
|
||||
uint32_t i, base;
|
||||
uint8_t bit;
|
||||
|
||||
shadowbios = shadowbios_write = 0;
|
||||
|
||||
/* F0000-FFFFF */
|
||||
if (dev->regs[0x15] & 0x80) {
|
||||
shadowbios |= 1;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
|
||||
} else {
|
||||
shadowbios_write |= 1;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
}
|
||||
|
||||
/* C0000-CFFFF */
|
||||
if (dev->regs[0x15] & 0x01)
|
||||
mem_set_mem_state_both(0xc0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else {
|
||||
for (i = 0; i < 4; i++) {
|
||||
base = 0xc0000 + (i << 14);
|
||||
bit = 1 << (i + 2);
|
||||
if (dev->regs[0x15] & bit) {
|
||||
if (dev->regs[0x15] & 0x02)
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->green) {
|
||||
/* D0000-DFFFF */
|
||||
if (dev->regs[0x6e] & 0x01)
|
||||
mem_set_mem_state_both(0xd0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else {
|
||||
for (i = 0; i < 4; i++) {
|
||||
base = 0xd0000 + (i << 14);
|
||||
bit = 1 << (i + 2);
|
||||
if (dev->regs[0x6e] & bit) {
|
||||
if (dev->regs[0x6e] & 0x02)
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
}
|
||||
|
||||
/* E0000-EFFFF */
|
||||
if (dev->regs[0x6f] & 0x01)
|
||||
mem_set_mem_state_both(0xe0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else {
|
||||
for (i = 0; i < 4; i++) {
|
||||
base = 0xe0000 + (i << 14);
|
||||
bit = 1 << (i + 2);
|
||||
if (dev->regs[0x6f] & bit) {
|
||||
shadowbios |= 1;
|
||||
if (dev->regs[0x6f] & 0x02)
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
else {
|
||||
shadowbios_write |= 1;
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
}
|
||||
} else
|
||||
mem_set_mem_state_both(base, 0x04000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
contaq_82c59x_smram_recalc(contaq_82c59x_t *dev)
|
||||
{
|
||||
smram_disable(dev->smram[1]);
|
||||
|
||||
if (dev->regs[0x70] & 0x04)
|
||||
smram_enable(dev->smram[1], 0x00040000, 0x000a0000, 0x00020000, 1, 1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
contaq_82c59x_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
contaq_82c59x_t *dev = (contaq_82c59x_t *)priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
|
||||
case 0x23:
|
||||
contaq_82c59x_log("Contaq 82C59x: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
|
||||
if ((dev->index >= 0x60) && !dev->green)
|
||||
return;
|
||||
|
||||
switch (dev->index) {
|
||||
/* Registers common to 82C596(A) and 82C597. */
|
||||
case 0x10:
|
||||
dev->regs[dev->index] = val;
|
||||
contaq_82c59x_isa_speed_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x11:
|
||||
dev->regs[dev->index] = val;
|
||||
cpu_cache_int_enabled = !!(val & 0x01);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x12: case 0x13:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x14:
|
||||
dev->regs[dev->index] = val;
|
||||
reset_on_hlt = !!(val & 0x80);
|
||||
break;
|
||||
|
||||
case 0x15:
|
||||
dev->regs[dev->index] = val;
|
||||
contaq_82c59x_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x16 ... 0x1b:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x1c:
|
||||
/* TODO: What's NPRST (generated if bit 3 is set)? */
|
||||
dev->regs[dev->index] = val;
|
||||
contaq_82c59x_isa_speed_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x1d ... 0x1f:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
/* Green (82C597-specific) registers. */
|
||||
case 0x60 ... 0x63:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x64:
|
||||
dev->regs[dev->index] = val;
|
||||
if (val & 0x80) {
|
||||
if (dev->regs[0x65] & 0x80)
|
||||
smi_line = 1;
|
||||
dev->smi_status[0] |= 0x10;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x65 ... 0x69:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x6a:
|
||||
dev->regs[dev->index] = val;
|
||||
dev->smi_status_set = !!(val & 0x80);
|
||||
break;
|
||||
|
||||
case 0x6b ... 0x6d:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x6e: case 0x6f:
|
||||
dev->regs[dev->index] = val;
|
||||
contaq_82c59x_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x70:
|
||||
dev->regs[dev->index] = val;
|
||||
contaq_82c59x_smram_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x71 ... 0x79:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x7b: case 0x7c:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
contaq_82c59x_read(uint16_t addr, void *priv)
|
||||
{
|
||||
contaq_82c59x_t *dev = (contaq_82c59x_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (addr == 0x23) {
|
||||
if (dev->index == 0x6a) {
|
||||
ret = dev->smi_status[dev->smi_status_set];
|
||||
/* I assume it's cleared on read. */
|
||||
dev->smi_status[dev->smi_status_set] = 0x00;
|
||||
} else
|
||||
ret = dev->regs[dev->index];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
contaq_82c59x_close(void *priv)
|
||||
{
|
||||
contaq_82c59x_t *dev = (contaq_82c59x_t *)priv;
|
||||
|
||||
smram_del(dev->smram[1]);
|
||||
smram_del(dev->smram[0]);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
contaq_82c59x_init(const device_t *info)
|
||||
{
|
||||
contaq_82c59x_t *dev = (contaq_82c59x_t *)malloc(sizeof(contaq_82c59x_t));
|
||||
memset(dev, 0x00, sizeof(contaq_82c59x_t));
|
||||
|
||||
dev->green = info->local;
|
||||
|
||||
io_sethandler(0x0022, 0x0002, contaq_82c59x_read, NULL, NULL, contaq_82c59x_write, NULL, NULL, dev);
|
||||
|
||||
contaq_82c59x_isa_speed_recalc(dev);
|
||||
|
||||
cpu_cache_int_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
reset_on_hlt = 0;
|
||||
|
||||
contaq_82c59x_shadow_recalc(dev);
|
||||
|
||||
if (dev->green) {
|
||||
/* SMRAM 0: Fixed A0000-BFFFF to A0000-BFFFF DRAM. */
|
||||
dev->smram[0] = smram_add();
|
||||
smram_enable(dev->smram[0], 0x000a0000, 0x000a0000, 0x00020000, 0, 1);
|
||||
|
||||
/* SMRAM 1: Optional. */
|
||||
dev->smram[1] = smram_add();
|
||||
contaq_82c59x_smram_recalc(dev);
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
const device_t contaq_82c596a_device = {
|
||||
"Contaq 82C596A",
|
||||
0,
|
||||
0,
|
||||
contaq_82c59x_init,
|
||||
contaq_82c59x_close,
|
||||
NULL,
|
||||
{ NULL },
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
const device_t contaq_82c597_device = {
|
||||
"Contaq 82C597",
|
||||
0,
|
||||
1,
|
||||
contaq_82c59x_init,
|
||||
contaq_82c59x_close,
|
||||
NULL,
|
||||
{ NULL },
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
411
src/chipset/ims8848.c
Normal file
411
src/chipset/ims8848.c
Normal file
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the IMS 8848/8849 chipset.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Tiseno100,
|
||||
*
|
||||
* Copyright 2021 Miran Grca.
|
||||
* Copyright 2021 Tiseno100.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
/*
|
||||
IMS 884x Configuration Registers
|
||||
|
||||
Note: IMS 884x are rebadged ATMEL AT 40411/40412 chipsets
|
||||
|
||||
By: Tiseno100, Miran Grca(OBattler)
|
||||
|
||||
Register 00h:
|
||||
Bit 3: F0000-FFFFF Shadow Enable
|
||||
Bit 2: E0000-EFFFF Shadow Enable
|
||||
Bit 0: ????
|
||||
|
||||
Register 04h:
|
||||
Bit 3: Cache Write Hit Wait State
|
||||
Bit 2: Cache Read Hit Wait State
|
||||
|
||||
Register 06h:
|
||||
Bit 3: System BIOS Cacheable (1: Yes / 0: No)
|
||||
Bit 1: Power Management Mode (1: IRQ / 0: SMI#)
|
||||
|
||||
Register 08h:
|
||||
Bit 2: System BIOS Shadow Write (1: Enable / 0: Disable)
|
||||
Bit 1: System BIOS Shadow Read?
|
||||
|
||||
Register 0Dh:
|
||||
Bit 0: IO 100H-3FFH Idle Detect (1: Enable / 0: Disable)
|
||||
|
||||
Register 0Eh:
|
||||
Bit 7: DMA & Local Bus Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 6: Floppy Disk Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 5: IDE Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 4: Serial Port Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 3: Parallel Port Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 2: Keyboard Idle Detect (1: Enable / 0: Disable)
|
||||
Bit 1: Video Idle Detect (1: Enable / 0: Disable)
|
||||
|
||||
Register 12h:
|
||||
Bits 3-2: Power Saving Timer (00 = 1 MIN, 01 = 3 MIN, 10 = 5 MIN, 11 = 8 MIN)
|
||||
Bit 1: Base Memory (1: 512KB / 0: 640KB)
|
||||
|
||||
Register 1Ah:
|
||||
Bit 3: Cache Write Hit W/S For PCI (1: Enabled / 0: Disable)
|
||||
Bit 2: Cache Read Hit W/S For PCI (1: Enabled / 0: Disable)
|
||||
Bit 1: VESA Clock Skew (1: 4ns/6ns, 0: No Delay/2ns)
|
||||
|
||||
Register 1Bh:
|
||||
Bit 6: Enable SMRAM (always at 30000-4FFFF) in SMM
|
||||
Bit 5: ????
|
||||
Bit 4: Software SMI#
|
||||
Bit 3: DC000-DFFFF Shadow Enable
|
||||
Bit 2: D8000-DBFFF Shadow Enable
|
||||
Bit 1: D4000-D7FFF Shadow Enable
|
||||
Bit 0: D0000-D3FFF Shadow Enable
|
||||
|
||||
Register 1Ch:
|
||||
Bits 7-4: INTA IRQ routing (0 = disabled, 1 to F = IRQ)
|
||||
Bit 3: CC000-CFFFF Shadow Enable
|
||||
Bit 2: C8000-CBFFF Shadow Enable
|
||||
Bit 1: C4000-C7FFF Shadow Enable
|
||||
Bit 0: C0000-C3FFF Shadow Enable
|
||||
|
||||
Register 1Dh:
|
||||
Bits 7-4: INTB IRQ routing (0 = disabled, 1 to F = IRQ)
|
||||
|
||||
Register 1Eh:
|
||||
Bits 7-4: INTC IRQ routing (0 = disabled, 1 to F = IRQ)
|
||||
Bit 1: C4000-C7FFF Cacheable
|
||||
Bit 0: C0000-C3FFF Cacheable
|
||||
|
||||
Register 21h:
|
||||
Bits 7-4: INTD IRQ routing (0 = disabled, 1 to F = IRQ)
|
||||
|
||||
Register 22h:
|
||||
Bit 5: Local Bus Master #2 select (0 = VESA, 1 = PCI)
|
||||
Bit 4: Local Bus Master #1 select (0 = VESA, 1 = PCI)
|
||||
Bits 1-0: Internal HADS# Delay Always (00 = No Delay, 01 = 1 Clk, 10 = 2 Clks)
|
||||
|
||||
Register 23h:
|
||||
Bit 7: Seven Bits Tag (1: Enabled / 0: Disable)
|
||||
Bit 3: Extend LBRDY#(VL Master) (1: Enabled / 0: Disable)
|
||||
Bit 2: Sync LRDY#(VL Slave) (1: Enabled / 0: Disable)
|
||||
Bit 0: HADS# Delay After LB. Cycle (1: Enabled / 0: Disable)
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t idx, access_data,
|
||||
regs[256], pci_conf[256];
|
||||
|
||||
smram_t *smram;
|
||||
} ims8848_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_IMS8848_LOG
|
||||
int ims8848_do_log = ENABLE_IMS8848_LOG;
|
||||
|
||||
|
||||
static void
|
||||
ims8848_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (ims8848_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define ims8848_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
/* Shadow write always enabled, 1B and 1C control C000-DFFF read. */
|
||||
static void
|
||||
ims8848_recalc(ims8848_t *dev)
|
||||
{
|
||||
int i, state_on;
|
||||
uint32_t base;
|
||||
ims8848_log("SHADOW: 00 = %02X, 08 = %02X, 1B = %02X, 1C = %02X\n",
|
||||
dev->regs[0x00], dev->regs[0x08], dev->regs[0x1b], dev->regs[0x1c]);
|
||||
|
||||
state_on = MEM_READ_INTERNAL;
|
||||
state_on |= (dev->regs[0x08] & 0x04) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
base = 0xe0000 + (i << 16);
|
||||
if (dev->regs[0x00] & (1 << (i + 2)))
|
||||
mem_set_mem_state_both(base, 0x10000, state_on);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
base = 0xc0000 + (i << 14);
|
||||
if (dev->regs[0x1c] & (1 << i))
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
|
||||
base = 0xd0000 + (i << 14);
|
||||
if (dev->regs[0x1b] & (1 << i))
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ims8848_base_memory(ims8848_t *dev)
|
||||
{
|
||||
/* We can use the proper mem_set_access to handle that. */
|
||||
mem_set_mem_state_both(0x80000, 0x20000, (dev->regs[0x12] & 2) ?
|
||||
(MEM_READ_DISABLED | MEM_WRITE_DISABLED) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ims8848_smram(ims8848_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
|
||||
smram_enable(dev->smram, 0x00030000, 0x00030000, 0x20000, dev->regs[0x1b] & 0x40, 1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ims8848_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
ims8848_t *dev = (ims8848_t *) priv;
|
||||
uint8_t old = dev->regs[dev->idx];
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
ims8848_log("[W] IDX = %02X\n", val);
|
||||
dev->idx = val;
|
||||
break;
|
||||
case 0x23:
|
||||
ims8848_log("[W] IDX IN = %02X\n", val);
|
||||
if (((val & 0x0f) == ((dev->idx >> 4) & 0x0f)) && ((val & 0xf0) == ((dev->idx << 4) & 0xf0)))
|
||||
dev->access_data = 1;
|
||||
break;
|
||||
case 0x24:
|
||||
ims8848_log("[W] [%i] REG %02X = %02X\n", dev->access_data, dev->idx, val);
|
||||
if (dev->access_data) {
|
||||
dev->regs[dev->idx] = val;
|
||||
switch (dev->idx) {
|
||||
case 0x00: case 0x08: case 0x1b: case 0x1c:
|
||||
/* Shadow RAM */
|
||||
ims8848_recalc(dev);
|
||||
if (dev->idx == 0x1b) {
|
||||
ims8848_smram(dev);
|
||||
if (!(old & 0x10) && (val & 0x10))
|
||||
smi_line = 1;
|
||||
} else if (dev->idx == 0x1c)
|
||||
pci_set_irq_routing(PCI_INTA, (val >> 4) ? (val >> 4) : PCI_IRQ_DISABLED);
|
||||
break;
|
||||
|
||||
case 0x1d: case 0x1e:
|
||||
pci_set_irq_routing(PCI_INTB + (dev->idx - 0x1d), (val >> 4) ? (val >> 4) : PCI_IRQ_DISABLED);
|
||||
break;
|
||||
case 0x21:
|
||||
pci_set_irq_routing(PCI_INTD, (val >> 4) ? (val >> 4) : PCI_IRQ_DISABLED);
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
/* Base Memory */
|
||||
ims8848_base_memory(dev);
|
||||
break;
|
||||
}
|
||||
dev->access_data = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ims8848_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
ims8848_t *dev = (ims8848_t *) priv;
|
||||
#ifdef ENABLE_IMS8848_LOG
|
||||
uint8_t old_ad = dev->access_data;
|
||||
#endif
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
ims8848_log("[R] IDX = %02X\n", ret);
|
||||
ret = dev->idx;
|
||||
break;
|
||||
case 0x23:
|
||||
ims8848_log("[R] IDX IN = %02X\n", ret);
|
||||
ret = (dev->idx >> 4) | (dev->idx << 4);
|
||||
break;
|
||||
case 0x24:
|
||||
if (dev->access_data) {
|
||||
ret = dev->regs[dev->idx];
|
||||
dev->access_data = 0;
|
||||
}
|
||||
ims8848_log("[R] [%i] REG %02X = %02X\n", old_ad, dev->idx, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ims8849_pci_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
ims8848_t *dev = (ims8848_t *)priv;
|
||||
|
||||
ims8848_log("IMS 884x-PCI: dev->regs[%02x] = %02x POST: %02x\n", addr, val, inb(0x80));
|
||||
|
||||
if (func == 0) switch (addr) {
|
||||
case 0x04:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
dev->pci_conf[addr] = val & 3;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->pci_conf[addr] &= val & 0xf7;
|
||||
break;
|
||||
|
||||
case 0x0c ... 0x0d:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x52 ... 0x55:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ims8849_pci_read(int func, int addr, void *priv)
|
||||
{
|
||||
ims8848_t *dev = (ims8848_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0)
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ims8848_reset(void *priv)
|
||||
{
|
||||
ims8848_t *dev = (ims8848_t *)priv;
|
||||
|
||||
memset(dev->regs, 0x00, sizeof(dev->regs));
|
||||
memset(dev->pci_conf, 0x00, sizeof(dev->pci_conf));
|
||||
|
||||
dev->pci_conf[0x00] = 0xe0; /* Integrated Micro Solutions (IMS) */
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x49; /* 8849 */
|
||||
dev->pci_conf[0x03] = 0x88;
|
||||
|
||||
dev->pci_conf[0x04] = 0x07;
|
||||
dev->pci_conf[0x07] = 0x02;
|
||||
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
|
||||
ims8848_recalc(dev); /* Shadow RAM Setup */
|
||||
ims8848_base_memory(dev); /* Base Memory Setup */
|
||||
|
||||
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);
|
||||
|
||||
ims8848_smram(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ims8848_close(void *priv)
|
||||
{
|
||||
ims8848_t *dev = (ims8848_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ims8848_init(const device_t *info)
|
||||
{
|
||||
ims8848_t *dev = (ims8848_t *) malloc(sizeof(ims8848_t));
|
||||
memset(dev, 0, sizeof(ims8848_t));
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
/* IMS 8848:
|
||||
22h Index
|
||||
23h Data Unlock
|
||||
24h Data
|
||||
|
||||
IMS 8849:
|
||||
PCI Device 0: IMS 8849 Dummy for compatibility reasons
|
||||
*/
|
||||
io_sethandler(0x0022, 0x0003, ims8848_read, NULL, NULL, ims8848_write, NULL, NULL, dev);
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ims8849_pci_read, ims8849_pci_write, dev);
|
||||
|
||||
dev->smram = smram_add();
|
||||
smram_set_separate_smram(1);
|
||||
|
||||
cpu_cache_ext_enabled = 1;
|
||||
cpu_update_waitstates();
|
||||
|
||||
ims8848_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
const device_t ims8848_device = {
|
||||
"IMS 8848/8849",
|
||||
0,
|
||||
0,
|
||||
ims8848_init, ims8848_close, ims8848_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -55,6 +55,7 @@ typedef struct
|
||||
smram_locked, max_drb,
|
||||
drb_unit, drb_default;
|
||||
uint8_t regs[256], regs_locked[256];
|
||||
uint8_t mem_state[256];
|
||||
int type;
|
||||
smram_t *smram_low, *smram_high;
|
||||
} i4x0_t;
|
||||
@@ -81,23 +82,18 @@ i4x0_log(const char *fmt, ...)
|
||||
|
||||
|
||||
static void
|
||||
i4x0_map(uint32_t addr, uint32_t size, int state)
|
||||
i4x0_map(i4x0_t *dev, uint32_t addr, uint32_t size, int state)
|
||||
{
|
||||
switch (state & 3) {
|
||||
case 0:
|
||||
mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
uint32_t base = addr >> 12;
|
||||
int states[4] = { MEM_READ_EXTANY | MEM_WRITE_EXTANY, MEM_READ_INTERNAL | MEM_WRITE_EXTANY,
|
||||
MEM_READ_EXTANY | MEM_WRITE_INTERNAL, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL };
|
||||
|
||||
state &= 3;
|
||||
if (dev->mem_state[base] != state) {
|
||||
mem_set_mem_state_both(addr, size, states[state]);
|
||||
dev->mem_state[base] = state;
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
@@ -584,10 +580,10 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x59: /* PAM0 */
|
||||
if (dev->type <= INTEL_430NX) {
|
||||
if ((regs[0x59] ^ val) & 0x0f)
|
||||
i4x0_map(0x80000, 0x20000, val & 0x0f);
|
||||
i4x0_map(dev, 0x80000, 0x20000, val & 0x0f);
|
||||
}
|
||||
if ((regs[0x59] ^ val) & 0xf0) {
|
||||
i4x0_map(0xf0000, 0x10000, val >> 4);
|
||||
i4x0_map(dev, 0xf0000, 0x10000, val >> 4);
|
||||
shadowbios = (val & 0x10);
|
||||
}
|
||||
if (dev->type > INTEL_430NX)
|
||||
@@ -597,44 +593,44 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case 0x5a: /* PAM1 */
|
||||
if ((regs[0x5a] ^ val) & 0x0f)
|
||||
i4x0_map(0xc0000, 0x04000, val & 0xf);
|
||||
i4x0_map(dev, 0xc0000, 0x04000, val & 0xf);
|
||||
if ((regs[0x5a] ^ val) & 0xf0)
|
||||
i4x0_map(0xc4000, 0x04000, val >> 4);
|
||||
i4x0_map(dev, 0xc4000, 0x04000, val >> 4);
|
||||
regs[0x5a] = val & 0x77;
|
||||
break;
|
||||
case 0x5b: /*PAM2 */
|
||||
if ((regs[0x5b] ^ val) & 0x0f)
|
||||
i4x0_map(0xc8000, 0x04000, val & 0xf);
|
||||
i4x0_map(dev, 0xc8000, 0x04000, val & 0xf);
|
||||
if ((regs[0x5b] ^ val) & 0xf0)
|
||||
i4x0_map(0xcc000, 0x04000, val >> 4);
|
||||
i4x0_map(dev, 0xcc000, 0x04000, val >> 4);
|
||||
regs[0x5b] = val & 0x77;
|
||||
break;
|
||||
case 0x5c: /*PAM3 */
|
||||
if ((regs[0x5c] ^ val) & 0x0f)
|
||||
i4x0_map(0xd0000, 0x04000, val & 0xf);
|
||||
i4x0_map(dev, 0xd0000, 0x04000, val & 0xf);
|
||||
if ((regs[0x5c] ^ val) & 0xf0)
|
||||
i4x0_map(0xd4000, 0x04000, val >> 4);
|
||||
i4x0_map(dev, 0xd4000, 0x04000, val >> 4);
|
||||
regs[0x5c] = val & 0x77;
|
||||
break;
|
||||
case 0x5d: /* PAM4 */
|
||||
if ((regs[0x5d] ^ val) & 0x0f)
|
||||
i4x0_map(0xd8000, 0x04000, val & 0xf);
|
||||
i4x0_map(dev, 0xd8000, 0x04000, val & 0xf);
|
||||
if ((regs[0x5d] ^ val) & 0xf0)
|
||||
i4x0_map(0xdc000, 0x04000, val >> 4);
|
||||
i4x0_map(dev, 0xdc000, 0x04000, val >> 4);
|
||||
regs[0x5d] = val & 0x77;
|
||||
break;
|
||||
case 0x5e: /* PAM5 */
|
||||
if ((regs[0x5e] ^ val) & 0x0f)
|
||||
i4x0_map(0xe0000, 0x04000, val & 0xf);
|
||||
i4x0_map(dev, 0xe0000, 0x04000, val & 0xf);
|
||||
if ((regs[0x5e] ^ val) & 0xf0)
|
||||
i4x0_map(0xe4000, 0x04000, val >> 4);
|
||||
i4x0_map(dev, 0xe4000, 0x04000, val >> 4);
|
||||
regs[0x5e] = val & 0x77;
|
||||
break;
|
||||
case 0x5f: /* PAM6 */
|
||||
if ((regs[0x5f] ^ val) & 0x0f)
|
||||
i4x0_map(0xe8000, 0x04000, val & 0xf);
|
||||
i4x0_map(dev, 0xe8000, 0x04000, val & 0xf);
|
||||
if ((regs[0x5f] ^ val) & 0xf0)
|
||||
i4x0_map(0xec000, 0x04000, val >> 4);
|
||||
i4x0_map(dev, 0xec000, 0x04000, val >> 4);
|
||||
regs[0x5f] = val & 0x77;
|
||||
break;
|
||||
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64:
|
||||
@@ -1303,11 +1299,11 @@ static void
|
||||
regs[0x0d] = 0x20;
|
||||
/* According to information from FreeBSD 3.x source code:
|
||||
0x00 = 486DX, 0x20 = 486SX, 0x40 = 486DX2 or 486DX4, 0x80 = Pentium OverDrive. */
|
||||
if (!(hasfpu) && (cpu_multi = 1))
|
||||
if (!(hasfpu) && (cpu_multi == 1))
|
||||
regs[0x50] = 0x20;
|
||||
else if (!(hasfpu) && (cpu_multi = 2))
|
||||
else if (!(hasfpu) && (cpu_multi == 2))
|
||||
regs[0x50] = 0x60; /* Guess based on the SX, DX, and DX2 values. */
|
||||
else if (hasfpu && (cpu_multi = 1))
|
||||
else if (hasfpu && (cpu_multi == 1))
|
||||
regs[0x50] = 0x00;
|
||||
else if (hasfpu && (cpu_multi >= 2) && !(cpu_s->cpu_type == CPU_P24T))
|
||||
regs[0x50] = 0x40;
|
||||
|
||||
@@ -58,71 +58,95 @@ i450kx_log(const char *fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
/* Shadow RAM Flags */
|
||||
#define LSB_DECISION (((shadow_value & 1) ? MEM_READ_EXTANY : MEM_READ_INTERNAL) | ((shadow_value & 2) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL))
|
||||
#define MSB_DECISION (((shadow_value & 0x10) ? MEM_READ_EXTANY : MEM_READ_INTERNAL) | ((shadow_value & 0x20) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL))
|
||||
#define LSB_DECISION_MC (((shadow_value & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((shadow_value & 2) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY))
|
||||
#define MSB_DECISION_MC (((shadow_value & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((shadow_value & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY))
|
||||
|
||||
/* SMRAM */
|
||||
#define SMRAM_ADDR (((dev->pb_pci_conf[0xb9] << 8) | dev->pb_pci_conf[0xb8]) << 17)
|
||||
#define SMRAM_ADDR_MC (((dev->mc_pci_conf[0xb9] << 8) | dev->mc_pci_conf[0xb8]) << 16)
|
||||
#define SMRAM_SIZE (((dev->pb_pci_conf[0xbb] >> 4) + 1) * 64)
|
||||
#define SMRAM_SIZE_MC (((dev->mc_pci_conf[0xbb] >> 4) + 1) * 64)
|
||||
|
||||
/* Miscellaneous */
|
||||
#define ENABLE_SEGMENT (MEM_READ_EXTANY | MEM_WRITE_EXTANY)
|
||||
#define DISABLE_SEGMENT (MEM_READ_DISABLED | MEM_WRITE_DISABLED)
|
||||
|
||||
|
||||
/* TODO: Finish the bus index stuff. */
|
||||
typedef struct i450kx_t {
|
||||
smram_t *smram;
|
||||
smram_t * smram[2];
|
||||
|
||||
uint8_t pb_pci_conf[256], mc_pci_conf[256];
|
||||
uint8_t pb_pci_conf[256], mc_pci_conf[256];
|
||||
uint8_t mem_state[2][256];
|
||||
|
||||
uint8_t bus_index;
|
||||
} i450kx_t;
|
||||
|
||||
|
||||
static void
|
||||
i450kx_shadow(int is_mc, int cur_reg, uint8_t shadow_value, i450kx_t *dev)
|
||||
i450kx_map(i450kx_t *dev, int bus, uint32_t addr, uint32_t size, int state)
|
||||
{
|
||||
if (cur_reg == 0x59) {
|
||||
mem_set_mem_state_both(0x80000, 0x20000, (is_mc) ? LSB_DECISION_MC : LSB_DECISION);
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, (is_mc) ? MSB_DECISION_MC : MSB_DECISION);
|
||||
} else {
|
||||
mem_set_mem_state_both(0xc0000 + (((cur_reg & 7) - 2) * 0x8000), 0x4000, (is_mc) ? LSB_DECISION_MC : LSB_DECISION);
|
||||
mem_set_mem_state_both(0xc4000 + (((cur_reg & 7) - 2) * 0x8000), 0x4000, (is_mc) ? MSB_DECISION_MC : MSB_DECISION);
|
||||
uint32_t base = addr >> 12;
|
||||
int states[4] = { MEM_READ_EXTANY | MEM_WRITE_EXTANY, MEM_READ_INTERNAL | MEM_WRITE_EXTANY,
|
||||
MEM_READ_EXTANY | MEM_WRITE_INTERNAL, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL };
|
||||
|
||||
state &= 3;
|
||||
if (dev->mem_state[bus][base] != state) {
|
||||
if (bus)
|
||||
mem_set_mem_state_bus_both(addr, size, states[state]);
|
||||
else
|
||||
mem_set_mem_state_cpu_both(addr, size, states[state]);
|
||||
dev->mem_state[bus][base] = state;
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i450kx_smm(uint32_t smram_addr, uint32_t smram_size, i450kx_t *dev)
|
||||
i450kx_smram_recalc(i450kx_t *dev, int bus)
|
||||
{
|
||||
smram_disable_all();
|
||||
uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf;
|
||||
uint32_t addr, size;
|
||||
|
||||
if ((smram_addr != 0) && !!(dev->mc_pci_conf[0x57] & 8))
|
||||
smram_enable(dev->smram, smram_addr, smram_addr, smram_size, !!(dev->pb_pci_conf[0x57] & 8), 1);
|
||||
smram_disable(dev->smram[bus]);
|
||||
|
||||
addr = ((uint32_t) regs[0xb8] << 16) | ((uint32_t) regs[0xb9] << 24);
|
||||
size = (((uint32_t) ((regs[0xbb] >> 4) & 0x0f)) << 16) + 0x00010000;
|
||||
|
||||
if ((addr != 0x00000000) && !!(regs[0x57] & 0x08)) {
|
||||
if (bus)
|
||||
smram_enable_ex(dev->smram[bus], addr, addr, size, 0, !!(regs[0x57] & 8), 0, 1);
|
||||
else
|
||||
smram_enable_ex(dev->smram[bus], addr, addr, size, !!(regs[0x57] & 8), 0, 1, 0);
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i450kx_vid_buf_recalc(i450kx_t *dev, int bus)
|
||||
{
|
||||
uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf;
|
||||
|
||||
// int state = (regs[0x58] & 0x02) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_DISABLED | MEM_WRITE_DISABLED);
|
||||
int state = (regs[0x58] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
|
||||
if (bus)
|
||||
mem_set_mem_state_bus_both(0x000a0000, 0x00020000, state);
|
||||
else
|
||||
mem_set_mem_state_cpu_both(0x000a0000, 0x00020000, state);
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pb_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
i450kx_t *dev = (i450kx_t *)priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x04:
|
||||
dev->pb_pci_conf[addr] &= val & 0xd7;
|
||||
break;
|
||||
// pclog("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80));
|
||||
i450kx_log("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80));
|
||||
|
||||
case 0x06:
|
||||
dev->pb_pci_conf[addr] = val & 0x80;
|
||||
if (func == 0) switch (addr) {
|
||||
case 0x04:
|
||||
dev->pb_pci_conf[addr] = (dev->pb_pci_conf[addr] & 0x04) | (val & 0x53);
|
||||
break;
|
||||
case 0x05:
|
||||
dev->pb_pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->pb_pci_conf[addr] &= ~(val & 0xf9);
|
||||
break;
|
||||
|
||||
case 0x0d:
|
||||
dev->pb_pci_conf[addr] = val;
|
||||
break;
|
||||
@@ -131,63 +155,106 @@ pb_write(int func, int addr, uint8_t val, void *priv)
|
||||
dev->pb_pci_conf[addr] = val & 0xcf;
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
case 0x41:
|
||||
case 0x40: case 0x41:
|
||||
dev->pb_pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x43:
|
||||
dev->pb_pci_conf[addr] = val & 0x80;
|
||||
break;
|
||||
|
||||
case 0x48:
|
||||
dev->pb_pci_conf[addr] = val & 6;
|
||||
dev->pb_pci_conf[addr] = val & 0x06;
|
||||
break;
|
||||
|
||||
case 0x4a:
|
||||
case 0x4b:
|
||||
case 0x4a: case 0x4b:
|
||||
dev->pb_pci_conf[addr] = val;
|
||||
// if (addr == 0x4a)
|
||||
// pci_remap_bus(dev->bus_index, val);
|
||||
break;
|
||||
|
||||
case 0x4c:
|
||||
dev->pb_pci_conf[addr] = val & 0xd8;
|
||||
dev->pb_pci_conf[addr] = (dev->pb_pci_conf[addr] & 0x01) | (val & 0xd8);
|
||||
break;
|
||||
|
||||
case 0x51:
|
||||
dev->pb_pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x53:
|
||||
dev->pb_pci_conf[addr] = val & 2;
|
||||
dev->pb_pci_conf[addr] = val & 0x02;
|
||||
break;
|
||||
|
||||
case 0x54:
|
||||
dev->pb_pci_conf[addr] = val & 0x7b;
|
||||
break;
|
||||
|
||||
case 0x55:
|
||||
dev->pb_pci_conf[addr] = val & 2;
|
||||
dev->pb_pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
|
||||
case 0x57:
|
||||
dev->pb_pci_conf[addr] = val & 8;
|
||||
i450kx_smm(SMRAM_ADDR, SMRAM_SIZE, dev);
|
||||
dev->pb_pci_conf[addr] = val & 0x08;
|
||||
i450kx_smram_recalc(dev, 1);
|
||||
break;
|
||||
|
||||
case 0x58:
|
||||
dev->pb_pci_conf[addr] = val & 2;
|
||||
mem_set_mem_state_both(0xa0000, 0x20000, (val & 2) ? ENABLE_SEGMENT : DISABLE_SEGMENT);
|
||||
dev->pb_pci_conf[addr] = val & 0x02;
|
||||
i450kx_vid_buf_recalc(dev, 1);
|
||||
break;
|
||||
|
||||
case 0x59:
|
||||
case 0x5a:
|
||||
case 0x5b:
|
||||
case 0x5c:
|
||||
case 0x5d:
|
||||
case 0x5e:
|
||||
case 0x5f:
|
||||
dev->pb_pci_conf[addr] = val & 0x33;
|
||||
i450kx_shadow(0, addr, val, dev);
|
||||
case 0x59: /* PAM0 */
|
||||
if ((dev->pb_pci_conf[0x59] ^ val) & 0x0f)
|
||||
i450kx_map(dev, 1, 0x80000, 0x20000, val & 0x0f);
|
||||
if ((dev->pb_pci_conf[0x59] ^ val) & 0xf0) {
|
||||
i450kx_map(dev, 1, 0xf0000, 0x10000, val >> 4);
|
||||
shadowbios = (val & 0x10);
|
||||
}
|
||||
dev->pb_pci_conf[0x59] = val & 0x33;
|
||||
break;
|
||||
case 0x5a: /* PAM1 */
|
||||
if ((dev->pb_pci_conf[0x5a] ^ val) & 0x0f)
|
||||
i450kx_map(dev, 1, 0xc0000, 0x04000, val & 0xf);
|
||||
if ((dev->pb_pci_conf[0x5a] ^ val) & 0xf0)
|
||||
i450kx_map(dev, 1, 0xc4000, 0x04000, val >> 4);
|
||||
dev->pb_pci_conf[0x5a] = val & 0x33;
|
||||
break;
|
||||
case 0x5b: /*PAM2 */
|
||||
if ((dev->pb_pci_conf[0x5b] ^ val) & 0x0f)
|
||||
i450kx_map(dev, 1, 0xc8000, 0x04000, val & 0xf);
|
||||
if ((dev->pb_pci_conf[0x5b] ^ val) & 0xf0)
|
||||
i450kx_map(dev, 1, 0xcc000, 0x04000, val >> 4);
|
||||
dev->pb_pci_conf[0x5b] = val & 0x33;
|
||||
break;
|
||||
case 0x5c: /*PAM3 */
|
||||
if ((dev->pb_pci_conf[0x5c] ^ val) & 0x0f)
|
||||
i450kx_map(dev, 1, 0xd0000, 0x04000, val & 0xf);
|
||||
if ((dev->pb_pci_conf[0x5c] ^ val) & 0xf0)
|
||||
i450kx_map(dev, 1, 0xd4000, 0x04000, val >> 4);
|
||||
dev->pb_pci_conf[0x5c] = val & 0x33;
|
||||
break;
|
||||
case 0x5d: /* PAM4 */
|
||||
if ((dev->pb_pci_conf[0x5d] ^ val) & 0x0f)
|
||||
i450kx_map(dev, 1, 0xd8000, 0x04000, val & 0xf);
|
||||
if ((dev->pb_pci_conf[0x5d] ^ val) & 0xf0)
|
||||
i450kx_map(dev, 1, 0xdc000, 0x04000, val >> 4);
|
||||
dev->pb_pci_conf[0x5d] = val & 0x33;
|
||||
break;
|
||||
case 0x5e: /* PAM5 */
|
||||
if ((dev->pb_pci_conf[0x5e] ^ val) & 0x0f)
|
||||
i450kx_map(dev, 1, 0xe0000, 0x04000, val & 0xf);
|
||||
if ((dev->pb_pci_conf[0x5e] ^ val) & 0xf0)
|
||||
i450kx_map(dev, 1, 0xe4000, 0x04000, val >> 4);
|
||||
dev->pb_pci_conf[0x5e] = val & 0x33;
|
||||
break;
|
||||
case 0x5f: /* PAM6 */
|
||||
if ((dev->pb_pci_conf[0x5f] ^ val) & 0x0f)
|
||||
i450kx_map(dev, 1, 0xe8000, 0x04000, val & 0xf);
|
||||
if ((dev->pb_pci_conf[0x5f] ^ val) & 0xf0)
|
||||
i450kx_map(dev, 1, 0xec000, 0x04000, val >> 4);
|
||||
dev->pb_pci_conf[0x5f] = val & 0x33;
|
||||
break;
|
||||
|
||||
case 0x70:
|
||||
dev->pb_pci_conf[addr] = val & 0xfc;
|
||||
dev->pb_pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x71:
|
||||
@@ -197,47 +264,49 @@ pb_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x78:
|
||||
dev->pb_pci_conf[addr] = val & 0xf0;
|
||||
break;
|
||||
|
||||
case 0x79:
|
||||
dev->pb_pci_conf[addr] = val & 0xfc;
|
||||
break;
|
||||
|
||||
case 0x7c:
|
||||
dev->pb_pci_conf[addr] = val & 0x5f;
|
||||
case 0x7a:
|
||||
dev->pb_pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x7b:
|
||||
dev->pb_pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x7c:
|
||||
dev->pb_pci_conf[addr] = val & 0x9f;
|
||||
break;
|
||||
case 0x7d:
|
||||
dev->pb_pci_conf[addr] = val & 0x1a;
|
||||
break;
|
||||
|
||||
case 0x7e:
|
||||
dev->pb_pci_conf[addr] = val & 0xf0;
|
||||
break;
|
||||
|
||||
case 0x7f:
|
||||
case 0x88:
|
||||
case 0x89:
|
||||
case 0x8a:
|
||||
dev->pb_pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x88: case 0x89:
|
||||
dev->pb_pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x8b:
|
||||
dev->pb_pci_conf[addr] = val & 0x80;
|
||||
break;
|
||||
|
||||
case 0x9c:
|
||||
dev->pb_pci_conf[addr] = val & 1;
|
||||
break;
|
||||
|
||||
case 0xa4:
|
||||
dev->pb_pci_conf[addr] = val & 0xf9;
|
||||
break;
|
||||
|
||||
case 0xa5:
|
||||
case 0xa6:
|
||||
case 0x8c: case 0x8d:
|
||||
dev->pb_pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x9c:
|
||||
dev->pb_pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
|
||||
case 0xa4:
|
||||
dev->pb_pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
case 0xa5: case 0xa6:
|
||||
dev->pb_pci_conf[addr] = val;
|
||||
break;
|
||||
case 0xa7:
|
||||
dev->pb_pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
@@ -245,36 +314,45 @@ pb_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0xb0:
|
||||
dev->pb_pci_conf[addr] = val & 0xe0;
|
||||
break;
|
||||
|
||||
case 0xb1:
|
||||
dev->pb_pci_conf[addr] = val & 0x1f;
|
||||
dev->pb_pci_conf[addr] = val & /*0x1a*/ 0x1f;
|
||||
break;
|
||||
|
||||
case 0xb4:
|
||||
dev->pb_pci_conf[addr] = val & 0xe8;
|
||||
dev->pb_pci_conf[addr] = val & 0xe0;
|
||||
break;
|
||||
|
||||
case 0xb5:
|
||||
dev->pb_pci_conf[addr] = val & 0x1f;
|
||||
break;
|
||||
|
||||
case 0xb8:
|
||||
case 0xb9:
|
||||
case 0xb8: case 0xb9:
|
||||
dev->pb_pci_conf[addr] = val;
|
||||
i450kx_smram_recalc(dev, 1);
|
||||
break;
|
||||
case 0xbb:
|
||||
dev->pb_pci_conf[addr] = !(addr == 0xbb) ? val : (val & 0xf0);
|
||||
i450kx_smm(SMRAM_ADDR, SMRAM_SIZE, dev);
|
||||
dev->pb_pci_conf[addr] = val & 0xf0;
|
||||
i450kx_smram_recalc(dev, 1);
|
||||
break;
|
||||
|
||||
case 0xbc:
|
||||
dev->pb_pci_conf[addr] = val & 0x11;
|
||||
break;
|
||||
|
||||
case 0xc0:
|
||||
dev->pb_pci_conf[addr] = val & 0xdf;
|
||||
break;
|
||||
case 0xc1:
|
||||
dev->pb_pci_conf[addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0xc4:
|
||||
dev->pb_pci_conf[addr] = val & 5;
|
||||
dev->pb_pci_conf[addr] &= ~(val & 0x0f);
|
||||
break;
|
||||
|
||||
case 0xc5:
|
||||
dev->pb_pci_conf[addr] = val & 0x0a;
|
||||
dev->pb_pci_conf[addr] &= ~(val & 0x0a);
|
||||
break;
|
||||
|
||||
case 0xc6:
|
||||
dev->pb_pci_conf[addr] = val & 0x1d;
|
||||
dev->pb_pci_conf[addr] &= ~(val & 0x1f);
|
||||
break;
|
||||
|
||||
case 0xc8:
|
||||
@@ -286,7 +364,6 @@ pb_write(int func, int addr, uint8_t val, void *priv)
|
||||
dev->pb_pci_conf[addr] = val;
|
||||
break;
|
||||
}
|
||||
i450kx_log("i450KX-PB: dev->regs[%02x] = %02x POST: %02x\n", addr, dev->pb_pci_conf[addr], inb(0x80));
|
||||
}
|
||||
|
||||
|
||||
@@ -294,7 +371,30 @@ static uint8_t
|
||||
pb_read(int func, int addr, void *priv)
|
||||
{
|
||||
i450kx_t *dev = (i450kx_t *)priv;
|
||||
return dev->pb_pci_conf[addr];
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0)
|
||||
ret = dev->pb_pci_conf[addr];
|
||||
|
||||
// pclog("i450KX-PB: [R] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* A way to use spd_write_drbs_interlaved() and convert the output to what we need. */
|
||||
static void
|
||||
mc_fill_drbs(i450kx_t *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
spd_write_drbs_interleaved(dev->mc_pci_conf, 0x60, 0x6f, 4);
|
||||
for (i = 0x60; i <= 0x6f; i++) {
|
||||
if (i & 0x01)
|
||||
dev->mc_pci_conf[i] = 0x00;
|
||||
else
|
||||
dev->mc_pci_conf[i] &= 0x7f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -303,75 +403,97 @@ mc_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
i450kx_t *dev = (i450kx_t *)priv;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
// pclog("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80));
|
||||
i450kx_log("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80));
|
||||
|
||||
if (func == 0) switch (addr) {
|
||||
case 0x4c:
|
||||
dev->mc_pci_conf[addr] = val & 0xdf;
|
||||
break;
|
||||
|
||||
case 0x4d:
|
||||
dev->mc_pci_conf[addr] = val & 0xdf;
|
||||
dev->mc_pci_conf[addr] = val & 0xff;
|
||||
break;
|
||||
|
||||
case 0x57:
|
||||
dev->mc_pci_conf[addr] = val & 8;
|
||||
i450kx_smm(SMRAM_ADDR, SMRAM_SIZE, dev);
|
||||
dev->mc_pci_conf[addr] = val & 0x08;
|
||||
i450kx_smram_recalc(dev, 0);
|
||||
break;
|
||||
|
||||
case 0x58:
|
||||
dev->mc_pci_conf[addr] = val & 2;
|
||||
dev->mc_pci_conf[addr] = val & 0x02;
|
||||
i450kx_vid_buf_recalc(dev, 0);
|
||||
break;
|
||||
|
||||
case 0x59:
|
||||
case 0x5a:
|
||||
case 0x5b:
|
||||
case 0x5c:
|
||||
case 0x5d:
|
||||
case 0x5e:
|
||||
case 0x5f:
|
||||
dev->mc_pci_conf[addr] = val & 0x33;
|
||||
i450kx_shadow(1, addr, val, dev);
|
||||
case 0x59: /* PAM0 */
|
||||
if ((dev->mc_pci_conf[0x59] ^ val) & 0x0f)
|
||||
i450kx_map(dev, 0, 0x80000, 0x20000, val & 0x0f);
|
||||
if ((dev->mc_pci_conf[0x59] ^ val) & 0xf0) {
|
||||
i450kx_map(dev, 0, 0xf0000, 0x10000, val >> 4);
|
||||
shadowbios = (val & 0x10);
|
||||
}
|
||||
dev->mc_pci_conf[0x59] = val & 0x33;
|
||||
break;
|
||||
case 0x5a: /* PAM1 */
|
||||
if ((dev->mc_pci_conf[0x5a] ^ val) & 0x0f)
|
||||
i450kx_map(dev, 0, 0xc0000, 0x04000, val & 0xf);
|
||||
if ((dev->mc_pci_conf[0x5a] ^ val) & 0xf0)
|
||||
i450kx_map(dev, 0, 0xc4000, 0x04000, val >> 4);
|
||||
dev->mc_pci_conf[0x5a] = val & 0x33;
|
||||
break;
|
||||
case 0x5b: /*PAM2 */
|
||||
if ((dev->mc_pci_conf[0x5b] ^ val) & 0x0f)
|
||||
i450kx_map(dev, 0, 0xc8000, 0x04000, val & 0xf);
|
||||
if ((dev->mc_pci_conf[0x5b] ^ val) & 0xf0)
|
||||
i450kx_map(dev, 0, 0xcc000, 0x04000, val >> 4);
|
||||
dev->mc_pci_conf[0x5b] = val & 0x33;
|
||||
break;
|
||||
case 0x5c: /*PAM3 */
|
||||
if ((dev->mc_pci_conf[0x5c] ^ val) & 0x0f)
|
||||
i450kx_map(dev, 0, 0xd0000, 0x04000, val & 0xf);
|
||||
if ((dev->mc_pci_conf[0x5c] ^ val) & 0xf0)
|
||||
i450kx_map(dev, 0, 0xd4000, 0x04000, val >> 4);
|
||||
dev->mc_pci_conf[0x5c] = val & 0x33;
|
||||
break;
|
||||
case 0x5d: /* PAM4 */
|
||||
if ((dev->mc_pci_conf[0x5d] ^ val) & 0x0f)
|
||||
i450kx_map(dev, 0, 0xd8000, 0x04000, val & 0xf);
|
||||
if ((dev->mc_pci_conf[0x5d] ^ val) & 0xf0)
|
||||
i450kx_map(dev, 0, 0xdc000, 0x04000, val >> 4);
|
||||
dev->mc_pci_conf[0x5d] = val & 0x33;
|
||||
break;
|
||||
case 0x5e: /* PAM5 */
|
||||
if ((dev->mc_pci_conf[0x5e] ^ val) & 0x0f)
|
||||
i450kx_map(dev, 0, 0xe0000, 0x04000, val & 0xf);
|
||||
if ((dev->mc_pci_conf[0x5e] ^ val) & 0xf0)
|
||||
i450kx_map(dev, 0, 0xe4000, 0x04000, val >> 4);
|
||||
dev->mc_pci_conf[0x5e] = val & 0x33;
|
||||
break;
|
||||
case 0x5f: /* PAM6 */
|
||||
if ((dev->mc_pci_conf[0x5f] ^ val) & 0x0f)
|
||||
i450kx_map(dev, 0, 0xe8000, 0x04000, val & 0xf);
|
||||
if ((dev->mc_pci_conf[0x5f] ^ val) & 0xf0)
|
||||
i450kx_map(dev, 0, 0xec000, 0x04000, val >> 4);
|
||||
dev->mc_pci_conf[0x5f] = val & 0x33;
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
case 0x61:
|
||||
case 0x62:
|
||||
case 0x63:
|
||||
case 0x64:
|
||||
case 0x65:
|
||||
case 0x66:
|
||||
case 0x67:
|
||||
case 0x68:
|
||||
case 0x69:
|
||||
case 0x6a:
|
||||
case 0x6b:
|
||||
case 0x6c:
|
||||
case 0x6d:
|
||||
case 0x6e:
|
||||
case 0x6f:
|
||||
dev->mc_pci_conf[addr] = ((addr & 0x0f) % 2) ? 0 : (val & 0x7f);
|
||||
spd_write_drbs(dev->mc_pci_conf, 0x60, 0x6f, 4);
|
||||
case 0x60 ... 0x6f:
|
||||
dev->mc_pci_conf[addr] = ((addr & 0x0f) & 0x01) ? 0x00 : (val & 0x7f);
|
||||
mc_fill_drbs(dev);
|
||||
break;
|
||||
|
||||
case 0x74:
|
||||
case 0x75:
|
||||
case 0x76:
|
||||
case 0x77:
|
||||
case 0x74 ... 0x77:
|
||||
dev->mc_pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x78:
|
||||
dev->mc_pci_conf[addr] = val & 0xf0;
|
||||
break;
|
||||
|
||||
case 0x79:
|
||||
dev->mc_pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x7a:
|
||||
dev->mc_pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x7b:
|
||||
dev->mc_pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
@@ -379,45 +501,36 @@ mc_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x7c:
|
||||
dev->mc_pci_conf[addr] = val & 0x1f;
|
||||
break;
|
||||
|
||||
case 0x7d:
|
||||
dev->mc_pci_conf[addr] = val & 0x0c;
|
||||
break;
|
||||
|
||||
case 0x7e:
|
||||
dev->mc_pci_conf[addr] = val & 0xf0;
|
||||
break;
|
||||
|
||||
case 0x7f:
|
||||
dev->mc_pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x88:
|
||||
case 0x89:
|
||||
case 0x88: case 0x89:
|
||||
dev->mc_pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x8b:
|
||||
dev->mc_pci_conf[addr] = val & 0x80;
|
||||
break;
|
||||
|
||||
case 0x8c:
|
||||
case 0x8d:
|
||||
case 0x8c: case 0x8d:
|
||||
dev->mc_pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xa4:
|
||||
dev->mc_pci_conf[addr] = val & 1;
|
||||
dev->mc_pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
|
||||
case 0xa5:
|
||||
dev->pb_pci_conf[addr] = val & 0xf0;
|
||||
break;
|
||||
|
||||
case 0xa6:
|
||||
dev->mc_pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xa7:
|
||||
dev->mc_pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
@@ -425,49 +538,56 @@ mc_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0xa8:
|
||||
dev->mc_pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0xa9:
|
||||
case 0xaa:
|
||||
case 0xab:
|
||||
case 0xac:
|
||||
case 0xad:
|
||||
case 0xae:
|
||||
case 0xa9 ... 0xab:
|
||||
dev->mc_pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xac ... 0xae:
|
||||
dev->mc_pci_conf[addr] = val;
|
||||
break;
|
||||
case 0xaf:
|
||||
dev->mc_pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
|
||||
case 0xb8:
|
||||
case 0xb9:
|
||||
case 0xb8: case 0xb9:
|
||||
dev->mc_pci_conf[addr] = val;
|
||||
i450kx_smram_recalc(dev, 0);
|
||||
break;
|
||||
case 0xbb:
|
||||
dev->mc_pci_conf[addr] = !(addr == 0xbb) ? val : (val & 0xf0);
|
||||
|
||||
i450kx_smm(SMRAM_ADDR_MC, SMRAM_SIZE_MC, dev);
|
||||
dev->mc_pci_conf[addr] = val & 0xf0;
|
||||
i450kx_smram_recalc(dev, 0);
|
||||
break;
|
||||
|
||||
case 0xbc:
|
||||
dev->mc_pci_conf[addr] = val & 1;
|
||||
dev->mc_pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
|
||||
case 0xc0:
|
||||
dev->mc_pci_conf[addr] = val & 7;
|
||||
dev->mc_pci_conf[addr] = val & 0x07;
|
||||
break;
|
||||
|
||||
case 0xc2:
|
||||
dev->mc_pci_conf[addr] = val & 3;
|
||||
dev->mc_pci_conf[addr] &= ~(val & 0x03);
|
||||
break;
|
||||
|
||||
case 0xc4:
|
||||
dev->mc_pci_conf[addr] = val & 0x3f;
|
||||
dev->mc_pci_conf[addr] = val & 0xbf;
|
||||
break;
|
||||
case 0xc5:
|
||||
dev->mc_pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
|
||||
case 0xc6:
|
||||
dev->mc_pci_conf[addr] = val & 0x19;
|
||||
dev->mc_pci_conf[addr] &= ~(val & 0x19);
|
||||
break;
|
||||
|
||||
case 0xc8:
|
||||
dev->mc_pci_conf[addr] = val & 0x1f;
|
||||
break;
|
||||
case 0xca: case 0xcb:
|
||||
dev->mc_pci_conf[addr] = val;
|
||||
break;
|
||||
}
|
||||
i450kx_log("i450KX-MC: dev->regs[%02x] = %02x POST: %02x\n", addr, dev->mc_pci_conf[addr], inb(0x80));
|
||||
}
|
||||
|
||||
|
||||
@@ -475,7 +595,14 @@ static uint8_t
|
||||
mc_read(int func, int addr, void *priv)
|
||||
{
|
||||
i450kx_t *dev = (i450kx_t *)priv;
|
||||
return dev->mc_pci_conf[addr];
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0)
|
||||
ret = dev->mc_pci_conf[addr];
|
||||
|
||||
// pclog("i450KX-MC: [R] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -483,57 +610,168 @@ static void
|
||||
i450kx_reset(void *priv)
|
||||
{
|
||||
i450kx_t *dev = (i450kx_t *)priv;
|
||||
uint32_t i;
|
||||
|
||||
/* CONFLICTS WARNING! We do not program anything on reset due to that */
|
||||
// pclog("i450KX: i450kx_reset()\n");
|
||||
|
||||
/* Defaults PB */
|
||||
dev->pb_pci_conf[0x00] = 0x86;
|
||||
dev->pb_pci_conf[0x01] = 0x80;
|
||||
dev->pb_pci_conf[0x02] = 0xc4;
|
||||
dev->pb_pci_conf[0x03] = 0x84;
|
||||
dev->pb_pci_conf[0x05] = 4;
|
||||
dev->pb_pci_conf[0x04] = 0x07;
|
||||
dev->pb_pci_conf[0x05] = 0x00;
|
||||
dev->pb_pci_conf[0x06] = 0x40;
|
||||
dev->pb_pci_conf[0x07] = 2;
|
||||
dev->pb_pci_conf[0x08] = 2;
|
||||
dev->pb_pci_conf[0x0b] = 6;
|
||||
dev->pb_pci_conf[0x0c] = 8;
|
||||
dev->pb_pci_conf[0x07] = 0x02;
|
||||
dev->pb_pci_conf[0x08] = 0x02;
|
||||
dev->pb_pci_conf[0x09] = 0x00;
|
||||
dev->pb_pci_conf[0x0a] = 0x00;
|
||||
dev->pb_pci_conf[0x0b] = 0x06;
|
||||
dev->pb_pci_conf[0x0c] = 0x08;
|
||||
dev->pb_pci_conf[0x0d] = 0x20;
|
||||
dev->pb_pci_conf[0x49] = 0x14;
|
||||
dev->pb_pci_conf[0x4c] = 0x39;
|
||||
dev->pb_pci_conf[0x58] = 2;
|
||||
dev->pb_pci_conf[0x59] = 0x30;
|
||||
dev->pb_pci_conf[0x5a] = 0x33;
|
||||
dev->pb_pci_conf[0x5b] = 0x33;
|
||||
dev->pb_pci_conf[0x5c] = 0x33;
|
||||
dev->pb_pci_conf[0x5d] = 0x33;
|
||||
dev->pb_pci_conf[0x5e] = 0x33;
|
||||
dev->pb_pci_conf[0x5f] = 0x33;
|
||||
dev->pb_pci_conf[0xa4] = 1;
|
||||
dev->pb_pci_conf[0x0e] = 0x00;
|
||||
dev->pb_pci_conf[0x0f] = 0x00;
|
||||
dev->pb_pci_conf[0x40] = 0x00;
|
||||
dev->pb_pci_conf[0x41] = 0x00;
|
||||
dev->pb_pci_conf[0x42] = 0x00;
|
||||
dev->pb_pci_conf[0x43] = 0x00;
|
||||
dev->pb_pci_conf[0x48] = 0x06;
|
||||
dev->pb_pci_conf[0x49] = 0x19;
|
||||
dev->pb_pci_conf[0x4a] = 0x00;
|
||||
dev->pb_pci_conf[0x4b] = 0x00;
|
||||
dev->pb_pci_conf[0x4c] = 0x19;
|
||||
dev->pb_pci_conf[0x51] = 0x80;
|
||||
dev->pb_pci_conf[0x53] = 0x00;
|
||||
dev->pb_pci_conf[0x54] = 0x00;
|
||||
dev->pb_pci_conf[0x55] = 0x00;
|
||||
dev->pb_pci_conf[0x57] = 0x00;
|
||||
dev->pb_pci_conf[0x58] = 0x02;
|
||||
dev->pb_pci_conf[0x70] = 0x00;
|
||||
dev->pb_pci_conf[0x71] = 0x00;
|
||||
dev->pb_pci_conf[0x78] = 0x00;
|
||||
dev->pb_pci_conf[0x79] = 0x00;
|
||||
dev->pb_pci_conf[0x7a] = 0x00;
|
||||
dev->pb_pci_conf[0x7b] = 0x00;
|
||||
dev->pb_pci_conf[0x7c] = 0x00;
|
||||
dev->pb_pci_conf[0x7d] = 0x00;
|
||||
dev->pb_pci_conf[0x7e] = 0x00;
|
||||
dev->pb_pci_conf[0x7f] = 0x00;
|
||||
dev->pb_pci_conf[0x88] = 0x00;
|
||||
dev->pb_pci_conf[0x89] = 0x00;
|
||||
dev->pb_pci_conf[0x8a] = 0x00;
|
||||
dev->pb_pci_conf[0x8b] = 0x00;
|
||||
dev->pb_pci_conf[0x8c] = 0x00;
|
||||
dev->pb_pci_conf[0x8d] = 0x00;
|
||||
dev->pb_pci_conf[0x8e] = 0x00;
|
||||
dev->pb_pci_conf[0x8f] = 0x00;
|
||||
dev->pb_pci_conf[0x9c] = 0x00;
|
||||
dev->pb_pci_conf[0xa4] = 0x01;
|
||||
dev->pb_pci_conf[0xa5] = 0xc0;
|
||||
dev->pb_pci_conf[0xa6] = 0xfe;
|
||||
dev->pb_pci_conf[0xc8] = 3;
|
||||
dev->pb_pci_conf[0xb8] = 5;
|
||||
dev->pb_pci_conf[0xa7] = 0x00;
|
||||
/* Note: Do NOT reset these two registers on programmed (TRC) hard reset! */
|
||||
// dev->pb_pci_conf[0xb0] = 0x00;
|
||||
// dev->pb_pci_conf[0xb1] = 0x00;
|
||||
dev->pb_pci_conf[0xb4] = 0x00;
|
||||
dev->pb_pci_conf[0xb5] = 0x00;
|
||||
dev->pb_pci_conf[0xb8] = 0x05;
|
||||
dev->pb_pci_conf[0xb9] = 0x00;
|
||||
dev->pb_pci_conf[0xba] = 0x00;
|
||||
dev->pb_pci_conf[0xbb] = 0x00;
|
||||
dev->pb_pci_conf[0xbc] = 0x01;
|
||||
dev->pb_pci_conf[0xc0] = 0x02;
|
||||
dev->pb_pci_conf[0xc1] = 0x00;
|
||||
dev->pb_pci_conf[0xc2] = 0x00;
|
||||
dev->pb_pci_conf[0xc3] = 0x00;
|
||||
dev->pb_pci_conf[0xc4] = 0x00;
|
||||
dev->pb_pci_conf[0xc5] = 0x00;
|
||||
dev->pb_pci_conf[0xc6] = 0x00;
|
||||
dev->pb_pci_conf[0xc7] = 0x00;
|
||||
dev->pb_pci_conf[0xc8] = 0x03;
|
||||
dev->pb_pci_conf[0xc9] = 0x00;
|
||||
dev->pb_pci_conf[0xca] = 0x00;
|
||||
dev->pb_pci_conf[0xcb] = 0x00;
|
||||
|
||||
// pci_remap_bus(dev->bus_index, 0x00);
|
||||
i450kx_smram_recalc(dev, 1);
|
||||
i450kx_vid_buf_recalc(dev, 1);
|
||||
pb_write(0, 0x59, 0x30, dev);
|
||||
for (i = 0x5a; i <= 0x5f; i++)
|
||||
pb_write(0, i, 0x33, dev);
|
||||
|
||||
/* Defaults MC */
|
||||
dev->mc_pci_conf[0x00] = 0x86;
|
||||
dev->mc_pci_conf[0x01] = 0x80;
|
||||
dev->mc_pci_conf[0x02] = 0xc5;
|
||||
dev->mc_pci_conf[0x03] = 0x84;
|
||||
dev->mc_pci_conf[0x04] = 0x00;
|
||||
dev->mc_pci_conf[0x05] = 0x00;
|
||||
dev->mc_pci_conf[0x06] = 0x80;
|
||||
dev->mc_pci_conf[0x08] = 4;
|
||||
dev->mc_pci_conf[0x0b] = 5;
|
||||
dev->mc_pci_conf[0x07] = 0x00;
|
||||
dev->mc_pci_conf[0x08] = 0x04;
|
||||
dev->mc_pci_conf[0x09] = 0x00;
|
||||
dev->mc_pci_conf[0x0a] = 0x00;
|
||||
dev->mc_pci_conf[0x0b] = 0x05;
|
||||
dev->mc_pci_conf[0x49] = 0x14;
|
||||
dev->mc_pci_conf[0x4c] = 0x0b;
|
||||
dev->mc_pci_conf[0x4d] = 0x08;
|
||||
dev->mc_pci_conf[0x4e] = 0x00;
|
||||
dev->mc_pci_conf[0x4f] = 0x00;
|
||||
dev->mc_pci_conf[0x57] = 0x00;
|
||||
dev->mc_pci_conf[0x58] = 0x00;
|
||||
dev->mc_pci_conf[0x74] = 0x00;
|
||||
dev->mc_pci_conf[0x75] = 0x00;
|
||||
dev->mc_pci_conf[0x76] = 0x00;
|
||||
dev->mc_pci_conf[0x77] = 0x00;
|
||||
dev->mc_pci_conf[0x78] = 0x10;
|
||||
dev->mc_pci_conf[0xa4] = 1;
|
||||
dev->mc_pci_conf[0x79] = 0x00;
|
||||
dev->mc_pci_conf[0x7a] = 0x00;
|
||||
dev->mc_pci_conf[0x7b] = 0x00;
|
||||
dev->mc_pci_conf[0x7c] = 0x00;
|
||||
dev->mc_pci_conf[0x7d] = 0x00;
|
||||
dev->mc_pci_conf[0x7e] = 0x10;
|
||||
dev->mc_pci_conf[0x7f] = 0x00;
|
||||
dev->mc_pci_conf[0x88] = 0x00;
|
||||
dev->mc_pci_conf[0x89] = 0x00;
|
||||
dev->mc_pci_conf[0x8a] = 0x00;
|
||||
dev->mc_pci_conf[0x8b] = 0x00;
|
||||
dev->mc_pci_conf[0x8c] = 0x00;
|
||||
dev->mc_pci_conf[0x8d] = 0x00;
|
||||
dev->mc_pci_conf[0x8e] = 0x00;
|
||||
dev->mc_pci_conf[0x8f] = 0x00;
|
||||
dev->mc_pci_conf[0xa4] = 0x01;
|
||||
dev->mc_pci_conf[0xa5] = 0xc0;
|
||||
dev->mc_pci_conf[0xa6] = 0xfe;
|
||||
dev->mc_pci_conf[0xa7] = 0x00;
|
||||
dev->mc_pci_conf[0xa8] = 0x00;
|
||||
dev->mc_pci_conf[0xa9] = 0x00;
|
||||
dev->mc_pci_conf[0xaa] = 0x00;
|
||||
dev->mc_pci_conf[0xab] = 0x00;
|
||||
dev->mc_pci_conf[0xac] = 0x16;
|
||||
dev->mc_pci_conf[0xad] = 0x35;
|
||||
dev->mc_pci_conf[0xae] = 0xdf;
|
||||
dev->mc_pci_conf[0xaf] = 0x30;
|
||||
dev->mc_pci_conf[0xb8] = 0x0a;
|
||||
dev->mc_pci_conf[0xbc] = 1;
|
||||
dev->mc_pci_conf[0xb9] = 0x00;
|
||||
dev->mc_pci_conf[0xba] = 0x00;
|
||||
dev->mc_pci_conf[0xbb] = 0x00;
|
||||
dev->mc_pci_conf[0xbc] = 0x01;
|
||||
dev->mc_pci_conf[0xc0] = 0x00;
|
||||
dev->mc_pci_conf[0xc1] = 0x00;
|
||||
dev->mc_pci_conf[0xc2] = 0x00;
|
||||
dev->mc_pci_conf[0xc3] = 0x00;
|
||||
dev->mc_pci_conf[0xc4] = 0x00;
|
||||
dev->mc_pci_conf[0xc5] = 0x00;
|
||||
dev->mc_pci_conf[0xc6] = 0x00;
|
||||
dev->mc_pci_conf[0xc7] = 0x00;
|
||||
|
||||
i450kx_smram_recalc(dev, 0);
|
||||
i450kx_vid_buf_recalc(dev, 0);
|
||||
mc_write(0, 0x59, 0x03, dev);
|
||||
for (i = 0x5a; i <= 0x5f; i++)
|
||||
mc_write(0, i, 0x00, dev);
|
||||
for (i = 0x60; i <= 0x6f; i++)
|
||||
dev->mc_pci_conf[i] = 0x01;
|
||||
}
|
||||
|
||||
|
||||
@@ -542,7 +780,8 @@ i450kx_close(void *priv)
|
||||
{
|
||||
i450kx_t *dev = (i450kx_t *)priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
smram_del(dev->smram[1]);
|
||||
smram_del(dev->smram[0]);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
@@ -552,10 +791,11 @@ i450kx_init(const device_t *info)
|
||||
{
|
||||
i450kx_t *dev = (i450kx_t *)malloc(sizeof(i450kx_t));
|
||||
memset(dev, 0, sizeof(i450kx_t));
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, pb_read, pb_write, dev); /* Device 19: Intel 450KX PCI Bridge PB */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, mc_read, mc_write, dev); /* Device 14: Intel 450KX Memory Controller MC */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, pb_read, pb_write, dev); /* Device 19h: Intel 450KX PCI Bridge PB */
|
||||
pci_add_card(PCI_ADD_AGPBRIDGE, mc_read, mc_write, dev); /* Device 14h: Intel 450KX Memory Controller MC */
|
||||
|
||||
dev->smram = smram_add();
|
||||
dev->smram[0] = smram_add();
|
||||
dev->smram[1] = smram_add();
|
||||
|
||||
cpu_cache_int_enabled = 1;
|
||||
cpu_cache_ext_enabled = 1;
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/usb.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/smbus_piix4.h>
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
@@ -281,7 +281,7 @@ piix_trap_io(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv)
|
||||
|
||||
if (*(trap->en_reg) & trap->en_mask) {
|
||||
*(trap->sts_reg) |= trap->sts_mask;
|
||||
acpi_raise_smi(trap->dev->acpi);
|
||||
acpi_raise_smi(trap->dev->acpi, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -690,6 +690,8 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0xab:
|
||||
if (dev->type == 3)
|
||||
fregs[addr] &= (val & 0x01);
|
||||
else if (dev->type < 3)
|
||||
fregs[addr] = val;
|
||||
break;
|
||||
case 0xb0:
|
||||
if (dev->type == 4)
|
||||
@@ -1406,6 +1408,17 @@ piix_reset(void *p)
|
||||
piix_write(3, 0x91, 0x00, p);
|
||||
piix_write(3, 0xd2, 0x00, p);
|
||||
}
|
||||
|
||||
sff_set_irq_mode(dev->bm[0], 0, 0);
|
||||
sff_set_irq_mode(dev->bm[1], 0, 0);
|
||||
|
||||
if (dev->type >= 4) {
|
||||
sff_set_irq_mode(dev->bm[0], 1, 0);
|
||||
sff_set_irq_mode(dev->bm[1], 1, 0);
|
||||
} else {
|
||||
sff_set_irq_mode(dev->bm[0], 1, 2);
|
||||
sff_set_irq_mode(dev->bm[1], 1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1461,6 +1474,17 @@ static void
|
||||
ide_board_set_force_ata3(1, 1);
|
||||
}
|
||||
|
||||
sff_set_irq_mode(dev->bm[0], 0, 0);
|
||||
sff_set_irq_mode(dev->bm[1], 0, 0);
|
||||
|
||||
if (dev->type >= 4) {
|
||||
sff_set_irq_mode(dev->bm[0], 1, 0);
|
||||
sff_set_irq_mode(dev->bm[1], 1, 0);
|
||||
} else {
|
||||
sff_set_irq_mode(dev->bm[0], 1, 2);
|
||||
sff_set_irq_mode(dev->bm[1], 1, 2);
|
||||
}
|
||||
|
||||
if (dev->type >= 3)
|
||||
dev->usb = device_add(&usb_device);
|
||||
|
||||
|
||||
226
src/chipset/opti391.c
Normal file
226
src/chipset/opti391.c
Normal file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the OPTi 82C391/392 chipset.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 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/mem.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
#ifdef ENABLE_OPTI391_LOG
|
||||
int opti391_do_log = ENABLE_OPTI391_LOG;
|
||||
|
||||
static void
|
||||
opti391_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (opti391_do_log)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define opti391_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t phys, virt;
|
||||
} mem_remapping_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t index, regs[256];
|
||||
} opti391_t;
|
||||
|
||||
|
||||
static void
|
||||
opti391_shadow_recalc(opti391_t *dev)
|
||||
{
|
||||
uint32_t i, base;
|
||||
uint8_t sh_enable, sh_master;
|
||||
uint8_t sh_wp, sh_write_internal;
|
||||
|
||||
shadowbios = shadowbios_write = 0;
|
||||
|
||||
/* F0000-FFFFF */
|
||||
sh_enable = !(dev->regs[0x22] & 0x80);
|
||||
if (sh_enable)
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
|
||||
sh_write_internal = (dev->regs[0x26] & 0x40);
|
||||
/* D0000-EFFFF */
|
||||
for (i = 0; i < 8; i++) {
|
||||
base = 0xd0000 + (i << 14);
|
||||
if (base >= 0xe0000) {
|
||||
sh_master = (dev->regs[0x22] & 0x40);
|
||||
sh_wp = (dev->regs[0x22] & 0x10);
|
||||
} else {
|
||||
sh_master = (dev->regs[0x22] & 0x20);
|
||||
sh_wp = (dev->regs[0x22] & 0x08);
|
||||
}
|
||||
sh_enable = dev->regs[0x23] & (1 << i);
|
||||
|
||||
if (sh_master) {
|
||||
if (sh_enable) {
|
||||
if (sh_wp)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else if (sh_write_internal)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
} else if (sh_write_internal)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
}
|
||||
|
||||
/* C0000-CFFFF */
|
||||
sh_master = !(dev->regs[0x26] & 0x10);
|
||||
sh_wp = (dev->regs[0x26] & 0x20);
|
||||
for (i = 0; i < 4; i++) {
|
||||
base = 0xc0000 + (i << 14);
|
||||
sh_enable = dev->regs[0x26] & (1 << i);
|
||||
|
||||
if (sh_master) {
|
||||
if (sh_enable) {
|
||||
if (sh_wp)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else if (sh_write_internal)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
} else if (sh_write_internal)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti391_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
opti391_t *dev = (opti391_t *)priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
|
||||
case 0x24:
|
||||
opti391_log("OPTi 391: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
|
||||
switch (dev->index) {
|
||||
case 0x20:
|
||||
dev->regs[dev->index] = (dev->regs[dev->index] & 0xc0) | (val & 0x3f);
|
||||
break;
|
||||
|
||||
case 0x21: case 0x24: case 0x25: case 0x27:
|
||||
case 0x28: case 0x29: case 0x2a: case 0x2b:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x22: case 0x23:
|
||||
case 0x26:
|
||||
dev->regs[dev->index] = val;
|
||||
opti391_shadow_recalc(dev);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
opti391_read(uint16_t addr, void *priv)
|
||||
{
|
||||
opti391_t *dev = (opti391_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (addr == 0x24)
|
||||
ret = dev->regs[dev->index];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti391_close(void *priv)
|
||||
{
|
||||
opti391_t *dev = (opti391_t *)priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
opti391_init(const device_t *info)
|
||||
{
|
||||
opti391_t *dev = (opti391_t *)malloc(sizeof(opti391_t));
|
||||
memset(dev, 0x00, sizeof(opti391_t));
|
||||
|
||||
io_sethandler(0x0022, 0x0001, opti391_read, NULL, NULL, opti391_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0024, 0x0001, opti391_read, NULL, NULL, opti391_write, NULL, NULL, dev);
|
||||
|
||||
dev->regs[0x21] = 0x84;
|
||||
dev->regs[0x24] = 0x07;
|
||||
dev->regs[0x25] = 0xf0;
|
||||
dev->regs[0x26] = 0x30;
|
||||
dev->regs[0x27] = 0x91;
|
||||
dev->regs[0x28] = 0x80;
|
||||
dev->regs[0x29] = 0x10;
|
||||
dev->regs[0x2a] = 0x80;
|
||||
dev->regs[0x2b] = 0x10;
|
||||
|
||||
opti391_shadow_recalc(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
const device_t opti391_device = {
|
||||
"OPTi 82C391",
|
||||
0,
|
||||
0,
|
||||
opti391_init,
|
||||
opti391_close,
|
||||
NULL,
|
||||
{ NULL },
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
264
src/chipset/opti499.c
Normal file
264
src/chipset/opti499.c
Normal file
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the OPTi 82C493/82C499 chipset.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2020 Tiseno100.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t idx,
|
||||
regs[256], scratch[2];
|
||||
} opti499_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_OPTI499_LOG
|
||||
int opti499_do_log = ENABLE_OPTI499_LOG;
|
||||
|
||||
|
||||
static void
|
||||
opti499_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (opti499_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define opti499_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
opti499_recalc(opti499_t *dev)
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t i, shflags = 0;
|
||||
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 0;
|
||||
|
||||
if (dev->regs[0x22] & 0x80) {
|
||||
shadowbios = 1;
|
||||
shadowbios_write = 0;
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 1;
|
||||
shflags = MEM_READ_INTERNAL | MEM_WRITE_DISABLED;
|
||||
}
|
||||
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, shflags);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
base = 0xd0000 + (i << 14);
|
||||
|
||||
if ((dev->regs[0x22] & ((base >= 0xe0000) ? 0x20 : 0x40)) &&
|
||||
(dev->regs[0x23] & (1 << i))) {
|
||||
shflags = MEM_READ_INTERNAL;
|
||||
shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x2d] && (1 << ((i >> 1) + 2)))
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
|
||||
else
|
||||
shflags = MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL;
|
||||
}
|
||||
|
||||
mem_set_mem_state_both(base, 0x4000, shflags);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
base = 0xc0000 + (i << 14);
|
||||
|
||||
if ((dev->regs[0x26] & 0x10) && (dev->regs[0x26] & (1 << i))) {
|
||||
shflags = MEM_READ_INTERNAL;
|
||||
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x26] & 0x40) {
|
||||
if (dev->regs[0x2d] && (1 << (i >> 1)))
|
||||
shflags = MEM_READ_EXTANY;
|
||||
else
|
||||
shflags = MEM_READ_EXTERNAL;
|
||||
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x2d] && (1 << (i >> 1)))
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
|
||||
else
|
||||
shflags = MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
mem_set_mem_state_both(base, 0x4000, shflags);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti499_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
opti499_t *dev = (opti499_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
opti499_log("[%04X:%08X] [W] dev->idx = %02X\n", CS, cpu_state.pc, val);
|
||||
dev->idx = val;
|
||||
break;
|
||||
case 0x24:
|
||||
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
|
||||
if (dev->idx == 0x20)
|
||||
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0xc0) | (val & 0x3f);
|
||||
else
|
||||
dev->regs[dev->idx] = val;
|
||||
opti499_log("[%04X:%08X] [W] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, val);
|
||||
|
||||
switch(dev->idx) {
|
||||
case 0x20:
|
||||
reset_on_hlt = !(val & 0x02);
|
||||
break;
|
||||
|
||||
case 0x21:
|
||||
cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x22: case 0x23:
|
||||
case 0x26: case 0x2d:
|
||||
opti499_recalc(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xe1: case 0xe2:
|
||||
dev->scratch[addr] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
opti499_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
opti499_t *dev = (opti499_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
opti499_log("[%04X:%08X] [R] dev->idx = %02X\n", CS, cpu_state.pc, ret);
|
||||
break;
|
||||
case 0x24:
|
||||
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
|
||||
if (dev->idx == 0x2d)
|
||||
ret = dev->regs[dev->idx] & 0xbf;
|
||||
else
|
||||
ret = dev->regs[dev->idx];
|
||||
opti499_log("[%04X:%08X] [R] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, ret);
|
||||
}
|
||||
break;
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
ret = dev->scratch[addr];
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti499_reset(void *priv)
|
||||
{
|
||||
opti499_t *dev = (opti499_t *) priv;
|
||||
|
||||
memset(dev->regs, 0xff, sizeof(dev->regs));
|
||||
memset(&(dev->regs[0x20]), 0x00, 14 * sizeof(uint8_t));
|
||||
|
||||
dev->scratch[0] = dev->scratch[1] = 0xff;
|
||||
|
||||
dev->regs[0x22] = 0x84;
|
||||
dev->regs[0x24] = 0x87;
|
||||
dev->regs[0x25] = 0xf0;
|
||||
dev->regs[0x27] = 0xd1;
|
||||
dev->regs[0x28] = dev->regs[0x2a] = 0x80;
|
||||
dev->regs[0x29] = dev->regs[0x2b] = 0x10;
|
||||
dev->regs[0x2d] = 0x40;
|
||||
|
||||
reset_on_hlt = 1;
|
||||
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
opti499_recalc(dev);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opti499_close(void *priv)
|
||||
{
|
||||
opti499_t *dev = (opti499_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
opti499_init(const device_t *info)
|
||||
{
|
||||
opti499_t *dev = (opti499_t *) malloc(sizeof(opti499_t));
|
||||
memset(dev, 0, sizeof(opti499_t));
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
io_sethandler(0x0022, 0x0001, opti499_read, NULL, NULL, opti499_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0024, 0x0001, opti499_read, NULL, NULL, opti499_write, NULL, NULL, dev);
|
||||
|
||||
opti499_reset(dev);
|
||||
|
||||
io_sethandler(0x00e1, 0x0002, opti499_read, NULL, NULL, opti499_write, NULL, NULL, dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
const device_t opti499_device = {
|
||||
"OPTi 82C499",
|
||||
0,
|
||||
1,
|
||||
opti499_init, opti499_close, opti499_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -43,6 +43,7 @@ typedef struct
|
||||
} opti895_t;
|
||||
|
||||
|
||||
#define ENABLE_OPTI895_LOG 1
|
||||
#ifdef ENABLE_OPTI895_LOG
|
||||
int opti895_do_log = ENABLE_OPTI895_LOG;
|
||||
|
||||
@@ -91,11 +92,15 @@ opti895_recalc(opti895_t *dev)
|
||||
shflags = MEM_READ_INTERNAL;
|
||||
shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x26] & 0x40) {
|
||||
shflags = MEM_READ_EXTANY;
|
||||
shflags = (dev->regs[0x2d] & (1 << ((i >> 1) + 2))) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
if (dev->regs[0x26] & 0x40)
|
||||
shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
|
||||
else {
|
||||
if (dev->regs[0x26] & 0x80)
|
||||
shflags |= (dev->regs[0x2d] & (1 << ((i >> 1) + 2))) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
else
|
||||
shflags |= MEM_WRITE_EXTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
mem_set_mem_state_both(base, 0x4000, shflags);
|
||||
@@ -108,17 +113,21 @@ opti895_recalc(opti895_t *dev)
|
||||
shflags = MEM_READ_INTERNAL;
|
||||
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x26] & 0x40) {
|
||||
shflags = MEM_READ_EXTANY;
|
||||
shflags = (dev->regs[0x2d] & (1 << (i >> 1))) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
if (dev->regs[0x26] & 0x40)
|
||||
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
|
||||
else {
|
||||
if (dev->regs[0x26] & 0x80)
|
||||
shflags |= (dev->regs[0x2d] & (1 << (i >> 1))) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
else
|
||||
shflags |= MEM_WRITE_EXTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
mem_set_mem_state_both(base, 0x4000, shflags);
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
@@ -138,7 +147,7 @@ opti895_write(uint16_t addr, uint8_t val, void *priv)
|
||||
}
|
||||
break;
|
||||
case 0x24:
|
||||
if (((dev->idx >= 0x20) && (dev->idx <= 0x2c)) ||
|
||||
if (((dev->idx >= 0x20) && (dev->idx <= 0x2f)) ||
|
||||
((dev->idx >= 0xe0) && (dev->idx <= 0xef))) {
|
||||
dev->regs[dev->idx] = val;
|
||||
opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val);
|
||||
@@ -152,6 +161,7 @@ opti895_write(uint16_t addr, uint8_t val, void *priv)
|
||||
case 0x22:
|
||||
case 0x23:
|
||||
case 0x26:
|
||||
case 0x2d:
|
||||
opti895_recalc(dev);
|
||||
break;
|
||||
|
||||
@@ -177,7 +187,7 @@ opti895_write(uint16_t addr, uint8_t val, void *priv)
|
||||
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
dev->scratch[addr] = val;
|
||||
dev->scratch[addr - 0xe1] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -195,7 +205,7 @@ opti895_read(uint16_t addr, void *priv)
|
||||
ret = dev->regs[dev->idx];
|
||||
break;
|
||||
case 0x24:
|
||||
if (((dev->idx >= 0x20) && (dev->idx <= 0x2c)) ||
|
||||
if (((dev->idx >= 0x20) && (dev->idx <= 0x2f)) ||
|
||||
((dev->idx >= 0xe0) && (dev->idx <= 0xef))) {
|
||||
ret = dev->regs[dev->idx];
|
||||
if (dev->idx == 0xe0)
|
||||
@@ -204,7 +214,7 @@ opti895_read(uint16_t addr, void *priv)
|
||||
break;
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
ret = dev->scratch[addr];
|
||||
ret = dev->scratch[addr - 0xe1];
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,40 +79,56 @@ typedef struct sis_5511_t
|
||||
} sis_5511_t;
|
||||
|
||||
static void
|
||||
sis_5511_shadow_recalc(int cur_reg, sis_5511_t *dev)
|
||||
sis_5511_shadow_recalc(sis_5511_t *dev)
|
||||
{
|
||||
if (cur_reg == 0x86)
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, ((dev->pci_conf[cur_reg] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->pci_conf[cur_reg] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
|
||||
else
|
||||
{
|
||||
mem_set_mem_state_both(0xc0000 + ((cur_reg & 7) << 15), 0x4000, ((dev->pci_conf[cur_reg] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->pci_conf[cur_reg] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
|
||||
mem_set_mem_state_both(0xc4000 + ((cur_reg & 7) << 15), 0x4000, ((dev->pci_conf[cur_reg] & 8) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->pci_conf[cur_reg] & 2) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
|
||||
}
|
||||
int i, state;
|
||||
uint32_t base;
|
||||
|
||||
flushmmucache_nopc();
|
||||
for (i = 0x80; i <= 0x86; i++) {
|
||||
if (i == 0x86) {
|
||||
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, state);
|
||||
pclog("000F0000-000FFFFF\n");
|
||||
} else {
|
||||
base = ((i & 0x07) << 15) + 0xc0000;
|
||||
|
||||
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(base, 0x4000, state);
|
||||
pclog("%08X-%08X\n", base, base + 0x3fff);
|
||||
|
||||
state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(base + 0x4000, 0x4000, state);
|
||||
pclog("%08X-%08X\n", base + 0x4000, base + 0x7fff);
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5511_smram_recalc(sis_5511_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
smram_disable_all();
|
||||
|
||||
switch (dev->pci_conf[0x65] >> 6)
|
||||
{
|
||||
case 0:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
break;
|
||||
case 1:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
break;
|
||||
case 2:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
break;
|
||||
}
|
||||
switch (dev->pci_conf[0x65] >> 6) {
|
||||
case 0:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
break;
|
||||
case 1:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
break;
|
||||
case 2:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
|
||||
void sis_5513_ide_handler(sis_5511_t *dev)
|
||||
{
|
||||
ide_pri_disable();
|
||||
@@ -140,31 +156,19 @@ void sis_5513_bm_handler(sis_5511_t *dev)
|
||||
sff_bus_master_handler(dev->ide_drive[1], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE + 8);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_5511_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5511_t *dev = (sis_5511_t *)priv;
|
||||
sis_5511_t *dev = (sis_5511_t *)priv;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x04: /* Command - low byte */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x05: /* Command - high byte */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x06: /* Status - Low Byte */
|
||||
dev->pci_conf[addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf[addr] &= 0x16;
|
||||
switch (addr) {
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf[addr] &= 0xb0;
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
dev->pci_conf[addr] = (val & 0xf9) | 4;
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_ext_enabled = !!(val & 0x40);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
@@ -177,8 +181,7 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv)
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x53:
|
||||
case 0x54:
|
||||
case 0x53: case 0x54:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
@@ -186,15 +189,17 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv)
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x57:
|
||||
case 0x58:
|
||||
case 0x59:
|
||||
case 0x56 ... 0x59:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5a:
|
||||
/* TODO: Fast Gate A20 Emulation and Fast Reset Emulation on the KBC.
|
||||
The former (bit 7) means the chipset intercepts D1h to 64h and 00h to 60h.
|
||||
The latter (bit 6) means the chipset intercepts all odd FXh to 64h.
|
||||
Bit 5 sets fast reset latency. This should be fixed on the other SiS
|
||||
chipsets as well. */
|
||||
dev->pci_conf[addr] = val;
|
||||
port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x80));
|
||||
break;
|
||||
|
||||
case 0x5b:
|
||||
@@ -214,22 +219,18 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0x5f:
|
||||
dev->pci_conf[addr] = val;
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
dev->pci_conf[addr] = val & 0x3e;
|
||||
if (!!(val & 2) && (dev->pci_conf[0x68] & 1))
|
||||
{
|
||||
if ((dev->pci_conf[0x68] & 1) && (val & 2)) {
|
||||
smi_line = 1;
|
||||
dev->pci_conf[0x69] |= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x61: /* STPCLK# Assertion Timer */
|
||||
case 0x62: /* STPCLK# De-assertion Timer */
|
||||
case 0x63: /* System Standby Timer */
|
||||
case 0x64:
|
||||
case 0x61 ... 0x64:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
@@ -242,8 +243,7 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv)
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x67:
|
||||
case 0x68:
|
||||
case 0x67: case 0x68:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
@@ -251,11 +251,7 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv)
|
||||
dev->pci_conf[addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x6a:
|
||||
case 0x6b:
|
||||
case 0x6c:
|
||||
case 0x6d:
|
||||
case 0x6e:
|
||||
case 0x6a ... 0x6e:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
@@ -329,8 +325,7 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x85:
|
||||
case 0x86:
|
||||
dev->pci_conf[addr] = val & ((addr == 0x86) ? 0xe8 : 0xee);
|
||||
sis_5511_shadow_recalc(addr, dev);
|
||||
sis_5511_smram_recalc(dev);
|
||||
sis_5511_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x90: /* 5512 General Purpose Register Index */
|
||||
@@ -620,24 +615,45 @@ sis_5513_isa_read(uint16_t addr, void *priv)
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_5511_reset(void *priv)
|
||||
{
|
||||
sis_5511_t *dev = (sis_5511_t *)priv;
|
||||
sis_5511_t *dev = (sis_5511_t *)priv;
|
||||
|
||||
/* SiS 5511 */
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x11;
|
||||
dev->pci_conf[0x03] = 0x55;
|
||||
dev->pci_conf[0x04] = 0x07;
|
||||
dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00;
|
||||
dev->pci_conf[0x07] = 0x02;
|
||||
dev->pci_conf[0x08] = 0x00;
|
||||
dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00;
|
||||
dev->pci_conf[0x52] = 0x20;
|
||||
dev->pci_conf[0x53] = dev->pci_conf[0x54] = 0x00;
|
||||
dev->pci_conf[0x55] = dev->pci_conf[0x56] = 0x00;
|
||||
dev->pci_conf[0x57] = dev->pci_conf[0x58] = 0x00;
|
||||
dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00;
|
||||
dev->pci_conf[0x5b] = dev->pci_conf[0x5c] = 0x00;
|
||||
dev->pci_conf[0x5d] = dev->pci_conf[0x5e] = 0x00;
|
||||
dev->pci_conf[0x5f] = dev->pci_conf[0x60] = 0x00;
|
||||
dev->pci_conf[0x61] = dev->pci_conf[0x62] = 0xff;
|
||||
dev->pci_conf[0x63] = 0xff;
|
||||
dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00;
|
||||
dev->pci_conf[0x66] = 0x00;
|
||||
dev->pci_conf[0x67] = 0xff;
|
||||
dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00;
|
||||
dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00;
|
||||
dev->pci_conf[0x6c] = dev->pci_conf[0x6d] = 0x00;
|
||||
dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00;
|
||||
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
/* SiS 5511 */
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x11;
|
||||
dev->pci_conf[0x03] = 0x55;
|
||||
dev->pci_conf[0x04] = 7;
|
||||
dev->pci_conf[0x07] = 2;
|
||||
dev->pci_conf[0x0b] = 6;
|
||||
dev->pci_conf[0x52] = 0x20;
|
||||
dev->pci_conf[0x61] = 0xff;
|
||||
dev->pci_conf[0x62] = 0xff;
|
||||
dev->pci_conf[0x63] = 0xff;
|
||||
dev->pci_conf[0x67] = 0xff;
|
||||
dev->pci_conf[0x6b] = 0xff;
|
||||
dev->pci_conf[0x6c] = 0xff;
|
||||
dev->pci_conf[0x70] = 4;
|
||||
@@ -652,6 +668,15 @@ sis_5511_reset(void *priv)
|
||||
dev->pci_conf[0x7c] = 4;
|
||||
dev->pci_conf[0x7e] = 4;
|
||||
dev->pci_conf[0x7f] = 0x80;
|
||||
dev->pci_conf[0x80] = 0x00;
|
||||
dev->pci_conf[0x81] = 0x00;
|
||||
dev->pci_conf[0x82] = 0x00;
|
||||
dev->pci_conf[0x83] = 0x00;
|
||||
dev->pci_conf[0x84] = 0x00;
|
||||
dev->pci_conf[0x85] = 0x00;
|
||||
dev->pci_conf[0x86] = 0x00;
|
||||
sis_5511_smram_recalc(dev);
|
||||
sis_5511_shadow_recalc(dev);
|
||||
|
||||
/* SiS 5513 */
|
||||
dev->pci_conf_sb[0][0x00] = 0x39;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include "x86.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
@@ -39,6 +40,7 @@ typedef struct
|
||||
reg_base, reg_last,
|
||||
reg_00, is_471,
|
||||
regs[39], scratch[2];
|
||||
uint32_t mem_state[8];
|
||||
smram_t *smram;
|
||||
port_92_t *port_92;
|
||||
} sis_85c4xx_t;
|
||||
@@ -47,7 +49,7 @@ typedef struct
|
||||
static void
|
||||
sis_85c4xx_recalcmapping(sis_85c4xx_t *dev)
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t base, n = 0;
|
||||
uint32_t i, shflags = 0;
|
||||
uint32_t readext, writeext;
|
||||
uint8_t romcs = 0xc0, cur_romcs;
|
||||
@@ -73,12 +75,25 @@ sis_85c4xx_recalcmapping(sis_85c4xx_t *dev)
|
||||
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);
|
||||
if (dev->mem_state[i] != shflags) {
|
||||
n++;
|
||||
mem_set_mem_state(base, 0x8000, shflags);
|
||||
if ((base >= 0xf0000) && (dev->mem_state[i] & MEM_READ_INTERNAL) && !(shflags & MEM_READ_INTERNAL))
|
||||
mem_invalidate_range(base, base + 0x7fff);
|
||||
dev->mem_state[i] = shflags;
|
||||
}
|
||||
} else {
|
||||
shflags = readext | writeext;
|
||||
if (dev->mem_state[i] != shflags) {
|
||||
n++;
|
||||
mem_set_mem_state(base, 0x8000, shflags);
|
||||
dev->mem_state[i] = shflags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
if (n > 0)
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
@@ -141,7 +156,8 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
case 0x02: case 0x03:
|
||||
case 0x08:
|
||||
sis_85c4xx_recalcmapping(dev);
|
||||
if (valxor)
|
||||
sis_85c4xx_recalcmapping(dev);
|
||||
break;
|
||||
|
||||
case 0x0b:
|
||||
@@ -237,6 +253,69 @@ sis_85c4xx_in(uint16_t port, void *priv)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c4xx_reset(void *priv)
|
||||
{
|
||||
sis_85c4xx_t *dev = (sis_85c4xx_t *) priv;
|
||||
int mem_size_mb = mem_size >> 10;
|
||||
static uint8_t ram_4xx[64] = { 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00,
|
||||
0x19, 0x00, 0x06, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static uint8_t ram_471[64] = { 0x00, 0x00, 0x01, 0x01, 0x02, 0x20, 0x09, 0x09, 0x04, 0x04, 0x05, 0x05, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x13, 0x21, 0x06, 0x06, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
|
||||
0x1b, 0x1b, 0x1b, 0x1b, 0x0f, 0x0f, 0x0f, 0x0f, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
|
||||
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e };
|
||||
|
||||
memset(dev->regs, 0x00, sizeof(dev->regs));
|
||||
|
||||
if (cpu_s->rspeed < 25000000)
|
||||
dev->regs[0x08] = 0x80;
|
||||
|
||||
if (dev->is_471) {
|
||||
dev->regs[0x09] = 0x40;
|
||||
if (mem_size_mb >= 64) {
|
||||
if ((mem_size_mb >= 65) && (mem_size_mb < 68))
|
||||
dev->regs[0x09] |= 0x22;
|
||||
else
|
||||
dev->regs[0x09] |= 0x24;
|
||||
} else
|
||||
dev->regs[0x09] |= ram_471[mem_size_mb];
|
||||
|
||||
dev->regs[0x11] = 0x09;
|
||||
dev->regs[0x12] = 0xff;
|
||||
dev->regs[0x1f] = 0x20; /* Video access enabled. */
|
||||
dev->regs[0x23] = 0xf0;
|
||||
dev->regs[0x26] = 0x01;
|
||||
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x00010000, 0, 1);
|
||||
|
||||
port_92_remove(dev->port_92);
|
||||
|
||||
mem_remap_top(256);
|
||||
soft_reset_mask = 0;
|
||||
} else {
|
||||
/* Bits 6 and 7 must be clear on the SiS 40x. */
|
||||
if (dev->reg_base == 0x60)
|
||||
dev->reg_00 = 0x24;
|
||||
|
||||
if (mem_size_mb == 64)
|
||||
dev->regs[0x00] = 0x1f;
|
||||
else if (mem_size_mb < 64)
|
||||
dev->regs[0x00] = ram_4xx[mem_size_mb];
|
||||
|
||||
dev->regs[0x11] = 0x01;
|
||||
}
|
||||
|
||||
dev->scratch[0] = dev->scratch[1] = 0xff;
|
||||
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
sis_85c4xx_recalcmapping(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c4xx_close(void *priv)
|
||||
{
|
||||
@@ -252,8 +331,6 @@ sis_85c4xx_close(void *priv)
|
||||
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));
|
||||
|
||||
@@ -261,161 +338,22 @@ sis_85c4xx_init(const device_t *info)
|
||||
|
||||
dev->reg_base = info->local & 0xff;
|
||||
|
||||
mem_size_mb = mem_size >> 10;
|
||||
|
||||
if (cpu_s->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 {
|
||||
} else
|
||||
dev->reg_last = dev->reg_base + 0x11;
|
||||
|
||||
/* Bits 6 and 7 must be clear on the SiS 40x. */
|
||||
if (dev->reg_base == 0x60)
|
||||
dev->reg_00 = 0x24;
|
||||
|
||||
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);
|
||||
sis_85c4xx_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
@@ -425,7 +363,7 @@ const device_t sis_85c401_device = {
|
||||
"SiS 85c401/85c402",
|
||||
0,
|
||||
0x060,
|
||||
sis_85c4xx_init, sis_85c4xx_close, NULL,
|
||||
sis_85c4xx_init, sis_85c4xx_close, sis_85c4xx_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -434,7 +372,7 @@ const device_t sis_85c460_device = {
|
||||
"SiS 85c460",
|
||||
0,
|
||||
0x050,
|
||||
sis_85c4xx_init, sis_85c4xx_close, NULL,
|
||||
sis_85c4xx_init, sis_85c4xx_close, sis_85c4xx_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -444,7 +382,7 @@ const device_t sis_85c461_device = {
|
||||
"SiS 85c461",
|
||||
0,
|
||||
0x050,
|
||||
sis_85c4xx_init, sis_85c4xx_close, NULL,
|
||||
sis_85c4xx_init, sis_85c4xx_close, sis_85c4xx_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -453,7 +391,7 @@ const device_t sis_85c471_device = {
|
||||
"SiS 85c407/85c471",
|
||||
0,
|
||||
0x150,
|
||||
sis_85c4xx_init, sis_85c4xx_close, NULL,
|
||||
sis_85c4xx_init, sis_85c4xx_close, sis_85c4xx_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -89,7 +89,7 @@ sis_85c50x_shadow_recalc(sis_85c50x_t *dev)
|
||||
mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x56] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
@@ -107,8 +107,7 @@ sis_85c50x_smm_recalc(sis_85c50x_t *dev)
|
||||
|
||||
switch ((dev->pci_conf[0x65] & 0xe0) >> 5) {
|
||||
case 0x00:
|
||||
if (!(dev->pci_conf[0x54] & 0xc0))
|
||||
smram_enable(dev->smram, 0xe0000, 0xe0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
smram_enable(dev->smram, 0xe0000, 0xe0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
break;
|
||||
case 0x01:
|
||||
smram_enable(dev->smram, 0xb0000, ram_base, 0x10000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
|
||||
@@ -12,14 +12,17 @@
|
||||
* reverse engineering the BIOS of various machines using it.
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Copyright 2021 Miran Grca.
|
||||
*/
|
||||
|
||||
/* UMC 8886 Configuration Registers
|
||||
/*
|
||||
UMC 8886xx Configuration Registers
|
||||
|
||||
TODO:
|
||||
- More Appropriate Bitmasking(If it's even possible)
|
||||
Note: PMU functionality is quite basic. There may be Enable/Disable bits, IRQ/SMI picks and it also
|
||||
required for 386_common.c to get patched in order to function properly.
|
||||
|
||||
Warning: Register documentation may be inaccurate!
|
||||
|
||||
@@ -34,11 +37,9 @@
|
||||
Bits 7-4 PCI IRQ for INTD
|
||||
Bits 3-0 PCI IRQ for INTC
|
||||
|
||||
Function 0 Register 46:
|
||||
Bit 7: Replace SMI request for non-SMM CPU's (1: IRQ15/0: IRQ10)
|
||||
|
||||
Function 0 Register 51:
|
||||
Bit 2: VGA Power Down (0: Standard/1: VESA DPMS)
|
||||
Function 0 Register 46 (corrected by Miran Grca):
|
||||
Bit 7: IRQ SMI Request (1: IRQ 15, 0: IRQ 10)
|
||||
Bit 6: PMU Trigger(1: By IRQ/0: By SMI)
|
||||
|
||||
Function 0 Register 56:
|
||||
Bit 1-0 ISA Bus Speed
|
||||
@@ -46,10 +47,22 @@
|
||||
0 1 PCICLK/4
|
||||
1 0 PCICLK/2
|
||||
|
||||
Function 0 Register A2 - non-software SMI# status register
|
||||
(documented by Miran Grca):
|
||||
Bit 4: I set, graphics card goes into sleep mode
|
||||
This register is most likely R/WC
|
||||
|
||||
Function 0 Register A3 (added more details by Miran Grca):
|
||||
Bit 7: Unlock SMM
|
||||
Bit 6: Software SMI trigger (also doubles as software SMI# status register,
|
||||
cleared by writing a 0 to it - see the handler used by Phoenix BIOS'es):
|
||||
If Function 0 Register 46 Bit 6 is set, it raises the specified IRQ (15
|
||||
or 10) instead.
|
||||
|
||||
Function 0 Register A4:
|
||||
Bit 0: Host to PCI Clock (1: 1 by 1/0: 1 by half)
|
||||
|
||||
Function 1 Register 4:
|
||||
Function 1 Register 4: (UMC 8886AF/8886BF Only!)
|
||||
Bit 0: Enable Internal IDE
|
||||
*/
|
||||
|
||||
@@ -69,23 +82,28 @@
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pci.h>
|
||||
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
#define IDE_BIT 0x01
|
||||
|
||||
|
||||
#ifdef ENABLE_UMC_8886_LOG
|
||||
int umc_8886_do_log = ENABLE_UMC_8886_LOG;
|
||||
|
||||
|
||||
static void
|
||||
umc_8886_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (umc_8886_do_log)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
if (umc_8886_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -94,23 +112,24 @@ umc_8886_log(const char *fmt, ...)
|
||||
|
||||
|
||||
/* PCI IRQ Flags */
|
||||
#define INTA (PCI_INTA + (2 * !(addr & 1)))
|
||||
#define INTB (PCI_INTB + (2 * !(addr & 1)))
|
||||
#define IRQRECALCA (((val & 0xf0) != 0) ? ((val & 0xf0) >> 4) : PCI_IRQ_DISABLED)
|
||||
#define IRQRECALCB (((val & 0x0f) != 0) ? (val & 0x0f) : PCI_IRQ_DISABLED)
|
||||
#define INTA (PCI_INTA + (2 * !(addr & 1)))
|
||||
#define INTB (PCI_INTB + (2 * !(addr & 1)))
|
||||
#define IRQRECALCA (((val & 0xf0) != 0) ? ((val & 0xf0) >> 4) : PCI_IRQ_DISABLED)
|
||||
#define IRQRECALCB (((val & 0x0f) != 0) ? (val & 0x0f) : PCI_IRQ_DISABLED)
|
||||
|
||||
/* Disable Internal IDE Flag needed for the BF Southbridge variant */
|
||||
#define HAS_IDE dev->has_ide
|
||||
/* Disable Internal IDE Flag needed for the AF or BF Southbridge variant */
|
||||
#define HAS_IDE dev->has_ide
|
||||
|
||||
/* Southbridge Revision */
|
||||
#define SB_ID dev->sb_id
|
||||
#define SB_ID dev->sb_id
|
||||
|
||||
|
||||
typedef struct umc_8886_t
|
||||
{
|
||||
uint8_t pci_conf_sb[2][256]; /* PCI Registers */
|
||||
uint16_t sb_id; /* Southbridge Revision */
|
||||
int has_ide; /* Check if Southbridge Revision is AF or F */
|
||||
uint8_t max_func, /* Last function number */
|
||||
pci_conf_sb[2][256]; /* PCI Registers */
|
||||
uint16_t sb_id; /* Southbridge Revision */
|
||||
int has_ide; /* Check if Southbridge Revision is AF or F */
|
||||
} umc_8886_t;
|
||||
|
||||
|
||||
@@ -121,39 +140,66 @@ umc_8886_ide_handler(int status)
|
||||
ide_sec_disable();
|
||||
|
||||
if (status) {
|
||||
ide_pri_enable();
|
||||
ide_sec_enable();
|
||||
ide_pri_enable();
|
||||
ide_sec_enable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
um8886_write(int func, int addr, uint8_t val, void *priv)
|
||||
umc_8886_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
umc_8886_t *dev = (umc_8886_t *)priv;
|
||||
umc_8886_log("UM8886: dev->regs[%02x] = %02x (%02x)\n", addr, val, func);
|
||||
|
||||
/* We don't know the RW status of registers but Phoenix writes on some RO registers too*/
|
||||
if (addr > 3) switch (func) {
|
||||
case 0: /* Southbridge */
|
||||
if (func <= dev->max_func) switch (func) {
|
||||
case 0: /* PCI to ISA Bridge */
|
||||
umc_8886_log("UM8886: dev->regs[%02x] = %02x POST %02x\n", addr, val, inb(0x80));
|
||||
|
||||
switch (addr) {
|
||||
case 0x43:
|
||||
case 0x44:
|
||||
case 0x04: case 0x05:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->pci_conf_sb[func][addr] &= ~(val & 0xf9);
|
||||
break;
|
||||
|
||||
case 0x0c: case 0x0d:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x40: case 0x41:
|
||||
case 0x42:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x43: case 0x44:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
pci_set_irq_routing(INTA, IRQRECALCA);
|
||||
pci_set_irq_routing(INTB, IRQRECALCB);
|
||||
break;
|
||||
|
||||
case 0x45:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x46:
|
||||
dev->pci_conf_sb[func][addr] = val & 0xaf;
|
||||
/* Bit 6 seems to be the IRQ/SMI# toggle, 1 = IRQ, 0 = SMI#. */
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x47:
|
||||
dev->pci_conf_sb[func][addr] = val & 0x4f;
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x50: case 0x51: case 0x52: case 0x53:
|
||||
case 0x54: case 0x55:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x56:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
|
||||
switch (val & 2) {
|
||||
case 0:
|
||||
cpu_set_isa_pci_div(3);
|
||||
@@ -165,52 +211,78 @@ um8886_write(int func, int addr, uint8_t val, void *priv)
|
||||
cpu_set_isa_pci_div(2);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 0x57:
|
||||
dev->pci_conf_sb[func][addr] = val & 0x38;
|
||||
case 0x70 ... 0x76:
|
||||
case 0x80: case 0x81:
|
||||
case 0x90 ... 0x92:
|
||||
case 0xa0 ... 0xa1:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x71:
|
||||
dev->pci_conf_sb[func][addr] = val & 1;
|
||||
case 0xa2:
|
||||
dev->pci_conf_sb[func][addr] &= ~val;
|
||||
break;
|
||||
|
||||
case 0x90:
|
||||
dev->pci_conf_sb[func][addr] = val & 2;
|
||||
break;
|
||||
case 0xa3:
|
||||
/* SMI Provocation (Bit 7 Enable SMM + Bit 6 Software SMI) */
|
||||
if (((val & 0xc0) == 0xc0) && !(dev->pci_conf_sb[0][0xa3] & 0x40)) {
|
||||
if (dev->pci_conf_sb[0][0x46] & 0x40)
|
||||
picint(1 << ((dev->pci_conf_sb[0][0x46] & 0x80) ? 15 : 10));
|
||||
else
|
||||
smi_line = 1;
|
||||
dev->pci_conf_sb[0][0xa3] |= 0x04;
|
||||
}
|
||||
|
||||
case 0x92:
|
||||
dev->pci_conf_sb[func][addr] = val & 0x1f;
|
||||
break;
|
||||
|
||||
case 0xa0:
|
||||
dev->pci_conf_sb[func][addr] = val & 0xfc;
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0xa4:
|
||||
dev->pci_conf_sb[func][addr] = val & 0x89;
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
cpu_set_pci_speed(cpu_busspeed / ((val & 1) ? 1 : 2));
|
||||
break;
|
||||
|
||||
default:
|
||||
case 0xa5 ... 0xa8:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1: /* IDE Controller */
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
if ((addr == 4) && HAS_IDE)
|
||||
umc_8886_ide_handler(val & 1);
|
||||
|
||||
case 1: /* IDE Controller */
|
||||
umc_8886_log("UM8886-IDE: dev->regs[%02x] = %02x POST: %02x\n", addr, val, inb(0x80));
|
||||
|
||||
switch (addr) {
|
||||
case 0x04:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
umc_8886_ide_handler(val & 1);
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->pci_conf_sb[func][addr] &= ~(val & 0xf9);
|
||||
break;
|
||||
|
||||
case 0x3c:
|
||||
case 0x40: case 0x41:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
um8886_read(int func, int addr, void *priv)
|
||||
umc_8886_read(int func, int addr, void *priv)
|
||||
{
|
||||
umc_8886_t *dev = (umc_8886_t *)priv;
|
||||
return dev->pci_conf_sb[func][addr];
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func <= dev->max_func)
|
||||
ret = dev->pci_conf_sb[func][addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -219,26 +291,57 @@ umc_8886_reset(void *priv)
|
||||
{
|
||||
umc_8886_t *dev = (umc_8886_t *)priv;
|
||||
|
||||
/* Defaults */
|
||||
dev->pci_conf_sb[0][0] = 0x60; /* UMC */
|
||||
memset(dev->pci_conf_sb[0], 0x00, sizeof(dev->pci_conf_sb[0]));
|
||||
memset(dev->pci_conf_sb[1], 0x00, sizeof(dev->pci_conf_sb[1]));
|
||||
|
||||
dev->pci_conf_sb[0][0] = 0x60; /* UMC */
|
||||
dev->pci_conf_sb[0][1] = 0x10;
|
||||
|
||||
dev->pci_conf_sb[0][2] = (SB_ID & 0xff); /* 8886xx */
|
||||
dev->pci_conf_sb[0][2] = (SB_ID & 0xff); /* 8886xx */
|
||||
dev->pci_conf_sb[0][3] = ((SB_ID >> 8) & 0xff);
|
||||
|
||||
dev->pci_conf_sb[0][8] = 1;
|
||||
dev->pci_conf_sb[0][4] = 0x0f;
|
||||
dev->pci_conf_sb[0][7] = 2;
|
||||
|
||||
dev->pci_conf_sb[0][8] = 0x0e;
|
||||
|
||||
dev->pci_conf_sb[0][0x09] = 0x00;
|
||||
dev->pci_conf_sb[0][0x0a] = 0x01;
|
||||
dev->pci_conf_sb[0][0x0b] = 0x06;
|
||||
|
||||
for (int i = 1; i < 5; i++) /* Disable all IRQ interrupts */
|
||||
pci_set_irq_routing(i, PCI_IRQ_DISABLED);
|
||||
dev->pci_conf_sb[0][0x40] = 1;
|
||||
dev->pci_conf_sb[0][0x41] = 6;
|
||||
dev->pci_conf_sb[0][0x42] = 8;
|
||||
dev->pci_conf_sb[0][0x43] = 0x9a;
|
||||
dev->pci_conf_sb[0][0x44] = 0xbc;
|
||||
dev->pci_conf_sb[0][0x45] = 4;
|
||||
dev->pci_conf_sb[0][0x47] = 0x40;
|
||||
dev->pci_conf_sb[0][0x50] = 1;
|
||||
dev->pci_conf_sb[0][0x51] = 3;
|
||||
dev->pci_conf_sb[0][0xa8] = 0x20;
|
||||
|
||||
if (HAS_IDE) {
|
||||
dev->pci_conf_sb[1][0] = 0x60; /* UMC */
|
||||
dev->pci_conf_sb[1][1] = 0x10;
|
||||
|
||||
dev->pci_conf_sb[1][2] = 0x3a; /* 8886BF IDE */
|
||||
dev->pci_conf_sb[1][3] = 0x67;
|
||||
|
||||
dev->pci_conf_sb[1][4] = 1; /* Start with Internal IDE Enabled */
|
||||
|
||||
dev->pci_conf_sb[1][8] = 0x10;
|
||||
|
||||
dev->pci_conf_sb[1][0x09] = 0x0f;
|
||||
dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 1;
|
||||
|
||||
umc_8886_ide_handler(1);
|
||||
}
|
||||
|
||||
for (int i = 1; i < 5; i++) /* Disable all IRQ interrupts */
|
||||
pci_set_irq_routing(i, PCI_IRQ_DISABLED);
|
||||
|
||||
cpu_set_isa_pci_div(3);
|
||||
cpu_set_pci_speed(cpu_busspeed / 2);
|
||||
}
|
||||
|
||||
|
||||
@@ -257,12 +360,14 @@ umc_8886_init(const device_t *info)
|
||||
umc_8886_t *dev = (umc_8886_t *)malloc(sizeof(umc_8886_t));
|
||||
memset(dev, 0, sizeof(umc_8886_t));
|
||||
|
||||
dev->has_ide = (info->local == 0x886a);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, um8886_read, um8886_write, dev); /* Device 12: UMC 8886xx */
|
||||
dev->has_ide = !!(info->local == 0x886a);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev); /* Device 12: UMC 8886xx */
|
||||
|
||||
/* Add IDE if UM8886AF variant */
|
||||
if (HAS_IDE)
|
||||
device_add(&ide_pci_2ch_device);
|
||||
device_add(&ide_pci_2ch_device);
|
||||
|
||||
dev->max_func = (HAS_IDE) ? 1 : 0;
|
||||
|
||||
/* Get the Southbridge Revision */
|
||||
SB_ID = info->local;
|
||||
@@ -277,24 +382,16 @@ const device_t umc_8886f_device = {
|
||||
"UMC 8886F",
|
||||
DEVICE_PCI,
|
||||
0x8886,
|
||||
umc_8886_init,
|
||||
umc_8886_close,
|
||||
umc_8886_reset,
|
||||
{ NULL },
|
||||
NULL,
|
||||
NULL,
|
||||
umc_8886_init, umc_8886_close, umc_8886_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
const device_t umc_8886af_device = {
|
||||
"UMC 8886AF",
|
||||
"UMC 8886AF/8886BF",
|
||||
DEVICE_PCI,
|
||||
0x886a,
|
||||
umc_8886_init,
|
||||
umc_8886_close,
|
||||
umc_8886_reset,
|
||||
{ NULL },
|
||||
NULL,
|
||||
NULL,
|
||||
umc_8886_init, umc_8886_close, umc_8886_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the UMC 8890 Chipset.
|
||||
*
|
||||
* Note: This chipset has no datasheet, everything were done via
|
||||
* reverse engineering the BIOS of various machines using it.
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
|
||||
#include <86box/apm.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#ifdef ENABLE_UMC_8890_LOG
|
||||
int umc_8890_do_log = ENABLE_UMC_8890_LOG;
|
||||
static void
|
||||
umc_8890_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (umc_8890_do_log)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define umc_8890_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
/* Shadow RAM Flags */
|
||||
#define ENABLE_SHADOW (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL)
|
||||
#define DISABLE_SHADOW (MEM_READ_EXTANY | MEM_WRITE_EXTANY)
|
||||
|
||||
typedef struct umc_8890_t
|
||||
{
|
||||
apm_t *apm;
|
||||
smram_t *smram;
|
||||
|
||||
uint8_t pci_conf[256];
|
||||
} umc_8890_t;
|
||||
|
||||
uint16_t umc_8890_shadow_flag(uint8_t flag)
|
||||
{
|
||||
return (flag & 1) ? (MEM_READ_INTERNAL | ((flag & 2) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
}
|
||||
|
||||
void umc_8890_shadow(umc_8890_t *dev)
|
||||
{
|
||||
|
||||
mem_set_mem_state_both(0xe0000, 0x10000, umc_8890_shadow_flag((dev->pci_conf[0x5f] & 0x0c) >> 2));
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, umc_8890_shadow_flag((dev->pci_conf[0x5f] & 0xc0) >> 6));
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, umc_8890_shadow_flag(!!(dev->pci_conf[0x5d] & (1 << i))));
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
um8890_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
umc_8890_t *dev = (umc_8890_t *)priv;
|
||||
|
||||
dev->pci_conf[addr] = val;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x5c:
|
||||
case 0x5d:
|
||||
case 0x5e:
|
||||
case 0x5f:
|
||||
umc_8890_shadow(dev);
|
||||
break;
|
||||
|
||||
case 0x65: /* We don't know the default SMRAM values */
|
||||
smram_disable_all();
|
||||
smram_enable(dev->smram, 0xe0000, 0xe0000, 0x10000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
flushmmucache_nopc();
|
||||
break;
|
||||
}
|
||||
|
||||
umc_8890_log("UM8890: dev->regs[%02x] = %02x POST: %02x\n", addr, dev->pci_conf[addr], inb(0x80));
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
um8890_read(int func, int addr, void *priv)
|
||||
{
|
||||
umc_8890_t *dev = (umc_8890_t *)priv;
|
||||
return dev->pci_conf[addr];
|
||||
}
|
||||
|
||||
static void
|
||||
umc_8890_reset(void *priv)
|
||||
{
|
||||
umc_8890_t *dev = (umc_8890_t *)priv;
|
||||
|
||||
/* Defaults */
|
||||
dev->pci_conf[0] = 0x60; /* UMC */
|
||||
dev->pci_conf[1] = 0x10;
|
||||
|
||||
dev->pci_conf[2] = 0x91; /* 8891F */
|
||||
dev->pci_conf[3] = 0x88;
|
||||
|
||||
dev->pci_conf[8] = 1;
|
||||
|
||||
dev->pci_conf[0x09] = 0x00;
|
||||
dev->pci_conf[0x0a] = 0x00;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
}
|
||||
|
||||
static void
|
||||
umc_8890_close(void *priv)
|
||||
{
|
||||
umc_8890_t *dev = (umc_8890_t *)priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
umc_8890_init(const device_t *info)
|
||||
{
|
||||
umc_8890_t *dev = (umc_8890_t *)malloc(sizeof(umc_8890_t));
|
||||
memset(dev, 0, sizeof(umc_8890_t));
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, um8890_read, um8890_write, dev); /* Device 0: UMC 8890 */
|
||||
|
||||
/* APM */
|
||||
dev->apm = device_add(&apm_pci_device);
|
||||
|
||||
/* SMRAM(Needs excessive documentation before we begin SMM implementation) */
|
||||
dev->smram = smram_add();
|
||||
|
||||
/* Port 92 */
|
||||
device_add(&port_92_pci_device);
|
||||
|
||||
umc_8890_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t umc_8890_device = {
|
||||
"UMC 8890(8891BF/8892BF)",
|
||||
DEVICE_PCI,
|
||||
0x886a,
|
||||
umc_8890_init,
|
||||
umc_8890_close,
|
||||
umc_8890_reset,
|
||||
{NULL},
|
||||
NULL,
|
||||
NULL,
|
||||
NULL};
|
||||
@@ -15,71 +15,77 @@
|
||||
* around the web.
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Copyright 2021 Miran Grca.
|
||||
*/
|
||||
|
||||
/*
|
||||
UMC HB4 Configuration Registers
|
||||
UMC HB4 Configuration Registers
|
||||
|
||||
Sources & Notes:
|
||||
Cache registers were found at Vogons: https://www.vogons.org/viewtopic.php?f=46&t=68829&start=20
|
||||
Basic Reverse engineering effort was done personally by me
|
||||
Sources & Notes:
|
||||
Cache registers were found at Vogons: https://www.vogons.org/viewtopic.php?f=46&t=68829&start=20
|
||||
Basic Reverse engineering effort was done personally by me
|
||||
|
||||
TODO:
|
||||
- APM, SMM, SMRAM registers(Did some early work. Still quite incomplete)
|
||||
- More Appropriate Bitmasking(If it's even possible)
|
||||
Warning: Register documentation may be inaccurate!
|
||||
|
||||
Warning: Register documentation may be inaccurate!
|
||||
UMC 8881x:
|
||||
|
||||
UMC 8881x:
|
||||
Register 50:
|
||||
Bit 7: Enable L2 Cache
|
||||
Bit 6: Cache Policy (0: Write Thru / 1: Write Back)
|
||||
|
||||
Register 50:
|
||||
Bit 7: Enable L2 Cache
|
||||
Bit 6: Cache Policy (0: Write Thru / 1: Write Back)
|
||||
Bit 5-4 Cache Speed
|
||||
0 0 Read 3-2-2-2 Write 3T
|
||||
0 1 Read 3-1-1-1 Write 3T
|
||||
1 0 Read 2-2-2-2 Write 2T
|
||||
1 1 Read 2-1-1-1 Write 2T
|
||||
|
||||
Bit 5-4 Cache Speed
|
||||
0 0 Read 3-2-2-2 Write 3T
|
||||
0 1 Read 3-1-1-1 Write 3T
|
||||
1 0 Read 2-2-2-2 Write 2T
|
||||
1 1 Read 2-1-1-1 Write 2T
|
||||
Bit 3 Cache Banks (0: 1 Bank / 1: 2 Banks)
|
||||
|
||||
Bit 3 Cache Banks (0: 1 Bank / 1: 2 Banks)
|
||||
Bit 2-1-0 Cache Size
|
||||
0 0 0 0KB
|
||||
0 0 1 64KB
|
||||
x-x-x Multiplications of 2(64*2 for 0 1 0) till 2MB
|
||||
|
||||
Bit 2-1-0 Cache Size
|
||||
0 0 0 0KB
|
||||
0 0 1 64KB
|
||||
x-x-x Multiplications of 2(64*2 for 0 1 0) till 2MB
|
||||
Register 51:
|
||||
Bit 7-6 DRAM Read Speed
|
||||
5-4 DRAM Write Speed
|
||||
0 0 1 Waits
|
||||
0 1 1 Waits
|
||||
1 0 1 Wait
|
||||
1 1 0 Waits
|
||||
|
||||
Register 51:
|
||||
Bit 7-6 DRAM Read Speed
|
||||
5-4 DRAM Write Speed
|
||||
0 0 1 Waits
|
||||
0 1 1 Waits
|
||||
1 0 1 Wait
|
||||
1 1 0 Waits
|
||||
Bit 3 Resource Lock Enable
|
||||
Bit 2 Graphics Adapter (0: VL Bus / 1: PCI Bus)
|
||||
Bit 1 L1 WB Policy (0: WT / 1: WB)
|
||||
Bit 0 L2 Cache Tag Lenght (0: 7 Bits / 1: 8 Bits)
|
||||
|
||||
Bit 3 Resource Lock Enable
|
||||
Bit 2 Graphics Adapter (0: VL Bus / 1: PCI Bus)
|
||||
Bit 1 L1 WB Policy (0: WT / 1: WB)
|
||||
Bit 0 L2 Cache Tag Lenght (0: 7 Bits / 1: 8 Bits)
|
||||
Register 52:
|
||||
Bit 7: Host-to-PCI Post Write (0: 1 Wait State / 1: 0 Wait States)
|
||||
|
||||
Register 52:
|
||||
Bit 7: Host-to-PCI Post Write (0: 1 Wait State / 1: 0 Wait States)
|
||||
Register 54:
|
||||
Bit 7: DC000-DFFFF Read Enable
|
||||
Bit 6: D8000-DBFFF Read Enable
|
||||
Bit 5: D4000-D7FFF Read Enable
|
||||
Bit 4: D0000-D3FFF Read Enable
|
||||
Bit 3: CC000-CFFFF Read Enable
|
||||
Bit 2: C8000-CBFFF Read Enable
|
||||
Bit 1: C0000-C7FFF Read Enable
|
||||
Bit 0: Enable C0000-DFFFF Shadow Segment Bits
|
||||
|
||||
Register 54:
|
||||
Bit 7: DC000-DFFFF
|
||||
Bit 6: D8000-DBFFF
|
||||
Bit 5: D4000-D7FFF
|
||||
Bit 4: D0000-D3FFF
|
||||
Bit 3: CC000-CFFFF
|
||||
Bit 2: C8000-CBFFF
|
||||
Bit 1: C0000-C7FFF
|
||||
Bit 0: Reserved
|
||||
Register 55:
|
||||
Bit 7: E0000-FFFF Read Enable
|
||||
Bit 6: Shadow Write Status (1: Write Protect/0: Write)
|
||||
|
||||
Register 55:
|
||||
Bit 7: Enable Shadow Reads For System & Selected Segments
|
||||
Bit 6: Write Protect Enable
|
||||
Register 56h & 57h: DRAM Bank 0 Configuration
|
||||
Register 58h & 59h: DRAM Bank 1 Configuration
|
||||
|
||||
Register 60:
|
||||
Bit 5: If set and SMRAM is enabled, data cycles go to PCI and code cycles go to DRAM
|
||||
Bit 0: SMRAM Local Access Enable - if set, SMRAM is also enabled outside SMM
|
||||
SMRAM appears to always be enabled in SMM, and always set to A0000-BFFFF.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
@@ -91,161 +97,331 @@ Bit 6: Write Protect Enable
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include "x86.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
|
||||
#include <86box/apm.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
# include "codegen_public.h"
|
||||
#else
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
# define PAGE_MASK_SHIFT 6
|
||||
#else
|
||||
# define PAGE_MASK_INDEX_MASK 3
|
||||
# define PAGE_MASK_INDEX_SHIFT 10
|
||||
# define PAGE_MASK_SHIFT 4
|
||||
#endif
|
||||
# define PAGE_MASK_MASK 63
|
||||
#endif
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
#ifdef ENABLE_HB4_LOG
|
||||
int hb4_do_log = ENABLE_HB4_LOG;
|
||||
|
||||
|
||||
static void
|
||||
hb4_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (hb4_do_log)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
if (hb4_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define hb4_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
/* Shadow RAM Flags */
|
||||
#define CAN_READ ((dev->pci_conf[0x55] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY)
|
||||
#define CAN_WRITE ((dev->pci_conf[0x55] & 0x40) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)
|
||||
#define DISABLE (MEM_READ_EXTANY | MEM_WRITE_EXTANY)
|
||||
|
||||
typedef struct hb4_t
|
||||
{
|
||||
apm_t *apm;
|
||||
smram_t *smram;
|
||||
|
||||
uint8_t pci_conf[256]; /* PCI Registers */
|
||||
uint8_t shadow,
|
||||
shadow_read, shadow_write,
|
||||
pci_conf[256]; /* PCI Registers */
|
||||
int mem_state[9];
|
||||
smram_t *smram[3]; /* SMRAM Handlers */
|
||||
} hb4_t;
|
||||
|
||||
void hb4_shadow(int cur_addr, hb4_t *dev)
|
||||
{
|
||||
mem_set_mem_state_both(0xc0000, 0x8000, (dev->pci_conf[0x54] & 2) ? (CAN_READ | CAN_WRITE) : DISABLE);
|
||||
for (int i = 2; i < 8; i++)
|
||||
mem_set_mem_state_both(0xc8000 + ((i - 2) << 14), 0x4000, (dev->pci_conf[0x54] & (1 << i)) ? (CAN_READ | CAN_WRITE) : DISABLE);
|
||||
|
||||
mem_set_mem_state_both(0xe0000, 0x20000, CAN_READ | CAN_WRITE);
|
||||
|
||||
static int shadow_bios[4] = { (MEM_READ_EXTANY | MEM_WRITE_INTERNAL), (MEM_READ_EXTANY | MEM_WRITE_EXTANY),
|
||||
(MEM_READ_INTERNAL | MEM_WRITE_INTERNAL), (MEM_READ_INTERNAL | MEM_WRITE_EXTANY) };
|
||||
static int shadow_read[2] = { MEM_READ_EXTANY, MEM_READ_INTERNAL };
|
||||
static int shadow_write[2] = { MEM_WRITE_INTERNAL, MEM_WRITE_EXTANY };
|
||||
|
||||
|
||||
int
|
||||
hb4_shadow_bios_high(hb4_t *dev)
|
||||
{
|
||||
int state;
|
||||
|
||||
state = shadow_bios[dev->pci_conf[0x55] >> 6];
|
||||
|
||||
if (state != dev->mem_state[8]) {
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, state);
|
||||
if ((dev->mem_state[8] & MEM_READ_INTERNAL) && !(state & MEM_READ_INTERNAL))
|
||||
mem_invalidate_range(0xf0000, 0xfffff);
|
||||
dev->mem_state[8] = state;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hb4_shadow_bios_low(hb4_t *dev)
|
||||
{
|
||||
int state;
|
||||
|
||||
state = shadow_bios[(dev->pci_conf[0x55] >> 6) & (dev->shadow | 0x01)];
|
||||
|
||||
if (state != dev->mem_state[7]) {
|
||||
mem_set_mem_state_both(0xe0000, 0x10000, state);
|
||||
dev->mem_state[7] = state;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hb4_shadow_main(hb4_t *dev)
|
||||
{
|
||||
int i, state;
|
||||
int n = 0;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
state = shadow_read[dev->shadow && ((dev->pci_conf[0x54] >> (i + 2)) & 0x01)] |
|
||||
shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
|
||||
|
||||
if (state != dev->mem_state[i + 1]) {
|
||||
n++;
|
||||
mem_set_mem_state_both(0xc8000 + (i << 14), 0x4000, state);
|
||||
dev->mem_state[i + 1] = state;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hb4_shadow_video(hb4_t *dev)
|
||||
{
|
||||
int state;
|
||||
|
||||
state = shadow_read[dev->shadow && ((dev->pci_conf[0x54] >> 1) & 0x01)] |
|
||||
shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
|
||||
|
||||
if (state != dev->mem_state[0]) {
|
||||
mem_set_mem_state_both(0xc0000, 0x8000, state);
|
||||
dev->mem_state[0] = state;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hb4_shadow(hb4_t *dev)
|
||||
{
|
||||
int n = 0;
|
||||
hb4_log("SHADOW: %02X%02X\n", dev->pci_conf[0x55], dev->pci_conf[0x54]);
|
||||
|
||||
n = hb4_shadow_bios_high(dev);
|
||||
n += hb4_shadow_bios_low(dev);
|
||||
n += hb4_shadow_main(dev);
|
||||
n += hb4_shadow_video(dev);
|
||||
|
||||
if (n > 0)
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
um8881_write(int func, int addr, uint8_t val, void *priv)
|
||||
hb4_smram(hb4_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
|
||||
/* Bit 0, if set, enables SMRAM access outside SMM. SMRAM appears to be always enabled
|
||||
in SMM, and is always set to A0000-BFFFF. */
|
||||
smram_enable(dev->smram[0], 0x000a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1);
|
||||
/* There's a mirror of the SMRAM at 0E0A0000, mapped to A0000. */
|
||||
smram_enable(dev->smram[1], 0x0e0a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1);
|
||||
/* There's another mirror of the SMRAM at 4E0A0000, mapped to A0000. */
|
||||
smram_enable(dev->smram[2], 0x4e0a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1);
|
||||
|
||||
/* Bit 5 seems to set data to go to PCI and code to DRAM. The Samsung SPC7700P-LW uses
|
||||
this. */
|
||||
if (dev->pci_conf[0x60] & 0x20) {
|
||||
if (dev->pci_conf[0x60] & 0x01)
|
||||
mem_set_mem_state_smram_ex(0, 0x000a0000, 0x20000, 0x02);
|
||||
mem_set_mem_state_smram_ex(1, 0x000a0000, 0x20000, 0x02);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hb4_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
hb4_t *dev = (hb4_t *)priv;
|
||||
hb4_log("UM8881: dev->regs[%02x] = %02x\n", addr, val);
|
||||
|
||||
if (addr > 3) /* We don't know the RW status of registers but Phoenix writes on some RO registers too*/
|
||||
hb4_log("UM8881: dev->regs[%02x] = %02x POST: %02x \n", addr, val, inb(0x80));
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x50:
|
||||
dev->pci_conf[addr] = ((val & 0xf8) | 4); /* Hardcode Cache Size to 512KB */
|
||||
cpu_cache_ext_enabled = !!(val & 0x80); /* Fixes freezing issues on the HOT-433A*/
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
switch (addr) {
|
||||
case 0x04: case 0x05:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x54:
|
||||
case 0x55:
|
||||
dev->pci_conf[addr] = val & (!(addr & 1) ? 0xfe : 0xff);
|
||||
hb4_shadow(addr, dev);
|
||||
break;
|
||||
case 0x07:
|
||||
dev->pci_conf[addr] &= ~(val & 0xf9);
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
break;
|
||||
case 0x0c: case 0x0d:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x61:
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
case 0x50:
|
||||
dev->pci_conf[addr] = ((val & 0xf8) | 4); /* Hardcode Cache Size to 512KB */
|
||||
cpu_cache_ext_enabled = !!(val & 0x80); /* Fixes freezing issues on the HOT-433A*/
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
default:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
}
|
||||
case 0x51: case 0x52:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x53:
|
||||
dev->pci_conf[addr] = val;
|
||||
hb4_log("HB53: %02X\n", val);
|
||||
break;
|
||||
|
||||
case 0x55:
|
||||
dev->shadow_read = (val & 0x80);
|
||||
dev->shadow_write = (val & 0x40);
|
||||
dev->pci_conf[addr] = val;
|
||||
hb4_shadow(dev);
|
||||
break;
|
||||
case 0x54:
|
||||
dev->shadow = (val & 0x01) << 1;
|
||||
dev->pci_conf[addr] = val;
|
||||
hb4_shadow(dev);
|
||||
break;
|
||||
|
||||
case 0x56 ... 0x5f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
dev->pci_conf[addr] = val;
|
||||
hb4_smram(dev);
|
||||
break;
|
||||
|
||||
case 0x61:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
um8881_read(int func, int addr, void *priv)
|
||||
hb4_read(int func, int addr, void *priv)
|
||||
{
|
||||
hb4_t *dev = (hb4_t *)priv;
|
||||
return dev->pci_conf[addr];
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0)
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hb4_reset(void *priv)
|
||||
{
|
||||
hb4_t *dev = (hb4_t *)priv;
|
||||
memset(dev->pci_conf, 0x00, sizeof(dev->pci_conf));
|
||||
|
||||
/* Defaults */
|
||||
dev->pci_conf[0] = 0x60; /* UMC */
|
||||
dev->pci_conf[1] = 0x10;
|
||||
|
||||
dev->pci_conf[2] = 0x81; /* 8881x */
|
||||
dev->pci_conf[3] = 0x88;
|
||||
|
||||
dev->pci_conf[8] = 1;
|
||||
dev->pci_conf[7] = 2;
|
||||
|
||||
dev->pci_conf[8] = 4;
|
||||
|
||||
dev->pci_conf[0x09] = 0x00;
|
||||
dev->pci_conf[0x0a] = 0x00;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
|
||||
dev->pci_conf[0x51] = 1;
|
||||
dev->pci_conf[0x52] = 1;
|
||||
dev->pci_conf[0x5a] = 4;
|
||||
dev->pci_conf[0x5c] = 0xc0;
|
||||
dev->pci_conf[0x5d] = 0x20;
|
||||
dev->pci_conf[0x5f] = 0xff;
|
||||
|
||||
hb4_write(0, 0x54, 0x00, dev);
|
||||
hb4_write(0, 0x55, 0x00, dev);
|
||||
hb4_write(0, 0x60, 0x80, dev);
|
||||
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
memset(dev->mem_state, 0x00, sizeof(dev->mem_state));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hb4_close(void *priv)
|
||||
{
|
||||
hb4_t *dev = (hb4_t *)priv;
|
||||
|
||||
//smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
hb4_init(const device_t *info)
|
||||
{
|
||||
hb4_t *dev = (hb4_t *)malloc(sizeof(hb4_t));
|
||||
memset(dev, 0, sizeof(hb4_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, um8881_read, um8881_write, dev); /* Device 10: UMC 8881x */
|
||||
|
||||
/* APM */
|
||||
dev->apm = device_add(&apm_pci_device);
|
||||
|
||||
/* SMRAM(Needs excessive documentation before we begin SMM implementation) */
|
||||
//dev->smram = smram_add();
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, hb4_read, hb4_write, dev); /* Device 10: UMC 8881x */
|
||||
|
||||
/* Port 92 */
|
||||
device_add(&port_92_pci_device);
|
||||
|
||||
/* SMRAM */
|
||||
dev->smram[0] = smram_add();
|
||||
dev->smram[1] = smram_add();
|
||||
dev->smram[2] = smram_add();
|
||||
|
||||
hb4_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
const device_t umc_hb4_device = {
|
||||
"UMC HB4(8881F)",
|
||||
DEVICE_PCI,
|
||||
0x886a,
|
||||
hb4_init,
|
||||
hb4_close,
|
||||
hb4_reset,
|
||||
{NULL},
|
||||
NULL,
|
||||
NULL,
|
||||
NULL};
|
||||
hb4_init, hb4_close, hb4_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -213,13 +213,12 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
|
||||
return;
|
||||
|
||||
/*Read-only addresses*/
|
||||
if ((addr < 4) || ((addr >= 5) && (addr < 7)) || ((addr >= 8) && (addr < 0xd)) ||
|
||||
((addr >= 0xe) && (addr < 0x12)) || ((addr >= 0x14) && (addr < 0x50)) ||
|
||||
(addr == 0x69) || ((addr >= 0x79) && (addr < 0x7e)) ||
|
||||
((addr >= 0x81) && (addr < 0x84)) || ((addr >= 0x85) && (addr < 0x88)) ||
|
||||
((addr >= 0x8c) && (addr < 0xa8)) || ((addr >= 0xaa) && (addr < 0xac)) ||
|
||||
((addr >= 0xad) && (addr < 0xf0)) || ((addr >= 0xf8) && (addr < 0xfc)) ||
|
||||
(addr == 0xfd))
|
||||
if ((addr < 4) || ((addr > 5) && (addr < 7)) || ((addr >= 8) && (addr < 0xd)) ||
|
||||
((addr >= 0xe) && (addr != 0x0f) && (addr < 0x12)) || ((addr >= 0x14) && (addr < 0x50)) ||
|
||||
((addr > 0x7a) && (addr < 0x7e)) || ((addr >= 0x81) && (addr < 0x84)) ||
|
||||
((addr >= 0x85) && (addr < 0x88)) || ((addr >= 0x8c) && (addr < 0xa8)) ||
|
||||
((addr >= 0xaa) && (addr < 0xac)) || ((addr > 0xad) && (addr < 0xf0)) ||
|
||||
((addr >= 0xf8) && (addr < 0xfc)))
|
||||
return;
|
||||
if (((addr == 0x78) || (addr >= 0xad)) && (dev->id == VIA_597))
|
||||
return;
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/usb.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/smbus_piix4.h>
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/sio.h>
|
||||
#include <86box/hwm.h>
|
||||
@@ -172,7 +172,7 @@ pipc_trap_io_pact(int size, uint16_t addr, uint8_t write, uint8_t val, void *pri
|
||||
*(trap->sts_reg) |= trap->mask;
|
||||
trap->dev->acpi->regs.glbsts |= 0x0001;
|
||||
if (trap->dev->acpi->regs.glben & 0x0001)
|
||||
acpi_raise_smi(trap->dev->acpi);
|
||||
acpi_raise_smi(trap->dev->acpi, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ pipc_io_trap_glb(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv
|
||||
|
||||
if (*(trap->en_reg) & trap->mask) {
|
||||
*(trap->sts_reg) |= trap->mask;
|
||||
acpi_raise_smi(trap->dev->acpi);
|
||||
acpi_raise_smi(trap->dev->acpi, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -133,9 +133,9 @@ vt82c49x_recalc(vt82c49x_t *dev)
|
||||
state = (dev->regs[0x33] & 0x10) ? MEM_WRITE_ROMCS : MEM_WRITE_EXTERNAL;
|
||||
|
||||
if ((dev->regs[0x32]) & (1 << (bit + 1)))
|
||||
state = MEM_READ_INTERNAL;
|
||||
state |= MEM_READ_INTERNAL;
|
||||
else
|
||||
state = (dev->regs[0x33] & 0x10) ? MEM_READ_ROMCS : MEM_READ_EXTERNAL;
|
||||
state |= (dev->regs[0x33] & 0x10) ? MEM_READ_ROMCS : MEM_READ_EXTERNAL;
|
||||
} else if ((base >= 0xe8000) && (base <= 0xeffff)) {
|
||||
if (dev->regs[0x40] & 0x20)
|
||||
state = MEM_WRITE_DISABLED;
|
||||
|
||||
@@ -98,9 +98,18 @@ vl82c480_write(uint16_t addr, uint8_t val, void *p)
|
||||
default:
|
||||
dev->regs[dev->idx] = val;
|
||||
break;
|
||||
case 0x04:
|
||||
if (dev->regs[0x00] == 0x98)
|
||||
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x08) | (val & 0xf7);
|
||||
else
|
||||
dev->regs[dev->idx] = val;
|
||||
break;
|
||||
case 0x05:
|
||||
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x10) | (val & 0xef);
|
||||
break;
|
||||
case 0x07:
|
||||
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x40) | (val & 0xbf);
|
||||
break;
|
||||
case 0x0d: case 0x0e: case 0x0f: case 0x10:
|
||||
case 0x11: case 0x12:
|
||||
dev->regs[dev->idx] = val;
|
||||
@@ -163,11 +172,13 @@ vl82c480_init(const device_t *info)
|
||||
vl82c480_t *dev = (vl82c480_t *)malloc(sizeof(vl82c480_t));
|
||||
memset(dev, 0, sizeof(vl82c480_t));
|
||||
|
||||
dev->regs[0x00] = 0x90;
|
||||
dev->regs[0x00] = info->local;
|
||||
dev->regs[0x01] = 0xff;
|
||||
dev->regs[0x02] = 0x8a;
|
||||
dev->regs[0x03] = 0x88;
|
||||
dev->regs[0x06] = 0x1b;
|
||||
if (info->local == 0x98)
|
||||
dev->regs[0x07] = 0x21;
|
||||
dev->regs[0x08] = 0x38;
|
||||
|
||||
io_sethandler(0x00ec, 0x0004, vl82c480_read, NULL, NULL, vl82c480_write, NULL, NULL, dev);
|
||||
@@ -181,7 +192,17 @@ vl82c480_init(const device_t *info)
|
||||
const device_t vl82c480_device = {
|
||||
"VLSI VL82c480",
|
||||
0,
|
||||
0,
|
||||
0x90,
|
||||
vl82c480_init, vl82c480_close, NULL,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
const device_t vl82c486_device = {
|
||||
"VLSI VL82c486",
|
||||
0,
|
||||
0x98,
|
||||
vl82c480_init, vl82c480_close, NULL,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
|
||||
30
src/config.c
30
src/config.c
@@ -629,20 +629,26 @@ load_machine(void)
|
||||
machine = machine_get_machine_from_internal_name("pc916sx");
|
||||
else if (! strcmp(p, "cbm_sl386sx16"))
|
||||
machine = machine_get_machine_from_internal_name("cmdsl386sx16");
|
||||
else if (! strcmp(p, "olivetti_m300_08"))
|
||||
machine = machine_get_machine_from_internal_name("m30008");
|
||||
else if (! strcmp(p, "olivetti_m300_15"))
|
||||
machine = machine_get_machine_from_internal_name("m30015");
|
||||
else if (! strcmp(p, "cbm_sl386sx25"))
|
||||
machine = machine_get_machine_from_internal_name("cmdsl386sx25");
|
||||
else if (! strcmp(p, "award386dx")) /* ...merged machines... */
|
||||
machine = machine_get_machine_from_internal_name("award486");
|
||||
machine = machine_get_machine_from_internal_name("award495");
|
||||
else if (! strcmp(p, "ami386dx"))
|
||||
machine = machine_get_machine_from_internal_name("ami486");
|
||||
machine = machine_get_machine_from_internal_name("ami495");
|
||||
else if (! strcmp(p, "mr386dx"))
|
||||
machine = machine_get_machine_from_internal_name("mr486");
|
||||
machine = machine_get_machine_from_internal_name("mr495");
|
||||
else if (! strcmp(p, "award486"))
|
||||
machine = machine_get_machine_from_internal_name("award495");
|
||||
else if (! strcmp(p, "ami486"))
|
||||
machine = machine_get_machine_from_internal_name("ami495");
|
||||
else if (! strcmp(p, "mr486"))
|
||||
machine = machine_get_machine_from_internal_name("mr495");
|
||||
else if (! strcmp(p, "fw6400gx_s1"))
|
||||
machine = machine_get_machine_from_internal_name("fw6400gx");
|
||||
else if (! strcmp(p, "p54vl"))
|
||||
machine = machine_get_machine_from_internal_name("p5vl");
|
||||
else if (! strcmp(p, "chariot"))
|
||||
machine = machine_get_machine_from_internal_name("fmb");
|
||||
else if (! strcmp(p, "president")) { /* ...and removed machines */
|
||||
machine = machine_get_machine_from_internal_name("mb500n");
|
||||
migrate_from = NULL;
|
||||
@@ -1039,12 +1045,12 @@ load_ports(void)
|
||||
char temp[512];
|
||||
int c, d;
|
||||
|
||||
for (c = 0; c < 4; c++) {
|
||||
for (c = 0; c < SERIAL_MAX; c++) {
|
||||
sprintf(temp, "serial%d_enabled", c + 1);
|
||||
serial_enabled[c] = !!config_get_int(cat, temp, (c >= 2) ? 0 : 1);
|
||||
}
|
||||
|
||||
for (c = 0; c < 3; c++) {
|
||||
for (c = 0; c < PARALLEL_MAX; c++) {
|
||||
sprintf(temp, "lpt%d_enabled", c + 1);
|
||||
lpt_ports[c].enabled = !!config_get_int(cat, temp, (c == 0) ? 1 : 0);
|
||||
|
||||
@@ -1056,7 +1062,7 @@ load_ports(void)
|
||||
/* Legacy config compatibility. */
|
||||
d = config_get_int(cat, "lpt_enabled", 2);
|
||||
if (d < 2) {
|
||||
for (c = 0; c < 3; c++)
|
||||
for (c = 0; c < PARALLEL_MAX; c++)
|
||||
lpt_ports[c].enabled = d;
|
||||
}
|
||||
config_delete_var(cat, "lpt_enabled");
|
||||
@@ -2509,7 +2515,7 @@ save_ports(void)
|
||||
char temp[512];
|
||||
int c, d;
|
||||
|
||||
for (c = 0; c < 4; c++) {
|
||||
for (c = 0; c < SERIAL_MAX; c++) {
|
||||
sprintf(temp, "serial%d_enabled", c + 1);
|
||||
if (((c < 2) && serial_enabled[c]) || ((c >= 2) && !serial_enabled[c]))
|
||||
config_delete_var(cat, temp);
|
||||
@@ -2517,7 +2523,7 @@ save_ports(void)
|
||||
config_set_int(cat, temp, serial_enabled[c]);
|
||||
}
|
||||
|
||||
for (c = 0; c < 3; c++) {
|
||||
for (c = 0; c < PARALLEL_MAX; c++) {
|
||||
sprintf(temp, "lpt%d_enabled", c + 1);
|
||||
d = (c == 0) ? 1 : 0;
|
||||
if (lpt_ports[c].enabled == d)
|
||||
|
||||
@@ -591,7 +591,7 @@ smram_restore_state_p5(uint32_t *saved_state)
|
||||
smm_seg_load(&cpu_state.seg_gs);
|
||||
|
||||
if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION)
|
||||
smbase = saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET] & 0x00ffffff;
|
||||
smbase = saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET];
|
||||
|
||||
/* Am486/5x86 stuff */
|
||||
if (!is_pentium) {
|
||||
|
||||
@@ -148,9 +148,9 @@ static int fopcode;
|
||||
|
||||
static int ILLEGAL(uint32_t fetchdat)
|
||||
{
|
||||
pclog("[%04X:%08X] Illegal instruction %08X (%02X)\n", CS, cpu_state.pc, fetchdat, fopcode);
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
|
||||
pclog("Illegal instruction %08X (%02X)\n", fetchdat, fopcode);
|
||||
x86illegal();
|
||||
return 0;
|
||||
}
|
||||
@@ -457,7 +457,7 @@ const OpFn OP_TABLE(386_0f)[1024] =
|
||||
/*16-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
@@ -479,7 +479,7 @@ const OpFn OP_TABLE(386_0f)[1024] =
|
||||
/*32-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a16, opMOV_l_r_a16, opMOV_r_b_a16, opMOV_r_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
@@ -501,7 +501,7 @@ const OpFn OP_TABLE(386_0f)[1024] =
|
||||
/*16-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a32, opMOV_w_r_a32, opMOV_r_b_a32, opMOV_r_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
@@ -523,7 +523,7 @@ const OpFn OP_TABLE(386_0f)[1024] =
|
||||
/*32-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a32, opMOV_l_r_a32, opMOV_r_b_a32, opMOV_r_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
@@ -548,7 +548,7 @@ const OpFn OP_TABLE(486_0f)[1024] =
|
||||
/*16-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
@@ -570,7 +570,7 @@ const OpFn OP_TABLE(486_0f)[1024] =
|
||||
/*32-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a16, opMOV_l_r_a16, opMOV_r_b_a16, opMOV_r_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
@@ -592,7 +592,7 @@ const OpFn OP_TABLE(486_0f)[1024] =
|
||||
/*16-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a32, opMOV_w_r_a32, opMOV_r_b_a32, opMOV_r_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
@@ -614,7 +614,7 @@ const OpFn OP_TABLE(486_0f)[1024] =
|
||||
/*32-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a32, opMOV_l_r_a32, opMOV_r_b_a32, opMOV_r_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
@@ -821,7 +821,7 @@ const OpFn OP_TABLE(ibm486_0f)[1024] =
|
||||
/*16-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, ILLEGAL, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
@@ -843,7 +843,7 @@ const OpFn OP_TABLE(ibm486_0f)[1024] =
|
||||
/*32-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a16, opMOV_l_r_a16, opMOV_r_b_a16, opMOV_r_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, ILLEGAL, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
@@ -865,7 +865,7 @@ const OpFn OP_TABLE(ibm486_0f)[1024] =
|
||||
/*16-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a32, opMOV_w_r_a32, opMOV_r_b_a32, opMOV_r_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, ILLEGAL, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
@@ -887,7 +887,7 @@ const OpFn OP_TABLE(ibm486_0f)[1024] =
|
||||
/*32-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a32, opMOV_l_r_a32, opMOV_r_b_a32, opMOV_r_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, ILLEGAL, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
@@ -1094,7 +1094,7 @@ const OpFn OP_TABLE(pentium_0f)[1024] =
|
||||
/*16-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
@@ -1116,7 +1116,7 @@ const OpFn OP_TABLE(pentium_0f)[1024] =
|
||||
/*32-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a16, opMOV_l_r_a16, opMOV_r_b_a16, opMOV_r_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
@@ -1138,7 +1138,7 @@ const OpFn OP_TABLE(pentium_0f)[1024] =
|
||||
/*16-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a32, opMOV_w_r_a32, opMOV_r_b_a32, opMOV_r_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
@@ -1160,7 +1160,7 @@ const OpFn OP_TABLE(pentium_0f)[1024] =
|
||||
/*32-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a32, opMOV_l_r_a32, opMOV_r_b_a32, opMOV_r_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
|
||||
@@ -24,10 +24,6 @@ if(CYRIX_6X86)
|
||||
target_compile_definitions(cpu PRIVATE USE_CYRIX_6X86)
|
||||
endif()
|
||||
|
||||
if(M6117)
|
||||
target_compile_definitions(cpu PRIVATE USE_M6117)
|
||||
endif()
|
||||
|
||||
if(DYNAREC)
|
||||
add_library(cgt OBJECT codegen_timing_486.c codegen_timing_686.c
|
||||
codegen_timing_common.c codegen_timing_k6.c
|
||||
|
||||
@@ -124,6 +124,10 @@ int isa_cycles, cpu_inited,
|
||||
timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate, timing_misaligned;
|
||||
uint32_t cpu_features, cpu_fast_off_flags;
|
||||
|
||||
uint32_t _tr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint32_t cache_index = 0;
|
||||
uint8_t _cache[2048];
|
||||
|
||||
uint64_t cpu_CR4_mask, tsc = 0;
|
||||
uint64_t pmc[2] = {0, 0};
|
||||
|
||||
@@ -2290,6 +2294,7 @@ amd_k_invalid_rdmsr:
|
||||
EDX = tsc >> 32;
|
||||
break;
|
||||
}
|
||||
pclog("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX);
|
||||
break;
|
||||
|
||||
case CPU_PENTIUMPRO:
|
||||
@@ -2695,6 +2700,7 @@ amd_k_invalid_wrmsr:
|
||||
case CPU_CxGX1:
|
||||
case CPU_Cx6x86MX:
|
||||
#endif
|
||||
pclog("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX);
|
||||
switch (ECX) {
|
||||
case 0x10:
|
||||
tsc = EAX | ((uint64_t)EDX << 32);
|
||||
|
||||
@@ -542,6 +542,9 @@ extern uint64_t amd_efer, star;
|
||||
#define msw cpu_state.CR0.w
|
||||
extern uint32_t cr2, cr3, cr4;
|
||||
extern uint32_t dr[8];
|
||||
extern uint32_t _tr[8];
|
||||
extern uint32_t cache_index;
|
||||
extern uint8_t _cache[2048];
|
||||
|
||||
|
||||
/*Segments -
|
||||
@@ -656,6 +659,7 @@ extern void resetx86(void);
|
||||
extern void refreshread(void);
|
||||
extern void resetreadlookup(void);
|
||||
extern void softresetx86(void);
|
||||
extern void hardresetx86(void);
|
||||
extern void x86_int(int num);
|
||||
extern void x86_int_sw(int num);
|
||||
extern int x86_int_sw_rm(int num);
|
||||
|
||||
@@ -186,7 +186,6 @@ const cpu_family_t cpu_families[] = {
|
||||
{"", 0}
|
||||
}
|
||||
},
|
||||
#if defined(DEV_BRANCH) && defined(USE_M6117)
|
||||
{
|
||||
.package = CPU_PKG_M6117,
|
||||
.manufacturer = "ALi",
|
||||
@@ -198,7 +197,6 @@ const cpu_family_t cpu_families[] = {
|
||||
{"", 0}
|
||||
}
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.package = CPU_PKG_386SLC_IBM,
|
||||
.manufacturer = "IBM",
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include "cpu.h"
|
||||
#include "x86.h"
|
||||
#include <86box/machine.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/rom.h>
|
||||
@@ -239,8 +241,13 @@ reset_common(int hard)
|
||||
leave_smm();
|
||||
|
||||
/* Needed for the ALi M1533. */
|
||||
if (soft_reset_pci && !hard)
|
||||
if (is486 && (hard || soft_reset_pci)) {
|
||||
pci_reset();
|
||||
if (!hard && soft_reset_pci) {
|
||||
dma_reset();
|
||||
device_reset_all();
|
||||
}
|
||||
}
|
||||
|
||||
use32 = 0;
|
||||
cpu_cur_status = 0;
|
||||
@@ -299,7 +306,8 @@ reset_common(int hard)
|
||||
smi_block = 0;
|
||||
|
||||
if (hard) {
|
||||
smbase = is_am486dxl ? 0x00060000 : 0x00030000;
|
||||
if (is486)
|
||||
smbase = is_am486dxl ? 0x00060000 : 0x00030000;
|
||||
ppi_reset();
|
||||
}
|
||||
in_sys = 0;
|
||||
@@ -307,8 +315,12 @@ reset_common(int hard)
|
||||
shadowbios = shadowbios_write = 0;
|
||||
alt_access = cpu_end_block_after_ins = 0;
|
||||
|
||||
if (hard)
|
||||
if (hard) {
|
||||
reset_on_hlt = hlt_reset_pending = 0;
|
||||
cache_index = 0;
|
||||
memset(_tr, 0x00, sizeof(_tr));
|
||||
memset(_cache, 0x00, sizeof(_cache));
|
||||
}
|
||||
|
||||
if (!is286)
|
||||
reset_808x(hard);
|
||||
@@ -334,3 +346,21 @@ softresetx86(void)
|
||||
|
||||
reset_common(0);
|
||||
}
|
||||
|
||||
|
||||
/* Actual hard reset. */
|
||||
void
|
||||
hardresetx86(void)
|
||||
{
|
||||
dma_reset();
|
||||
device_reset_all();
|
||||
|
||||
cpu_alt_reset = 0;
|
||||
|
||||
mem_a20_alt = 0;
|
||||
mem_a20_recalc();
|
||||
|
||||
flushmmucache();
|
||||
|
||||
resetx86();
|
||||
}
|
||||
|
||||
@@ -607,6 +607,8 @@ static int opF7_l_a32(uint32_t fetchdat)
|
||||
|
||||
static int opHLT(uint32_t fetchdat)
|
||||
{
|
||||
pclog("HLT: CS = %04X, DS = %04X, ES = %04X, SS = %04X, IP = %04X\n", CS, DS, ES, SS, cpu_state.pc);
|
||||
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
|
||||
@@ -256,54 +256,113 @@ static int opMOV_DRx_r_a32(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void opMOV_r_TRx(void)
|
||||
{
|
||||
uint32_t base;
|
||||
|
||||
base = _tr[4] & 0xfffff800;
|
||||
switch (cpu_reg) {
|
||||
case 3:
|
||||
pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]);
|
||||
_tr[3] = *(uint32_t *) &(_cache[cache_index]);
|
||||
cache_index = (cache_index + 4) & 0xf;
|
||||
break;
|
||||
}
|
||||
cpu_state.regs[cpu_rm].l = _tr[cpu_reg];
|
||||
CLOCK_CYCLES(6);
|
||||
}
|
||||
static int opMOV_r_TRx_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
cpu_state.regs[cpu_rm].l = 0;
|
||||
CLOCK_CYCLES(6);
|
||||
opMOV_r_TRx();
|
||||
PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opMOV_r_TRx_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
cpu_state.regs[cpu_rm].l = 0;
|
||||
CLOCK_CYCLES(6);
|
||||
opMOV_r_TRx();
|
||||
PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void opMOV_TRx_r(void)
|
||||
{
|
||||
uint32_t base;
|
||||
int i, ctl;
|
||||
|
||||
_tr[cpu_reg] = cpu_state.regs[cpu_rm].l;
|
||||
base = _tr[4] & 0xfffff800;
|
||||
ctl = _tr[5] & 3;
|
||||
switch (cpu_reg) {
|
||||
case 3:
|
||||
pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]);
|
||||
*(uint32_t *) &(_cache[cache_index]) = _tr[3];
|
||||
cache_index = (cache_index + 4) & 0xf;
|
||||
break;
|
||||
case 4:
|
||||
if (!(cr0 & 1) && !(_tr[5] & (1 << 19)))
|
||||
pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16);
|
||||
break;
|
||||
case 5:
|
||||
pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0);
|
||||
if (!(_tr[5] & (1 << 19))) {
|
||||
switch(ctl) {
|
||||
case 0:
|
||||
pclog(" Cache fill or read...\n", base);
|
||||
break;
|
||||
case 1:
|
||||
base += (_tr[5] & 0x7f0);
|
||||
pclog(" Writing 16 bytes to %08X...\n", base);
|
||||
for (i = 0; i < 16; i += 4)
|
||||
mem_writel_phys(base + i, *(uint32_t *) &(_cache[i]));
|
||||
break;
|
||||
case 2:
|
||||
base += (_tr[5] & 0x7f0);
|
||||
pclog(" Reading 16 bytes from %08X...\n", base);
|
||||
for (i = 0; i < 16; i += 4)
|
||||
*(uint32_t *) &(_cache[i]) = mem_readl_phys(base + i);
|
||||
break;
|
||||
case 3:
|
||||
pclog(" Cache invalidate/flush...\n", base);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
CLOCK_CYCLES(6);
|
||||
}
|
||||
static int opMOV_TRx_r_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
CLOCK_CYCLES(6);
|
||||
opMOV_TRx_r();
|
||||
PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opMOV_TRx_r_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
CLOCK_CYCLES(6);
|
||||
fetch_ea_32(fetchdat);
|
||||
opMOV_TRx_r();
|
||||
PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
284
src/cpu/x86seg.c
284
src/cpu/x86seg.c
@@ -942,173 +942,173 @@ void loadcscall(uint16_t seg)
|
||||
segdat[2] = (segdat[2] & ~(3 << (5+8))) | (CPL << (5+8));
|
||||
} else /* On non-conforming segments, set RPL = CPL */
|
||||
seg = (seg & 0xfffc) | CPL;
|
||||
CS = seg;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if ((CPL == 3) && (oldcpl != 3))
|
||||
flushmmucache_cr3();
|
||||
CS = seg;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if ((CPL == 3) && (oldcpl != 3))
|
||||
flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
#ifdef ENABLE_X86SEG_LOG
|
||||
x86seg_log("Complete\n");
|
||||
x86seg_log("Complete\n");
|
||||
#endif
|
||||
cycles -= timing_call_pm;
|
||||
} else {
|
||||
type = segdat[2] & 0x0f00;
|
||||
x86seg_log("Type %03X\n", type);
|
||||
switch (type) {
|
||||
case 0x0400: /* Call gate */
|
||||
case 0x0c00: /* 386 Call gate */
|
||||
x86seg_log("Callgate %08X\n", cpu_state.pc);
|
||||
cgate32 = (type & 0x0800);
|
||||
cgate16 = !cgate32;
|
||||
cycles -= timing_call_pm;
|
||||
} else {
|
||||
type = segdat[2] & 0x0f00;
|
||||
x86seg_log("Type %03X\n", type);
|
||||
switch (type) {
|
||||
case 0x0400: /* Call gate */
|
||||
case 0x0c00: /* 386 Call gate */
|
||||
x86seg_log("Callgate %08X\n", cpu_state.pc);
|
||||
cgate32 = (type & 0x0800);
|
||||
cgate16 = !cgate32;
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oldcs = CS;
|
||||
oldcs = CS;
|
||||
#endif
|
||||
count = segdat[2] & 0x001f;
|
||||
if (DPL < CPL) {
|
||||
x86gpf("loadcscall(): ex DPL < CPL",seg & 0xfffc);
|
||||
return;
|
||||
}
|
||||
if (DPL < (seg & 0x0003)) {
|
||||
x86gpf("loadcscall(): ex DPL < RPL", seg & 0xfffc);
|
||||
return;
|
||||
}
|
||||
if (!(segdat[2] & 0x8000)) {
|
||||
x86np("Call gate not present", seg & 0xfffc);
|
||||
return;
|
||||
}
|
||||
seg2 = segdat[1];
|
||||
count = segdat[2] & 0x001f;
|
||||
if (DPL < CPL) {
|
||||
x86gpf("loadcscall(): ex DPL < CPL",seg & 0xfffc);
|
||||
return;
|
||||
}
|
||||
if (DPL < (seg & 0x0003)) {
|
||||
x86gpf("loadcscall(): ex DPL < RPL", seg & 0xfffc);
|
||||
return;
|
||||
}
|
||||
if (!(segdat[2] & 0x8000)) {
|
||||
x86np("Call gate not present", seg & 0xfffc);
|
||||
return;
|
||||
}
|
||||
seg2 = segdat[1];
|
||||
|
||||
x86seg_log("New address : %04X:%08X\n", seg2, newpc);
|
||||
x86seg_log("New address : %04X:%08X\n", seg2, newpc);
|
||||
|
||||
if (!(seg2 & 0xfffc)) {
|
||||
x86gpf("loadcscall(): ex selector is NULL", 0);
|
||||
return;
|
||||
}
|
||||
addr = seg2 & 0xfff8;
|
||||
dt = (seg2 & 0x0004) ? &ldt : &gdt;
|
||||
if ((addr + 7) > dt->limit) {
|
||||
x86gpf("loadcscall(): ex Selector > DT limit", seg2 & 0xfff8);
|
||||
return;
|
||||
}
|
||||
addr += dt->base;
|
||||
read_descriptor(addr, segdat, segdat32, 1);
|
||||
if (cpu_state.abrt)
|
||||
return;
|
||||
if (!(seg2 & 0xfffc)) {
|
||||
x86gpf("loadcscall(): ex selector is NULL", 0);
|
||||
return;
|
||||
}
|
||||
addr = seg2 & 0xfff8;
|
||||
dt = (seg2 & 0x0004) ? &ldt : &gdt;
|
||||
if ((addr + 7) > dt->limit) {
|
||||
x86gpf("loadcscall(): ex Selector > DT limit", seg2 & 0xfff8);
|
||||
return;
|
||||
}
|
||||
addr += dt->base;
|
||||
read_descriptor(addr, segdat, segdat32, 1);
|
||||
if (cpu_state.abrt)
|
||||
return;
|
||||
|
||||
x86seg_log("Code seg2 call - %04X - %04X %04X %04X\n", seg2, segdat[0], segdat[1], segdat[2]);
|
||||
|
||||
if (DPL > CPL) {
|
||||
x86gpf("loadcscall(): ex DPL > CPL", seg2 & 0xfffc);
|
||||
return;
|
||||
}
|
||||
if (!(segdat[2] & 0x8000)) {
|
||||
x86seg_log("Call gate CS not present %04X\n", seg2);
|
||||
x86np("Call gate CS not present", seg2 & 0xfffc);
|
||||
return;
|
||||
}
|
||||
if (DPL > CPL) {
|
||||
x86gpf("loadcscall(): ex DPL > CPL", seg2 & 0xfffc);
|
||||
return;
|
||||
}
|
||||
if (!(segdat[2] & 0x8000)) {
|
||||
x86seg_log("Call gate CS not present %04X\n", seg2);
|
||||
x86np("Call gate CS not present", seg2 & 0xfffc);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (segdat[2] & 0x1f00) {
|
||||
case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming code */
|
||||
if (DPL < CPL) {
|
||||
switch (segdat[2] & 0x1f00) {
|
||||
case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming code */
|
||||
if (DPL < CPL) {
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
uint16_t oldcs = CS;
|
||||
uint16_t oldcs = CS;
|
||||
#endif
|
||||
oaddr = addr;
|
||||
/* Load new stack */
|
||||
oldss = SS;
|
||||
oldsp = oldsp2 = ESP;
|
||||
cpl_override = 1;
|
||||
if (tr.access & 8) {
|
||||
addr = 4 + tr.base + (DPL << 3);
|
||||
newss = readmemw(0, addr + 4);
|
||||
if (cpu_16bitbus) {
|
||||
newsp = readmemw(0, addr);
|
||||
newsp |= (readmemw(0, addr + 2) << 16);
|
||||
} else
|
||||
newsp = readmeml(0, addr);
|
||||
} else {
|
||||
addr = 2 + tr.base + (DPL * 4);
|
||||
newss = readmemw(0, addr + 2);
|
||||
oaddr = addr;
|
||||
/* Load new stack */
|
||||
oldss = SS;
|
||||
oldsp = oldsp2 = ESP;
|
||||
cpl_override = 1;
|
||||
if (tr.access & 8) {
|
||||
addr = 4 + tr.base + (DPL << 3);
|
||||
newss = readmemw(0, addr + 4);
|
||||
if (cpu_16bitbus) {
|
||||
newsp = readmemw(0, addr);
|
||||
}
|
||||
cpl_override = 0;
|
||||
if (cpu_state.abrt)
|
||||
return;
|
||||
x86seg_log("New stack %04X:%08X\n", newss, newsp);
|
||||
if (!(newss & 0xfffc)) {
|
||||
x86ts(NULL, newss & 0xfffc);
|
||||
return;
|
||||
}
|
||||
addr = newss & 0xfff8;
|
||||
dt = (newss & 0x0004) ? &ldt : &gdt;
|
||||
if ((addr + 7) > dt->limit) {
|
||||
fatal("Bigger than DT limit %04X %08X %04X CSC SS\n", newss, addr, dt->limit);
|
||||
x86ts(NULL, newss & ~3);
|
||||
return;
|
||||
}
|
||||
addr += dt->base;
|
||||
x86seg_log("Read stack seg\n");
|
||||
read_descriptor(addr, segdat2, segdat232, 1);
|
||||
if (cpu_state.abrt)
|
||||
return;
|
||||
x86seg_log("Read stack seg done!\n");
|
||||
if (((newss & 0x0003) != DPL) || (DPL2 != DPL)) {
|
||||
x86ts(NULL, newss & 0xfffc);
|
||||
return;
|
||||
}
|
||||
if ((segdat2[2] & 0x1a00) != 0x1200) {
|
||||
x86ts("Call gate loading SS unknown type", newss & 0xfffc);
|
||||
return;
|
||||
}
|
||||
if (!(segdat2[2] & 0x8000)) {
|
||||
x86ss("Call gate loading SS not present", newss & 0xfffc);
|
||||
return;
|
||||
}
|
||||
if (!stack32)
|
||||
oldsp &= 0xffff;
|
||||
SS = newss;
|
||||
set_stack32((segdat2[3] & 0x0040) ? 1 : 0);
|
||||
if (stack32)
|
||||
ESP = newsp;
|
||||
else
|
||||
SP = newsp;
|
||||
newsp |= (readmemw(0, addr + 2) << 16);
|
||||
} else
|
||||
newsp = readmeml(0, addr);
|
||||
} else {
|
||||
addr = 2 + tr.base + (DPL * 4);
|
||||
newss = readmemw(0, addr + 2);
|
||||
newsp = readmemw(0, addr);
|
||||
}
|
||||
cpl_override = 0;
|
||||
if (cpu_state.abrt)
|
||||
return;
|
||||
x86seg_log("New stack %04X:%08X\n", newss, newsp);
|
||||
if (!(newss & 0xfffc)) {
|
||||
x86ts(NULL, newss & 0xfffc);
|
||||
return;
|
||||
}
|
||||
addr = newss & 0xfff8;
|
||||
dt = (newss & 0x0004) ? &ldt : &gdt;
|
||||
if ((addr + 7) > dt->limit) {
|
||||
fatal("Bigger than DT limit %04X %08X %04X CSC SS\n", newss, addr, dt->limit);
|
||||
x86ts(NULL, newss & ~3);
|
||||
return;
|
||||
}
|
||||
addr += dt->base;
|
||||
x86seg_log("Read stack seg\n");
|
||||
read_descriptor(addr, segdat2, segdat232, 1);
|
||||
if (cpu_state.abrt)
|
||||
return;
|
||||
x86seg_log("Read stack seg done!\n");
|
||||
if (((newss & 0x0003) != DPL) || (DPL2 != DPL)) {
|
||||
x86ts(NULL, newss & 0xfffc);
|
||||
return;
|
||||
}
|
||||
if ((segdat2[2] & 0x1a00) != 0x1200) {
|
||||
x86ts("Call gate loading SS unknown type", newss & 0xfffc);
|
||||
return;
|
||||
}
|
||||
if (!(segdat2[2] & 0x8000)) {
|
||||
x86ss("Call gate loading SS not present", newss & 0xfffc);
|
||||
return;
|
||||
}
|
||||
if (!stack32)
|
||||
oldsp &= 0xffff;
|
||||
SS = newss;
|
||||
set_stack32((segdat2[3] & 0x0040) ? 1 : 0);
|
||||
if (stack32)
|
||||
ESP = newsp;
|
||||
else
|
||||
SP = newsp;
|
||||
|
||||
do_seg_load(&cpu_state.seg_ss, segdat2);
|
||||
do_seg_load(&cpu_state.seg_ss, segdat2);
|
||||
|
||||
x86seg_log("Set access 1\n");
|
||||
cpl_override = 1;
|
||||
writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */
|
||||
cpl_override = 0;
|
||||
x86seg_log("Set access 1\n");
|
||||
cpl_override = 1;
|
||||
writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */
|
||||
cpl_override = 0;
|
||||
|
||||
CS = seg2;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if ((CPL == 3) && (oldcpl != 3))
|
||||
flushmmucache_cr3();
|
||||
CS = seg2;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if ((CPL == 3) && (oldcpl != 3))
|
||||
flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
set_use32(segdat[3] & 0x0040);
|
||||
cpu_state.pc = newpc;
|
||||
set_use32(segdat[3] & 0x0040);
|
||||
cpu_state.pc = newpc;
|
||||
|
||||
x86seg_log("Set access 2\n");
|
||||
x86seg_log("Set access 2\n");
|
||||
|
||||
cpl_override = 1;
|
||||
writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */
|
||||
cpl_override = 0;
|
||||
cpl_override = 1;
|
||||
writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */
|
||||
cpl_override = 0;
|
||||
|
||||
x86seg_log("Type %04X\n", type);
|
||||
if (type == 0x0c00) {
|
||||
PUSHL(oldss);
|
||||
PUSHL(oldsp2);
|
||||
if (cpu_state.abrt) {
|
||||
SS = oldss;
|
||||
ESP = oldsp2;
|
||||
x86seg_log("Type %04X\n", type);
|
||||
if (type == 0x0c00) {
|
||||
PUSHL(oldss);
|
||||
PUSHL(oldsp2);
|
||||
if (cpu_state.abrt) {
|
||||
SS = oldss;
|
||||
ESP = oldsp2;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
CS = oldcs;
|
||||
CS = oldcs;
|
||||
#endif
|
||||
return;
|
||||
return;
|
||||
}
|
||||
if (count) {
|
||||
while (count--) {
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
|
||||
add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c
|
||||
hwm_vt82c686.c ibm_5161.c isamem.c isartc.c ../lpt.c pci_bridge.c
|
||||
postcard.c serial.c vpc2007.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c
|
||||
smbus_piix4.c keyboard.c keyboard_xt.c keyboard_at.c mouse.c mouse_bus.c
|
||||
mouse_serial.c mouse_ps2.c phoenix_486_jumper.c)
|
||||
postcard.c serial.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c
|
||||
smbus_piix4.c smbus_ali7101.c keyboard.c keyboard_xt.c keyboard_at.c
|
||||
mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c phoenix_486_jumper.c)
|
||||
|
||||
if(LASERXT)
|
||||
target_compile_definitions(dev PRIVATE USE_LASERXT)
|
||||
|
||||
@@ -41,7 +41,7 @@ typedef struct {
|
||||
uint16_t regs[32];
|
||||
uint8_t addr_register: 5;
|
||||
|
||||
uint8_t i2c_addr: 7, i2c_state: 2;
|
||||
uint8_t i2c_addr: 7, i2c_state: 2, i2c_enabled: 1;
|
||||
} gl518sm_t;
|
||||
|
||||
|
||||
@@ -78,12 +78,14 @@ gl518sm_remap(gl518sm_t *dev, uint8_t addr)
|
||||
{
|
||||
gl518sm_log("GL518SM: remapping to SMBus %02Xh\n", addr);
|
||||
|
||||
i2c_removehandler(i2c_smbus, dev->i2c_addr, 1, gl518sm_i2c_start, gl518sm_i2c_read, gl518sm_i2c_write, NULL, dev);
|
||||
if (dev->i2c_enabled)
|
||||
i2c_removehandler(i2c_smbus, dev->i2c_addr, 1, gl518sm_i2c_start, gl518sm_i2c_read, gl518sm_i2c_write, NULL, dev);
|
||||
|
||||
if (addr < 0x80)
|
||||
i2c_sethandler(i2c_smbus, addr, 1, gl518sm_i2c_start, gl518sm_i2c_read, gl518sm_i2c_write, NULL, dev);
|
||||
|
||||
dev->i2c_addr = addr;
|
||||
dev->i2c_addr = addr & 0x7f;
|
||||
dev->i2c_enabled = !(addr & 0x80);
|
||||
}
|
||||
|
||||
|
||||
@@ -244,6 +246,8 @@ gl518sm_reset(gl518sm_t *dev)
|
||||
dev->regs[0x0b] = 0xdac5;
|
||||
dev->regs[0x0c] = 0xdac5;
|
||||
dev->regs[0x0f] = 0xf8;
|
||||
|
||||
gl518sm_remap(dev, dev->i2c_addr | (dev->i2c_enabled ? 0x00 : 0x80));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -187,13 +187,14 @@ lm75_remap(lm75_t *dev, uint8_t addr)
|
||||
{
|
||||
lm75_log("LM75: remapping to SMBus %02Xh\n", addr);
|
||||
|
||||
if (dev->i2c_addr < 0x80)
|
||||
if (dev->i2c_enabled)
|
||||
i2c_removehandler(i2c_smbus, dev->i2c_addr, 1, lm75_i2c_start, lm75_i2c_read, lm75_i2c_write, NULL, dev);
|
||||
|
||||
if (addr < 0x80)
|
||||
i2c_sethandler(i2c_smbus, addr, 1, lm75_i2c_start, lm75_i2c_read, lm75_i2c_write, NULL, dev);
|
||||
|
||||
dev->i2c_addr = addr;
|
||||
dev->i2c_addr = addr & 0x7f;
|
||||
dev->i2c_enabled = !(addr & 0x80);
|
||||
}
|
||||
|
||||
|
||||
@@ -203,7 +204,7 @@ lm75_reset(lm75_t *dev)
|
||||
dev->regs[0x3] = 0x4b;
|
||||
dev->regs[0x5] = 0x50;
|
||||
|
||||
lm75_remap(dev, dev->local & 0x7f);
|
||||
lm75_remap(dev, dev->i2c_addr | (dev->i2c_enabled ? 0x00 : 0x80));
|
||||
}
|
||||
|
||||
|
||||
@@ -231,6 +232,9 @@ lm75_init(const device_t *info)
|
||||
hwm_values.temperatures[dev->local >> 8] = 30;
|
||||
dev->values = &hwm_values;
|
||||
|
||||
dev->i2c_addr = dev->local & 0x7f;
|
||||
dev->i2c_enabled = 1;
|
||||
|
||||
lm75_reset(dev);
|
||||
|
||||
return dev;
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#define LM78_AS99127F_REV1 0x040000
|
||||
#define LM78_AS99127F_REV2 0x080000
|
||||
#define LM78_W83782D 0x100000
|
||||
#define LM78_P5A 0x200000
|
||||
#define LM78_AS99127F (LM78_AS99127F_REV1 | LM78_AS99127F_REV2) /* mask covering both _REV1 and _REV2 */
|
||||
#define LM78_WINBOND (LM78_W83781D | LM78_AS99127F | LM78_W83782D) /* mask covering all Winbond variants */
|
||||
#define LM78_WINBOND_VENDOR_ID ((dev->local & LM78_AS99127F_REV1) ? 0x12c3 : 0x5ca3)
|
||||
@@ -72,7 +73,7 @@ typedef struct {
|
||||
};
|
||||
uint8_t addr_register, data_register;
|
||||
|
||||
uint8_t i2c_addr: 7, i2c_state: 1;
|
||||
uint8_t i2c_addr: 7, i2c_state: 1, i2c_enabled: 1;
|
||||
} lm78_t;
|
||||
|
||||
|
||||
@@ -258,8 +259,13 @@ lm78_reset(void *priv)
|
||||
dev->regs[0x46] = 0x40;
|
||||
dev->regs[0x47] = 0x50;
|
||||
if (dev->local & LM78_I2C) {
|
||||
if (!initialization) /* don't reset main I2C address if the reset was triggered by the INITIALIZATION bit */
|
||||
dev->i2c_addr = 0x2d;
|
||||
if (!initialization) { /* don't reset main I2C address if the reset was triggered by the INITIALIZATION bit */
|
||||
if (dev->local & LM78_P5A)
|
||||
dev->i2c_addr = 0x77;
|
||||
else
|
||||
dev->i2c_addr = 0x2d;
|
||||
dev->i2c_enabled = 1;
|
||||
}
|
||||
dev->regs[0x48] = dev->i2c_addr;
|
||||
if (dev->local & LM78_WINBOND)
|
||||
dev->regs[0x4a] = 0x01;
|
||||
@@ -315,7 +321,7 @@ lm78_reset(void *priv)
|
||||
dev->regs[0x49] = 0x40;
|
||||
}
|
||||
|
||||
lm78_remap(dev, dev->i2c_addr);
|
||||
lm78_remap(dev, dev->i2c_addr | (dev->i2c_enabled ? 0x00 : 0x80));
|
||||
}
|
||||
|
||||
|
||||
@@ -668,12 +674,14 @@ lm78_remap(lm78_t *dev, uint8_t addr)
|
||||
|
||||
lm78_log("LM78: remapping to SMBus %02Xh\n", addr);
|
||||
|
||||
i2c_removehandler(i2c_smbus, dev->i2c_addr, 1, lm78_i2c_start, lm78_i2c_read, lm78_i2c_write, NULL, dev);
|
||||
if (dev->i2c_enabled)
|
||||
i2c_removehandler(i2c_smbus, dev->i2c_addr, 1, lm78_i2c_start, lm78_i2c_read, lm78_i2c_write, NULL, dev);
|
||||
|
||||
if (addr < 0x80)
|
||||
i2c_sethandler(i2c_smbus, addr, 1, lm78_i2c_start, lm78_i2c_read, lm78_i2c_write, NULL, dev);
|
||||
|
||||
dev->i2c_addr = addr;
|
||||
dev->i2c_addr = addr & 0x7f;
|
||||
dev->i2c_enabled = !(addr & 0x80);
|
||||
|
||||
if (dev->local & LM78_AS99127F) {
|
||||
/* Store our handle on the primary LM75 device to ensure reads/writes
|
||||
@@ -798,6 +806,17 @@ const device_t w83781d_device = {
|
||||
};
|
||||
|
||||
|
||||
/* Winbond W83781D on ISA and SMBus. */
|
||||
const device_t w83781d_p5a_device = {
|
||||
"Winbond W83781D Hardware Monitor (ASUS P5A)",
|
||||
DEVICE_ISA,
|
||||
0x290 | LM78_I2C | LM78_W83781D | LM78_P5A,
|
||||
lm78_init, lm78_close, lm78_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/* The AS99127F is an ASIC manufactured by Holtek for ASUS, containing an
|
||||
I2C-only W83781D clone with additional voltages, GPIOs and fan control. */
|
||||
const device_t as99127f_device = {
|
||||
|
||||
@@ -57,8 +57,6 @@
|
||||
#define STAT_IFULL 0x02
|
||||
#define STAT_OFULL 0x01
|
||||
|
||||
#define PS2_REFRESH_TIME (16 * TIMER_USEC)
|
||||
|
||||
#define RESET_DELAY_TIME (100 * 10) /* 600ms */
|
||||
|
||||
#define CCB_UNUSED 0x80
|
||||
@@ -97,8 +95,8 @@
|
||||
typedef struct {
|
||||
uint8_t command, status, old_status, out, old_out, secr_phase,
|
||||
mem_addr, input_port, output_port, old_output_port,
|
||||
key_command, output_locked, ami_stat, want60,
|
||||
wantirq, key_wantdata, refresh, first_write;
|
||||
key_command, output_locked, ami_stat, want60,
|
||||
wantirq, key_wantdata, ami_flags, first_write;
|
||||
|
||||
uint8_t mem[0x100];
|
||||
|
||||
@@ -108,7 +106,7 @@ typedef struct {
|
||||
|
||||
uint32_t flags;
|
||||
|
||||
pc_timer_t refresh_time, pulse_cb;
|
||||
pc_timer_t pulse_cb;
|
||||
|
||||
uint8_t (*write60_ven)(void *p, uint8_t val);
|
||||
uint8_t (*write64_ven)(void *p, uint8_t val);
|
||||
@@ -1320,6 +1318,7 @@ write60_ami(void *priv, uint8_t val)
|
||||
|
||||
case 0xcb: /* set keyboard mode */
|
||||
kbd_log("ATkbc: AMI - set keyboard mode\n");
|
||||
dev->ami_flags = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1704,11 +1703,6 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
|
||||
uint8_t mask, kbc_ven = 0x0;
|
||||
kbc_ven = dev->flags & KBC_VEN_MASK;
|
||||
|
||||
if ((kbc_ven == KBC_VEN_XI8088) && (port == 0x63))
|
||||
port = 0x61;
|
||||
|
||||
kbd_log((port == 0x61) ? "" : "ATkbc: write(%04X, %02X)\n", port, val);
|
||||
|
||||
switch (port) {
|
||||
case 0x60:
|
||||
dev->status &= ~STAT_CD;
|
||||
@@ -1970,20 +1964,6 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x61:
|
||||
ppi.pb = (ppi.pb & 0x10) | (val & 0x0f);
|
||||
|
||||
speaker_update();
|
||||
speaker_gated = val & 1;
|
||||
speaker_enable = val & 2;
|
||||
if (speaker_enable)
|
||||
was_speaker_enable = 1;
|
||||
pit_ctr_set_gate(&pit->counters[2], val & 1);
|
||||
|
||||
if (kbc_ven == KBC_VEN_XI8088)
|
||||
xi8088_turbo_set(!!(val & 0x04));
|
||||
break;
|
||||
|
||||
case 0x64:
|
||||
/* Controller command. */
|
||||
dev->want60 = 0;
|
||||
@@ -2063,7 +2043,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
case 0xca: /* read keyboard mode */
|
||||
kbd_log("ATkbc: AMI - read keyboard mode\n");
|
||||
add_data(dev, ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 0x01 : 0x00); /*ISA mode*/
|
||||
add_data(dev, dev->ami_flags);
|
||||
break;
|
||||
|
||||
case 0xcb: /* set keyboard mode */
|
||||
@@ -2133,9 +2113,6 @@ kbd_read(uint16_t port, void *priv)
|
||||
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)
|
||||
cycles -= ISA_CYCLES(8);
|
||||
|
||||
if ((kbc_ven == KBC_VEN_XI8088) && (port == 0x63))
|
||||
port = 0x61;
|
||||
|
||||
switch (port) {
|
||||
case 0x60:
|
||||
ret = dev->out;
|
||||
@@ -2144,56 +2121,6 @@ kbd_read(uint16_t port, void *priv)
|
||||
dev->last_irq = 0;
|
||||
break;
|
||||
|
||||
case 0x61:
|
||||
ret = ppi.pb & ~0xe0;
|
||||
if (ppispeakon)
|
||||
ret |= 0x20;
|
||||
if ((dev->flags & KBC_TYPE_MASK) > KBC_TYPE_PS2_NOREF) {
|
||||
if (dev->refresh)
|
||||
ret |= 0x10;
|
||||
else
|
||||
ret &= ~0x10;
|
||||
}
|
||||
if (kbc_ven == KBC_VEN_XI8088) {
|
||||
if (xi8088_turbo_get())
|
||||
ret |= 0x04;
|
||||
else
|
||||
ret &= ~0x04;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x62:
|
||||
ret = 0xff;
|
||||
if (kbc_ven == KBC_VEN_OLIVETTI) {
|
||||
/* SWA on Olivetti M240 mainboard (off=1) */
|
||||
ret = 0x00;
|
||||
if (ppi.pb & 0x8) {
|
||||
/* Switches 4, 5 - floppy drives (number) */
|
||||
int i, fdd_count = 0;
|
||||
for (i = 0; i < FDD_NUM; i++) {
|
||||
if (fdd_get_flags(i))
|
||||
fdd_count++;
|
||||
}
|
||||
if (!fdd_count)
|
||||
ret |= 0x00;
|
||||
else
|
||||
ret |= ((fdd_count - 1) << 2);
|
||||
/* Switches 6, 7 - monitor type */
|
||||
if (video_is_mda())
|
||||
ret |= 0x3;
|
||||
else if (video_is_cga())
|
||||
ret |= 0x2; /* 0x10 would be 40x25 */
|
||||
else
|
||||
ret |= 0x0;
|
||||
} else {
|
||||
/* bit 2 always on */
|
||||
ret |= 0x4;
|
||||
/* Switch 8 - 8087 FPU. */
|
||||
if (hasfpu)
|
||||
ret |= 0x02;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x64:
|
||||
ret = (dev->status & 0xfb);
|
||||
if (dev->mem[0] & STAT_SYSFLAG)
|
||||
@@ -2217,23 +2144,12 @@ kbd_read(uint16_t port, void *priv)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
kbd_refresh(void *priv)
|
||||
{
|
||||
atkbd_t *dev = (atkbd_t *)priv;
|
||||
|
||||
dev->refresh = !dev->refresh;
|
||||
timer_advance_u64(&dev->refresh_time, PS2_REFRESH_TIME);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
kbd_reset(void *priv)
|
||||
{
|
||||
atkbd_t *dev = (atkbd_t *)priv;
|
||||
int i;
|
||||
uint8_t kbc_ven = 0x0;
|
||||
kbc_ven = dev->flags & KBC_VEN_MASK;
|
||||
uint8_t kbc_ven = dev->flags & KBC_VEN_MASK;
|
||||
|
||||
dev->first_write = 1;
|
||||
// dev->status = STAT_UNLOCKED | STAT_CD;
|
||||
@@ -2271,6 +2187,8 @@ kbd_reset(void *priv)
|
||||
memset(keyboard_set3_flags, 0, 512);
|
||||
|
||||
set_scancode_map(dev);
|
||||
|
||||
dev->ami_flags = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) ? 0x01 : 0x00;
|
||||
}
|
||||
|
||||
|
||||
@@ -2292,7 +2210,6 @@ kbd_close(void *priv)
|
||||
|
||||
/* Stop timers. */
|
||||
timer_disable(&dev->send_delay_timer);
|
||||
timer_disable(&dev->refresh_time);
|
||||
|
||||
keyboard_scan = 0;
|
||||
keyboard_send = NULL;
|
||||
@@ -2318,15 +2235,11 @@ kbd_init(const device_t *info)
|
||||
video_reset(gfxcard);
|
||||
kbd_reset(dev);
|
||||
|
||||
io_sethandler(0x0060, 5,
|
||||
kbd_read, NULL, NULL, kbd_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0060, 1, kbd_read, NULL, NULL, kbd_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0064, 1, kbd_read, NULL, NULL, kbd_write, NULL, NULL, dev);
|
||||
keyboard_send = add_data_kbd;
|
||||
|
||||
timer_add(&dev->send_delay_timer, kbd_poll, dev, 1);
|
||||
|
||||
if ((dev->flags & KBC_TYPE_MASK) > KBC_TYPE_PS2_NOREF)
|
||||
timer_add(&dev->refresh_time, kbd_refresh, dev, 1);
|
||||
|
||||
timer_add(&dev->pulse_cb, pulse_poll, dev, 0);
|
||||
|
||||
dev->write60_ven = NULL;
|
||||
|
||||
@@ -593,20 +593,18 @@ kbd_read(uint16_t port, void *priv)
|
||||
case 0x62:
|
||||
if (kbd->type == 0)
|
||||
ret = 0x00;
|
||||
else if (kbd->type == 1) {
|
||||
else if (kbd->type == 1) {
|
||||
if (kbd->pb & 0x04)
|
||||
ret = ((mem_size-64) / 32) & 0x0f;
|
||||
ret = ((mem_size - 64) / 32) & 0x0f;
|
||||
else
|
||||
ret = ((mem_size-64) / 32) >> 4;
|
||||
}
|
||||
else if (kbd->type == 8 || kbd->type == 9) {
|
||||
/* Olivetti M19 or Zenith Data Systems Z-151 */
|
||||
if (kbd->pb & 0x04)
|
||||
ret = ((mem_size - 64) / 32) >> 4;
|
||||
} else if (kbd->type == 8 || kbd->type == 9) {
|
||||
/* Olivetti M19 or Zenith Data Systems Z-151 */
|
||||
if (kbd->pb & 0x04)
|
||||
ret = kbd->pd & 0xbf;
|
||||
else
|
||||
ret = kbd->pd >> 4;
|
||||
}
|
||||
else {
|
||||
else
|
||||
ret = kbd->pd >> 4;
|
||||
} else {
|
||||
if (kbd->pb & 0x08)
|
||||
ret = kbd->pd >> 4;
|
||||
else {
|
||||
@@ -638,7 +636,6 @@ kbd_read(uint16_t port, void *priv)
|
||||
case 0x63:
|
||||
if ((kbd->type == 2) || (kbd->type == 3) || (kbd->type == 4) || (kbd->type == 6))
|
||||
ret = kbd->pd;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -688,119 +685,116 @@ kbd_init(const device_t *info)
|
||||
|
||||
video_reset(gfxcard);
|
||||
|
||||
if (kbd->type <= 3 || kbd-> type == 8) {
|
||||
|
||||
if ((kbd->type <= 3) || (kbd->type == 4) || (kbd->type == 6)) {
|
||||
/* DIP switch readout: bit set = OFF, clear = ON. */
|
||||
if (kbd->type != 8)
|
||||
/* Switches 7, 8 - floppy drives. */
|
||||
kbd->pd = get_fdd_switch_settings();
|
||||
else
|
||||
/* Olivetti M19
|
||||
* Jumpers J1, J2 - monitor type.
|
||||
* 01 - mono (high-res)
|
||||
* 10 - color (low-res, disables 640x400x2 mode)
|
||||
* 00 - autoswitching
|
||||
*/
|
||||
kbd->pd |= 0x00;
|
||||
|
||||
kbd->pd |= get_videomode_switch_settings();
|
||||
|
||||
/* Switches 3, 4 - memory size. */
|
||||
// Note to Compaq/Toshiba keyboard maintainers: type 4 and 6 will never be activated in this block
|
||||
// Should the top if be closed right after setting floppy drive count?
|
||||
if ((kbd->type == 3) || (kbd->type == 4) || (kbd->type == 6)) {
|
||||
switch (mem_size) {
|
||||
case 256:
|
||||
kbd->pd |= 0x00;
|
||||
break;
|
||||
case 512:
|
||||
kbd->pd |= 0x04;
|
||||
break;
|
||||
case 576:
|
||||
kbd->pd |= 0x08;
|
||||
break;
|
||||
case 640:
|
||||
default:
|
||||
kbd->pd |= 0x0c;
|
||||
break;
|
||||
}
|
||||
} else if (kbd->type >= 1) {
|
||||
switch (mem_size) {
|
||||
case 64:
|
||||
kbd->pd |= 0x00;
|
||||
break;
|
||||
case 128:
|
||||
kbd->pd |= 0x04;
|
||||
break;
|
||||
case 192:
|
||||
kbd->pd |= 0x08;
|
||||
break;
|
||||
case 256:
|
||||
default:
|
||||
kbd->pd |= 0x0c;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (mem_size) {
|
||||
case 16:
|
||||
kbd->pd |= 0x00;
|
||||
break;
|
||||
case 32:
|
||||
kbd->pd |= 0x04;
|
||||
break;
|
||||
case 48:
|
||||
kbd->pd |= 0x08;
|
||||
break;
|
||||
case 64:
|
||||
default:
|
||||
kbd->pd |= 0x0c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (kbd->type == 8)
|
||||
/* Olivetti M19
|
||||
* Jumpers J1, J2 - monitor type.
|
||||
* 01 - mono (high-res)
|
||||
* 10 - color (low-res, disables 640x400x2 mode)
|
||||
* 00 - autoswitching
|
||||
*/
|
||||
kbd->pd |= 0x00;
|
||||
else
|
||||
/* Switches 7, 8 - floppy drives. */
|
||||
kbd->pd = get_fdd_switch_settings();
|
||||
|
||||
/* Switch 2 - 8087 FPU. */
|
||||
if (hasfpu)
|
||||
kbd->pd |= 0x02;
|
||||
kbd->pd |= get_videomode_switch_settings();
|
||||
|
||||
/* Switch 1 - always off. */
|
||||
kbd->pd |= 0x01;
|
||||
/* Switches 3, 4 - memory size. */
|
||||
if ((kbd->type == 3) || (kbd->type == 4) || (kbd->type == 6)) {
|
||||
switch (mem_size) {
|
||||
case 256:
|
||||
kbd->pd |= 0x00;
|
||||
break;
|
||||
case 512:
|
||||
kbd->pd |= 0x04;
|
||||
break;
|
||||
case 576:
|
||||
kbd->pd |= 0x08;
|
||||
break;
|
||||
case 640:
|
||||
default:
|
||||
kbd->pd |= 0x0c;
|
||||
break;
|
||||
}
|
||||
} else if (kbd->type >= 1) {
|
||||
switch (mem_size) {
|
||||
case 64:
|
||||
kbd->pd |= 0x00;
|
||||
break;
|
||||
case 128:
|
||||
kbd->pd |= 0x04;
|
||||
break;
|
||||
case 192:
|
||||
kbd->pd |= 0x08;
|
||||
break;
|
||||
case 256:
|
||||
default:
|
||||
kbd->pd |= 0x0c;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (mem_size) {
|
||||
case 16:
|
||||
kbd->pd |= 0x00;
|
||||
break;
|
||||
case 32:
|
||||
kbd->pd |= 0x04;
|
||||
break;
|
||||
case 48:
|
||||
kbd->pd |= 0x08;
|
||||
break;
|
||||
case 64:
|
||||
default:
|
||||
kbd->pd |= 0x0c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Switch 2 - 8087 FPU. */
|
||||
if (hasfpu)
|
||||
kbd->pd |= 0x02;
|
||||
|
||||
/* Switch 1 - always off. */
|
||||
kbd->pd |= 0x01;
|
||||
} else if (kbd-> type == 9) {
|
||||
/* Zenith Data Systems Z-151
|
||||
* SW2 switch settings:
|
||||
* bit 7: monitor frequency
|
||||
* bits 5-6: autoboot (00-11 resident monitor, 10 hdd, 01 fdd)
|
||||
* bits 0-4: installed memory
|
||||
*/
|
||||
kbd->pd = 0x20;
|
||||
switch (mem_size) {
|
||||
case 128:
|
||||
kbd->pd |= 0x02;
|
||||
break;
|
||||
case 192:
|
||||
kbd->pd |= 0x04;
|
||||
break;
|
||||
case 256:
|
||||
kbd->pd |= 0x02|0x04;
|
||||
break;
|
||||
case 320:
|
||||
kbd->pd |= 0x08;
|
||||
break;
|
||||
case 384:
|
||||
kbd->pd |= 0x02|0x08;
|
||||
break;
|
||||
case 448:
|
||||
kbd->pd |= 0x04|0x08;
|
||||
break;
|
||||
case 512:
|
||||
kbd->pd |= 0x02|0x04|0x08;
|
||||
break;
|
||||
case 576:
|
||||
kbd->pd |= 0x10;
|
||||
break;
|
||||
case 640:
|
||||
default:
|
||||
kbd->pd |= 0x02|0x10;
|
||||
break;
|
||||
/* Zenith Data Systems Z-151
|
||||
* SW2 switch settings:
|
||||
* bit 7: monitor frequency
|
||||
* bits 5-6: autoboot (00-11 resident monitor, 10 hdd, 01 fdd)
|
||||
* bits 0-4: installed memory
|
||||
*/
|
||||
kbd->pd = 0x20;
|
||||
switch (mem_size) {
|
||||
case 128:
|
||||
kbd->pd |= 0x02;
|
||||
break;
|
||||
case 192:
|
||||
kbd->pd |= 0x04;
|
||||
break;
|
||||
case 256:
|
||||
kbd->pd |= 0x06;
|
||||
break;
|
||||
case 320:
|
||||
kbd->pd |= 0x08;
|
||||
break;
|
||||
case 384:
|
||||
kbd->pd |= 0x0a;
|
||||
break;
|
||||
case 448:
|
||||
kbd->pd |= 0x0c;
|
||||
break;
|
||||
case 512:
|
||||
kbd->pd |= 0x0e;
|
||||
break;
|
||||
case 576:
|
||||
kbd->pd |= 0x10;
|
||||
break;
|
||||
case 640:
|
||||
default:
|
||||
kbd->pd |= 0x12;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -96,6 +96,9 @@ ps2_write(uint8_t val, void *priv)
|
||||
if (dev->flags & FLAG_CTRLDAT) {
|
||||
dev->flags &= ~FLAG_CTRLDAT;
|
||||
|
||||
if (val == 0xff)
|
||||
goto mouse_reset;
|
||||
|
||||
switch (dev->command) {
|
||||
case 0xe8: /* set mouse resolution */
|
||||
dev->resolution = val;
|
||||
@@ -191,9 +194,10 @@ ps2_write(uint8_t val, void *priv)
|
||||
|
||||
case 0xf6: /* set defaults */
|
||||
case 0xff: /* reset */
|
||||
mouse_reset:
|
||||
dev->mode = MODE_STREAM;
|
||||
dev->flags &= 0x88;
|
||||
mouse_scan = 0;
|
||||
mouse_scan = 1;
|
||||
keyboard_at_mouse_reset();
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
if (dev->command == 0xff) {
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
|
||||
#define PCI_BRIDGE_DEC_21150 0x10110022
|
||||
#define AGP_BRIDGE_ALI_M5243 0x10b95243
|
||||
#define AGP_BRIDGE_ALI_M5247 0x10b95247
|
||||
#define AGP_BRIDGE_INTEL_440LX 0x80867181
|
||||
#define AGP_BRIDGE_INTEL_440BX 0x80867191
|
||||
#define AGP_BRIDGE_INTEL_440GX 0x808671a1
|
||||
@@ -41,15 +43,16 @@
|
||||
#define AGP_BRIDGE_VIA_691 0x11068691
|
||||
#define AGP_BRIDGE_VIA_8601 0x11068601
|
||||
|
||||
#define AGP_BRIDGE_ALI(x) (((x) >> 16) == 0x10b9)
|
||||
#define AGP_BRIDGE_INTEL(x) (((x) >> 16) == 0x8086)
|
||||
#define AGP_BRIDGE_VIA(x) (((x) >> 16) == 0x1106)
|
||||
#define AGP_BRIDGE(x) ((x) >= AGP_BRIDGE_VIA_597)
|
||||
#define AGP_BRIDGE(x) ((x) >= AGP_BRIDGE_ALI_M5243)
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t local;
|
||||
uint8_t type;
|
||||
uint8_t type, ctl;
|
||||
|
||||
uint8_t regs[256];
|
||||
uint8_t bus_index;
|
||||
@@ -77,6 +80,15 @@ pci_bridge_log(const char *fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
pci_bridge_set_ctl(void *priv, uint8_t ctl)
|
||||
{
|
||||
pci_bridge_t *dev = (pci_bridge_t *) priv;
|
||||
|
||||
dev->ctl = ctl;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pci_bridge_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
@@ -87,6 +99,9 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv)
|
||||
if (func > 0)
|
||||
return;
|
||||
|
||||
if ((dev->local == AGP_BRIDGE_ALI_M5247) && (addr >= 0x40))
|
||||
return;
|
||||
|
||||
switch (addr) {
|
||||
case 0x00: case 0x01: case 0x02: case 0x03:
|
||||
case 0x06: case 0x08: case 0x09: case 0x0a:
|
||||
@@ -94,21 +109,26 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x11: case 0x12: case 0x13: case 0x14:
|
||||
case 0x15: case 0x16: case 0x17: case 0x1e:
|
||||
case 0x34: case 0x3d: case 0x67: case 0xdc:
|
||||
case 0xdd: case 0xde: case 0xdf: case 0xe0:
|
||||
case 0xe1: case 0xe2: case 0xe3:
|
||||
case 0xdd: case 0xde: case 0xdf:
|
||||
return;
|
||||
|
||||
case 0x04:
|
||||
if (AGP_BRIDGE_INTEL(dev->local)) {
|
||||
if (dev->local == AGP_BRIDGE_INTEL_440BX)
|
||||
val &= 0x1f;
|
||||
} else
|
||||
} else if (dev->local == AGP_BRIDGE_ALI_M5243)
|
||||
val |= 0x02;
|
||||
else if (dev->local == AGP_BRIDGE_ALI_M5247)
|
||||
val &= 0xc3;
|
||||
else
|
||||
val &= 0x67;
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
if (AGP_BRIDGE_INTEL(dev->local))
|
||||
val &= 0x01;
|
||||
else if (AGP_BRIDGE_ALI(dev->local))
|
||||
val &= 0x01;
|
||||
else
|
||||
val &= 0x03;
|
||||
break;
|
||||
@@ -116,6 +136,10 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x07:
|
||||
if (dev->local == AGP_BRIDGE_INTEL_440LX)
|
||||
dev->regs[addr] &= ~(val & 0x40);
|
||||
else if (dev->local == AGP_BRIDGE_ALI_M5243)
|
||||
dev->regs[addr] &= ~(val & 0xf8);
|
||||
else if (dev->local == AGP_BRIDGE_ALI_M5247)
|
||||
dev->regs[addr] &= ~(val & 0xc0);
|
||||
return;
|
||||
|
||||
case 0x0c: case 0x18:
|
||||
@@ -129,6 +153,8 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv)
|
||||
return;
|
||||
else if (AGP_BRIDGE_INTEL(dev->local))
|
||||
val &= 0xf8;
|
||||
else if (AGP_BRIDGE_ALI(dev->local))
|
||||
val &= 0xf8;
|
||||
break;
|
||||
|
||||
case 0x19:
|
||||
@@ -144,7 +170,8 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv)
|
||||
else if ((dev->local == AGP_BRIDGE_INTEL_440BX) ||
|
||||
(dev->local == AGP_BRIDGE_INTEL_440GX))
|
||||
dev->regs[addr] &= ~(val & 0xf0);
|
||||
}
|
||||
} else if (AGP_BRIDGE_ALI(dev->local))
|
||||
dev->regs[addr] &= ~(val & 0xf0);
|
||||
return;
|
||||
|
||||
case 0x1c: case 0x1d: case 0x20: case 0x22:
|
||||
@@ -152,9 +179,18 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv)
|
||||
val &= 0xf0;
|
||||
break;
|
||||
|
||||
case 0x3c:
|
||||
if (!(dev->ctl & 0x80))
|
||||
return;
|
||||
break;
|
||||
|
||||
case 0x3e:
|
||||
if (AGP_BRIDGE_VIA(dev->local))
|
||||
val &= 0x0c;
|
||||
else if (dev->local == AGP_BRIDGE_ALI_M5247)
|
||||
val &= 0x0f;
|
||||
else if (dev->local == AGP_BRIDGE_ALI_M5243)
|
||||
return;
|
||||
else if (AGP_BRIDGE(dev->local)) {
|
||||
if ((dev->local == AGP_BRIDGE_INTEL_440BX) ||
|
||||
(dev->local == AGP_BRIDGE_INTEL_440GX))
|
||||
@@ -170,7 +206,11 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv)
|
||||
if (dev->local == AGP_BRIDGE_INTEL_440LX) {
|
||||
dev->regs[addr] = ((dev->regs[addr] & 0x04) | (val & 0x02)) & ~(val & 0x04);
|
||||
return;
|
||||
} else if (AGP_BRIDGE(dev->local))
|
||||
} else if (dev->local == AGP_BRIDGE_ALI_M5247)
|
||||
return;
|
||||
else if (dev->local == AGP_BRIDGE_ALI_M5243)
|
||||
val &= 0x06;
|
||||
else if (AGP_BRIDGE(dev->local))
|
||||
return;
|
||||
else if (dev->local == PCI_BRIDGE_DEC_21150)
|
||||
val &= 0x0f;
|
||||
@@ -207,6 +247,94 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv)
|
||||
if (dev->local == PCI_BRIDGE_DEC_21150)
|
||||
val &= 0x3f;
|
||||
break;
|
||||
|
||||
case 0x86:
|
||||
if (AGP_BRIDGE_ALI(dev->local))
|
||||
val &= 0x3f;
|
||||
break;
|
||||
|
||||
case 0x87:
|
||||
if (AGP_BRIDGE_ALI(dev->local))
|
||||
val &= 0x60;
|
||||
break;
|
||||
|
||||
case 0x88:
|
||||
if (AGP_BRIDGE_ALI(dev->local))
|
||||
val &= 0x8c;
|
||||
break;
|
||||
|
||||
case 0x8b:
|
||||
if (AGP_BRIDGE_ALI(dev->local))
|
||||
val &= 0x0f;
|
||||
break;
|
||||
|
||||
case 0x8c:
|
||||
if (AGP_BRIDGE_ALI(dev->local))
|
||||
val &= 0x83;
|
||||
break;
|
||||
|
||||
case 0x8d:
|
||||
if (AGP_BRIDGE_ALI(dev->local))
|
||||
return;
|
||||
break;
|
||||
|
||||
case 0xe0: case 0xe1:
|
||||
if (AGP_BRIDGE_ALI(dev->local)) {
|
||||
if (!(dev->ctl & 0x20))
|
||||
return;
|
||||
} else
|
||||
return;
|
||||
break;
|
||||
|
||||
case 0xe2:
|
||||
if (AGP_BRIDGE_ALI(dev->local)) {
|
||||
if (dev->ctl & 0x20)
|
||||
val &= 0x3f;
|
||||
else
|
||||
return;
|
||||
} else
|
||||
return;
|
||||
break;
|
||||
case 0xe3:
|
||||
if (AGP_BRIDGE_ALI(dev->local)) {
|
||||
if (dev->ctl & 0x20)
|
||||
val &= 0xfe;
|
||||
else
|
||||
return;
|
||||
} else
|
||||
return;
|
||||
break;
|
||||
|
||||
case 0xe4:
|
||||
if (AGP_BRIDGE_ALI(dev->local)) {
|
||||
if (dev->ctl & 0x20)
|
||||
val &= 0x03;
|
||||
else
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0xe5:
|
||||
if (AGP_BRIDGE_ALI(dev->local)) {
|
||||
if (!(dev->ctl & 0x20))
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xe6:
|
||||
if (AGP_BRIDGE_ALI(dev->local)) {
|
||||
if (dev->ctl & 0x20)
|
||||
val &= 0xc0;
|
||||
else
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xe7:
|
||||
if (AGP_BRIDGE_ALI(dev->local)) {
|
||||
if (!(dev->ctl & 0x20))
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
dev->regs[addr] = val;
|
||||
@@ -251,6 +379,26 @@ pci_bridge_reset(void *priv)
|
||||
dev->regs[0x07] = 0x02;
|
||||
break;
|
||||
|
||||
case AGP_BRIDGE_ALI_M5243:
|
||||
dev->regs[0x04] = 0x06;
|
||||
dev->regs[0x07] = 0x04;
|
||||
dev->regs[0x0d] = 0x20;
|
||||
dev->regs[0x19] = 0x01;
|
||||
dev->regs[0x1b] = 0x20;
|
||||
dev->regs[0x34] = 0xe0;
|
||||
dev->regs[0x89] = 0x20;
|
||||
dev->regs[0x8a] = 0xa0;
|
||||
dev->regs[0x8e] = 0x20;
|
||||
dev->regs[0x8f] = 0x20;
|
||||
dev->regs[0xe0] = 0x01;
|
||||
pci_remap_bus(dev->bus_index, 0x01);
|
||||
break;
|
||||
|
||||
case AGP_BRIDGE_ALI_M5247:
|
||||
dev->regs[0x04] = 0x03;
|
||||
dev->regs[0x08] = 0x01;
|
||||
break;
|
||||
|
||||
case AGP_BRIDGE_INTEL_440LX:
|
||||
dev->regs[0x06] = 0xa0;
|
||||
dev->regs[0x07] = 0x02;
|
||||
@@ -266,7 +414,7 @@ pci_bridge_reset(void *priv)
|
||||
case AGP_BRIDGE_VIA_597:
|
||||
case AGP_BRIDGE_VIA_598:
|
||||
case AGP_BRIDGE_VIA_691:
|
||||
case AGP_BRIDGE_VIA_8601:
|
||||
case AGP_BRIDGE_VIA_8601:
|
||||
dev->regs[0x04] = 0x07;
|
||||
dev->regs[0x06] = 0x20;
|
||||
dev->regs[0x07] = 0x02;
|
||||
@@ -284,7 +432,9 @@ pci_bridge_reset(void *priv)
|
||||
else
|
||||
dev->regs[0x1c] = dev->regs[0x1d] = 0x01;
|
||||
|
||||
if (!AGP_BRIDGE_VIA(dev->local)) {
|
||||
if (dev->local == AGP_BRIDGE_ALI_M5247)
|
||||
dev->regs[0x1e] = 0x20;
|
||||
else if (!AGP_BRIDGE_VIA(dev->local)) {
|
||||
dev->regs[0x1e] = AGP_BRIDGE(dev->local) ? 0xa0 : 0x80;
|
||||
dev->regs[0x1f] = 0x02;
|
||||
}
|
||||
@@ -323,8 +473,10 @@ pci_bridge_init(const device_t *info)
|
||||
dev->slot = pci_add_card(AGP_BRIDGE(dev->local) ? PCI_ADD_AGPBRIDGE : PCI_ADD_BRIDGE, pci_bridge_read, pci_bridge_write, dev);
|
||||
interrupt_count = sizeof(interrupts);
|
||||
interrupt_mask = interrupt_count - 1;
|
||||
for (i = 0; i < interrupt_count; i++)
|
||||
interrupts[i] = pci_get_int(dev->slot, PCI_INTA + i);
|
||||
if (dev->slot < 32) {
|
||||
for (i = 0; i < interrupt_count; i++)
|
||||
interrupts[i] = pci_get_int(dev->slot, PCI_INTA + i);
|
||||
}
|
||||
pci_bridge_log("PCI Bridge %d: upstream bus %02X slot %02X interrupts %02X %02X %02X %02X\n", dev->bus_index, (dev->slot >> 5) & 0xff, dev->slot & 31, interrupts[0], interrupts[1], interrupts[2], interrupts[3]);
|
||||
|
||||
if (info->local == PCI_BRIDGE_DEC_21150)
|
||||
@@ -362,6 +514,35 @@ const device_t dec21150_device =
|
||||
};
|
||||
|
||||
/* AGP bridges */
|
||||
const device_t ali5243_agp_device =
|
||||
{
|
||||
"ALi M5243 AGP Bridge",
|
||||
DEVICE_PCI,
|
||||
AGP_BRIDGE_ALI_M5243,
|
||||
pci_bridge_init,
|
||||
NULL,
|
||||
pci_bridge_reset,
|
||||
{ NULL },
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* AGP bridges */
|
||||
const device_t ali5247_agp_device =
|
||||
{
|
||||
"ALi M5247 AGP Bridge",
|
||||
DEVICE_PCI,
|
||||
AGP_BRIDGE_ALI_M5247,
|
||||
pci_bridge_init,
|
||||
NULL,
|
||||
pci_bridge_reset,
|
||||
{ NULL },
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
const device_t i440lx_agp_device =
|
||||
{
|
||||
"Intel 82443LX/EX AGP Bridge",
|
||||
|
||||
@@ -39,11 +39,14 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t jumper;
|
||||
uint8_t type, jumper;
|
||||
} phoenix_486_jumper_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_PHOENIX_486_JUMPER_LOG
|
||||
int phoenix_486_jumper_do_log = ENABLE_PHOENIX_486_JUMPER_LOG;
|
||||
|
||||
|
||||
static void
|
||||
phoenix_486_jumper_log(const char *fmt, ...)
|
||||
{
|
||||
@@ -59,14 +62,19 @@ phoenix_486_jumper_log(const char *fmt, ...)
|
||||
#define phoenix_486_jumper_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
phoenix_486_jumper_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) priv;
|
||||
phoenix_486_jumper_log("Phoenix 486 Jumper: Write %02x\n", val);
|
||||
dev->jumper = val;
|
||||
if (dev->type == 1)
|
||||
dev->jumper = val & 0xbf;
|
||||
else
|
||||
dev->jumper = val;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
phoenix_486_jumper_read(uint16_t addr, void *priv)
|
||||
{
|
||||
@@ -76,6 +84,21 @@ phoenix_486_jumper_read(uint16_t addr, void *priv)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
phoenix_486_jumper_reset(void *priv)
|
||||
{
|
||||
phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) priv;
|
||||
|
||||
if (dev->type == 1)
|
||||
dev->jumper = 0x00;
|
||||
else {
|
||||
dev->jumper = 0x9f;
|
||||
if (gfxcard != 0x01)
|
||||
dev->jumper |= 0x40;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
phoenix_486_jumper_close(void *priv)
|
||||
{
|
||||
@@ -84,26 +107,38 @@ phoenix_486_jumper_close(void *priv)
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
phoenix_486_jumper_init(const device_t *info)
|
||||
{
|
||||
phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) malloc(sizeof(phoenix_486_jumper_t));
|
||||
memset(dev, 0, sizeof(phoenix_486_jumper_t));
|
||||
|
||||
dev->jumper = 0x9f;
|
||||
if (gfxcard != 0x01)
|
||||
dev->jumper |= 0x40;
|
||||
dev->type = info->local;
|
||||
|
||||
phoenix_486_jumper_reset(dev);
|
||||
|
||||
io_sethandler(0x0078, 0x0001, phoenix_486_jumper_read, NULL, NULL, phoenix_486_jumper_write, NULL, NULL, dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
const device_t phoenix_486_jumper_device = {
|
||||
"Phoenix 486 Jumper Readout",
|
||||
0,
|
||||
0,
|
||||
phoenix_486_jumper_init, phoenix_486_jumper_close, NULL,
|
||||
phoenix_486_jumper_init, phoenix_486_jumper_close, phoenix_486_jumper_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
const device_t phoenix_486_jumper_pci_device = {
|
||||
"Phoenix 486 Jumper Readout (PCI machines)",
|
||||
0,
|
||||
1,
|
||||
phoenix_486_jumper_init, phoenix_486_jumper_close, phoenix_486_jumper_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -717,20 +717,8 @@ serial_set_next_inst(int ni)
|
||||
|
||||
void
|
||||
serial_standalone_init(void) {
|
||||
if (next_inst == 0) {
|
||||
device_add_inst(&i8250_device, 1);
|
||||
device_add_inst(&i8250_device, 2);
|
||||
device_add_inst(&i8250_device, 3);
|
||||
device_add_inst(&i8250_device, 4);
|
||||
} else if (next_inst == 1) {
|
||||
device_add_inst(&i8250_device, 2);
|
||||
device_add_inst(&i8250_device, 3);
|
||||
device_add_inst(&i8250_device, 4);
|
||||
} else if (next_inst == 2) {
|
||||
device_add_inst(&i8250_device, 3);
|
||||
device_add_inst(&i8250_device, 4);
|
||||
} else
|
||||
device_add_inst(&i8250_device, 4);
|
||||
for ( ; next_inst < 4; )
|
||||
device_add_inst(&i8250_device, next_inst + 1);
|
||||
};
|
||||
|
||||
|
||||
|
||||
310
src/device/smbus_ali7101.c
Normal file
310
src/device/smbus_ali7101.c
Normal file
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of a generic ALi M7101-compatible SMBus host
|
||||
* controller.
|
||||
*
|
||||
* Authors: RichardG, <richardg867@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2020,2021 RichardG.
|
||||
* Copyright 2021 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/i2c.h>
|
||||
#include <86box/smbus.h>
|
||||
|
||||
|
||||
#ifdef ENABLE_SMBUS_ALI7101_LOG
|
||||
int smbus_ali7101_do_log = ENABLE_SMBUS_ALI7101_LOG;
|
||||
|
||||
|
||||
static void
|
||||
smbus_ali7101_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (smbus_ali7101_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define smbus_ali7101_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static uint8_t
|
||||
smbus_ali7101_read(uint16_t addr, void *priv)
|
||||
{
|
||||
smbus_ali7101_t *dev = (smbus_ali7101_t *) priv;
|
||||
uint8_t ret = 0x00;
|
||||
|
||||
switch (addr - dev->io_base) {
|
||||
case 0x00:
|
||||
ret = dev->stat;
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
ret = dev->addr;
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
ret = dev->data0;
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
ret = dev->data1;
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
ret = dev->data[dev->index++];
|
||||
if (dev->index >= SMBUS_ALI7101_BLOCK_DATA_SIZE)
|
||||
dev->index = 0;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
ret = dev->cmd;
|
||||
break;
|
||||
}
|
||||
|
||||
smbus_ali7101_log("SMBus ALI7101: read(%02X) = %02x\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
smbus_ali7101_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
smbus_ali7101_t *dev = (smbus_ali7101_t *) priv;
|
||||
uint8_t smbus_addr, cmd, read, prev_stat;
|
||||
uint16_t timer_bytes = 0;
|
||||
|
||||
smbus_ali7101_log("SMBus ALI7101: write(%02X, %02X)\n", addr, val);
|
||||
|
||||
prev_stat = dev->next_stat;
|
||||
dev->next_stat = 0x04;
|
||||
switch (addr - dev->io_base) {
|
||||
case 0x00:
|
||||
dev->stat &= ~(val & 0xf2);
|
||||
/* Make sure IDLE is set if we're not busy or errored. */
|
||||
if (dev->stat == 0x00)
|
||||
dev->stat = 0x04;
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
dev->ctl = val & 0xfc;
|
||||
if (val & 0x04) { /* cancel an in-progress command if KILL is set */
|
||||
if (prev_stat) { /* cancel only if a command is in progress */
|
||||
timer_disable(&dev->response_timer);
|
||||
dev->stat = 0x80; /* raise FAILED */
|
||||
}
|
||||
} else if (val & 0x08) { /* T_OUT_CMD */
|
||||
if (prev_stat) { /* cancel only if a command is in progress */
|
||||
timer_disable(&dev->response_timer);
|
||||
dev->stat = 0x20; /* raise DEVICE_ERR */
|
||||
}
|
||||
}
|
||||
|
||||
if (val & 0x80)
|
||||
dev->index = 0;
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
/* dispatch command if START is set */
|
||||
timer_bytes++; /* address */
|
||||
|
||||
smbus_addr = (dev->addr >> 1);
|
||||
read = dev->addr & 0x01;
|
||||
|
||||
cmd = (dev->ctl >> 4) & 0x7;
|
||||
smbus_ali7101_log("SMBus ALI7101: addr=%02X read=%d protocol=%X cmd=%02X data0=%02X data1=%02X\n", smbus_addr, read, cmd, dev->cmd, dev->data0, dev->data1);
|
||||
|
||||
/* Raise DEV_ERR if no device is at this address, or if the device returned NAK when starting the transfer. */
|
||||
if (!i2c_start(i2c_smbus, smbus_addr, read)) {
|
||||
dev->next_stat = 0x40;
|
||||
break;
|
||||
}
|
||||
|
||||
dev->next_stat = 0x10; /* raise INTER (command completed) by default */
|
||||
|
||||
/* Decode the command protocol. */
|
||||
switch (cmd) {
|
||||
case 0x0: /* quick R/W */
|
||||
break;
|
||||
|
||||
case 0x1: /* byte R/W */
|
||||
if (read) /* byte read */
|
||||
dev->data0 = i2c_read(i2c_smbus, smbus_addr);
|
||||
else /* byte write */
|
||||
i2c_write(i2c_smbus, smbus_addr, dev->data0);
|
||||
timer_bytes++;
|
||||
|
||||
break;
|
||||
|
||||
case 0x2: /* byte data R/W */
|
||||
/* command write */
|
||||
i2c_write(i2c_smbus, smbus_addr, dev->cmd);
|
||||
timer_bytes++;
|
||||
|
||||
if (read) /* byte read */
|
||||
dev->data0 = i2c_read(i2c_smbus, smbus_addr);
|
||||
else /* byte write */
|
||||
i2c_write(i2c_smbus, smbus_addr, dev->data0);
|
||||
timer_bytes++;
|
||||
|
||||
break;
|
||||
|
||||
case 0x3: /* word data R/W */
|
||||
/* command write */
|
||||
i2c_write(i2c_smbus, smbus_addr, dev->cmd);
|
||||
timer_bytes++;
|
||||
|
||||
if (read) { /* word read */
|
||||
dev->data0 = i2c_read(i2c_smbus, smbus_addr);
|
||||
dev->data1 = i2c_read(i2c_smbus, smbus_addr);
|
||||
} else { /* word write */
|
||||
i2c_write(i2c_smbus, smbus_addr, dev->data0);
|
||||
i2c_write(i2c_smbus, smbus_addr, dev->data1);
|
||||
}
|
||||
timer_bytes += 2;
|
||||
|
||||
break;
|
||||
|
||||
case 0x4: /* block R/W */
|
||||
timer_bytes++; /* count the SMBus length byte now */
|
||||
|
||||
/* fall-through */
|
||||
|
||||
default: /* unknown */
|
||||
dev->next_stat = 0x20; /* raise DEV_ERR */
|
||||
timer_bytes = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Finish transfer. */
|
||||
i2c_stop(i2c_smbus, smbus_addr);
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
dev->addr = val;
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
dev->data0 = val;
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
dev->data1 = val;
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
dev->data[dev->index++] = val;
|
||||
if (dev->index >= SMBUS_ALI7101_BLOCK_DATA_SIZE)
|
||||
dev->index = 0;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->cmd = val;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev->next_stat != 0x04) { /* schedule dispatch of any pending status register update */
|
||||
dev->stat = 0x08; /* raise HOST_BUSY while waiting */
|
||||
timer_disable(&dev->response_timer);
|
||||
/* delay = ((half clock for start + half clock for stop) + (bytes * (8 bits + ack))) * 60us period measured on real VIA 686B */
|
||||
timer_set_delay_u64(&dev->response_timer, (1 + (timer_bytes * 9)) * 60 * TIMER_USEC);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
smbus_ali7101_response(void *priv)
|
||||
{
|
||||
smbus_ali7101_t *dev = (smbus_ali7101_t *) priv;
|
||||
|
||||
/* Dispatch the status register update. */
|
||||
dev->stat = dev->next_stat;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
smbus_ali7101_remap(smbus_ali7101_t *dev, uint16_t new_io_base, uint8_t enable)
|
||||
{
|
||||
if (dev->io_base)
|
||||
io_removehandler(dev->io_base, 0x10, smbus_ali7101_read, NULL, NULL, smbus_ali7101_write, NULL, NULL, dev);
|
||||
|
||||
dev->io_base = new_io_base;
|
||||
smbus_ali7101_log("SMBus ALI7101: remap to %04Xh (%sabled)\n", dev->io_base, enable ? "en" : "dis");
|
||||
|
||||
if (enable && dev->io_base)
|
||||
io_sethandler(dev->io_base, 0x10, smbus_ali7101_read, NULL, NULL, smbus_ali7101_write, NULL, NULL, dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
smbus_ali7101_reset(void *priv)
|
||||
{
|
||||
smbus_ali7101_t *dev = (smbus_ali7101_t *) priv;
|
||||
|
||||
timer_disable(&dev->response_timer);
|
||||
dev->stat = 0x04;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
smbus_ali7101_init(const device_t *info)
|
||||
{
|
||||
smbus_ali7101_t *dev = (smbus_ali7101_t *) malloc(sizeof(smbus_ali7101_t));
|
||||
memset(dev, 0, sizeof(smbus_ali7101_t));
|
||||
|
||||
dev->local = info->local;
|
||||
dev->stat = 0x04;
|
||||
/* We save the I2C bus handle on dev but use i2c_smbus for all operations because
|
||||
dev and therefore dev->i2c will be invalidated if a device triggers a hard reset. */
|
||||
i2c_smbus = dev->i2c = i2c_addbus("smbus_ali7101");
|
||||
|
||||
timer_add(&dev->response_timer, smbus_ali7101_response, dev, 0);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
smbus_ali7101_close(void *priv)
|
||||
{
|
||||
smbus_ali7101_t *dev = (smbus_ali7101_t *) priv;
|
||||
|
||||
if (i2c_smbus == dev->i2c)
|
||||
i2c_smbus = NULL;
|
||||
i2c_removebus(dev->i2c);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
const device_t ali7101_smbus_device = {
|
||||
"ALi M7101-compatible SMBus Host Controller",
|
||||
DEVICE_AT,
|
||||
0,
|
||||
smbus_ali7101_init, smbus_ali7101_close, smbus_ali7101_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <86box/device.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/i2c.h>
|
||||
#include <86box/smbus_piix4.h>
|
||||
#include <86box/smbus.h>
|
||||
|
||||
|
||||
#ifdef ENABLE_SMBUS_PIIX4_LOG
|
||||
|
||||
@@ -1,186 +0,0 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the port 440h device from Virtual PC 2007.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Author: RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2020 RichardG.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/ui.h>
|
||||
#include <86box/mem.h>
|
||||
#include "cpu.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t port440, port440read, port442, port443, port444;
|
||||
} vpc2007_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_VPC2007_LOG
|
||||
int vpc2007_do_log = ENABLE_VPC2007_LOG;
|
||||
|
||||
|
||||
static void
|
||||
vpc2007_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (vpc2007_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
int vpc2007_do_log = 0;
|
||||
|
||||
#define vpc2007_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static uint8_t
|
||||
vpc2007_read(uint16_t port, void *priv)
|
||||
{
|
||||
vpc2007_t *dev = (vpc2007_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (port) {
|
||||
case 0x440:
|
||||
ret = dev->port440read;
|
||||
dev->port440read = 0x02;
|
||||
break;
|
||||
|
||||
case 0x445:
|
||||
if ((dev->port440 == 0x1e) && (dev->port442 == 0x48) && (dev->port444 == 0xa7)) {
|
||||
switch (dev->port443) {
|
||||
case 0x0b:
|
||||
ret = 0x00;
|
||||
break;
|
||||
|
||||
case 0x1b: case 0x05:
|
||||
ret = 0x01;
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
ret = 0x02;
|
||||
break;
|
||||
|
||||
case 0x11:
|
||||
ret = 0x04;
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
ret = 0x06;
|
||||
break;
|
||||
|
||||
case 0x04: case 0x0d:
|
||||
ret = 0x08;
|
||||
break;
|
||||
|
||||
case 0x03: case 0x09:
|
||||
ret = 0x0b;
|
||||
break;
|
||||
|
||||
case 0x15:
|
||||
ret = 0x12;
|
||||
break;
|
||||
|
||||
case 0x17:
|
||||
ret = 0x40;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0xff)
|
||||
vpc2007_log("VPC2007: unknown combination %02X %02X %02X %02X\n", dev->port440, dev->port442, dev->port443, dev->port444);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
vpc2007_log("VPC2007: read from unknown port %02X\n", port);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vpc2007_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
vpc2007_t *dev = (vpc2007_t *) priv;
|
||||
|
||||
switch (port) {
|
||||
case 0x440:
|
||||
dev->port440 = val;
|
||||
dev->port440read = 0x03;
|
||||
break;
|
||||
|
||||
case 0x442:
|
||||
dev->port442 = val;
|
||||
break;
|
||||
|
||||
case 0x443:
|
||||
dev->port443 = val;
|
||||
break;
|
||||
|
||||
case 0x444:
|
||||
dev->port444 = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
vpc2007_init(const device_t *info)
|
||||
{
|
||||
vpc2007_t *dev = (vpc2007_t *) malloc(sizeof(vpc2007_t));
|
||||
memset(dev, 0, sizeof(vpc2007_t));
|
||||
|
||||
io_sethandler(0x440, 6,
|
||||
vpc2007_read, NULL, NULL, vpc2007_write, NULL, NULL, dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vpc2007_close(void *priv)
|
||||
{
|
||||
vpc2007_t *dev = (vpc2007_t *) priv;
|
||||
|
||||
io_removehandler(0x440, 6,
|
||||
vpc2007_read, NULL, NULL, vpc2007_write, NULL, NULL, dev);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
const device_t vpc2007_device = {
|
||||
"Virtual PC 2007 Port 440h Device",
|
||||
DEVICE_ISA,
|
||||
0,
|
||||
vpc2007_init, vpc2007_close, NULL,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
add_library(hdd OBJECT hdd.c hdd_image.c hdd_table.c hdc.c hdc_st506_xt.c
|
||||
hdc_st506_at.c hdc_xta.c hdc_esdi_at.c hdc_esdi_mca.c hdc_xtide.c
|
||||
hdc_ide.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_sff8038i.c)
|
||||
hdc_ide.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_cmd646.c hdc_ide_sff8038i.c)
|
||||
|
||||
add_library(zip OBJECT zip.c)
|
||||
|
||||
|
||||
@@ -916,13 +916,14 @@ ide_atapi_attach(ide_t *ide)
|
||||
void
|
||||
ide_set_callback(ide_t *ide, double callback)
|
||||
{
|
||||
ide_log("ide_set_callback(%i)\n", ide->channel);
|
||||
|
||||
if (!ide) {
|
||||
ide_log("Set callback failed\n");
|
||||
ide_log("ide_set_callback(NULL): Set callback failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ide_log("ide_set_callback(%i)\n", ide->channel);
|
||||
|
||||
if (callback == 0.0)
|
||||
timer_stop(&ide->timer);
|
||||
else
|
||||
@@ -2504,6 +2505,60 @@ id_not_found:
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
ide_read_ali_75(void)
|
||||
{
|
||||
ide_t *ide0, *ide1;
|
||||
int ch0, ch1;
|
||||
uint8_t ret = 0x00;
|
||||
|
||||
ch0 = ide_boards[0]->cur_dev;
|
||||
ch1 = ide_boards[1]->cur_dev;
|
||||
ide0 = ide_drives[ch0];
|
||||
ide1 = ide_drives[ch1];
|
||||
|
||||
if (ch1)
|
||||
ret |= 0x08;
|
||||
if (ch0)
|
||||
ret |= 0x04;
|
||||
if (ide1->irqstat)
|
||||
ret |= 0x02;
|
||||
if (ide0->irqstat)
|
||||
ret |= 0x01;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
ide_read_ali_76(void)
|
||||
{
|
||||
ide_t *ide0, *ide1;
|
||||
int ch0, ch1;
|
||||
uint8_t ret = 0x00;
|
||||
|
||||
ch0 = ide_boards[0]->cur_dev;
|
||||
ch1 = ide_boards[1]->cur_dev;
|
||||
ide0 = ide_drives[ch0];
|
||||
ide1 = ide_drives[ch1];
|
||||
|
||||
if (ide1->atastat & BSY_STAT)
|
||||
ret |= 0x40;
|
||||
if (ide1->atastat & DRQ_STAT)
|
||||
ret |= 0x20;
|
||||
if (ide1->atastat & ERR_STAT)
|
||||
ret |= 0x10;
|
||||
if (ide0->atastat & BSY_STAT)
|
||||
ret |= 0x04;
|
||||
if (ide0->atastat & DRQ_STAT)
|
||||
ret |= 0x02;
|
||||
if (ide0->atastat & ERR_STAT)
|
||||
ret |= 0x01;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ide_set_handlers(uint8_t board)
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the CMD PCI-0640B controller.
|
||||
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2020 Miran Grca.
|
||||
@@ -42,7 +42,8 @@ typedef struct
|
||||
{
|
||||
uint8_t vlb_idx, id,
|
||||
in_cfg, single_channel,
|
||||
regs[256];
|
||||
pci, regs[256];
|
||||
uint32_t local;
|
||||
int slot, irq_mode[2],
|
||||
irq_pin, irq_line;
|
||||
} cmd640_t;
|
||||
@@ -51,15 +52,45 @@ typedef struct
|
||||
static int next_id = 0;
|
||||
|
||||
|
||||
#ifdef ENABLE_CMD640_LOG
|
||||
int cmd640_do_log = ENABLE_CMD640_LOG;
|
||||
static void
|
||||
cmd640_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (cmd640_do_log)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define cmd640_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
cmd640_set_irq(int channel, void *priv)
|
||||
{
|
||||
cmd640_t *dev = (cmd640_t *) priv;
|
||||
dev->regs[0x50] &= ~0x04;
|
||||
dev->regs[0x50] |= (channel >> 4);
|
||||
int irq = !!(channel & 0x40);
|
||||
|
||||
if (channel & 0x01) {
|
||||
if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) {
|
||||
dev->regs[0x57] &= ~0x10;
|
||||
dev->regs[0x57] |= (channel >> 2);
|
||||
}
|
||||
} else {
|
||||
if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) {
|
||||
dev->regs[0x50] &= ~0x04;
|
||||
dev->regs[0x50] |= (channel >> 4);
|
||||
}
|
||||
}
|
||||
|
||||
channel &= 0x01;
|
||||
if (dev->regs[0x50] & 0x04) {
|
||||
if (irq) {
|
||||
if (dev->irq_mode[channel] == 1)
|
||||
pci_set_irq(dev->slot, dev->irq_pin);
|
||||
else
|
||||
@@ -196,6 +227,8 @@ cmd640_vlb_read(uint16_t addr, void *priv)
|
||||
ret = dev->regs[dev->vlb_idx];
|
||||
if (dev->vlb_idx == 0x50)
|
||||
dev->regs[0x50] &= ~0x04;
|
||||
else if (dev->vlb_idx == 0x57)
|
||||
dev->regs[0x57] &= ~0x10;
|
||||
if (dev->regs[0x50] & 0x80)
|
||||
dev->in_cfg = 0;
|
||||
break;
|
||||
@@ -234,6 +267,8 @@ cmd640_pci_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
cmd640_t *dev = (cmd640_t *) priv;
|
||||
|
||||
cmd640_log("cmd640_pci_write(%i, %02X, %02X)\n", func, addr, val);
|
||||
|
||||
if (func == 0x00) switch (addr) {
|
||||
case 0x04:
|
||||
dev->regs[addr] = (val & 0x41);
|
||||
@@ -315,15 +350,20 @@ cmd640_pci_read(int func, int addr, void *priv)
|
||||
ret = dev->regs[addr];
|
||||
if (addr == 0x50)
|
||||
dev->regs[0x50] &= ~0x04;
|
||||
else if (addr == 0x57)
|
||||
dev->regs[0x57] &= ~0x10;
|
||||
}
|
||||
|
||||
cmd640_log("cmd640_pci_read(%i, %02X, %02X)\n", func, addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cmd640_reset(void *p)
|
||||
cmd640_reset(void *priv)
|
||||
{
|
||||
cmd640_t *dev = (cmd640_t *) priv;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < CDROM_NUM; i++) {
|
||||
@@ -342,8 +382,58 @@ cmd640_reset(void *p)
|
||||
mo_reset((scsi_common_t *) mo_drives[i].priv);
|
||||
}
|
||||
|
||||
cmd640_set_irq(0x00, p);
|
||||
cmd640_set_irq(0x01, p);
|
||||
cmd640_set_irq(0x00, priv);
|
||||
cmd640_set_irq(0x01, priv);
|
||||
|
||||
memset(dev->regs, 0x00, sizeof(dev->regs));
|
||||
|
||||
dev->regs[0x50] = 0x02; /* Revision 02 */
|
||||
dev->regs[0x50] |= (dev->id << 3); /* Device ID: 00 = 60h, 01 = 61h, 10 = 62h, 11 = 63h */
|
||||
|
||||
dev->regs[0x59] = 0x40;
|
||||
|
||||
if (dev->pci) {
|
||||
cmd640_log("dev->local = %08X\n", dev->local);
|
||||
if ((dev->local & 0xffff) == 0x0a) {
|
||||
dev->regs[0x50] |= 0x40; /* Enable Base address register R/W;
|
||||
If 0, they return 0 and are read-only 8 */
|
||||
}
|
||||
|
||||
dev->regs[0x00] = 0x95; /* CMD */
|
||||
dev->regs[0x01] = 0x10;
|
||||
dev->regs[0x02] = 0x40; /* PCI-0640B */
|
||||
dev->regs[0x03] = 0x06;
|
||||
dev->regs[0x04] = 0x01; /* Apparently required by the ASUS PCI/I-P5SP4 AND PCI/I-P54SP4 */
|
||||
dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */
|
||||
dev->regs[0x08] = 0x02; /* Revision 02 */
|
||||
dev->regs[0x09] = dev->local; /* Programming interface */
|
||||
dev->regs[0x0a] = 0x01; /* IDE controller */
|
||||
dev->regs[0x0b] = 0x01; /* Mass storage controller */
|
||||
|
||||
/* Base addresses (1F0, 3F4, 170, 374) */
|
||||
if (dev->regs[0x50] & 0x40) {
|
||||
dev->regs[0x10] = 0xf1; dev->regs[0x11] = 0x01;
|
||||
dev->regs[0x14] = 0xf5; dev->regs[0x15] = 0x03;
|
||||
dev->regs[0x18] = 0x71; dev->regs[0x19] = 0x01;
|
||||
dev->regs[0x1c] = 0x75; dev->regs[0x1d] = 0x03;
|
||||
}
|
||||
|
||||
dev->regs[0x3c] = 0x14; /* IRQ 14 */
|
||||
dev->regs[0x3d] = 0x01; /* INTA */
|
||||
|
||||
dev->irq_mode[0] = dev->irq_mode[1] = 0;
|
||||
dev->irq_pin = PCI_INTA;
|
||||
dev->irq_line = 14;
|
||||
} else {
|
||||
if ((dev->local & 0xffff) == 0x0078)
|
||||
dev->regs[0x50] |= 0x20; /* 0 = 178h, 17Ch; 1 = 078h, 07Ch */
|
||||
|
||||
/* If bit 7 is 1, then device ID has to be written on port x78h before
|
||||
accessing the configuration registers */
|
||||
dev->in_cfg = 1; /* Configuration registers are accessible */
|
||||
}
|
||||
|
||||
cmd640_ide_handlers(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -366,45 +456,13 @@ cmd640_init(const device_t *info)
|
||||
|
||||
dev->id = next_id | 0x60;
|
||||
|
||||
dev->regs[0x50] = 0x02; /* Revision 02 */
|
||||
dev->regs[0x50] |= (next_id << 3); /* Device ID: 00 = 60h, 01 = 61h, 10 = 62h, 11 = 63h */
|
||||
|
||||
dev->regs[0x59] = 0x40;
|
||||
dev->pci = !!(info->flags & DEVICE_PCI);
|
||||
dev->local = info->local;
|
||||
|
||||
if (info->flags & DEVICE_PCI) {
|
||||
if ((info->local & 0xffff) == 0x0a) {
|
||||
dev->regs[0x50] |= 0x40; /* Enable Base address register R/W;
|
||||
If 0, they return 0 and are read-only 8 */
|
||||
}
|
||||
|
||||
dev->regs[0x00] = 0x95; /* CMD */
|
||||
dev->regs[0x01] = 0x10;
|
||||
dev->regs[0x02] = 0x40; /* PCI-0640B */
|
||||
dev->regs[0x03] = 0x06;
|
||||
dev->regs[0x04] = 0x01; /* Apparently required by the ASUS PCI/I-P5SP4 AND PCI/I-P54SP4 */
|
||||
dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */
|
||||
dev->regs[0x08] = 0x02; /* Revision 02 */
|
||||
dev->regs[0x09] = info->local; /* Programming interface */
|
||||
dev->regs[0x0a] = 0x01; /* IDE controller */
|
||||
dev->regs[0x0b] = 0x01; /* Mass storage controller */
|
||||
|
||||
/* Base addresses (1F0, 3F4, 170, 374) */
|
||||
if (dev->regs[0x50] & 0x40) {
|
||||
dev->regs[0x10] = 0xf1; dev->regs[0x11] = 0x01;
|
||||
dev->regs[0x14] = 0xf5; dev->regs[0x15] = 0x03;
|
||||
dev->regs[0x18] = 0x71; dev->regs[0x19] = 0x01;
|
||||
dev->regs[0x1c] = 0x75; dev->regs[0x1d] = 0x03;
|
||||
}
|
||||
|
||||
dev->regs[0x3c] = 0x14; /* IRQ 14 */
|
||||
dev->regs[0x3d] = 0x01; /* INTA */
|
||||
|
||||
device_add(&ide_pci_2ch_device);
|
||||
|
||||
dev->slot = pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev);
|
||||
dev->irq_mode[0] = dev->irq_mode[1] = 0;
|
||||
dev->irq_pin = PCI_INTA;
|
||||
dev->irq_line = 14;
|
||||
|
||||
ide_set_bus_master(0, NULL, cmd640_set_irq, dev);
|
||||
ide_set_bus_master(1, NULL, cmd640_set_irq, dev);
|
||||
@@ -416,12 +474,6 @@ cmd640_init(const device_t *info)
|
||||
|
||||
// ide_pri_disable();
|
||||
} else if (info->flags & DEVICE_VLB) {
|
||||
if ((info->local & 0xffff) == 0x0078)
|
||||
dev->regs[0x50] |= 0x20; /* 0 = 178h, 17Ch; 1 = 078h, 07Ch */
|
||||
/* If bit 7 is 1, then device ID has to be written on port x78h before
|
||||
accessing the configuration registers */
|
||||
dev->in_cfg = 1; /* Configuration register are accessible */
|
||||
|
||||
device_add(&ide_vlb_2ch_device);
|
||||
|
||||
io_sethandler(info->local & 0xffff, 0x0008,
|
||||
@@ -432,11 +484,10 @@ cmd640_init(const device_t *info)
|
||||
|
||||
dev->single_channel = !!(info->local & 0x20000);
|
||||
|
||||
if (!dev->single_channel)
|
||||
ide_sec_disable();
|
||||
|
||||
next_id++;
|
||||
|
||||
cmd640_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
@@ -445,7 +496,7 @@ const device_t ide_cmd640_vlb_device = {
|
||||
"CMD PCI-0640B VLB",
|
||||
DEVICE_VLB,
|
||||
0x0078,
|
||||
cmd640_init, cmd640_close, NULL,
|
||||
cmd640_init, cmd640_close, cmd640_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -454,7 +505,7 @@ const device_t ide_cmd640_vlb_178_device = {
|
||||
"CMD PCI-0640B VLB (Port 178h)",
|
||||
DEVICE_VLB,
|
||||
0x0178,
|
||||
cmd640_init, cmd640_close, NULL,
|
||||
cmd640_init, cmd640_close, cmd640_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
435
src/disk/hdc_ide_cmd646.c
Normal file
435
src/disk/hdc_ide_cmd646.c
Normal file
@@ -0,0 +1,435 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the CMD PCI-0646 controller.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 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 <86box/cdrom.h>
|
||||
#include <86box/scsi_device.h>
|
||||
#include <86box/scsi_cdrom.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/zip.h>
|
||||
#include <86box/mo.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t vlb_idx, single_channel,
|
||||
in_cfg, regs[256];
|
||||
uint32_t local;
|
||||
int slot, irq_mode[2],
|
||||
irq_pin;
|
||||
sff8038i_t *bm[2];
|
||||
} cmd646_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_CMD646_LOG
|
||||
int cmd646_do_log = ENABLE_CMD646_LOG;
|
||||
static void
|
||||
cmd646_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (cmd646_do_log)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define cmd646_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
cmd646_set_irq(int channel, void *priv)
|
||||
{
|
||||
cmd646_t *dev = (cmd646_t *) priv;
|
||||
|
||||
if (channel & 0x01) {
|
||||
if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) {
|
||||
dev->regs[0x57] &= ~0x10;
|
||||
dev->regs[0x57] |= (channel >> 2);
|
||||
}
|
||||
} else {
|
||||
if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) {
|
||||
dev->regs[0x50] &= ~0x04;
|
||||
dev->regs[0x50] |= (channel >> 4);
|
||||
}
|
||||
}
|
||||
|
||||
sff_bus_master_set_irq(channel, dev->bm[channel & 0x01]);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cmd646_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv)
|
||||
{
|
||||
cmd646_t *dev = (cmd646_t *) priv;
|
||||
|
||||
return sff_bus_master_dma(channel, data, transfer_length, out, dev->bm[channel & 0x01]);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cmd646_ide_handlers(cmd646_t *dev)
|
||||
{
|
||||
uint16_t main, side;
|
||||
int irq_mode[2] = { 0, 0 };
|
||||
|
||||
ide_pri_disable();
|
||||
|
||||
if ((dev->regs[0x09] & 0x01) && (dev->regs[0x50] & 0x40)) {
|
||||
main = (dev->regs[0x11] << 8) | (dev->regs[0x10] & 0xf8);
|
||||
side = ((dev->regs[0x15] << 8) | (dev->regs[0x14] & 0xfc)) + 2;
|
||||
} else {
|
||||
main = 0x1f0;
|
||||
side = 0x3f6;
|
||||
}
|
||||
|
||||
ide_set_base(0, main);
|
||||
ide_set_side(0, side);
|
||||
|
||||
if (dev->regs[0x09] & 0x01)
|
||||
irq_mode[0] = 1;
|
||||
|
||||
sff_set_irq_mode(dev->bm[0], 0, irq_mode[0]);
|
||||
sff_set_irq_mode(dev->bm[0], 1, irq_mode[1]);
|
||||
|
||||
if (dev->regs[0x04] & 0x01)
|
||||
ide_pri_enable();
|
||||
|
||||
if (dev->single_channel)
|
||||
return;
|
||||
|
||||
ide_sec_disable();
|
||||
|
||||
if ((dev->regs[0x09] & 0x04) && (dev->regs[0x50] & 0x40)) {
|
||||
main = (dev->regs[0x19] << 8) | (dev->regs[0x18] & 0xf8);
|
||||
side = ((dev->regs[0x1d] << 8) | (dev->regs[0x1c] & 0xfc)) + 2;
|
||||
} else {
|
||||
main = 0x170;
|
||||
side = 0x376;
|
||||
}
|
||||
|
||||
ide_set_base(1, main);
|
||||
ide_set_side(1, side);
|
||||
|
||||
if (dev->regs[0x09] & 0x04)
|
||||
irq_mode[1] = 1;
|
||||
|
||||
sff_set_irq_mode(dev->bm[1], 0, irq_mode[0]);
|
||||
sff_set_irq_mode(dev->bm[1], 1, irq_mode[1]);
|
||||
|
||||
if ((dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08))
|
||||
ide_sec_enable();
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cmd646_ide_bm_handlers(cmd646_t *dev)
|
||||
{
|
||||
uint16_t base = (dev->regs[0x20] & 0xf0) | (dev->regs[0x21] << 8);
|
||||
|
||||
sff_bus_master_handler(dev->bm[0], (dev->regs[0x04] & 1), base);
|
||||
sff_bus_master_handler(dev->bm[1], (dev->regs[0x04] & 1), base + 8);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cmd646_pci_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
cmd646_t *dev = (cmd646_t *) priv;
|
||||
|
||||
cmd646_log("[%04X:%08X] (%08X) cmd646_pci_write(%i, %02X, %02X)\n", CS, cpu_state.pc, ESI, func, addr, val);
|
||||
|
||||
if (func == 0x00) switch (addr) {
|
||||
case 0x04:
|
||||
dev->regs[addr] = (val & 0x45);
|
||||
cmd646_ide_handlers(dev);
|
||||
break;
|
||||
case 0x07:
|
||||
dev->regs[addr] &= ~(val & 0xb1);
|
||||
break;
|
||||
case 0x09:
|
||||
if ((dev->regs[addr] & 0x0a) == 0x0a) {
|
||||
dev->regs[addr] = (dev->regs[addr] & 0x0a) | (val & 0x05);
|
||||
dev->irq_mode[0] = !!(val & 0x01);
|
||||
dev->irq_mode[1] = !!(val & 0x04);
|
||||
cmd646_ide_handlers(dev);
|
||||
}
|
||||
break;
|
||||
case 0x10:
|
||||
if (dev->regs[0x50] & 0x40) {
|
||||
dev->regs[0x10] = (val & 0xf8) | 1;
|
||||
cmd646_ide_handlers(dev);
|
||||
}
|
||||
break;
|
||||
case 0x11:
|
||||
if (dev->regs[0x50] & 0x40) {
|
||||
dev->regs[0x11] = val;
|
||||
cmd646_ide_handlers(dev);
|
||||
}
|
||||
break;
|
||||
case 0x14:
|
||||
if (dev->regs[0x50] & 0x40) {
|
||||
dev->regs[0x14] = (val & 0xfc) | 1;
|
||||
cmd646_ide_handlers(dev);
|
||||
}
|
||||
break;
|
||||
case 0x15:
|
||||
if (dev->regs[0x50] & 0x40) {
|
||||
dev->regs[0x15] = val;
|
||||
cmd646_ide_handlers(dev);
|
||||
}
|
||||
break;
|
||||
case 0x18:
|
||||
if (dev->regs[0x50] & 0x40) {
|
||||
dev->regs[0x18] = (val & 0xf8) | 1;
|
||||
cmd646_ide_handlers(dev);
|
||||
}
|
||||
break;
|
||||
case 0x19:
|
||||
if (dev->regs[0x50] & 0x40) {
|
||||
dev->regs[0x19] = val;
|
||||
cmd646_ide_handlers(dev);
|
||||
}
|
||||
break;
|
||||
case 0x1c:
|
||||
if (dev->regs[0x50] & 0x40) {
|
||||
dev->regs[0x1c] = (val & 0xfc) | 1;
|
||||
cmd646_ide_handlers(dev);
|
||||
}
|
||||
break;
|
||||
case 0x1d:
|
||||
if (dev->regs[0x50] & 0x40) {
|
||||
dev->regs[0x1d] = val;
|
||||
cmd646_ide_handlers(dev);
|
||||
}
|
||||
break;
|
||||
case 0x20:
|
||||
dev->regs[0x20] = (val & 0xf0) | 1;
|
||||
cmd646_ide_bm_handlers(dev);
|
||||
break;
|
||||
case 0x21:
|
||||
dev->regs[0x21] = val;
|
||||
cmd646_ide_bm_handlers(dev);
|
||||
break;
|
||||
case 0x51:
|
||||
dev->regs[addr] = val & 0xc8;
|
||||
cmd646_ide_handlers(dev);
|
||||
break;
|
||||
case 0x52: case 0x54: case 0x56: case 0x58:
|
||||
case 0x59: case 0x5b:
|
||||
dev->regs[addr] = val;
|
||||
break;
|
||||
case 0x53: case 0x55:
|
||||
dev->regs[addr] = val & 0xc0;
|
||||
break;
|
||||
case 0x57:
|
||||
dev->regs[addr] = (dev->regs[addr] & 0x10) | (val & 0xcc);
|
||||
break;
|
||||
case 0x70 ... 0x77:
|
||||
sff_bus_master_write(addr & 0x0f, val, dev->bm[0]);
|
||||
break;
|
||||
case 0x78 ... 0x7f:
|
||||
sff_bus_master_write(addr & 0x0f, val, dev->bm[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
cmd646_pci_read(int func, int addr, void *priv)
|
||||
{
|
||||
cmd646_t *dev = (cmd646_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0x00) {
|
||||
ret = dev->regs[addr];
|
||||
|
||||
if (addr == 0x50)
|
||||
dev->regs[0x50] &= ~0x04;
|
||||
else if (addr == 0x57)
|
||||
dev->regs[0x57] &= ~0x10;
|
||||
else if ((addr >= 0x70) && (addr <= 0x77))
|
||||
ret = sff_bus_master_read(addr & 0x0f, dev->bm[0]);
|
||||
else if ((addr >= 0x78) && (addr <= 0x7f))
|
||||
ret = sff_bus_master_read(addr & 0x0f, dev->bm[0]);
|
||||
}
|
||||
|
||||
cmd646_log("[%04X:%08X] (%08X) cmd646_pci_read(%i, %02X, %02X)\n", CS, cpu_state.pc, ESI, func, addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cmd646_reset(void *priv)
|
||||
{
|
||||
cmd646_t *dev = (cmd646_t *) priv;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < CDROM_NUM; i++) {
|
||||
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) &&
|
||||
(cdrom[i].ide_channel < 4) && cdrom[i].priv)
|
||||
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
|
||||
}
|
||||
for (i = 0; i < ZIP_NUM; i++) {
|
||||
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) &&
|
||||
(zip_drives[i].ide_channel < 4) && zip_drives[i].priv)
|
||||
zip_reset((scsi_common_t *) zip_drives[i].priv);
|
||||
}
|
||||
for (i = 0; i < MO_NUM; i++) {
|
||||
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) &&
|
||||
(mo_drives[i].ide_channel < 4) && mo_drives[i].priv)
|
||||
mo_reset((scsi_common_t *) mo_drives[i].priv);
|
||||
}
|
||||
|
||||
cmd646_set_irq(0x00, priv);
|
||||
cmd646_set_irq(0x01, priv);
|
||||
|
||||
memset(dev->regs, 0x00, sizeof(dev->regs));
|
||||
|
||||
dev->regs[0x00] = 0x95; /* CMD */
|
||||
dev->regs[0x01] = 0x10;
|
||||
dev->regs[0x02] = 0x46; /* PCI-0646 */
|
||||
dev->regs[0x03] = 0x06;
|
||||
dev->regs[0x04] = 0x00;
|
||||
dev->regs[0x06] = 0x80;
|
||||
dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */
|
||||
dev->regs[0x09] = dev->local; /* Programming interface */
|
||||
dev->regs[0x0a] = 0x01; /* IDE controller */
|
||||
dev->regs[0x0b] = 0x01; /* Mass storage controller */
|
||||
|
||||
if ((dev->local & 0xffff) == 0x8a) {
|
||||
dev->regs[0x50] = 0x40; /* Enable Base address register R/W;
|
||||
If 0, they return 0 and are read-only 8 */
|
||||
|
||||
/* Base addresses (1F0, 3F4, 170, 374) */
|
||||
dev->regs[0x10] = 0xf1; dev->regs[0x11] = 0x01;
|
||||
dev->regs[0x14] = 0xf5; dev->regs[0x15] = 0x03;
|
||||
dev->regs[0x18] = 0x71; dev->regs[0x19] = 0x01;
|
||||
dev->regs[0x1c] = 0x75; dev->regs[0x1d] = 0x03;
|
||||
}
|
||||
|
||||
dev->regs[0x20] = 0x01;
|
||||
|
||||
dev->regs[0x3c] = 0x0e; /* IRQ 14 */
|
||||
dev->regs[0x3d] = 0x01; /* INTA */
|
||||
dev->regs[0x3e] = 0x02; /* Min_Gnt */
|
||||
dev->regs[0x3f] = 0x04; /* Max_Iat */
|
||||
|
||||
if (!dev->single_channel)
|
||||
dev->regs[0x51] = 0x08;
|
||||
|
||||
dev->regs[0x57] = 0x0c;
|
||||
dev->regs[0x59] = 0x40;
|
||||
|
||||
dev->irq_mode[0] = dev->irq_mode[1] = 0;
|
||||
dev->irq_pin = PCI_INTA;
|
||||
|
||||
cmd646_ide_handlers(dev);
|
||||
cmd646_ide_bm_handlers(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cmd646_close(void *priv)
|
||||
{
|
||||
cmd646_t *dev = (cmd646_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
cmd646_init(const device_t *info)
|
||||
{
|
||||
cmd646_t *dev = (cmd646_t *) malloc(sizeof(cmd646_t));
|
||||
memset(dev, 0x00, sizeof(cmd646_t));
|
||||
|
||||
dev->local = info->local;
|
||||
|
||||
device_add(&ide_pci_2ch_device);
|
||||
|
||||
dev->slot = pci_add_card(PCI_ADD_IDE, cmd646_pci_read, cmd646_pci_write, dev);
|
||||
|
||||
dev->single_channel = !!(info->local & 0x20000);
|
||||
|
||||
dev->bm[0] = device_add_inst(&sff8038i_device, 1);
|
||||
if (!dev->single_channel)
|
||||
dev->bm[1] = device_add_inst(&sff8038i_device, 2);
|
||||
|
||||
ide_set_bus_master(0, cmd646_bus_master_dma, cmd646_set_irq, dev);
|
||||
if (!dev->single_channel)
|
||||
ide_set_bus_master(1, cmd646_bus_master_dma, cmd646_set_irq, dev);
|
||||
|
||||
sff_set_irq_mode(dev->bm[0], 0, 0);
|
||||
sff_set_irq_mode(dev->bm[0], 1, 0);
|
||||
|
||||
if (!dev->single_channel) {
|
||||
sff_set_irq_mode(dev->bm[1], 0, 0);
|
||||
sff_set_irq_mode(dev->bm[1], 1, 0);
|
||||
}
|
||||
|
||||
cmd646_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
const device_t ide_cmd646_device = {
|
||||
"CMD PCI-0646",
|
||||
DEVICE_PCI,
|
||||
0x8a,
|
||||
cmd646_init, cmd646_close, cmd646_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
const device_t ide_cmd646_legacy_only_device = {
|
||||
"CMD PCI-0646 (Legacy Mode Only)",
|
||||
DEVICE_PCI,
|
||||
0x80,
|
||||
cmd646_init, cmd646_close, cmd646_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
const device_t ide_cmd646_single_channel_device = {
|
||||
"CMD PCI-0646",
|
||||
DEVICE_PCI,
|
||||
0x2008a,
|
||||
cmd646_init, cmd646_close, cmd646_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -56,11 +56,11 @@ opti611_cfg_write(uint16_t addr, uint8_t val, void *priv)
|
||||
case 0x0002:
|
||||
dev->regs[0x12] = (val & 0xc1) | 0x02;
|
||||
if (val & 0xc0) {
|
||||
if (val & 0x40)
|
||||
dev->cfg_locked = 1;
|
||||
dev->in_cfg = 0;
|
||||
opti611_ide_handler(dev);
|
||||
}
|
||||
if (val & 0x40)
|
||||
dev->cfg_locked = 1;
|
||||
break;
|
||||
case 0x0003:
|
||||
dev->regs[0x03] = (val & 0xdf);
|
||||
|
||||
@@ -47,10 +47,10 @@
|
||||
static int next_id = 0;
|
||||
|
||||
|
||||
static uint8_t sff_bus_master_read(uint16_t port, void *priv);
|
||||
uint8_t sff_bus_master_read(uint16_t port, void *priv);
|
||||
static uint16_t sff_bus_master_readw(uint16_t port, void *priv);
|
||||
static uint32_t sff_bus_master_readl(uint16_t port, void *priv);
|
||||
static void sff_bus_master_write(uint16_t port, uint8_t val, void *priv);
|
||||
void sff_bus_master_write(uint16_t port, uint8_t val, void *priv);
|
||||
static void sff_bus_master_writew(uint16_t port, uint16_t val, void *priv);
|
||||
static void sff_bus_master_writel(uint16_t port, uint32_t val, void *priv);
|
||||
|
||||
@@ -112,7 +112,7 @@ sff_bus_master_next_addr(sff8038i_t *dev)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
void
|
||||
sff_bus_master_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
sff8038i_t *dev = (sff8038i_t *) priv;
|
||||
@@ -138,6 +138,9 @@ sff_bus_master_write(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
dev->command = val;
|
||||
break;
|
||||
case 1:
|
||||
dev->dma_mode = val & 0x03;
|
||||
break;
|
||||
case 2:
|
||||
sff_log("sff Status: val = %02X, old = %02X\n", val, dev->status);
|
||||
dev->status &= 0x07;
|
||||
@@ -177,6 +180,7 @@ sff_bus_master_writew(uint16_t port, uint16_t val, void *priv)
|
||||
|
||||
switch (port & 7) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
sff_bus_master_write(port, val & 0xff, priv);
|
||||
break;
|
||||
@@ -202,6 +206,7 @@ sff_bus_master_writel(uint16_t port, uint32_t val, void *priv)
|
||||
|
||||
switch (port & 7) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
sff_bus_master_write(port, val & 0xff, priv);
|
||||
break;
|
||||
@@ -214,7 +219,7 @@ sff_bus_master_writel(uint16_t port, uint32_t val, void *priv)
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
uint8_t
|
||||
sff_bus_master_read(uint16_t port, void *priv)
|
||||
{
|
||||
sff8038i_t *dev = (sff8038i_t *) priv;
|
||||
@@ -225,6 +230,9 @@ sff_bus_master_read(uint16_t port, void *priv)
|
||||
case 0:
|
||||
ret = dev->command;
|
||||
break;
|
||||
case 1:
|
||||
ret = dev->dma_mode & 0x03;
|
||||
break;
|
||||
case 2:
|
||||
ret = dev->status & 0x67;
|
||||
break;
|
||||
@@ -257,6 +265,7 @@ sff_bus_master_readw(uint16_t port, void *priv)
|
||||
|
||||
switch (port & 7) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
ret = (uint16_t) sff_bus_master_read(port, priv);
|
||||
break;
|
||||
@@ -283,6 +292,7 @@ sff_bus_master_readl(uint16_t port, void *priv)
|
||||
|
||||
switch (port & 7) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
ret = (uint32_t) sff_bus_master_read(port, priv);
|
||||
break;
|
||||
@@ -297,7 +307,7 @@ sff_bus_master_readl(uint16_t port, void *priv)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
int
|
||||
sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv)
|
||||
{
|
||||
sff8038i_t *dev = (sff8038i_t *) priv;
|
||||
@@ -311,8 +321,10 @@ sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, voi
|
||||
sop = out ? "Read" : "Writ";
|
||||
#endif
|
||||
|
||||
if (!(dev->status & 1))
|
||||
if (!(dev->status & 1)) {
|
||||
sff_log("DMA disabled\n");
|
||||
return 2; /*DMA disabled*/
|
||||
}
|
||||
|
||||
sff_log("SFF-8038i Bus master %s: %i bytes\n", out ? "write" : "read", transfer_length);
|
||||
|
||||
@@ -373,31 +385,50 @@ sff_bus_master_set_irq(int channel, void *priv)
|
||||
uint8_t irq = !!(channel & 0x40);
|
||||
|
||||
if (!(dev->status & 0x04) || (channel & 0x40)) {
|
||||
dev->status &= ~4;
|
||||
dev->status &= ~0x04;
|
||||
dev->status |= (channel >> 4);
|
||||
}
|
||||
|
||||
channel &= 0x01;
|
||||
if (irq) {
|
||||
sff_log("SFF8038i: Channel %i IRQ raise\n", channel);
|
||||
if (dev->irq_mode[channel] == 3)
|
||||
picintlevel(1 << dev->irq_line);
|
||||
else if ((dev->irq_mode[channel] == 2) && channel && pci_use_mirq(0))
|
||||
pci_set_mirq(0, 0);
|
||||
else if (dev->irq_mode[channel] == 1)
|
||||
pci_set_irq(dev->slot, dev->irq_pin);
|
||||
else
|
||||
picint(1 << (14 + channel));
|
||||
} else {
|
||||
sff_log("SFF8038i: Channel %i IRQ lower\n", channel);
|
||||
if (dev->irq_mode[channel] == 3)
|
||||
picintc(1 << dev->irq_line);
|
||||
else if ((dev->irq_mode[channel] == 2) && channel && pci_use_mirq(0))
|
||||
pci_clear_mirq(0, 0);
|
||||
else if (dev->irq_mode[channel] == 1)
|
||||
pci_clear_irq(dev->slot, dev->irq_pin);
|
||||
else
|
||||
picintc(1 << (14 + channel));
|
||||
|
||||
switch (dev->irq_mode[channel]) {
|
||||
case 0:
|
||||
default:
|
||||
/* Legacy IRQ mode. */
|
||||
if (irq)
|
||||
picint(1 << (14 + channel));
|
||||
else
|
||||
picintc(1 << (14 + channel));
|
||||
break;
|
||||
case 1:
|
||||
/* Native PCI IRQ mode with interrupt pin. */
|
||||
if (irq)
|
||||
pci_set_irq(dev->slot, dev->irq_pin);
|
||||
else
|
||||
pci_clear_irq(dev->slot, dev->irq_pin);
|
||||
break;
|
||||
case 2:
|
||||
case 5:
|
||||
/* MIRQ 0 or 1. */
|
||||
if (irq)
|
||||
pci_set_mirq(dev->irq_mode[channel] & 1, 0);
|
||||
else
|
||||
pci_clear_mirq(dev->irq_mode[channel] & 1, 0);
|
||||
break;
|
||||
case 3:
|
||||
/* Native PCI IRQ mode with specified interrupt line. */
|
||||
if (irq)
|
||||
picintlevel(1 << dev->irq_line);
|
||||
else
|
||||
picintc(1 << dev->irq_line);
|
||||
break;
|
||||
case 4:
|
||||
/* ALi Aladdin Native PCI INTAJ mode. */
|
||||
if (irq)
|
||||
pci_set_mirq(channel + 2, dev->irq_level[channel]);
|
||||
else
|
||||
pci_clear_mirq(channel + 2, dev->irq_level[channel]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,10 +501,42 @@ sff_set_irq_line(sff8038i_t *dev, int irq_line)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sff_set_irq_level(sff8038i_t *dev, int channel, int irq_level)
|
||||
{
|
||||
dev->irq_level[channel] = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sff_set_irq_mode(sff8038i_t *dev, int channel, int irq_mode)
|
||||
{
|
||||
dev->irq_mode[channel] = irq_mode;
|
||||
|
||||
switch (dev->irq_mode[channel]) {
|
||||
case 0:
|
||||
default:
|
||||
/* Legacy IRQ mode. */
|
||||
sff_log("[%08X] Setting channel %i to legacy IRQ %i\n", dev, channel, 14 + channel);
|
||||
break;
|
||||
case 1:
|
||||
/* Native PCI IRQ mode with interrupt pin. */
|
||||
sff_log("[%08X] Setting channel %i to native PCI INT%c\n", dev, channel, '@' + dev->irq_pin);
|
||||
break;
|
||||
case 2:
|
||||
case 5:
|
||||
/* MIRQ 0 or 1. */
|
||||
sff_log("[%08X] Setting channel %i to PCI MIRQ%i\n", dev, channel, irq_mode & 1);
|
||||
break;
|
||||
case 3:
|
||||
/* Native PCI IRQ mode with specified interrupt line. */
|
||||
sff_log("[%08X] Setting channel %i to native PCI IRQ %i\n", dev, channel, dev->irq_line);
|
||||
break;
|
||||
case 4:
|
||||
/* ALi Aladdin Native PCI INTAJ mode. */
|
||||
sff_log("[%08X] Setting channel %i to INT%cJ\n", dev, channel, 'A' + channel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -510,9 +573,11 @@ static void
|
||||
ide_set_bus_master(next_id, sff_bus_master_dma, sff_bus_master_set_irq, dev);
|
||||
|
||||
dev->slot = 7;
|
||||
dev->irq_mode[0] = dev->irq_mode[1] = 2;
|
||||
dev->irq_mode[0] = 0; /* Channel 0 goes to IRQ 14. */
|
||||
dev->irq_mode[1] = 2; /* Channel 1 goes to MIRQ0. */
|
||||
dev->irq_pin = PCI_INTA;
|
||||
dev->irq_line = 14;
|
||||
dev->irq_level[0] = dev->irq_level[1] = 0;
|
||||
|
||||
next_id++;
|
||||
|
||||
|
||||
30
src/dma.c
30
src/dma.c
@@ -166,6 +166,28 @@ dma_block_transfer(int channel)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dma_mem_to_mem_transfer(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ((dma[0].mode & 0x0c) != 0x08)
|
||||
fatal("DMA memory to memory transfer: channel 0 mode not read\n");
|
||||
if ((dma[1].mode & 0x0c) != 0x04)
|
||||
fatal("DMA memory to memory transfer: channel 1 mode not write\n");
|
||||
|
||||
dma_req_is_soft = 1;
|
||||
|
||||
for (i = 0; i <= dma[0].cb; i++)
|
||||
dma_buffer[i] = dma_channel_read(0);
|
||||
|
||||
for (i = 0; i <= dma[1].cb; i++)
|
||||
dma_channel_write(1, dma_buffer[i]);
|
||||
|
||||
dma_req_is_soft = 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dma_sg_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
@@ -506,14 +528,18 @@ dma_write(uint16_t addr, uint8_t val, void *priv)
|
||||
case 8: /*Control register*/
|
||||
dma_command[0] = val;
|
||||
if (val & 0x01)
|
||||
fatal("Memory-to-memory enable\n");
|
||||
pclog("[%08X:%04X] Memory-to-memory enable\n", CS, cpu_state.pc);
|
||||
return;
|
||||
|
||||
case 9: /*Request register */
|
||||
channel = (val & 3);
|
||||
if (val & 4) {
|
||||
dma_stat_rq_pc |= (1 << channel);
|
||||
dma_block_transfer(channel);
|
||||
if ((channel == 0) && (dma_command[0] & 0x01)) {
|
||||
pclog("Memory to memory transfer start\n");
|
||||
dma_mem_to_mem_transfer();
|
||||
} else
|
||||
dma_block_transfer(channel);
|
||||
} else
|
||||
dma_stat_rq_pc &= ~(1 << channel);
|
||||
break;
|
||||
|
||||
@@ -61,7 +61,7 @@ typedef struct
|
||||
{
|
||||
uint8_t acpitst, auxen, auxsts, plvl2, plvl3,
|
||||
smicmd, gpio_dir,
|
||||
gpio_val, muxcntrl, pad,
|
||||
gpio_val, muxcntrl, ali_soft_smi,
|
||||
timer32, smireg,
|
||||
gpireg[3], gporeg[4],
|
||||
extiotrapsts, extiotrapen;
|
||||
@@ -92,7 +92,8 @@ typedef struct
|
||||
uint16_t io_base, aux_io_base;
|
||||
int vendor,
|
||||
slot, irq_mode,
|
||||
irq_pin, irq_line;
|
||||
irq_pin, irq_line,
|
||||
mirq_is_level;
|
||||
pc_timer_t timer, resume_timer;
|
||||
nvr_t *nvr;
|
||||
apm_t *apm;
|
||||
@@ -114,7 +115,7 @@ extern const device_t acpi_via_596b_device;
|
||||
|
||||
/* Functions */
|
||||
extern void acpi_update_irq(acpi_t *dev);
|
||||
extern void acpi_raise_smi(acpi_t *dev);
|
||||
extern void acpi_raise_smi(void *priv, int do_smi);
|
||||
extern void acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en);
|
||||
extern void acpi_update_aux_io_mapping(acpi_t *dev, uint32_t base, int chipset_en);
|
||||
extern void acpi_init_gporeg(acpi_t *dev, uint8_t val0, uint8_t val1, uint8_t val2, uint8_t val3);
|
||||
@@ -123,9 +124,12 @@ extern void acpi_set_slot(acpi_t *dev, int slot);
|
||||
extern void acpi_set_irq_mode(acpi_t *dev, int irq_mode);
|
||||
extern void acpi_set_irq_pin(acpi_t *dev, int irq_pin);
|
||||
extern void acpi_set_irq_line(acpi_t *dev, int irq_line);
|
||||
extern void acpi_set_mirq_is_level(acpi_t *dev, int mirq_is_level);
|
||||
extern void acpi_set_gpireg2_default(acpi_t *dev, uint8_t gpireg2_default);
|
||||
extern void acpi_set_nvr(acpi_t *dev, nvr_t *nvr);
|
||||
extern void acpi_set_trap_update(acpi_t *dev, void (*update)(void *priv), void *priv);
|
||||
extern uint8_t acpi_ali_soft_smi_status_read(acpi_t *dev);
|
||||
extern void acpi_ali_soft_smi_status_write(acpi_t *dev, uint8_t soft_smi);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -24,18 +24,22 @@ extern const device_t acc2168_device;
|
||||
/* ALi */
|
||||
extern const device_t ali1217_device;
|
||||
extern const device_t ali1429_device;
|
||||
extern const device_t ali1429g_device;
|
||||
extern const device_t ali1489_device;
|
||||
#if defined(DEV_BRANCH) && defined(USE_M154X)
|
||||
extern const device_t ali1531_device;
|
||||
extern const device_t ali1541_device;
|
||||
extern const device_t ali1543_device;
|
||||
#endif
|
||||
#if defined(DEV_BRANCH) && defined(USE_M6117)
|
||||
extern const device_t ali1543c_device;
|
||||
extern const device_t ali1621_device;
|
||||
extern const device_t ali6117d_device;
|
||||
#endif
|
||||
|
||||
/* AMD */
|
||||
extern const device_t amd640_device;
|
||||
|
||||
/* Contaq/Cypress */
|
||||
extern const device_t contaq_82c596a_device;
|
||||
extern const device_t contaq_82c597_device;
|
||||
|
||||
/* C&T */
|
||||
extern const device_t ct_82c100_device;
|
||||
extern const device_t neat_device;
|
||||
@@ -45,9 +49,6 @@ extern const device_t scat_sx_device;
|
||||
extern const device_t cs8230_device;
|
||||
extern const device_t cs4031_device;
|
||||
|
||||
/* ETEQ */
|
||||
extern const device_t et6000_device;
|
||||
|
||||
/* G2 */
|
||||
extern const device_t gc100_device;
|
||||
extern const device_t gc100a_device;
|
||||
@@ -58,9 +59,13 @@ extern const device_t headland_ht18a_device;
|
||||
extern const device_t headland_ht18b_device;
|
||||
extern const device_t headland_ht18c_device;
|
||||
|
||||
/* IMS */
|
||||
extern const device_t ims8848_device;
|
||||
|
||||
/* Intel */
|
||||
extern const device_t intel_82335_device;
|
||||
extern const device_t i420ex_device;
|
||||
extern const device_t i420ex_ide_device;
|
||||
extern const device_t i420tx_device;
|
||||
extern const device_t i420zx_device;
|
||||
extern const device_t i430lx_device;
|
||||
@@ -78,10 +83,7 @@ extern const device_t i440bx_device;
|
||||
extern const device_t i440bx_no_agp_device;
|
||||
extern const device_t i440gx_device;
|
||||
extern const device_t i440zx_device;
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_I450KX)
|
||||
extern const device_t i450kx_device;
|
||||
#endif
|
||||
|
||||
extern const device_t sio_device;
|
||||
extern const device_t sio_zb_device;
|
||||
@@ -128,11 +130,10 @@ extern const device_t stpc_serial_device;
|
||||
extern const device_t stpc_lpt_device;
|
||||
|
||||
/* UMC */
|
||||
extern const device_t umc_hb4_device;
|
||||
extern const device_t umc_8890_device;
|
||||
|
||||
extern const device_t umc_um82c49x_device;
|
||||
extern const device_t umc_8886f_device;
|
||||
extern const device_t umc_8886af_device;
|
||||
extern const device_t umc_hb4_device;
|
||||
|
||||
/* VIA */
|
||||
extern const device_t via_vt82c49x_device;
|
||||
@@ -155,6 +156,7 @@ extern const device_t via_vt8231_device;
|
||||
|
||||
/* VLSI */
|
||||
extern const device_t vl82c480_device;
|
||||
extern const device_t vl82c486_device;
|
||||
extern const device_t vlsi_scamp_device;
|
||||
|
||||
/* WD */
|
||||
@@ -162,7 +164,7 @@ extern const device_t wd76c10_device;
|
||||
|
||||
/* Miscellaneous Hardware */
|
||||
extern const device_t phoenix_486_jumper_device;
|
||||
extern const device_t vpc2007_device;
|
||||
extern const device_t phoenix_486_jumper_pci_device;
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_OLIVETTI)
|
||||
extern const device_t olivetti_eva_device;
|
||||
|
||||
@@ -110,9 +110,9 @@ typedef struct {
|
||||
/* Ports category */
|
||||
char parallel_devices[3][32]; /* LPT device names */
|
||||
#ifdef USE_SERIAL_DEVICES
|
||||
char serial_devices[2][32]; /* Serial device names */
|
||||
char serial_devices[4][32]; /* Serial device names */
|
||||
#endif
|
||||
int serial_enabled[2], /* Serial ports 1 and 2 enabled */
|
||||
int serial_enabled[4], /* Serial ports 1 and 2 enabled */
|
||||
parallel_enabled[3]; /* LPT1, LPT2, LPT3 enabled */
|
||||
|
||||
/* Other peripherals category */
|
||||
|
||||
@@ -56,6 +56,9 @@ extern const device_t ide_cmd640_vlb_178_device; /* CMD PCI-640B VLB (Port 178h
|
||||
extern const device_t ide_cmd640_pci_device; /* CMD PCI-640B PCI */
|
||||
extern const device_t ide_cmd640_pci_legacy_only_device; /* CMD PCI-640B PCI (Legacy Mode Only) */
|
||||
extern const device_t ide_cmd640_pci_single_channel_device; /* CMD PCI-640B PCI (Only primary channel) */
|
||||
extern const device_t ide_cmd646_device; /* CMD PCI-646 */
|
||||
extern const device_t ide_cmd646_legacy_only_device; /* CMD PCI-646 (Legacy Mode Only) */
|
||||
extern const device_t ide_cmd646_single_channel_device; /* CMD PCI-646 (Only primary channel) */
|
||||
|
||||
extern const device_t ide_opti611_vlb_device; /* OPTi 82c611/611A VLB */
|
||||
|
||||
|
||||
@@ -153,5 +153,8 @@ extern int (*ide_bus_master_dma)(int channel, uint8_t *data, int transfer_length
|
||||
extern void (*ide_bus_master_set_irq)(int channel, void *priv);
|
||||
extern void *ide_bus_master_priv[2];
|
||||
|
||||
extern uint8_t ide_read_ali_75(void);
|
||||
extern uint8_t ide_read_ali_76(void);
|
||||
|
||||
|
||||
#endif /*EMU_IDE_H*/
|
||||
|
||||
@@ -19,14 +19,16 @@
|
||||
typedef struct
|
||||
{
|
||||
uint8_t command, status,
|
||||
ptr0, enabled;
|
||||
uint16_t base, pad;
|
||||
ptr0, enabled,
|
||||
dma_mode, pad,
|
||||
pad0, pad1;
|
||||
uint16_t base, pad2;
|
||||
uint32_t ptr, ptr_cur,
|
||||
addr;
|
||||
int count, eot,
|
||||
slot,
|
||||
irq_mode[2], irq_pin,
|
||||
irq_line;
|
||||
irq_mode[2], irq_level[2],
|
||||
irq_pin, irq_line;
|
||||
} sff8038i_t;
|
||||
|
||||
|
||||
@@ -39,6 +41,11 @@ extern int sff_bus_master_dma_write(int channel, uint8_t *data, int transfer_len
|
||||
|
||||
extern void sff_bus_master_set_irq(int channel, void *priv);
|
||||
|
||||
extern int sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv);
|
||||
|
||||
extern void sff_bus_master_write(uint16_t port, uint8_t val, void *priv);
|
||||
extern uint8_t sff_bus_master_read(uint16_t port, void *priv);
|
||||
|
||||
extern void sff_bus_master_reset(sff8038i_t *dev, uint16_t old_base);
|
||||
|
||||
extern void sff_set_slot(sff8038i_t *dev, int slot);
|
||||
@@ -47,3 +54,5 @@ extern void sff_set_irq_line(sff8038i_t *dev, int irq_line);
|
||||
|
||||
extern void sff_set_irq_mode(sff8038i_t *dev, int channel, int irq_mode);
|
||||
extern void sff_set_irq_pin(sff8038i_t *dev, int irq_pin);
|
||||
|
||||
extern void sff_set_irq_level(sff8038i_t *dev, int channel, int irq_level);
|
||||
|
||||
@@ -36,6 +36,7 @@ typedef struct {
|
||||
uint8_t regs[8];
|
||||
uint8_t addr_register;
|
||||
uint8_t i2c_addr: 7, i2c_state: 2;
|
||||
uint8_t i2c_enabled: 1;
|
||||
} lm75_t;
|
||||
|
||||
|
||||
@@ -63,6 +64,7 @@ extern const device_t lm75_w83781d_device;
|
||||
|
||||
extern const device_t lm78_device;
|
||||
extern const device_t w83781d_device;
|
||||
extern const device_t w83781d_p5a_device;
|
||||
extern const device_t as99127f_device;
|
||||
extern const device_t as99127f_rev2_device;
|
||||
extern const device_t w83782d_device;
|
||||
|
||||
@@ -72,14 +72,12 @@ extern const device_t keyboard_xt_olivetti_device;
|
||||
extern const device_t keyboard_xt_zenith_device;
|
||||
extern const device_t keyboard_at_device;
|
||||
extern const device_t keyboard_at_ami_device;
|
||||
extern const device_t keyboard_at_samsung_device;
|
||||
extern const device_t keyboard_at_toshiba_device;
|
||||
extern const device_t keyboard_at_olivetti_device;
|
||||
extern const device_t keyboard_at_ncr_device;
|
||||
extern const device_t keyboard_ps2_device;
|
||||
extern const device_t keyboard_ps2_ps1_device;
|
||||
extern const device_t keyboard_ps2_ps1_pci_device;
|
||||
extern const device_t keyboard_ps2_ps2_device;
|
||||
extern const device_t keyboard_ps2_xi8088_device;
|
||||
extern const device_t keyboard_ps2_ami_device;
|
||||
extern const device_t keyboard_ps2_olivetti_device;
|
||||
@@ -108,12 +106,15 @@ extern int keyboard_isfsexit(void);
|
||||
extern int keyboard_ismsexit(void);
|
||||
extern void keyboard_set_is_amstrad(int ams);
|
||||
|
||||
extern void keyboard_at_adddata_keyboard_raw(uint8_t val);
|
||||
extern void keyboard_at_adddata_mouse(uint8_t val);
|
||||
extern void keyboard_at_adddata_mouse_direct(uint8_t val);
|
||||
extern void keyboard_at_adddata_mouse_cmd(uint8_t val);
|
||||
extern void keyboard_at_mouse_reset(void);
|
||||
extern uint8_t keyboard_at_mouse_pos(void);
|
||||
extern int keyboard_at_fixed_channel(void);
|
||||
extern void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val,void *), void *);
|
||||
extern void keyboard_at_set_a20_key(int state);
|
||||
extern void keyboard_at_set_mode(int ps2);
|
||||
extern uint8_t keyboard_at_get_mouse_scan(void);
|
||||
extern void keyboard_at_set_mouse_scan(uint8_t val);
|
||||
extern void keyboard_at_reset(void);
|
||||
|
||||
@@ -98,9 +98,11 @@ enum {
|
||||
MACHINE_TYPE_8086,
|
||||
MACHINE_TYPE_286,
|
||||
MACHINE_TYPE_386SX,
|
||||
MACHINE_TYPE_486SLC,
|
||||
MACHINE_TYPE_386DX,
|
||||
MACHINE_TYPE_386DX_486,
|
||||
MACHINE_TYPE_486,
|
||||
MACHINE_TYPE_486_S2,
|
||||
MACHINE_TYPE_486_S3,
|
||||
MACHINE_TYPE_486_MISC,
|
||||
MACHINE_TYPE_SOCKET4,
|
||||
@@ -252,6 +254,8 @@ extern int machine_at_mr286_init(const machine_t *);
|
||||
extern int machine_at_neat_init(const machine_t *);
|
||||
extern int machine_at_neat_ami_init(const machine_t *);
|
||||
|
||||
extern int machine_at_quadt386sx_init(const machine_t *);
|
||||
|
||||
extern int machine_at_award286_init(const machine_t *);
|
||||
extern int machine_at_gdc212m_init(const machine_t *);
|
||||
extern int machine_at_gw286ct_init(const machine_t *);
|
||||
@@ -273,20 +277,19 @@ extern int machine_at_shuttle386sx_init(const machine_t *);
|
||||
extern int machine_at_adi386sx_init(const machine_t *);
|
||||
extern int machine_at_cmdsl386sx16_init(const machine_t *);
|
||||
extern int machine_at_cmdsl386sx25_init(const machine_t *);
|
||||
extern int machine_at_dataexpert386sx_init(const machine_t *);
|
||||
extern int machine_at_spc6033p_init(const machine_t *);
|
||||
extern int machine_at_wd76c10_init(const machine_t *);
|
||||
extern int machine_at_arb1374_init(const machine_t *);
|
||||
extern int machine_at_sbc_350a_init(const machine_t *);
|
||||
extern int machine_at_flytech386_init(const machine_t *);
|
||||
extern int machine_at_mr1217_init(const machine_t *);
|
||||
extern int machine_at_pja511m_init(const machine_t *);
|
||||
extern int machine_at_prox1332_init(const machine_t *);
|
||||
|
||||
extern int machine_at_awardsx_init(const machine_t *);
|
||||
#if defined(DEV_BRANCH) && defined(USE_M6117)
|
||||
extern int machine_at_arb1375_init(const machine_t *);
|
||||
extern int machine_at_pja511m_init(const machine_t *);
|
||||
#endif
|
||||
|
||||
extern int machine_at_pc916sx_init(const machine_t *);
|
||||
|
||||
extern int machine_at_m30008_init(const machine_t *);
|
||||
extern int machine_at_m30015_init(const machine_t *);
|
||||
extern int machine_at_pc916sx_init(const machine_t *);
|
||||
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t *at_ama932j_get_device(void);
|
||||
@@ -294,7 +297,6 @@ extern const device_t *at_flytech386_get_device(void);
|
||||
extern const device_t *at_cmdsl386sx25_get_device(void);
|
||||
extern const device_t *at_spc4620p_get_device(void);
|
||||
extern const device_t *at_spc6033p_get_device(void);
|
||||
extern const device_t *at_m30008_get_device(void);
|
||||
#endif
|
||||
|
||||
/* m_at_386dx_486.c */
|
||||
@@ -312,6 +314,9 @@ extern int machine_at_cs4031_init(const machine_t *);
|
||||
|
||||
extern int machine_at_pb410a_init(const machine_t *);
|
||||
|
||||
extern int machine_at_decpc_lpv_init(const machine_t *);
|
||||
extern int machine_at_acerv10_init(const machine_t *);
|
||||
|
||||
extern int machine_at_acera1g_init(const machine_t *);
|
||||
extern int machine_at_ali1429_init(const machine_t *);
|
||||
extern int machine_at_winbios1429_init(const machine_t *);
|
||||
@@ -323,9 +328,9 @@ extern int machine_at_opti495_mr_init(const machine_t *);
|
||||
extern int machine_at_vect486vl_init(const machine_t *);
|
||||
extern int machine_at_d824_init(const machine_t *);
|
||||
|
||||
extern int machine_at_pcs46c_init(const machine_t *);
|
||||
|
||||
extern int machine_at_403tg_init(const machine_t *);
|
||||
extern int machine_at_403tg_rev_d_init(const machine_t *);
|
||||
extern int machine_at_403tg_rev_d_mr_init(const machine_t *);
|
||||
extern int machine_at_pc330_6573_init(const machine_t *);
|
||||
extern int machine_at_mvi486_init(const machine_t *);
|
||||
|
||||
@@ -340,6 +345,7 @@ extern int machine_at_dtk486_init(const machine_t *);
|
||||
extern int machine_at_px471_init(const machine_t *);
|
||||
extern int machine_at_win471_init(const machine_t *);
|
||||
extern int machine_at_vi15g_init(const machine_t *);
|
||||
extern int machine_at_green_b_init(const machine_t *);
|
||||
|
||||
extern int machine_at_r418_init(const machine_t *);
|
||||
extern int machine_at_ls486e_init(const machine_t *);
|
||||
@@ -347,29 +353,42 @@ extern int machine_at_4dps_init(const machine_t *);
|
||||
extern int machine_at_4sa2_init(const machine_t *);
|
||||
extern int machine_at_m4li_init(const machine_t *);
|
||||
extern int machine_at_alfredo_init(const machine_t *);
|
||||
extern int machine_at_ninja_init(const machine_t *);
|
||||
extern int machine_at_486sp3_init(const machine_t *);
|
||||
extern int machine_at_486sp3c_init(const machine_t *);
|
||||
extern int machine_at_486sp3g_init(const machine_t *);
|
||||
extern int machine_at_486ap4_init(const machine_t *);
|
||||
extern int machine_at_g486vpa_init(const machine_t *);
|
||||
extern int machine_at_486vipio2_init(const machine_t *);
|
||||
extern int machine_at_abpb4_init(const machine_t *);
|
||||
extern int machine_at_win486pci_init(const machine_t *);
|
||||
extern int machine_at_ms4145_init(const machine_t *);
|
||||
extern int machine_at_sbc_490_init(const machine_t *);
|
||||
extern int machine_at_tf_486_init(const machine_t *);
|
||||
|
||||
extern int machine_at_atc1415_init(const machine_t *);
|
||||
extern int machine_at_ecs486_init(const machine_t *);
|
||||
extern int machine_at_hot433_init(const machine_t *);
|
||||
extern int machine_at_pci400c_b_init(const machine_t *);
|
||||
extern int machine_at_g486ip_init(const machine_t *);
|
||||
|
||||
extern int machine_at_itoxstar_init(const machine_t *);
|
||||
extern int machine_at_arb1423c_init(const machine_t *);
|
||||
extern int machine_at_arb1479_init(const machine_t *);
|
||||
extern int machine_at_pcm9340_init(const machine_t *);
|
||||
extern int machine_at_pcm5330_init(const machine_t *);
|
||||
|
||||
extern int machine_at_ecs486_init(const machine_t *);
|
||||
extern int machine_at_hot433_init(const machine_t *);
|
||||
extern int machine_at_atc1415_init(const machine_t *);
|
||||
extern int machine_at_actionpc2600_init(const machine_t *);
|
||||
extern int machine_at_m919_init(const machine_t *);
|
||||
extern int machine_at_spc7700p_lw_init(const machine_t *);
|
||||
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t *at_acera1g_get_device(void);
|
||||
extern const device_t *at_vect486vl_get_device(void);
|
||||
extern const device_t *at_d824_get_device(void);
|
||||
extern const device_t *at_pcs46c_get_device(void);
|
||||
extern const device_t *at_valuepoint433_get_device(void);
|
||||
extern const device_t *at_sbc_490_get_device(void);
|
||||
#endif
|
||||
|
||||
/* m_at_commodore.c */
|
||||
@@ -383,118 +402,144 @@ extern int machine_at_portableiii386_init(const machine_t *);
|
||||
extern const device_t *at_cpqiii_get_device(void);
|
||||
#endif
|
||||
|
||||
/* m_at_socket4_5.c */
|
||||
extern int machine_at_excalibur_init(const machine_t *);
|
||||
/* m_at_socket4.c */
|
||||
extern void machine_at_premiere_common_init(const machine_t *, int);
|
||||
extern void machine_at_award_common_init(const machine_t *);
|
||||
|
||||
extern int machine_at_pat54pv_init(const machine_t *);
|
||||
extern void machine_at_sp4_common_init(const machine_t *model);
|
||||
|
||||
extern int machine_at_hot543_init(const machine_t *);
|
||||
extern int machine_at_p54vl_init(const machine_t *);
|
||||
|
||||
extern int machine_at_batman_init(const machine_t *);
|
||||
extern int machine_at_ambradp60_init(const machine_t *);
|
||||
extern int machine_at_excalibur_pci_init(const machine_t *);
|
||||
extern int machine_at_p5mp3_init(const machine_t *);
|
||||
extern int machine_at_dellxp60_init(const machine_t *);
|
||||
extern int machine_at_opti560l_init(const machine_t *);
|
||||
extern int machine_at_ambradp60_init(const machine_t *);
|
||||
extern int machine_at_valuepointp60_init(const machine_t *);
|
||||
extern int machine_at_p5mp3_init(const machine_t *);
|
||||
extern int machine_at_pb520r_init(const machine_t *);
|
||||
extern int machine_at_revenge_init(const machine_t *);
|
||||
extern int machine_at_586mc1_init(const machine_t *);
|
||||
extern int machine_at_pb520r_init(const machine_t *);
|
||||
|
||||
extern int machine_at_excalibur_init(const machine_t *);
|
||||
|
||||
extern int machine_at_p5vl_init(const machine_t *);
|
||||
|
||||
extern int machine_at_excalibur_pci_2_init(const machine_t *);
|
||||
extern int machine_at_p5sp4_init(const machine_t *);
|
||||
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t *at_pb520r_get_device(void);
|
||||
#endif
|
||||
|
||||
/* m_at_socket5.c */
|
||||
extern int machine_at_plato_init(const machine_t *);
|
||||
extern int machine_at_ambradp90_init(const machine_t *);
|
||||
extern int machine_at_430nx_init(const machine_t *);
|
||||
|
||||
extern int machine_at_p54tp4xe_init(const machine_t *);
|
||||
extern int machine_at_endeavor_init(const machine_t *);
|
||||
extern int machine_at_zappa_init(const machine_t *);
|
||||
extern int machine_at_mb500n_init(const machine_t *);
|
||||
extern int machine_at_apollo_init(const machine_t *);
|
||||
extern int machine_at_vectra54_init(const machine_t *);
|
||||
extern int machine_at_powermatev_init(const machine_t *);
|
||||
extern int machine_at_acerv30_init(const machine_t *);
|
||||
extern int machine_at_apollo_init(const machine_t *);
|
||||
extern int machine_at_exp8551_init(const machine_t *);
|
||||
extern int machine_at_vectra54_init(const machine_t *);
|
||||
extern int machine_at_zappa_init(const machine_t *);
|
||||
extern int machine_at_powermatev_init(const machine_t *);
|
||||
extern int machine_at_mb500n_init(const machine_t *);
|
||||
extern int machine_at_hawk_init(const machine_t *);
|
||||
|
||||
extern int machine_at_pat54pv_init(const machine_t *);
|
||||
|
||||
extern int machine_at_hot543_init(const machine_t *);
|
||||
|
||||
extern int machine_at_p5sp4_init(const machine_t *);
|
||||
extern int machine_at_p54sp4_init(const machine_t *);
|
||||
extern int machine_at_sq588_init(const machine_t *);
|
||||
|
||||
extern int machine_at_hot539_init(const machine_t *);
|
||||
#ifdef EMU_DEVICE_H
|
||||
#define at_vectra54_get_device at_endeavor_get_device
|
||||
#endif
|
||||
|
||||
/* m_at_socket7_3v.c */
|
||||
extern int machine_at_p54tp4xe_init(const machine_t *);
|
||||
extern int machine_at_mr586_init(const machine_t *);
|
||||
extern int machine_at_gw2katx_init(const machine_t *);
|
||||
extern int machine_at_thor_init(const machine_t *);
|
||||
extern int machine_at_mrthor_init(const machine_t *);
|
||||
extern int machine_at_endeavor_init(const machine_t *);
|
||||
extern int machine_at_ms5119_init(const machine_t *);
|
||||
extern int machine_at_pb640_init(const machine_t *);
|
||||
extern int machine_at_fmb_init(const machine_t *);
|
||||
|
||||
extern int machine_at_acerm3a_init(const machine_t *);
|
||||
extern int machine_at_ap53_init(const machine_t *);
|
||||
extern int machine_at_8500tuc_init(const machine_t *);
|
||||
extern int machine_at_p55t2s_init(const machine_t *);
|
||||
|
||||
extern int machine_at_p5vxb_init(const machine_t *);
|
||||
extern int machine_at_gw2kte_init(const machine_t *);
|
||||
|
||||
extern int machine_at_ap5s_init(const machine_t *);
|
||||
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t *at_endeavor_get_device(void);
|
||||
#define at_vectra54_get_device at_endeavor_get_device
|
||||
extern const device_t *at_pb520r_get_device(void);
|
||||
extern const device_t *at_thor_get_device(void);
|
||||
#define at_mrthor_get_device at_thor_get_device
|
||||
extern const device_t *at_pb640_get_device(void);
|
||||
#endif
|
||||
|
||||
/* m_at_socket7_s7.c */
|
||||
extern int machine_at_ap5s_init(const machine_t *);
|
||||
|
||||
extern int machine_at_chariot_init(const machine_t *);
|
||||
extern int machine_at_mr586_init(const machine_t *);
|
||||
extern int machine_at_thor_init(const machine_t *);
|
||||
extern int machine_at_gw2katx_init(const machine_t *);
|
||||
extern int machine_at_mrthor_init(const machine_t *);
|
||||
extern int machine_at_pb640_init(const machine_t *);
|
||||
|
||||
extern int machine_at_acerm3a_init(const machine_t *);
|
||||
/* m_at_socket7.c */
|
||||
extern int machine_at_acerv35n_init(const machine_t *);
|
||||
extern int machine_at_ap53_init(const machine_t *);
|
||||
extern int machine_at_p55t2p4_init(const machine_t *);
|
||||
extern int machine_at_p55t2s_init(const machine_t *);
|
||||
extern int machine_at_8500tuc_init(const machine_t *);
|
||||
extern int machine_at_m7shi_init(const machine_t *);
|
||||
extern int machine_at_tc430hx_init(const machine_t *);
|
||||
extern int machine_at_equium5200_init(const machine_t *);
|
||||
extern int machine_at_pcv240_init(const machine_t *);
|
||||
extern int machine_at_p65up5_cp55t2d_init(const machine_t *);
|
||||
|
||||
extern int machine_at_mb520n_init(const machine_t *);
|
||||
extern int machine_at_ap5vm_init(const machine_t *);
|
||||
extern int machine_at_p55tvp4_init(const machine_t *);
|
||||
extern int machine_at_p55va_init(const machine_t *);
|
||||
extern int machine_at_i430vx_init(const machine_t *);
|
||||
extern int machine_at_5ivg_init(const machine_t *);
|
||||
extern int machine_at_brio80xx_init(const machine_t *);
|
||||
extern int machine_at_8500tvxa_init(const machine_t *);
|
||||
extern int machine_at_presario2240_init(const machine_t *);
|
||||
extern int machine_at_presario4500_init(const machine_t *);
|
||||
extern int machine_at_gw2kte_init(const machine_t *);
|
||||
extern int machine_at_p55va_init(const machine_t *);
|
||||
extern int machine_at_brio80xx_init(const machine_t *);
|
||||
extern int machine_at_pb680_init(const machine_t *);
|
||||
extern int machine_at_mb520n_init(const machine_t *);
|
||||
extern int machine_at_i430vx_init(const machine_t *);
|
||||
|
||||
extern int machine_at_nupro592_init(const machine_t *);
|
||||
extern int machine_at_tx97_init(const machine_t *);
|
||||
extern int machine_at_ym430tx_init(const machine_t *);
|
||||
#if defined(DEV_BRANCH) && defined(NO_SIO)
|
||||
extern int machine_at_an430tx_init(const machine_t *);
|
||||
#endif
|
||||
extern int machine_at_ym430tx_init(const machine_t *);
|
||||
extern int machine_at_mb540n_init(const machine_t *);
|
||||
extern int machine_at_p5mms98_init(const machine_t *);
|
||||
|
||||
extern int machine_at_r534f_init(const machine_t *);
|
||||
extern int machine_at_ms5146_init(const machine_t *);
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_M154X)
|
||||
extern int machine_at_m560_init(const machine_t *);
|
||||
extern int machine_at_ms5164_init(const machine_t *);
|
||||
#endif
|
||||
|
||||
extern int machine_at_ficva502_init(const machine_t *);
|
||||
|
||||
extern int machine_at_ficpa2012_init(const machine_t *);
|
||||
|
||||
extern int machine_at_r534f_init(const machine_t *);
|
||||
extern int machine_at_ms5146_init(const machine_t *);
|
||||
|
||||
extern int machine_at_m560_init(const machine_t *);
|
||||
extern int machine_at_ms5164_init(const machine_t *);
|
||||
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t *at_thor_get_device(void);
|
||||
extern const device_t *at_pb640_get_device(void);
|
||||
extern const device_t *at_presario2240_get_device(void);
|
||||
#define at_presario4500_get_device at_presario2240_get_device
|
||||
#endif
|
||||
|
||||
/* m_at_super7_ss7.c */
|
||||
/* m_at_sockets7.c */
|
||||
extern int machine_at_p5a_init(const machine_t *);
|
||||
extern int machine_at_m579_init(const machine_t *);
|
||||
extern int machine_at_ga_5aa_init(const machine_t *);
|
||||
extern int machine_at_ga_5ax_init(const machine_t *);
|
||||
|
||||
extern int machine_at_ax59pro_init(const machine_t *);
|
||||
extern int machine_at_mvp3_init(const machine_t *);
|
||||
extern int machine_at_ficva503a_init(const machine_t *);
|
||||
extern int machine_at_sy_5ema_pro_init(const machine_t *);
|
||||
|
||||
/* m_at_socket8.c */
|
||||
#if defined(DEV_BRANCH) && defined(USE_I450KX)
|
||||
extern int machine_at_p6rp4_init(const machine_t *);
|
||||
#endif
|
||||
|
||||
extern int machine_at_686nx_init(const machine_t *);
|
||||
extern int machine_at_v60n_init(const machine_t *);
|
||||
@@ -509,6 +554,8 @@ extern void machine_at_p65up5_common_init(const machine_t *, const device_t *nor
|
||||
extern int machine_at_p65up5_cp6nd_init(const machine_t *);
|
||||
|
||||
/* m_at_slot1.c */
|
||||
extern int machine_at_m729_init(const machine_t *);
|
||||
|
||||
extern int machine_at_p65up5_cpknd_init(const machine_t *);
|
||||
extern int machine_at_kn97_init(const machine_t *);
|
||||
|
||||
@@ -525,9 +572,6 @@ extern int machine_at_atc6310bxii_init(const machine_t *);
|
||||
extern int machine_at_686bx_init(const machine_t *);
|
||||
extern int machine_at_tsunamiatx_init(const machine_t *);
|
||||
extern int machine_at_p6sba_init(const machine_t *);
|
||||
#if defined(DEV_BRANCH) && defined(NO_SIO)
|
||||
extern int machine_at_ergox365_init(const machine_t *);
|
||||
#endif
|
||||
extern int machine_at_ficka6130_init(const machine_t *);
|
||||
extern int machine_at_p3v133_init(const machine_t *);
|
||||
extern int machine_at_p3v4x_init(const machine_t *);
|
||||
@@ -651,10 +695,6 @@ extern int machine_xt_pc500_init(const machine_t *);
|
||||
|
||||
extern int machine_xt_iskra3104_init(const machine_t *);
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_HEDAKA)
|
||||
extern int machine_xt_hed919_init(const machine_t *);
|
||||
#endif
|
||||
|
||||
/* m_xt_compaq.c */
|
||||
extern int machine_xt_compaq_deskpro_init(const machine_t *);
|
||||
extern int machine_xt_compaq_portable_init(const machine_t *);
|
||||
|
||||
@@ -64,6 +64,15 @@
|
||||
#define ACCESS_READ 1
|
||||
#define ACCESS_WRITE 2
|
||||
|
||||
#define ACCESS_SMRAM_OFF 0
|
||||
#define ACCESS_SMRAM_X 1
|
||||
#define ACCESS_SMRAM_W 2
|
||||
#define ACCESS_SMRAM_WX 3
|
||||
#define ACCESS_SMRAM_R 4
|
||||
#define ACCESS_SMRAM_RX 5
|
||||
#define ACCESS_SMRAM_RW 6
|
||||
#define ACCESS_SMRAM_RWX 7
|
||||
|
||||
/* Conversion #define's - we need these to seamlessly convert the old mem_set_mem_state() calls to
|
||||
the new stuff in order to make this a drop in replacement.
|
||||
|
||||
@@ -80,7 +89,10 @@
|
||||
/* Internal execute access, external read access. */
|
||||
#define MEM_READ_EXTERNAL_EX 0
|
||||
#define MEM_READ_SMRAM (ACCESS_X_SMRAM | ACCESS_R_SMRAM)
|
||||
#define MEM_READ_CACHE (ACCESS_X_CACHE | ACCESS_R_CACHE)
|
||||
#define MEM_READ_SMRAM_EX (ACCESS_X_SMRAM)
|
||||
#define MEM_EXEC_SMRAM MEM_READ_SMRAM_EX
|
||||
#define MEM_READ_SMRAM_2 (ACCESS_R_SMRAM)
|
||||
/* Theese two are going to be identical. */
|
||||
#define MEM_READ_DISABLED_EX MEM_READ_DISABLED
|
||||
#define MEM_READ_MASK 0x7c1f
|
||||
@@ -93,6 +105,7 @@
|
||||
#define MEM_WRITE_ROMCS (ACCESS_W_ROMCS)
|
||||
#define MEM_WRITE_EXTANY (ACCESS_W_ROMCS)
|
||||
#define MEM_WRITE_SMRAM (ACCESS_W_SMRAM)
|
||||
#define MEM_WRITE_CACHE (ACCESS_W_CACHE)
|
||||
/* Theese two are going to be identical. */
|
||||
#define MEM_WRITE_DISABLED_EX MEM_READ_DISABLED
|
||||
#define MEM_WRITE_MASK 0x03e0
|
||||
@@ -132,10 +145,18 @@
|
||||
mem_set_access(ACCESS_SMM, 0, base, size, access)
|
||||
#define mem_set_mem_state_both(base, size, access) \
|
||||
mem_set_access(ACCESS_ALL, 0, base, size, access)
|
||||
#define mem_set_mem_state_cpu_both(base, size, access) \
|
||||
mem_set_access(ACCESS_CPU_BOTH, 0, base, size, access)
|
||||
#define mem_set_mem_state_bus_both(base, size, access) \
|
||||
mem_set_access(ACCESS_BUS_BOTH, 0, base, size, access)
|
||||
#define mem_set_mem_state_smram(smm, base, size, is_smram) \
|
||||
mem_set_access((smm ? ACCESS_SMM : ACCESS_NORMAL), 1, base, size, is_smram)
|
||||
#define mem_set_mem_state_smram_ex(smm, base, size, is_smram) \
|
||||
mem_set_access((smm ? ACCESS_SMM : ACCESS_NORMAL), 2, base, size, is_smram)
|
||||
#define mem_set_access_smram_cpu(smm, base, size, is_smram) \
|
||||
mem_set_access((smm ? ACCESS_CPU_SMM : ACCESS_CPU), 1, base, size, is_smram)
|
||||
#define mem_set_access_smram_bus(smm, base, size, is_smram) \
|
||||
mem_set_access((smm ? ACCESS_BUS_SMM : ACCESS_BUS), 1, base, size, is_smram)
|
||||
#define flushmmucache_cr3 \
|
||||
flushmmucache_nopc
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@ extern const device_t piix4_nvr_device;
|
||||
extern const device_t ls486e_nvr_device;
|
||||
extern const device_t ami_apollo_nvr_device;
|
||||
extern const device_t via_nvr_device;
|
||||
extern const device_t p6rp4_nvr_device;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -45,9 +45,15 @@
|
||||
#define PCI_MIRQ1 1
|
||||
#define PCI_MIRQ2 2
|
||||
#define PCI_MIRQ3 3
|
||||
#define PCI_MIRQ4 4
|
||||
#define PCI_MIRQ5 5
|
||||
#define PCI_MIRQ6 6
|
||||
#define PCI_MIRQ7 7
|
||||
|
||||
#define PCI_IRQ_DISABLED -1
|
||||
|
||||
#define PCI_ADD_STRICT 0x80
|
||||
|
||||
enum {
|
||||
PCI_CARD_NORTHBRIDGE = 0,
|
||||
PCI_CARD_AGPBRIDGE,
|
||||
@@ -119,10 +125,14 @@ extern void trc_init(void);
|
||||
extern uint8_t trc_read(uint16_t port, void *priv);
|
||||
extern void trc_write(uint16_t port, uint8_t val, void *priv);
|
||||
|
||||
extern void pci_bridge_set_ctl(void *priv, uint8_t ctl);
|
||||
|
||||
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t dec21150_device;
|
||||
|
||||
extern const device_t ali5243_agp_device;
|
||||
extern const device_t ali5247_agp_device;
|
||||
extern const device_t i440lx_agp_device;
|
||||
extern const device_t i440bx_agp_device;
|
||||
extern const device_t i440gx_agp_device;
|
||||
|
||||
@@ -33,6 +33,11 @@ typedef struct pic {
|
||||
extern pic_t pic, pic2;
|
||||
|
||||
|
||||
extern void pic_reset_smi_irq_mask(void);
|
||||
extern void pic_set_smi_irq_mask(int irq, int set);
|
||||
extern uint16_t pic_get_smi_irq_status(void);
|
||||
extern void pic_clear_smi_irq_status(int irq);
|
||||
|
||||
extern int pic_elcr_get_enabled(void);
|
||||
extern void pic_elcr_set_enabled(int enabled);
|
||||
extern void pic_elcr_io_handler(int set);
|
||||
@@ -40,6 +45,7 @@ extern void pic_elcr_write(uint16_t port, uint8_t val, void *priv);
|
||||
extern uint8_t pic_elcr_read(uint16_t port, void *priv);
|
||||
|
||||
extern void pic_set_shadow(int sh);
|
||||
extern void pic_set_pci(void);
|
||||
extern void pic_init(void);
|
||||
extern void pic_init_pcjr(void);
|
||||
extern void pic2_init(void);
|
||||
|
||||
38
src/include/86box/port_6x.h
Normal file
38
src/include/86box/port_6x.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Header for the implementation of Port 6x used by various
|
||||
* machines.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Miran Grca.
|
||||
*/
|
||||
#ifndef EMU_PORT_6X_H
|
||||
# define EMU_PORT_6X_H
|
||||
|
||||
|
||||
#ifdef _TIMER_H_
|
||||
typedef struct
|
||||
{
|
||||
uint8_t refresh, flags;
|
||||
|
||||
pc_timer_t refresh_timer;
|
||||
} port_6x_t;
|
||||
#endif
|
||||
|
||||
|
||||
extern const device_t port_6x_device;
|
||||
extern const device_t port_6x_xi8088_device;
|
||||
extern const device_t port_6x_ps2_device;
|
||||
extern const device_t port_6x_olivetti_device;
|
||||
|
||||
|
||||
#endif /*EMU_PORT_6X_H*/
|
||||
@@ -27,6 +27,8 @@
|
||||
#define SERIAL_NS16450 2
|
||||
#define SERIAL_NS16550 3
|
||||
|
||||
#define SERIAL_FIFO_SIZE 16
|
||||
|
||||
/* Default settings for the standard ports. */
|
||||
#define SERIAL1_ADDR 0x03f8
|
||||
#define SERIAL1_IRQ 4
|
||||
@@ -54,7 +56,7 @@ typedef struct serial_s
|
||||
|
||||
uint8_t rcvr_fifo_pos, xmit_fifo_pos,
|
||||
pad0, pad1,
|
||||
rcvr_fifo[16], xmit_fifo[16];
|
||||
rcvr_fifo[SERIAL_FIFO_SIZE], xmit_fifo[SERIAL_FIFO_SIZE];
|
||||
|
||||
pc_timer_t transmit_timer, timeout_timer;
|
||||
double clock_src, transmit_period;
|
||||
|
||||
@@ -22,12 +22,14 @@ extern const device_t acc3221_device;
|
||||
extern const device_t f82c710_device;
|
||||
extern const device_t f82c606_device;
|
||||
extern const device_t fdc37c651_device;
|
||||
extern const device_t fdc37c651_ide_device;
|
||||
extern const device_t fdc37c661_device;
|
||||
extern const device_t fdc37c663_device;
|
||||
extern const device_t fdc37c663_ide_device;
|
||||
extern const device_t fdc37c665_device;
|
||||
extern const device_t fdc37c665_ide_device;
|
||||
extern const device_t fdc37c666_device;
|
||||
extern const device_t fdc37c67x_device;
|
||||
extern const device_t fdc37c669_device;
|
||||
extern const device_t fdc37c669_370_device;
|
||||
extern const device_t fdc37c931apm_device;
|
||||
@@ -54,6 +56,7 @@ extern const device_t pc87311_ide_device;
|
||||
extern const device_t pc87332_device;
|
||||
extern const device_t pc87332_398_device;
|
||||
extern const device_t pc87332_398_ide_device;
|
||||
extern const device_t pc87332_398_ide_sec_device;
|
||||
extern const device_t pc87332_398_ide_fdcon_device;
|
||||
extern const device_t pc97307_device;
|
||||
extern const device_t prime3b_device;
|
||||
|
||||
70
src/include/86box/smbus.h
Normal file
70
src/include/86box/smbus.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Definitions for the SMBus host controllers.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2020 RichardG.
|
||||
*/
|
||||
#ifndef EMU_SMBUS_PIIX4_H
|
||||
# define EMU_SMBUS_PIIX4_H
|
||||
|
||||
|
||||
#define SMBUS_PIIX4_BLOCK_DATA_SIZE 32
|
||||
#define SMBUS_PIIX4_BLOCK_DATA_MASK (SMBUS_PIIX4_BLOCK_DATA_SIZE - 1)
|
||||
|
||||
#define SMBUS_ALI7101_BLOCK_DATA_SIZE 32
|
||||
#define SMBUS_ALI7101_BLOCK_DATA_MASK (SMBUS_ALI7101_BLOCK_DATA_SIZE - 1)
|
||||
|
||||
|
||||
enum {
|
||||
SMBUS_PIIX4 = 0,
|
||||
SMBUS_VIA
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint32_t local;
|
||||
uint16_t io_base;
|
||||
int clock;
|
||||
double bit_period;
|
||||
uint8_t stat, next_stat, ctl, cmd, addr,
|
||||
data0, data1,
|
||||
index, data[SMBUS_PIIX4_BLOCK_DATA_SIZE];
|
||||
pc_timer_t response_timer;
|
||||
void *i2c;
|
||||
} smbus_piix4_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t local;
|
||||
uint16_t io_base;
|
||||
uint8_t stat, next_stat, ctl, cmd, addr,
|
||||
data0, data1,
|
||||
index, data[SMBUS_ALI7101_BLOCK_DATA_SIZE];
|
||||
pc_timer_t response_timer;
|
||||
void *i2c;
|
||||
} smbus_ali7101_t;
|
||||
|
||||
|
||||
extern void smbus_piix4_remap(smbus_piix4_t *dev, uint16_t new_io_base, uint8_t enable);
|
||||
extern void smbus_piix4_setclock(smbus_piix4_t *dev, int clock);
|
||||
|
||||
extern void smbus_ali7101_remap(smbus_ali7101_t *dev, uint16_t new_io_base, uint8_t enable);
|
||||
|
||||
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t piix4_smbus_device;
|
||||
extern const device_t via_smbus_device;
|
||||
|
||||
extern const device_t ali7101_smbus_device;
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*EMU_SMBUS_PIIX4_H*/
|
||||
@@ -39,12 +39,19 @@ extern void smram_recalc_all(int ret);
|
||||
extern void smram_del(smram_t *smr);
|
||||
/* Add a SMRAM mapping. */
|
||||
extern smram_t *smram_add(void);
|
||||
/* Set memory state in the specified model (normal or SMM) according to the specified flags,
|
||||
separately for bus and CPU. */
|
||||
extern void smram_map_ex(int bus, int smm, uint32_t addr, uint32_t size, int is_smram);
|
||||
/* Set memory state in the specified model (normal or SMM) according to the specified flags. */
|
||||
extern void smram_map(int smm, uint32_t addr, uint32_t size, int is_smram);
|
||||
/* Disable a specific SMRAM mapping. */
|
||||
extern void smram_disable(smram_t *smr);
|
||||
/* Disable all SMRAM mappings. */
|
||||
extern void smram_disable_all(void);
|
||||
/* Enable SMRAM mappings according to flags for both normal and SMM modes, separately for bus
|
||||
and CPU. */
|
||||
extern void smram_enable_ex(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size,
|
||||
int flags_normal, int flags_normal_bus, int flags_smm, int flags_smm_bus);
|
||||
/* Enable SMRAM mappings according to flags for both normal and SMM modes. */
|
||||
extern void smram_enable(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size,
|
||||
int flags_normal, int flags_smm);
|
||||
@@ -52,6 +59,8 @@ extern void smram_enable(smram_t *smr, uint32_t host_base, uint32_t ram_base, ui
|
||||
extern int smram_enabled(smram_t *smr);
|
||||
/* Changes the SMRAM state. */
|
||||
extern void smram_state_change(smram_t *smr, int smm, int flags);
|
||||
/* Enables or disables the use of a separate SMRAM for addresses below A0000. */
|
||||
extern void smram_set_separate_smram(uint8_t set);
|
||||
|
||||
|
||||
#endif /*EMU_SMRAM_H*/
|
||||
|
||||
@@ -106,6 +106,8 @@ typedef struct {
|
||||
|
||||
extern void spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size);
|
||||
extern void spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit);
|
||||
extern void spd_write_drbs_interleaved(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit);
|
||||
extern void spd_write_drbs_ali1621(uint8_t *regs, uint8_t reg_min, uint8_t reg_max);
|
||||
|
||||
|
||||
#endif /*EMU_SPD_H*/
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#define FLAG_NOSKEW 16
|
||||
#define FLAG_ADDR_BY16 32
|
||||
#define FLAG_RAMDAC_SHIFT 64
|
||||
|
||||
#define FLAG_128K_MASK 128
|
||||
|
||||
typedef struct {
|
||||
int ena,
|
||||
@@ -50,7 +50,8 @@ typedef struct svga_t
|
||||
lowres, interlace, linedbl, rowcount,
|
||||
set_reset_disabled, bpp, ramdac_type, fb_only,
|
||||
readmode, writemode, readplane,
|
||||
hwcursor_oddeven, dac_hwcursor_oddeven, overlay_oddeven;
|
||||
hwcursor_oddeven, dac_hwcursor_oddeven, overlay_oddeven,
|
||||
fcr, hblank_overscan;
|
||||
|
||||
int dac_addr, dac_pos, dac_r, dac_g,
|
||||
vtotal, dispend, vsyncstart, split, vblankstart,
|
||||
@@ -60,8 +61,9 @@ typedef struct svga_t
|
||||
con, cursoron, blink, scrollcache, char_width,
|
||||
firstline, lastline, firstline_draw, lastline_draw,
|
||||
displine, fullchange, x_add, y_add, pan,
|
||||
vram_display_mask, vidclock,
|
||||
hwcursor_on, dac_hwcursor_on, overlay_on, set_override;
|
||||
vram_display_mask, vidclock, dots_per_clock, hblank_ext,
|
||||
hwcursor_on, dac_hwcursor_on, overlay_on, set_override,
|
||||
hblankstart, hblankend, hblank_sub, hblank_end_val, hblank_end_len;
|
||||
|
||||
/*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 :
|
||||
0MB-1MB - VRAM
|
||||
|
||||
@@ -44,6 +44,8 @@ void svga_render_4bpp_lowres(svga_t *svga);
|
||||
void svga_render_4bpp_highres(svga_t *svga);
|
||||
void svga_render_8bpp_lowres(svga_t *svga);
|
||||
void svga_render_8bpp_highres(svga_t *svga);
|
||||
void svga_render_8bpp_tseng_lowres(svga_t *svga);
|
||||
void svga_render_8bpp_tseng_highres(svga_t *svga);
|
||||
void svga_render_8bpp_gs_lowres(svga_t *svga);
|
||||
void svga_render_8bpp_gs_highres(svga_t *svga);
|
||||
void svga_render_8bpp_rgb_lowres(svga_t *svga);
|
||||
|
||||
@@ -176,6 +176,7 @@ extern void updatewindowsize(int x, int y);
|
||||
extern void video_init(void);
|
||||
extern void video_close(void);
|
||||
extern void video_reset_close(void);
|
||||
extern void video_pre_reset(int card);
|
||||
extern void video_reset(int card);
|
||||
extern uint8_t video_force_resize_get(void);
|
||||
extern void video_force_resize_set(uint8_t res);
|
||||
@@ -264,7 +265,11 @@ extern const device_t f82c425_video_device;
|
||||
/* NCR NGA */
|
||||
extern const device_t nga_device;
|
||||
|
||||
/* Tseng ET3000AX */
|
||||
extern const device_t et3000_isa_device;
|
||||
|
||||
/* Tseng ET4000AX */
|
||||
extern const device_t et4000_tc6058af_isa_device;
|
||||
extern const device_t et4000_isa_device;
|
||||
extern const device_t et4000k_isa_device;
|
||||
extern const device_t et4000k_tg286_isa_device;
|
||||
@@ -316,7 +321,6 @@ extern const device_t oti037c_device;
|
||||
extern const device_t oti067_device;
|
||||
extern const device_t oti067_acer386_device;
|
||||
extern const device_t oti067_ama932j_device;
|
||||
extern const device_t oti067_m300_device;
|
||||
extern const device_t oti077_device;
|
||||
|
||||
/* Paradise/WD (S)VGA */
|
||||
@@ -375,6 +379,7 @@ extern const device_t s3_spea_mercury_p64v_pci_device;
|
||||
extern const device_t s3_elsa_winner2000_pro_x_964_pci_device;
|
||||
extern const device_t s3_elsa_winner2000_pro_x_pci_device;
|
||||
extern const device_t s3_trio64v2_dx_pci_device;
|
||||
extern const device_t s3_trio64v2_dx_onboard_pci_device;
|
||||
|
||||
/* S3 ViRGE */
|
||||
extern const device_t s3_virge_325_pci_device;
|
||||
@@ -397,6 +402,7 @@ extern const device_t sigma_device;
|
||||
extern const device_t tgui9400cxi_device;
|
||||
extern const device_t tgui9440_vlb_device;
|
||||
extern const device_t tgui9440_pci_device;
|
||||
extern const device_t tgui9440_onboard_pci_device;
|
||||
extern const device_t tgui9660_pci_device;
|
||||
extern const device_t tgui9680_pci_device;
|
||||
|
||||
|
||||
6
src/io.c
6
src/io.c
@@ -322,6 +322,10 @@ inb(uint16_t port)
|
||||
if (!found)
|
||||
cycles -= io_delay;
|
||||
|
||||
/* TriGem 486-BIOS MHz output. */
|
||||
if (port == 0x1ed)
|
||||
ret = 0xfe;
|
||||
|
||||
io_log("[%04X:%08X] (%i, %i, %04i) in b(%04X) = %02X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret);
|
||||
|
||||
return(ret);
|
||||
@@ -345,7 +349,7 @@ outb(uint16_t port, uint8_t val)
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
|
||||
|
||||
if (!found) {
|
||||
cycles -= io_delay;
|
||||
#ifdef USE_DYNAREC
|
||||
|
||||
@@ -43,6 +43,9 @@ typedef struct
|
||||
} log_t;
|
||||
|
||||
|
||||
extern FILE *stdlog; /* file to log output to */
|
||||
|
||||
|
||||
void
|
||||
log_set_suppr_seen(void *priv, int suppr_seen)
|
||||
{
|
||||
|
||||
@@ -20,17 +20,14 @@ add_library(mch OBJECT machine.c machine_table.c m_xt.c m_xt_compaq.c
|
||||
m_at.c m_at_commodore.c
|
||||
m_at_t3100e.c m_at_t3100e_vid.c m_ps1.c m_ps1_hdc.c m_ps2_isa.c
|
||||
m_ps2_mca.c m_at_compaq.c m_at_286_386sx.c m_at_386dx_486.c
|
||||
m_at_socket4_5.c m_at_socket7.c m_at_sockets7.c m_at_socket8.c
|
||||
m_at_slot1.c m_at_slot2.c m_at_socket370.c m_at_misc.c)
|
||||
m_at_socket4.c m_at_socket5.c m_at_socket7_3v.c m_at_socket7.c
|
||||
m_at_sockets7.c m_at_socket8.c m_at_slot1.c m_at_slot2.c m_at_socket370.c
|
||||
m_at_misc.c)
|
||||
|
||||
if(HEDAKA)
|
||||
target_compile_definitions(mch PRIVATE USE_HEDAKA)
|
||||
endif()
|
||||
|
||||
if(I450KX)
|
||||
target_compile_definitions(mch PRIVATE USE_I450KX)
|
||||
endif()
|
||||
|
||||
if(LASERXT)
|
||||
target_sources(mch PRIVATE m_xt_laserxt.c)
|
||||
target_compile_definitions(mch PRIVATE USE_LASERXT)
|
||||
@@ -46,8 +43,4 @@ endif()
|
||||
|
||||
if(M154X)
|
||||
target_compile_definitions(mch PRIVATE USE_M154X)
|
||||
endif()
|
||||
|
||||
if(M6117)
|
||||
target_compile_definitions(mch PRIVATE USE_M6117)
|
||||
endif()
|
||||
@@ -56,6 +56,7 @@
|
||||
#include <86box/lpt.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/port_6x.h>
|
||||
#include <86box/machine.h>
|
||||
|
||||
|
||||
@@ -69,6 +70,10 @@ machine_at_common_init_ex(const machine_t *model, int type)
|
||||
pic2_init();
|
||||
dma16_init();
|
||||
|
||||
if (!(type & 4))
|
||||
device_add(&port_6x_device);
|
||||
type &= 3;
|
||||
|
||||
if (type == 1)
|
||||
device_add(&ibmat_nvr_device);
|
||||
else if (type == 0)
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/fdc_ext.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/port_6x.h>
|
||||
#include <86box/sio.h>
|
||||
#include <86box/serial.h>
|
||||
#include <86box/video.h>
|
||||
@@ -119,11 +120,11 @@ machine_at_ama932j_init(const machine_t *model)
|
||||
|
||||
machine_at_common_ide_init(model);
|
||||
|
||||
machine_at_headland_common_init(1);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&oti067_ama932j_device);
|
||||
|
||||
machine_at_headland_common_init(1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -141,7 +142,7 @@ machine_at_quadt286_init(const machine_t *model)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
device_add(&keyboard_at_device);
|
||||
device_add(&keyboard_at_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
@@ -152,6 +153,30 @@ machine_at_quadt286_init(const machine_t *model)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_quadt386sx_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_interleaved("roms/machines/quadt386sx/QTC-SXM-EVEN-U3-05-07.BIN",
|
||||
"roms/machines/quadt386sx/QTC-SXM-ODD-U3-05-07.BIN",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
device_add(&keyboard_at_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
device_add(&headland_gc10x_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_neat_init(const machine_t *model)
|
||||
{
|
||||
@@ -414,14 +439,14 @@ machine_at_spc4620p_init(const machine_t *model)
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&ati28800k_spc4620p_device);
|
||||
|
||||
machine_at_scat_init(model, 1);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&ati28800k_spc4620p_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -525,13 +550,13 @@ machine_at_wd76c10_init(const machine_t *model)
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(¶dise_wd90c11_megapc_device);
|
||||
|
||||
device_add(&keyboard_ps2_quadtel_device);
|
||||
|
||||
device_add(&wd76c10_device);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(¶dise_wd90c11_megapc_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -565,14 +590,17 @@ machine_at_cmdsl386sx16_init(const machine_t *model)
|
||||
|
||||
|
||||
static void
|
||||
machine_at_scamp_common_init(const machine_t *model)
|
||||
machine_at_scamp_common_init(const machine_t *model, int is_ps2)
|
||||
{
|
||||
machine_at_common_ide_init(model);
|
||||
|
||||
device_add(&keyboard_ps2_ami_device);
|
||||
if (is_ps2)
|
||||
device_add(&keyboard_ps2_ami_device);
|
||||
else
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
device_add(&vlsi_scamp_device);
|
||||
}
|
||||
@@ -596,11 +624,28 @@ machine_at_cmdsl386sx25_init(const machine_t *model)
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_scamp_common_init(model);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&gd5402_onboard_device);
|
||||
|
||||
machine_at_scamp_common_init(model, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_dataexpert386sx_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/dataexpert386sx/5e9f20e5ef967717086346.BIN",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_scamp_common_init(model, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -623,11 +668,11 @@ machine_at_spc6033p_init(const machine_t *model)
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_scamp_common_init(model);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&ati28800k_spc6033p_device);
|
||||
|
||||
machine_at_scamp_common_init(model, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -653,6 +698,49 @@ machine_at_awardsx_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_arb1374_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/arb1374/1374s.rom",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&ali1217_device);
|
||||
device_add(&w83787f_ide_en_device);
|
||||
device_add(&keyboard_ps2_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_sbc_350a_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/sbc_350a/350a.rom",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&ali1217_device);
|
||||
device_add(&fdc37c665_ide_device);
|
||||
device_add(&keyboard_at_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_flytech386_init(const machine_t *model)
|
||||
{
|
||||
@@ -668,38 +756,40 @@ machine_at_flytech386_init(const machine_t *model)
|
||||
|
||||
device_add(&ali1217_device);
|
||||
device_add(&w83787f_ide_en_device);
|
||||
device_add(&keyboard_ps2_device);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&tvga8900d_device);
|
||||
|
||||
device_add(&keyboard_ps2_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const device_t *
|
||||
at_flytech386_get_device(void)
|
||||
{
|
||||
return &tvga8900d_device;
|
||||
}
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_M6117)
|
||||
|
||||
int
|
||||
machine_at_arb1375_init(const machine_t *model)
|
||||
machine_at_mr1217_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/arb1375/a1375v25.u11-a",
|
||||
0x000e0000, 131072, 0);
|
||||
ret = bios_load_linear("roms/machines/mr1217/mrbios.BIN",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&fdc37c669_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&ali6117d_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
device_add(&ali1217_device);
|
||||
device_add(&fdc_at_device);
|
||||
device_add(&ide_isa_device);
|
||||
device_add(&keyboard_ps2_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -719,14 +809,36 @@ machine_at_pja511m_init(const machine_t *model)
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add_inst(&fdc37c669_device, 1);
|
||||
//device_add_inst(&fdc37c669_device, 2); /* enable when dual FDC37C669 is implemented */
|
||||
device_add_inst(&fdc37c669_device, 2);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&ali6117d_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
machine_at_prox1332_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/prox1332/D30B3AC1.BIN",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&fdc37c669_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&ali6117d_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Current bugs:
|
||||
@@ -753,6 +865,7 @@ machine_at_pc8_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Current bugs:
|
||||
* - ctrl-alt-del produces an 8042 error
|
||||
@@ -775,17 +888,19 @@ machine_at_3302_init(const machine_t *model)
|
||||
|
||||
machine_at_common_ide_init(model);
|
||||
device_add(&neat_device);
|
||||
device_add(&keyboard_at_ncr_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(¶dise_pvga1a_ncr3302_device);
|
||||
|
||||
device_add(&keyboard_at_ncr_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Current bugs:
|
||||
* - soft-reboot after saving CMOS settings/pressing ctrl-alt-del produces an 8042 error
|
||||
@@ -813,6 +928,7 @@ machine_at_pc916sx_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_OLIVETTI)
|
||||
int
|
||||
machine_at_m290_init(const machine_t *model)
|
||||
@@ -825,9 +941,10 @@ machine_at_m290_init(const machine_t *model)
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
machine_at_common_init_ex(model, 4);
|
||||
device_add(&keyboard_at_olivetti_device);
|
||||
|
||||
device_add(&port_6x_olivetti_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
@@ -836,58 +953,3 @@ machine_at_m290_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
const device_t *
|
||||
at_m30008_get_device(void)
|
||||
{
|
||||
return &oti067_m300_device;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_m30008_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/m30008/BIOS.ROM",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&opti283_device);
|
||||
device_add(&keyboard_ps2_olivetti_device);
|
||||
device_add(&pc87310_ide_device);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&oti067_m300_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Almost identical to M300-08, save for CPU speed, VRAM, and BIOS identification string */
|
||||
int
|
||||
machine_at_m30015_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/m30015/BIOS.ROM",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&opti283_device);
|
||||
device_add(&keyboard_ps2_olivetti_device);
|
||||
device_add(&pc87310_ide_device);
|
||||
|
||||
/* Stock VRAM is maxed out, so no need to expose video card config */
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&oti067_m300_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,12 +32,17 @@
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/fdc_ext.h>
|
||||
#include <86box/gameport.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/sio.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/port_6x.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/flash.h>
|
||||
#include <86box/scsi_ncr53c8xx.h>
|
||||
@@ -61,7 +66,7 @@ machine_at_acc386_init(const machine_t *model)
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -170,23 +175,25 @@ machine_at_valuepoint433_init(const machine_t *model) // hangs without the PS/2
|
||||
|
||||
machine_at_common_ide_init(model);
|
||||
device_add(&sis_85c461_device);
|
||||
device_add(&keyboard_ps2_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&et4000w32_onboard_device);
|
||||
|
||||
device_add(&keyboard_ps2_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const device_t *
|
||||
at_valuepoint433_get_device(void)
|
||||
{
|
||||
return &et4000w32_onboard_device;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_ecs386_init(const machine_t *model)
|
||||
{
|
||||
@@ -229,7 +236,7 @@ machine_at_spc6000a_init(const machine_t *model)
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
device_add(&keyboard_at_samsung_device);
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -297,7 +304,7 @@ machine_at_cs4031_init(const machine_t *model)
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -341,15 +348,16 @@ machine_at_vect486vl_init(const machine_t *model) // has HDC problems
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
machine_at_common_ide_init(model);
|
||||
|
||||
device_add(&vl82c480_device);
|
||||
device_add(&keyboard_ps2_ami_device);
|
||||
device_add(&fdc37c651_device);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&gd5428_onboard_device);
|
||||
|
||||
device_add(&keyboard_ps2_ami_device);
|
||||
device_add(&fdc37c651_ide_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -359,6 +367,7 @@ at_vect486vl_get_device(void)
|
||||
return &gd5428_onboard_device;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_d824_init(const machine_t *model)
|
||||
{
|
||||
@@ -373,48 +382,23 @@ machine_at_d824_init(const machine_t *model)
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&vl82c480_device);
|
||||
device_add(&keyboard_ps2_device);
|
||||
device_add(&fdc37c651_device);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&gd5428_onboard_device);
|
||||
|
||||
device_add(&keyboard_ps2_device);
|
||||
device_add(&fdc37c651_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const device_t *
|
||||
at_d824_get_device(void)
|
||||
{
|
||||
return &gd5428_onboard_device;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_pcs46c_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/pcs46c/OLIVETTI.BIN",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_ide_init(model);
|
||||
|
||||
device_add(&et6000_device);
|
||||
device_add(&keyboard_ps2_device);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&gd5428_onboard_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const device_t *
|
||||
at_pcs46c_get_device(void)
|
||||
{
|
||||
return &gd5428_onboard_device;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_acera1g_init(const machine_t *model)
|
||||
@@ -428,16 +412,16 @@ machine_at_acera1g_init(const machine_t *model)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
device_add(&ali1429g_device);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&gd5428_onboard_device);
|
||||
|
||||
device_add(&ali1429_device);
|
||||
device_add(&keyboard_ps2_acer_pci_device);
|
||||
device_add(&ide_isa_2ch_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -450,12 +434,62 @@ at_acera1g_get_device(void)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_acerv10_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/acerv10/ALL.BIN",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&sis_85c461_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&ide_isa_2ch_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_decpc_lpv_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/decpc_lpv/bios.bin-5f2c71ca0a0a5135083487.bin",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&sis_85c461_device);
|
||||
/* TODO: Phoenix MultiKey KBC */
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&ide_isa_2ch_device);
|
||||
device_add(&fdc37c663_device);
|
||||
/* TODO: On-board S3 805 with AT&T 490 RAM DAC. */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
machine_at_ali1429_common_init(const machine_t *model)
|
||||
machine_at_ali1429_common_init(const machine_t *model, int is_green)
|
||||
{
|
||||
machine_at_common_ide_init(model);
|
||||
|
||||
device_add(&ali1429_device);
|
||||
if (is_green)
|
||||
device_add(&ali1429g_device);
|
||||
else
|
||||
device_add(&ali1429_device);
|
||||
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
@@ -475,7 +509,7 @@ machine_at_ali1429_init(const machine_t *model)
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_ali1429_common_init(model);
|
||||
machine_at_ali1429_common_init(model, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -492,7 +526,7 @@ machine_at_winbios1429_init(const machine_t *model)
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_ali1429_common_init(model);
|
||||
machine_at_ali1429_common_init(model, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -569,6 +603,25 @@ machine_at_opti495_mr_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
machine_at_403tg_common_init(const machine_t *model, int nvr_hack)
|
||||
{
|
||||
if (nvr_hack) {
|
||||
machine_at_common_init_ex(model, 2);
|
||||
device_add(&ls486e_nvr_device);
|
||||
} else
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&opti895_device);
|
||||
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_403tg_init(const machine_t *model)
|
||||
{
|
||||
@@ -580,14 +633,41 @@ machine_at_403tg_init(const machine_t *model)
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
machine_at_403tg_common_init(model, 0);
|
||||
|
||||
device_add(&opti895_device);
|
||||
return ret;
|
||||
}
|
||||
|
||||
device_add(&keyboard_at_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
int
|
||||
machine_at_403tg_rev_d_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/403tg_rev_d/J403TGRevD.BIN",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_403tg_common_init(model, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_403tg_rev_d_mr_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/403tg_rev_d/MRBiosOPT895.bin",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_403tg_common_init(model, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -647,7 +727,7 @@ machine_at_sis_85c471_common_init(const machine_t *model)
|
||||
machine_at_common_init(model);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
device_add(&sis_85c471_device);
|
||||
}
|
||||
@@ -685,7 +765,7 @@ machine_at_vli486sv2g_init(const machine_t *model)
|
||||
|
||||
machine_at_sis_85c471_common_init(model);
|
||||
device_add(&ide_vlb_2ch_device);
|
||||
device_add(&keyboard_at_device);
|
||||
device_add(&keyboard_ps2_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -767,6 +847,30 @@ machine_at_vi15g_init(const machine_t *model)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_green_b_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/green-b/4gpv31-ami-1993-8273517.bin",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
device_add(&contaq_82c597_device);
|
||||
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
machine_at_sis_85c496_common_init(const machine_t *model)
|
||||
{
|
||||
@@ -884,7 +988,7 @@ machine_at_4dps_init(const machine_t *model)
|
||||
pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
|
||||
device_add(&w83787f_device);
|
||||
device_add(&keyboard_ps2_pci_device);
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
@@ -970,7 +1074,7 @@ machine_at_alfredo_init(const machine_t *model)
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4);
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4);
|
||||
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&keyboard_ps2_pci_device);
|
||||
device_add(&sio_device);
|
||||
device_add(&fdc37c663_device);
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
@@ -981,6 +1085,34 @@ machine_at_alfredo_init(const machine_t *model)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_ninja_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear_combined("roms/machines/ninja/1008AY0_.BIO",
|
||||
"roms/machines/ninja/1008AY0_.BI1", 0x1c000, 128);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1 | PCI_NO_IRQ_STEERING);
|
||||
pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 1, 2);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 2, 1);
|
||||
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 1, 2, 1);
|
||||
device_add(&keyboard_ps2_intel_ami_pci_device);
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
|
||||
device_add(&i420ex_device);
|
||||
device_add(&i82091aa_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_486sp3_init(const machine_t *model)
|
||||
{
|
||||
@@ -1015,6 +1147,68 @@ machine_at_486sp3_init(const machine_t *model)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_pci400c_b_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/pci400c-b/032295.ROM",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
device_add(&ide_isa_device);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 3, 2, 1); /* 0F = Slot 1 */
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 0E = Slot 2 */
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 0D = Slot 3 */
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 0C = Slot 4 */
|
||||
device_add(&keyboard_ps2_ami_pci_device); /* Assume AMI Megakey 1993 stanalone ('P')
|
||||
because of the Tekram machine below. */
|
||||
|
||||
device_add(&ims8848_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_g486ip_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/g486ip/G486IP.BIN",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
device_add(&ide_isa_device);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 03 = Slot 1 */
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 04 = Slot 2 */
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 05 = Slot 3 */
|
||||
device_add(&keyboard_ps2_ami_pci_device); /* AMI Megakey 1993 stanalone ('P') */
|
||||
|
||||
device_add(&ims8848_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_486sp3g_init(const machine_t *model)
|
||||
{
|
||||
@@ -1071,7 +1265,7 @@ machine_at_486ap4_init(const machine_t *model)
|
||||
device_add(&keyboard_ps2_ami_pci_device); /* Uses the AMIKEY KBC */
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
device_add(&i420ex_device);
|
||||
|
||||
@@ -1079,6 +1273,36 @@ machine_at_486ap4_init(const machine_t *model)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_g486vpa_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/g486vpa/3.BIN",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
|
||||
device_add(&via_vt82c49x_pci_ide_device);
|
||||
device_add(&via_vt82c505_device);
|
||||
device_add(&pc87332_398_ide_sec_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_486vipio2_init(const machine_t *model)
|
||||
{
|
||||
@@ -1166,11 +1390,11 @@ machine_at_win486pci_init(const machine_t *model)
|
||||
|
||||
|
||||
int
|
||||
machine_at_atc1415_init(const machine_t *model)
|
||||
machine_at_ms4145_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/atc1415/1415V330.ROM",
|
||||
ret = bios_load_linear("roms/machines/ms4145/AG56S.ROM",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
@@ -1179,29 +1403,27 @@ machine_at_atc1415_init(const machine_t *model)
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0c, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
|
||||
device_add(&umc_hb4_device);
|
||||
device_add(&umc_8886af_device);
|
||||
device_add(&ali1489_device);
|
||||
device_add(&w83787f_device);
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_ecs486_init(const machine_t *model)
|
||||
machine_at_sbc_490_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/ecs486/8810AIO.32J",
|
||||
ret = bios_load_linear("roms/machines/sbc-490/07159589.rom",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
@@ -1210,29 +1432,39 @@ machine_at_ecs486_init(const machine_t *model)
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0c, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0d, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0e, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x0f, PCI_CARD_IDE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x01, PCI_CARD_VIDEO, 4, 1, 2, 3);
|
||||
|
||||
device_add(&umc_hb4_device);
|
||||
device_add(&umc_8886f_device);
|
||||
device_add(&ide_cmd640_pci_legacy_only_device);
|
||||
device_add(&ali1489_device);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&tgui9440_onboard_pci_device);
|
||||
|
||||
device_add(&keyboard_ps2_ami_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const device_t *
|
||||
at_sbc_490_get_device(void)
|
||||
{
|
||||
return &tgui9440_onboard_pci_device;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_hot433_init(const machine_t *model)
|
||||
machine_at_tf_486_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/hot433/433AUS33.ROM",
|
||||
ret = bios_load_linear("roms/machines/tf-486/tf486v10.BIN",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
@@ -1241,18 +1473,13 @@ machine_at_hot433_init(const machine_t *model)
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0c, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0d, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x0e, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x0f, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
|
||||
device_add(&umc_hb4_device);
|
||||
device_add(&umc_8886af_device);
|
||||
device_add(&um8669f_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
device_add(&keyboard_at_ami_device);
|
||||
device_add(&ali1489_device);
|
||||
device_add(&w83977ef_device);
|
||||
device_add(&keyboard_ps2_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1288,6 +1515,34 @@ machine_at_itoxstar_init(const machine_t *model)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_arb1423c_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/arb1423c/A1423C.v12",
|
||||
0x000c0000, 262144, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x1F, PCI_CARD_NORMAL, 1, 0, 0, 0);
|
||||
pci_register_slot(0x1E, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x1D, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
device_add(&w83977f_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&stpc_consumer2_device);
|
||||
device_add(&winbond_flash_w29c020_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_arb1479_init(const machine_t *model)
|
||||
{
|
||||
@@ -1372,3 +1627,191 @@ machine_at_pcm5330_init(const machine_t *model)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_ecs486_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/ecs486/8810AIO.32J",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0F, PCI_CARD_IDE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
|
||||
device_add(&umc_hb4_device);
|
||||
device_add(&umc_8886f_device);
|
||||
device_add(&ide_cmd640_pci_legacy_only_device);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_hot433_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/hot433/433AUS33.ROM",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
|
||||
device_add(&umc_hb4_device);
|
||||
device_add(&umc_8886af_device);
|
||||
device_add(&um8669f_device);
|
||||
// device_add(&intel_flash_bxt_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
// device_add(&keyboard_at_ami_device);
|
||||
device_add(&keyboard_ps2_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_atc1415_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/atc1415/1415V330.ROM",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
|
||||
device_add(&umc_hb4_device);
|
||||
device_add(&umc_8886af_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_actionpc2600_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/actionpc2600/action2600.BIN",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
|
||||
device_add(&umc_hb4_device);
|
||||
device_add(&umc_8886af_device);
|
||||
device_add(&um8669f_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_m919_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/m919/9190914s.rom",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
|
||||
device_add(&umc_hb4_device);
|
||||
device_add(&umc_8886af_device);
|
||||
device_add(&um8669f_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_spc7700p_lw_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/spc7700p-lw/77LW13FH.P24",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
|
||||
device_add(&umc_hb4_device);
|
||||
device_add(&umc_8886af_device);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -810,8 +810,6 @@ at_cpqiii_get_device(void)
|
||||
static void
|
||||
machine_at_compaq_init(const machine_t *model, int type)
|
||||
{
|
||||
machine_at_init(model);
|
||||
|
||||
if (type != COMPAQ_DESKPRO386)
|
||||
mem_remap_top(384);
|
||||
|
||||
@@ -846,6 +844,8 @@ machine_at_compaq_init(const machine_t *model, int type)
|
||||
device_add(&ide_isa_device);
|
||||
break;
|
||||
}
|
||||
|
||||
machine_at_init(model);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -68,7 +68,6 @@ machine_at_vpc2007_init(const machine_t *model)
|
||||
device_add(&w83977f_370_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
device_add(&vpc2007_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0xF, 256); /* real VPC provides invalid SPD data */
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -489,37 +489,6 @@ at_tsunamiatx_get_device(void)
|
||||
return &es1371_onboard_device;
|
||||
}
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(NO_SIO)
|
||||
int
|
||||
machine_at_ergox365_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/ergox365/M63v115.rom",
|
||||
0x00080000, 524288, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init_ex(model, 2);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x08, PCI_CARD_VIDEO, 3, 0, 0, 0);
|
||||
device_add(&i440bx_device);
|
||||
device_add(&piix4e_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&fdc37c665_device); /* Placeholder for the SM(S)C FDC37C675 */
|
||||
device_add(&sst_flash_39sf040_device); /* Placeholder for the Intel 28F004 flash chip */
|
||||
spd_register(SPD_TYPE_SDRAM, 0xF, 256);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
machine_at_ficka6130_init(const machine_t *model)
|
||||
@@ -651,8 +620,10 @@ machine_at_vei8_init(const machine_t *model)
|
||||
device_add(&piix4e_device);
|
||||
device_add(&fdc37m60x_370_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(ics9xxx_get(ICS9250_08));
|
||||
device_add(&sst_flash_39sf020_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x3, 512);
|
||||
device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -674,13 +645,14 @@ machine_at_ms6168_common_init(const machine_t *model)
|
||||
device_add(&i440zx_device);
|
||||
device_add(&piix4e_device);
|
||||
device_add(&w83977ef_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x3, 256);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&voodoo_3_2000_agp_onboard_8m_device);
|
||||
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x3, 256);
|
||||
|
||||
if (sound_card_current == SOUND_INTERNAL) {
|
||||
device_add(&es1371_onboard_device);
|
||||
device_add(&cs4297_device);
|
||||
@@ -724,3 +696,36 @@ machine_at_ms6168_init(const machine_t *model)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_m729_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/m729/M729NEW.BIN",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init_ex(model, 2);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
device_add(&ali1621_device);
|
||||
device_add(&ali1543c_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x3, 128);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ machine_at_trinity371_init(const machine_t *model)
|
||||
device_add(&i440bx_device);
|
||||
device_add(&piix4e_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&w83977f_370_device);
|
||||
device_add(&w83977ef_370_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
return ret;
|
||||
|
||||
471
src/machine/m_at_socket4.c
Normal file
471
src/machine/m_at_socket4.c
Normal file
@@ -0,0 +1,471 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of Socket 4 machines.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2010-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/fdc_ext.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/flash.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/scsi_ncr53c8xx.h>
|
||||
#include <86box/sio.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/machine.h>
|
||||
|
||||
|
||||
void
|
||||
machine_at_premiere_common_init(const machine_t *model, int pci_switch)
|
||||
{
|
||||
machine_at_common_init(model);
|
||||
device_add(&ide_pci_2ch_device);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_2 | pci_switch);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x01, PCI_CARD_IDE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4);
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4);
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4);
|
||||
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
device_add(&keyboard_ps2_intel_ami_pci_device);
|
||||
device_add(&sio_zb_device);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_award_common_init(const machine_t *model)
|
||||
{
|
||||
machine_at_common_init(model);
|
||||
device_add(&ide_pci_2ch_device);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x01, PCI_CARD_IDE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 03 = Slot 1 */
|
||||
pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 04 = Slot 2 */
|
||||
pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 05 = Slot 3 */
|
||||
pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 06 = Slot 4 */
|
||||
pci_register_slot(0x07, PCI_CARD_SCSI, 1, 2, 3, 4); /* 07 = SCSI */
|
||||
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
// device_add(&keyboard_ps2_pci_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_sp4_common_init(const machine_t *model)
|
||||
{
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
/* Excluded: 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F, 10, 11, 12, 13, 14 */
|
||||
pci_register_slot(0x0D, PCI_CARD_IDE, 1, 2, 3, 4);
|
||||
/* Excluded: 02, 03*, 04*, 05*, 06*, 07*, 08* */
|
||||
/* Slots: 09 (04), 0A (03), 0B (02), 0C (07) */
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
device_add(&sis_85c50x_device);
|
||||
device_add(&ide_cmd640_pci_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_excalibur_pci_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear_inverted("roms/machines/excalibur_pci/S701P.ROM",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_2);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x03, PCI_CARD_IDE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&ide_cmd640_pci_legacy_only_device);
|
||||
|
||||
device_add(&i430lx_device);
|
||||
device_add(&sio_zb_device);
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_p5mp3_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/p5mp3/0205.bin",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
device_add(&ide_pci_device);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x05, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 05 = Slot 1 */
|
||||
pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 04 = Slot 2 */
|
||||
pci_register_slot(0x03, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 03 = Slot 3 */
|
||||
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
device_add(&fdc_at_device);
|
||||
device_add(&keyboard_ps2_pci_device);
|
||||
|
||||
device_add(&sio_zb_device);
|
||||
device_add(&catalyst_flash_device);
|
||||
device_add(&i430lx_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_dellxp60_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear_inverted("roms/machines/dellxp60/XP60-A08.ROM",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
device_add(&ide_pci_2ch_device);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_2);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
/* Not: 00, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F. */
|
||||
/* Yes: 01, 10, 11, 12, 13, 14. */
|
||||
pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 3, 2, 4);
|
||||
pci_register_slot(0x04, PCI_CARD_NORMAL, 4, 4, 3, 3);
|
||||
pci_register_slot(0x05, PCI_CARD_NORMAL, 1, 4, 3, 2);
|
||||
pci_register_slot(0x06, PCI_CARD_NORMAL, 2, 1, 3, 4);
|
||||
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
device_add(&i430lx_device);
|
||||
device_add(&keyboard_ps2_intel_ami_pci_device);
|
||||
device_add(&sio_zb_device);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_opti560l_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear_inverted("roms/machines/opti560l/560L_A06.ROM",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
device_add(&ide_pci_2ch_device);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_2);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x03, PCI_CARD_NORMAL, 4, 4, 3, 3);
|
||||
pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 4, 3, 2);
|
||||
pci_register_slot(0x08, PCI_CARD_NORMAL, 2, 1, 3, 4);
|
||||
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
device_add(&i430lx_device);
|
||||
device_add(&keyboard_ps2_intel_ami_pci_device);
|
||||
device_add(&sio_zb_device);
|
||||
device_add(&i82091aa_device);
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_ambradp60_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear_combined("roms/machines/ambradp60/1004AF1P.BIO",
|
||||
"roms/machines/ambradp60/1004AF1P.BI1", 0x1c000, 128);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_premiere_common_init(model, 0);
|
||||
|
||||
device_add(&i430lx_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_valuepointp60_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear_combined("roms/machines/valuepointp60/1006AV0M.BIO",
|
||||
"roms/machines/valuepointp60/1006AV0M.BI1", 0x1d000, 128);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
device_add(&ide_pci_2ch_device);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x01, PCI_CARD_IDE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4);
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4);
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4);
|
||||
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
device_add(&keyboard_ps2_ps1_pci_device);
|
||||
device_add(&sio_device);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
|
||||
device_add(&i430lx_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_revenge_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear_combined("roms/machines/revenge/1009af2_.bio",
|
||||
"roms/machines/revenge/1009af2_.bi1", 0x1c000, 128);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_premiere_common_init(model, 0);
|
||||
|
||||
device_add(&i430lx_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_586mc1_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/586mc1/IS.34",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_award_common_init(model);
|
||||
|
||||
device_add(&sio_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
device_add(&i430lx_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_pb520r_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear_combined("roms/machines/pb520r/1009bc0r.bio",
|
||||
"roms/machines/pb520r/1009bc0r.bi1", 0x1c000, 128);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_2);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x01, PCI_CARD_IDE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x03, PCI_CARD_VIDEO, 3, 3, 3, 3);
|
||||
pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4);
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4);
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4);
|
||||
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
device_add(&i430lx_device);
|
||||
device_add(&ide_cmd640_pci_single_channel_device);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&gd5434_onboard_pci_device);
|
||||
|
||||
device_add(&keyboard_ps2_pci_device);
|
||||
device_add(&sio_zb_device);
|
||||
device_add(&i82091aa_ide_device);
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const device_t *
|
||||
at_pb520r_get_device(void)
|
||||
{
|
||||
return &gd5434_onboard_pci_device;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_excalibur_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear_inverted("roms/machines/excalibur/S75P.ROM",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&opti5x7_device);
|
||||
device_add(&ide_opti611_vlb_device);
|
||||
device_add(&fdc37c661_device);
|
||||
device_add(&keyboard_ps2_intel_ami_pci_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_p5vl_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/p5vl/SM507.ROM",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
device_add(&opti5x7_device);
|
||||
device_add(&opti822_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_excalibur_pci_2_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear_inverted("roms/machines/excalibur_pci-2/S722P.ROM",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x08, PCI_CARD_IDE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&ide_cmd640_pci_legacy_only_device);
|
||||
|
||||
device_add(&sis_85c50x_device);
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_p5sp4_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/p5sp4/0106.001",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_sp4_common_init(model);
|
||||
|
||||
return ret;
|
||||
}
|
||||
446
src/machine/m_at_socket5.c
Normal file
446
src/machine/m_at_socket5.c
Normal file
@@ -0,0 +1,446 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of Socket 5 machines.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2010-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/fdc_ext.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/flash.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/scsi_ncr53c8xx.h>
|
||||
#include <86box/sio.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/machine.h>
|
||||
|
||||
|
||||
int
|
||||
machine_at_plato_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear_combined("roms/machines/plato/1016ax1_.bio",
|
||||
"roms/machines/plato/1016ax1_.bi1", 0x1d000, 128);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_premiere_common_init(model, PCI_CAN_SWITCH_TYPE);
|
||||
|
||||
device_add(&i430nx_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_ambradp90_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear_combined("roms/machines/ambradp90/1002AX1P.BIO",
|
||||
"roms/machines/ambradp90/1002AX1P.BI1", 0x1d000, 128);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_premiere_common_init(model, PCI_CAN_SWITCH_TYPE);
|
||||
|
||||
device_add(&i430nx_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_430nx_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/430nx/IP.20",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_award_common_init(model);
|
||||
|
||||
device_add(&sio_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
device_add(&i430nx_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_acerv30_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/acerv30/V30R01N9.BIN",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
device_add(&i430fx_device);
|
||||
device_add(&piix_device);
|
||||
device_add(&keyboard_ps2_acer_pci_device);
|
||||
device_add(&fdc37c665_device);
|
||||
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_apollo_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/apollo/S728P.ROM",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init_ex(model, 2);
|
||||
device_add(&ami_apollo_nvr_device);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&i430fx_device);
|
||||
device_add(&piix_device);
|
||||
device_add(&pc87332_398_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_exp8551_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/exp8551/AMI20.BIO",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&i430fx_device);
|
||||
device_add(&piix_device);
|
||||
device_add(&w83787f_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_vectra54_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/vectra54/GT0724.22",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init_ex(model, 2);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0D, PCI_CARD_VIDEO, 0, 0, 0, 0);
|
||||
pci_register_slot(0x06, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x07, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x08, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&s3_phoenix_trio64_onboard_pci_device);
|
||||
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&i430fx_device);
|
||||
device_add(&piix_device);
|
||||
device_add(&fdc37c931apm_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_zappa_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear_combined("roms/machines/zappa/1006bs0_.bio",
|
||||
"roms/machines/zappa/1006bs0_.bi1", 0x20000, 128);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
device_add(&keyboard_ps2_intel_ami_pci_device);
|
||||
device_add(&i430fx_device);
|
||||
device_add(&piix_device);
|
||||
device_add(&pc87306_device);
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_powermatev_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/powermatev/BIOS.ROM",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x08, PCI_CARD_NORMAL, 0, 0, 0, 0);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&i430fx_device);
|
||||
device_add(&piix_device);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_mb500n_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/mb500n/031396s.bin",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
device_add(&keyboard_ps2_pci_device);
|
||||
device_add(&i430fx_device);
|
||||
device_add(&piix_device);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_hawk_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/hawk/HAWK.ROM",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&i430fx_device);
|
||||
device_add(&piix_device);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_pat54pv_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/pat54pv/pat54pv.bin",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&opti5x7_device);
|
||||
device_add(&keyboard_ps2_intel_ami_pci_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_hot543_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/hot543/543_R21.BIN",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
device_add(&opti5x7_device);
|
||||
device_add(&opti822_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
device_add(&keyboard_at_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_p54sp4_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/p54sp4/SI5I0204.AWD",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_sp4_common_init(model);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_sq588_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/sq588/sq588b03.rom",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
/* Correct: 0D (01), 0F (02), 11 (03), 13 (04) */
|
||||
pci_register_slot(0x02, PCI_CARD_IDE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
device_add(&sis_85c50x_device);
|
||||
device_add(&ide_cmd640_pci_single_channel_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&fdc37c665_ide_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
554
src/machine/m_at_socket7_3v.c
Normal file
554
src/machine/m_at_socket7_3v.c
Normal file
@@ -0,0 +1,554 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of Socket 7 (Single Voltage) machines.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Melissa Goad, <mszoopers@protonmail.com>
|
||||
*
|
||||
* Copyright 2010-2020 Sarah Walker.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/flash.h>
|
||||
#include <86box/sio.h>
|
||||
#include <86box/hwm.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/spd.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/machine.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/nvr.h>
|
||||
|
||||
|
||||
static void
|
||||
machine_at_thor_common_init(const machine_t *model, int mr)
|
||||
{
|
||||
machine_at_common_init_ex(model, mr);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0);
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 2, 1);
|
||||
pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 3, 2, 1);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&s3_phoenix_trio64vplus_onboard_pci_device);
|
||||
|
||||
// device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&keyboard_ps2_intel_ami_pci_device);
|
||||
device_add(&i430fx_device);
|
||||
device_add(&piix_device);
|
||||
device_add(&pc87306_device);
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_p54tp4xe_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/p54tp4xe/t15i0302.awd",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
/* Award BIOS, SMC FDC37C665. */
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
device_add(&keyboard_ps2_pci_device);
|
||||
device_add(&i430fx_device);
|
||||
device_add(&piix_device);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_mr586_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/mr586/TRITON.BIO",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
|
||||
device_add(&i430fx_device);
|
||||
device_add(&piix_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_gw2katx_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear_combined("roms/machines/gw2katx/1003cn0t.bio",
|
||||
"roms/machines/gw2katx/1003cn0t.bi1", 0x20000, 128);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_thor_common_init(model, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_thor_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear_combined("roms/machines/thor/1006cn0_.bio",
|
||||
"roms/machines/thor/1006cn0_.bi1", 0x20000, 128);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_thor_common_init(model, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const device_t *
|
||||
at_thor_get_device(void)
|
||||
{
|
||||
return &s3_phoenix_trio64vplus_onboard_pci_device;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_mrthor_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/mrthor/mr_atx.bio",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_thor_common_init(model, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_endeavor_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear_combined("roms/machines/endeavor/1006cb0_.bio",
|
||||
"roms/machines/endeavor/1006cb0_.bi1", 0x1d000, 128);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0);
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&s3_phoenix_trio64_onboard_pci_device);
|
||||
|
||||
device_add(&keyboard_ps2_intel_ami_pci_device);
|
||||
device_add(&i430fx_device);
|
||||
device_add(&piix_device);
|
||||
device_add(&pc87306_device);
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const device_t *
|
||||
at_endeavor_get_device(void)
|
||||
{
|
||||
return &s3_phoenix_trio64_onboard_pci_device;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_ms5119_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/ms5119/A37E.ROM",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0d, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0e, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0f, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
|
||||
device_add(&i430fx_device);
|
||||
device_add(&piix_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&w83787f_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_pb640_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear_combined("roms/machines/pb640/1007CP0R.BIO",
|
||||
"roms/machines/pb640/1007CP0R.BI1", 0x1d000, 128);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 3, 4);
|
||||
pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 2, 1, 4);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
device_add(&i430fx_rev02_device);
|
||||
device_add(&piix_rev02_device);
|
||||
|
||||
if (gfxcard == VID_INTERNAL)
|
||||
device_add(&gd5440_onboard_pci_device);
|
||||
|
||||
device_add(&keyboard_ps2_intel_ami_pci_device);
|
||||
device_add(&pc87306_device);
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const device_t *
|
||||
at_pb640_get_device(void)
|
||||
{
|
||||
return &gd5440_onboard_pci_device;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_fmb_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/fmb/P5IV183.ROM",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 2, 1);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 3, 2, 1);
|
||||
|
||||
device_add(&i430fx_device);
|
||||
device_add(&piix_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&w83787f_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_acerm3a_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/acerm3a/r01-b3.bin",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x10, PCI_CARD_VIDEO, 4, 0, 0, 0);
|
||||
device_add(&i430hx_device);
|
||||
device_add(&piix3_device);
|
||||
device_add(&keyboard_ps2_pci_device);
|
||||
device_add(&fdc37c932fr_device);
|
||||
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_ap53_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/ap53/ap53r2c0.rom",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x06, PCI_CARD_VIDEO, 1, 2, 3, 4);
|
||||
device_add(&i430hx_device);
|
||||
device_add(&piix3_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&fdc37c669_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_8500tuc_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/8500tuc/Tuc0221b.rom",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
device_add(&i430hx_device);
|
||||
device_add(&piix3_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&um8669f_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_p55t2s_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/p55t2s/s6y08t.rom",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
device_add(&i430hx_device);
|
||||
device_add(&piix3_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&pc87306_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_p5vxb_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/p5vxb/P5VXB10.BIN",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x05, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x06, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x08, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4);
|
||||
device_add(&i430vx_device);
|
||||
device_add(&piix3_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&w83877f_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_gw2kte_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear_combined2("roms/machines/gw2kte/1008CY1T.BIO",
|
||||
"roms/machines/gw2kte/1008CY1T.BI1",
|
||||
"roms/machines/gw2kte/1008CY1T.BI2",
|
||||
"roms/machines/gw2kte/1008CY1T.BI3",
|
||||
"roms/machines/gw2kte/1008CY1T.RCV",
|
||||
0x3a000, 128);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0);
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4);
|
||||
device_add(&i430vx_device);
|
||||
device_add(&piix3_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&fdc37c932fr_device);
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_ap5s_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/ap5s/AP5S150.BIN",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 2, 1);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 3, 2, 1);
|
||||
|
||||
device_add(&sis_5511_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -30,6 +30,8 @@
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/flash.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/sio.h>
|
||||
#include <86box/hwm.h>
|
||||
#include <86box/spd.h>
|
||||
@@ -37,7 +39,7 @@
|
||||
#include "cpu.h"
|
||||
#include <86box/machine.h>
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_I450KX)
|
||||
|
||||
int
|
||||
machine_at_p6rp4_init(const machine_t *model)
|
||||
{
|
||||
@@ -49,11 +51,12 @@ machine_at_p6rp4_init(const machine_t *model)
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
machine_at_common_init_ex(model, 2);
|
||||
device_add(&p6rp4_nvr_device);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x19, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x12, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x14, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x08, PCI_CARD_IDE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
@@ -62,14 +65,15 @@ machine_at_p6rp4_init(const machine_t *model)
|
||||
pci_register_slot(0x04, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
device_add(&i450kx_device);
|
||||
device_add(&sio_zb_device);
|
||||
device_add(&ide_cmd646_device);
|
||||
/* Input port bit 2 must be 1 or CMOS Setup is disabled. */
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&ide_cmd640_pci_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
machine_at_686nx_init(const machine_t *model)
|
||||
|
||||
@@ -41,6 +41,145 @@
|
||||
#include "cpu.h"
|
||||
#include <86box/machine.h>
|
||||
#include <86box/snd_ac97.h>
|
||||
#include <86box/clock.h>
|
||||
|
||||
|
||||
int
|
||||
machine_at_p5a_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/p5a/1011.005",
|
||||
0x000c0000, 262144, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init_ex(model, 2);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
device_add(&ali1541_device);
|
||||
device_add(&ali1543c_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&sst_flash_39sf020_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0xF, 256);
|
||||
device_add(&w83781d_p5a_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_m579_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/m579/MS6260S_Socket7_ALi_M1542_AMI.BIN",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init_ex(model, 2);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
device_add(&ali1541_device);
|
||||
device_add(&ali1543c_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x3, 128);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_ga_5aa_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/ga-5aa/GA-5AA.F7b",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init_ex(model, 2);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
device_add(&ali1541_device);
|
||||
device_add(&ali1543c_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x3, 128);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_ga_5ax_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/ga-5ax/5AX.F4",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init_ex(model, 2);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
device_add(&ali1541_device);
|
||||
device_add(&ali1543c_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x3, 128);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
@@ -145,3 +284,44 @@ machine_at_ficva503a_init(const machine_t *model)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_sy_5ema_pro_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/sy-5ema_pro/5emo1aa2.bin",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init_ex(model, 2);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 4);
|
||||
pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
|
||||
|
||||
device_add(&via_mvp3_device);
|
||||
device_add(&via_vt82c686a_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
// device_add(&via_vt82c686_sio_device);
|
||||
device_add(&fdc37c669_device);
|
||||
device_add(&sst_flash_39sf010_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
|
||||
device_add(&via_vt82c686_hwm_device); /* fans: CPU1, Chassis; temperatures: CPU, System, unused */
|
||||
hwm_values.temperatures[0] += 2; /* CPU offset */
|
||||
hwm_values.temperatures[1] += 2; /* System offset */
|
||||
hwm_values.temperatures[2] = 0; /* unused */
|
||||
|
||||
device_add(&wm9701a_device); /* on daughtercard */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -867,7 +867,7 @@ machine_pcjr_init(const machine_t *model)
|
||||
device_add(&fdc_pcjr_device);
|
||||
|
||||
device_add(&i8250_pcjr_device);
|
||||
serial_set_next_inst(2); /* So that serial_standalone_init() won't do anything. */
|
||||
serial_set_next_inst(MAX_SERIAL); /* So that serial_standalone_init() won't do anything. */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/port_6x.h>
|
||||
#include <86box/sound.h>
|
||||
#include <86box/snd_sn76489.h>
|
||||
#include <86box/video.h>
|
||||
@@ -514,6 +515,7 @@ ps1_common_init(const machine_t *model)
|
||||
pic2_init();
|
||||
|
||||
device_add(&keyboard_ps2_ps1_device);
|
||||
device_add(&port_6x_device);
|
||||
|
||||
/* Audio uses ports 200h and 202-207h, so only initialize gameport on 201h. */
|
||||
standalone_gameport_type = &gameport_201_device;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user