diff --git a/src/cpu.c b/src/cpu.c index 70ee33f..9391550 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -4,6 +4,7 @@ #include "io.h" #include "x86_ops.h" #include "mem.h" +#include "pci.h" #include "codegen.h" OpFn *x86_dynarec_opcodes; @@ -106,223 +107,223 @@ static struct CPU cpus_8088[] = { /*8088 standard*/ - {"8088/4.77", CPU_8088, 0, 4772727, 1, 0, 0, 0, 0}, - {"8088/8", CPU_8088, 1, 8000000, 1, 0, 0, 0, 0}, - {"8088/10", CPU_8088, 2, 10000000, 1, 0, 0, 0, 0}, - {"8088/12", CPU_8088, 3, 12000000, 1, 0, 0, 0, 0}, - {"8088/16", CPU_8088, 4, 16000000, 1, 0, 0, 0, 0}, + {"8088/4.77", CPU_8088, 0, 4772727, 1, 0, 0, 0, 0, 0}, + {"8088/8", CPU_8088, 1, 8000000, 1, 0, 0, 0, 0, 0}, + {"8088/10", CPU_8088, 2, 10000000, 1, 0, 0, 0, 0, 0}, + {"8088/12", CPU_8088, 3, 12000000, 1, 0, 0, 0, 0, 0}, + {"8088/16", CPU_8088, 4, 16000000, 1, 0, 0, 0, 0, 0}, {"", -1, 0, 0, 0, 0} }; CPU cpus_pcjr[] = { /*8088 PCjr*/ - {"8088/4.77", CPU_8088, 0, 4772727, 1, 0, 0, 0, 0}, + {"8088/4.77", CPU_8088, 0, 4772727, 1, 0, 0, 0, 0, 0}, {"", -1, 0, 0, 0, 0} }; CPU cpus_8086[] = { /*8086 standard*/ - {"8086/7.16", CPU_8086, 1, 3579545*2, 1, 0, 0, 0, 0}, - {"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0}, - {"8086/9.54", CPU_8086, 1, (3579545*8)/3, 1, 0, 0, 0, 0}, - {"8086/10", CPU_8086, 2, 10000000, 1, 0, 0, 0, 0}, - {"8086/12", CPU_8086, 3, 12000000, 1, 0, 0, 0, 0}, - {"8086/16", CPU_8086, 4, 16000000, 1, 0, 0, 0, 0}, + {"8086/7.16", CPU_8086, 1, 3579545*2, 1, 0, 0, 0, 0, 0}, + {"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0}, + {"8086/9.54", CPU_8086, 1, (3579545*8)/3, 1, 0, 0, 0, 0, 0}, + {"8086/10", CPU_8086, 2, 10000000, 1, 0, 0, 0, 0, 0}, + {"8086/12", CPU_8086, 3, 12000000, 1, 0, 0, 0, 0, 0}, + {"8086/16", CPU_8086, 4, 16000000, 1, 0, 0, 0, 0, 0}, {"", -1, 0, 0, 0, 0} }; CPU cpus_pc1512[] = { /*8086 Amstrad*/ - {"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0}, + {"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0}, {"", -1, 0, 0, 0, 0} }; CPU cpus_286[] = { /*286*/ - {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0}, - {"286/8", CPU_286, 1, 8000000, 1, 0, 0, 0, 0}, - {"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0}, - {"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0}, - {"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0}, - {"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0}, - {"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0}, + {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0}, + {"286/8", CPU_286, 1, 8000000, 1, 0, 0, 0, 0, 0}, + {"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0}, + {"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0}, + {"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0}, + {"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0}, + {"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0}, {"", -1, 0, 0, 0, 0} }; CPU cpus_ibmat[] = { /*286*/ - {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0}, - {"286/8", CPU_286, 0, 8000000, 1, 0, 0, 0, 0}, + {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0}, + {"286/8", CPU_286, 0, 8000000, 1, 0, 0, 0, 0, 0}, {"", -1, 0, 0, 0, 0} }; CPU cpus_i386[] = { /*i386*/ - {"i386SX/16", CPU_386SX, 0, 16000000, 1, 0x2308, 0, 0, 0}, - {"i386SX/20", CPU_386SX, 1, 20000000, 1, 0x2308, 0, 0, 0}, - {"i386SX/25", CPU_386SX, 2, 25000000, 1, 0x2308, 0, 0, 0}, - {"i386SX/33", CPU_386SX, 3, 33333333, 1, 0x2308, 0, 0, 0}, - {"i386DX/16", CPU_386DX, 0, 16000000, 1, 0x0308, 0, 0, 0}, - {"i386DX/20", CPU_386DX, 1, 20000000, 1, 0x0308, 0, 0, 0}, - {"i386DX/25", CPU_386DX, 2, 25000000, 1, 0x0308, 0, 0, 0}, - {"i386DX/33", CPU_386DX, 3, 33333333, 1, 0x0308, 0, 0, 0}, + {"i386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0}, + {"i386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0}, + {"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0}, + {"i386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0}, + {"i386DX/16", CPU_386DX, 0, 16000000, 1, 0, 0x0308, 0, 0, 0}, + {"i386DX/20", CPU_386DX, 1, 20000000, 1, 0, 0x0308, 0, 0, 0}, + {"i386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0}, + {"i386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0}, {"", -1, 0, 0, 0} }; CPU cpus_acer[] = { /*i386*/ - {"i386SX/25", CPU_386SX, 2, 25000000, 1, 0x2308, 0, 0, 0}, + {"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0}, {"", -1, 0, 0, 0} }; CPU cpus_Am386[] = { /*Am386*/ - {"Am386SX/16", CPU_386SX, 0, 16000000, 1, 0x2308, 0, 0, 0}, - {"Am386SX/20", CPU_386SX, 1, 20000000, 1, 0x2308, 0, 0, 0}, - {"Am386SX/25", CPU_386SX, 2, 25000000, 1, 0x2308, 0, 0, 0}, - {"Am386SX/33", CPU_386SX, 3, 33333333, 1, 0x2308, 0, 0, 0}, - {"Am386SX/40", CPU_386SX, 4, 40000000, 1, 0x2308, 0, 0, 0}, - {"Am386DX/25", CPU_386DX, 2, 25000000, 1, 0x0308, 0, 0, 0}, - {"Am386DX/33", CPU_386DX, 3, 33333333, 1, 0x0308, 0, 0, 0}, - {"Am386DX/40", CPU_386DX, 4, 40000000, 1, 0x0308, 0, 0, 0}, + {"Am386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0}, + {"Am386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0}, + {"Am386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0}, + {"Am386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0}, + {"Am386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0}, + {"Am386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0}, + {"Am386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0}, + {"Am386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0}, {"", -1, 0, 0, 0} }; CPU cpus_486SDLC[] = { /*Cx486SLC/DLC*/ - {"Cx486SLC/20", CPU_486SLC, 1, 20000000, 1, 0, 0, 0x0000, 0}, - {"Cx486SLC/25", CPU_486SLC, 2, 25000000, 1, 0, 0, 0x0000, 0}, - {"Cx486SLC/33", CPU_486SLC, 3, 33333333, 1, 0, 0, 0x0000, 0}, - {"Cx486SRx2/32", CPU_486SLC, 3, 32000000, 2, 0, 0, 0x0006, 0}, - {"Cx486SRx2/40", CPU_486SLC, 4, 40000000, 2, 0, 0, 0x0006, 0}, - {"Cx486SRx2/50", CPU_486SLC, 5, 50000000, 2, 0, 0, 0x0006, 0}, - {"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0, 0x0001, 0}, - {"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0, 0x0001, 0}, - {"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0, 0x0001, 0}, - {"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0, 0x0007, 0}, - {"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0, 0x0007, 0}, - {"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0, 0x0007, 0}, - {"Cx486DRx2/66", CPU_486DLC, 6, 66666666, 2, 0, 0, 0x0007, 0}, + {"Cx486SLC/20", CPU_486SLC, 1, 20000000, 1, 0, 0, 0, 0x0000, 0}, + {"Cx486SLC/25", CPU_486SLC, 2, 25000000, 1, 0, 0, 0, 0x0000, 0}, + {"Cx486SLC/33", CPU_486SLC, 3, 33333333, 1, 0, 0, 0, 0x0000, 0}, + {"Cx486SRx2/32", CPU_486SLC, 3, 32000000, 2, 0, 0, 0, 0x0006, 0}, + {"Cx486SRx2/40", CPU_486SLC, 4, 40000000, 2, 0, 0, 0, 0x0006, 0}, + {"Cx486SRx2/50", CPU_486SLC, 5, 50000000, 2, 0, 0, 0, 0x0006, 0}, + {"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0, 0, 0x0001, 0}, + {"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0, 0, 0x0001, 0}, + {"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0, 0, 0x0001, 0}, + {"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0, 0, 0x0007, 0}, + {"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0, 0, 0x0007, 0}, + {"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0, 0, 0x0007, 0}, + {"Cx486DRx2/66", CPU_486DLC, 6, 66666666, 2, 0, 0, 0, 0x0007, 0}, {"", -1, 0, 0, 0} }; CPU cpus_i486[] = { /*i486*/ - {"i486SX/16", CPU_i486SX, 0, 16000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC}, - {"i486SX/20", CPU_i486SX, 1, 20000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC}, - {"i486SX/25", CPU_i486SX, 2, 25000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC}, - {"i486SX/33", CPU_i486SX, 3, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC}, - {"i486SX2/50", CPU_i486SX, 5, 50000000, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC}, - {"i486DX/25", CPU_i486DX, 2, 25000000, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC}, - {"i486DX/33", CPU_i486DX, 3, 33333333, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC}, - {"i486DX/50", CPU_i486DX, 5, 50000000, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC}, - {"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC}, - {"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC}, - {"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC}, - {"iDX4/75", CPU_i486DX, 7, 75000000, 3, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC}, /*CPUID available on DX4, >= 75 MHz*/ - {"iDX4/100", CPU_i486DX,10, 100000000, 3, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ - {"Pentium OverDrive/63", CPU_PENTIUM, 6, 62500000, 3, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Pentium OverDrive/83", CPU_PENTIUM, 8, 83333333, 3, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"i486SX/16", CPU_i486SX, 0, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC}, + {"i486SX/20", CPU_i486SX, 1, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC}, + {"i486SX/25", CPU_i486SX, 2, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC}, + {"i486SX/33", CPU_i486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC}, + {"i486SX2/50", CPU_i486SX, 5, 50000000, 2, 25000000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC}, + {"i486DX/25", CPU_i486DX, 2, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC}, + {"i486DX/33", CPU_i486DX, 3, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC}, + {"i486DX/50", CPU_i486DX, 5, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC}, + {"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC}, + {"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC}, + {"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC}, + {"iDX4/75", CPU_i486DX, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC}, /*CPUID available on DX4, >= 75 MHz*/ + {"iDX4/100", CPU_i486DX,10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ + {"Pentium OverDrive/63", CPU_PENTIUM, 6, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Pentium OverDrive/83", CPU_PENTIUM, 8, 83333333, 3, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, {"", -1, 0, 0, 0} }; CPU cpus_Am486[] = { /*Am486/5x86*/ - {"Am486SX/33", CPU_Am486SX, 3, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC}, - {"Am486SX/40", CPU_Am486SX, 4, 40000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC}, - {"Am486SX2/50", CPU_Am486SX, 5, 50000000, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ - {"Am486SX2/66", CPU_Am486SX, 6, 66666666, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/ - {"Am486DX/33", CPU_Am486DX, 3, 33333333, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC}, - {"Am486DX/40", CPU_Am486DX, 4, 40000000, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC}, - {"Am486DX2/50", CPU_Am486DX, 5, 50000000, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC}, - {"Am486DX2/66", CPU_Am486DX, 6, 66666666, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC}, - {"Am486DX2/80", CPU_Am486DX, 8, 80000000, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC}, - {"Am486DX4/75", CPU_Am486DX, 7, 75000000, 3, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC}, - {"Am486DX4/90", CPU_Am486DX, 9, 90000000, 3, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC}, - {"Am486DX4/100", CPU_Am486DX, 10, 100000000, 3, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC}, - {"Am486DX4/120", CPU_Am486DX, 11, 120000000, 3, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC}, - {"Am5x86/P75", CPU_Am486DX, 12, 133333333, 4, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC}, - {"Am5x86/P75+", CPU_Am486DX, 13, 150000000, 4, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC}, + {"Am486SX/33", CPU_Am486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC}, + {"Am486SX/40", CPU_Am486SX, 4, 40000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC}, + {"Am486SX2/50", CPU_Am486SX, 5, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ + {"Am486SX2/66", CPU_Am486SX, 6, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/ + {"Am486DX/33", CPU_Am486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC}, + {"Am486DX/40", CPU_Am486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC}, + {"Am486DX2/50", CPU_Am486DX, 5, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC}, + {"Am486DX2/66", CPU_Am486DX, 6, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC}, + {"Am486DX2/80", CPU_Am486DX, 8, 80000000, 2, 20000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC}, + {"Am486DX4/75", CPU_Am486DX, 7, 75000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC}, + {"Am486DX4/90", CPU_Am486DX, 9, 90000000, 3, 30000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC}, + {"Am486DX4/100", CPU_Am486DX, 10, 100000000, 3, 33333333, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC}, + {"Am486DX4/120", CPU_Am486DX, 11, 120000000, 3, 20000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC}, + {"Am5x86/P75", CPU_Am486DX, 12, 133333333, 4, 33333333, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC}, + {"Am5x86/P75+", CPU_Am486DX, 13, 160000000, 4, 20000000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC}, {"", -1, 0, 0, 0} }; CPU cpus_Cx486[] = { /*Cx486/5x86*/ - {"Cx486S/25", CPU_Cx486S, 2, 25000000, 1, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC}, - {"Cx486S/33", CPU_Cx486S, 3, 33333333, 1, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC}, - {"Cx486S/40", CPU_Cx486S, 4, 40000000, 1, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC}, - {"Cx486DX/33", CPU_Cx486DX, 3, 33333333, 1, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC}, - {"Cx486DX/40", CPU_Cx486DX, 4, 40000000, 1, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC}, - {"Cx486DX2/50", CPU_Cx486DX, 5, 50000000, 2, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC}, - {"Cx486DX2/66", CPU_Cx486DX, 6, 66666666, 2, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC}, - {"Cx486DX2/80", CPU_Cx486DX, 8, 80000000, 2, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC}, - {"Cx486DX4/75", CPU_Cx486DX, 7, 75000000, 3, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC}, - {"Cx486DX4/100", CPU_Cx486DX, 10, 100000000, 3, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC}, - {"Cx5x86/100", CPU_Cx5x86, 10, 100000000, 3, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC}, - {"Cx5x86/120", CPU_Cx5x86, 11, 120000000, 3, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC}, - {"Cx5x86/133", CPU_Cx5x86, 12, 133333333, 4, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC}, + {"Cx486S/25", CPU_Cx486S, 2, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC}, + {"Cx486S/33", CPU_Cx486S, 3, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC}, + {"Cx486S/40", CPU_Cx486S, 4, 40000000, 1, 20000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC}, + {"Cx486DX/33", CPU_Cx486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC}, + {"Cx486DX/40", CPU_Cx486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC}, + {"Cx486DX2/50", CPU_Cx486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC}, + {"Cx486DX2/66", CPU_Cx486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC}, + {"Cx486DX2/80", CPU_Cx486DX, 8, 80000000, 2, 20000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC}, + {"Cx486DX4/75", CPU_Cx486DX, 7, 75000000, 3, 25000000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC}, + {"Cx486DX4/100", CPU_Cx486DX, 10, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC}, + {"Cx5x86/100", CPU_Cx5x86, 10, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC}, + {"Cx5x86/120", CPU_Cx5x86, 11, 120000000, 3, 20000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC}, + {"Cx5x86/133", CPU_Cx5x86, 12, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC}, {"", -1, 0, 0, 0} }; CPU cpus_WinChip[] = { /*IDT WinChip*/ - {"WinChip 75", CPU_WINCHIP, 7, 75000000, 2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, - {"WinChip 90", CPU_WINCHIP, 9, 90000000, 2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, - {"WinChip 100", CPU_WINCHIP, 10, 100000000, 2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, - {"WinChip 120", CPU_WINCHIP, 11, 120000000, 2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, - {"WinChip 133", CPU_WINCHIP, 12, 133333333, 2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, - {"WinChip 150", CPU_WINCHIP, 13, 150000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, - {"WinChip 166", CPU_WINCHIP, 15, 166666666, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, - {"WinChip 180", CPU_WINCHIP, 16, 180000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, - {"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, - {"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, - {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, + {"WinChip 75", CPU_WINCHIP, 7, 75000000, 2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, + {"WinChip 90", CPU_WINCHIP, 9, 90000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, + {"WinChip 100", CPU_WINCHIP, 10, 100000000, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, + {"WinChip 120", CPU_WINCHIP, 11, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, + {"WinChip 133", CPU_WINCHIP, 12, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, + {"WinChip 150", CPU_WINCHIP, 13, 150000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, + {"WinChip 166", CPU_WINCHIP, 15, 166666666, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, + {"WinChip 180", CPU_WINCHIP, 16, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, + {"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, + {"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, + {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC}, {"", -1, 0, 0, 0} }; CPU cpus_Pentium5V[] = { /*Intel Pentium (5V, socket 4)*/ - {"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, {"", -1, 0, 0, 0} }; CPU cpus_Pentium[] = { /*Intel Pentium*/ - {"Pentium 75", CPU_PENTIUM, 7, 75000000, 2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Pentium 90", CPU_PENTIUM, 9, 90000000, 2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Pentium 100", CPU_PENTIUM, 10, 100000000, 2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Pentium 120", CPU_PENTIUM, 11, 120000000, 2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Pentium 133", CPU_PENTIUM, 12, 133333333, 2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Pentium 150", CPU_PENTIUM, 12, 150000000, 3, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Pentium 166", CPU_PENTIUM, 12, 166666666, 3, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Pentium 200", CPU_PENTIUM, 12, 200000000, 3, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Pentium MMX 166", CPU_PENTIUMMMX, 12, 166666666, 3, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Pentium MMX 200", CPU_PENTIUMMMX, 12, 200000000, 3, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Pentium MMX 233", CPU_PENTIUMMMX, 12, 233333333, 4, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 12, 120000000, 2, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 12, 133333333, 2, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 12, 150000000, 3, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 12, 166666666, 3, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 12, 200000000, 3, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 12, 233333333, 4, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 12, 266666666, 4, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 12, 300000000, 5, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Pentium 75", CPU_PENTIUM, 7, 75000000, 2, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Pentium 90", CPU_PENTIUM, 9, 90000000, 2, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Pentium 100", CPU_PENTIUM, 10, 100000000, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Pentium 120", CPU_PENTIUM, 11, 120000000, 2, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Pentium 133", CPU_PENTIUM, 12, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Pentium 150", CPU_PENTIUM, 12, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Pentium 166", CPU_PENTIUM, 12, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Pentium 200", CPU_PENTIUM, 12, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Pentium MMX 166", CPU_PENTIUMMMX, 12, 166666666, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Pentium MMX 200", CPU_PENTIUMMMX, 12, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Pentium MMX 233", CPU_PENTIUMMMX, 12, 233333333, 4, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 12, 120000000, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 12, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 12, 150000000, 3, 33333333, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 12, 166666666, 3, 33333333, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 12, 200000000, 3, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 12, 233333333, 4, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 12, 266666666, 4, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, + {"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 12, 300000000, 5, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, {"", -1, 0, 0, 0} }; @@ -359,6 +360,18 @@ void cpu_set() cpu_hasMSR = 0; cpu_hasCR4 = 0; + if (cpu_s->pci_speed) + { + pci_nonburst_time = 3*cpu_s->rspeed / cpu_s->pci_speed; + pci_burst_time = cpu_s->rspeed / cpu_s->pci_speed; + } + else + { + pci_nonburst_time = 3; + pci_burst_time = 1; + } + pclog("PCI burst=%i nonburst=%i\n", pci_burst_time, pci_nonburst_time); + if (cpu_iscyrix) io_sethandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL); else diff --git a/src/cpu.h b/src/cpu.h index f12b422..fb5d678 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -47,6 +47,7 @@ typedef struct int speed; int rspeed; int multi; + int pci_speed; uint32_t edx_reset; uint32_t cpuid_model; uint16_t cyrix_id; diff --git a/src/pci.c b/src/pci.c index da535ce..10c7622 100644 --- a/src/pci.c +++ b/src/pci.c @@ -9,6 +9,7 @@ uint8_t (*pci_card_read[32])(int func, int addr, void *priv); void *pci_priv[32]; static int pci_index, pci_func, pci_card, pci_bus, pci_enable, pci_key; static int pci_min_card, pci_max_card; +int pci_burst_time, pci_nonburst_time; void pci_cf8_write(uint16_t port, uint32_t val, void *p) { diff --git a/src/pci.h b/src/pci.h index 321d7ca..f248c36 100644 --- a/src/pci.h +++ b/src/pci.h @@ -9,3 +9,5 @@ void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int #define PCI_CONFIG_TYPE_1 1 #define PCI_CONFIG_TYPE_2 2 + +extern int pci_burst_time, pci_nonburst_time; diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index c4edc1f..6196188 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -263,7 +263,9 @@ typedef struct voodoo_t int flush; int scrfilter; - + + uint32_t last_write_addr; + rgb_t clutData[33]; int clutData_dirty; rgb_t clutData256[256]; @@ -3503,6 +3505,8 @@ static uint16_t voodoo_readw(uint32_t addr, void *p) addr &= 0xffffff; + cycles -= pci_nonburst_time; + if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/ { voodoo->flush = 1; @@ -3528,6 +3532,8 @@ static uint32_t voodoo_readl(uint32_t addr, void *p) voodoo->rd_count++; addr &= 0xffffff; + cycles -= pci_nonburst_time; + if (addr & 0x800000) /*Texture*/ { } @@ -3606,6 +3612,12 @@ static void voodoo_writew(uint32_t addr, uint16_t val, void *p) voodoo->wr_count++; addr &= 0xffffff; + if (addr == voodoo->last_write_addr+4) + cycles -= pci_burst_time; + else + cycles -= pci_nonburst_time; + voodoo->last_write_addr = addr; + if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/ queue_command(voodoo, addr | FIFO_WRITEW_FB, val); } @@ -3640,6 +3652,12 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) voodoo->wr_count++; addr &= 0xffffff; + if (addr == voodoo->last_write_addr+4) + cycles -= pci_burst_time; + else + cycles -= pci_nonburst_time; + voodoo->last_write_addr = addr; + if (addr & 0x800000) /*Texture*/ { voodoo->tex_count++;