Add Gigabyte GA-686BX emulation.
As part of this, add i440BX chipset, PIIX4, and i28F002BC Flash.
This commit is contained in:
parent
3c4fa0511e
commit
fda3832e3a
16 changed files with 571 additions and 54 deletions
29
src/cpu.c
29
src/cpu.c
|
|
@ -70,6 +70,7 @@ enum
|
|||
CPUID_TSC = (1 << 4),
|
||||
CPUID_MSR = (1 << 5),
|
||||
CPUID_CMPXCHG8B = (1 << 8),
|
||||
CPUID_SEP = (1 << 11),
|
||||
CPUID_CMOV = (1 << 15),
|
||||
CPUID_MMX = (1 << 23)
|
||||
};
|
||||
|
|
@ -1048,7 +1049,7 @@ void cpu_set()
|
|||
timing_jmp_pm = 3;
|
||||
timing_jmp_pm_gate = 18;
|
||||
timing_misaligned = 3;
|
||||
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_CX8;
|
||||
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_CX8 | CPU_FEATURE_SYSCALL;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE;
|
||||
codegen_timing_set(&codegen_timing_p6);
|
||||
|
|
@ -1097,7 +1098,7 @@ void cpu_set()
|
|||
timing_jmp_pm = 3;
|
||||
timing_jmp_pm_gate = 18;
|
||||
timing_misaligned = 3;
|
||||
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_CX8 | CPU_FEATURE_MMX;
|
||||
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_CX8 | CPU_FEATURE_MMX | CPU_FEATURE_SYSCALL;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE;
|
||||
codegen_timing_set(&codegen_timing_p6);
|
||||
|
|
@ -1637,7 +1638,7 @@ void cpu_CPUID()
|
|||
{
|
||||
EAX = CPUID;
|
||||
EBX = ECX = 0;
|
||||
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV;
|
||||
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV;// | CPUID_SEP;
|
||||
}
|
||||
else
|
||||
EAX = EBX = ECX = EDX = 0;
|
||||
|
|
@ -1655,7 +1656,7 @@ void cpu_CPUID()
|
|||
{
|
||||
EAX = CPUID;
|
||||
EBX = ECX = 0;
|
||||
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX;
|
||||
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX;// | CPUID_SEP;
|
||||
}
|
||||
else
|
||||
EAX = EBX = ECX = EDX = 0;
|
||||
|
|
@ -1735,6 +1736,17 @@ void cpu_RDMSR()
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case CPU_PENTIUMPRO:
|
||||
case CPU_PENTIUM_2:
|
||||
EAX = EDX = 0;
|
||||
switch (ECX)
|
||||
{
|
||||
case 0x10:
|
||||
EAX = tsc & 0xffffffff;
|
||||
EDX = tsc >> 32;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1818,6 +1830,15 @@ void cpu_WRMSR()
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case CPU_PENTIUMPRO:
|
||||
case CPU_PENTIUM_2:
|
||||
switch (ECX)
|
||||
{
|
||||
case 0x10:
|
||||
tsc = EAX | ((uint64_t)EDX << 32);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
16
src/cpu.h
16
src/cpu.h
|
|
@ -120,6 +120,7 @@ extern CPU cpus_6x86_SS7[];
|
|||
extern CPU cpus_K6_S7[];
|
||||
extern CPU cpus_K6_SS7[];
|
||||
extern CPU cpus_PentiumPro[];
|
||||
extern CPU cpus_Slot1_100MHz[];
|
||||
|
||||
extern CPU cpus_pcjr[];
|
||||
extern CPU cpus_europc[];
|
||||
|
|
@ -138,13 +139,14 @@ extern int cpu_multi;
|
|||
/*Cyrix 5x86/6x86 only has data misalignment penalties when crossing 8-byte boundaries*/
|
||||
extern int cpu_cyrix_alignment;
|
||||
|
||||
#define CPU_FEATURE_RDTSC (1 << 0)
|
||||
#define CPU_FEATURE_MSR (1 << 1)
|
||||
#define CPU_FEATURE_MMX (1 << 2)
|
||||
#define CPU_FEATURE_CR4 (1 << 3)
|
||||
#define CPU_FEATURE_VME (1 << 4)
|
||||
#define CPU_FEATURE_CX8 (1 << 5)
|
||||
#define CPU_FEATURE_3DNOW (1 << 6)
|
||||
#define CPU_FEATURE_RDTSC (1 << 0)
|
||||
#define CPU_FEATURE_MSR (1 << 1)
|
||||
#define CPU_FEATURE_MMX (1 << 2)
|
||||
#define CPU_FEATURE_CR4 (1 << 3)
|
||||
#define CPU_FEATURE_VME (1 << 4)
|
||||
#define CPU_FEATURE_CX8 (1 << 5)
|
||||
#define CPU_FEATURE_3DNOW (1 << 6)
|
||||
#define CPU_FEATURE_SYSCALL (1 << 7)
|
||||
|
||||
extern uint32_t cpu_features;
|
||||
static inline int cpu_has_feature(int feature)
|
||||
|
|
|
|||
|
|
@ -512,3 +512,16 @@ CPU cpus_PentiumPro[] =
|
|||
{"Pentium II Overdrive 333", CPU_PENTIUM_2, fpus_builtin, 21, 333333333, 3, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 40},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Slot1_100MHz[] =
|
||||
{
|
||||
/*Intel Pentium II*/
|
||||
{"Pentium II/233", CPU_PENTIUM_2, fpus_builtin, 20, 233333333, 3, 33333333, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 28},
|
||||
{"Pentium II/266", CPU_PENTIUM_2, fpus_builtin, 20, 266666666, 3, 33333333, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 32},
|
||||
{"Pentium II/300", CPU_PENTIUM_2, fpus_builtin, 20, 300000000, 3, 33333333, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 36},
|
||||
{"Pentium II/333", CPU_PENTIUM_2, fpus_builtin, 20, 333333333, 3, 33333333, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 40},
|
||||
{"Pentium II/350", CPU_PENTIUM_2, fpus_builtin, 20, 350000000, 3, 33333333, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 42},
|
||||
{"Pentium II/400", CPU_PENTIUM_2, fpus_builtin, 20, 400000000, 3, 33333333, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 48},
|
||||
{"Pentium II/450", CPU_PENTIUM_2, fpus_builtin, 20, 450000000, 3, 33333333, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 54},
|
||||
{"", -1, 0, 0, 0}
|
||||
};
|
||||
|
|
|
|||
176
src/i440bx.c
Normal file
176
src/i440bx.c
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "keyboard_at.h"
|
||||
#include "mem.h"
|
||||
#include "pci.h"
|
||||
#include "x86.h"
|
||||
|
||||
#include "i440bx.h"
|
||||
|
||||
static uint8_t card_i440bx[256];
|
||||
|
||||
static void i440bx_map(uint32_t addr, uint32_t size, int state)
|
||||
{
|
||||
switch (state & 3)
|
||||
{
|
||||
case 0:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
}
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
void i440bx_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
if (func)
|
||||
return;
|
||||
|
||||
if (addr >= 0x10 && addr < 0x4f)
|
||||
return;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x00: case 0x01: case 0x02: case 0x03:
|
||||
case 0x08: case 0x09: case 0x0a: case 0x0b:
|
||||
case 0x0c: case 0x0e:
|
||||
return;
|
||||
|
||||
case 0x04: /*Command register*/
|
||||
val &= 0x02;
|
||||
val |= 0x04;
|
||||
break;
|
||||
case 0x05:
|
||||
val = 0;
|
||||
break;
|
||||
|
||||
case 0x06: /*Status*/
|
||||
val = 0;
|
||||
break;
|
||||
case 0x07:
|
||||
val = 0x02;
|
||||
break;
|
||||
|
||||
case 0x59: /*PAM0*/
|
||||
if ((card_i440bx[0x59] ^ val) & 0xf0)
|
||||
{
|
||||
i440bx_map(0xf0000, 0x10000, val >> 4);
|
||||
}
|
||||
pclog("i440bx_write : PAM0 write %02X\n", val);
|
||||
// if (val == 0x10)
|
||||
// output = 3;
|
||||
break;
|
||||
case 0x5a: /*PAM1*/
|
||||
if ((card_i440bx[0x5a] ^ val) & 0x0f)
|
||||
i440bx_map(0xc0000, 0x04000, val & 0xf);
|
||||
if ((card_i440bx[0x5a] ^ val) & 0xf0)
|
||||
i440bx_map(0xc4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5b: /*PAM2*/
|
||||
if ((card_i440bx[0x5b] ^ val) & 0x0f)
|
||||
i440bx_map(0xc8000, 0x04000, val & 0xf);
|
||||
if ((card_i440bx[0x5b] ^ val) & 0xf0)
|
||||
i440bx_map(0xcc000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5c: /*PAM3*/
|
||||
if ((card_i440bx[0x5c] ^ val) & 0x0f)
|
||||
i440bx_map(0xd0000, 0x04000, val & 0xf);
|
||||
if ((card_i440bx[0x5c] ^ val) & 0xf0)
|
||||
i440bx_map(0xd4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5d: /*PAM4*/
|
||||
if ((card_i440bx[0x5d] ^ val) & 0x0f)
|
||||
i440bx_map(0xd8000, 0x04000, val & 0xf);
|
||||
if ((card_i440bx[0x5d] ^ val) & 0xf0)
|
||||
i440bx_map(0xdc000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5e: /*PAM5*/
|
||||
if ((card_i440bx[0x5e] ^ val) & 0x0f)
|
||||
i440bx_map(0xe0000, 0x04000, val & 0xf);
|
||||
if ((card_i440bx[0x5e] ^ val) & 0xf0)
|
||||
i440bx_map(0xe4000, 0x04000, val >> 4);
|
||||
pclog("i440bx_write : PAM5 write %02X\n", val);
|
||||
break;
|
||||
case 0x5f: /*PAM6*/
|
||||
if ((card_i440bx[0x5f] ^ val) & 0x0f)
|
||||
i440bx_map(0xe8000, 0x04000, val & 0xf);
|
||||
if ((card_i440bx[0x5f] ^ val) & 0xf0)
|
||||
i440bx_map(0xec000, 0x04000, val >> 4);
|
||||
pclog("i440bx_write : PAM6 write %02X\n", val);
|
||||
break;
|
||||
|
||||
case 0x72: /*SMRAM*/
|
||||
// pclog("Write SMRAM %02x was %02x\n", val,
|
||||
val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/
|
||||
val |= (card_i440bx[0x72] & 0x10); /*D_LCK can not be cleared by software*/
|
||||
if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/
|
||||
{
|
||||
val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/
|
||||
val |= (card_i440bx[0x72] & 0x08);
|
||||
}
|
||||
if ((card_i440bx[0x72] ^ val) & 0x40)
|
||||
{
|
||||
if (val & 0x40) /*SMRAM enabled*/
|
||||
{
|
||||
pclog("Enable SMRAM\n");
|
||||
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
pclog("Disable SMRAM\n");
|
||||
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
card_i440bx[addr] = val;
|
||||
}
|
||||
|
||||
uint8_t i440bx_read(int func, int addr, void *priv)
|
||||
{
|
||||
if (func)
|
||||
return 0xff;
|
||||
|
||||
return card_i440bx[addr];
|
||||
}
|
||||
|
||||
void i440bx_init()
|
||||
{
|
||||
pci_add_specific(0, i440bx_read, i440bx_write, NULL);
|
||||
|
||||
memset(card_i440bx, 0, 256);
|
||||
card_i440bx[0x00] = 0x86; card_i440bx[0x01] = 0x80; /*Intel*/
|
||||
card_i440bx[0x02] = 0x92; card_i440bx[0x03] = 0x71; /*82441FX*/
|
||||
card_i440bx[0x04] = 0x06; card_i440bx[0x05] = 0x00;
|
||||
card_i440bx[0x06] = 0x00; card_i440bx[0x07] = 0x02;
|
||||
card_i440bx[0x08] = 0x02; /*B1 stepping*/
|
||||
card_i440bx[0x09] = 0x00; card_i440bx[0x0a] = 0x00; card_i440bx[0x0b] = 0x06;
|
||||
card_i440bx[0x51] = 0x20; /*66 MHz bus*/
|
||||
card_i440bx[0x60] = card_i440bx[0x61] = card_i440bx[0x62] = card_i440bx[0x63] = 0x01;
|
||||
card_i440bx[0x64] = card_i440bx[0x65] = card_i440bx[0x66] = card_i440bx[0x67] = 0x01;
|
||||
card_i440bx[0x72] = 0x02;
|
||||
card_i440bx[0x73] = 0x38;
|
||||
card_i440bx[0x7a] = 0x02; /*AGP disabled*/
|
||||
}
|
||||
|
||||
void i440bx_reset()
|
||||
{
|
||||
i440bx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/
|
||||
i440bx_write(0, 0x5a, 0x0, NULL);
|
||||
i440bx_write(0, 0x5b, 0x0, NULL);
|
||||
i440bx_write(0, 0x5c, 0x0, NULL);
|
||||
i440bx_write(0, 0x5d, 0x0, NULL);
|
||||
i440bx_write(0, 0x5e, 0x0, NULL);
|
||||
i440bx_write(0, 0x5f, 0x0, NULL);
|
||||
}
|
||||
2
src/i440bx.h
Normal file
2
src/i440bx.h
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
void i440bx_init();
|
||||
void i440bx_reset();
|
||||
|
|
@ -265,6 +265,7 @@ enum
|
|||
ROM_ITAUTEC_INFOWAYM,
|
||||
ROM_DESKPRO,
|
||||
ROM_VS440FX,
|
||||
ROM_GA686BX,
|
||||
|
||||
ROM_MAX
|
||||
};
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ enum
|
|||
typedef struct flash_t
|
||||
{
|
||||
uint8_t command, status;
|
||||
uint8_t flash_id;
|
||||
uint16_t flash_id;
|
||||
uint8_t type;
|
||||
int invert_high_pin;
|
||||
mem_mapping_t mapping[8], mapping_h[10];
|
||||
|
|
@ -71,7 +71,18 @@ static uint16_t flash_readw(uint32_t addr, void *p)
|
|||
flash_t *flash = (flash_t *)p;
|
||||
addr &= flash->addr_mask;
|
||||
if (flash->invert_high_pin) addr ^= 0x10000;
|
||||
return *(uint16_t *)&(flash->array[addr]);
|
||||
switch (flash->command)
|
||||
{
|
||||
case CMD_READ_ARRAY:
|
||||
default:
|
||||
return *(uint16_t *)&(flash->array[addr]);
|
||||
|
||||
case CMD_IID:
|
||||
return 0x89 | (flash->flash_id << 8);
|
||||
|
||||
case CMD_READ_STATUS:
|
||||
return flash->status;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t flash_readl(uint32_t addr, void *p)
|
||||
|
|
@ -187,7 +198,7 @@ static void intel_flash_add_mappings_inverted(flash_t *flash)
|
|||
}
|
||||
}
|
||||
|
||||
void *intel_flash_init(uint8_t type)
|
||||
void *intel_flash_init(uint8_t type, uint8_t flash_id)
|
||||
{
|
||||
FILE *f;
|
||||
flash_t *flash = malloc(sizeof(flash_t));
|
||||
|
|
@ -232,24 +243,16 @@ void *intel_flash_init(uint8_t type)
|
|||
case ROM_VS440FX:
|
||||
strcpy(flash_path, "vs440fx/");
|
||||
break;
|
||||
case ROM_GA686BX:
|
||||
strcpy(flash_path, "ga686bx/");
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("intel_flash_init on unsupported ROM set %i\n", romset);
|
||||
}
|
||||
// pclog("Flash init: Path is: %s\n", flash_path);
|
||||
|
||||
switch (type & (FLASH_IS_BXB | FLASH_2MBIT))
|
||||
{
|
||||
case 0:
|
||||
flash->flash_id = 0x94;
|
||||
break;
|
||||
case FLASH_IS_BXB:
|
||||
flash->flash_id = 0x95;
|
||||
break;
|
||||
case FLASH_2MBIT:
|
||||
flash->flash_id = 0x74;
|
||||
break;
|
||||
}
|
||||
flash->flash_id = flash_id;
|
||||
|
||||
flash->addr_mask = (type & FLASH_2MBIT) ? 0x3ffff : 0x1ffff;
|
||||
|
||||
|
|
@ -377,24 +380,29 @@ void *intel_flash_init(uint8_t type)
|
|||
/* For AMI BIOS'es - Intel 28F001BXT with high address pin inverted. */
|
||||
void *intel_flash_bxt_ami_init()
|
||||
{
|
||||
return intel_flash_init(FLASH_INVERT);
|
||||
return intel_flash_init(FLASH_INVERT, 0x94);
|
||||
}
|
||||
|
||||
/* For Award BIOS'es - Intel 28F001BXT with high address pin not inverted. */
|
||||
void *intel_flash_bxt_init()
|
||||
{
|
||||
return intel_flash_init(0);
|
||||
return intel_flash_init(0, 0x94);
|
||||
}
|
||||
|
||||
/* For Acer BIOS'es - Intel 28F001BXB. */
|
||||
void *intel_flash_bxb_init()
|
||||
{
|
||||
return intel_flash_init(FLASH_IS_BXB);
|
||||
return intel_flash_init(FLASH_IS_BXB, 0x95);
|
||||
}
|
||||
|
||||
static void *intel_flash_28fb200bxt_init(void)
|
||||
{
|
||||
return intel_flash_init(FLASH_INVERT | FLASH_2MBIT);
|
||||
return intel_flash_init(FLASH_INVERT | FLASH_2MBIT, 0x74);
|
||||
}
|
||||
|
||||
static void *intel_flash_28f002bc_init(void)
|
||||
{
|
||||
return intel_flash_init(FLASH_INVERT | FLASH_2MBIT, 0x7c);
|
||||
}
|
||||
|
||||
void intel_flash_close(void *p)
|
||||
|
|
@ -468,3 +476,16 @@ device_t intel_flash_28fb200bxt_device =
|
|||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
device_t intel_flash_28f002bc_device =
|
||||
{
|
||||
"Intel 28F002BC Flash BIOS",
|
||||
0,
|
||||
intel_flash_28f002bc_init,
|
||||
intel_flash_close,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,3 +2,4 @@ extern device_t intel_flash_bxt_ami_device;
|
|||
extern device_t intel_flash_bxt_device;
|
||||
extern device_t intel_flash_bxb_device;
|
||||
extern device_t intel_flash_28fb200bxt_device;
|
||||
extern device_t intel_flash_28f002bc_device;
|
||||
|
|
|
|||
|
|
@ -310,6 +310,10 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv)
|
|||
keyboard_at.output_port = val;
|
||||
break;
|
||||
|
||||
case 0xd2: /*Write to keyboard output buffer*/
|
||||
keyboard_at_adddata(val);
|
||||
break;
|
||||
|
||||
case 0xd3: /*Write to mouse output buffer*/
|
||||
keyboard_at_adddata_mouse(val);
|
||||
break;
|
||||
|
|
@ -624,7 +628,10 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv)
|
|||
break;
|
||||
|
||||
case 0xca: /*AMI - read keyboard mode*/
|
||||
keyboard_at_adddata(0x00); /*ISA mode*/
|
||||
if (romset == ROM_GA686BX) /*TODO*/
|
||||
keyboard_at_adddata(0x01); /*PS2 mode*/
|
||||
else
|
||||
keyboard_at_adddata(0x00); /*ISA mode*/
|
||||
break;
|
||||
|
||||
case 0xcb: /*AMI - set keyboard mode*/
|
||||
|
|
@ -643,6 +650,10 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv)
|
|||
keyboard_at.want60 = 1;
|
||||
break;
|
||||
|
||||
case 0xd2: /*Write keyboard output buffer*/
|
||||
keyboard_at.want60 = 1;
|
||||
break;
|
||||
|
||||
case 0xd3: /*Write mouse output buffer*/
|
||||
keyboard_at.want60 = 1;
|
||||
break;
|
||||
|
|
|
|||
36
src/mem.c
36
src/mem.c
|
|
@ -33,7 +33,7 @@ mem_mapping_t ram_high_mapping;
|
|||
mem_mapping_t ram_mid_mapping;
|
||||
mem_mapping_t ram_remapped_mapping;
|
||||
mem_mapping_t bios_mapping[8];
|
||||
mem_mapping_t bios_high_mapping[8];
|
||||
mem_mapping_t bios_high_mapping[9];
|
||||
static mem_mapping_t romext_mapping;
|
||||
|
||||
static uint8_t ff_array[0x1000];
|
||||
|
|
@ -1343,24 +1343,26 @@ void mem_add_bios()
|
|||
{
|
||||
if (AT || (romset == ROM_XI8088 && xi8088_bios_128kb()))
|
||||
{
|
||||
mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_mapping[2], 0xe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_mapping[3], 0xec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x20000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x24000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_mapping[2], 0xe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x28000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_mapping[3], 0xec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x2c000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
|
||||
}
|
||||
mem_mapping_add(&bios_mapping[4], 0xf0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_mapping[5], 0xf4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_mapping[4], 0xf0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x30000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_mapping[5], 0xf4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x34000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x38000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x3c000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
|
||||
|
||||
mem_mapping_add(&bios_high_mapping[0], (AT && cpu_16bitbus) ? 0xfe0000 : 0xfffe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_high_mapping[1], (AT && cpu_16bitbus) ? 0xfe4000 : 0xfffe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_high_mapping[2], (AT && cpu_16bitbus) ? 0xfe8000 : 0xfffe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_high_mapping[3], (AT && cpu_16bitbus) ? 0xfec000 : 0xfffec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000 & biosmask), MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_high_mapping[4], (AT && cpu_16bitbus) ? 0xff0000 : 0xffff0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_high_mapping[5], (AT && cpu_16bitbus) ? 0xff4000 : 0xffff4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_high_mapping[6], (AT && cpu_16bitbus) ? 0xff8000 : 0xffff8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_high_mapping[7], (AT && cpu_16bitbus) ? 0xffc000 : 0xffffc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_high_mapping[0], (AT && cpu_16bitbus) ? 0xfe0000 : 0xfffe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x20000 & biosmask), MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_high_mapping[1], (AT && cpu_16bitbus) ? 0xfe4000 : 0xfffe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x24000 & biosmask), MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_high_mapping[2], (AT && cpu_16bitbus) ? 0xfe8000 : 0xfffe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x28000 & biosmask), MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_high_mapping[3], (AT && cpu_16bitbus) ? 0xfec000 : 0xfffec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x2c000 & biosmask), MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_high_mapping[4], (AT && cpu_16bitbus) ? 0xff0000 : 0xffff0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x30000 & biosmask), MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_high_mapping[5], (AT && cpu_16bitbus) ? 0xff4000 : 0xffff4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x34000 & biosmask), MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_high_mapping[6], (AT && cpu_16bitbus) ? 0xff8000 : 0xffff8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x38000 & biosmask), MEM_MAPPING_ROM, 0);
|
||||
mem_mapping_add(&bios_high_mapping[7], (AT && cpu_16bitbus) ? 0xffc000 : 0xffffc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x3c000 & biosmask), MEM_MAPPING_ROM, 0);
|
||||
if (biosmask == 0x3ffff)
|
||||
mem_mapping_add(&bios_high_mapping[8], (AT && cpu_16bitbus) ? 0xfc0000 : 0xfffc0000, 0x20000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_ROM, 0);
|
||||
}
|
||||
|
||||
int mem_a20_key = 0, mem_a20_alt = 0;
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ void mem_write_nulll(uint32_t addr, uint32_t val, void *p);
|
|||
FILE *romfopen(char *fn, char *mode);
|
||||
|
||||
mem_mapping_t bios_mapping[8];
|
||||
mem_mapping_t bios_high_mapping[8];
|
||||
mem_mapping_t bios_high_mapping[9];
|
||||
|
||||
extern mem_mapping_t ram_high_mapping;
|
||||
extern mem_mapping_t ram_remapped_mapping;
|
||||
|
|
|
|||
|
|
@ -1167,6 +1167,15 @@ int loadbios()
|
|||
|
||||
biosmask = 0x3ffff;
|
||||
return 1;
|
||||
|
||||
case ROM_GA686BX:
|
||||
f = romfopen("ga686bx/6BX.F2a", "rb");
|
||||
if (!f) break;
|
||||
romfread(rom, 0x40000, 1, f);
|
||||
fclose(f);
|
||||
|
||||
biosmask = 0x3ffff;
|
||||
return 1;
|
||||
}
|
||||
printf("Failed to load ROM!\n");
|
||||
if (f) fclose(f);
|
||||
|
|
|
|||
18
src/model.c
18
src/model.c
|
|
@ -29,6 +29,7 @@
|
|||
#include "i430hx.h"
|
||||
#include "i430lx.h"
|
||||
#include "i430vx.h"
|
||||
#include "i440bx.h"
|
||||
#include "i440fx.h"
|
||||
#include "ide.h"
|
||||
#include "intel.h"
|
||||
|
|
@ -133,6 +134,7 @@ void xt_xi8088_init();
|
|||
void xt_zenith_init();
|
||||
void at_mvp3_init();
|
||||
void at_vs440fx_init();
|
||||
void at_ga686bx_init();
|
||||
int model;
|
||||
|
||||
int AMSTRAD, AT, PCI, TANDY, MCA;
|
||||
|
|
@ -241,6 +243,8 @@ MODEL models[] =
|
|||
|
||||
{"[Socket 8] Intel VS440FX", ROM_VS440FX, "vs440fx", { {"Intel", cpus_PentiumPro}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 256, 8, at_vs440fx_init, NULL},
|
||||
|
||||
{"[Slot 1] Gigabyte GA-686BX", ROM_GA686BX, "ga686bx", { {"Intel", cpus_Slot1_100MHz}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 512, 8, at_ga686bx_init, NULL},
|
||||
|
||||
{"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0, 0}
|
||||
};
|
||||
|
||||
|
|
@ -833,6 +837,20 @@ void at_vs440fx_init()
|
|||
device_add(&intel_flash_28fb200bxt_device);
|
||||
}
|
||||
|
||||
void at_ga686bx_init()
|
||||
{
|
||||
at_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_slot(0x8);
|
||||
pci_slot(0x9);
|
||||
pci_slot(0xa);
|
||||
pci_slot(0xb);
|
||||
i440bx_init();
|
||||
piix4_init(7, 0x8, 0x9, 0xa, 0xb, i440bx_reset);
|
||||
w83877tf_init(0x250, 0x89);
|
||||
device_add(&intel_flash_28f002bc_device);
|
||||
}
|
||||
|
||||
void model_init()
|
||||
{
|
||||
pclog("Initting as %s\n", model_getname());
|
||||
|
|
|
|||
|
|
@ -357,6 +357,7 @@ void loadnvr()
|
|||
case ROM_IBMPS1_2133_451: f = nvrfopen("ibmps1_2133.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_ECS_386_32: f = nvrfopen("ecs_386_32.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_VS440FX: f = nvrfopen("vs440fx.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_GA686BX: f = nvrfopen("ga686bx.nvr", "rb"); nvrmask = 127; break;
|
||||
|
||||
default: return;
|
||||
}
|
||||
|
|
@ -465,6 +466,7 @@ void savenvr()
|
|||
case ROM_IBMPS1_2133_451: f = nvrfopen("ibmps1_2133.nvr", "wb"); break;
|
||||
case ROM_ECS_386_32: f = nvrfopen("ecs_386_32.nvr", "wb"); break;
|
||||
case ROM_VS440FX: f = nvrfopen("vs440fx.nvr", "wb"); break;
|
||||
case ROM_GA686BX: f = nvrfopen("ga686bx.nvr", "wb"); break;
|
||||
|
||||
default: return;
|
||||
}
|
||||
|
|
|
|||
245
src/piix.c
245
src/piix.c
|
|
@ -16,15 +16,168 @@
|
|||
|
||||
#include "piix.h"
|
||||
|
||||
enum
|
||||
{
|
||||
TYPE_PIIX = 0,
|
||||
TYPE_PIIX3,
|
||||
TYPE_PIIX4
|
||||
};
|
||||
|
||||
static struct
|
||||
{
|
||||
int type;
|
||||
|
||||
/*PIIX4*/
|
||||
uint8_t card_pm[256];
|
||||
|
||||
uint16_t pmba;
|
||||
struct
|
||||
{
|
||||
uint64_t timer_offset;
|
||||
} pm;
|
||||
|
||||
uint16_t smbba;
|
||||
struct
|
||||
{
|
||||
uint8_t host_ctrl;
|
||||
} smbus;
|
||||
|
||||
uint8_t port_92;
|
||||
} piix;
|
||||
|
||||
static uint8_t card_piix[256], card_piix_ide[256];
|
||||
static sff_busmaster_t piix_busmaster[2];
|
||||
static uint8_t piix_rc = 0;
|
||||
static void (*piix_nb_reset)();
|
||||
|
||||
static void piix_pm_write(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
// pclog("piix_pm_write: port=%04x val=%02x\n", port, val);
|
||||
}
|
||||
static uint8_t piix_pm_read(uint16_t port, void *p)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (port & 0x3f)
|
||||
{
|
||||
case 0x02: case 0x03:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case 0x04: case 0x05:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case 0x08: case 0x09: case 0x0a: case 0x0b:
|
||||
{
|
||||
uint64_t timer = tsc - piix.pm.timer_offset;
|
||||
uint32_t pm_timer = (timer * 3579545) / cpu_get_speed();
|
||||
|
||||
ret = pm_timer >> ((port & 3) * 8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x0e: case 0x0f:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case 0x10: case 0x11:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case 0x18: case 0x19:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case 0x20: case 0x21:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case 0x28: case 0x29: case 0x2a: case 0x2b:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case 0x2c: case 0x2d: case 0x2e: case 0x2f:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case 0x30:
|
||||
ret = 0;
|
||||
break;
|
||||
case 0x31:
|
||||
ret = 0;
|
||||
break;
|
||||
case 0x32:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
// default:
|
||||
// fatal("piix_pm_read: unknown read %04x\n", port);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void piix_smbus_write(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
// pclog("piix_smbus_write: port=%04x val=%02x\n", port, val);
|
||||
|
||||
switch (port & 0xf)
|
||||
{
|
||||
case 0x2:
|
||||
piix.smbus.host_ctrl = (val & 0x5f) | (piix.smbus.host_ctrl & 0x40);
|
||||
break;
|
||||
}
|
||||
}
|
||||
static uint8_t piix_smbus_read(uint16_t port, void *p)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (port & 0x0f)
|
||||
{
|
||||
case 0x0:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
ret = piix.smbus.host_ctrl;
|
||||
break;
|
||||
|
||||
case 0x5:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
// default:
|
||||
// fatal("piix_smbus_read: unknown read %04x\n", port);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pm_clear_io(void)
|
||||
{
|
||||
io_removehandler(piix.pmba, 0x0040, piix_pm_read, NULL, NULL, piix_pm_write, NULL, NULL, NULL);
|
||||
io_removehandler(piix.smbba, 0x0010, piix_smbus_read, NULL, NULL, piix_smbus_write, NULL, NULL, NULL);
|
||||
}
|
||||
static void pm_set_io(void)
|
||||
{
|
||||
// pclog("pm_set_io: %02x %04x\n", piix.card_pm[0x04], piix.smbba);
|
||||
if ((piix.card_pm[0x04] & 0x01) && piix.pmba)
|
||||
{
|
||||
// pclog("PMBA=%04x\n", piix.pmba);
|
||||
io_sethandler(piix.pmba, 0x0040, piix_pm_read, NULL, NULL, piix_pm_write, NULL, NULL, NULL);
|
||||
}
|
||||
if ((piix.card_pm[0x04] & 0x01) && piix.smbba)
|
||||
{
|
||||
// pclog("SMBBA=%04x\n", piix.smbba);
|
||||
io_sethandler(piix.smbba, 0x0010, piix_smbus_read, NULL, NULL, piix_smbus_write, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
// pclog("piix_write: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, pc);
|
||||
if (func > 1)
|
||||
if (func > ((piix.type == TYPE_PIIX4) ? 3 : 1))
|
||||
return;
|
||||
|
||||
if (func == 1) /*IDE*/
|
||||
|
|
@ -82,6 +235,41 @@ void piix_write(int func, int addr, uint8_t val, void *priv)
|
|||
}
|
||||
// pclog("PIIX write %02X %02X\n", addr, val);
|
||||
}
|
||||
else if (func == 2) /*USB*/
|
||||
{
|
||||
/*Not implemented*/
|
||||
}
|
||||
else if (func == 3) /*PM*/
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
case 0x04:
|
||||
pm_clear_io();
|
||||
piix.card_pm[0x04] = val & 1;
|
||||
pm_set_io();
|
||||
break;
|
||||
case 0x40:
|
||||
pm_clear_io();
|
||||
piix.pmba = (piix.pmba & 0xff00) | (val & 0xc0);
|
||||
pm_set_io();
|
||||
break;
|
||||
case 0x41:
|
||||
pm_clear_io();
|
||||
piix.pmba = (piix.pmba & 0xc0) | (val << 8);
|
||||
pm_set_io();
|
||||
break;
|
||||
case 0x90:
|
||||
pm_clear_io();
|
||||
piix.smbba = (piix.smbba & 0xff00) | (val & 0xf0);
|
||||
pm_set_io();
|
||||
break;
|
||||
case 0x91:
|
||||
pm_clear_io();
|
||||
piix.smbba = (piix.smbba & 0xf0) | (val << 8);
|
||||
pm_set_io();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (addr >= 0x0f && addr < 0x4c)
|
||||
|
|
@ -130,16 +318,20 @@ void piix_write(int func, int addr, uint8_t val, void *priv)
|
|||
uint8_t piix_read(int func, int addr, void *priv)
|
||||
{
|
||||
// pclog("piix_read: func=%d addr=%02x %04x:%08x\n", func, addr, CS, pc);
|
||||
if (func > 1)
|
||||
return 0xff;
|
||||
if (func > ((piix.type == TYPE_PIIX4) ? 3 : 1))
|
||||
return 0xff;
|
||||
|
||||
if (func == 1) /*IDE*/
|
||||
{
|
||||
// pclog("PIIX IDE read %02X %02X\n", addr, card_piix_ide[addr]);
|
||||
return card_piix_ide[addr];
|
||||
}
|
||||
else if (func == 2) /*USB*/
|
||||
return 0xff; /*Not implemented*/
|
||||
else if (func == 3)
|
||||
return piix.card_pm[addr];
|
||||
else
|
||||
return card_piix[addr];
|
||||
return card_piix[addr];
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -157,6 +349,7 @@ void piix_rc_write(uint16_t port, uint8_t val, void *p)
|
|||
piix_nb_reset();
|
||||
keyboard_at_reset(); /*Reset keyboard controller to reset system flag*/
|
||||
ide_reset_devices();
|
||||
piix.pm.timer_offset = tsc;
|
||||
}
|
||||
resetx86();
|
||||
}
|
||||
|
|
@ -164,6 +357,25 @@ void piix_rc_write(uint16_t port, uint8_t val, void *p)
|
|||
piix_rc = val & ~4;
|
||||
}
|
||||
|
||||
static uint8_t piix_92_read(uint16_t port, void *p)
|
||||
{
|
||||
return piix.port_92;
|
||||
}
|
||||
static void piix_92_write(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
if ((mem_a20_alt ^ val) & 2)
|
||||
{
|
||||
mem_a20_alt = val & 2;
|
||||
mem_a20_recalc();
|
||||
}
|
||||
if ((~piix.port_92 & val) & 1)
|
||||
{
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
}
|
||||
piix.port_92 = val;
|
||||
}
|
||||
|
||||
void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)())
|
||||
{
|
||||
pci_add_specific(card, piix_read, piix_write, NULL);
|
||||
|
|
@ -217,4 +429,29 @@ void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_r
|
|||
|
||||
io_sethandler(0x0cf9, 0x0001, piix_rc_read, NULL, NULL, piix_rc_write, NULL, NULL, NULL);
|
||||
piix_nb_reset = nb_reset;
|
||||
|
||||
piix.type = TYPE_PIIX3;
|
||||
}
|
||||
|
||||
void piix4_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)())
|
||||
{
|
||||
piix_init(card, pci_a, pci_b, pci_c, pci_d, nb_reset);
|
||||
|
||||
piix.type = TYPE_PIIX4;
|
||||
|
||||
card_piix[0x02] = 0x10; card_piix[0x03] = 0x71; /*82371EB (PIIX4)*/
|
||||
|
||||
card_piix_ide[0x02] = 0x11; card_piix_ide[0x03] = 0x71; /*82371EB (PIIX4)*/
|
||||
|
||||
memset(&piix.card_pm, 0, sizeof(piix.card_pm));
|
||||
piix.card_pm[0x00] = 0x86; piix.card_pm[0x01] = 0x80; /*Intel*/
|
||||
piix.card_pm[0x02] = 0x13; piix.card_pm[0x03] = 0x71; /*82371EB (PIIX4)*/
|
||||
piix.card_pm[0x06] = 0x80; piix.card_pm[0x07] = 0x02;
|
||||
piix.card_pm[0x09] = 0x00; piix.card_pm[0x0a] = 0x80; piix.card_pm[0x0b] = 0x06; /*Bridge device*/
|
||||
piix.card_pm[0x3d] = 0x01; /*IRQA*/
|
||||
piix.card_pm[0x40] = 0x01;
|
||||
piix.card_pm[0x90] = 0x01;
|
||||
piix.pm.timer_offset = 0;
|
||||
|
||||
io_sethandler(0x0092, 0x0001, piix_92_read, NULL, NULL, piix_92_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)());
|
||||
void piix4_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)());
|
||||
|
|
|
|||
Loading…
Reference in a new issue