diff --git a/src/cpu.c b/src/cpu.c index 4a96355..0192e8c 100644 --- a/src/cpu.c +++ b/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; } } diff --git a/src/cpu.h b/src/cpu.h index c3d0009..9a6ff03 100644 --- a/src/cpu.h +++ b/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) diff --git a/src/cpu_tables.c b/src/cpu_tables.c index 3f2bc9f..0c651f8 100644 --- a/src/cpu_tables.c +++ b/src/cpu_tables.c @@ -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} +}; diff --git a/src/i440bx.c b/src/i440bx.c new file mode 100644 index 0000000..4a1304e --- /dev/null +++ b/src/i440bx.c @@ -0,0 +1,176 @@ +#include + +#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); +} diff --git a/src/i440bx.h b/src/i440bx.h new file mode 100644 index 0000000..8ed559f --- /dev/null +++ b/src/i440bx.h @@ -0,0 +1,2 @@ +void i440bx_init(); +void i440bx_reset(); diff --git a/src/ibm.h b/src/ibm.h index 1d0f48b..86ac97a 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -265,6 +265,7 @@ enum ROM_ITAUTEC_INFOWAYM, ROM_DESKPRO, ROM_VS440FX, + ROM_GA686BX, ROM_MAX }; diff --git a/src/intel_flash.c b/src/intel_flash.c index 2d28956..716d450 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -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 +}; diff --git a/src/intel_flash.h b/src/intel_flash.h index 8ab1a6b..2ea4db5 100644 --- a/src/intel_flash.h +++ b/src/intel_flash.h @@ -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; diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 5cadb78..572ab30 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -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; diff --git a/src/mem.c b/src/mem.c index 8c23410..fc53ab0 100644 --- a/src/mem.c +++ b/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; diff --git a/src/mem.h b/src/mem.h index 5c7935b..34d5194 100644 --- a/src/mem.h +++ b/src/mem.h @@ -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; diff --git a/src/mem_bios.c b/src/mem_bios.c index 78e59c7..f461a79 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -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); diff --git a/src/model.c b/src/model.c index 35a2efd..de53ef2 100644 --- a/src/model.c +++ b/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()); diff --git a/src/nvr.c b/src/nvr.c index 21df383..0c813c6 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -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; } diff --git a/src/piix.c b/src/piix.c index 5ce6ec5..05214ea 100644 --- a/src/piix.c +++ b/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); } diff --git a/src/piix.h b/src/piix.h index e8d7039..08b0032 100644 --- a/src/piix.h +++ b/src/piix.h @@ -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)());