Added the AOpen AP61 and fixed floppies on the LG IBM 440 FX.

This commit is contained in:
OBattler
2024-01-24 04:56:31 +01:00
parent a21b8d865d
commit 9107c2fa25
8 changed files with 139 additions and 92 deletions

View File

@@ -8,19 +8,14 @@
*
* Implementation of the Intel 450KX Mars Chipset.
*
* i450GX is way more popular of an option but needs more stuff.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Tiseno100,
*
* Authors: Tiseno100
*
* Copyright 2021-2024 Miran Grca.
* Copyright 2021 Tiseno100.
*/
/*
Note: i450KX PB manages PCI memory access with MC manages DRAM memory access.
Due to 86Box limitations we can't manage them seperately thus it is dev branch till then.
i450GX is way more popular of an option but needs more stuff.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -97,17 +92,18 @@ i450kx_smram_recalc(i450kx_t *dev, int bus)
const uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf;
uint32_t addr;
uint32_t size;
int enable = bus ? !(regs[0x57] & 0x08) : (regs[0x57] & 0x08);
smram_disable(dev->smram[bus]);
addr = ((uint32_t) regs[0xb8] << 16) | ((uint32_t) regs[0xb9] << 24);
size = (((uint32_t) ((regs[0xbb] >> 4) & 0x0f)) << 16) + 0x00010000;
if ((addr != 0x00000000) && !!(regs[0x57] & 0x08)) {
if ((addr != 0x00000000) && enable) {
if (bus)
smram_enable_ex(dev->smram[bus], addr, addr, size, 0, !!(regs[0x57] & 8), 0, 1);
smram_enable_ex(dev->smram[bus], addr, addr, size, 0, 0, 0, enable);
else
smram_enable_ex(dev->smram[bus], addr, addr, size, !!(regs[0x57] & 8), 0, 1, 0);
smram_enable_ex(dev->smram[bus], addr, addr, size, 0, 0, enable, 0);
}
flushmmucache();
@@ -118,10 +114,8 @@ i450kx_vid_buf_recalc(i450kx_t *dev, int bus)
{
const uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf;
#if 0
// int state = (regs[0x58] & 0x02) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_DISABLED | MEM_WRITE_DISABLED);
#endif
int state = (regs[0x58] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY);
int state = (regs[0x58] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) :
(MEM_READ_EXTANY | MEM_WRITE_EXTANY);
if (bus)
mem_set_mem_state_bus_both(0x000a0000, 0x00020000, state);
@@ -136,10 +130,10 @@ pb_write(int func, int addr, uint8_t val, void *priv)
{
i450kx_t *dev = (i450kx_t *) priv;
// pclog("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80));
i450kx_log("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80));
if (func == 0) {
i450kx_log("[%04X:%08X] i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X\n", CS, cpu_state.pc,
addr, val);
if (func == 0)
switch (addr) {
case 0x04:
dev->pb_pci_conf[addr] = (dev->pb_pci_conf[addr] & 0x04) | (val & 0x53);
@@ -373,6 +367,7 @@ pb_write(int func, int addr, uint8_t val, void *priv)
default:
break;
}
}
}
static uint8_t
@@ -381,10 +376,12 @@ pb_read(int func, int addr, void *priv)
const i450kx_t *dev = (i450kx_t *) priv;
uint8_t ret = 0xff;
if (func == 0)
if (func == 0) {
ret = dev->pb_pci_conf[addr];
// pclog("i450KX-PB: [R] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80));
i450kx_log("[%04X:%08X] i450KX-PB: [R] dev->pb_pci_conf[%02X] = %02X\n", CS, cpu_state.pc,
addr, ret);
}
return ret;
}
@@ -407,10 +404,10 @@ mc_write(int func, int addr, uint8_t val, void *priv)
{
i450kx_t *dev = (i450kx_t *) priv;
// pclog("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80));
i450kx_log("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80));
if (func == 0) {
i450kx_log("[%04X:%08X] i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X\n", CS, cpu_state.pc,
addr, val);
if (func == 0)
switch (addr) {
case 0x4c:
dev->mc_pci_conf[addr] = val & 0xdf;
@@ -600,6 +597,7 @@ mc_write(int func, int addr, uint8_t val, void *priv)
default:
break;
}
}
}
static uint8_t
@@ -608,10 +606,12 @@ mc_read(int func, int addr, void *priv)
const i450kx_t *dev = (i450kx_t *) priv;
uint8_t ret = 0xff;
if (func == 0)
if (func == 0) {
ret = dev->mc_pci_conf[addr];
// pclog("i450KX-MC: [R] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80));
i450kx_log("[%04X:%08X] i450KX-MC: [R] dev->mc_pci_conf[%02X] = %02X\n", CS, cpu_state.pc,
addr, ret);
}
return ret;
}
@@ -622,10 +622,6 @@ i450kx_reset(void *priv)
i450kx_t *dev = (i450kx_t *) priv;
uint32_t i;
#if 0
// pclog("i450KX: i450kx_reset()\n");
#endif
/* Defaults PB */
dev->pb_pci_conf[0x00] = 0x86;
dev->pb_pci_conf[0x01] = 0x80;

View File

@@ -2372,10 +2372,10 @@ cpu_CPUID(void)
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV;
} else if (EAX == 2) {
if (!strcmp(machine_get_internal_name(), "ap61")) {
/* if (!strcmp(machine_get_internal_name(), "ap61")) {
EAX = 0x00000001;
EDX = 0x00000000;
} else {
} else */ {
EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries
Instruction TLB: 4 MB pages, fully associative, 2 entries
Data TLB: 4 KB pages, 4-way set associative, 64 entries */
@@ -2799,7 +2799,9 @@ amd_k_invalid_rdmsr:
case CPU_PENTIUM2:
case CPU_PENTIUM2D:
EAX = EDX = 0;
switch (ECX) {
/* Per RichardG's probing of a real Deschutes using my RDMSR tool,
we have discovered that the top 18 bits are filtered out. */
switch (ECX & 0x00003fff) {
case 0x00:
case 0x01:
break;
@@ -2821,6 +2823,11 @@ amd_k_invalid_rdmsr:
EDX = msr.apic_base >> 32;
cpu_log("APIC_BASE read : %08X%08X\n", EDX, EAX);
break;
/* Unknown (undocumented?) MSR used by the Hyper-V BIOS. */
case 0x20:
EAX = msr.ecx20 & 0xffffffff;
EDX = msr.ecx20 >> 32;
break;
case 0x2a:
EAX = 0xc4000000;
EDX = 0;
@@ -3022,26 +3029,6 @@ amd_k_invalid_rdmsr:
EAX = msr.ecx570 & 0xffffffff;
EDX = msr.ecx570 >> 32;
break;
case 0x1002ff:
EAX = msr.ecx1002ff & 0xffffffff;
EDX = msr.ecx1002ff >> 32;
break;
case 0x40000020:
EAX = msr.ecx40000020 & 0xffffffff;
EDX = msr.ecx40000020 >> 32;
break;
case 0xf0f00250:
EAX = msr.ecxf0f00250 & 0xffffffff;
EDX = msr.ecxf0f00250 >> 32;
break;
case 0xf0f00258:
EAX = msr.ecxf0f00258 & 0xffffffff;
EDX = msr.ecxf0f00258 >> 32;
break;
case 0xf0f00259:
EAX = msr.ecxf0f00259 & 0xffffffff;
EDX = msr.ecxf0f00259 >> 32;
break;
default:
i686_invalid_rdmsr:
cpu_log("RDMSR: Invalid MSR: %08X\n", ECX);
@@ -3303,7 +3290,9 @@ amd_k_invalid_wrmsr:
case CPU_PENTIUMPRO:
case CPU_PENTIUM2:
case CPU_PENTIUM2D:
switch (ECX) {
/* Per RichardG's probing of a real Deschutes using my RDMSR tool,
we have discovered that the top 18 bits are filtered out. */
switch (ECX & 0x00003fff) {
case 0x00:
case 0x01:
if (EAX || EDX)
@@ -3318,6 +3307,10 @@ amd_k_invalid_wrmsr:
msr.apic_base = EAX | ((uint64_t) EDX << 32);
#endif
break;
/* Unknown (undocumented?) MSR used by the Hyper-V BIOS. */
case 0x20:
msr.ecx20 = EAX | ((uint64_t) EDX << 32);
break;
case 0x2a:
break;
case 0x79:
@@ -3462,21 +3455,6 @@ amd_k_invalid_wrmsr:
case 0x570:
msr.ecx570 = EAX | ((uint64_t) EDX << 32);
break;
case 0x1002ff:
msr.ecx1002ff = EAX | ((uint64_t) EDX << 32);
break;
case 0x40000020:
msr.ecx40000020 = EAX | ((uint64_t) EDX << 32);
break;
case 0xf0f00250:
msr.ecxf0f00250 = EAX | ((uint64_t) EDX << 32);
break;
case 0xf0f00258:
msr.ecxf0f00258 = EAX | ((uint64_t) EDX << 32);
break;
case 0xf0f00259:
msr.ecxf0f00259 = EAX | ((uint64_t) EDX << 32);
break;
default:
i686_invalid_wrmsr:
cpu_log("WRMSR: Invalid MSR: %08X\n", ECX);

View File

@@ -253,6 +253,12 @@ typedef struct {
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
uint64_t apic_base; /* 0x0000001b - Should the Pentium not also have this? */
/* Weird long MSR's used by the Hyper-V BIOS. */
uint64_t ecx20; /* 0x00000020, really 0x40000020, but we filter out the top 18 bits
like a real Deschutes does. */
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
uint64_t ecx79; /* 0x00000079 */
/* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */
@@ -314,9 +320,6 @@ typedef struct {
/* IBM 486SLC and 486BL MSR's */
uint64_t ibm_por2; /* 0x00001002 - Processor Operation Register */
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
uint64_t ecx1002ff; /* 0x001002ff - MSR used by some Intel AMI boards */
/* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */
uint64_t amd_efer; /* 0xc0000080 */
@@ -338,14 +341,6 @@ typedef struct {
/* K6-3, K6-2P, and K6-3P MSR's */
uint64_t amd_l2aar; /* 0xc0000089 */
/* Weird long MSR's used by the Hyper-V BIOS. */
uint64_t ecx40000020; /* 0x40000020 */
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
uint64_t ecxf0f00250; /* 0xf0f00250 - Some weird long MSR's used by i686 AMI & some Phoenix BIOSes */
uint64_t ecxf0f00258; /* 0xf0f00258 */
uint64_t ecxf0f00259; /* 0xf0f00259 */
} msr_t;
typedef struct {

View File

@@ -705,8 +705,8 @@ extern int machine_at_ficva503a_init(const machine_t *);
extern int machine_at_5emapro_init(const machine_t *);
/* m_at_socket8.c */
extern int machine_at_ap61_init(const machine_t *);
extern int machine_at_p6rp4_init(const machine_t *);
extern int machine_at_aurora_init(const machine_t *);
extern int machine_at_686nx_init(const machine_t *);
extern int machine_at_acerv60n_init(const machine_t *);

View File

@@ -39,6 +39,39 @@
#include "cpu.h"
#include <86box/machine.h>
int
machine_at_ap61_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/ap61/ap61r120.bin",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x19, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x14, PCI_CARD_NORTHBRIDGE_SEC, 0, 0, 0, 0);
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x07, PCI_CARD_IDE, 0xFE, 0xFF, 0, 0);
pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3);
device_add(&i450kx_device);
device_add(&sio_zb_device);
device_add(&ide_cmd646_device);
device_add(&keyboard_ps2_acer_pci_device);
device_add(&fdc37c665_device);
device_add(&sst_flash_29ee010_device);
// device_add(&intel_flash_bxt_device);
return ret;
}
int
machine_at_p6rp4_init(const machine_t *model)
{
@@ -183,8 +216,10 @@ machine_at_lgibm440fx_init(const machine_t *model)
pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3);
device_add(&i440fx_device);
device_add(&piix3_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&w83787f_device);
// device_add(&keyboard_ps2_ami_pci_device);
device_add(&keyboard_ps2_ami_device);
// device_add(&w83787f_device);
device_add(&w83877f_president_device);
device_add(&sst_flash_29ee010_device);
return ret;

View File

@@ -11655,6 +11655,46 @@ const machine_t machines[] = {
/* Socket 8 machines */
/* 450KX */
/* This has an AMIKey-2, which is an updated version of type 'H'. */
{
.name = "[i450KX] AOpen AP61",
.internal_name = "ap61",
.type = MACHINE_TYPE_SOCKET8,
.chipset = MACHINE_CHIPSET_INTEL_450KX,
.init = machine_at_ap61_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_SOCKET8,
.block = CPU_BLOCK_NONE,
.min_bus = 60000000,
.max_bus = 66666667,
.min_voltage = 2100,
.max_voltage = 3500,
.min_multi = 1.5,
.max_multi = 8.0
},
.bus_flags = MACHINE_PS2_PCI,
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI,
.ram = {
.min = 8192,
.max = 524288,
.step = 8192
},
.nvrmask = 127,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* This has an AMIKey-2, which is an updated version of type 'H'. */
{
.name = "[i450KX] ASUS P/I-P6RP4",
.internal_name = "p6rp4",

View File

@@ -215,8 +215,9 @@ static void
w83787f_fdc_handler(w83787f_t *dev)
{
fdc_remove(dev->fdc);
if (!(dev->regs[0] & 0x20) && !(dev->regs[6] & 0x08))
if (!(dev->regs[0] & 0x20))
fdc_set_base(dev->fdc, (dev->regs[0] & 0x10) ? FDC_PRIMARY_ADDR : FDC_SECONDARY_ADDR);
fdc_set_power_down(dev->fdc, !!(dev->regs[6] & 0x08));
}
static void
@@ -258,10 +259,10 @@ w83787f_write(uint16_t port, uint8_t val, void *priv)
return;
} else {
if (dev->locked) {
if (dev->rw_locked)
if (dev->rw_locked && (dev->cur_reg <= 0x0b))
return;
if (dev->cur_reg == 6)
val &= 0xF3;
val &= 0xFB;
valxor = val ^ dev->regs[dev->cur_reg];
dev->regs[dev->cur_reg] = val;
} else
@@ -363,7 +364,7 @@ w83787f_read(uint16_t port, void *priv)
else if (port == 0x252) {
if (dev->cur_reg == 7)
ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2));
else if (!dev->rw_locked)
else if (!dev->rw_locked || (dev->cur_reg > 0x0b))
ret = dev->regs[dev->cur_reg];
}
}
@@ -406,6 +407,7 @@ w83787f_reset(w83787f_t *dev)
dev->regs[0x00] = 0xd0;
fdc_reset(dev->fdc);
w83787f_fdc_handler(dev);
dev->regs[0x01] = 0x2C;
dev->regs[0x03] = 0x70;

View File

@@ -78,12 +78,12 @@ w83877f_remap(w83877f_t *dev)
{
uint8_t hefras = HEFRAS;
io_removehandler(0x250, 0x0002,
io_removehandler(0x250, 0x0003,
w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev);
io_removehandler(FDC_PRIMARY_ADDR, 0x0002,
w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev);
dev->base_address = (hefras ? FDC_PRIMARY_ADDR : 0x250);
io_sethandler(dev->base_address, 0x0002,
io_sethandler(dev->base_address, hefras ? 0x0002 : 0x0003,
w83877f_read, NULL, NULL, w83877f_write, NULL, NULL, dev);
dev->key_times = hefras + 1;
dev->key = (hefras ? 0x86 : 0x88) | HEFERE;
@@ -155,8 +155,9 @@ static void
w83877f_fdc_handler(w83877f_t *dev)
{
fdc_remove(dev->fdc);
if (!(dev->regs[6] & 0x08) && (dev->regs[0x20] & 0xc0))
fdc_set_base(dev->fdc, FDC_PRIMARY_ADDR);
if (dev->regs[0x20] & 0xc0)
fdc_set_base(dev->fdc, make_port(dev, 0x20));
fdc_set_power_down(dev->fdc, !!(dev->regs[6] & 0x08));
}
static void
@@ -252,7 +253,7 @@ w83877f_write(uint16_t port, uint8_t val, void *priv)
if (dev->cur_reg == 0x29)
return;
if (dev->cur_reg == 6)
val &= 0xF3;
val &= 0xFB;
valxor = val ^ dev->regs[dev->cur_reg];
dev->regs[dev->cur_reg] = val;
} else