diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index 2014def33..c14a61e83 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -891,13 +891,13 @@ ali1543_init(const device_t *info) dev->pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, ali1533_read, ali1533_write, dev); /* Device 0B: M5229 IDE Controller*/ - dev->ide_slot = pci_add_card(PCI_ADD_IDE, ali5229_read, ali5229_write, dev); - - /* Device 0D: M5237 USB */ - dev->usb_slot = pci_add_card(PCI_ADD_NORMAL_NOBRIDGE, ali5237_read, ali5237_write, dev); + dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, ali5229_read, ali5229_write, dev); /* Device 0C: M7101 Power Managment Controller */ - dev->pmu_slot = pci_add_card(PCI_ADD_BRIDGE, ali7101_read, ali7101_write, dev); + dev->pmu_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, ali7101_read, ali7101_write, dev); + + /* Device 0D: M5237 USB */ + dev->usb_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, ali5237_read, ali5237_write, dev); /* Ports 3F0-1h: M1543 Super I/O */ io_sethandler(0x03f0, 0x0002, ali1533_sio_read, NULL, NULL, ali1533_sio_write, NULL, NULL, dev); diff --git a/src/chipset/ali6117.c b/src/chipset/ali6117.c index 3c3e0f812..0718ce7ee 100644 --- a/src/chipset/ali6117.c +++ b/src/chipset/ali6117.c @@ -146,6 +146,42 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv) case 0x1e: val &= 0x07; + + switch (val) { + /* Half PIT clock. */ + case 0x0: + cpu_set_isa_speed(7159091); + break; + + /* Divisors on the input clock PCLK2, which is double the CPU clock. */ + case 0x1: + cpu_set_isa_speed(cpu_busspeed / 1.5); + break; + + case 0x2: + cpu_set_isa_speed(cpu_busspeed / 2); + break; + + case 0x3: + cpu_set_isa_speed(cpu_busspeed / 2.5); + break; + + case 0x4: + cpu_set_isa_speed(cpu_busspeed / 3); + break; + + case 0x5: + cpu_set_isa_speed(cpu_busspeed / 4); + break; + + case 0x6: + cpu_set_isa_speed(cpu_busspeed / 5); + break; + + case 0x7: + cpu_set_isa_speed(cpu_busspeed / 6); + break; + } break; case 0x20: @@ -282,6 +318,8 @@ ali6117_reset(void *priv) dev->regs[0x34] = 0x04; /* enable internal RTC */ dev->regs[0x35] = 0x20; /* enable internal KBC */ dev->regs[0x36] = dev->local & 0x4; /* M6117D ID */ + + cpu_set_isa_speed(7159091); } diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 2a4f62dc9..fa0ed301a 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -1540,6 +1540,15 @@ static void cpu_update_waitstates(); } + /* Out-of-spec PCI and AGP clocks with overclocked bus. */ + if ((dev->type <= INTEL_440FX) && (cpu_busspeed >= 66666666)) + cpu_set_pci_speed(cpu_busspeed / 2); + + if ((dev->type >= INTEL_440BX) && (cpu_busspeed >= 100000000)) + cpu_set_agp_speed(cpu_busspeed / 1.5); + else if (dev->type >= INTEL_440LX) + cpu_set_agp_speed(cpu_busspeed); + i4x0_write(regs[0x59], 0x59, 0x00, dev); i4x0_write(regs[0x5a], 0x5a, 0x00, dev); i4x0_write(regs[0x5b], 0x5b, 0x00, dev); diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 2d87cdf70..7a7af6855 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -1237,9 +1237,10 @@ static void piix_speed_changed(void *priv) { piix_t *dev = (piix_t *) priv; - int te; + if (!dev) + return; - te = timer_is_enabled(&dev->fast_off_timer); + int te = timer_is_enabled(&dev->fast_off_timer); timer_stop(&dev->fast_off_timer); if (te) @@ -1306,6 +1307,8 @@ static void dev->port_92 = device_add(&port_92_pci_device); + cpu_set_isa_pci_div(4); + dma_alias_set(); if (dev->type < 4) diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index b9a5d77bb..f780ba142 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -157,19 +157,33 @@ via_apollo_setup(via_apollo_t *dev) if (dev->id >= VIA_691) dev->pci_conf[0x67] = 0xec; /* DRAM Timing for Banks 6, 7 */ if (dev->id >= VIA_693A) { - if (cpu_busspeed < 95000000) - dev->pci_conf[0x68] |= 0x00; /* 66 MHz */ - else if (cpu_busspeed < 124000000) - dev->pci_conf[0x68] |= 0x01; /* 100 MHz */ - else - dev->pci_conf[0x68] |= (dev->id == VIA_8601) ? 0x03 : 0x02; /* 133 MHz */ + if (cpu_busspeed < 95000000) { /* 66 MHz */ + cpu_set_pci_speed(cpu_busspeed / 2); + cpu_set_agp_speed(cpu_busspeed); + dev->pci_conf[0x68] |= 0x00; + } else if (cpu_busspeed < 124000000) { /* 100 MHz */ + cpu_set_pci_speed(cpu_busspeed / 3); + cpu_set_agp_speed(cpu_busspeed / 1.5); + dev->pci_conf[0x68] |= 0x01; + } else { /* 133 MHz */ + cpu_set_pci_speed(cpu_busspeed / 4); + cpu_set_agp_speed(cpu_busspeed / 2); + dev->pci_conf[0x68] |= (dev->id == VIA_8601) ? 0x03 : 0x02; + } } else if (dev->id >= VIA_598) { - if (cpu_busspeed < 75000000) - dev->pci_conf[0x68] |= 0x00; /* 66 MHz */ - else if (cpu_busspeed < 100000000) - dev->pci_conf[0x68] |= (dev->id >= VIA_691) ? 0x00 : 0x03; /* 75/83 MHz (66 MHz on 691) */ - else - dev->pci_conf[0x68] |= 0x01; /* 100 MHz */ + if (cpu_busspeed < ((dev->id >= VIA_691) ? 100000000 : 75000000)) { /* 66 MHz */ + cpu_set_pci_speed(cpu_busspeed / 2); + cpu_set_agp_speed(cpu_busspeed); + dev->pci_conf[0x68] |= 0x00; + } else if (cpu_busspeed < 100000000) { /* 75/83 MHz (not available on 691) */ + cpu_set_pci_speed(cpu_busspeed / 2.5); + cpu_set_agp_speed(cpu_busspeed / 1.25); + dev->pci_conf[0x68] |= 0x03; + } else { /* 100 MHz */ + cpu_set_pci_speed(cpu_busspeed / 3); + cpu_set_agp_speed(cpu_busspeed / 1.5); + dev->pci_conf[0x68] |= 0x01; + } } dev->pci_conf[0x6b] = 0x01; diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index 7e4a0835c..aa31fac48 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -503,6 +503,52 @@ pipc_write(int func, int addr, uint8_t val, void *priv) dev->pci_isa_regs[0x07] &= ~(val & 0xb0); break; + case 0x42: + dev->pci_isa_regs[0x42] = val & 0xcf; + + switch (val & 0xf) { + /* Divisors on the PCI clock. */ + case 0x8: + cpu_set_isa_pci_div(3); + break; + + case 0x9: + cpu_set_isa_pci_div(2); + break; + + case 0xa: + cpu_set_isa_pci_div(4); + break; + + case 0xb: + cpu_set_isa_pci_div(6); + break; + + case 0xc: + cpu_set_isa_pci_div(5); + break; + + case 0xd: + cpu_set_isa_pci_div(10); + break; + + case 0xe: + cpu_set_isa_pci_div(12); + break; + + /* Half PIT clock. */ + case 0xf: + cpu_set_isa_speed(7159091); + break; + + /* Divisor 4 on the PCI clock whenever bit 3 is clear. */ + default: + cpu_set_isa_pci_div(4); + break; + } + + break; + case 0x47: if (val & 0x01) trc_write(0x0047, (val & 0x80) ? 0x06 : 0x04, NULL); @@ -940,6 +986,8 @@ pipc_init(const device_t *info) device_add(&port_92_pci_device); + cpu_set_isa_pci_div(4); + dma_alias_set(); if (dev->local <= VIA_PIPC_586B) { diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 98b885cd7..062ba292a 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -167,7 +167,7 @@ int cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles; int cpu_waitstates; int cpu_cache_int_enabled, cpu_cache_ext_enabled; -int cpu_pci_speed, cpu_alt_reset; +int cpu_isa_speed, cpu_pci_speed, cpu_isa_pci_div, cpu_agp_speed, cpu_alt_reset; uint16_t cpu_fast_off_count, cpu_fast_off_val; uint32_t cpu_fast_off_flags; int is_vpc; @@ -564,22 +564,16 @@ cpu_set(void) cpu_update_waitstates(); - isa_cycles = cpu_s->atclk_div; + isa_cycles = cpu_s->atclk_div; if (cpu_s->rspeed <= 8000000) cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; else cpu_rom_prefetch_cycles = cpu_s->rspeed / 1000000; - if (cpu_busspeed < 42500000) - cpu_pci_speed = cpu_busspeed; - else if ((cpu_busspeed > 42500000) && (cpu_busspeed < 84000000)) - cpu_pci_speed = cpu_busspeed / 2; - else - cpu_pci_speed = cpu_busspeed / 3; - - pci_burst_time = cpu_s->rspeed / cpu_pci_speed; - pci_nonburst_time = 4 * pci_burst_time; + cpu_set_isa_pci_div(0); + cpu_set_pci_speed(0); + cpu_set_agp_speed(0); if (cpu_iscyrix) io_sethandler(0x0022, 0x0002, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); @@ -710,34 +704,34 @@ cpu_set(void) if (fpu_type == FPU_287) { #ifdef USE_DYNAREC - x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; - x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32; - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32; + x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; + x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32; + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32; x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32; x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16; - x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32; + x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32; x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16; - x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32; + x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32; x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16; - x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32; + x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32; x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; #endif x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; x86_opcodes_da_a16 = ops_fpu_287_da_a16; x86_opcodes_da_a32 = ops_fpu_287_da_a32; - x86_opcodes_db_a16 = ops_fpu_287_db_a16; + x86_opcodes_db_a16 = ops_fpu_287_db_a16; x86_opcodes_db_a32 = ops_fpu_287_db_a32; - x86_opcodes_dc_a16 = ops_fpu_287_dc_a16; + x86_opcodes_dc_a16 = ops_fpu_287_dc_a16; x86_opcodes_dc_a32 = ops_fpu_287_dc_a32; - x86_opcodes_dd_a16 = ops_fpu_287_dd_a16; + x86_opcodes_dd_a16 = ops_fpu_287_dd_a16; x86_opcodes_dd_a32 = ops_fpu_287_dd_a32; - x86_opcodes_de_a16 = ops_fpu_287_de_a16; + x86_opcodes_de_a16 = ops_fpu_287_de_a16; x86_opcodes_de_a32 = ops_fpu_287_de_a32; - x86_opcodes_df_a16 = ops_fpu_287_df_a16; + x86_opcodes_df_a16 = ops_fpu_287_df_a16; x86_opcodes_df_a32 = ops_fpu_287_df_a32; } timing_rr = 2; /*register dest - register src*/ @@ -820,34 +814,34 @@ cpu_set(void) if (fpu_type == FPU_287) /*In case we get Deskpro 386 emulation*/ { #ifdef USE_DYNAREC - x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; - x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32; - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32; + x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; + x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32; + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32; x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32; x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16; - x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32; + x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32; x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16; - x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32; + x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32; x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16; - x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32; + x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32; x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; #endif x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; x86_opcodes_da_a16 = ops_fpu_287_da_a16; x86_opcodes_da_a32 = ops_fpu_287_da_a32; - x86_opcodes_db_a16 = ops_fpu_287_db_a16; + x86_opcodes_db_a16 = ops_fpu_287_db_a16; x86_opcodes_db_a32 = ops_fpu_287_db_a32; - x86_opcodes_dc_a16 = ops_fpu_287_dc_a16; + x86_opcodes_dc_a16 = ops_fpu_287_dc_a16; x86_opcodes_dc_a32 = ops_fpu_287_dc_a32; - x86_opcodes_dd_a16 = ops_fpu_287_dd_a16; + x86_opcodes_dd_a16 = ops_fpu_287_dd_a16; x86_opcodes_dd_a32 = ops_fpu_287_dd_a32; - x86_opcodes_de_a16 = ops_fpu_287_de_a16; + x86_opcodes_de_a16 = ops_fpu_287_de_a16; x86_opcodes_de_a32 = ops_fpu_287_de_a32; - x86_opcodes_df_a16 = ops_fpu_287_df_a16; + x86_opcodes_df_a16 = ops_fpu_287_df_a16; x86_opcodes_df_a32 = ops_fpu_287_df_a32; } timing_rr = 2; /*register dest - register src*/ @@ -1416,9 +1410,9 @@ cpu_set(void) cpu_features = CPU_FEATURE_RDTSC; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); #ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_686); + codegen_timing_set(&codegen_timing_686); #endif - ccr4 = 0x80; + ccr4 = 0x80; break; @@ -1443,7 +1437,7 @@ cpu_set(void) msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE; #ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_686); + codegen_timing_set(&codegen_timing_686); #endif break; @@ -1499,9 +1493,9 @@ cpu_set(void) msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE; #ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_686); + codegen_timing_set(&codegen_timing_686); #endif - ccr4 = 0x80; + ccr4 = 0x80; break; #endif @@ -1692,7 +1686,7 @@ cpu_set(void) 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_PAE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_p6); + codegen_timing_set(&codegen_timing_p6); #endif break; @@ -1747,7 +1741,7 @@ cpu_set(void) 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_PAE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_p6); + codegen_timing_set(&codegen_timing_p6); #endif break; @@ -1802,7 +1796,7 @@ cpu_set(void) 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_PAE | CR4_PCE | CR4_OSFXSR; #ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_p6); + codegen_timing_set(&codegen_timing_p6); #endif break; @@ -1879,6 +1873,82 @@ cpu_set(void) x87_timings = x87_timings_486; } } + + +void +cpu_set_isa_speed(int speed) +{ + if (speed) { + cpu_isa_speed = speed; + pc_speed_changed(); + } else + cpu_isa_speed = 8000000; + + cpu_log("cpu_set_isa_speed(%d) = %d\n", speed, cpu_isa_speed); +} + + +void +cpu_set_pci_speed(int speed) +{ + if (speed) + cpu_pci_speed = speed; + else if (cpu_busspeed < 42500000) + cpu_pci_speed = cpu_busspeed; + else if (cpu_busspeed < 84000000) + cpu_pci_speed = cpu_busspeed / 2; + else if (cpu_busspeed < 120000000) + cpu_pci_speed = cpu_busspeed / 3; + else + cpu_pci_speed = cpu_busspeed / 4; + + if (cpu_isa_pci_div) + cpu_set_isa_pci_div(cpu_isa_pci_div); + else if (speed) + pc_speed_changed(); + + pci_burst_time = cpu_s->rspeed / cpu_pci_speed; + pci_nonburst_time = 4 * pci_burst_time; + + cpu_log("cpu_set_pci_speed(%d) = %d\n", speed, cpu_pci_speed); +} + + +void +cpu_set_isa_pci_div(int div) +{ + cpu_isa_pci_div = div; + + cpu_log("cpu_set_isa_pci_div(%d)\n", cpu_isa_pci_div); + + if (cpu_isa_pci_div) + cpu_set_isa_speed(cpu_pci_speed / cpu_isa_pci_div); + else + cpu_set_isa_speed(0); +} + + +void +cpu_set_agp_speed(int speed) +{ + if (speed) { + cpu_agp_speed = speed; + pc_speed_changed(); + } + else if (cpu_busspeed < 84000000) + cpu_agp_speed = cpu_busspeed; + else if (cpu_busspeed < 120000000) + cpu_agp_speed = cpu_busspeed / 1.5; + else + cpu_agp_speed = cpu_busspeed / 2; + + agp_burst_time = cpu_s->rspeed / cpu_agp_speed; + agp_nonburst_time = 4 * agp_burst_time; + + cpu_log("cpu_set_agp_speed(%d) = %d\n", speed, cpu_agp_speed); +} + + char * cpu_current_pc(char *bufp) { @@ -3209,12 +3279,12 @@ void cpu_RDMSR() case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F: if (ECX & 1) { - EAX = mtrr_physmask_msr[(ECX - 0x200) >> 1] & 0xffffffff; + EAX = mtrr_physmask_msr[(ECX - 0x200) >> 1] & 0xffffffff; EDX = mtrr_physmask_msr[(ECX - 0x200) >> 1] >> 32; } else { - EAX = mtrr_physbase_msr[(ECX - 0x200) >> 1] & 0xffffffff; + EAX = mtrr_physbase_msr[(ECX - 0x200) >> 1] & 0xffffffff; EDX = mtrr_physbase_msr[(ECX - 0x200) >> 1] >> 32; } break; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 061f8154c..c97016e82 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -433,7 +433,7 @@ extern uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw; extern uint32_t pccache; extern uint8_t *pccache2; -extern double bus_timing, pci_timing; +extern double bus_timing, isa_timing, pci_timing, agp_timing; extern uint64_t pmc[2]; extern uint16_t temp_seg_data[4]; extern uint16_t cs_msr; @@ -477,7 +477,7 @@ extern int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_writ extern int cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles; extern int cpu_waitstates; extern int cpu_cache_int_enabled, cpu_cache_ext_enabled; -extern int cpu_pci_speed; +extern int cpu_isa_speed, cpu_pci_speed, cpu_agp_speed; extern int timing_rr; extern int timing_mr, timing_mrl; @@ -523,6 +523,10 @@ extern char *cpu_current_pc(char *bufp); extern void cpu_update_waitstates(void); extern void cpu_set(void); +extern void cpu_set_isa_speed(int speed); +extern void cpu_set_pci_speed(int speed); +extern void cpu_set_isa_pci_div(int div); +extern void cpu_set_agp_speed(int speed); extern void cpu_CPUID(void); extern void cpu_RDMSR(void); diff --git a/src/device/clock_ics9xxx.c b/src/device/clock_ics9xxx.c index f36a7a5f1..ddca7712b 100644 --- a/src/device/clock_ics9xxx.c +++ b/src/device/clock_ics9xxx.c @@ -1050,10 +1050,11 @@ ics9xxx_set(ics9xxx_t *dev, uint8_t val) } } -#ifdef ENABLE_ICS9xxx_LOG uint16_t bus = dev->frequencies_ptr[val].bus; - ics9xxx_log("ICS9xxx: set(%d) = hw=%d bus=%d ram=%d pci=%d\n", val, hw_select, bus, bus * dev->frequencies_ptr[val].ram_mult, bus / dev->frequencies_ptr[val].pci_div); -#endif + uint32_t pci = bus / dev->frequencies_ptr[val].pci_div; + cpu_set_pci_speed(pci * 10000); + + ics9xxx_log("ICS9xxx: set(%d) = hw=%d bus=%d ram=%d pci=%d\n", val, hw_select, bus, bus * dev->frequencies_ptr[val].ram_mult, pci); } diff --git a/src/device/pci_bridge.c b/src/device/pci_bridge.c index eff3e93bc..ab2d010ac 100644 --- a/src/device/pci_bridge.c +++ b/src/device/pci_bridge.c @@ -335,8 +335,7 @@ pci_bridge_init(const device_t *info) for (i = 0; i < slot_count; i++) { /* Interrupts for bridge slots are assigned in round-robin: ABCD, BCDA, CDAB and so on. */ pci_bridge_log("PCI Bridge %d: downstream slot %02X interrupts %02X %02X %02X %02X\n", dev->bus_index, i, interrupts[i & interrupt_mask], interrupts[(i + 1) & interrupt_mask], interrupts[(i + 2) & interrupt_mask], interrupts[(i + 3) & interrupt_mask]); - /* Use _NOBRIDGE for VIA AGP bridges, as they don't like PCI bridges under them. */ - pci_register_bus_slot(dev->bus_index, i, AGP_BRIDGE_VIA(dev->local) ? PCI_CARD_NORMAL_NOBRIDGE : PCI_CARD_NORMAL, + pci_register_bus_slot(dev->bus_index, i, AGP_BRIDGE(dev->local) ? PCI_CARD_AGP : PCI_CARD_NORMAL, interrupts[i & interrupt_mask], interrupts[(i + 1) & interrupt_mask], interrupts[(i + 2) & interrupt_mask], diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index db4e7f332..e01deb371 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -51,8 +51,8 @@ enum { PCI_CARD_NORTHBRIDGE = 0, PCI_CARD_AGPBRIDGE, PCI_CARD_SOUTHBRIDGE, + PCI_CARD_AGP = 0x0f, PCI_CARD_NORMAL = 0x10, - PCI_CARD_NORMAL_NOBRIDGE, PCI_CARD_VIDEO, PCI_CARD_SCSI, PCI_CARD_SOUND, @@ -65,8 +65,8 @@ enum { PCI_ADD_NORTHBRIDGE = 0, PCI_ADD_AGPBRIDGE, PCI_ADD_SOUTHBRIDGE, + PCI_ADD_AGP = 0x0f, PCI_ADD_NORMAL = 0x10, - PCI_ADD_NORMAL_NOBRIDGE, PCI_ADD_VIDEO, PCI_ADD_SCSI, PCI_ADD_SOUND, @@ -81,8 +81,8 @@ typedef union { } bar_t; -extern int pci_burst_time, - pci_nonburst_time; +extern int pci_burst_time, agp_burst_time, + pci_nonburst_time, agp_nonburst_time; extern void pci_set_irq_routing(int pci_int, int irq); diff --git a/src/include/86box/pit.h b/src/include/86box/pit.h index 366be2ad6..82a885dc5 100644 --- a/src/include/86box/pit.h +++ b/src/include/86box/pit.h @@ -49,7 +49,7 @@ typedef struct PIT { extern pit_t *pit, *pit2; -extern double SYSCLK, PCICLK; +extern double SYSCLK, PCICLK, AGPCLK; extern uint64_t PITCONST, ISACONST, CGACONST, diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 17a564069..c335f8969 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -48,7 +48,8 @@ enum { VIDEO_ISA = 0, VIDEO_MCA, VIDEO_BUS, - VIDEO_PCI + VIDEO_PCI, + VIDEO_AGP }; #define VIDEO_FLAG_TYPE_CGA 0 @@ -381,7 +382,9 @@ extern const device_t voodoo_device; extern const device_t voodoo_banshee_device; extern const device_t creative_voodoo_banshee_device; extern const device_t voodoo_3_2000_device; +extern const device_t voodoo_3_2000_agp_device; extern const device_t voodoo_3_3000_device; +extern const device_t voodoo_3_3000_agp_device; /* Wyse 700 */ extern const device_t wy700_device; diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 202f975ff..eee7de00e 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -215,7 +215,7 @@ machine_at_p2bls_init(const machine_t *model) device_add(&piix4e_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&w83977ef_device); - device_add(ics9xxx_get(ICS9150_08)); + //device_add(ics9xxx_get(ICS9150_08)); /* setting proper speeds requires some interaction with the AS97127F ASIC */ device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); device_add(&w83781d_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */ diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index f81a6d28f..62747df4a 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1049,14 +1049,14 @@ machine_at_m560_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_IDE, 1, 2, 3, 4); - pci_register_slot(0x0C, PCI_CARD_BRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0D, PCI_CARD_NORMAL_NOBRIDGE, 1, 2, 3, 4); device_add(&ali1531_device); device_add(&ali1543_device); device_add(&keyboard_ps2_ami_pci_device); @@ -1082,14 +1082,14 @@ machine_at_ms5164_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_IDE, 1, 2, 3, 4); - pci_register_slot(0x0C, PCI_CARD_BRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0D, PCI_CARD_NORMAL_NOBRIDGE, 1, 2, 3, 4); device_add(&ali1531_device); device_add(&ali1543_device); diff --git a/src/pci.c b/src/pci.c index b7420c953..22ec1dc26 100644 --- a/src/pci.c +++ b/src/pci.c @@ -51,8 +51,8 @@ typedef struct { } pci_mirq_t; -int pci_burst_time, - pci_nonburst_time; +int pci_burst_time, agp_burst_time, + pci_nonburst_time, agp_nonburst_time; static pci_card_t pci_cards[32]; static uint8_t pci_pmc = 0, last_pci_card = 0, last_normal_pci_card = 0, last_pci_bus = 1; @@ -860,8 +860,7 @@ pci_find_slot(uint8_t add_type, uint8_t ignore_slot) if (!dev->read && !dev->write && ((ignore_slot == 0xff) || (i != ignore_slot))) { if (((dev->type == PCI_CARD_NORMAL) && (add_type >= PCI_ADD_NORMAL)) || - (dev->type == add_type) || - ((dev->type == PCI_CARD_NORMAL_NOBRIDGE) && (add_type >= PCI_ADD_NORMAL) && (add_type != PCI_ADD_BRIDGE))) { + (dev->type == add_type)) { ret = i; break; } @@ -878,16 +877,16 @@ pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), pci_card_t *dev; uint8_t i, j; - if (add_type < PCI_ADD_NORMAL) + if (add_type < PCI_ADD_AGP) pci_log("pci_add_card(): Adding PCI CARD at specific slot %02X [SPECIFIC]\n", add_type); if (! PCI) { - pci_log("pci_add_card(): Adding PCI CARD failed (non-PCI machine) [%s]\n", (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : ((add_type == PCI_ADD_SCSI) ? "SCSI" : ((add_type == PCI_ADD_SOUND) ? "SOUND" : "SPECIFIC")))); + pci_log("pci_add_card(): Adding PCI CARD failed (non-PCI machine) [%s]\n", (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_AGP) ? "AGP" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : ((add_type == PCI_ADD_SCSI) ? "SCSI" : ((add_type == PCI_ADD_SOUND) ? "SOUND" : "SPECIFIC"))))); return 0xff; } if (! last_pci_card) { - pci_log("pci_add_card(): Adding PCI CARD failed (no PCI slots) [%s]\n", (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : ((add_type == PCI_ADD_SCSI) ? "SCSI" : ((add_type == PCI_ADD_SOUND) ? "SOUND" : "SPECIFIC")))); + pci_log("pci_add_card(): Adding PCI CARD failed (no PCI slots) [%s]\n", (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_AGP) ? "AGP" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : ((add_type == PCI_ADD_SCSI) ? "SCSI" : ((add_type == PCI_ADD_SOUND) ? "SOUND" : "SPECIFIC"))))); return 0xff; } @@ -908,7 +907,7 @@ pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), dev->read = read; dev->write = write; dev->priv = priv; - pci_log("pci_add_card(): Adding PCI CARD to pci_cards[%i] (bus %02X slot %02X) [%s]\n", i, dev->bus, dev->id, (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : ((add_type == PCI_ADD_SCSI) ? "SCSI" : ((add_type == PCI_ADD_SOUND) ? "SOUND" : "SPECIFIC")))); + pci_log("pci_add_card(): Adding PCI CARD to pci_cards[%i] (bus %02X slot %02X) [%s]\n", i, dev->bus, dev->id, (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_AGP) ? "AGP" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : ((add_type == PCI_ADD_SCSI) ? "SCSI" : ((add_type == PCI_ADD_SOUND) ? "SOUND" : "SPECIFIC"))))); return i; } diff --git a/src/pit.c b/src/pit.c index 2e10a7b38..7087a1f6a 100644 --- a/src/pit.c +++ b/src/pit.c @@ -44,8 +44,8 @@ pit_t *pit, *pit2; double cpuclock, PITCONSTD, SYSCLK, isa_timing, - bus_timing, pci_timing, - PCICLK; + bus_timing, pci_timing, agp_timing, + PCICLK, AGPCLK; uint64_t PITCONST, ISACONST, CGACONST, @@ -961,17 +961,18 @@ pit_set_clock(int clock) { /* Set default CPU/crystal clock and xt_cpu_multi. */ if (cpu_s->cpu_type >= CPU_286) { - if (clock == 66666666) - cpuclock = 200000000.0 / 3.0; - else if (clock == 33333333) - cpuclock = 100000000.0 / 3.0; + int remainder = (clock % 100000000); + if (remainder == 66666666) + cpuclock = (double) (clock - remainder) + (200000000.0 / 3.0); + else if (remainder == 33333333) + cpuclock = (double) (clock - remainder) + (100000000.0 / 3.0); else cpuclock = (double) clock; PITCONSTD = (cpuclock / 1193182.0); PITCONST = (uint64_t) (PITCONSTD * (double)(1ull << 32)); CGACONST = (uint64_t) ((cpuclock / (19687503.0/11.0)) * (double)(1ull << 32)); - ISACONST = (uint64_t) ((cpuclock / 8000000.0) * (double)(1ull << 32)); + ISACONST = (uint64_t) ((cpuclock / (double)cpu_isa_speed) * (double)(1ull << 32)); xt_cpu_multi = 1ULL; } else { cpuclock = 14318184.0; @@ -1039,15 +1040,17 @@ pit_set_clock(int clock) TIMER_USEC = (uint64_t)((cpuclock / 1000000.0) * (double)(1ull << 32)); - isa_timing = (cpuclock / (double)8000000.0); + isa_timing = (cpuclock / (double)cpu_isa_speed); if (cpu_64bitbus) bus_timing = (cpuclock / ((double)cpu_busspeed / 2)); else bus_timing = (cpuclock / (double)cpu_busspeed); pci_timing = (cpuclock / (double)cpu_pci_speed); + agp_timing = (cpuclock / (double)cpu_agp_speed); /* PCICLK in us for use with timer_on_auto(). */ PCICLK = pci_timing / (cpuclock / 1000000.0); + AGPCLK = agp_timing / (cpuclock / 1000000.0); if (cpu_busspeed >= 30000000) SYSCLK = bus_timing * 4.0; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index d81e19147..f1a6ba30a 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -186,6 +186,8 @@ video_cards[] = { { "virge375_vbe20_vlb", &s3_virge_375_4_vlb_device }, { "tgui9400cxi_vlb", &tgui9400cxi_device }, { "tgui9440_vlb", &tgui9440_vlb_device }, + { "voodoo3_2k_agp", &voodoo_3_2000_agp_device }, + { "voodoo3_3k_agp", &voodoo_3_3000_agp_device }, { "", NULL } }; diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index bb9f00de3..bb043a6e2 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -44,7 +44,8 @@ #include <86box/vid_voodoo_render.h> -static video_timings_t timing_banshee = {VIDEO_BUS, 2, 2, 1, 20, 20, 21}; +static video_timings_t timing_banshee = {VIDEO_PCI, 2, 2, 1, 20, 20, 21}; +static video_timings_t timing_banshee_agp = {VIDEO_AGP, 2, 2, 1, 20, 20, 21}; #ifdef CLAMP @@ -116,7 +117,7 @@ typedef struct banshee_t int desktop_y; uint32_t desktop_stride_tiled; - int type, card; + int type, card, agp; int vblank_irq; void *i2c, *i2c_ddc, *ddc; @@ -228,10 +229,12 @@ enum #define PIX_FORMAT_RGB24 2 #define PIX_FORMAT_RGB32 3 +#define VIDSERIAL_DDC_EN (1 << 18) #define VIDSERIAL_DDC_DCK_W (1 << 19) #define VIDSERIAL_DDC_DDA_W (1 << 20) #define VIDSERIAL_DDC_DCK_R (1 << 21) #define VIDSERIAL_DDC_DDA_R (1 << 22) +#define VIDSERIAL_I2C_EN (1 << 23) #define VIDSERIAL_I2C_SCK_W (1 << 24) #define VIDSERIAL_I2C_SDA_W (1 << 25) #define VIDSERIAL_I2C_SCK_R (1 << 26) @@ -617,9 +620,9 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p) { case Init_pciInit0: banshee->pciInit0 = val; - voodoo->read_time = pci_nonburst_time + pci_burst_time * ((val & 0x100) ? 2 : 1); - voodoo->burst_time = pci_burst_time * ((val & 0x200) ? 1 : 0); - voodoo->write_time = pci_nonburst_time + voodoo->burst_time; + voodoo->read_time = (banshee->agp ? agp_nonburst_time : pci_nonburst_time) + (banshee->agp ? agp_burst_time : pci_burst_time) * ((val & 0x100) ? 2 : 1); + voodoo->burst_time = (banshee->agp ? agp_burst_time : pci_burst_time) * ((val & 0x200) ? 1 : 0); + voodoo->write_time = (banshee->agp ? agp_nonburst_time : pci_nonburst_time) + voodoo->burst_time; break; case Init_lfbMemoryConfig: @@ -965,16 +968,19 @@ static uint32_t banshee_ext_inl(uint16_t addr, void *p) break; case Video_vidSerialParallelPort: - ret = banshee->vidSerialParallelPort & ~(VIDSERIAL_DDC_DCK_R | VIDSERIAL_DDC_DDA_R); - if (!(banshee->vidSerialParallelPort & VIDSERIAL_DDC_DCK_W) || i2c_gpio_get_scl(banshee->i2c_ddc)) - ret |= VIDSERIAL_DDC_DCK_R; - if (!(banshee->vidSerialParallelPort & VIDSERIAL_DDC_DDA_W) || i2c_gpio_get_sda(banshee->i2c_ddc)) - ret |= VIDSERIAL_DDC_DDA_R; - ret = ret & ~(VIDSERIAL_I2C_SCK_R | VIDSERIAL_I2C_SDA_R); - if (!(banshee->vidSerialParallelPort & VIDSERIAL_I2C_SCK_W) || i2c_gpio_get_scl(banshee->i2c)) - ret |= VIDSERIAL_I2C_SCK_R; - if (!(banshee->vidSerialParallelPort & VIDSERIAL_I2C_SDA_W) || i2c_gpio_get_sda(banshee->i2c)) - ret |= VIDSERIAL_I2C_SDA_R; + ret = banshee->vidSerialParallelPort& ~(VIDSERIAL_DDC_DCK_R | VIDSERIAL_DDC_DDA_R | VIDSERIAL_I2C_SCK_R | VIDSERIAL_I2C_SDA_R); + if (banshee->vidSerialParallelPort & VIDSERIAL_DDC_EN) { + if (i2c_gpio_get_scl(banshee->i2c_ddc)) + ret |= VIDSERIAL_DDC_DCK_R; + if (i2c_gpio_get_sda(banshee->i2c_ddc)) + ret |= VIDSERIAL_DDC_DDA_R; + } + if (banshee->vidSerialParallelPort & VIDSERIAL_I2C_EN) { + if (i2c_gpio_get_scl(banshee->i2c)) + ret |= VIDSERIAL_I2C_SCK_R; + if (i2c_gpio_get_sda(banshee->i2c)) + ret |= VIDSERIAL_I2C_SDA_R; + } // banshee_log("vidSerialParallelPort: read %08x %08x %04x(%08x):%08x\n", ret, ret & (VIDSERIAL_DDC_DCK_R | VIDSERIAL_DDC_DDA_R), CS,cs,cpu_state.pc); break; @@ -2426,13 +2432,39 @@ static uint8_t banshee_pci_read(int func, int addr, void *p) case 0x32: ret = banshee->pci_regs[0x32]; break; case 0x33: ret = banshee->pci_regs[0x33]; break; + case 0x34: ret = banshee->agp ? 0x54 : 0x60; break; + case 0x3c: ret = banshee->pci_regs[0x3c]; break; case 0x3d: ret = 0x01; break; /*INTA*/ case 0x3e: ret = 0x04; break; case 0x3f: ret = 0xff; break; - + + case 0x40: ret = 0x01; break; + + case 0x50: ret = banshee->pci_regs[0x50]; break; + + case 0x54: ret = 0x02; break; + case 0x55: ret = 0x60; break; + case 0x56: ret = 0x10; break; /* assumed AGP 1.0 */ + + case 0x58: ret = (banshee->type == TYPE_BANSHEE) ? 0x21 : 0x23; break; + case 0x59: ret = 0x02; break; + case 0x5b: ret = 0x07; break; + + case 0x5c: ret = banshee->pci_regs[0x5c]; break; + case 0x5d: ret = banshee->pci_regs[0x5d]; break; + case 0x5e: ret = banshee->pci_regs[0x5e]; break; + case 0x5f: ret = banshee->pci_regs[0x5f]; break; + + case 0x60: ret = 0x01; break; + case 0x62: ret = 0x21; break; + + case 0x64: ret = banshee->pci_regs[0x64]; break; + case 0x65: ret = banshee->pci_regs[0x65]; break; + case 0x66: ret = banshee->pci_regs[0x66]; break; + case 0x67: ret = banshee->pci_regs[0x67]; break; } // banshee_log("%02X\n", ret); return ret; @@ -2524,8 +2556,28 @@ static void banshee_pci_write(int func, int addr, uint8_t val, void *p) mem_mapping_disable(&banshee->bios_rom.mapping); } return; - case 0x3c: - banshee->pci_regs[0x3c] = val; + case 0x3c: case 0x50: case 0x65: case 0x67: + banshee->pci_regs[addr] = val; + return; + + case 0x5c: + banshee->pci_regs[0x5c] = val & 0x27; + return; + + case 0x5d: + banshee->pci_regs[0x5d] = val & 0x03; + return; + + case 0x5f: + banshee->pci_regs[0x5e] = val; + return; + + case 0x64: + banshee->pci_regs[0x64] = val & 0x03; + return; + + case 0x66: + banshee->pci_regs[0x66] = val & 0xc0; return; } } @@ -2652,13 +2704,14 @@ static const device_config_t banshee_sdram_config[] = } }; -static void *banshee_init_common(const device_t *info, wchar_t *fn, int has_sgram, int type, int voodoo_type) +static void *banshee_init_common(const device_t *info, wchar_t *fn, int has_sgram, int type, int voodoo_type, int agp) { int mem_size; banshee_t *banshee = malloc(sizeof(banshee_t)); memset(banshee, 0, sizeof(banshee_t)); banshee->type = type; + banshee->agp = agp; rom_init(&banshee->bios_rom, fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_disable(&banshee->bios_rom.mapping); @@ -2717,7 +2770,7 @@ static void *banshee_init_common(const device_t *info, wchar_t *fn, int has_sgra banshee->dramInit1 = 1 << 30; /*SDRAM*/ banshee->svga.decode_mask = 0x1ffffff; - banshee->card = pci_add_card(PCI_ADD_VIDEO, banshee_pci_read, banshee_pci_write, banshee); + banshee->card = pci_add_card(banshee->agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, banshee_pci_read, banshee_pci_write, banshee); banshee->voodoo = voodoo_2d3d_card_init(voodoo_type); banshee->voodoo->p = banshee; @@ -2769,26 +2822,34 @@ static void *banshee_init_common(const device_t *info, wchar_t *fn, int has_sgra break; } - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_banshee); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, banshee->agp ? &timing_banshee_agp : &timing_banshee); return banshee; } static void *banshee_init(const device_t *info) { - return banshee_init_common(info, L"roms/video/voodoo/Pci_sg.rom", 1, TYPE_BANSHEE, VOODOO_BANSHEE); + return banshee_init_common(info, L"roms/video/voodoo/Pci_sg.rom", 1, TYPE_BANSHEE, VOODOO_BANSHEE, 1); } static void *creative_banshee_init(const device_t *info) { - return banshee_init_common(info, L"roms/video/voodoo/BlasterPCI.rom", 0, TYPE_BANSHEE, VOODOO_BANSHEE); + return banshee_init_common(info, L"roms/video/voodoo/BlasterPCI.rom", 0, TYPE_BANSHEE, VOODOO_BANSHEE, 0); } static void *v3_2000_init(const device_t *info) { - return banshee_init_common(info, L"roms/video/voodoo/2k11sd.rom", 0, TYPE_V3_2000, VOODOO_3); + return banshee_init_common(info, L"roms/video/voodoo/2k11sd.rom", 0, TYPE_V3_2000, VOODOO_3, 0); +} +static void *v3_2000_agp_init(const device_t *info) +{ + return banshee_init_common(info, L"roms/video/voodoo/2k11sd.rom", 0, TYPE_V3_2000, VOODOO_3, 1); } static void *v3_3000_init(const device_t *info) { - return banshee_init_common(info, L"roms/video/voodoo/3k12sd.rom", 0, TYPE_V3_3000, VOODOO_3); + return banshee_init_common(info, L"roms/video/voodoo/3k12sd.rom", 0, TYPE_V3_3000, VOODOO_3, 0); +} +static void *v3_3000_agp_init(const device_t *info) +{ + return banshee_init_common(info, L"roms/video/voodoo/3k12sd.rom", 0, TYPE_V3_3000, VOODOO_3, 1); } static int banshee_available(void) @@ -2803,10 +2864,12 @@ static int v3_2000_available(void) { return rom_present(L"roms/video/voodoo/2k11sd.rom"); } +#define v3_2000_agp_available v3_2000_available static int v3_3000_available(void) { return rom_present(L"roms/video/voodoo/3k12sd.rom"); } +#define v3_3000_agp_available v3_3000_available static void banshee_close(void *p) { @@ -2878,6 +2941,20 @@ const device_t voodoo_3_2000_device = banshee_sdram_config }; +const device_t voodoo_3_2000_agp_device = +{ + "3dfx Voodoo3 2000", + DEVICE_AGP, + 0, + v3_2000_agp_init, + banshee_close, + NULL, + { v3_2000_agp_available }, + banshee_speed_changed, + banshee_force_redraw, + banshee_sdram_config +}; + const device_t voodoo_3_3000_device = { "3dfx Voodoo3 3000", @@ -2891,3 +2968,17 @@ const device_t voodoo_3_3000_device = banshee_force_redraw, banshee_sdram_config }; + +const device_t voodoo_3_3000_agp_device = +{ + "3dfx Voodoo3 3000", + DEVICE_AGP, + 0, + v3_3000_agp_init, + banshee_close, + NULL, + { v3_3000_agp_available }, + banshee_speed_changed, + banshee_force_redraw, + banshee_sdram_config +}; diff --git a/src/video/video.c b/src/video/video.c index 66fb1d024..00329b07c 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -653,6 +653,13 @@ video_update_timing(void) video_timing_write_b = (int)(pci_timing * vid_timings->write_b); video_timing_write_w = (int)(pci_timing * vid_timings->write_w); video_timing_write_l = (int)(pci_timing * vid_timings->write_l); + } else if (vid_timings->type == VIDEO_AGP) { + video_timing_read_b = (int)(agp_timing * vid_timings->read_b); + video_timing_read_w = (int)(agp_timing * vid_timings->read_w); + video_timing_read_l = (int)(agp_timing * vid_timings->read_l); + video_timing_write_b = (int)(agp_timing * vid_timings->write_b); + video_timing_write_w = (int)(agp_timing * vid_timings->write_w); + video_timing_write_l = (int)(agp_timing * vid_timings->write_l); } else { video_timing_read_b = (int)(bus_timing * vid_timings->read_b); video_timing_read_w = (int)(bus_timing * vid_timings->read_w); diff --git a/src/win/win_settings.c b/src/win/win_settings.c index e999d6a64..3fc32a960 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -826,10 +826,17 @@ machine_type_get_internal_name(int id) int machine_type_available(int id) { - if ((id > 0) && (id < MACHINE_TYPE_MAX)) - return 1; - else - return 0; + int c = 0; + + if ((id > 0) && (id < MACHINE_TYPE_MAX)) { + while (machine_get_internal_name_ex(c) != NULL) { + if (machine_available(c) && (machines[c].type == id)) + return 1; + c++; + } + } + + return 0; }