Merge branch 'master' of ssh://github.com/86Box/86Box into feature/mtrr

# Conflicts:
#	src/include/86box/machine.h
#	src/machine/machine_table.c
#	src/mem/mem.c
This commit is contained in:
RichardG867
2020-06-19 13:41:26 -03:00
398 changed files with 9515 additions and 13938 deletions

View File

@@ -10,8 +10,6 @@
# settings, so we can avoid changing the main one for all of
# our local setups.
#
# Version: @(#)Makefile.local 1.0.22 2019/10/20
#
# Author: Fred N. van Kempen, <decwiz@yahoo.com>
#
@@ -35,15 +33,21 @@ STUFF :=
# -DENABLE_VRAM_DUMP enables Video Ram dumping.
# -DENABLE_LOG_BREAKPOINT enables extra logging.
# Root logging:
# -DENABLE_ACPI_LOG=N sets logging level at N.
# -DENABLE_APM_LOG=N sets logging level at N.
# -DENABLE_BUGGER_LOG=N sets logging level at N.
# -DENABLE_CONFIG_LOG=N sets logging level at N.
# -DENABLE_DDMA_LOG=N sets logging level at N.
# -DENABLE_DEVICE_LOG=N sets logging level at N.
# -DENABLE_DMA_LOG=N sets logging level at N.
# -DENABLE_IO_LOG=N sets logging level at N.
# -DENABLE_PIIX_LOG=N sets logging level at N.
# -DENABLE_IOAPIC_LOG=N sets logging level at N.
# -DENABLE_ISAMEM_LOG=N sets logging level at N.
# -DENABLE_ISARTC_LOG=N sets logging level at N.
# -DENABLE_KEYBOARD_AT_LOG=N sets logging level at N.
# -DENABLE_KEYBOARD_XT_LOG=N sets logging level at N.
# -DENABLE_LM75_LOG=N sets logging level at N.
# -DENABLE_LM78_LOG=N sets logging level at N.
# -DENABLE_MEM_LOG=N sets logging level at N.
# -DENABLE_MOUSE_LOG=N sets logging level at N.
# -DENABLE_MOUSE_BUS_LOG=N sets logging level at N.
@@ -53,30 +57,41 @@ STUFF :=
# -DENABLE_PC_LOG=N sets logging level at N.
# -DENABLE_PCI_LOG=N sets logging level at N.
# -DENABLE_PIC_LOG=N sets logging level at N.
# -DENABLE_PIT_LOG=N sets logging level at N.
# -DENABLE_POSTCARD_LOG=N sets logging level at N.
# -DENABLE_ROM_LOG=N sets logging level at N.
# -DENABLE_SERIAL_LOG=N sets logging level at N.
# -DENABLE_SMBUS_LOG=N sets logging level at N.
# -DENABLE_SMBUS_PIIX4_LOG=N sets logging level at N.
# -DENABLE_SPD_LOG=N sets logging level at N.
# -DENABLE_USB_LOG=N sets logging level at N.
# -DENABLE_VNC_LOG=N sets logging level at N.
# -DENABLE_VNC_KEYMAP_LOG=N sets logging level at N.
# cdrom/ logging:
# -DENABLE_CDROM_LOG=N sets logging level at N.
# -DENABLE_CDROM_DOSBOX_LOG=N sets logging level at N.
# -DENABLE_CDROM_IMAGE_LOG=N sets logging level at N.
# -DENABLE_CDROM_IMAGE_BACKEND_LOG=N sets logging level at N.
# chipset/ logging:
# -DENABLE_I420EX_LOG=N sets logging level at N.
# -DENABLE_NEAT_LOG=N sets logging level at N.
# -DENABLE_PIIX_LOG=N sets logging level at N.
# -DENABLE_SIO_LOG=N sets logging level at N.
# codegen/, codegen_new/, cpu/ logging:
# -DENABLE_X86SEG_LOG=N sets logging level at N.
# cpu/ logging:
# -DENABLE_386_LOG=N sets logging level at N.
# -DENABLE_386_COMMON_LOG=N sets logging level at N.
# -DENABLE_386_DYNAREC_LOG=N sets logging level at N.
# -DENABLE_808X_LOG=N sets logging level at N.
# -DENABLE_CPU_LOG=N sets logging level at N.
# -DENABLE_FPU_LOG=N sets logging level at N.
# -DENABLE_X86SEG_LOG=N sets logging level at N.
# cpu_new/ logging:
# -DENABLE_386_COMMON_LOG=N sets logging level at N.
# chipset/ logging:
# -DENABLE_NEAT_LOG=N sets logging level at N.
# disk/ logging:
# -DENABLE_ESDI_AT_LOG=N sets logging level at N.
# -DENABLE_ESDI_MCA_LOG=N sets logging level at N.
# -DENABLE_HDC_LOG=N sets logging level at N.
# -DENABLE_HDD_IMAGE_LOG=N sets logging level at N.
# -DENABLE_IDE_LOG=N sets logging level at N.
# -DENABLE_MO_LOG=N sets logging level at N.
# -DENABLE_SFF_LOG=N sets logging level at N.
# -DENABLE_ST506_AT_LOG=N sets logging level at N.
# -DENABLE_ST506_XT_LOG=N sets logging level at N.
@@ -109,15 +124,19 @@ STUFF :=
# -DENABLE_NETWORK_LOG=N sets logging level at N.
# -DENABLE_NIC_LOG=N sets logging level at N.
# -DENABLE_PCAP_LOG=N sets logging level at N.
# -DENABLE_PCNET_LOG=N sets logging level at N.
# -DENABLE_SLIRP_LOG=N sets logging level at N.
# -DENABLE_WD_LOG=N sets logging level at N.
# printer/ logging:
# -DENABLE_ESCP_LOG=N sets logging level at N.
# scsi/ logging:
# -DENABLE_AHA154X_LOG=N sets logging level at N.
# -DENABLE_BUSLOGIC_LOG=N sets logging level at N.
# -DENABLE_SCSI_CDROM_LOG=N sets logging level at N.
# -DENABLE_SCSI_DISK_LOG=N sets logging level at N.
# -DENABLE_NCR5380_LOG=N sets logging level at N.
# -DENABLE_NCR53C8XX_LOG=N sets logging level at N.
# -DENABLE_SCSI_CDROM_LOG=N sets logging level at N.
# -DENABLE_SCSI_DISK_LOG=N sets logging level at N.
# -DENABLE_SPOCK_LOG=N sets logging level at N.
# -DENABLE_X54X_LOG=N sets logging level at N.
# sound/ logging:
# -DENABLE_ADLIB_LOG=N sets logging level at N.
@@ -139,15 +158,13 @@ STUFF :=
# -DENABLE_PGC_LOG=N sets logging level at N.
# -DENABLE_S3_VIRGE_LOG=N sets logging level at N.
# -DENABLE_VID_TABLE_LOG=N sets logging level at N.
# -DENABLE_VIDEO_LOG=N sets logging level at N.
# -DENABLE_VOODOO_LOG=N sets logging level at N.
# -DENABLE_VRAM_DUMP=N sets logging level at N.
# win/ logging:
# -DENABLE_WIN_LOG=N sets logging level at N.
# -DENABLE_D2D_LOG=N sets logging level at N.
# -DENABLE_DDRAW_LOG=N sets logging level at N.
# -DENABLE_DISCORD_LOG=N sets logging level at N.
# -DENABLE_DYNLD_LOG=N sets logging level at N.
# -DENABLE_JOYSTICK_LOG=N sets logging level at N.
# -DENABLE_LOG_BREAKPOINT=N sets logging level at N.
# -DENABLE_LOG_TOGGLES=N sets logging level at N.
# -DENABLE_SDL_LOG=N sets logging level at N.
# -DENABLE_SETTINGS_LOG=N sets logging level at N.

View File

@@ -125,8 +125,10 @@ acpi_reg_read_intel(int size, uint16_t addr, void *p)
case 0x08: case 0x09: case 0x0a: case 0x0b:
/* PMTMR - Power Management Timer Register (IO) */
ret = (dev->regs.timer_val >> shift32) & 0xff;
#ifdef USE_DYNAREC
if (cpu_use_dynarec)
update_tsc();
#endif
break;
case 0x0c: case 0x0d:
/* GPSTS - General Purpose Status Register (IO) */
@@ -213,8 +215,10 @@ acpi_reg_read_via(int size, uint16_t addr, void *p)
case 0x08: case 0x09: case 0x0a: case 0x0b:
/* PMTMR - Power Management Timer Register (IO) */
ret = (dev->regs.timer_val >> shift32) & 0xff;
#ifdef USE_DYNAREC
if (cpu_use_dynarec)
update_tsc();
#endif
break;
case 0x10: case 0x11: case 0x12: case 0x13:
/* PCNTRL - Processor Control Register (IO) */

View File

@@ -27,12 +27,14 @@
#include <86box/cdrom.h>
#include <86box/cdrom_image.h>
#include <86box/plat.h>
#include <86box/scsi_device.h>
#include <86box/sound.h>
/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong:
there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start
of the audio while audio still plays. With an absolute conversion, the counter is fine. */
#undef MSFtoLBA
#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f)
#define RAW_SECTOR_SIZE 2352
@@ -1171,6 +1173,9 @@ cdrom_close(void)
for (i = 0; i < CDROM_NUM; i++) {
dev = &cdrom[i];
if (dev->bus_type == CDROM_BUS_SCSI)
memset(&scsi_devices[dev->scsi_device_id], 0x00, sizeof(scsi_device_t));
if (dev->close)
dev->close(dev->priv);

View File

@@ -83,14 +83,14 @@ bin_read(void *p, uint8_t *buffer, uint64_t seek, size_t count)
return 0;
if (fseeko64(tf->file, seek, SEEK_SET) == -1) {
#ifdef ENABLE_cdrom_image_backend_log
#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG
cdrom_image_backend_log("CDROM: binary_read failed during seek!\n");
#endif
return 0;
}
if (fread(buffer, count, 1, tf->file) != 1) {
#ifdef ENABLE_cdrom_image_backend_log
#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG
cdrom_image_backend_log("CDROM: binary_read failed during read!\n");
#endif
return 0;
@@ -953,7 +953,7 @@ cdi_load_cue(cd_img_t *cdi, const wchar_t *cuefile)
trk.file = track_file_init(filename, &error);
}
if (error) {
#ifdef ENABLE_cdrom_image_backend_log
#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG
cdrom_image_backend_log("CUE: cannot open fille '%ls' in cue sheet!\n",
filename);
#endif
@@ -971,7 +971,7 @@ cdi_load_cue(cd_img_t *cdi, const wchar_t *cuefile)
/* Ignored commands. */
success = 1;
} else {
#ifdef ENABLE_cdrom_image_backend_log
#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG
cdrom_image_backend_log("CUE: unsupported command '%s' in cue sheet!\n",
command.c_str());
#endif

View File

@@ -142,6 +142,11 @@ static void
cs8230_write, NULL, NULL,
cs8230);
if (mem_size > 768) {
mem_mapping_set_addr(&ram_mid_mapping, 0xa0000, mem_size > 1024 ? 0x60000 : 0x20000 + (mem_size - 768) * 1024);
mem_mapping_set_exec(&ram_mid_mapping, ram + 0xa0000);
}
return cs8230;
}

573
src/chipset/intel_420ex.c Normal file
View File

@@ -0,0 +1,573 @@
/*
* 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.
*
* Emulation of Intel 82420EX chipset that acts as both the
* northbridge and the southbridge.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2020 Miran Grca.
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/io.h>
#include <86box/apm.h>
#include <86box/dma.h>
#include <86box/mem.h>
#include <86box/pci.h>
#include <86box/timer.h>
#include <86box/pit.h>
#include <86box/port_92.h>
#include <86box/hdc_ide.h>
#include <86box/hdc.h>
#include <86box/machine.h>
#include <86box/chipset.h>
#define MEM_STATE_SHADOW_R 0x01
#define MEM_STATE_SHADOW_W 0x02
#define MEM_STATE_SMRAM 0x04
typedef struct
{
uint8_t id, smram_locked,
regs[256];
uint16_t timer_base,
timer_latch;
double fast_off_period;
pc_timer_t timer, fast_off_timer;
apm_t * apm;
port_92_t * port_92;
} i420ex_t;
#ifdef ENABLE_I420EX_LOG
int i420ex_do_log = ENABLE_I420EX_LOG;
static void
i420ex_log(const char *fmt, ...)
{
va_list ap;
if (i420ex_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define i420ex_log(fmt, ...)
#endif
static void
i420ex_map(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;
}
flushmmucache_nopc();
}
static void
i420ex_smram_map(int smm, uint32_t addr, uint32_t size, int is_smram)
{
mem_set_mem_state_smram(smm, addr, size, is_smram);
flushmmucache();
}
static void
i420ex_smram_handler_phase0(void)
{
/* Disable low extended SMRAM. */
if (smram[0].size != 0x00000000) {
i420ex_smram_map(0, smram[0].host_base, smram[0].size, 0);
i420ex_smram_map(1, smram[0].host_base, smram[0].size, 0);
memset(&smram[0], 0x00, sizeof(smram_t));
mem_mapping_disable(&ram_smram_mapping[0]);
}
}
static void
i420ex_smram_handler_phase1(i420ex_t *dev)
{
uint8_t *regs = (uint8_t *) dev->regs;
uint32_t base = 0x000a0000;
uint32_t size = 0x00010000;
switch (regs[0x70] & 0x07) {
case 0: case 1:
default:
base = size = 0x00000000;
break;
case 2:
base = 0x000a0000;
smram[0].host_base = 0x000a0000;
smram[0].ram_base = 0x000a0000;
break;
case 3:
base = 0x000b0000;
smram[0].host_base = 0x000b0000;
smram[0].ram_base = 0x000b0000;
break;
case 4:
base = 0x000c0000;
smram[0].host_base = 0x000c0000;
smram[0].ram_base = 0x000a0000;
break;
case 5:
base = 0x000d0000;
smram[0].host_base = 0x000d0000;
smram[0].ram_base = 0x000a0000;
break;
case 6:
base = 0x000e0000;
smram[0].host_base = 0x000e0000;
smram[0].ram_base = 0x000a0000;
break;
case 7:
base = 0x000f0000;
smram[0].host_base = 0x000f0000;
smram[0].ram_base = 0x000a0000;
break;
}
smram[0].size = size;
if (size != 0x00000000) {
mem_mapping_set_addr(&ram_smram_mapping[0], smram[0].host_base, 0x00010000);
mem_mapping_set_exec(&ram_smram_mapping[0], ram + smram[0].ram_base);
/* If OSS = 1 and LSS = 0, extended SMRAM is visible outside SMM. */
i420ex_smram_map(0, base, size, (regs[0x70] & 0x70) == 0x40);
/* If the register is set accordingly, disable the mapping also in SMM. */
i420ex_smram_map(1, base, size, !(regs[0x70] & 0x20));
}
}
static void
i420ex_write(int func, int addr, uint8_t val, void *priv)
{
i420ex_t *dev = (i420ex_t *) priv;
if (func > 0)
return;
if (((addr >= 0x0f) && (addr < 0x4c)) && (addr != 0x40))
return;
/* The IB (original) variant of the I420EX has no PCI IRQ steering. */
if ((addr >= 0x60) && (addr <= 0x63) && (dev->id < 0x03))
return;
switch (addr) {
case 0x05:
dev->regs[addr] = (val & 0x01);
break;
case 0x07:
dev->regs[addr] &= ~(val & 0xf0);
break;
case 0x40:
dev->regs[addr] = (val & 0x7f);
break;
case 0x44:
dev->regs[addr] = (val & 0x07);
break;
case 0x48:
dev->regs[addr] = (val & 0x3f);
#ifdef USE_420EX_IDE
ide_pri_disable();
switch (val & 0x03) {
case 0x01:
ide_set_base(0, 0x01f0);
ide_set_side(0, 0x03f6);
ide_pri_enable();
break;
case 0x02:
ide_set_base(0, 0x0170);
ide_set_side(0, 0x0376);
ide_pri_enable();
break;
}
#endif
break;
case 0x49: case 0x53:
dev->regs[addr] = (val & 0x1f);
break;
case 0x4c: case 0x51:
case 0x57:
case 0x60: case 0x61: case 0x62: case 0x63:
case 0x64:
case 0x68: case 0x69:
dev->regs[addr] = val;
if (addr == 0x4c) {
dma_alias_remove();
if (!(val & 0x80))
dma_alias_set();
}
break;
case 0x4d:
dev->regs[addr] = (dev->regs[addr] & 0xef) | (val & 0x10);
break;
case 0x4e:
dev->regs[addr] = (val & 0xf7);
break;
case 0x50:
dev->regs[addr] = (val & 0x0f);
break;
case 0x52:
dev->regs[addr] = (val & 0x7f);
break;
case 0x56:
dev->regs[addr] = (val & 0x3e);
break;
case 0x59: /* PAM0 */
if ((dev->regs[0x59] ^ val) & 0xf0) {
i420ex_map(0xf0000, 0x10000, val >> 4);
shadowbios = (val & 0x10);
}
dev->regs[0x59] = val & 0xf0;
break;
case 0x5a: /* PAM1 */
if ((dev->regs[0x5a] ^ val) & 0x0f)
i420ex_map(0xc0000, 0x04000, val & 0xf);
if ((dev->regs[0x5a] ^ val) & 0xf0)
i420ex_map(0xc4000, 0x04000, val >> 4);
dev->regs[0x5a] = val;
break;
case 0x5b: /*PAM2 */
if ((dev->regs[0x5b] ^ val) & 0x0f)
i420ex_map(0xc8000, 0x04000, val & 0xf);
if ((dev->regs[0x5b] ^ val) & 0xf0)
i420ex_map(0xcc000, 0x04000, val >> 4);
dev->regs[0x5b] = val;
break;
case 0x5c: /*PAM3 */
if ((dev->regs[0x5c] ^ val) & 0x0f)
i420ex_map(0xd0000, 0x04000, val & 0xf);
if ((dev->regs[0x5c] ^ val) & 0xf0)
i420ex_map(0xd4000, 0x04000, val >> 4);
dev->regs[0x5c] = val;
break;
case 0x5d: /* PAM4 */
if ((dev->regs[0x5d] ^ val) & 0x0f)
i420ex_map(0xd8000, 0x04000, val & 0xf);
if ((dev->regs[0x5d] ^ val) & 0xf0)
i420ex_map(0xdc000, 0x04000, val >> 4);
dev->regs[0x5d] = val;
break;
case 0x5e: /* PAM5 */
if ((dev->regs[0x5e] ^ val) & 0x0f)
i420ex_map(0xe0000, 0x04000, val & 0xf);
if ((dev->regs[0x5e] ^ val) & 0xf0)
i420ex_map(0xe4000, 0x04000, val >> 4);
dev->regs[0x5e] = val;
break;
case 0x5f: /* PAM6 */
if ((dev->regs[0x5f] ^ val) & 0x0f)
i420ex_map(0xe8000, 0x04000, val & 0xf);
if ((dev->regs[0x5f] ^ val) & 0xf0)
i420ex_map(0xec000, 0x04000, val >> 4);
dev->regs[0x5f] = val;
break;
case 0x66: case 0x67:
i420ex_log("Set IRQ routing: INT %c -> %02X\n", 0x41 + (addr & 0x01), val);
dev->regs[addr] = val & 0x8f;
if (val & 0x80)
pci_set_irq_routing(PCI_INTA + (addr & 0x01), PCI_IRQ_DISABLED);
else
pci_set_irq_routing(PCI_INTA + (addr & 0x01), val & 0xf);
break;
case 0x70: /* SMRAM */
i420ex_smram_handler_phase0();
if (dev->smram_locked)
dev->regs[0x70] = (dev->regs[0x70] & 0xdf) | (val & 0x20);
else {
dev->regs[0x70] = (dev->regs[0x70] & 0x88) | (val & 0x77);
dev->smram_locked = (val & 0x10);
if (dev->smram_locked)
dev->regs[0x70] &= 0xbf;
}
i420ex_smram_handler_phase1(dev);
break;
case 0xa0:
dev->regs[addr] = val & 0x1f;
apm_set_do_smi(dev->apm, !!(val & 0x01) && !!(dev->regs[0xa2] & 0x80));
switch ((val & 0x18) >> 3) {
case 0x00:
dev->fast_off_period = PCICLK * 32768.0 * 60000.0;
break;
case 0x01:
default:
dev->fast_off_period = 0.0;
break;
case 0x02:
dev->fast_off_period = PCICLK;
break;
case 0x03:
dev->fast_off_period = PCICLK * 32768.0;
break;
}
cpu_fast_off_count = dev->regs[0xa8] + 1;
timer_disable(&dev->fast_off_timer);
if (dev->fast_off_period != 0.0)
timer_on_auto(&dev->fast_off_timer, dev->fast_off_period);
break;
case 0xa2:
dev->regs[addr] = val & 0xff;
apm_set_do_smi(dev->apm, !!(dev->regs[0xa0] & 0x01) && !!(val & 0x80));
break;
case 0xaa:
dev->regs[addr] &= (val & 0xff);
break;
case 0xac: case 0xae:
dev->regs[addr] = val & 0xff;
break;
case 0xa4:
dev->regs[addr] = val & 0xfb;
cpu_fast_off_flags = (cpu_fast_off_flags & 0xffffff00) | dev->regs[addr];
break;
case 0xa5:
dev->regs[addr] = val;
cpu_fast_off_flags = (cpu_fast_off_flags & 0xffff00ff) | (dev->regs[addr] << 8);
break;
case 0xa7:
dev->regs[addr] = val & 0xe0;
cpu_fast_off_flags = (cpu_fast_off_flags & 0x00ffffff) | (dev->regs[addr] << 24);
break;
case 0xa8:
dev->regs[addr] = val & 0xff;
cpu_fast_off_val = val;
cpu_fast_off_count = val + 1;
timer_disable(&dev->fast_off_timer);
if (dev->fast_off_period != 0.0)
timer_on_auto(&dev->fast_off_timer, dev->fast_off_period);
break;
}
}
static uint8_t
i420ex_read(int func, int addr, void *priv)
{
i420ex_t *dev = (i420ex_t *) priv;
uint8_t ret;
ret = 0xff;
if (func == 0)
ret = dev->regs[addr];
return ret;
}
static void
i420ex_reset_hard(void *priv)
{
i420ex_t *dev = (i420ex_t *) priv;
memset(dev->regs, 0, 256);
dev->regs[0x00] = 0x86; dev->regs[0x01] = 0x80; /*Intel*/
dev->regs[0x02] = 0x86; dev->regs[0x03] = 0x04; /*82378IB (I420EX)*/
dev->regs[0x04] = 0x07;
dev->regs[0x07] = 0x02;
dev->regs[0x08] = dev->id;
dev->regs[0x4c] = 0x4d;
dev->regs[0x4e] = 0x03;
/* Bits 2:1 of register 50h are 00 is 25 MHz, and 01 if 33 MHz, 10 and 11 are reserved. */
if (cpu_busspeed >= 33333333)
dev->regs[0x50] |= 0x02;
dev->regs[0x51] = 0x80;
dev->regs[0x60] = dev->regs[0x61] = dev->regs[0x62] = dev->regs[0x63] = dev->regs[0x64] = 0x01;
dev->regs[0x66] = 0x80; dev->regs[0x67] = 0x80;
dev->regs[0x69] = 0x02;
dev->regs[0xa0] = 0x08;
dev->regs[0xa8] = 0x0f;
mem_set_mem_state(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
mem_set_mem_state_smm(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
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);
}
static void
i420ex_apm_out(uint16_t port, uint8_t val, void *p)
{
i420ex_t *dev = (i420ex_t *) p;
if (dev->apm->do_smi)
dev->regs[0xaa] |= 0x80;
}
static void
i420ex_fast_off_count(void *priv)
{
i420ex_t *dev = (i420ex_t *) priv;
cpu_fast_off_count--;
if (cpu_fast_off_count == 0) {
smi_line = 1;
dev->regs[0xaa] |= 0x20;
cpu_fast_off_count = dev->regs[0xa8] + 1;
}
timer_on_auto(&dev->fast_off_timer, dev->fast_off_period);
}
static void
i420ex_reset(void *p)
{
i420ex_t *dev = (i420ex_t *) p;
int i;
for (i = 0; i < 7; i++)
i420ex_write(0, 0x59 + i, 0x00, p);
for (i = 0; i <= 4; i++)
i420ex_write(0, 0x60 + i, 0x01, p);
dev->regs[0x70] &= 0xef; /* Forcibly unlock the SMRAM register. */
dev->smram_locked = 0;
i420ex_write(0, 0x70, 0x00, p);
mem_set_mem_state(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
mem_set_mem_state_smm(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
i420ex_write(0, 0xa0, 0x08, p);
i420ex_write(0, 0xa2, 0x00, p);
i420ex_write(0, 0xa4, 0x00, p);
i420ex_write(0, 0xa5, 0x00, p);
i420ex_write(0, 0xa6, 0x00, p);
i420ex_write(0, 0xa7, 0x00, p);
i420ex_write(0, 0xa8, 0x0f, p);
}
static void
i420ex_close(void *p)
{
i420ex_t *dev = (i420ex_t *)p;
free(dev);
}
static void
i420ex_speed_changed(void *priv)
{
i420ex_t *dev = (i420ex_t *) priv;
int te;
te = timer_is_enabled(&dev->timer);
timer_disable(&dev->timer);
if (te)
timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC);
if (dev->id == 0x03) {
te = timer_is_enabled(&dev->fast_off_timer);
timer_stop(&dev->fast_off_timer);
if (te)
timer_on_auto(&dev->fast_off_timer, dev->fast_off_period);
}
}
static void *
i420ex_init(const device_t *info)
{
i420ex_t *dev = (i420ex_t *) malloc(sizeof(i420ex_t));
memset(dev, 0, sizeof(i420ex_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, i420ex_read, i420ex_write, dev);
dev->id = info->local;
timer_add(&dev->fast_off_timer, i420ex_fast_off_count, dev, 0);
i420ex_reset_hard(dev);
cpu_fast_off_flags = 0x00000000;
cpu_fast_off_val = dev->regs[0xa8];
cpu_fast_off_count = cpu_fast_off_val + 1;
dev->apm = device_add(&apm_pci_device);
/* APM intercept handler to update 82420EX SMI status on APM SMI. */
io_sethandler(0x00b2, 0x0001, NULL, NULL, NULL, i420ex_apm_out, NULL, NULL, dev);
dev->port_92 = device_add(&port_92_pci_device);
dma_alias_set();
#ifdef USE_420EX_IDE
device_add(&ide_pci_device);
ide_pri_disable();
#else
device_add(&ide_pci_2ch_device);
#endif
return dev;
}
const device_t i420ex_device =
{
"Intel 82420EX",
DEVICE_PCI,
0x00,
i420ex_init,
i420ex_close,
i420ex_reset,
NULL,
i420ex_speed_changed,
NULL,
NULL
};

View File

@@ -6,12 +6,11 @@
*
* This file is part of the 86Box distribution.
*
* Implementation of the Intel PCISet chips from 420TX to 440FX.
* Implementation of the Intel PCISet chips from 420TX to 440BX.
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2019,2020 Miran Grca.
*/
@@ -38,21 +37,22 @@ enum
INTEL_430LX,
INTEL_430NX,
INTEL_430FX,
INTEL_430FX_PB640,
INTEL_430HX,
INTEL_430VX,
INTEL_430TX,
INTEL_440FX,
INTEL_440LX,
INTEL_440EX,
INTEL_440LX,
INTEL_440EX,
INTEL_440BX,
INTEL_440GX,
INTEL_440ZX
};
typedef struct
{
uint8_t pm2_cntrl, max_func,
smram_locked;
smram_locked, max_drb,
drb_default;
uint8_t regs[2][256], regs_locked[2][256];
int type;
} i4x0_t;
@@ -63,16 +63,16 @@ i4x0_map(uint32_t addr, uint32_t size, int state)
{
switch (state & 3) {
case 0:
mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
break;
case 1:
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
break;
case 2:
mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
break;
case 3:
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
break;
}
flushmmucache_nopc();
@@ -80,55 +80,34 @@ i4x0_map(uint32_t addr, uint32_t size, int state)
static void
i4x0_smram_map(int smm, uint32_t addr, uint32_t size, int ram)
i4x0_smram_map(int smm, uint32_t addr, uint32_t size, int is_smram)
{
int state = ram ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY);
mem_set_mem_state_common(smm, addr, size, state);
flushmmucache();
mem_set_mem_state_smram(smm, addr, size, is_smram);
}
static void
i4x0_smram_handler_phase0(i4x0_t *dev)
{
uint32_t i, n;
uint32_t tom = (mem_size << 10);
/* Disable any active mappings. */
if (dev->type >= INTEL_430FX) {
if (dev->type >= INTEL_440LX) {
/* Disable high extended SMRAM. */
/* TODO: This area should point to A0000-FFFFF. */
for (i = 0x100a0000; i < 0x100fffff; i += MEM_GRANULARITY_SIZE) {
/* This is to make sure that if the remaining area is smaller than
or equal to MEM_GRANULARITY_SIZE, we do not change the state of
too much memory. */
n = ((mem_size << 10) - i);
/* Cap to MEM_GRANULARITY_SIZE if i is either at or beyond the end
of RAM or the remaining area is bigger than MEM_GRANULARITY_SIZE. */
if ((i >= (mem_size << 10)) || (n > MEM_GRANULARITY_SIZE))
n = MEM_GRANULARITY_SIZE;
i4x0_smram_map(0, i, n, (i < (mem_size << 10)));
i4x0_smram_map(1, i, n, (i < (mem_size << 10)));
if (n < MEM_GRANULARITY_SIZE) {
i4x0_smram_map(0, i + n, MEM_GRANULARITY_SIZE - n, 0);
i4x0_smram_map(1, i + n, MEM_GRANULARITY_SIZE - n, 0);
}
}
if (smram[0].size != 0x00000000) {
i4x0_smram_map(0, smram[0].host_base, smram[0].size, 0);
i4x0_smram_map(1, smram[0].host_base, smram[0].size, 0);
/* Disable TSEG. */
i4x0_smram_map(1, ((mem_size << 10) - (1 << 20)), (1 << 20), 1);
}
memset(&smram[0], 0x00, sizeof(smram_t));
mem_mapping_disable(&ram_smram_mapping[0]);
}
/* Disable low extended SMRAM. */
i4x0_smram_map(0, 0xa0000, 0x20000, 0);
i4x0_smram_map(1, 0xa0000, 0x20000, 0);
} else {
/* Disable low extended SMRAM. */
i4x0_smram_map(0, 0xa0000, 0x20000, 0);
i4x0_smram_map(0, (mem_size << 10) - 0x10000, 0x10000, 1);
i4x0_smram_map(1, 0xa0000, 0x20000, 0);
i4x0_smram_map(1, (mem_size << 10) - 0x10000, 0x10000, 1);
if ((dev->type >= INTEL_440BX) && (smram[1].size != 0x00000000)) {
i4x0_smram_map(1, smram[1].host_base, smram[1].size, 0);
tom -= (1 << 20);
mem_set_mem_state_smm(tom, (1 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
memset(&smram[1], 0x00, sizeof(smram_t));
mem_mapping_disable(&ram_smram_mapping[1]);
}
}
@@ -137,6 +116,7 @@ static void
i4x0_smram_handler_phase1(i4x0_t *dev)
{
uint8_t *regs = (uint8_t *) dev->regs[0];
uint32_t tom = (mem_size << 10);
uint32_t s, base[2] = { 0x000a0000, 0x00020000 };
uint32_t size[2] = { 0, 0 };
@@ -147,26 +127,54 @@ i4x0_smram_handler_phase1(i4x0_t *dev)
base[0] = 0x100a0000;
size[0] = 0x00060000;
} else {
base[0] = 0x000a0000;
size[0] = 0x00020000;
if (((dev->type == INTEL_440LX) || (dev->type == INTEL_440EX)) && ((regs[0x72] & 0x07) == 0x04)) {
base[0] = 0x000c0000;
size[0] = 0x00010000;
} else {
base[0] = 0x000a0000;
size[0] = 0x00020000;
}
}
/* If D_OPEN = 1 and D_LCK = 0, extended SMRAM is visible outside SMM. */
i4x0_smram_map(0, base[0], size[0], ((regs[0x72] & 0x70) == 0x40));
if (((regs[0x72] & 0x70) == 0x40) || ((regs[0x72] & 0x08) && !(regs[0x72] & 0x20))) {
smram[0].host_base = base[0];
smram[0].ram_base = base[0] & 0x000f0000;
smram[0].size = size[0];
/* If the register is set accordingly, disable the mapping also in SMM. */
i4x0_smram_map(1, base[0], size[0], ((regs[0x72] & 0x08) && !(regs[0x72] & 0x20)));
mem_mapping_set_addr(&ram_smram_mapping[0], smram[0].host_base, size[0]);
mem_mapping_set_exec(&ram_smram_mapping[0], ram + smram[0].ram_base);
/* If D_OPEN = 1 and D_LCK = 0, extended SMRAM is visible outside SMM. */
i4x0_smram_map(0, base[0], size[0], ((regs[0x72] & 0x70) == 0x40));
/* If the register is set accordingly, disable the mapping also in SMM. */
i4x0_smram_map(1, base[0], size[0], ((regs[0x72] & 0x08) && !(regs[0x72] & 0x20)));
}
/* TSEG mapping. */
if (dev->type >= INTEL_440BX) {
if ((regs[0x72] & 0x08) && (regs[0x73] & 0x01)) {
size[1] = (1 << (17 + ((regs[0x73] >> 1) & 0x03)));
base[1] = (mem_size << 10) - size[1];
tom -= size[1];
base[1] = tom;
} else
base[1] = size[1] = 0x00000000;
i4x0_smram_map(1, base[1], size[1], 1);
} else
base[1] = size[1] = 0x00000000;
if (size[1] != 0x00000000) {
smram[1].host_base = base[1] + (1 << 28);
smram[1].ram_base = base[1];
smram[1].size = size[1];
mem_mapping_set_addr(&ram_smram_mapping[1], smram[1].host_base, smram[1].size);
if (smram[1].ram_base < (1 << 30))
mem_mapping_set_exec(&ram_smram_mapping[1], ram + smram[1].ram_base);
else
mem_mapping_set_exec(&ram_smram_mapping[1], ram2 + smram[1].ram_base - (1 << 30));
mem_set_mem_state_smm(base[1], size[1], MEM_READ_EXTANY | MEM_WRITE_EXTANY);
i4x0_smram_map(1, smram[1].host_base, size[1], 1);
}
}
} else {
size[0] = 0x00010000;
switch (regs[0x72] & 0x03) {
@@ -189,20 +197,23 @@ i4x0_smram_handler_phase1(i4x0_t *dev)
break;
}
if (base[0] != 0x00000000) {
if (((((regs[0x72] & 0x38) == 0x20) || s) || (!(regs[0x72] & 0x10) || s)) && (size[0] != 0x00000000)) {
smram[0].host_base = base[0];
smram[0].ram_base = base[0];
smram[0].size = size[0];
mem_mapping_set_addr(&ram_smram_mapping[0], smram[0].host_base, size[0]);
mem_mapping_set_exec(&ram_smram_mapping[0], ram + smram[0].ram_base);
/* If OSS = 1 and LSS = 0, extended SMRAM is visible outside SMM. */
i4x0_smram_map(0, base[0], size[0], ((regs[0x72] & 0x38) == 0x20) || s);
/* If base is on top of memory, this mapping will point to RAM.
TODO: It should actually point to EXTERNAL (with a SMRAM mapping) instead. */
/* If we are open, not closed, and not locked, point to RAM. */
i4x0_smram_map(0, base[0], size[0], (((regs[0x72] & 0x38) == 0x20) || s));
/* If the register is set accordingly, disable the mapping also in SMM. */
i4x0_smram_map(0, base[0], size[0], !(regs[0x72] & 0x10) || s);
/* If base is on top of memory, this mapping will point to RAM.
TODO: It should actually point to EXTERNAL (with a SMRAM mapping) instead. */
/* If we are not closed, point to RAM. */
i4x0_smram_map(0, base[0], size[0], (!(regs[0x72] & 0x10) || s));
}
}
flushmmucache();
}
@@ -254,11 +265,11 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case 0x04: /*Command register*/
switch (dev->type) {
case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX:
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX:
default:
regs[0x04] = (regs[0x04] & ~0x42) | (val & 0x42);
break;
case INTEL_430FX: case INTEL_430FX_PB640: case INTEL_430HX: case INTEL_430VX: case INTEL_430TX:
case INTEL_430FX: case INTEL_430HX: case INTEL_430VX: case INTEL_430TX:
case INTEL_440FX: case INTEL_440LX: case INTEL_440EX:
regs[0x04] = (regs[0x04] & ~0x02) | (val & 0x02);
break;
@@ -268,7 +279,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
switch (dev->type) {
case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: case INTEL_430HX:
case INTEL_440FX: case INTEL_440LX: case INTEL_440EX:
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX:
regs[0x05] = (regs[0x05] & ~0x01) | (val & 0x01);
break;
}
@@ -279,14 +290,14 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
default:
regs[0x07] &= ~(val & 0x70);
break;
case INTEL_430FX: case INTEL_430FX_PB640: case INTEL_430VX: case INTEL_430TX:
case INTEL_430FX: case INTEL_430VX: case INTEL_430TX:
case INTEL_440LX: case INTEL_440EX:
regs[0x07] &= ~(val & 0x30);
break;
case INTEL_440FX:
regs[0x07] &= ~(val & 0xf9);
break;
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX:
regs[0x07] &= ~(val & 0xf0);
break;
}
@@ -303,14 +314,14 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x0f:
switch (dev->type) {
case INTEL_430FX: case INTEL_430FX_PB640: case INTEL_430HX: case INTEL_430VX: case INTEL_430TX:
case INTEL_430FX: case INTEL_430HX: case INTEL_430VX: case INTEL_430TX:
regs[0x0f] = (val & 0x40);
break;
}
break;
case 0x12:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX:
regs[0x12] = (val & 0xc0);
i4x0_mask_bar(regs);
break;
@@ -318,7 +329,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x13:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX:
regs[0x13] = val;
i4x0_mask_bar(regs);
break;
@@ -326,7 +337,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x2c: case 0x2d: case 0x2e: case 0x2f:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX:
if (!regs_l[addr]) {
regs[addr] = val;
regs_l[addr] = 1;
@@ -364,7 +375,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_430NX:
regs[0x50] = (val & 0xe7);
break;
case INTEL_430FX: case INTEL_430FX_PB640:
case INTEL_430FX:
regs[0x50] = (val & 0xef);
break;
case INTEL_430HX:
@@ -385,6 +396,11 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440BX:
regs[0x50] = (regs[0x50] & 0x14) | (val & 0xeb);
break;
case INTEL_440GX:
/* TODO: Understand it more specifically */
regs[0x50] = (regs[0x50] & 0x2b) | (val & 0x28);
/*regs[0x50] = (regs[0x50] & 0x2b) | (val & 0xd7);*/
break;
case INTEL_440ZX:
regs[0x50] = (regs[0x50] & 0x34) | (val & 0xcb);
break;
@@ -405,13 +421,16 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440BX: case INTEL_440ZX:
regs[0x51] = (regs[0x50] & 0x70) | (val & 0x8f);
break;
case INTEL_440GX:
regs[0x51] = (regs[0x50] & 0x88) | (val & 0x08);
/*regs[0x51] = (regs[0x50] & 0x88) | (val & 0x77);*/
break;
}
break;
case 0x52: /* Cache Control Register */
switch (dev->type) {
case INTEL_420TX: case INTEL_420ZX:
case INTEL_430LX:
case INTEL_430FX: case INTEL_430FX_PB640:
case INTEL_430LX: case INTEL_430FX:
case INTEL_430VX: case INTEL_430TX:
default:
regs[0x52] = (val & 0xfb);
@@ -423,7 +442,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440LX:
regs[0x52] = (val & 0xd0);
break;
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX:
regs[0x52] = val & 0x07;
break;
}
@@ -443,7 +462,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440LX:
regs[0x53] = val & 0x0a;
break;
case INTEL_440EX: case INTEL_440BX:
case INTEL_440EX: case INTEL_440BX: case INTEL_440GX:
/* Not applicable to 440ZX as that does not support ECC. */
regs[0x53] = val;
break;
@@ -506,8 +525,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_430NX: case INTEL_440EX:
regs[0x57] = val;
break;
case INTEL_430FX: case INTEL_430FX_PB640:
case INTEL_430HX: case INTEL_430VX:
case INTEL_430FX: case INTEL_430HX:
case INTEL_430VX:
regs[0x57] = val & 0xcf;
break;
case INTEL_430TX:
@@ -519,7 +538,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440LX:
regs[0x57] = val & 0x11;
break;
case INTEL_440BX:
case INTEL_440BX: case INTEL_440GX:
regs[0x57] = val & 0x3f;
break;
case INTEL_440ZX:
@@ -537,8 +556,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440BX: case INTEL_440ZX:
regs[0x58] = val & 0x03;
break;
case INTEL_430FX: case INTEL_430FX_PB640:
case INTEL_440FX:
case INTEL_430FX: case INTEL_440FX:
regs[0x58] = val & 0x7f;
break;
case INTEL_430HX: case INTEL_430VX:
@@ -619,8 +637,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
default:
regs[addr] = val;
break;
case INTEL_430FX: case INTEL_430FX_PB640:
case INTEL_430VX:
case INTEL_430FX: case INTEL_430VX:
regs[addr] = val & 0x3f;
break;
case INTEL_430TX:
@@ -635,6 +652,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_430HX:
case INTEL_440FX:
case INTEL_440LX: case INTEL_440EX:
case INTEL_440GX:
case INTEL_440BX: case INTEL_440ZX:
regs[addr] = val;
break;
@@ -650,7 +668,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
switch (dev->type) {
case INTEL_430NX: case INTEL_430HX:
case INTEL_440FX: case INTEL_440LX:
case INTEL_440EX:
case INTEL_440EX: case INTEL_440GX:
case INTEL_440BX: case INTEL_440ZX:
regs[addr] = val;
break;
@@ -661,7 +679,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_430NX: case INTEL_430HX:
case INTEL_440FX: case INTEL_440LX:
case INTEL_440EX:
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
regs[addr] = val;
break;
case INTEL_430VX:
@@ -678,7 +697,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_430VX: case INTEL_430TX:
regs[0x68] = val;
break;
case INTEL_430FX: case INTEL_430FX_PB640:
case INTEL_430FX:
regs[0x68] = val & 0x1f;
break;
case INTEL_440FX: case INTEL_440LX:
@@ -688,6 +707,9 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440BX:
regs[0x68] = (regs[0x68] & 0x38) | (val & 0xc7);
break;
case INTEL_440GX:
regs[0x68] = (regs[0x68] & 0xc0) | (val & 0x3f);
break;
case INTEL_440ZX:
regs[0x68] = (regs[0x68] & 0x3f) | (val & 0xc0);
break;
@@ -697,6 +719,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
switch (dev->type) {
case INTEL_430NX:
case INTEL_440BX:
case INTEL_440GX:
regs[0x69] = val;
break;
case INTEL_430VX:
@@ -713,6 +736,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440LX:
case INTEL_440EX:
case INTEL_440BX:
case INTEL_440GX:
regs[addr] = val;
break;
case INTEL_440ZX:
@@ -728,6 +752,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440LX:
case INTEL_440EX:
case INTEL_440BX:
case INTEL_440GX:
regs[addr] = val;
break;
case INTEL_440ZX:
@@ -784,7 +809,10 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
if (dev->smram_locked)
regs[0x72] = (regs[0x72] & 0xdf) | (val & 0x20);
else {
regs[0x72] = (regs[0x72] & 0x87) | (val & 0x78);
if ((dev->type == INTEL_440LX) || (dev->type == INTEL_440EX))
regs[0x72] = (regs[0x72] & 0x80) | (val & 0x7f);
else
regs[0x72] = (regs[0x72] & 0x87) | (val & 0x78);
dev->smram_locked = (val & 0x10);
if (dev->smram_locked)
regs[0x72] &= 0xbf;
@@ -796,7 +824,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
regs[0x72] = (regs[0x72] & 0xc0) | (val & 0x3f);
dev->smram_locked = (val & 0x08);
if (dev->smram_locked)
regs[0x72] &= 0xef;
regs[0x72] &= 0xdf;
}
}
i4x0_smram_handler_phase1(dev);
@@ -806,7 +834,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_430VX:
regs[0x73] = val & 0x03;
break;
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX:
if (!dev->smram_locked) {
i4x0_smram_handler_phase0(dev);
regs[0x73] = (regs[0x72] & 0x38) | (val & 0xc7);
@@ -826,13 +854,13 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case 0x75: case 0x76:
case 0x7b:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX:
regs[addr] = val;
}
break;
case 0x77:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX:
regs[0x77] = val & 0x03;
}
break;
@@ -841,7 +869,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_430VX:
regs[0x78] = val & 0xcf;
break;
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX:
regs[0x78] = val & 0x0f;
break;
}
@@ -854,14 +882,14 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
if (val & 0x40)
io_sethandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev);
break;
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX:
regs[0x79] = val;
break;
}
break;
case 0x7a:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX:
regs[0x7a] = (regs[0x7a] & 0x0a) | (val & 0xf5);
io_removehandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev);
if (val & 0x40)
@@ -875,7 +903,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_430LX: case INTEL_430NX:
regs[0x7c] = val & 0x8f;
break;
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
regs[0x7c] = val & 0x1f;
break;
}
@@ -911,7 +940,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440LX:
regs[0x80] = val & 0x08;
break;
case INTEL_440EX:
case INTEL_440EX: case INTEL_440GX:
regs[0x80] = val & 0x18;
break;
case INTEL_440BX: case INTEL_440ZX:
@@ -923,7 +952,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
switch (dev->type) {
case INTEL_430HX: case INTEL_440BX:
case INTEL_440FX: case INTEL_440LX:
case INTEL_440EX:
case INTEL_440EX: case INTEL_440GX:
/* Not applicable on 82443ZX. */
regs[0x91] &= ~(val & 0x11);
break;
@@ -932,7 +961,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case 0x92:
switch (dev->type) {
case INTEL_440LX: case INTEL_440EX:
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
regs[0x92] &= ~(val & 0x1f);
break;
}
@@ -956,7 +986,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
case 0xb0:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
regs[0xb0] = (val & 0x80);
break;
}
@@ -969,11 +1000,15 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440BX: case INTEL_440ZX:
regs[0xb1] = (val & 0xa0);
break;
case INTEL_440GX:
regs[0xb1] = (val & 0xa2);
break;
}
break;
case 0xb4:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
regs[0xb4] = (val & 0x3f);
i4x0_mask_bar(regs);
break;
@@ -981,7 +1016,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
case 0xb9:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
regs[0xb9] = (val & 0xf0);
break;
}
@@ -989,7 +1025,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case 0xba: case 0xbb:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
regs[addr] = val;
break;
}
@@ -997,7 +1034,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case 0xbc:
switch (dev->type) {
case INTEL_440EX:
case INTEL_440EX: case INTEL_440GX:
regs[addr] = (val & 0xf8);
break;
}
@@ -1005,7 +1042,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case 0xbd:
switch (dev->type) {
case INTEL_440EX:
case INTEL_440EX: case INTEL_440GX:
regs[addr] = (val & 0xf8);
break;
}
@@ -1013,14 +1050,15 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
regs[addr] = val;
break;
}
break;
case 0xca:
switch (dev->type) {
case INTEL_440BX:
case INTEL_440BX: case INTEL_440GX:
regs[addr] = val;
break;
case INTEL_440ZX:
@@ -1030,7 +1068,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
case 0xcb:
switch (dev->type) {
case INTEL_440BX:
case INTEL_440BX: case INTEL_440GX:
regs[addr] = val;
break;
case INTEL_440ZX:
@@ -1040,7 +1078,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
case 0xcc:
switch (dev->type) {
case INTEL_440BX:
case INTEL_440BX: case INTEL_440GX:
regs[0xcc] = (val & 0x7f);
break;
case INTEL_440ZX:
@@ -1051,7 +1089,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4:
case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
if (!regs_l[addr])
regs[addr] = val;
break;
@@ -1059,7 +1098,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
case 0xe5: case 0xed:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
if (!regs_l[addr])
regs[addr] = (val & 0x3f);
break;
@@ -1067,7 +1107,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
case 0xe7:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
regs[0xe7] = 0x80;
for (i = 0; i < 16; i++)
regs_l[0xe0 + i] = !!(val & 0x80);
@@ -1079,14 +1120,16 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
case 0xf0:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
regs[0xf0] = (val & 0xc0);
break;
}
break;
case 0xf1:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
regs[0xf1] = (val & 0x03);
break;
}
@@ -1097,18 +1140,22 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440BX: case INTEL_440ZX:
regs[0x04] = (val & 0x1f);
break;
case INTEL_440GX:
regs[0x04] = val;
}
break;
case 0x05:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
regs[0x05] = (val & 0x01);
break;
}
break;
case 0x0d: case 0x1b:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
regs[addr] = (val & 0xf8);
break;
}
@@ -1117,7 +1164,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case 0x21: case 0x23:
case 0x25: case 0x27:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
regs[addr] = val;
break;
}
@@ -1126,21 +1174,24 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case 0x20: case 0x22:
case 0x24: case 0x26:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
regs[addr] = (val & 0xf0);
break;
}
break;
case 0x1f:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
regs[0x1f] &= ~(val & 0xf0);
break;
}
break;
case 0x3e:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
case INTEL_440BX: case INTEL_440GX:
case INTEL_440ZX:
regs[0x3e] = (val & 0xed);
break;
}
@@ -1184,10 +1235,16 @@ i4x0_reset(void *priv)
for (i = 0; i < 6; i++)
i4x0_write(0, 0x5a + i, 0x00, priv);
if (dev->type >= INTEL_430FX)
for (i = 0; i <= dev->max_drb; i++)
i4x0_write(0, 0x60 + i, dev->drb_default, priv);
if (dev->type >= INTEL_430FX) {
dev->regs[0][0x72] &= 0xef; /* Forcibly unlock the SMRAM register. */
i4x0_write(0, 0x72, 0x02, priv);
else
} else {
dev->regs[0][0x72] &= 0xf7; /* Forcibly unlock the SMRAM register. */
i4x0_write(0, 0x72, 0x00, priv);
}
if ((dev->type == INTEL_440LX) || (dev->type == INTEL_440BX) || (dev->type == INTEL_440ZX)) {
for (i = 0; i <= dev->max_func; i++)
@@ -1217,9 +1274,6 @@ static void
regs = (uint8_t *) dev->regs[0];
// This is off by default and has to be moved to the appropriate register handling.
// io_sethandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev);
regs[0x00] = 0x86; regs[0x01] = 0x80; /*Intel*/
switch (dev->type) {
@@ -1250,6 +1304,8 @@ static void
regs[0x57] = 0x31;
regs[0x59] = 0x0f;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02;
dev->max_drb = 5;
dev->drb_default = 0x02;
break;
case INTEL_430LX:
regs[0x02] = 0xa3; regs[0x03] = 0x04; /* 82434LX/NX */
@@ -1266,6 +1322,8 @@ static void
regs[0x57] = 0x31;
regs[0x59] = 0x0f;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02;
dev->max_drb = 5;
dev->drb_default = 0x02;
break;
case INTEL_430NX:
regs[0x02] = 0xa3; regs[0x03] = 0x04; /* 82434LX/NX */
@@ -1284,12 +1342,12 @@ static void
regs[0x57] = 0x31;
regs[0x59] = 0x0f;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02;
dev->max_drb = 7;
dev->drb_default = 0x02;
break;
case INTEL_430FX_PB640:
regs[0x08] = 0x02;
/* FALLTHROUGH */
case INTEL_430FX:
regs[0x02] = 0x2d; regs[0x03] = 0x12; /* SB82437FX-66 */
regs[0x08] = (info->local >> 8) & 0xff;
regs[0x52] = 0xb2; /* 512 kB PLB cache, set to 0x42 for 256 kB */
if (cpu_busspeed <= 50000000)
regs[0x57] |= 0x01;
@@ -1299,6 +1357,8 @@ static void
regs[0x57] |= 0x03;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = 0x02;
regs[0x72] = 0x02;
dev->max_drb = 4;
dev->drb_default = 0x02;
break;
case INTEL_430HX:
regs[0x02] = 0x50; regs[0x03] = 0x12; /* 82439HX */
@@ -1311,6 +1371,8 @@ static void
regs[0x57] |= 0x03;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02;
regs[0x72] = 0x02;
dev->max_drb = 7;
dev->drb_default = 0x02;
break;
case INTEL_430VX:
regs[0x02] = 0x30; regs[0x03] = 0x70; /* 82437VX */
@@ -1330,6 +1392,8 @@ static void
regs[0x72] = 0x02;
regs[0x74] = 0x0e;
regs[0x78] = 0x23;
dev->max_drb = 4;
dev->drb_default = 0x02;
break;
case INTEL_430TX:
regs[0x02] = 0x00; regs[0x03] = 0x71; /* 82439TX */
@@ -1345,6 +1409,8 @@ static void
regs[0x67] |= 0x80;
regs[0x70] = 0x20;
regs[0x72] = 0x02;
dev->max_drb = 5;
dev->drb_default = 0x02;
break;
case INTEL_440FX:
regs[0x02] = 0x37; regs[0x03] = 0x12; /* 82441FX */
@@ -1359,6 +1425,8 @@ static void
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02;
regs[0x71] = 0x10;
regs[0x72] = 0x02;
dev->max_drb = 7;
dev->drb_default = 0x02;
break;
case INTEL_440LX:
dev->max_func = 1;
@@ -1381,6 +1449,8 @@ static void
regs[0xa4] = 0x03;
regs[0xa5] = 0x02;
regs[0xa7] = 0x1f;
dev->max_drb = 7;
dev->drb_default = 0x01;
break;
case INTEL_440EX:
dev->max_func = 1;
@@ -1403,6 +1473,8 @@ static void
regs[0xa4] = 0x03;
regs[0xa5] = 0x02;
regs[0xa7] = 0x1f;
dev->max_drb = 7;
dev->drb_default = 0x01;
break;
case INTEL_440BX: case INTEL_440ZX:
regs[0x7a] = (info->local >> 8) & 0xff;
@@ -1429,6 +1501,33 @@ static void
regs[0xa4] = 0x03;
regs[0xa5] = 0x02;
regs[0xa7] = 0x1f;
dev->max_drb = 7;
dev->drb_default = 0x01;
break;
case INTEL_440GX:
regs[0x7a] = (info->local >> 8) & 0xff;
dev->max_func = (regs[0x7a] & 0x02) ? 0 : 1;
regs[0x02] = 0xa0; regs[0x03] = 0x71; /* 82443GX */
regs[0x06] = (regs[0x7a] & 0x02) ? 0x00 : 0x10;
regs[0x08] = 0x02;
regs[0x10] = 0x08;
regs[0x34] = (regs[0x7a] & 0x02) ? 0x00 : 0xa0;
regs[0x51] |= 0x20;
regs[0x57] = 0x28;
regs[0x58] = 0x03;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01;
regs[0x72] = 0x02;
regs[0x73] = 0x38;
regs[0x7b] = 0x38;
regs[0x90] = 0x80;
regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02;
regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10;
regs[0xa4] = 0x03;
regs[0xa5] = 0x02;
regs[0xa7] = 0x1f;
dev->max_drb = 7;
dev->drb_default = 0x01;
break;
}
@@ -1463,11 +1562,15 @@ static void
regs[0x24] = 0xf0; regs[0x25] = 0xff;
}
if (((dev->type == INTEL_440BX) || (dev->type == INTEL_440ZX)) && (dev->max_func == 1)) {
if (((dev->type == INTEL_440BX) || (dev->type == INTEL_440GX) || (dev->type == INTEL_440ZX)) && (dev->max_func == 1)) {
regs = (uint8_t *) dev->regs[1];
regs[0x00] = 0x86; regs[0x01] = 0x80; /* Intel */
if(dev->type != INTEL_440GX){
regs[0x02] = 0x91; regs[0x03] = 0x71; /* 82443BX */
} else {
regs[0x02] = 0xa1; regs[0x03] = 0x71; /* 82443GX (They seem to share the same deal*/
}
regs[0x06] = 0x20; regs[0x07] = 0x02;
regs[0x08] = 0x02;
regs[0x0a] = 0x04; regs[0x0b] = 0x06;
@@ -1560,11 +1663,11 @@ const device_t i430fx_device =
};
const device_t i430fx_pb640_device =
const device_t i430fx_rev02_device =
{
"Intel SB82437FX-66 (PB640)",
"Intel SB82437FX-66 (Rev. 02)",
DEVICE_PCI,
INTEL_430FX_PB640,
0x0200 | INTEL_430FX,
i4x0_init,
i4x0_close,
i4x0_reset,
@@ -1677,6 +1780,19 @@ const device_t i440bx_device =
NULL
};
const device_t i440gx_device =
{
"Intel 82443GX",
DEVICE_PCI,
0x8000 | INTEL_440GX,
i4x0_init,
i4x0_close,
i4x0_reset,
NULL,
NULL,
NULL,
NULL
};
const device_t i440zx_device =
{

View File

@@ -13,10 +13,8 @@
*
*
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2020 Sarah Walker.
* Copyright 2016-2020 Miran Grca.
*/
#include <stdarg.h>
@@ -53,7 +51,7 @@
#include <86box/zip.h>
#include <86box/machine.h>
#include <86box/smbus_piix4.h>
#include <86box/piix.h>
#include <86box/chipset.h>
typedef struct
@@ -281,10 +279,10 @@ piix_write(int func, int addr, uint8_t val, void *priv)
/* Return on unsupported function. */
if (dev->max_func > 0) {
if (func > dev->max_func)
if (func > dev->max_func)
return;
} else {
if (func > 1)
if (func > 1)
return;
}
@@ -480,11 +478,11 @@ piix_write(int func, int addr, uint8_t val, void *priv)
apm_set_do_smi(dev->apm, !!(fregs[0xa0] & 0x01) && !!(val & 0x80));
}
break;
case 0xaa: case 0xac: case 0xae:
case 0xac: case 0xae:
if (dev->type < 4)
fregs[addr] = val & 0xff;
break;
case 0xa3: case 0xab:
case 0xa3:
if (dev->type == 3)
fregs[addr] = val & 0x01;
break;
@@ -524,6 +522,14 @@ piix_write(int func, int addr, uint8_t val, void *priv)
timer_on_auto(&dev->fast_off_timer, dev->fast_off_period);
}
break;
case 0xaa:
if (dev->type < 4)
fregs[addr] &= val;
break;
case 0xab:
if (dev->type == 3)
fregs[addr] &= (val & 0x01);
break;
case 0xb0:
if (dev->type == 4)
fregs[addr] = (fregs[addr] & 0x8c) | (val & 0x73);
@@ -755,16 +761,16 @@ piix_write(int func, int addr, uint8_t val, void *priv)
fregs[addr] = val & 0x01;
break;
case 0x6a:
if (dev->type == 4)
if (dev->type <= 4)
fregs[0x6a] = val & 0x01;
break;
case 0xc0:
if (dev->type == 4)
fregs[0xc0] = val;
if (dev->type <= 4)
fregs[0xc0] = (fregs[0xc0] & ~(val & 0xbf)) | (val & 0x20);
break;
case 0xc1:
if (dev->type == 4)
fregs[0xc1] = val & 0xbf;
if (dev->type <= 4)
fregs[0xc1] &= ~val;
break;
case 0xff:
if (dev->type == 4) {
@@ -873,6 +879,9 @@ piix_read(int func, int addr, void *priv)
piix_t *dev = (piix_t *) priv;
uint8_t ret = 0xff, *fregs;
if ((dev->type == 3) && (func == 2) && (dev->max_func == 1) && (addr >= 0x40))
ret = 0x00;
/* Return on unsupported function. */
if ((func <= dev->max_func) || ((func == 1) && (dev->max_func == 0))) {
fregs = (uint8_t *) dev->regs[func];
@@ -995,6 +1004,8 @@ piix_reset_hard(piix_t *dev)
fregs[0x69] = 0x02;
if ((dev->type == 1) && (dev->rev != 2))
fregs[0x6a] = 0x04;
else if (dev->type == 3)
fregs[0x6a] = 0x10;
fregs[0x70] = (dev->type < 4) ? 0x80 : 0x00;
fregs[0x71] = (dev->type < 3) ? 0x80 : 0x00;
if (dev->type <= 4) {
@@ -1065,7 +1076,7 @@ piix_reset_hard(piix_t *dev)
fregs[0xc1] = 0x20;
fregs[0xff] = (dev->type > 3) ? 0x10 : 0x00;
}
dev->max_func = 1; /* It starts with USB disabled, then enables it. */
dev->max_func = 2; /* It starts with USB disabled, then enables it. */
}
/* Function 3: Power Management */
@@ -1149,6 +1160,13 @@ piix_reset(void *p)
piix_write(0, 0xa7, 0x00, p);
piix_write(0, 0xa8, 0x0f, p);
}
piix_write(1, 0x04, 0x00, p);
piix_write(1, 0x41, 0x00, p);
piix_write(1, 0x43, 0x00, p);
ide_pri_disable();
ide_sec_disable();
}
@@ -1161,6 +1179,20 @@ piix_close(void *p)
}
static void
piix_speed_changed(void *priv)
{
piix_t *dev = (piix_t *) priv;
int te;
te = timer_is_enabled(&dev->fast_off_timer);
timer_stop(&dev->fast_off_timer);
if (te)
timer_on_auto(&dev->fast_off_timer, dev->fast_off_period);
}
static void
*piix_init(const device_t *info)
{
@@ -1300,7 +1332,7 @@ const device_t piix_device =
piix_close,
piix_reset,
NULL,
NULL,
piix_speed_changed,
NULL,
NULL
};
@@ -1314,7 +1346,7 @@ const device_t piix_rev02_device =
piix_close,
piix_reset,
NULL,
NULL,
piix_speed_changed,
NULL,
NULL
};
@@ -1328,7 +1360,7 @@ const device_t piix3_device =
piix_close,
piix_reset,
NULL,
NULL,
piix_speed_changed,
NULL,
NULL
};
@@ -1342,7 +1374,7 @@ const device_t piix4_device =
piix_close,
piix_reset,
NULL,
NULL,
piix_speed_changed,
NULL,
NULL
};
@@ -1356,7 +1388,7 @@ const device_t piix4e_device =
piix_close,
piix_reset,
NULL,
NULL,
piix_speed_changed,
NULL,
NULL
};
@@ -1370,7 +1402,7 @@ const device_t slc90e66_device =
piix_close,
piix_reset,
NULL,
NULL,
piix_speed_changed,
NULL,
NULL
};

573
src/chipset/intel_sio.c Normal file
View File

@@ -0,0 +1,573 @@
/*
* 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.
*
* Emulation of Intel System I/O PCI chip.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2016-2018 Miran Grca.
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/io.h>
#include <86box/apm.h>
#include <86box/dma.h>
#include <86box/mem.h>
#include <86box/pci.h>
#include <86box/timer.h>
#include <86box/pit.h>
#include <86box/port_92.h>
#include <86box/machine.h>
#include <86box/chipset.h>
typedef struct
{
uint8_t id,
regs[256];
uint16_t timer_base,
timer_latch;
double fast_off_period;
pc_timer_t timer, fast_off_timer;
apm_t * apm;
port_92_t * port_92;
} sio_t;
#ifdef ENABLE_SIO_LOG
int sio_do_log = ENABLE_SIO_LOG;
static void
sio_log(const char *fmt, ...)
{
va_list ap;
if (sio_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define sio_log(fmt, ...)
#endif
static void
sio_timer_write(uint16_t addr, uint8_t val, void *priv)
{
sio_t *dev = (sio_t *) priv;
if (!(addr & 0x0002)) {
if (addr & 0x0001)
dev->timer_latch = (dev->timer_latch & 0xff) | (val << 8);
else
dev->timer_latch = (dev->timer_latch & 0xff00) | val;
timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC);
}
}
static void
sio_timer_writew(uint16_t addr, uint16_t val, void *priv)
{
sio_t *dev = (sio_t *) priv;
if (!(addr & 0x0002)) {
dev->timer_latch = val;
timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC);
}
}
static uint8_t
sio_timer_read(uint16_t addr, void *priv)
{
sio_t *dev = (sio_t *) priv;
uint16_t sio_timer_latch;
uint8_t ret = 0xff;
if (!(addr & 0x0002)) {
sub_cycles((int)(PITCONST >> 32));
sio_timer_latch = timer_get_remaining_us(&dev->timer);
if (addr & 0x0001)
ret = sio_timer_latch >> 8;
else
ret = sio_timer_latch & 0xff;
}
return ret;
}
static uint16_t
sio_timer_readw(uint16_t addr, void *priv)
{
sio_t *dev = (sio_t *) priv;
uint16_t ret = 0xffff;
if (!(addr & 0x0002)) {
sub_cycles((int)(PITCONST >> 32));
ret = timer_get_remaining_us(&dev->timer);
}
return ret;
}
static void
sio_write(int func, int addr, uint8_t val, void *priv)
{
sio_t *dev = (sio_t *) priv;
uint8_t old;
if (func > 0)
return;
if (((addr >= 0x0f) && (addr < 0x4c)) && (addr != 0x40))
return;
/* The IB (original) variant of the SIO has no PCI IRQ steering. */
if ((addr >= 0x60) && (addr <= 0x63) && (dev->id < 0x03))
return;
old = dev->regs[addr];
switch (addr) {
case 0x04: /*Command register*/
if (dev->id == 0x03)
dev->regs[addr] = (dev->regs[addr] & 0xf7) | (val & 0x08);
break;
case 0x07:
dev->regs[addr] &= ~(val & 0x38);
break;
case 0x40:
if (dev->id == 0x03) {
dev->regs[addr] = (val & 0x7f);
if (!((val ^ old) & 0x40))
return;
dma_alias_remove();
if (!(val & 0x40))
dma_alias_set();
} else
dev->regs[addr] = (val & 0x3f);
break;
case 0x41: case 0x44:
dev->regs[addr] = (val & 0x1f);
break;
case 0x42:
if (dev->id == 0x03)
dev->regs[addr] = val;
else
dev->regs[addr] = (val & 0x77);
break;
case 0x43:
if (dev->id == 0x03)
dev->regs[addr] = (val & 0x01);
break;
case 0x45: case 0x46:
case 0x47: case 0x48:
case 0x49: case 0x4a:
case 0x4b: case 0x4e:
case 0x54: case 0x55:
case 0x56:
dev->regs[addr] = val;
break;
case 0x4c: case 0x4d:
dev->regs[addr] = (val & 0x7f);
break;
case 0x4f:
dev->regs[addr] = val;
if (!((val ^ old) & 0x40))
return;
port_92_remove(dev->port_92);
if (val & 0x40)
port_92_add(dev->port_92);
break;
case 0x57:
dev->regs[addr] = val;
dma_remove_sg();
dma_set_sg_base(val);
break;
case 0x60: case 0x61: case 0x62: case 0x63:
if (dev->id == 0x03) {
sio_log("Set IRQ routing: INT %c -> %02X\n", 0x41 + (addr & 0x03), val);
dev->regs[addr] = val & 0x8f;
if (val & 0x80)
pci_set_irq_routing(PCI_INTA + (addr & 0x03), PCI_IRQ_DISABLED);
else
pci_set_irq_routing(PCI_INTA + (addr & 0x03), val & 0xf);
}
break;
case 0x80:
case 0x81:
if (addr == 0x80)
dev->regs[addr] = val & 0xfd;
else
dev->regs[addr] = val;
if (dev->timer_base & 0x01) {
io_removehandler(dev->timer_base & 0xfffc, 0x0004,
sio_timer_read, sio_timer_readw, NULL,
sio_timer_write, sio_timer_writew, NULL, dev);
}
dev->timer_base = (dev->regs[0x81] << 8) | (dev->regs[0x80] & 0xfd);
if (dev->timer_base & 0x01) {
io_sethandler(dev->timer_base & 0xfffc, 0x0004,
sio_timer_read, sio_timer_readw, NULL,
sio_timer_write, sio_timer_writew, NULL, dev);
}
break;
case 0xa0:
if (dev->id == 0x03) {
dev->regs[addr] = val & 0x1f;
apm_set_do_smi(dev->apm, !!(val & 0x01) && !!(dev->regs[0xa2] & 0x80));
switch ((val & 0x18) >> 3) {
case 0x00:
dev->fast_off_period = PCICLK * 32768.0 * 60000.0;
break;
case 0x01:
default:
dev->fast_off_period = 0.0;
break;
case 0x02:
dev->fast_off_period = PCICLK;
break;
case 0x03:
dev->fast_off_period = PCICLK * 32768.0;
break;
}
cpu_fast_off_count = dev->regs[0xa8] + 1;
timer_disable(&dev->fast_off_timer);
if (dev->fast_off_period != 0.0)
timer_on_auto(&dev->fast_off_timer, dev->fast_off_period);
}
break;
case 0xa2:
if (dev->id == 0x03) {
dev->regs[addr] = val & 0xff;
apm_set_do_smi(dev->apm, !!(dev->regs[0xa0] & 0x01) && !!(val & 0x80));
}
break;
case 0xaa:
if (dev->id == 0x03)
dev->regs[addr] &= (val & 0xff);
break;
case 0xac: case 0xae:
if (dev->id == 0x03)
dev->regs[addr] = val & 0xff;
break;
case 0xa4:
if (dev->id == 0x03) {
dev->regs[addr] = val & 0xfb;
cpu_fast_off_flags = (cpu_fast_off_flags & 0xffffff00) | dev->regs[addr];
}
break;
case 0xa5:
if (dev->id == 0x03) {
dev->regs[addr] = val & 0xff;
cpu_fast_off_flags = (cpu_fast_off_flags & 0xffff00ff) | (dev->regs[addr] << 8);
}
break;
case 0xa7:
if (dev->id == 0x03) {
dev->regs[addr] = val & 0xa0;
cpu_fast_off_flags = (cpu_fast_off_flags & 0x00ffffff) | (dev->regs[addr] << 24);
}
break;
case 0xa8:
dev->regs[addr] = val & 0xff;
cpu_fast_off_val = val;
cpu_fast_off_count = val + 1;
timer_disable(&dev->fast_off_timer);
if (dev->fast_off_period != 0.0)
timer_on_auto(&dev->fast_off_timer, dev->fast_off_period);
break;
}
}
static uint8_t
sio_read(int func, int addr, void *priv)
{
sio_t *dev = (sio_t *) priv;
uint8_t ret;
ret = 0xff;
if (func == 0)
ret = dev->regs[addr];
return ret;
}
static void
sio_config_write(uint16_t addr, uint8_t val, void *priv)
{
}
static uint8_t
sio_config_read(uint16_t port, void *priv)
{
uint8_t ret = 0x00;
switch (port & 0x000f) {
case 3:
ret = 0xff;
break;
case 5:
ret = 0xd3;
switch (cpu_pci_speed) {
case 20000000:
ret |= 0x0c;
break;
case 25000000:
default:
ret |= 0x00;
break;
case 30000000:
ret |= 0x08;
break;
case 33333333:
ret |= 0x04;
break;
}
break;
}
return ret;
}
static void
sio_reset_hard(void *priv)
{
sio_t *dev = (sio_t *) priv;
memset(dev->regs, 0, 256);
dev->regs[0x00] = 0x86; dev->regs[0x01] = 0x80; /*Intel*/
dev->regs[0x02] = 0x84; dev->regs[0x03] = 0x04; /*82378IB (SIO)*/
dev->regs[0x04] = 0x07;
dev->regs[0x07] = 0x02;
dev->regs[0x08] = dev->id;
dev->regs[0x40] = 0x20; dev->regs[0x41] = 0x00;
dev->regs[0x42] = 0x04;
dev->regs[0x45] = 0x10; dev->regs[0x46] = 0x0f;
dev->regs[0x48] = 0x01;
dev->regs[0x4a] = 0x10; dev->regs[0x4b] = 0x0f;
dev->regs[0x4c] = 0x56; dev->regs[0x4d] = 0x40;
dev->regs[0x4e] = 0x07; dev->regs[0x4f] = 0x4f;
dev->regs[0x57] = 0x04;
if (dev->id == 0x03) {
dev->regs[0x60] = 0x80; dev->regs[0x61] = 0x80; dev->regs[0x62] = 0x80; dev->regs[0x63] = 0x80;
}
dev->regs[0x80] = 0x78;
if (dev->id == 0x03) {
dev->regs[0xa0] = 0x08;
dev->regs[0xa8] = 0x0f;
}
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);
if (dev->timer_base & 0x0001) {
io_removehandler(dev->timer_base & 0xfffc, 0x0004,
sio_timer_read, sio_timer_readw, NULL,
sio_timer_write, sio_timer_writew, NULL, dev);
}
dev->timer_base = 0x0078;
}
static void
sio_apm_out(uint16_t port, uint8_t val, void *p)
{
sio_t *dev = (sio_t *) p;
if (dev->apm->do_smi)
dev->regs[0xaa] |= 0x80;
}
static void
sio_fast_off_count(void *priv)
{
sio_t *dev = (sio_t *) priv;
cpu_fast_off_count--;
if (cpu_fast_off_count == 0) {
smi_line = 1;
dev->regs[0xaa] |= 0x20;
cpu_fast_off_count = dev->regs[0xa8] + 1;
}
timer_on_auto(&dev->fast_off_timer, dev->fast_off_period);
}
static void
sio_reset(void *p)
{
sio_t *dev = (sio_t *) p;
sio_write(0, 0x57, 0x04, p);
dma_set_params(1, 0xffffffff);
if (dev->id == 0x03) {
sio_write(0, 0xa0, 0x08, p);
sio_write(0, 0xa2, 0x00, p);
sio_write(0, 0xa4, 0x00, p);
sio_write(0, 0xa5, 0x00, p);
sio_write(0, 0xa6, 0x00, p);
sio_write(0, 0xa7, 0x00, p);
sio_write(0, 0xa8, 0x0f, p);
}
}
static void
sio_close(void *p)
{
sio_t *dev = (sio_t *)p;
free(dev);
}
static void
sio_speed_changed(void *priv)
{
sio_t *dev = (sio_t *) priv;
int te;
te = timer_is_enabled(&dev->timer);
timer_disable(&dev->timer);
if (te)
timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC);
if (dev->id == 0x03) {
te = timer_is_enabled(&dev->fast_off_timer);
timer_stop(&dev->fast_off_timer);
if (te)
timer_on_auto(&dev->fast_off_timer, dev->fast_off_period);
}
}
static void *
sio_init(const device_t *info)
{
sio_t *dev = (sio_t *) malloc(sizeof(sio_t));
memset(dev, 0, sizeof(sio_t));
pci_add_card(PCI_ADD_SOUTHBRIDGE, sio_read, sio_write, dev);
dev->id = info->local;
if (dev->id == 0x03)
timer_add(&dev->fast_off_timer, sio_fast_off_count, dev, 0);
sio_reset_hard(dev);
cpu_fast_off_flags = 0x00000000;
if (dev->id == 0x03) {
cpu_fast_off_val = dev->regs[0xa8];
cpu_fast_off_count = cpu_fast_off_val + 1;
} else
cpu_fast_off_val = cpu_fast_off_count = 0;
if (dev->id == 0x03) {
dev->apm = device_add(&apm_pci_device);
/* APM intercept handler to update 82378ZB SMI status on APM SMI. */
io_sethandler(0x00b2, 0x0001, NULL, NULL, NULL, sio_apm_out, NULL, NULL, dev);
}
dev->port_92 = device_add(&port_92_pci_device);
dma_set_sg_base(0x04);
dma_set_params(1, 0xffffffff);
dma_ext_mode_init();
dma_high_page_init();
if (dev->id == 0x03)
dma_alias_set();
io_sethandler(0x0073, 0x0001,
sio_config_read, NULL, NULL, sio_config_write, NULL, NULL, dev);
io_sethandler(0x0075, 0x0001,
sio_config_read, NULL, NULL, sio_config_write, NULL, NULL, dev);
timer_add(&dev->timer, NULL, NULL, 0);
return dev;
}
const device_t sio_device =
{
"Intel 82378IB (SIO)",
DEVICE_PCI,
0x00,
sio_init,
sio_close,
sio_reset,
NULL,
sio_speed_changed,
NULL,
NULL
};
const device_t sio_zb_device =
{
"Intel 82378ZB (SIO)",
DEVICE_PCI,
0x03,
sio_init,
sio_close,
sio_reset,
NULL,
sio_speed_changed,
NULL,
NULL
};

View File

@@ -1,119 +0,0 @@
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/mem.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/chipset.h>
typedef struct
{
uint8_t cur_reg,
regs[16];
} rabbit_t;
/*
static void
rabbit_recalcmapping(rabbit_t *dev)
{
uint32_t base;
uint32_t i, shflags = 0;
shadowbios = 0;
shadowbios_write = 0;
for (i = 0; i < 8; i++) {
base = 0xc0000 + (i << 15);
if (dev->regs[0x00] & 0x08) {
shadowbios |= (base >= 0xe0000) && (dev->regs[0x02] & 0x80);
shadowbios_write |= (base >= 0xe0000) && !(dev->regs[0x02] & 0x40);
shflags = (dev->regs[0x00] & 0x01) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
shflags |= (dev->regs[0x00] & 0x08) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL;
mem_set_mem_state(base, 0x8000, shflags);
} else
mem_set_mem_state(base, 0x8000, MEM_READ_EXTANY | MEM_WRITE_EXTERNAL);
}
flushmmucache();
}
*/
static void
rabbit_write(uint16_t addr, uint8_t val, void *priv)
{
rabbit_t *dev = (rabbit_t *) priv;
switch (addr) {
case 0x22:
dev->cur_reg = val;
break;
case 0x23:
dev->regs[dev->cur_reg] = val;
/*
if (dev->cur_reg == 0x00) {
rabbit_recalcmapping(dev);
}
*/
break;
}
}
static uint8_t
rabbit_read(uint16_t addr, void *priv)
{
uint8_t ret = 0xff;
rabbit_t *dev = (rabbit_t *) priv;
switch (addr) {
case 0x23:
ret = dev->regs[dev->cur_reg];
break;
}
return ret;
}
static void
rabbit_close(void *priv)
{
rabbit_t *dev = (rabbit_t *) priv;
free(dev);
}
static void *
rabbit_init(const device_t *info)
{
rabbit_t *dev = (rabbit_t *) malloc(sizeof(rabbit_t));
memset(dev, 0, sizeof(rabbit_t));
io_sethandler(0x0022, 0x0001, rabbit_read, NULL, NULL, rabbit_write, NULL, NULL, dev);
io_sethandler(0x0023, 0x0001, rabbit_read, NULL, NULL, rabbit_write, NULL, NULL, dev);
return dev;
}
const device_t rabbit_device = {
"SiS Rabbit",
0,
0,
rabbit_init, rabbit_close, NULL,
NULL, NULL, NULL,
NULL
};

150
src/chipset/sis_85c310.c Normal file
View File

@@ -0,0 +1,150 @@
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/mem.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/chipset.h>
typedef struct
{
uint8_t cur_reg, tries,
regs[258];
} rabbit_t;
static void
rabbit_recalcmapping(rabbit_t *dev)
{
uint32_t shread, shwrite;
uint32_t shflags = 0;
shread = !!(dev->regs[0x101] & 0x40);
shwrite = !!(dev->regs[0x100] & 0x02);
shflags = shread ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
shflags |= shwrite ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
shadowbios = !!shread;
shadowbios_write = !!shwrite;
#ifdef USE_SHADOW_C0000
mem_set_mem_state(0x000c0000, 0x00040000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
#else
mem_set_mem_state(0x000e0000, 0x00020000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
#endif
switch (dev->regs[0x100] & 0x09) {
case 0x01:
/* The one BIOS we use seems to use something else to control C0000-DFFFF shadow,
no idea what. */
#ifdef USE_SHADOW_C0000
/* 64K at 0C0000-0CFFFF */
mem_set_mem_state(0x000c0000, 0x00010000, shflags);
/* FALLTHROUGH */
#endif
case 0x00:
/* 64K at 0F0000-0FFFFF */
mem_set_mem_state(0x000f0000, 0x00010000, shflags);
break;
case 0x09:
#ifdef USE_SHADOW_C0000
/* 128K at 0C0000-0DFFFF */
mem_set_mem_state(0x000c0000, 0x00020000, shflags);
/* FALLTHROUGH */
#endif
case 0x08:
/* 128K at 0E0000-0FFFFF */
mem_set_mem_state(0x000e0000, 0x00020000, shflags);
break;
}
flushmmucache();
}
static void
rabbit_write(uint16_t addr, uint8_t val, void *priv)
{
rabbit_t *dev = (rabbit_t *) priv;
switch (addr) {
case 0x22:
dev->cur_reg = val;
dev->tries = 0;
break;
case 0x23:
if (dev->cur_reg == 0x83) {
if (dev->tries < 0x02) {
dev->regs[dev->tries++ | 0x100] = val;
if (dev->tries == 0x02)
rabbit_recalcmapping(dev);
}
} else
dev->regs[dev->cur_reg] = val;
break;
}
}
static uint8_t
rabbit_read(uint16_t addr, void *priv)
{
uint8_t ret = 0xff;
rabbit_t *dev = (rabbit_t *) priv;
switch (addr) {
case 0x23:
if (dev->cur_reg == 0x83) {
if (dev->tries < 0x02)
ret = dev->regs[dev->tries++ | 0x100];
} else
ret = dev->regs[dev->cur_reg];
break;
}
return ret;
}
static void
rabbit_close(void *priv)
{
rabbit_t *dev = (rabbit_t *) priv;
free(dev);
}
static void *
rabbit_init(const device_t *info)
{
rabbit_t *dev = (rabbit_t *) malloc(sizeof(rabbit_t));
memset(dev, 0, sizeof(rabbit_t));
io_sethandler(0x0022, 0x0002, rabbit_read, NULL, NULL, rabbit_write, NULL, NULL, dev);
return dev;
}
const device_t rabbit_device = {
"SiS Rabbit",
0,
0,
rabbit_init, rabbit_close, NULL,
NULL, NULL, NULL,
NULL
};

View File

@@ -46,16 +46,16 @@ apollo_map(uint32_t addr, uint32_t size, int state)
{
switch (state & 3) {
case 0:
mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
break;
case 1:
mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
break;
case 2:
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
break;
case 3:
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
break;
}
@@ -64,20 +64,17 @@ apollo_map(uint32_t addr, uint32_t size, int state)
static void
apollo_smram_map(int smm, uint32_t addr, uint32_t size, int ram)
apollo_smram_map(int smm, uint32_t addr, uint32_t size, int is_smram)
{
int state = (MEM_READ_EXTANY | MEM_WRITE_EXTANY);
if (((is_smram & 0x03) == 0x01) || ((is_smram & 0x03) == 0x02)) {
smram[0].ram_base = 0x000a0000;
smram[0].size = size;
if (ram == 0)
state = (MEM_READ_EXTANY | MEM_WRITE_EXTANY);
else if (ram == 1)
state = (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
else if (ram == 2)
state = (MEM_READ_EXTERNAL_EX | MEM_WRITE_EXTANY);
else if (ram == 3)
state = (MEM_READ_DISABLED | MEM_WRITE_DISABLED);
mem_mapping_set_addr(&ram_smram_mapping[0], smram[0].host_base, size);
mem_mapping_set_exec(&ram_smram_mapping[0], ram + smram[0].ram_base);
}
mem_set_mem_state_common(smm, addr, size, state);
mem_set_mem_state_smram_ex(smm, addr, size, is_smram & 0x03);
flushmmucache();
}
@@ -272,6 +269,14 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
if ((dev->pci_conf[0][0x63] ^ val) & 0xc0)
apollo_map(0xe0000, 0x10000, (val & 0xc0) >> 6);
dev->pci_conf[0][0x63] = val;
if (smram[0].size != 0x00000000) {
mem_set_mem_state_smram_ex(0, smram[0].host_base, smram[0].size, 0x00);
mem_set_mem_state_smram_ex(1, smram[0].host_base, smram[0].size, 0x00);
memset(&smram[0], 0x00, sizeof(smram_t));
mem_mapping_disable(&ram_smram_mapping[0]);
flushmmucache();
}
if (dev->id == 0x0691) switch (val & 0x03) {
case 0x00:
default:
@@ -310,9 +315,9 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
/* Reserved */
apollo_smram_map(1, 0x000a0000, 0x00020000, 3);
if (dev->id == 0x0597) {
/* TODO: SMI 3xxxx-4xxxx redirect to Axxxx-Bxxxx
(this needs a 3xxxx-4xxxx mapping set to EXTERNAL). */
apollo_smram_map(1, 0x00030000, 0x00020000, 3);
/* SMI 3xxxx-4xxxx redirect to Axxxx-Bxxxx. */
smram[0].host_base = 0x00030000;
apollo_smram_map(1, 0x00030000, 0x00020000, 1);
}
apollo_smram_map(0, 0x000a0000, 0x00020000, 3);
break;

View File

@@ -45,7 +45,7 @@
#include <86box/hdc_ide_sff8038i.h>
#include <86box/zip.h>
#include <86box/machine.h>
#include <86box/via_vt82c586b.h>
#include <86box/chipset.h>
#define ACPI_TIMER_FREQ 3579545

View File

@@ -49,7 +49,7 @@
#include <86box/hdc_ide_sff8038i.h>
#include <86box/zip.h>
#include <86box/machine.h>
#include <86box/via_vt82c586b.h>
#include <86box/chipset.h>
// As of now
#include <86box/smbus_piix4.h>

View File

@@ -38,7 +38,7 @@
#define _CODEGEN_H_
#include <86box/mem.h>
#include "../cpu_common/x86_ops.h"
#include "x86_ops.h"
#ifdef __amd64__
#include "codegen_x86-64.h"

View File

@@ -48,7 +48,7 @@
#include <86box/mem.h>
#include "x86.h"
#include "x86_flags.h"
#include "../cpu_common/x86_ops.h"
#include "x86_ops.h"
#include "x87.h"
#include "386_common.h"

View File

@@ -614,7 +614,10 @@ generate_call:
To prevent having zero cycle blocks (eg with a jump instruction pointing
to itself), apply the cycles that would be taken if this jump is taken,
then reverse it for subsequent instructions if the jump is not taken*/
int jump_cycles = codegen_timing_jump_cycles();
int jump_cycles = 0;
if (codegen_timing_jump_cycles)
codegen_timing_jump_cycles();
if (jump_cycles)
codegen_accumulate(ACCREG_cycles, -jump_cycles);

View File

@@ -3,7 +3,7 @@
#include <86box/mem.h>
#include <stddef.h>
#include "../cpu_common/x86_ops.h"
#include "x86_ops.h"
/*Handling self-modifying code (of which there is a lot on x86) :

Some files were not shown because too many files have changed in this diff Show More