Merge branch 'master' of https://github.com/86Box/86Box.git into EngiNerd

This commit is contained in:
EngiNerd89
2021-01-23 19:03:36 +01:00
29 changed files with 2233 additions and 99 deletions

View File

@@ -57,6 +57,7 @@ CMAKE_DEPENDENT_OPTION(S3TRIO3D2X "S3 Trio3D/2X" ON "DEV_BRANCH" OFF)
CMAKE_DEPENDENT_OPTION(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF)
CMAKE_DEPENDENT_OPTION(STPC "STPC machines" ON "DEV_BRANCH" OFF)
CMAKE_DEPENDENT_OPTION(M1489 "ALi M1489" ON "DEV_BRANCH" OFF)
CMAKE_DEPENDENT_OPTION(M154X "ALi ALADDiN IV" ON "DEV_BRANCH" OFF)
CMAKE_DEPENDENT_OPTION(M6117 "ALi M6117" ON "DEV_BRANCH" OFF)
CMAKE_DEPENDENT_OPTION(VGAWONDER "ATI VGA Wonder (ATI-18800)" ON "DEV_BRANCH" OFF)
CMAKE_DEPENDENT_OPTION(VNC "VNC renderer" ON "DEV_BRANCH" OFF)

View File

@@ -97,7 +97,7 @@ acpi_raise_smi(void *priv)
smi_line = 1;
dev->regs.smi_active = 1;
}
} else if (dev->vendor == VEN_INTEL) {
} else if ((dev->vendor == VEN_INTEL) || (dev->vendor == VEN_ALI)) {
smi_line = 1;
/* Clear bit 16 of GLBCTL. */
dev->regs.glbctl &= ~0x00010000;
@@ -152,6 +152,72 @@ acpi_reg_read_common_regs(int size, uint16_t addr, void *p)
return ret;
}
static uint32_t
acpi_reg_read_ali(int size, uint16_t addr, void *p)
{
acpi_t *dev = (acpi_t *) p;
uint32_t ret = 0x00000000;
int shift16, shift32;
addr &= 0x3f;
shift16 = (addr & 1) << 3;
shift32 = (addr & 3) << 3;
switch(addr)
{
case 0x10: case 0x11: case 0x12: case 0x13:
/* PCNTRL - Processor Control Register (IO) */
ret = (dev->regs.pcntrl >> shift16) & 0xff;
break;
case 0x14:
/* LVL2 - Processor Level 2 Register */
ret = dev->regs.plvl2;
break;
case 0x15:
/* LVL3 - Processor Level 3 Register */
ret = dev->regs.plvl3;
break;
case 0x18: case 0x19:
/* GPE0_STS - General Purpose Event0 Status Register */
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;
case 0x1d: case 0x1c:
/* GPE1_STS - General Purpose Event1 Status Register */
ret = (dev->regs.gpsts >> 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:
/* GPE1_CTL - General Purpose Event1 Control Register */
ret = (dev->regs.gpcntrl >> shift32) & 0xff;
break;
case 0x30:
/* PM2_CNTRL - Power Management 2 Control Register( */
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);
#endif
return ret;
}
static uint32_t
acpi_reg_read_intel(int size, uint16_t addr, void *p)
@@ -518,6 +584,76 @@ acpi_reg_write_common_regs(int size, uint16_t addr, uint8_t val, void *p)
}
}
static void
acpi_reg_write_ali(int size, uint16_t addr, uint8_t val, void *p)
{
acpi_t *dev = (acpi_t *) p;
int shift16, shift32;
addr &= 0x3f;
#ifdef ENABLE_ACPI_LOG
if (size != 1)
acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val);
#endif
shift16 = (addr & 1) << 3;
shift32 = (addr & 3) << 3;
switch (addr) {
case 0x10: case 0x11: case 0x12: case 0x13:
/* PCNTRL - Processor Control Register (IO) */
dev->regs.pcntrl = ((dev->regs.pcntrl & ~(0xff << shift32)) | (val << shift32)) & 0x00023e1e;
break;
case 0x14:
/* LVL2 - Processor Level 2 Register */
dev->regs.plvl2 = val;
break;
case 0x15:
/* LVL3 - Processor Level 3 Register */
dev->regs.plvl3 = val;
break;
case 0x18: case 0x19:
/* GPE0_STS - General Purpose Event0 Status Register */
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;
case 0x1d: case 0x1c:
/* GPE1_STS - General Purpose Event1 Status Register */
dev->regs.gpsts &= ~((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:
/* GPE1_CTL - General Purpose Event1 Control Register */
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;
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;
else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) {
dev->regs.glbsts |= 0x01;
if (dev->regs.glben & 0x02)
acpi_raise_smi(dev);
}
}
}
static void
acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p)
@@ -823,7 +959,9 @@ acpi_reg_read_common(int size, uint16_t addr, void *p)
acpi_t *dev = (acpi_t *) p;
uint8_t ret = 0xff;
if (dev->vendor == VEN_VIA)
if (dev->vendor == VEN_ALI)
ret = acpi_reg_read_ali(size, addr, p);
else if (dev->vendor == VEN_VIA)
ret = acpi_reg_read_via(size, addr, p);
else if (dev->vendor == VEN_VIA_596B)
ret = acpi_reg_read_via_596b(size, addr, p);
@@ -841,6 +979,8 @@ acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *p)
{
acpi_t *dev = (acpi_t *) p;
if (dev->vendor == VEN_ALI)
acpi_reg_write_ali(size, addr, val, p);
if (dev->vendor == VEN_VIA)
acpi_reg_write_via(size, addr, val, p);
else if (dev->vendor == VEN_VIA_596B)
@@ -1021,6 +1161,7 @@ acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en)
int size;
switch (dev->vendor) {
case VEN_ALI:
case VEN_INTEL:
default:
size = 0x040;
@@ -1173,7 +1314,7 @@ acpi_apm_out(uint16_t port, uint8_t val, void *p)
if (port == 0x0000) {
dev->apm->cmd = val;
if (dev->apm->do_smi) {
if (dev->vendor == VEN_INTEL)
if ((dev->vendor == VEN_INTEL) || (dev->vendor == VEN_ALI))
dev->regs.glbsts |= 0x20;
acpi_raise_smi(dev);
}
@@ -1285,7 +1426,7 @@ acpi_init(const device_t *info)
dev->irq_line = 9;
if (dev->vendor == VEN_INTEL) {
if ((dev->vendor == VEN_INTEL) || (dev->vendor == VEN_ALI)) {
dev->apm = device_add(&apm_pci_acpi_device);
io_sethandler(0x00b2, 0x0002, acpi_apm_in, NULL, NULL, acpi_apm_out, NULL, NULL, dev);
} else if (dev->vendor == VEN_VIA) {
@@ -1301,6 +1442,19 @@ acpi_init(const device_t *info)
return dev;
}
const device_t acpi_ali_device =
{
"ALi M7101 ACPI",
DEVICE_PCI,
VEN_ALI,
acpi_init,
acpi_close,
acpi_reset,
{ NULL },
acpi_speed_changed,
NULL,
NULL
};
const device_t acpi_intel_device =
{

View File

@@ -13,11 +13,11 @@
# Copyright 2020,2021 David Hrdlička.
#
add_library(chipset OBJECT acc2168.c cs8230.c ali1429.c headland.c intel_82335.c
add_library(chipset OBJECT acc2168.c cs8230.c ali1217.c ali1429.c headland.c intel_82335.c
cs4031.c intel_420ex.c intel_4x0.c intel_sio.c intel_piix.c ../ioapic.c
neat.c opti495.c opti895.c opti5x7.c scamp.c scat.c via_vt82c49x.c
via_vt82c505.c sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c
opti283.c opti291.c umc491.c via_apollo.c via_pipc.c wd76c10.c
opti283.c opti291.c via_apollo.c via_pipc.c wd76c10.c
vl82c480.c)
if(STPC)
@@ -28,6 +28,11 @@ if(M1489)
target_sources(chipset PRIVATE ali1489.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()

152
src/chipset/ali1217.c Normal file
View File

@@ -0,0 +1,152 @@
/*
* 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(ali1217_t *dev)
{
for (uint8_t i = 0; i < 4; i++)
{
mem_set_mem_state_both(0xc0000 + (i << 15), 0x8000, ((dev->regs[0x14] & (1 << (i * 2))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x14] & (1 << ((i * 2) + 1))) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
mem_set_mem_state_both(0xe0000 + (i << 15), 0x8000, ((dev->regs[0x15] & (1 << (i * 2))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x15] & (1 << ((i * 2) + 1))) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
}
shadowbios = !!(dev->regs[0x15] & 5);
shadowbios_write = !!(dev->regs[0x15] & 0x0a);
flushmmucache();
}
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);
if (dev->index == 0x13)
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);
}
break;
}
}
static uint8_t
ali1217_read(uint16_t addr, void *priv)
{
ali1217_t *dev = (ali1217_t *)priv;
return !(addr == 0x22) ? dev->regs[dev->index] : dev->index;
}
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);
ali1217_shadow_recalc(dev);
return dev;
}
const device_t ali1217_device = {
"ALi M1217",
0,
0,
ali1217_init,
ali1217_close,
NULL,
{NULL},
NULL,
NULL,
NULL};

View File

@@ -101,17 +101,16 @@ ali1429_write(uint16_t addr, uint8_t val, void *priv)
/* Don't log register unlock patterns */
if(dev->index != 0x03)
{
ali1429_log("M1429: dev->regs[%02x] = %02x\n", dev->index, val);
}
dev->regs[dev->index] = val;
/* Unlock/Lock Registers */
dev->cfg_locked = !(dev->regs[0x03] && 0xc5);
if(dev->index == 0x03)
dev->cfg_locked = !(val == 0xc5);
if(dev->cfg_locked == 0)
if(!dev->cfg_locked)
{
dev->regs[dev->index] = val;
switch(dev->index){
/* Shadow RAM */
case 0x13:

316
src/chipset/ali1531.c Normal file
View File

@@ -0,0 +1,316 @@
/*
* 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 M1531B CPU-to-PCI Bridge.
*
*
*
* 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 <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 ali1531_t
{
uint8_t pci_conf[256];
smram_t *smram;
} ali1531_t;
void ali1531_shadow_recalc(ali1531_t *dev)
{
for (uint32_t i = 0; i < 8; i++)
{
mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, (((dev->pci_conf[0x4c] >> i) & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | (((dev->pci_conf[0x4e] >> i) & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
mem_set_mem_state_both(0xe0000 + (i << 14), 0x4000, (((dev->pci_conf[0x4d] >> i) & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | (((dev->pci_conf[0x4f] >> i) & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
}
shadowbios = !!(dev->pci_conf[0x4d] & 0xf0);
shadowbios_write = !!(dev->pci_conf[0x4f] & 0xf0);
flushmmucache();
}
void ali1531_smm_recalc(uint8_t smm_state, ali1531_t *dev)
{
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;
}
}
else
smram_disable_all();
flushmmucache();
}
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;
case 0x07:
dev->pci_conf[addr] = val & 0xfe;
break;
case 0x0d:
dev->pci_conf[addr] = val & 0xf8;
break;
case 0x40:
dev->pci_conf[addr] = val & 0xf1;
break;
case 0x41:
dev->pci_conf[addr] = val & 0xdf;
break;
case 0x42: /* L2 Cache */
dev->pci_conf[addr] = val & 0xf7;
cpu_cache_ext_enabled = !!(val & 1);
cpu_update_waitstates();
break;
case 0x43: /* L1 Cache */
dev->pci_conf[addr] = val;
cpu_cache_int_enabled = !!(val & 1);
cpu_update_waitstates();
break;
case 0x47:
dev->pci_conf[addr] = val & 0xfc;
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));
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));
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 0x48: /* SMRAM */
dev->pci_conf[addr] = val;
ali1531_smm_recalc((val >> 1) & 7, dev);
break;
case 0x49:
dev->pci_conf[addr] = val & 0x73;
break;
case 0x4c: /* Shadow RAM */
case 0x4d:
case 0x4e:
case 0x4f:
dev->pci_conf[addr] = val;
ali1531_shadow_recalc(dev);
break;
case 0x57: /* H2PO */
dev->pci_conf[addr] = val & 0x60;
if (!(val & 0x20))
outb(0x92, 0x01);
break;
case 0x58:
dev->pci_conf[addr] = val & 0x83;
break;
case 0x5b:
dev->pci_conf[addr] = val & 0x4f;
break;
case 0x5d:
dev->pci_conf[addr] = val & 0x53;
break;
case 0x5f:
dev->pci_conf[addr] = val & 0x7f;
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, 2);
break;
case 0x72:
dev->pci_conf[addr] = val & 0xf;
break;
case 0x74:
dev->pci_conf[addr] = val & 0x2b;
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;
default:
dev->pci_conf[addr] = val;
break;
}
}
static uint8_t
ali1531_read(int func, int addr, void *priv)
{
ali1531_t *dev = (ali1531_t *)priv;
return dev->pci_conf[addr];
}
static void
ali1531_reset(void *priv)
{
ali1531_t *dev = (ali1531_t *)priv;
/* Default Registers */
dev->pci_conf[0x00] = 0xb9;
dev->pci_conf[0x01] = 0x10;
dev->pci_conf[0x02] = 0x31;
dev->pci_conf[0x03] = 0x15;
dev->pci_conf[0x04] = 0x06;
dev->pci_conf[0x05] = 0x00;
dev->pci_conf[0x06] = 0x00;
dev->pci_conf[0x07] = 0x04;
dev->pci_conf[0x08] = 0xb0;
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] = 0x31;
dev->pci_conf[0x2f] = 0x15;
dev->pci_conf[0x52] = 0xf0;
dev->pci_conf[0x54] = 0xff;
dev->pci_conf[0x55] = 0xff;
dev->pci_conf[0x59] = 0x20;
dev->pci_conf[0x5a] = 0x20;
dev->pci_conf[0x70] = 0x22;
ali1531_write(0, 0x42, 0x00, dev);
ali1531_write(0, 0x43, 0x00, dev);
ali1531_write(0, 0x47, 0x00, dev);
ali1531_shadow_recalc(dev);
ali1531_write(0, 0x60, 0x08, dev);
ali1531_write(0, 0x61, 0x40, dev);
}
static void
ali1531_close(void *priv)
{
ali1531_t *dev = (ali1531_t *)priv;
smram_del(dev->smram);
free(dev);
}
static void *
ali1531_init(const device_t *info)
{
ali1531_t *dev = (ali1531_t *)malloc(sizeof(ali1531_t));
memset(dev, 0, sizeof(ali1531_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1531_read, ali1531_write, dev);
dev->smram = smram_add();
ali1531_reset(dev);
return dev;
}
const device_t ali1531_device = {
"ALi M1531 CPU-to-PCI Bridge",
DEVICE_PCI,
0,
ali1531_init,
ali1531_close,
ali1531_reset,
{NULL},
NULL,
NULL,
NULL};

957
src/chipset/ali1543.c Normal file
View File

@@ -0,0 +1,957 @@
/*
* 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 M1543 Desktop South Bridge.
*
*
*
* 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 <86box/timer.h>
#include <86box/device.h>
#include <86box/io.h>
#include <86box/apm.h>
#include <86box/dma.h>
#include <86box/ddma.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/hdc_ide.h>
#include <86box/hdc_ide_sff8038i.h>
#include <86box/lpt.h>
#include <86box/mem.h>
#include <86box/nvr.h>
#include <86box/pci.h>
#include <86box/port_92.h>
#include <86box/serial.h>
#include <86box/smbus_piix4.h>
#include <86box/usb.h>
#include <86box/acpi.h>
#include <86box/chipset.h>
#ifdef ENABLE_ALI1543_LOG
int ali1543_do_log = ENABLE_ALI1543_LOG;
static void
ali1543_log(const char *fmt, ...)
{
va_list ap;
if (ali1543_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define ali1543_log(fmt, ...)
#endif
typedef struct ali1543_t
{
uint8_t pci_conf[256], pmu_conf[256], usb_conf[256], ide_conf[256],
sio_regs[256], device_regs[8][256], sio_index, in_configuration_mode,
pci_slot, ide_slot, usb_slot, pmu_slot;
apm_t *apm;
acpi_t *acpi;
ddma_t *ddma;
fdc_t *fdc_controller;
nvr_t *nvr;
port_92_t *port_92;
serial_t *uart[2];
sff8038i_t *ide_controller[2];
smbus_piix4_t *smbus;
usb_t *usb;
} ali1543_t;
/*
Notes:
- Power Managment isn't functioning properly
- IDE isn't functioning properly
- 1543C differences have to be examined
- Some Chipset functionality might be missing
- Device numbers and types might be incorrect
- Code quality is abysmal and needs lot's of cleanup.
*/
void ali1533_ddma_handler(ali1543_t *dev)
{
for (uint8_t i = 0; i < 8; i++)
{
if (i != 4)
ddma_update_io_mapping(dev->ddma, i & 7, dev->pci_conf[0x73] & 0xf, dev->pci_conf[0x73] & 0xf0, dev->pci_conf[0x45] & 2);
}
}
void ali5229_ide_handler(ali1543_t *dev);
static void
ali1533_write(int func, int addr, uint8_t val, void *priv)
{
ali1543_t *dev = (ali1543_t *)priv;
ali1543_log("M1533: dev->pci_conf[%02x] = %02x\n", addr, val);
switch (addr)
{
case 0x04:
if (dev->pci_conf[0x5f] & 8)
dev->pci_conf[addr] = val;
break;
case 0x2c: /* Subsystem Vendor ID */
case 0x2d:
case 0x2e:
case 0x2f:
if (dev->pci_conf[0x74] & 0x40)
dev->pci_conf[addr] = val;
break;
case 0x40:
dev->pci_conf[addr] = val & 0x7f;
break;
case 0x42:
dev->pci_conf[addr] = val & 0xcf;
break;
case 0x43:
dev->pci_conf[addr] = val;
if (val & 0x80)
port_92_add(dev->port_92);
else
port_92_remove(dev->port_92);
break;
case 0x44: /* Set IRQ Line for Primary IDE if it's on native mode */
dev->pci_conf[addr] = 0xdf;
if (dev->ide_conf[0x09] & 1)
sff_set_irq_line(dev->ide_controller[0], val & 0x0f);
break;
case 0x45: /* DDMA Enable */
dev->pci_conf[addr] = 0xcf;
ali1533_ddma_handler(dev);
break;
case 0x48: /* PCI IRQ Routing */
case 0x49:
dev->pci_conf[addr] = val;
pci_set_irq_routing(((addr & 1) * 2) + 2, ((val & 0xf0) == 0) ? (val & 0xf0) : PCI_IRQ_DISABLED);
pci_set_irq_routing(((addr & 1) * 2) + 1, ((val & 0x0f) == 0) ? (val & 0x0f) : PCI_IRQ_DISABLED);
break;
case 0x53: /* USB Enable */
dev->pci_conf[addr] = val & 0xe7;
ohci_update_mem_mapping(dev->usb, 0x11, 0x12, 0x13, (dev->usb_conf[0x04] & 1) && (!(dev->pci_conf[0x53] & 0x40)));
break;
case 0x54: /* USB Control ? */
dev->pci_conf[addr] = val & 0xdf;
break;
case 0x57:
dev->pci_conf[addr] = val & 0xc7;
break;
case 0x58: /* IDE Enable */
dev->pci_conf[addr] = val & 0x7f;
ali5229_ide_handler(dev);
break;
case 0x59:
case 0x5a:
dev->pci_conf[addr] = val & 0x0e;
break;
case 0x5b:
dev->pci_conf[addr] = val & 0x02;
break;
case 0x5c:
dev->pci_conf[addr] = val & 0x7f;
break;
case 0x5d:
dev->pci_conf[addr] = val & 0x02;
break;
case 0x5e:
dev->pci_conf[addr] = val & 0xe0;
break;
case 0x5f:
dev->pci_conf[addr] = val;
acpi_update_io_mapping(dev->acpi, (dev->pmu_conf[0x11] << 8) | (dev->pmu_conf[0x10] & 0xc0), (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4)));
smbus_piix4_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xe0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4)));
break;
case 0x6d:
dev->pci_conf[addr] = val & 0xbf;
break;
case 0x71:
case 0x72:
dev->pci_conf[addr] = val & 0xef;
break;
case 0x73: /* DDMA Base Address */
dev->pci_conf[addr] = val;
ali1533_ddma_handler(dev);
break;
case 0x74: /* USB IRQ Routing */
dev->pci_conf[addr] = val & 0xdf;
pci_set_irq_routing(dev->usb_slot, ((val & 0x0f) == 0) ? (val & 0x0f) : PCI_IRQ_DISABLED);
break;
case 0x75: /* Set IRQ Line for Secondary IDE if it's on native mode */
dev->pci_conf[addr] = val & 0x1f;
if (dev->ide_conf[0x09] & 8)
sff_set_irq_line(dev->ide_controller[1], val & 0x0f);
break;
case 0x76: /* PMU IRQ Routing */
dev->pci_conf[addr] = val & 0x1f;
acpi_set_irq_line(dev->acpi, val & 0x0f);
break;
case 0x77: /* SMBus IRQ Routing */
dev->pci_conf[addr] = val & 0x1f;
break;
default:
dev->pci_conf[addr] = val;
break;
}
}
static uint8_t
ali1533_read(int func, int addr, void *priv)
{
ali1543_t *dev = (ali1543_t *)priv;
if (((dev->pci_conf[0x42] & 0x80) && (addr >= 0x40)) || ((dev->pci_conf[0x5f] & 8) && (addr == 4)))
return 0;
else
return dev->pci_conf[addr];
}
void ali5229_ide_handler(ali1543_t *dev)
{
uint16_t native_base_pri_addr = (dev->ide_conf[0x11] | dev->ide_conf[0x10] << 8);
uint16_t native_side_pri_addr = (dev->ide_conf[0x15] | dev->ide_conf[0x14] << 8);
uint16_t native_base_sec_addr = (dev->ide_conf[0x19] | dev->ide_conf[0x18] << 8);
uint16_t native_side_sec_addr = (dev->ide_conf[0x1c] | dev->ide_conf[0x1b] << 8);
uint16_t comp_base_pri_addr = 0x01f0;
uint16_t comp_side_pri_addr = 0x03f6;
uint16_t comp_base_sec_addr = 0x0170;
uint16_t comp_side_sec_addr = 0x0376;
uint16_t current_pri_base, current_pri_side, current_sec_base, current_sec_side;
/* Primary Channel Programming */
if (!(dev->ide_conf[0x52] & 0x10))
{
current_pri_base = (!(dev->ide_conf[0x09] & 1)) ? comp_base_pri_addr : native_base_pri_addr;
current_pri_side = (!(dev->ide_conf[0x09] & 1)) ? comp_side_pri_addr : native_side_pri_addr;
}
else
{
current_pri_base = (!(dev->ide_conf[0x09] & 1)) ? comp_base_sec_addr : native_base_sec_addr;
current_pri_side = (!(dev->ide_conf[0x09] & 1)) ? comp_side_sec_addr : native_side_sec_addr;
}
/* Secondary Channel Programming */
if (!(dev->ide_conf[0x52] & 0x10))
{
current_sec_base = (!(dev->ide_conf[0x09] & 4)) ? comp_base_sec_addr : native_base_sec_addr;
current_sec_side = (!(dev->ide_conf[0x09] & 4)) ? comp_side_sec_addr : native_side_sec_addr;
}
else
{
current_sec_base = (!(dev->ide_conf[0x09] & 4)) ? comp_base_pri_addr : native_base_pri_addr;
current_sec_side = (!(dev->ide_conf[0x09] & 4)) ? comp_side_pri_addr : native_side_pri_addr;
}
/* Both channels use one port */
if (dev->ide_conf[0x52] & 0x40)
{
current_pri_base = current_sec_base;
current_pri_side = current_sec_side;
}
if (dev->ide_conf[0x52] & 0x20)
{
current_sec_base = current_pri_base;
current_sec_side = current_pri_side;
}
ide_pri_disable();
ide_sec_disable();
if (dev->pci_conf[0x58] & 0x40)
{
sff_set_irq_pin(dev->ide_controller[0], dev->ide_conf[0x3d] & 4);
sff_set_irq_pin(dev->ide_controller[1], dev->ide_conf[0x3d] & 4);
/* Primary Channel Setup */
if (dev->ide_conf[0x09] & 0x10)
{
if (!(dev->ide_conf[0x09] & 1))
sff_set_irq_line(dev->ide_controller[0], dev->ide_conf[0x3c] & 0xf);
ide_set_base(0, current_pri_base);
ide_set_side(0, current_pri_side);
sff_bus_master_handler(dev->ide_controller[0], dev->ide_conf[0x09] & 0x80, (dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8));
ide_pri_enable();
ali1543_log("M5229 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side);
}
/* Secondary Channel Setup */
if (dev->ide_conf[0x09] & 8)
{
if (!(dev->ide_conf[0x09] & 4))
sff_set_irq_line(dev->ide_controller[1], dev->ide_conf[0x3c] & 0xf);
ide_set_base(1, current_sec_base);
ide_set_side(1, current_sec_side);
sff_bus_master_handler(dev->ide_controller[1], dev->ide_conf[0x09] & 0x80, ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + 8);
ide_sec_enable();
ali1543_log("M5229 SEC: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side);
}
}
}
static void
ali5229_write(int func, int addr, uint8_t val, void *priv)
{
ali1543_t *dev = (ali1543_t *)priv;
ali1543_log("M5229: dev->ide_conf[%02x] = %02x\n", addr, val);
switch (addr)
{
case 0x09: /* Control */
if (dev->ide_conf[0x4d] & 0x80)
dev->ide_conf[addr] |= val & 0x8f;
else
dev->ide_conf[addr] = val;
ali5229_ide_handler(dev);
break;
case 0x10: /* Primary Base Address */
case 0x11:
case 0x12:
case 0x13:
case 0x14:
case 0x18: /* Secondary Base Address */
case 0x19:
case 0x1a:
case 0x1b:
case 0x1c:
case 0x20: /* Bus Mastering Base Address */
case 0x21:
case 0x22:
case 0x23:
dev->ide_conf[addr] = val;
ali5229_ide_handler(dev);
break;
/* The machines don't touch anything beyond that point so we avoid any programming */
case 0x2c: /* Subsystem Vendor */
case 0x2d:
case 0x2e:
case 0x2f:
if (dev->ide_conf[0x53] & 0x80)
dev->ide_conf[addr] = val;
break;
case 0x4d:
dev->ide_conf[addr] = val & 0x80;
break;
case 0x4f:
dev->ide_conf[addr] = val & 0x3f;
break;
case 0x50: /* Configuration */
dev->ide_conf[addr] = val & 0x2b;
break;
case 0x51:
dev->ide_conf[addr] = val & 0xf7;
break;
case 0x53: /* Subsystem Vendor ID */
dev->ide_conf[addr] = val & 0x8b;
break;
case 0x58:
dev->ide_conf[addr] = val & 3;
break;
case 0x59:
case 0x5a:
case 0x5b:
dev->ide_conf[addr] = val & 0x7f;
break;
case 0x5c:
dev->ide_conf[addr] = val & 3;
break;
case 0x5d:
case 0x5e:
case 0x5f:
dev->ide_conf[addr] = val & 0x7f;
break;
default:
dev->ide_conf[addr] = val;
break;
}
}
static uint8_t
ali5229_read(int func, int addr, void *priv)
{
ali1543_t *dev = (ali1543_t *)priv;
return dev->ide_conf[addr];
}
static void
ali5237_write(int func, int addr, uint8_t val, void *priv)
{
ali1543_t *dev = (ali1543_t *)priv;
ali1543_log("M5237: dev->usb_conf[%02x] = %02x\n", addr, val);
switch (addr)
{
case 0x04: /* USB Enable */
dev->usb_conf[addr] = val;
ohci_update_mem_mapping(dev->usb, 0x10, 0x11, 0x12, (dev->usb_conf[0x04] & 1) && (!(dev->pci_conf[0x53] & 0x40)));
break;
case 0x05:
dev->usb_conf[addr] = 0x03;
break;
case 0x06:
dev->usb_conf[addr] = 0xc0;
break;
case 0x11:
case 0x12:
case 0x13: /* USB Base I/O */
dev->usb_conf[addr] = val;
ohci_update_mem_mapping(dev->usb, 0x11, 0x12, 0x13, (dev->usb_conf[0x04] & 1) && (!(dev->pci_conf[0x53] & 0x40)));
break;
case 0x42:
dev->usb_conf[addr] = 0x10;
break;
default:
dev->usb_conf[addr] = val;
break;
}
}
static uint8_t
ali5237_read(int func, int addr, void *priv)
{
ali1543_t *dev = (ali1543_t *)priv;
return dev->usb_conf[addr];
}
static void
ali7101_write(int func, int addr, uint8_t val, void *priv)
{
ali1543_t *dev = (ali1543_t *)priv;
ali1543_log("M7101: dev->pmu_conf[%02x] = %02x\n", addr, val);
switch (addr)
{
case 0x04: /* Enable PMU */
dev->pmu_conf[addr] = val & 0x1f;
acpi_update_io_mapping(dev->acpi, (dev->pmu_conf[0x11] << 8) | (dev->pmu_conf[0x10] & 0xc0), (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4)));
smbus_piix4_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xe0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4)));
break;
case 0x07:
dev->pmu_conf[addr] = val & 0xfe;
break;
case 0x10: /* PMU Base I/O */
case 0x11:
if (addr == 0x10)
dev->pmu_conf[addr] = (val & 0xe0) | 1;
else if (addr == 0x11)
dev->pmu_conf[addr] = val;
acpi_update_io_mapping(dev->acpi, (dev->pmu_conf[0x11] << 8) | (dev->pmu_conf[0x10] & 0xc0), (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4)));
break;
case 0x14: /* SMBus Base I/O */
case 0x15:
dev->pmu_conf[addr] = val;
smbus_piix4_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xe0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4)));
break;
case 0x2c: /* Subsystem Vendor ID */
case 0x2d:
case 0x2e:
case 0x2f:
if (dev->pmu_conf[0xd8] & 0x10)
dev->pmu_conf[addr] = val;
case 0x40:
dev->pmu_conf[addr] = val & 0x1f;
break;
case 0x41:
dev->pmu_conf[addr] = val & 0x10;
break;
case 0x45:
dev->pmu_conf[addr] = val & 0x9f;
break;
case 0x46:
dev->pmu_conf[addr] = val & 0x18;
break;
case 0x48:
dev->pmu_conf[addr] = val & 0x9f;
break;
case 0x49:
dev->pmu_conf[addr] = val & 0x38;
break;
case 0x4c:
dev->pmu_conf[addr] = val & 5;
break;
case 0x4d:
dev->pmu_conf[addr] = val & 1;
break;
case 0x4e:
dev->pmu_conf[addr] = val & 5;
break;
case 0x4f:
dev->pmu_conf[addr] = val & 1;
break;
case 0x55: /* APM Timer */
dev->pmu_conf[addr] = val & 0x7f;
break;
case 0x59:
dev->pmu_conf[addr] = val & 0x1f;
break;
case 0x5b: /* ACPI/SMB Base I/O Control */
dev->pmu_conf[addr] = val & 0x7f;
break;
case 0x61:
dev->pmu_conf[addr] = val & 0x13;
break;
case 0x62:
dev->pmu_conf[addr] = val & 0xf1;
break;
case 0x63:
dev->pmu_conf[addr] = val & 3;
break;
case 0x65:
dev->pmu_conf[addr] = val & 0x1f;
break;
case 0x68:
dev->pmu_conf[addr] = val & 7;
break;
case 0x6e:
dev->pmu_conf[addr] = val & 0xef;
break;
case 0x6f:
dev->pmu_conf[addr] = val & 7;
break;
/* Continue Further Later */
case 0xc0: /* GPO Registers */
case 0xc1:
case 0xc2:
case 0xc3:
dev->pmu_conf[addr] = val;
acpi_init_gporeg(dev->acpi, dev->pmu_conf[0xc0], dev->pmu_conf[0xc1], dev->pmu_conf[0xc2], dev->pmu_conf[0xc3]);
break;
case 0xe0:
dev->pmu_conf[addr] = val;
smbus_piix4_remap(dev->smbus, (dev->pmu_conf[0x15] << 8) | (dev->pmu_conf[0x14] & 0xe0), (dev->pmu_conf[0xe0] & 1) && (dev->pmu_conf[0x04] & 1) && (!(dev->pci_conf[0x5f] & 4)));
break;
default:
dev->pmu_conf[addr] = val;
break;
}
}
static uint8_t
ali7101_read(int func, int addr, void *priv)
{
ali1543_t *dev = (ali1543_t *)priv;
return dev->pmu_conf[addr];
}
void ali1533_sio_fdc_handler(ali1543_t *dev)
{
fdc_remove(dev->fdc_controller);
if (dev->device_regs[0][0x30] & 1)
{
fdc_set_base(dev->fdc_controller, dev->device_regs[0][0x61] | (dev->device_regs[0][0x60] << 8));
fdc_set_irq(dev->fdc_controller, dev->device_regs[0][0x70] & 0xf);
fdc_set_dma_ch(dev->fdc_controller, dev->device_regs[0][0x74] & 0x07);
ali1543_log("M1543-SIO FDC: ADDR %04x IRQ %02x DMA %02x\n", dev->device_regs[0][0x61] | (dev->device_regs[0][0x60] << 8), dev->device_regs[0][0x70] & 0xf, dev->device_regs[0][0x74] & 0x07);
}
}
void ali1533_sio_uart_handler(int num, ali1543_t *dev)
{
serial_remove(dev->uart[num]);
if (dev->device_regs[num + 4][0x30] & 1)
{
serial_setup(dev->uart[num], dev->device_regs[num + 4][0x61] | (dev->device_regs[num + 4][0x60] << 8), dev->device_regs[num + 4][0x70] & 0xf);
ali1543_log("M1543-SIO UART%d: ADDR %04x IRQ %02x\n", num, dev->device_regs[num + 4][0x61] | (dev->device_regs[num + 4][0x60] << 8), dev->device_regs[num + 4][0x70] & 0xf);
}
}
void ali1533_sio_lpt_handler(ali1543_t *dev)
{
lpt1_remove();
if (dev->device_regs[3][0x30] & 1)
{
lpt1_init(dev->device_regs[3][0x61] | (dev->device_regs[3][0x60] << 8));
lpt1_irq(dev->device_regs[3][0x70] & 0xf);
ali1543_log("M1543-SIO LPT: ADDR %04x IRQ %02x\n", dev->device_regs[3][0x61] | (dev->device_regs[3][0x60] << 8), dev->device_regs[3][0x70] & 0xf);
}
}
void ali1533_sio_ldn(uint16_t ldn, ali1543_t *dev)
{
/* We don't include all LDN's */
switch (ldn)
{
case 0: /* FDC */
ali1533_sio_fdc_handler(dev);
break;
case 3: /* LPT */
ali1533_sio_lpt_handler(dev);
break;
case 4: /* UART */
case 5:
ali1533_sio_uart_handler(ldn - 4, dev);
break;
}
}
static void
ali1533_sio_write(uint16_t addr, uint8_t val, void *priv)
{
ali1543_t *dev = (ali1543_t *)priv;
switch (addr)
{
case 0x3f0:
dev->sio_index = val;
if (dev->sio_index == 0x51)
{
dev->in_configuration_mode = 1;
}
else if (dev->sio_index == 0xbb)
dev->in_configuration_mode = 0;
break;
case 0x3f1:
if (dev->in_configuration_mode)
{
switch (dev->sio_index)
{
case 0x07:
dev->sio_regs[dev->sio_index] = val & 0x7;
break;
case 0x22:
dev->sio_regs[dev->sio_index] = val & 0x39;
break;
case 0x23:
dev->sio_regs[dev->sio_index] = val & 0x38;
break;
default:
if ((dev->sio_index < 0x30) || (dev->sio_index == 0x51) || (dev->sio_index == 0xbb))
dev->sio_regs[dev->sio_index] = val;
else if (dev->sio_regs[0x07] <= 7)
dev->device_regs[dev->sio_regs[0x07]][dev->sio_index] = val;
break;
}
}
break;
}
if ((!dev->in_configuration_mode) && (dev->sio_regs[0x07] <= 7) && (addr == 0x03f0))
{
ali1533_sio_ldn(dev->sio_regs[0x07], dev);
}
}
static uint8_t
ali1533_sio_read(uint16_t addr, void *priv)
{
ali1543_t *dev = (ali1543_t *)priv;
if (dev->sio_index >= 0x30)
return dev->device_regs[dev->sio_regs[0x07]][dev->sio_index];
else
return dev->sio_regs[dev->sio_index];
}
static void
ali1543_reset(void *priv)
{
ali1543_t *dev = (ali1543_t *)priv;
/* M1533 */
dev->pci_conf[0x00] = 0xb9;
dev->pci_conf[0x01] = 0x10;
dev->pci_conf[0x02] = 0x33;
dev->pci_conf[0x03] = 0x15;
dev->pci_conf[0x04] = 0x0f;
dev->pci_conf[0x08] = 0xb4;
dev->pci_conf[0x0a] = 0x01;
dev->pci_conf[0x0b] = 0x06;
ali1533_write(0, 0x48, 0x00, dev); // Disables all IRQ's
ali1533_write(0, 0x44, 0x00, dev);
ali1533_write(0, 0x74, 0x00, dev);
ali1533_write(0, 0x75, 0x00, dev);
ali1533_write(0, 0x76, 0x00, dev);
/* M5229 */
dev->ide_conf[0x00] = 0xb9;
dev->ide_conf[0x01] = 0x10;
dev->ide_conf[0x02] = 0x29;
dev->ide_conf[0x03] = 0x52;
dev->ide_conf[0x06] = 0x80;
dev->ide_conf[0x07] = 0x02;
dev->ide_conf[0x08] = 0x20;
dev->ide_conf[0x09] = 0xfa;
dev->ide_conf[0x0a] = 0x01;
dev->ide_conf[0x0b] = 0x01;
dev->ide_conf[0x10] = 0xf1;
dev->ide_conf[0x11] = 0x01;
dev->ide_conf[0x14] = 0xf5;
dev->ide_conf[0x15] = 0x03;
dev->ide_conf[0x18] = 0x71;
dev->ide_conf[0x19] = 0x01;
dev->ide_conf[0x1a] = 0x75;
dev->ide_conf[0x1b] = 0x03;
dev->ide_conf[0x20] = 0x01;
dev->ide_conf[0x23] = 0xf0;
dev->ide_conf[0x3d] = 0x01;
dev->ide_conf[0x3c] = 0x02;
dev->ide_conf[0x3d] = 0x03;
dev->ide_conf[0x54] = 0x55;
dev->ide_conf[0x55] = 0x55;
dev->ide_conf[0x63] = 0x01;
dev->ide_conf[0x64] = 0x02;
dev->ide_conf[0x67] = 0x01;
dev->ide_conf[0x78] = 0x21;
sff_set_slot(dev->ide_controller[0], dev->ide_slot);
sff_set_slot(dev->ide_controller[1], dev->ide_slot);
sff_bus_master_reset(dev->ide_controller[0], (dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8));
sff_bus_master_reset(dev->ide_controller[1], ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + 8);
ali5229_ide_handler(dev);
/* M5237 */
dev->usb_conf[0x00] = 0xb9;
dev->usb_conf[0x01] = 0x10;
dev->usb_conf[0x02] = 0x37;
dev->usb_conf[0x03] = 0x52;
dev->usb_conf[0x06] = 0x80;
dev->usb_conf[0x07] = 0x02;
dev->usb_conf[0x08] = 0x03;
dev->usb_conf[0x09] = 0x10;
dev->usb_conf[0x0a] = 0x03;
dev->usb_conf[0x0b] = 0x0c;
dev->usb_conf[0x3d] = 0x01;
ali5237_write(0, 0x04, 0x00, dev);
/* M7101 */
dev->pmu_conf[0x00] = 0xb9;
dev->pmu_conf[0x01] = 0x10;
dev->pmu_conf[0x02] = 0x01;
dev->pmu_conf[0x03] = 0x71;
dev->pmu_conf[0x04] = 0x0f;
dev->pmu_conf[0x05] = 0x00;
dev->pmu_conf[0x0a] = 0x01;
dev->pmu_conf[0x0b] = 0x06;
acpi_set_slot(dev->acpi, dev->pmu_slot);
acpi_set_nvr(dev->acpi, dev->nvr);
ali7101_write(0, 0x04, 0x00, dev);
ali7101_write(0, 0xc0, 0x00, dev);
/* M1543 Super I/O */
dev->device_regs[0][0x60] = 0x03;
dev->device_regs[0][0x61] = 0xf0;
dev->device_regs[0][0x70] = 0x06;
dev->device_regs[0][0x74] = 0x02;
dev->device_regs[0][0xf0] = 0x08;
dev->device_regs[0][0xf2] = 0xff;
dev->device_regs[3][0x60] = 0x03;
dev->device_regs[3][0x61] = 0x78;
dev->device_regs[3][0x70] = 0x05;
dev->device_regs[3][0x74] = 0x04;
dev->device_regs[3][0xf0] = 0x0c;
dev->device_regs[3][0xf1] = 0x05;
dev->device_regs[4][0x60] = 0x03;
dev->device_regs[4][0x61] = 0xf8;
dev->device_regs[4][0x70] = 0x04;
dev->device_regs[4][0xf1] = 0x02;
dev->device_regs[4][0xf2] = 0x0c;
dev->device_regs[5][0x60] = 0x02;
dev->device_regs[5][0x61] = 0xf8;
dev->device_regs[5][0x70] = 0x03;
dev->device_regs[5][0xf1] = 0x02;
dev->device_regs[5][0xf2] = 0x0c;
dev->device_regs[7][0x70] = 0x01;
ali1533_sio_fdc_handler(dev);
ali1533_sio_uart_handler(0, dev);
ali1533_sio_uart_handler(1, dev);
ali1533_sio_lpt_handler(dev);
}
static void
ali1543_close(void *priv)
{
ali1543_t *dev = (ali1543_t *)priv;
free(dev);
}
static void *
ali1543_init(const device_t *info)
{
ali1543_t *dev = (ali1543_t *)malloc(sizeof(ali1543_t));
memset(dev, 0, sizeof(ali1543_t));
/* Device 02: M1533 Southbridge */
dev->pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, ali1533_read, ali1533_write, dev);
/* Device 0B: M5229 IDE Controller*/
dev->ide_slot = pci_add_card(PCI_ADD_IDE, ali5229_read, ali5229_write, dev);
/* Device 0D: M5237 USB */
dev->usb_slot = pci_add_card(PCI_ADD_NORMAL_NOBRIDGE, ali5237_read, ali5237_write, dev);
/* Device 0C: M7101 Power Managment Controller */
dev->pmu_slot = pci_add_card(PCI_ADD_BRIDGE, ali7101_read, ali7101_write, dev);
/* Ports 3F0-1h: M1543 Super I/O */
io_sethandler(0x03f0, 0x0002, ali1533_sio_read, NULL, NULL, ali1533_sio_write, NULL, NULL, dev);
/* ACPI */
dev->acpi = device_add(&acpi_ali_device);
dev->nvr = device_add(&at_nvr_device); // Generic NVR
/* APM */
dev->apm = device_add(&apm_pci_device);
/* DMA */
dma_alias_set();
dma_high_page_init();
/* DDMA */
dev->ddma = device_add(&ddma_device);
/* Floppy Disk Controller */
dev->fdc_controller = device_add(&fdc_at_device);
/* IDE Controllers */
dev->ide_controller[0] = device_add_inst(&sff8038i_device, 1);
dev->ide_controller[1] = device_add_inst(&sff8038i_device, 2);
/* Port 92h */
dev->port_92 = device_add(&port_92_pci_device);
/* Serial NS16500 */
dev->uart[0] = device_add_inst(&ns16550_device, 1);
dev->uart[1] = device_add_inst(&ns16550_device, 2);
/* Standard SMBus */
dev->smbus = device_add(&piix4_smbus_device);
/* Super I/O Configuration Mechanism */
dev->in_configuration_mode = 1;
/* USB */
dev->usb = device_add(&usb_device);
ali1543_reset(dev);
return dev;
}
const device_t ali1543_device = {
"ALi M1543 Desktop South Bridge",
DEVICE_PCI,
0,
ali1543_init,
ali1543_close,
ali1543_reset,
{NULL},
NULL,
NULL,
NULL};

View File

@@ -104,8 +104,8 @@ intel_82335_write(uint16_t addr, uint16_t val, void *priv)
if (!EXTENDED_GRANULARITY_ENABLED)
{
shadowbios = (dev->regs[0x22] & 0x01);
shadowbios_write = (dev->regs[0x22] & 0x01);
shadowbios = !!(dev->regs[0x22] & 0x01);
shadowbios_write = !!(dev->regs[0x22] & 0x01);
/* Base System 512/640KB set */
mem_set_mem_state_both(0x80000, 0x20000, (dev->regs[0x22] & 0x08) ? ENABLE_TOP_128KB : DISABLE_TOP_128KB);

View File

@@ -88,8 +88,8 @@ sis_5571_shadow_recalc(sis_5571_t *dev)
can_read = (dev->pci_conf[0x76] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
can_write = (dev->pci_conf[0x76] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
shadowbios = (dev->pci_conf[0x76] & 0x80);
shadowbios_write = (dev->pci_conf[0x76] & 0x20);
shadowbios = !!(dev->pci_conf[0x76] & 0x80);
shadowbios_write = !!(dev->pci_conf[0x76] & 0x20);
mem_set_mem_state_both(0xf0000, 0x10000, can_read | can_write);
flushmmucache();
@@ -212,7 +212,7 @@ memory_pci_bridge_write(int func, int addr, uint8_t val, void *priv)
case 0x51: /* Cache */
dev->pci_conf[addr] = val;
cpu_cache_ext_enabled = (val & 0x40);
cpu_cache_ext_enabled = !!(val & 0x40);
cpu_update_waitstates();
break;

View File

@@ -36,11 +36,11 @@
#include <86box/chipset.h>
#include <86box/spd.h>
#define VIA_585 0x05850000
#define VIA_585 0x05851000
#define VIA_595 0x05950000
#define VIA_597 0x05970100
#define VIA_598 0x05980000
#define VIA_691 0x06910000
#define VIA_691 0x06910600
#define VIA_693A 0x06914400
#define VIA_694 0x0691c200
#define VIA_8601 0x86010500

View File

@@ -42,6 +42,7 @@ extern "C" {
#define ACPI_ENABLE 0xf1
#define ACPI_DISABLE 0xf0
#define VEN_ALI 0x010b9
#define VEN_INTEL 0x08086
#define VEN_SMC 0x01055
#define VEN_VIA 0x01106
@@ -56,8 +57,9 @@ typedef struct
timer32,
gpireg[3], gporeg[4];
uint16_t pmsts, pmen,
pmcntrl, gpsts,
gpen, gpscien,
pmcntrl, gpsts, gpsts1,
gpen, gpen1, gpscien,
gpcntrl,
gpsmien, pscntrl,
gpscists;
int smi_lock, smi_active;
@@ -91,13 +93,14 @@ typedef struct
/* Global variables. */
extern int acpi_rtc_status;
extern const device_t acpi_ali_device;
extern const device_t acpi_intel_device;
extern const device_t acpi_smc_device;
extern const device_t acpi_via_device;
extern const device_t acpi_via_596b_device;
/* Functions. */
/* Functions */
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);

View File

@@ -22,10 +22,15 @@
extern const device_t acc2168_device;
/* ALi */
extern const device_t ali1217_device;
extern const device_t ali1429_device;
#if defined(DEV_BRANCH) && defined(USE_M1489)
extern const device_t ali1489_device;
#endif
#if defined(DEV_BRANCH) && defined(USE_M154X)
extern const device_t ali1531_device;
extern const device_t ali1543_device;
#endif
#if defined(DEV_BRANCH) && defined(USE_M6117)
extern const device_t ali6117d_device;
#endif
@@ -110,9 +115,6 @@ extern const device_t stpc_serial_device;
extern const device_t stpc_lpt_device;
#endif
/* UMC */
extern const device_t umc491_device;
/* VIA */
extern const device_t via_vt82c49x_device;
extern const device_t via_vt82c49x_ide_device;

View File

@@ -267,6 +267,7 @@ extern int machine_at_commodore_sl386sx16_init(const machine_t *);
extern int machine_at_commodore_sl386sx25_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_flytech386_init(const machine_t *);
extern int machine_at_olim300_05_init(const machine_t *);
extern int machine_at_olim300_10_init(const machine_t *);
@@ -286,6 +287,7 @@ extern int machine_at_pja511m_init(const machine_t *);
#ifdef EMU_DEVICE_H
extern const device_t *at_ama932j_get_device(void);
extern const device_t *at_flytech386_get_device(void);
extern const device_t *at_commodore_sl386sx25_get_device(void);
extern const device_t *at_spc4620p_get_device(void);
extern const device_t *at_spc6033p_get_device(void);
@@ -298,7 +300,6 @@ extern int machine_at_acc386_init(const machine_t *);
extern int machine_at_asus386_init(const machine_t *);
extern int machine_at_ecs386_init(const machine_t *);
extern int machine_at_spc6000a_init(const machine_t *);
extern int machine_at_ustechnologies386_init(const machine_t *);
extern int machine_at_micronics386_init(const machine_t *);
extern int machine_at_rycleopardlx_init(const machine_t *);
@@ -349,6 +350,7 @@ extern int machine_at_486vipio2_init(const machine_t *);
#endif
#if defined(DEV_BRANCH) && defined(USE_M1489)
extern int machine_at_abpb4_init(const machine_t *);
extern int machine_at_win486pci_init(const machine_t *);
#endif
#if defined(DEV_BRANCH) && defined(USE_STPC)
extern int machine_at_itoxstar_init(const machine_t *);
@@ -454,6 +456,10 @@ 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 *);
#endif
#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 *);

View File

@@ -152,12 +152,14 @@ extern void thread_reset_event(event_t *arg);
extern int thread_wait_event(event_t *arg, int timeout);
extern void thread_destroy_event(event_t *arg);
#define MUTEX_DEFAULT_SPIN_COUNT 1024
extern mutex_t *thread_create_mutex(void);
extern mutex_t *thread_create_mutex_with_spin_count(unsigned int spin_count);
extern void thread_close_mutex(mutex_t *arg);
extern int thread_wait_mutex(mutex_t *arg);
extern int thread_release_mutex(mutex_t *mutex);
/* Other stuff. */
extern void startblit(void);
extern void endblit(void);

View File

@@ -50,6 +50,8 @@ extern const device_t pc87311_ide_device;
extern const device_t pc87332_device;
extern const device_t pc87332_ps1_device;
extern const device_t pc97307_device;
extern const device_t prime3b_device;
extern const device_t prime3b_ide_device;
extern const device_t prime3c_device;
extern const device_t prime3c_ide_device;
extern const device_t ps1_m2133_sio;
@@ -57,6 +59,7 @@ extern const device_t sio_detect_device;
extern const device_t um8669f_device;
extern const device_t via_vt82c686_sio_device;
extern const device_t w83787f_device;
extern const device_t w83787f_ide_device;
extern const device_t w83877f_device;
extern const device_t w83877f_president_device;
extern const device_t w83877tf_device;

View File

@@ -489,6 +489,10 @@ typedef struct voodoo_t
uint64_t time;
int render_time[4];
int force_blit_count;
int can_blit;
mutex_t* force_blit_mutex;
int use_recompiler;
void *codegen_data;

View File

@@ -50,6 +50,10 @@ if(M1489)
target_compile_definitions(mch PRIVATE USE_M1489)
endif()
if(M154X)
target_compile_definitions(mch PRIVATE USE_M154X)
endif()
if(M6117)
target_compile_definitions(mch PRIVATE USE_M6117)
endif()

View File

@@ -597,6 +597,34 @@ machine_at_awardsx_init(const machine_t *model)
return ret;
}
int
machine_at_flytech386_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/flytech386/FLYTECH.BIO",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&ali1217_device);
device_add(&w83787f_ide_device);
device_add(&keyboard_ps2_device);
if (gfxcard == VID_INTERNAL)
device_add(&tvga8900d_device);
return ret;
}
const device_t *
at_flytech386_get_device(void)
{
return &tvga8900d_device;
}
#if defined(DEV_BRANCH) && defined(USE_M6117)
int

View File

@@ -185,27 +185,6 @@ machine_at_spc6000a_init(const machine_t *model)
}
int
machine_at_ustechnologies386_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/ustechnologies386/3umw003.bin",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&umc491_device);
device_add(&keyboard_at_device);
device_add(&fdc_at_device);
return ret;
}
int
machine_at_rycleopardlx_init(const machine_t *model)
{
@@ -971,6 +950,32 @@ machine_at_abpb4_init(const machine_t *model)
return ret;
}
int
machine_at_win486pci_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/win486pci/v1hj3.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(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);
device_add(&ali1489_device);
device_add(&prime3b_device);
device_add(&keyboard_at_ami_device);
return ret;
}
#endif

View File

@@ -1032,6 +1032,75 @@ machine_at_p5mms98_init(const machine_t *model)
return ret;
}
#if defined(DEV_BRANCH) && defined(USE_M154X)
int
machine_at_m560_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/m560/5600410s.ami",
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(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
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);
pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0B, PCI_CARD_IDE, 1, 2, 3, 4);
pci_register_slot(0x0C, PCI_CARD_BRIDGE, 1, 2, 3, 4);
pci_register_slot(0x0D, PCI_CARD_NORMAL_NOBRIDGE, 1, 2, 3, 4);
device_add(&ali1531_device);
device_add(&ali1543_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_ms5164_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/ms5164/W564MS43.005",
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(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
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);
pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0B, PCI_CARD_IDE, 1, 2, 3, 4);
pci_register_slot(0x0C, PCI_CARD_BRIDGE, 1, 2, 3, 4);
pci_register_slot(0x0D, PCI_CARD_NORMAL_NOBRIDGE, 1, 2, 3, 4);
device_add(&ali1531_device);
device_add(&ali1543_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&sst_flash_29ee010_device);
spd_register(SPD_TYPE_SDRAM, 0x3, 128);
return ret;
}
#endif
#if defined(DEV_BRANCH) && defined(USE_SIS_5571)
int
machine_at_r534f_init(const machine_t *model)

View File

@@ -157,6 +157,7 @@ const machine_t machines[] = {
{ "[ALi M6117D] Acrosser AR-B1375", "arb1375", MACHINE_TYPE_386SX, CPU_PKG_M6117, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 32768,1024, 127, machine_at_arb1375_init, NULL },
{ "[ALi M6117D] Acrosser PJ-A511M", "pja511m", MACHINE_TYPE_386SX, CPU_PKG_M6117, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 32768,1024, 127, machine_at_pja511m_init, NULL },
#endif
{ "[ALi M1217] Flytech 386", "flytech386", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE | MACHINE_BUS_PS2 | MACHINE_VIDEO, 1024, 16384, 1024, 127, machine_at_flytech386_init, at_flytech386_get_device },
{ "[HT18] AMA-932J", "ama932j", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE | MACHINE_VIDEO, 512, 8192, 128, 127, machine_at_ama932j_init, at_ama932j_get_device },
{ "[Intel 82335] ADI 386SX", "adi386sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_adi386sx_init, NULL },
{ "[Intel 82335] Shuttle 386SX", "shuttle386sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_shuttle386sx_init, NULL },
@@ -181,7 +182,6 @@ const machine_t machines[] = {
{ "[ISA] Compaq Portable III (386)", "portableiii386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE | MACHINE_VIDEO, 1024, 14336, 1024, 127, machine_at_portableiii386_init, at_cpqiii_get_device },
{ "[ISA] Micronics 386 clone", "micronics386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_micronics386_init, NULL },
{ "[SiS 310] ASUS ISA-386C", "asus386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_asus386_init, NULL },
{ "[UMC 491] US Technologies 386", "ustechnologies386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 16384, 1024, 127, machine_at_ustechnologies386_init, NULL },
/* 386DX machines which utilize the VLB bus */
{ "[OPTi 495] Award 386DX clone", "award386dx", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 32768, 1024, 127, machine_at_opti495_init, NULL },
@@ -230,6 +230,7 @@ const machine_t machines[] = {
/* 486 machines which utilize the PCI bus */
#if defined(DEV_BRANCH) && defined(USE_M1489)
{ "[ALi M1489] ABIT AB-PB4", "abpb4", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 65536, 1024, 255, machine_at_abpb4_init, NULL },
{ "[ALi M1489] AMI WinBIOS 486 PCI", "win486pci", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 65536, 1024, 255, machine_at_win486pci_init, NULL },
#endif
{ "[i420EX] ASUS PVI-486AP4", "486ap4", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCIV | MACHINE_IDE_DUAL, 1024, 131072, 1024, 127, machine_at_486ap4_init, NULL },
{ "[i420ZX] ASUS PCI/I-486SP3G", "486sp3g", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 131072, 1024, 127, machine_at_486sp3g_init, NULL },
@@ -346,6 +347,12 @@ const machine_t machines[] = {
{ "[SiS 5571] MSI MS-5146", "ms5146", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 393216, 8192, 127, machine_at_ms5146_init, NULL },
#endif
/* ALi ALADDiN IV */
#if defined(DEV_BRANCH) && defined(USE_M154X)
{ "[ALi ALADDiN IV] PC Chips M560", "m560", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 255, machine_at_m560_init, NULL },
{ "[ALi ALADDiN IV] MSI MS-5164", "ms5164", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 262144, 8192, 255, machine_at_ms5164_init, NULL },
#endif
/* Super Socket 7 machines */
/* Apollo MVP3 */
{ "[VIA MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_TYPE_SOCKETS7, CPU_PKG_SOCKET5_7, 0, 66666667, 124242424, 1300, 3520, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_ax59pro_init, NULL },

View File

@@ -182,10 +182,10 @@ ncr_log(const char *fmt, ...)
#define SET_BUS_STATE(ncr, state) ncr->cur_bus = (ncr->cur_bus & ~(SCSI_PHASE_MESSAGE_IN)) | (state & (SCSI_PHASE_MESSAGE_IN))
static void
ncr_dma_send(ncr5380_t *ncr_dev, ncr_t *ncr);
ncr_dma_send(ncr5380_t *ncr_dev, ncr_t *ncr, scsi_device_t *dev);
static void
ncr_dma_initiator_receive(ncr5380_t *ncr_dev, ncr_t *ncr);
ncr_dma_initiator_receive(ncr5380_t *ncr_dev, ncr_t *ncr, scsi_device_t *dev);
static void
ncr_callback(void *priv);
@@ -249,9 +249,8 @@ ncr_timer_on(ncr5380_t *ncr_dev, ncr_t *ncr, int callback)
if (ncr->data_wait & 2)
ncr->data_wait &= ~2;
if (callback) {
if (callback)
p *= 128.0;
}
p += 1.0;
@@ -619,7 +618,7 @@ ncr_write(uint16_t port, uint8_t val, void *priv)
ncr_log("Write: start DMA send register\n");
/*a Write 6/10 has occurred, start the timer when the block count is loaded*/
ncr->dma_mode = DMA_SEND;
if (ncr_dev->block_count_loaded && (ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) {
if ((ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) {
ncr_timer_on(ncr_dev, ncr, 0);
}
break;
@@ -628,7 +627,7 @@ ncr_write(uint16_t port, uint8_t val, void *priv)
ncr_log("Write: start DMA initiator receive register, dma? = %02x\n", ncr->mode & MODE_DMA);
/*a Read 6/10 has occurred, start the timer when the block count is loaded*/
ncr->dma_mode = DMA_INITIATOR_RECEIVE;
if (ncr_dev->block_count_loaded && (ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) {
if ((ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) {
ncr_timer_on(ncr_dev, ncr, 0);
}
break;
@@ -888,10 +887,8 @@ memio_write(uint32_t addr, uint8_t val, void *priv)
ncr_dev->block_count = val;
ncr_dev->block_count_loaded = 1;
if (ncr->mode & MODE_DMA) {
ncr_log("Start timer, buffer not ready = %02x\n", !(ncr_dev->status_ctrl & STATUS_BUFFER_NOT_READY));
if (ncr->mode & MODE_DMA)
ncr_timer_on(ncr_dev, ncr, 0);
}
if (ncr_dev->status_ctrl & CTRL_DATA_DIR) {
ncr_dev->buffer_host_pos = 128;
@@ -988,15 +985,15 @@ t130b_out(uint16_t port, uint8_t val, void *priv)
}
static void
ncr_dma_send(ncr5380_t *ncr_dev, ncr_t *ncr)
ncr_dma_send(ncr5380_t *ncr_dev, ncr_t *ncr, scsi_device_t *dev)
{
scsi_device_t *dev = &scsi_devices[ncr->target_id];
int bus, c = 0;
uint8_t data;
if (scsi_device_get_callback(dev) > 0.0)
ncr_timer_on(ncr_dev, ncr, 1);
else
ncr_timer_on(ncr_dev, ncr, 0);
for (c = 0; c < 10; c++) {
ncr_bus_read(ncr_dev);
@@ -1004,9 +1001,6 @@ ncr_dma_send(ncr5380_t *ncr_dev, ncr_t *ncr)
break;
}
if (c == 10)
return;
/* Data ready. */
data = ncr_dev->buffer[ncr_dev->buffer_pos];
bus = get_bus_host(ncr) & ~BUS_DATAMASK;
@@ -1038,19 +1032,19 @@ ncr_dma_send(ncr5380_t *ncr_dev, ncr_t *ncr)
}
return;
}
ncr_dma_send(ncr_dev, ncr);
ncr_dma_send(ncr_dev, ncr, dev);
}
static void
ncr_dma_initiator_receive(ncr5380_t *ncr_dev, ncr_t *ncr)
ncr_dma_initiator_receive(ncr5380_t *ncr_dev, ncr_t *ncr, scsi_device_t *dev)
{
scsi_device_t *dev = &scsi_devices[ncr->target_id];
int bus, c = 0;
uint8_t temp;
if (scsi_device_get_callback(dev) > 0.0)
ncr_timer_on(ncr_dev, ncr, 1);
else
ncr_timer_on(ncr_dev, ncr, 0);
for (c = 0; c < 10; c++) {
ncr_bus_read(ncr_dev);
@@ -1058,9 +1052,6 @@ ncr_dma_initiator_receive(ncr5380_t *ncr_dev, ncr_t *ncr)
break;
}
if (c == 10)
return;
/* Data ready. */
ncr_bus_read(ncr_dev);
temp = BUS_GETDATA(ncr->cur_bus);
@@ -1091,7 +1082,7 @@ ncr_dma_initiator_receive(ncr5380_t *ncr_dev, ncr_t *ncr)
}
return;
}
ncr_dma_initiator_receive(ncr_dev, ncr);
ncr_dma_initiator_receive(ncr_dev, ncr, dev);
}
static void
@@ -1103,8 +1094,9 @@ ncr_callback(void *priv)
ncr_log("DMA mode=%d, status ctrl = %02x\n", ncr->dma_mode, ncr_dev->status_ctrl);
if (ncr->dma_mode != DMA_IDLE && (ncr->mode & MODE_DMA) && ncr_dev->block_count_loaded && scsi_device_get_callback(dev) <= 0.0)
timer_on_auto(&ncr_dev->timer, 10.0);
if (ncr->dma_mode != DMA_IDLE && (ncr->mode & MODE_DMA) && ncr_dev->block_count_loaded) {
ncr_timer_on(ncr_dev, ncr, 0);
}
if (ncr->data_wait & 1) {
ncr->clear_req = 3;
@@ -1129,7 +1121,7 @@ ncr_callback(void *priv)
if (!ncr_dev->block_count_loaded)
break;
ncr_dma_send(ncr_dev, ncr);
ncr_dma_send(ncr_dev, ncr, dev);
break;
case DMA_INITIATOR_RECEIVE:
@@ -1146,7 +1138,7 @@ ncr_callback(void *priv)
if (!ncr_dev->block_count_loaded)
break;
ncr_dma_initiator_receive(ncr_dev, ncr);
ncr_dma_initiator_receive(ncr_dev, ncr, dev);
break;
}

View File

@@ -16,7 +16,8 @@
add_library(sio OBJECT sio_acc3221.c sio_f82c710.c sio_82091aa.c sio_fdc37c661.c
sio_fdc37c66x.c sio_fdc37c669.c sio_fdc37c93x.c sio_fdc37m60x.c
sio_pc87306.c sio_pc87307.c sio_pc87309.c sio_pc87310.c sio_pc87311.c sio_pc87332.c
sio_prime3c.c sio_w83787f.c sio_w83877f.c sio_w83977f.c sio_um8669f.c
sio_prime3b.c sio_prime3c.c
sio_w83787f.c sio_w83877f.c sio_w83977f.c sio_um8669f.c
sio_vt82c686.c)
if(SIO_DETECT)

292
src/sio/sio_prime3b.c Normal file
View File

@@ -0,0 +1,292 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Emulation of the Goldstar Prime3B Super I/O
*
* Authors: Tiseno100
* Copyright 2021 Tiseno100
*/
#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/timer.h>
#include <86box/device.h>
#include <86box/lpt.h>
#include <86box/serial.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/sio.h>
#define FSR dev->regs[0xa0]
#define ASR dev->regs[0xa1]
#define PDR dev->regs[0xa2]
#define HAS_IDE_FUNCTIONALITY dev->ide_function
#ifdef ENABLE_PRIME3B_LOG
int prime3b_do_log = ENABLE_PRIME3B_LOG;
static void
prime3b_log(const char *fmt, ...)
{
va_list ap;
if (prime3b_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define prime3b_log(fmt, ...)
#endif
typedef struct
{
uint8_t index, regs[256], cfg_lock, ide_function;
uint16_t com3_addr, com4_addr;
fdc_t *fdc_controller;
serial_t *uart[2];
} prime3b_t;
void prime3b_fdc_handler(prime3b_t *dev);
void prime3b_uart_handler(uint8_t num, prime3b_t *dev);
void prime3b_lpt_handler(prime3b_t *dev);
void prime3b_ide_handler(prime3b_t *dev);
void prime3b_enable(prime3b_t *dev);
void prime3b_powerdown(prime3b_t *dev);
static void
prime3b_write(uint16_t addr, uint8_t val, void *priv)
{
prime3b_t *dev = (prime3b_t *)priv;
if (addr == 0x398)
{
dev->index = val;
/* Enter/Escape Configuration Mode */
if (val == 0x33)
dev->cfg_lock = 0;
else if (val == 0xcc)
dev->cfg_lock = 1;
}
else if ((addr == 0x399) && !dev->cfg_lock)
{
switch (dev->index)
{
case 0xa0: /* Function Selection Register (FSR) */
FSR = val;
prime3b_enable(dev);
break;
case 0xa1: /* Address Selection Register (ASR) */
ASR = val;
prime3b_enable(dev);
break;
case 0xa2: /* Power Down Register (PDR) */
dev->regs[0xa2] = val;
break;
case 0xa3: /* Test Mode Register (TMR) */
dev->regs[0xa3] = val;
break;
case 0xa4: /* Miscellaneous Function Register */
dev->regs[0xa4] = val;
switch ((dev->regs[0xa4] >> 6) & 3)
{
case 0:
dev->com3_addr = 0x3e8;
dev->com4_addr = 0x2e8;
break;
case 1:
dev->com3_addr = 0x338;
dev->com4_addr = 0x238;
break;
case 2:
dev->com3_addr = 0x2e8;
dev->com4_addr = 0x2e0;
break;
case 3:
dev->com3_addr = 0x220;
dev->com4_addr = 0x228;
break;
}
break;
case 0xa5: /* ECP Register */
dev->regs[0xa5] = val;
break;
}
}
}
static uint8_t
prime3b_read(uint16_t addr, void *priv)
{
prime3b_t *dev = (prime3b_t *)priv;
return dev->regs[dev->index];
}
void prime3b_fdc_handler(prime3b_t *dev)
{
uint16_t fdc_base = !(ASR & 0x40) ? 0x3f0 : 0x370;
fdc_remove(dev->fdc_controller);
fdc_set_base(dev->fdc_controller, fdc_base);
prime3b_log("Prime3B-FDC: Enabled with base %03x\n", fdc_base);
}
void prime3b_uart_handler(uint8_t num, prime3b_t *dev)
{
uint16_t uart_base;
if ((ASR >> (3 + 2 * num)) & 1)
uart_base = !((ASR >> (2 + 2 * num)) & 1) ? dev->com3_addr : dev->com4_addr;
else
uart_base = !((ASR >> (2 + 2 * num)) & 1) ? 0x3f8 : 0x2f8;
serial_remove(dev->uart[num]);
serial_setup(dev->uart[num], uart_base, 4 - num);
prime3b_log("Prime3B-UART%d: Enabled with base %03x\n", num, uart_base);
}
void prime3b_lpt_handler(prime3b_t *dev)
{
uint16_t lpt_base = (ASR & 2) ? 0x3bc : (!(ASR & 1) ? 0x378 : 0x278);
lpt1_remove();
lpt1_init(lpt_base);
lpt1_irq(7);
prime3b_log("Prime3B-LPT: Enabled with base %03x\n", lpt_base);
}
void prime3b_ide_handler(prime3b_t *dev)
{
ide_pri_disable();
uint16_t ide_base = !(ASR & 0x80) ? 0x1f0 : 0x170;
ide_set_base(0, ide_base);
ide_set_side(0, ide_base + 0x206);
prime3b_log("Prime3B-IDE: Enabled with base %03x and side %03x\n", ide_base, ide_base + 0x206);
}
void prime3b_enable(prime3b_t *dev)
{
/*
Simulate a device enable/disable scenario
Register A0: Function Selection Register (FSR)
Bit 7: Gameport
Bit 6: 4 FDD Enable
Bit 5: IDE
Bit 4: FDC
Bit 3: UART 2
Bit 2: UART 1
Bit 1/0: PIO (0/0 Bidirectional , 0/1 ECP, 1/0 EPP, 1/1 Disabled)
Note: 86Box LPT is simplistic and can't do ECP or EPP.
*/
!(FSR & 3) ? prime3b_lpt_handler(dev) : lpt1_remove();
(FSR & 4) ? prime3b_uart_handler(0, dev) : serial_remove(dev->uart[0]);
(FSR & 8) ? prime3b_uart_handler(1, dev) : serial_remove(dev->uart[1]);
(FSR & 0x10) ? prime3b_fdc_handler(dev) : fdc_remove(dev->fdc_controller);
if (HAS_IDE_FUNCTIONALITY)
(FSR & 0x20) ? prime3b_ide_handler(dev) : ide_pri_disable();
}
void prime3b_powerdown(prime3b_t *dev)
{
/* Note: It can be done more efficiently for sure */
uint8_t old_base = PDR;
if (PDR & 1)
PDR |= 0x1e;
if (PDR & 0x40)
io_removehandler(0x0398, 0x0002, prime3b_read, NULL, NULL, prime3b_write, NULL, NULL, dev);
if (PDR & 2)
fdc_remove(dev->fdc_controller);
if (PDR & 4)
serial_remove(dev->uart[0]);
if (PDR & 8)
serial_remove(dev->uart[1]);
if (PDR & 0x10)
lpt1_remove();
if (PDR & 1)
PDR = old_base;
}
static void
prime3b_close(void *priv)
{
prime3b_t *dev = (prime3b_t *)priv;
free(dev);
}
static void *
prime3b_init(const device_t *info)
{
prime3b_t *dev = (prime3b_t *)malloc(sizeof(prime3b_t));
memset(dev, 0, sizeof(prime3b_t));
/* Avoid conflicting with machines that make no use of the Prime3B Internal IDE */
HAS_IDE_FUNCTIONALITY = info->local;
dev->regs[0xa0] = 3;
dev->fdc_controller = device_add(&fdc_at_device);
dev->uart[0] = device_add_inst(&ns16550_device, 1);
dev->uart[1] = device_add_inst(&ns16550_device, 2);
if (HAS_IDE_FUNCTIONALITY)
device_add(&ide_isa_device);
dev->com3_addr = 0x3e8;
dev->com4_addr = 0x2e8;
fdc_reset(dev->fdc_controller);
prime3b_enable(dev);
io_sethandler(0x0398, 0x0002, prime3b_read, NULL, NULL, prime3b_write, NULL, NULL, dev);
return dev;
}
const device_t prime3b_device = {
"Goldstar Prime3B",
0,
0,
prime3b_init,
prime3b_close,
NULL,
{NULL},
NULL,
NULL,
NULL};
const device_t prime3b_ide_device = {
"Goldstar Prime3B with IDE functionality",
0,
1,
prime3b_init,
prime3b_close,
NULL,
{NULL},
NULL,
NULL,
NULL};

View File

@@ -16,24 +16,43 @@
* Author: Miran Grca, <mgrca8@gmail.com>
* Copyright 2020 Miran Grca.
*/
#include <stdio.h>
#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/device.h>
#include <86box/io.h>
#include <86box/timer.h>
#include <86box/pci.h>
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/lpt.h>
#include <86box/serial.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/sio.h>
#ifdef ENABLE_W83787_LOG
int w83787_do_log = ENABLE_W83787_LOG;
static void
w83787_log(const char *fmt, ...)
{
va_list ap;
if (w83787_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define w83787_log(fmt, ...)
#endif
#define FDDA_TYPE (dev->regs[7] & 3)
#define FDDB_TYPE ((dev->regs[7] >> 2) & 3)
@@ -52,13 +71,14 @@
#define HEFERE ((dev->regs[0xC] >> 5) & 1)
#define HAS_IDE_FUNCTIONALITY dev->ide_function
typedef struct {
uint8_t tries, regs[42];
uint16_t reg_init;
int locked, rw_locked,
cur_reg,
key;
key, ide_function;
fdc_t *fdc;
serial_t *uart[2];
} w83787f_t;
@@ -187,6 +207,17 @@ w83787f_fdc_handler(w83787f_t *dev)
fdc_set_base(dev->fdc, (dev->regs[0] & 0x10) ? 0x03f0 : 0x0370);
}
static void
w83787f_ide_handler(w83787f_t *dev)
{
ide_pri_disable();
if(dev->regs[0] & 0x80)
{
ide_set_base(0, (dev->regs[0] & 0x40) ? 0x1f0 : 0x170);
ide_set_side(0, (dev->regs[0] & 0x40) ? 0x3f6 : 0x376);
ide_pri_enable();
}
}
static void
w83787f_write(uint16_t port, uint8_t val, void *priv)
@@ -219,6 +250,8 @@ w83787f_write(uint16_t port, uint8_t val, void *priv)
switch (dev->cur_reg) {
case 0:
if ((valxor & 0xc0) && (HAS_IDE_FUNCTIONALITY))
w83787f_ide_handler(dev);
if (valxor & 0x30)
w83787f_fdc_handler(dev);
if (valxor & 0x0c)
@@ -281,7 +314,7 @@ w83787f_write(uint16_t port, uint8_t val, void *priv)
w83787f_lpt_handler(dev);
break;
case 0xB:
pclog("Writing %02X to CRB\n", val);
w83787_log("Writing %02X to CRB\n", val);
break;
case 0xC:
if (valxor & 0x20)
@@ -319,6 +352,14 @@ w83787f_reset(w83787f_t *dev)
lpt1_init(0x378);
lpt1_irq(7);
if(HAS_IDE_FUNCTIONALITY)
{
ide_pri_disable();
ide_set_base(0, 0x1f0);
ide_set_side(0, 0x3f6);
ide_pri_enable();
}
fdc_reset(dev->fdc);
memset(dev->regs, 0, 0x2A);
@@ -358,13 +399,17 @@ w83787f_init(const device_t *info)
w83787f_t *dev = (w83787f_t *) malloc(sizeof(w83787f_t));
memset(dev, 0, sizeof(w83787f_t));
HAS_IDE_FUNCTIONALITY = !!(info->local & 0x10);
dev->fdc = device_add(&fdc_at_winbond_device);
dev->uart[0] = device_add_inst(&ns16550_device, 1);
dev->uart[1] = device_add_inst(&ns16550_device, 2);
if(HAS_IDE_FUNCTIONALITY)
device_add(&ide_isa_device);
dev->reg_init = info->local;
dev->reg_init = info->local & 0x0f;
w83787f_reset(dev);
return dev;
@@ -379,3 +424,12 @@ const device_t w83787f_device = {
{ NULL }, NULL, NULL,
NULL
};
const device_t w83787f_ide_device = {
"Winbond W83787F/IF Super I/O with IDE functionality",
0,
0x19,
w83787f_init, w83787f_close, NULL,
{ NULL }, NULL, NULL,
NULL
};

View File

@@ -514,6 +514,12 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p)
if (voodoo->initEnable & 0x01)
{
voodoo->fbiInit0 = val;
thread_wait_mutex(voodoo->force_blit_mutex);
voodoo->can_blit = (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) ? 1 : 0;
if (!voodoo->can_blit)
voodoo->force_blit_count = 0;
thread_release_mutex(voodoo->force_blit_mutex);
if (voodoo->set->nr_cards == 2)
svga_set_override(voodoo->svga, (voodoo->set->voodoos[0]->fbiInit0 | voodoo->set->voodoos[1]->fbiInit0) & 1);
else
@@ -877,6 +883,24 @@ static void voodoo_speed_changed(void *p)
// voodoo_log("Voodoo read_time=%i write_time=%i burst_time=%i %08x %08x\n", voodoo->read_time, voodoo->write_time, voodoo->burst_time, voodoo->fbiInit1, voodoo->fbiInit4);
}
static void voodoo_force_blit(void *p)
{
voodoo_set_t *voodoo_set = (voodoo_set_t *)p;
thread_wait_mutex(voodoo_set->voodoos[0]->force_blit_mutex);
if(voodoo_set->voodoos[0]->can_blit) {
voodoo_set->voodoos[0]->force_blit_count++;
}
thread_release_mutex(voodoo_set->voodoos[0]->force_blit_mutex);
if(voodoo_set->nr_cards == 2) {
thread_wait_mutex(voodoo_set->voodoos[1]->force_blit_mutex);
if(voodoo_set->voodoos[1]->can_blit) {
voodoo_set->voodoos[1]->force_blit_count++;
}
thread_release_mutex(voodoo_set->voodoos[1]->force_blit_mutex);
}
}
void *voodoo_card_init()
{
int c;
@@ -1014,6 +1038,10 @@ void *voodoo_card_init()
voodoo->disp_buffer = 0;
voodoo->draw_buffer = 1;
voodoo->force_blit_count = 0;
voodoo->can_blit = 0;
voodoo->force_blit_mutex = thread_create_mutex_with_spin_count(MUTEX_DEFAULT_SPIN_COUNT);
return voodoo;
}
@@ -1128,6 +1156,10 @@ void *voodoo_2d3d_card_init(int type)
voodoo->disp_buffer = 0;
voodoo->draw_buffer = 1;
voodoo->force_blit_count = 0;
voodoo->can_blit = 0;
voodoo->force_blit_mutex = thread_create_mutex_with_spin_count(MUTEX_DEFAULT_SPIN_COUNT);
return voodoo;
}
@@ -1241,6 +1273,9 @@ void voodoo_card_close(voodoo_t *voodoo)
free(voodoo->tex_mem[1]);
free(voodoo->tex_mem[0]);
}
thread_close_mutex(voodoo->force_blit_mutex);
free(voodoo);
}
@@ -1386,6 +1421,6 @@ const device_t voodoo_device =
NULL,
{ NULL },
voodoo_speed_changed,
NULL,
voodoo_force_blit,
voodoo_config
};

View File

@@ -645,7 +645,16 @@ skip_draw:
{
if (voodoo->line == voodoo->v_disp)
{
if (voodoo->dirty_line_high > voodoo->dirty_line_low)
int force_blit = 0;
thread_wait_mutex(voodoo->force_blit_mutex);
if(voodoo->force_blit_count) {
force_blit = 1;
if(--voodoo->force_blit_count < 0)
voodoo->force_blit_count = 0;
}
thread_release_mutex(voodoo->force_blit_mutex);
if (voodoo->dirty_line_high > voodoo->dirty_line_low || force_blit)
svga_doblit(0, voodoo->v_disp, voodoo->h_disp, voodoo->v_disp-1, voodoo->svga);
if (voodoo->clutData_dirty)
{

View File

@@ -81,6 +81,9 @@ ifeq ($(DEV_BUILD), y)
ifndef M1489
M1489 := y
endif
ifndef M154X
M154X := y
endif
ifndef M6117
M6117 := y
endif
@@ -154,6 +157,9 @@ else
ifndef M1489
M1489 := n
endif
ifndef M154X
M154X := n
endif
ifndef M6117
M6117 := n
endif
@@ -553,6 +559,11 @@ OPTS += -DUSE_M1489
DEVBROBJ += ali1489.o
endif
ifeq ($(M1489), y)
OPTS += -DUSE_M154X
DEVBROBJ += ali1531.o ali1543.o
endif
ifeq ($(M6117), y)
OPTS += -DUSE_M6117
DEVBROBJ += ali6117.o
@@ -604,10 +615,10 @@ CPUOBJ := cpu.o cpu_table.o \
x86seg.o x87.o x87_timings.o \
$(DYNARECOBJ)
CHIPSETOBJ := acc2168.o cs8230.o ali1429.o headland.o intel_82335.o cs4031.o \
CHIPSETOBJ := acc2168.o cs8230.o ali1217.o ali1429.o headland.o intel_82335.o cs4031.o \
intel_420ex.o intel_4x0.o intel_sio.o intel_piix.o ioapic.o \
neat.o opti495.o opti895.o opti5x7.o scamp.o scat.o via_vt82c49x.o via_vt82c505.o \
sis_85c310.o sis_85c4xx.o sis_85c496.o sis_85c50x.o opti283.o opti291.o umc491.o \
sis_85c310.o sis_85c4xx.o sis_85c496.o sis_85c50x.o opti283.o opti291.o \
via_apollo.o via_pipc.o wd76c10.o vl82c480.o
MCHOBJ := machine.o machine_table.o \
@@ -641,7 +652,7 @@ SIOOBJ := sio_acc3221.o \
sio_f82c710.o sio_82091aa.o \
sio_fdc37c661.o sio_fdc37c66x.o sio_fdc37c669.o sio_fdc37c93x.o sio_fdc37m60x.o \
sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87310.o sio_pc87311.o sio_pc87332.o \
sio_prime3c.o \
sio_prime3b.o sio_prime3c.o \
sio_w83787f.o \
sio_w83877f.o sio_w83977f.o \
sio_um8669f.o \

View File

@@ -133,17 +133,23 @@ thread_destroy_event(event_t *arg)
mutex_t *
thread_create_mutex(void)
{
return((mutex_t*)CreateMutex(NULL, FALSE, NULL));
{
mutex_t *mutex = malloc(sizeof(CRITICAL_SECTION));
InitializeCriticalSection(mutex);
return mutex;
}
void
thread_close_mutex(mutex_t *mutex)
mutex_t *
thread_create_mutex_with_spin_count(unsigned int spin_count)
{
if (mutex == NULL) return;
mutex_t *mutex = malloc(sizeof(CRITICAL_SECTION));
CloseHandle((HANDLE)mutex);
InitializeCriticalSectionAndSpinCount(mutex, spin_count);
return mutex;
}
@@ -152,11 +158,11 @@ thread_wait_mutex(mutex_t *mutex)
{
if (mutex == NULL) return(0);
DWORD dwres = WaitForSingleObject((HANDLE)mutex, INFINITE);
LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)mutex;
if (dwres == WAIT_OBJECT_0) return(1);
EnterCriticalSection(critsec);
return(0);
return 1;
}
@@ -165,5 +171,22 @@ thread_release_mutex(mutex_t *mutex)
{
if (mutex == NULL) return(0);
return(!!ReleaseMutex((HANDLE)mutex));
LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)mutex;
LeaveCriticalSection(critsec);
return 1;
}
void
thread_close_mutex(mutex_t *mutex)
{
if (mutex == NULL) return;
LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)mutex;
DeleteCriticalSection(critsec);
free(critsec);
}