1 #include "ibm.h"
2 #include "cpu.h"
3 #include "model.h"
4 #include "io.h"
5 #include "x86_ops.h"
6 #include "mem.h"
7 #include "pci.h"
8 #include "codegen.h"
9
10 static int cpu_turbo_speed, cpu_nonturbo_speed;
11 static int cpu_turbo = 1;
12
13 int isa_cycles;
14 int has_vlb;
15 static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6;
16
17 OpFn *x86_dynarec_opcodes;
18 OpFn *x86_dynarec_opcodes_0f;
19 OpFn *x86_dynarec_opcodes_d8_a16;
20 OpFn *x86_dynarec_opcodes_d8_a32;
21 OpFn *x86_dynarec_opcodes_d9_a16;
22 OpFn *x86_dynarec_opcodes_d9_a32;
23 OpFn *x86_dynarec_opcodes_da_a16;
24 OpFn *x86_dynarec_opcodes_da_a32;
25 OpFn *x86_dynarec_opcodes_db_a16;
26 OpFn *x86_dynarec_opcodes_db_a32;
27 OpFn *x86_dynarec_opcodes_dc_a16;
28 OpFn *x86_dynarec_opcodes_dc_a32;
29 OpFn *x86_dynarec_opcodes_dd_a16;
30 OpFn *x86_dynarec_opcodes_dd_a32;
31 OpFn *x86_dynarec_opcodes_de_a16;
32 OpFn *x86_dynarec_opcodes_de_a32;
33 OpFn *x86_dynarec_opcodes_df_a16;
34 OpFn *x86_dynarec_opcodes_df_a32;
35 OpFn *x86_dynarec_opcodes_REPE;
36 OpFn *x86_dynarec_opcodes_REPNE;
37
38 OpFn *x86_opcodes;
39 OpFn *x86_opcodes_0f;
40 OpFn *x86_opcodes_d8_a16;
41 OpFn *x86_opcodes_d8_a32;
42 OpFn *x86_opcodes_d9_a16;
43 OpFn *x86_opcodes_d9_a32;
44 OpFn *x86_opcodes_da_a16;
45 OpFn *x86_opcodes_da_a32;
46 OpFn *x86_opcodes_db_a16;
47 OpFn *x86_opcodes_db_a32;
48 OpFn *x86_opcodes_dc_a16;
49 OpFn *x86_opcodes_dc_a32;
50 OpFn *x86_opcodes_dd_a16;
51 OpFn *x86_opcodes_dd_a32;
52 OpFn *x86_opcodes_de_a16;
53 OpFn *x86_opcodes_de_a32;
54 OpFn *x86_opcodes_df_a16;
55 OpFn *x86_opcodes_df_a32;
56 OpFn *x86_opcodes_REPE;
57 OpFn *x86_opcodes_REPNE;
58
59 enum
60 {
61 CPUID_FPU = (1 << 0),
62 CPUID_VME = (1 << 1),
63 CPUID_PSE = (1 << 3),
64 CPUID_TSC = (1 << 4),
65 CPUID_MSR = (1 << 5),
66 CPUID_CMPXCHG8B = (1 << 8),
67 CPUID_CMOV = (1 << 15),
68 CPUID_MMX = (1 << 23)
69 };
70
71 int cpu = 3, cpu_manufacturer = 0;
72 CPU *cpu_s;
73 int cpu_multi;
74 int cpu_iscyrix;
75 int cpu_16bitbus;
76 int cpu_busspeed;
77 int cpu_hasrdtsc;
78 int cpu_hasMMX, cpu_hasMSR;
79 int cpu_hasCR4;
80 int cpu_hasCX8;
81 int cpu_hasVME;
82 int cpu_use_dynarec;
83 int cpu_cyrix_alignment;
84
85 uint64_t cpu_CR4_mask;
86
87 int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l;
88 int cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles;
89 int cpu_waitstates;
90 int cpu_cache_int_enabled, cpu_cache_ext_enabled;
91
92 int is386;
93
94 uint64_t tsc = 0;
95
96 int timing_rr;
97 int timing_mr, timing_mrl;
98 int timing_rm, timing_rml;
99 int timing_mm, timing_mml;
100 int timing_bt, timing_bnt;
101 int timing_int, timing_int_rm, timing_int_v86, timing_int_pm, timing_int_pm_outer;
102 int timing_iret_rm, timing_iret_v86, timing_iret_pm, timing_iret_pm_outer;
103 int timing_call_rm, timing_call_pm, timing_call_pm_gate, timing_call_pm_gate_inner;
104 int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer;
105 int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate;
106 int timing_misaligned;
107
108 static struct
109 {
110 uint32_t tr1, tr12;
111 uint32_t cesr;
112 uint32_t fcr;
113 uint64_t fcr2, fcr3;
114 } msr;
115
116 /*Available cpuspeeds :
117 0 = 16 MHz
118 1 = 20 MHz
119 2 = 25 MHz
120 3 = 33 MHz
121 4 = 40 MHz
122 5 = 50 MHz
123 6 = 66 MHz
124 7 = 75 MHz
125 8 = 80 MHz
126 9 = 90 MHz
127 10 = 100 MHz
128 11 = 120 MHz
129 12 = 133 MHz
130 13 = 150 MHz
131 14 = 160 MHz
132 15 = 166 MHz
133 16 = 180 MHz
134 17 = 200 MHz
135 */
136
137 CPU cpus_8088[] =
138 {
139 /*8088 standard*/
140 {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
141 {"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
142 {"8088/8", CPU_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
143 {"8088/10", CPU_8088, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
144 {"8088/12", CPU_8088, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
145 {"8088/16", CPU_8088, 4, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
146 {"", -1, 0, 0, 0, 0}
147 };
148
149 CPU cpus_pcjr[] =
150 {
151 /*8088 PCjr*/
152 {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
153 {"", -1, 0, 0, 0, 0}
154 };
155
156 CPU cpus_europc[] =
157 {
158 /*8088 EuroPC*/
159 {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
160 {"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
161 {"8088/9.54", CPU_8088, 1, 4772728*2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
162 {"", -1, 0, 0, 0, 0}
163 };
164
165 CPU cpus_8086[] =
166 {
167 /*8086 standard*/
168 {"8086/7.16", CPU_8086, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
169 {"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
170 {"8086/9.54", CPU_8086, 1, 4772728*2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
171 {"8086/10", CPU_8086, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
172 {"8086/12", CPU_8086, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
173 {"8086/16", CPU_8086, 4, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 2},
174 {"", -1, 0, 0, 0, 0}
175 };
176
177 CPU cpus_pc1512[] =
178 {
179 /*8086 Amstrad*/
180 {"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
181 {"", -1, 0, 0, 0, 0}
182 };
183
184 CPU cpus_286[] =
185 {
186 /*286*/
187 {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
188 {"286/8", CPU_286, 1, 8000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
189 {"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
190 {"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
191 {"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
192 {"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
193 {"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
194 {"", -1, 0, 0, 0, 0}
195 };
196
197 CPU cpus_ibmat[] =
198 {
199 /*286*/
200 {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1},
201 {"286/8", CPU_286, 0, 8000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1},
202 {"", -1, 0, 0, 0, 0}
203 };
204
205 CPU cpus_ibmxt286[] =
206 {
207 /*286*/
208 {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
209 {"", -1, 0, 0, 0, 0}
210 };
211
212 CPU cpus_ps1_m2011[] =
213 {
214 /*286*/
215 {"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
216 {"", -1, 0, 0, 0, 0}
217 };
218
219 CPU cpus_ps2_m30_286[] =
220 {
221 /*286*/
222 {"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
223 {"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
224 {"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
225 {"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
226 {"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
227 {"", -1, 0, 0, 0, 0}
228 };
229
230 CPU cpus_i386SX[] =
231 {
232 /*i386SX*/
233 {"i386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2},
234 {"i386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
235 {"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
236 {"i386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4},
237 {"", -1, 0, 0, 0}
238 };
239
240 CPU cpus_i386DX[] =
241 {
242 /*i386DX*/
243 {"i386DX/16", CPU_386DX, 0, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3, 2},
244 {"i386DX/20", CPU_386DX, 1, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
245 {"i386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
246 {"i386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4},
247 {"", -1, 0, 0, 0}
248 };
249
250 CPU cpus_acer[] =
251 {
252 /*i386SX*/
253 {"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,4,4, 3},
254 {"", -1, 0, 0, 0}
255 };
256
257 CPU cpus_Am386SX[] =
258 {
259 /*Am386*/
260 {"Am386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2},
261 {"Am386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
262 {"Am386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
263 {"Am386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4},
264 {"Am386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5},
265 {"", -1, 0, 0, 0}
266 };
267
268 CPU cpus_Am386DX[] =
269 {
270 /*Am386*/
271 {"Am386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
272 {"Am386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4},
273 {"Am386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5},
274 {"", -1, 0, 0, 0}
275 };
276
277 CPU cpus_486SLC[] =
278 {
279 /*Cx486SLC*/
280 {"Cx486SLC/20", CPU_486SLC, 1, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3},
281 {"Cx486SLC/25", CPU_486SLC, 2, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3},
282 {"Cx486SLC/33", CPU_486SLC, 3, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3, 4},
283 {"Cx486SRx2/32", CPU_486SLC, 3, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6, 2*2},
284 {"Cx486SRx2/40", CPU_486SLC, 4, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 2*3},
285 {"Cx486SRx2/50", CPU_486SLC, 5, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 2*3},
286 {"", -1, 0, 0, 0}
287 };
288
289 CPU cpus_486DLC[] =
290 {
291 /*Cx486DLC*/
292 {"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4,4,3,3, 3},
293 {"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6,6,3,3, 4},
294 {"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7,7,3,3, 5},
295 {"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6,6,6,6, 2*2},
296 {"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6, 2*3},
297 {"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6, 2*3},
298 {"Cx486DRx2/66", CPU_486DLC, 6, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6, 2*4},
299 {"", -1, 0, 0, 0}
300 };
301
302 CPU cpus_i486[] =
303 {
304 /*i486*/
305 {"i486SX/16", CPU_i486SX, 0, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3,3,3,3, 2},
306 {"i486SX/20", CPU_i486SX, 1, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3},
307 {"i486SX/25", CPU_i486SX, 2, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3},
308 {"i486SX/33", CPU_i486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
309 {"i486SX2/50", CPU_i486SX, 5, 50000000, 2, 25000000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3},
310 {"i486DX/25", CPU_i486DX, 2, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3},
311 {"i486DX/33", CPU_i486DX, 3, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
312 {"i486DX/50", CPU_i486DX, 5, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4, 6},
313 {"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3},
314 {"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3},
315 {"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4},
316 {"iDX4/75", CPU_iDX4, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 3*3}, /*CPUID available on DX4, >= 75 MHz*/
317 {"iDX4/100", CPU_iDX4, 10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*4}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/
318 {"Pentium OverDrive/63", CPU_PENTIUM, 6, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, (5*3)/2},
319 {"Pentium OverDrive/83", CPU_PENTIUM, 8, 83333333, 3, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, (5*4)/2},
320 {"", -1, 0, 0, 0}
321 };
322
323 CPU cpus_Am486[] =
324 {
325 /*Am486/5x86*/
326 {"Am486SX/33", CPU_Am486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
327 {"Am486SX/40", CPU_Am486SX, 4, 40000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5},
328 {"Am486SX2/50", CPU_Am486SX, 5, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/
329 {"Am486SX2/66", CPU_Am486SX, 6, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/
330 {"Am486DX/33", CPU_Am486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
331 {"Am486DX/40", CPU_Am486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5},
332 {"Am486DX2/50", CPU_Am486DX, 5, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3},
333 {"Am486DX2/66", CPU_Am486DX, 6, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4},
334 {"Am486DX2/80", CPU_Am486DX, 8, 80000000, 2, 20000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14,6,6, 2*5},
335 {"Am486DX4/75", CPU_Am486DX, 7, 75000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 3*3},
336 {"Am486DX4/90", CPU_Am486DX, 9, 90000000, 3, 30000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4},
337 {"Am486DX4/100", CPU_Am486DX, 10, 100000000, 3, 33333333, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4},
338 {"Am486DX4/120", CPU_Am486DX, 11, 120000000, 3, 20000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21,9,9, 3*5},
339 {"Am5x86/P75", CPU_Am486DX, 12, 133333333, 4, 33333333, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*4},
340 {"Am5x86/P75+", CPU_Am486DX, 13, 160000000, 4, 20000000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 4*5},
341 {"", -1, 0, 0, 0}
342 };
343
344 CPU cpus_Cx486[] =
345 {
346 /*Cx486/5x86*/
347 {"Cx486S/25", CPU_Cx486S, 2, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3},
348 {"Cx486S/33", CPU_Cx486S, 3, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
349 {"Cx486S/40", CPU_Cx486S, 4, 40000000, 1, 20000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5},
350 {"Cx486DX/33", CPU_Cx486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
351 {"Cx486DX/40", CPU_Cx486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5},
352 {"Cx486DX2/50", CPU_Cx486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3},
353 {"Cx486DX2/66", CPU_Cx486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4},
354 {"Cx486DX2/80", CPU_Cx486DX, 8, 80000000, 2, 20000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14,16,16, 2*5},
355 {"Cx486DX4/75", CPU_Cx486DX, 7, 75000000, 3, 25000000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 3*3},
356 {"Cx486DX4/100", CPU_Cx486DX, 10, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4},
357 {"Cx5x86/100", CPU_Cx5x86, 10, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4},
358 {"Cx5x86/120", CPU_Cx5x86, 11, 120000000, 3, 20000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21,9,9, 3*5},
359 {"Cx5x86/133", CPU_Cx5x86, 12, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*4},
360 {"", -1, 0, 0, 0}
361 };
362
363 CPU cpus_6x86[] =
364 {
365 /*Cyrix 6x86*/
366 {"6x86-P90", CPU_Cx6x86, 17, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8,8,6,6, 2*5},
367 {"6x86-PR120+", CPU_Cx6x86, 17, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6},
368 {"6x86-PR133+", CPU_Cx6x86, 17, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*7},
369 {"6x86-PR150+", CPU_Cx6x86, 17, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7},
370 {"6x86-PR166+", CPU_Cx6x86, 17, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8},
371 {"6x86-PR200+", CPU_Cx6x86, 17, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*9},
372
373 /*Cyrix 6x86L*/
374 {"6x86L-PR133+", CPU_Cx6x86L, 19, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*7},
375 {"6x86L-PR150+", CPU_Cx6x86L, 19, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7},
376 {"6x86L-PR166+", CPU_Cx6x86L, 19, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8},
377 {"6x86L-PR200+", CPU_Cx6x86L, 19, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*9},
378
379 /*Cyrix 6x86MX*/
380 {"6x86MX-PR166", CPU_Cx6x86MX, 18, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8},
381 {"6x86MX-PR200", CPU_Cx6x86MX, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2},
382 {"6x86MX-PR233", CPU_Cx6x86MX, 18, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*9)/2},
383 {"6x86MX-PR266", CPU_Cx6x86MX, 18, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7, (5*10)/2},
384 {"6x86MX-PR300", CPU_Cx6x86MX, 18, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,7,7, (7*8)/2},
385 {"6x86MX-PR333", CPU_Cx6x86MX, 18, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20,9,9, 3*10},
386 {"6x86MX-PR366", CPU_Cx6x86MX, 18, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 3*10},
387 {"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 31666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*11},
388 {"", -1, 0, 0, 0}
389 };
390
391
392
393 CPU cpus_WinChip[] =
394 {
395 /*IDT WinChip*/
396 {"WinChip 75", CPU_WINCHIP, 7, 75000000, 2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4, (3*6)/2},
397 {"WinChip 90", CPU_WINCHIP, 9, 90000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4, (3*7)/2},
398 {"WinChip 100", CPU_WINCHIP, 10, 100000000, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4, (3*8)/2},
399 {"WinChip 120", CPU_WINCHIP, 11, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*7},
400 {"WinChip 133", CPU_WINCHIP, 12, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*8},
401 {"WinChip 150", CPU_WINCHIP, 13, 150000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7, (5*7)/2},
402 {"WinChip 166", CPU_WINCHIP, 15, 166666666, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7, (5*8)/2},
403 {"WinChip 180", CPU_WINCHIP, 16, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*7},
404 {"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8},
405 {"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9},
406 {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7},
407 {"", -1, 0, 0, 0}
408 };
409
410 CPU cpus_Pentium5V[] =
411 {
412 /*Intel Pentium (5V, socket 4)*/
413 {"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 7},
414 {"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 8},
415 {"Pentium OverDrive 120",CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7},
416 {"Pentium OverDrive 133",CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8},
417 {"", -1, 0, 0, 0}
418 };
419
420 CPU cpus_PentiumS5[] =
421 {
422 /*Intel Pentium (Socket 5)*/
423 {"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, (3*6)/2},
424 {"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*7)/2},
425 {"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6},
426 {"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*8)/2},
427 {"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7},
428 {"Pentium 133", CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8},
429 {"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2},
430 {"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2},
431 {"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2},
432 {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2},
433 {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2},
434 {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2},
435 {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*7},
436 {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8},
437 {"", -1, 0, 0, 0}
438 };
439
440 CPU cpus_Pentium[] =
441 {
442 /*Intel Pentium*/
443 {"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, (3*6)/2},
444 {"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*7)/2},
445 {"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6},
446 {"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*8)/2},
447 {"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7},
448 {"Pentium 133", CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8},
449 {"Pentium 150", CPU_PENTIUM, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2},
450 {"Pentium 166", CPU_PENTIUM, 19, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2},
451 {"Pentium 200", CPU_PENTIUM, 21, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8},
452 {"Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2},
453 {"Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8},
454 {"Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, (7*8)/2},
455 {"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 14, 120000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7},
456 {"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 16, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8},
457 {"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 17, 150000000, 3, 30000000, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2},
458 {"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2},
459 {"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8},
460 {"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, (7*8)/2},
461 {"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 26, 266666666, 4, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 4*8},
462 {"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 28, 300000000, 5, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, (9*8)/2},
463 {"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2},
464 {"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2},
465 {"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2},
466 {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2},
467 {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2},
468 {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2},
469 {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*7},
470 {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8},
471 {"", -1, 0, 0, 0}
472 };
473
cpu_set_edx()474 void cpu_set_edx()
475 {
476 EDX = models[model].cpu[cpu_manufacturer].cpus[cpu].edx_reset;
477 }
478
cpu_set()479 void cpu_set()
480 {
481 CPU *cpu_s;
482
483 if (!models[model].cpu[cpu_manufacturer].cpus)
484 {
485 /*CPU is invalid, set to default*/
486 cpu_manufacturer = 0;
487 cpu = 0;
488 }
489
490 cpu_s = &models[model].cpu[cpu_manufacturer].cpus[cpu];
491
492 CPUID = cpu_s->cpuid_model;
493 cpuspeed = cpu_s->speed;
494 is8086 = (cpu_s->cpu_type > CPU_8088);
495 is386 = (cpu_s->cpu_type >= CPU_386SX);
496 is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC);
497 hasfpu = (cpu_s->cpu_type >= CPU_i486DX);
498 cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86 || cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86MX || cpu_s->cpu_type == CPU_Cx6x86L || cpu_s->cpu_type == CPU_CxGX1);
499 cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC);
500 if (cpu_s->multi)
501 cpu_busspeed = cpu_s->rspeed / cpu_s->multi;
502 cpu_multi = cpu_s->multi;
503 cpu_hasrdtsc = 0;
504 cpu_hasMMX = 0;
505 cpu_hasMSR = 0;
506 cpu_hasCR4 = 0;
507 cpu_hasCX8 = 0;
508 ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0;
509 has_vlb = (cpu_s->cpu_type >= CPU_i486SX) && (cpu_s->cpu_type <= CPU_Cx5x86);
510
511 cpu_turbo_speed = cpu_s->rspeed;
512 if (cpu_s->cpu_type < CPU_286)
513 cpu_nonturbo_speed = 4772728;
514 else if (cpu_s->rspeed < 8000000)
515 cpu_nonturbo_speed = cpu_s->rspeed;
516 else
517 cpu_nonturbo_speed = 8000000;
518
519 cpu_update_waitstates();
520
521 isa_cycles = cpu_s->atclk_div;
522
523 if (cpu_s->rspeed <= 8000000)
524 cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles;
525 else
526 cpu_rom_prefetch_cycles = cpu_s->rspeed / 1000000;
527
528 if (cpu_s->pci_speed)
529 {
530 pci_nonburst_time = 4*cpu_s->rspeed / cpu_s->pci_speed;
531 pci_burst_time = cpu_s->rspeed / cpu_s->pci_speed;
532 }
533 else
534 {
535 pci_nonburst_time = 4;
536 pci_burst_time = 1;
537 }
538 pclog("PCI burst=%i nonburst=%i\n", pci_burst_time, pci_nonburst_time);
539
540 if (cpu_iscyrix)
541 io_sethandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL);
542 else
543 io_removehandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL);
544
545 pclog("hasfpu - %i\n",hasfpu);
546 pclog("is486 - %i %i\n",is486,cpu_s->cpu_type);
547
548 x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f);
549 x86_opcodes_REPE = ops_REPE;
550 x86_opcodes_REPNE = ops_REPNE;
551 x86_dynarec_opcodes_REPE = dynarec_ops_REPE;
552 x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE;
553
554 if (hasfpu)
555 {
556 x86_dynarec_opcodes_d8_a16 = dynarec_ops_fpu_d8_a16;
557 x86_dynarec_opcodes_d8_a32 = dynarec_ops_fpu_d8_a32;
558 x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_d9_a16;
559 x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_d9_a32;
560 x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_da_a16;
561 x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_da_a32;
562 x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_db_a16;
563 x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_db_a32;
564 x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_dc_a16;
565 x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_dc_a32;
566 x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_dd_a16;
567 x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_dd_a32;
568 x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_de_a16;
569 x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_de_a32;
570 x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_df_a16;
571 x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_df_a32;
572 }
573 else
574 {
575 x86_dynarec_opcodes_d8_a16 = dynarec_ops_nofpu_a16;
576 x86_dynarec_opcodes_d8_a32 = dynarec_ops_nofpu_a32;
577 x86_dynarec_opcodes_d9_a16 = dynarec_ops_nofpu_a16;
578 x86_dynarec_opcodes_d9_a32 = dynarec_ops_nofpu_a32;
579 x86_dynarec_opcodes_da_a16 = dynarec_ops_nofpu_a16;
580 x86_dynarec_opcodes_da_a32 = dynarec_ops_nofpu_a32;
581 x86_dynarec_opcodes_db_a16 = dynarec_ops_nofpu_a16;
582 x86_dynarec_opcodes_db_a32 = dynarec_ops_nofpu_a32;
583 x86_dynarec_opcodes_dc_a16 = dynarec_ops_nofpu_a16;
584 x86_dynarec_opcodes_dc_a32 = dynarec_ops_nofpu_a32;
585 x86_dynarec_opcodes_dd_a16 = dynarec_ops_nofpu_a16;
586 x86_dynarec_opcodes_dd_a32 = dynarec_ops_nofpu_a32;
587 x86_dynarec_opcodes_de_a16 = dynarec_ops_nofpu_a16;
588 x86_dynarec_opcodes_de_a32 = dynarec_ops_nofpu_a32;
589 x86_dynarec_opcodes_df_a16 = dynarec_ops_nofpu_a16;
590 x86_dynarec_opcodes_df_a32 = dynarec_ops_nofpu_a32;
591 }
592 codegen_timing_set(&codegen_timing_486);
593
594 if (hasfpu)
595 {
596 x86_opcodes_d8_a16 = ops_fpu_d8_a16;
597 x86_opcodes_d8_a32 = ops_fpu_d8_a32;
598 x86_opcodes_d9_a16 = ops_fpu_d9_a16;
599 x86_opcodes_d9_a32 = ops_fpu_d9_a32;
600 x86_opcodes_da_a16 = ops_fpu_da_a16;
601 x86_opcodes_da_a32 = ops_fpu_da_a32;
602 x86_opcodes_db_a16 = ops_fpu_db_a16;
603 x86_opcodes_db_a32 = ops_fpu_db_a32;
604 x86_opcodes_dc_a16 = ops_fpu_dc_a16;
605 x86_opcodes_dc_a32 = ops_fpu_dc_a32;
606 x86_opcodes_dd_a16 = ops_fpu_dd_a16;
607 x86_opcodes_dd_a32 = ops_fpu_dd_a32;
608 x86_opcodes_de_a16 = ops_fpu_de_a16;
609 x86_opcodes_de_a32 = ops_fpu_de_a32;
610 x86_opcodes_df_a16 = ops_fpu_df_a16;
611 x86_opcodes_df_a32 = ops_fpu_df_a32;
612 }
613 else
614 {
615 x86_opcodes_d8_a16 = ops_nofpu_a16;
616 x86_opcodes_d8_a32 = ops_nofpu_a32;
617 x86_opcodes_d9_a16 = ops_nofpu_a16;
618 x86_opcodes_d9_a32 = ops_nofpu_a32;
619 x86_opcodes_da_a16 = ops_nofpu_a16;
620 x86_opcodes_da_a32 = ops_nofpu_a32;
621 x86_opcodes_db_a16 = ops_nofpu_a16;
622 x86_opcodes_db_a32 = ops_nofpu_a32;
623 x86_opcodes_dc_a16 = ops_nofpu_a16;
624 x86_opcodes_dc_a32 = ops_nofpu_a32;
625 x86_opcodes_dd_a16 = ops_nofpu_a16;
626 x86_opcodes_dd_a32 = ops_nofpu_a32;
627 x86_opcodes_de_a16 = ops_nofpu_a16;
628 x86_opcodes_de_a32 = ops_nofpu_a32;
629 x86_opcodes_df_a16 = ops_nofpu_a16;
630 x86_opcodes_df_a32 = ops_nofpu_a32;
631 }
632
633 memset(&msr, 0, sizeof(msr));
634
635 timing_misaligned = 0;
636 cpu_cyrix_alignment = 0;
637
638 switch (cpu_s->cpu_type)
639 {
640 case CPU_8088:
641 case CPU_8086:
642 break;
643
644 case CPU_286:
645 x86_setopcodes(ops_286, ops_286_0f, dynarec_ops_286, dynarec_ops_286_0f);
646 timing_rr = 2; /*register dest - register src*/
647 timing_rm = 7; /*register dest - memory src*/
648 timing_mr = 7; /*memory dest - register src*/
649 timing_mm = 7; /*memory dest - memory src*/
650 timing_rml = 9; /*register dest - memory src long*/
651 timing_mrl = 11; /*memory dest - register src long*/
652 timing_mml = 11; /*memory dest - memory src*/
653 timing_bt = 7-3; /*branch taken*/
654 timing_bnt = 3; /*branch not taken*/
655 timing_int = 0;
656 timing_int_rm = 23;
657 timing_int_v86 = 0;
658 timing_int_pm = 40;
659 timing_int_pm_outer = 78;
660 timing_iret_rm = 17;
661 timing_iret_v86 = 0;
662 timing_iret_pm = 31;
663 timing_iret_pm_outer = 55;
664 timing_call_rm = 13;
665 timing_call_pm = 26;
666 timing_call_pm_gate = 52;
667 timing_call_pm_gate_inner = 82;
668 timing_retf_rm = 15;
669 timing_retf_pm = 25;
670 timing_retf_pm_outer = 55;
671 timing_jmp_rm = 11;
672 timing_jmp_pm = 23;
673 timing_jmp_pm_gate = 38;
674 break;
675
676 case CPU_386SX:
677 timing_rr = 2; /*register dest - register src*/
678 timing_rm = 6; /*register dest - memory src*/
679 timing_mr = 7; /*memory dest - register src*/
680 timing_mm = 6; /*memory dest - memory src*/
681 timing_rml = 8; /*register dest - memory src long*/
682 timing_mrl = 11; /*memory dest - register src long*/
683 timing_mml = 10; /*memory dest - memory src*/
684 timing_bt = 7-3; /*branch taken*/
685 timing_bnt = 3; /*branch not taken*/
686 timing_int = 0;
687 timing_int_rm = 37;
688 timing_int_v86 = 59;
689 timing_int_pm = 99;
690 timing_int_pm_outer = 119;
691 timing_iret_rm = 22;
692 timing_iret_v86 = 60;
693 timing_iret_pm = 38;
694 timing_iret_pm_outer = 82;
695 timing_call_rm = 17;
696 timing_call_pm = 34;
697 timing_call_pm_gate = 52;
698 timing_call_pm_gate_inner = 86;
699 timing_retf_rm = 18;
700 timing_retf_pm = 32;
701 timing_retf_pm_outer = 68;
702 timing_jmp_rm = 12;
703 timing_jmp_pm = 27;
704 timing_jmp_pm_gate = 45;
705 break;
706
707 case CPU_386DX:
708 timing_rr = 2; /*register dest - register src*/
709 timing_rm = 6; /*register dest - memory src*/
710 timing_mr = 7; /*memory dest - register src*/
711 timing_mm = 6; /*memory dest - memory src*/
712 timing_rml = 6; /*register dest - memory src long*/
713 timing_mrl = 7; /*memory dest - register src long*/
714 timing_mml = 6; /*memory dest - memory src*/
715 timing_bt = 7-3; /*branch taken*/
716 timing_bnt = 3; /*branch not taken*/
717 timing_int = 0;
718 timing_int_rm = 37;
719 timing_int_v86 = 59;
720 timing_int_pm = 99;
721 timing_int_pm_outer = 119;
722 timing_iret_rm = 22;
723 timing_iret_v86 = 60;
724 timing_iret_pm = 38;
725 timing_iret_pm_outer = 82;
726 timing_call_rm = 17;
727 timing_call_pm = 34;
728 timing_call_pm_gate = 52;
729 timing_call_pm_gate_inner = 86;
730 timing_retf_rm = 18;
731 timing_retf_pm = 32;
732 timing_retf_pm_outer = 68;
733 timing_jmp_rm = 12;
734 timing_jmp_pm = 27;
735 timing_jmp_pm_gate = 45;
736 break;
737
738 case CPU_486SLC:
739 timing_rr = 1; /*register dest - register src*/
740 timing_rm = 3; /*register dest - memory src*/
741 timing_mr = 5; /*memory dest - register src*/
742 timing_mm = 3;
743 timing_rml = 5; /*register dest - memory src long*/
744 timing_mrl = 7; /*memory dest - register src long*/
745 timing_mml = 7;
746 timing_bt = 6-1; /*branch taken*/
747 timing_bnt = 1; /*branch not taken*/
748 /*unknown*/
749 timing_int = 4;
750 timing_int_rm = 14;
751 timing_int_v86 = 82;
752 timing_int_pm = 49;
753 timing_int_pm_outer = 77;
754 timing_iret_rm = 14;
755 timing_iret_v86 = 66;
756 timing_iret_pm = 31;
757 timing_iret_pm_outer = 66;
758 timing_call_rm = 12;
759 timing_call_pm = 30;
760 timing_call_pm_gate = 41;
761 timing_call_pm_gate_inner = 83;
762 timing_retf_rm = 13;
763 timing_retf_pm = 26;
764 timing_retf_pm_outer = 61;
765 timing_jmp_rm = 9;
766 timing_jmp_pm = 26;
767 timing_jmp_pm_gate = 37;
768 timing_misaligned = 3;
769 break;
770
771 case CPU_486DLC:
772 timing_rr = 1; /*register dest - register src*/
773 timing_rm = 3; /*register dest - memory src*/
774 timing_mr = 3; /*memory dest - register src*/
775 timing_mm = 3;
776 timing_rml = 3; /*register dest - memory src long*/
777 timing_mrl = 3; /*memory dest - register src long*/
778 timing_mml = 3;
779 timing_bt = 6-1; /*branch taken*/
780 timing_bnt = 1; /*branch not taken*/
781 /*unknown*/
782 timing_int = 4;
783 timing_int_rm = 14;
784 timing_int_v86 = 82;
785 timing_int_pm = 49;
786 timing_int_pm_outer = 77;
787 timing_iret_rm = 14;
788 timing_iret_v86 = 66;
789 timing_iret_pm = 31;
790 timing_iret_pm_outer = 66;
791 timing_call_rm = 12;
792 timing_call_pm = 30;
793 timing_call_pm_gate = 41;
794 timing_call_pm_gate_inner = 83;
795 timing_retf_rm = 13;
796 timing_retf_pm = 26;
797 timing_retf_pm_outer = 61;
798 timing_jmp_rm = 9;
799 timing_jmp_pm = 26;
800 timing_jmp_pm_gate = 37;
801 timing_misaligned = 3;
802 break;
803
804 case CPU_iDX4:
805 cpu_hasCR4 = 1;
806 cpu_hasVME = 1;
807 cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_VME;
808 case CPU_i486SX:
809 case CPU_i486DX:
810 timing_rr = 1; /*register dest - register src*/
811 timing_rm = 2; /*register dest - memory src*/
812 timing_mr = 3; /*memory dest - register src*/
813 timing_mm = 3;
814 timing_rml = 2; /*register dest - memory src long*/
815 timing_mrl = 3; /*memory dest - register src long*/
816 timing_mml = 3;
817 timing_bt = 3-1; /*branch taken*/
818 timing_bnt = 1; /*branch not taken*/
819 timing_int = 4;
820 timing_int_rm = 26;
821 timing_int_v86 = 82;
822 timing_int_pm = 44;
823 timing_int_pm_outer = 71;
824 timing_iret_rm = 15;
825 timing_iret_v86 = 36; /*unknown*/
826 timing_iret_pm = 20;
827 timing_iret_pm_outer = 36;
828 timing_call_rm = 18;
829 timing_call_pm = 20;
830 timing_call_pm_gate = 35;
831 timing_call_pm_gate_inner = 69;
832 timing_retf_rm = 13;
833 timing_retf_pm = 17;
834 timing_retf_pm_outer = 35;
835 timing_jmp_rm = 17;
836 timing_jmp_pm = 19;
837 timing_jmp_pm_gate = 32;
838 timing_misaligned = 3;
839 break;
840
841 case CPU_Am486SX:
842 case CPU_Am486DX:
843 /*AMD timing identical to Intel*/
844 timing_rr = 1; /*register dest - register src*/
845 timing_rm = 2; /*register dest - memory src*/
846 timing_mr = 3; /*memory dest - register src*/
847 timing_mm = 3;
848 timing_rml = 2; /*register dest - memory src long*/
849 timing_mrl = 3; /*memory dest - register src long*/
850 timing_mml = 3;
851 timing_bt = 3-1; /*branch taken*/
852 timing_bnt = 1; /*branch not taken*/
853 timing_int = 4;
854 timing_int_rm = 26;
855 timing_int_v86 = 82;
856 timing_int_pm = 44;
857 timing_int_pm_outer = 71;
858 timing_iret_rm = 15;
859 timing_iret_v86 = 36; /*unknown*/
860 timing_iret_pm = 20;
861 timing_iret_pm_outer = 36;
862 timing_call_rm = 18;
863 timing_call_pm = 20;
864 timing_call_pm_gate = 35;
865 timing_call_pm_gate_inner = 69;
866 timing_retf_rm = 13;
867 timing_retf_pm = 17;
868 timing_retf_pm_outer = 35;
869 timing_jmp_rm = 17;
870 timing_jmp_pm = 19;
871 timing_jmp_pm_gate = 32;
872 timing_misaligned = 3;
873 break;
874
875 case CPU_Cx486S:
876 case CPU_Cx486DX:
877 timing_rr = 1; /*register dest - register src*/
878 timing_rm = 3; /*register dest - memory src*/
879 timing_mr = 3; /*memory dest - register src*/
880 timing_mm = 3;
881 timing_rml = 3; /*register dest - memory src long*/
882 timing_mrl = 3; /*memory dest - register src long*/
883 timing_mml = 3;
884 timing_bt = 4-1; /*branch taken*/
885 timing_bnt = 1; /*branch not taken*/
886 timing_int = 4;
887 timing_int_rm = 14;
888 timing_int_v86 = 82;
889 timing_int_pm = 49;
890 timing_int_pm_outer = 77;
891 timing_iret_rm = 14;
892 timing_iret_v86 = 66; /*unknown*/
893 timing_iret_pm = 31;
894 timing_iret_pm_outer = 66;
895 timing_call_rm = 12;
896 timing_call_pm = 30;
897 timing_call_pm_gate = 41;
898 timing_call_pm_gate_inner = 83;
899 timing_retf_rm = 13;
900 timing_retf_pm = 26;
901 timing_retf_pm_outer = 61;
902 timing_jmp_rm = 9;
903 timing_jmp_pm = 26;
904 timing_jmp_pm_gate = 37;
905 timing_misaligned = 3;
906 break;
907
908 case CPU_Cx5x86:
909 timing_rr = 1; /*register dest - register src*/
910 timing_rm = 1; /*register dest - memory src*/
911 timing_mr = 2; /*memory dest - register src*/
912 timing_mm = 2;
913 timing_rml = 1; /*register dest - memory src long*/
914 timing_mrl = 2; /*memory dest - register src long*/
915 timing_mml = 2;
916 timing_bt = 5-1; /*branch taken*/
917 timing_bnt = 1; /*branch not taken*/
918 timing_int = 0;
919 timing_int_rm = 9;
920 timing_int_v86 = 82; /*unknown*/
921 timing_int_pm = 21;
922 timing_int_pm_outer = 32;
923 timing_iret_rm = 7;
924 timing_iret_v86 = 26; /*unknown*/
925 timing_iret_pm = 10;
926 timing_iret_pm_outer = 26;
927 timing_call_rm = 4;
928 timing_call_pm = 15;
929 timing_call_pm_gate = 26;
930 timing_call_pm_gate_inner = 35;
931 timing_retf_rm = 4;
932 timing_retf_pm = 7;
933 timing_retf_pm_outer = 23;
934 timing_jmp_rm = 5;
935 timing_jmp_pm = 7;
936 timing_jmp_pm_gate = 17;
937 timing_misaligned = 2;
938 cpu_cyrix_alignment = 1;
939 break;
940
941 case CPU_WINCHIP:
942 x86_setopcodes(ops_386, ops_winchip_0f, dynarec_ops_386, dynarec_ops_winchip_0f);
943 timing_rr = 1; /*register dest - register src*/
944 timing_rm = 2; /*register dest - memory src*/
945 timing_mr = 2; /*memory dest - register src*/
946 timing_mm = 3;
947 timing_rml = 2; /*register dest - memory src long*/
948 timing_mrl = 2; /*memory dest - register src long*/
949 timing_mml = 3;
950 timing_bt = 3-1; /*branch taken*/
951 timing_bnt = 1; /*branch not taken*/
952 cpu_hasrdtsc = 1;
953 msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
954 cpu_hasMMX = cpu_hasMSR = 1;
955 cpu_hasCR4 = 1;
956 cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE;
957 /*unknown*/
958 timing_int_rm = 26;
959 timing_int_v86 = 82;
960 timing_int_pm = 44;
961 timing_int_pm_outer = 71;
962 timing_iret_rm = 7;
963 timing_iret_v86 = 26;
964 timing_iret_pm = 10;
965 timing_iret_pm_outer = 26;
966 timing_call_rm = 4;
967 timing_call_pm = 15;
968 timing_call_pm_gate = 26;
969 timing_call_pm_gate_inner = 35;
970 timing_retf_rm = 4;
971 timing_retf_pm = 7;
972 timing_retf_pm_outer = 23;
973 timing_jmp_rm = 5;
974 timing_jmp_pm = 7;
975 timing_jmp_pm_gate = 17;
976 timing_misaligned = 2;
977 cpu_cyrix_alignment = 1;
978 codegen_timing_set(&codegen_timing_winchip);
979 break;
980
981 case CPU_PENTIUM:
982 x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f);
983 timing_rr = 1; /*register dest - register src*/
984 timing_rm = 2; /*register dest - memory src*/
985 timing_mr = 3; /*memory dest - register src*/
986 timing_mm = 3;
987 timing_rml = 2; /*register dest - memory src long*/
988 timing_mrl = 3; /*memory dest - register src long*/
989 timing_mml = 3;
990 timing_bt = 0; /*branch taken*/
991 timing_bnt = 2; /*branch not taken*/
992 timing_int = 6;
993 timing_int_rm = 11;
994 timing_int_v86 = 54;
995 timing_int_pm = 25;
996 timing_int_pm_outer = 42;
997 timing_iret_rm = 7;
998 timing_iret_v86 = 27; /*unknown*/
999 timing_iret_pm = 10;
1000 timing_iret_pm_outer = 27;
1001 timing_call_rm = 4;
1002 timing_call_pm = 4;
1003 timing_call_pm_gate = 22;
1004 timing_call_pm_gate_inner = 44;
1005 timing_retf_rm = 4;
1006 timing_retf_pm = 4;
1007 timing_retf_pm_outer = 23;
1008 timing_jmp_rm = 3;
1009 timing_jmp_pm = 3;
1010 timing_jmp_pm_gate = 18;
1011 timing_misaligned = 3;
1012 cpu_hasrdtsc = 1;
1013 msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
1014 cpu_hasMMX = 0;
1015 cpu_hasMSR = 1;
1016 cpu_hasCR4 = 1;
1017 cpu_hasVME = 1;
1018 cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE;
1019 codegen_timing_set(&codegen_timing_pentium);
1020 break;
1021
1022 case CPU_PENTIUMMMX:
1023 x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f);
1024 timing_rr = 1; /*register dest - register src*/
1025 timing_rm = 2; /*register dest - memory src*/
1026 timing_mr = 3; /*memory dest - register src*/
1027 timing_mm = 3;
1028 timing_rml = 2; /*register dest - memory src long*/
1029 timing_mrl = 3; /*memory dest - register src long*/
1030 timing_mml = 3;
1031 timing_bt = 0; /*branch taken*/
1032 timing_bnt = 1; /*branch not taken*/
1033 timing_int = 6;
1034 timing_int_rm = 11;
1035 timing_int_v86 = 54;
1036 timing_int_pm = 25;
1037 timing_int_pm_outer = 42;
1038 timing_iret_rm = 7;
1039 timing_iret_v86 = 27; /*unknown*/
1040 timing_iret_pm = 10;
1041 timing_iret_pm_outer = 27;
1042 timing_call_rm = 4;
1043 timing_call_pm = 4;
1044 timing_call_pm_gate = 22;
1045 timing_call_pm_gate_inner = 44;
1046 timing_retf_rm = 4;
1047 timing_retf_pm = 4;
1048 timing_retf_pm_outer = 23;
1049 timing_jmp_rm = 3;
1050 timing_jmp_pm = 3;
1051 timing_jmp_pm_gate = 18;
1052 timing_misaligned = 3;
1053 cpu_hasrdtsc = 1;
1054 msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
1055 cpu_hasMMX = 1;
1056 cpu_hasMSR = 1;
1057 cpu_hasCR4 = 1;
1058 cpu_hasVME = 1;
1059 cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE;
1060 codegen_timing_set(&codegen_timing_pentium);
1061 break;
1062
1063 case CPU_Cx6x86:
1064 x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f);
1065 timing_rr = 1; /*register dest - register src*/
1066 timing_rm = 1; /*register dest - memory src*/
1067 timing_mr = 2; /*memory dest - register src*/
1068 timing_mm = 2;
1069 timing_rml = 1; /*register dest - memory src long*/
1070 timing_mrl = 2; /*memory dest - register src long*/
1071 timing_mml = 2;
1072 timing_bt = 0; /*branch taken*/
1073 timing_bnt = 2; /*branch not taken*/
1074 timing_int_rm = 9;
1075 timing_int_v86 = 46;
1076 timing_int_pm = 21;
1077 timing_int_pm_outer = 32;
1078 timing_iret_rm = 7;
1079 timing_iret_v86 = 26;
1080 timing_iret_pm = 10;
1081 timing_iret_pm_outer = 26;
1082 timing_call_rm = 3;
1083 timing_call_pm = 4;
1084 timing_call_pm_gate = 15;
1085 timing_call_pm_gate_inner = 26;
1086 timing_retf_rm = 4;
1087 timing_retf_pm = 4;
1088 timing_retf_pm_outer = 23;
1089 timing_jmp_rm = 1;
1090 timing_jmp_pm = 4;
1091 timing_jmp_pm_gate = 14;
1092 timing_misaligned = 2;
1093 cpu_cyrix_alignment = 1;
1094 cpu_hasrdtsc = 1;
1095 msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
1096 cpu_hasMMX = 0;
1097 cpu_hasMSR = 0;
1098 cpu_hasCR4 = 0;
1099 codegen_timing_set(&codegen_timing_686);
1100 CPUID = 0; /*Disabled on powerup by default*/
1101 break;
1102
1103 case CPU_Cx6x86L:
1104 x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f);
1105 timing_rr = 1; /*register dest - register src*/
1106 timing_rm = 1; /*register dest - memory src*/
1107 timing_mr = 2; /*memory dest - register src*/
1108 timing_mm = 2;
1109 timing_rml = 1; /*register dest - memory src long*/
1110 timing_mrl = 2; /*memory dest - register src long*/
1111 timing_mml = 2;
1112 timing_bt = 0; /*branch taken*/
1113 timing_bnt = 2; /*branch not taken*/
1114 timing_int_rm = 9;
1115 timing_int_v86 = 46;
1116 timing_int_pm = 21;
1117 timing_int_pm_outer = 32;
1118 timing_iret_rm = 7;
1119 timing_iret_v86 = 26;
1120 timing_iret_pm = 10;
1121 timing_iret_pm_outer = 26;
1122 timing_call_rm = 3;
1123 timing_call_pm = 4;
1124 timing_call_pm_gate = 15;
1125 timing_call_pm_gate_inner = 26;
1126 timing_retf_rm = 4;
1127 timing_retf_pm = 4;
1128 timing_retf_pm_outer = 23;
1129 timing_jmp_rm = 1;
1130 timing_jmp_pm = 4;
1131 timing_jmp_pm_gate = 14;
1132 timing_misaligned = 2;
1133 cpu_cyrix_alignment = 1;
1134 cpu_hasrdtsc = 1;
1135 msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
1136 cpu_hasMMX = 0;
1137 cpu_hasMSR = 0;
1138 cpu_hasCR4 = 0;
1139 codegen_timing_set(&codegen_timing_686);
1140 ccr4 = 0x80;
1141 break;
1142
1143
1144 case CPU_CxGX1:
1145 x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f);
1146 timing_rr = 1; /*register dest - register src*/
1147 timing_rm = 1; /*register dest - memory src*/
1148 timing_mr = 2; /*memory dest - register src*/
1149 timing_mm = 2;
1150 timing_rml = 1; /*register dest - memory src long*/
1151 timing_mrl = 2; /*memory dest - register src long*/
1152 timing_mml = 2;
1153 timing_bt = 5-1; /*branch taken*/
1154 timing_bnt = 1; /*branch not taken*/
1155 cpu_hasrdtsc = 1;
1156 msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
1157 cpu_hasMMX = 0;
1158 cpu_hasMSR = 1;
1159 cpu_hasCR4 = 1;
1160 cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE;
1161 codegen_timing_set(&codegen_timing_686);
1162 break;
1163
1164
1165 case CPU_Cx6x86MX:
1166 x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f);
1167 x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16;
1168 x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32;
1169 x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16;
1170 x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32;
1171 x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16;
1172 x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32;
1173 x86_opcodes_da_a16 = ops_fpu_686_da_a16;
1174 x86_opcodes_da_a32 = ops_fpu_686_da_a32;
1175 x86_opcodes_db_a16 = ops_fpu_686_db_a16;
1176 x86_opcodes_db_a32 = ops_fpu_686_db_a32;
1177 x86_opcodes_df_a16 = ops_fpu_686_df_a16;
1178 x86_opcodes_df_a32 = ops_fpu_686_df_a32;
1179 timing_rr = 1; /*register dest - register src*/
1180 timing_rm = 1; /*register dest - memory src*/
1181 timing_mr = 2; /*memory dest - register src*/
1182 timing_mm = 2;
1183 timing_rml = 1; /*register dest - memory src long*/
1184 timing_mrl = 2; /*memory dest - register src long*/
1185 timing_mml = 2;
1186 timing_bt = 0; /*branch taken*/
1187 timing_bnt = 2; /*branch not taken*/
1188 timing_int_rm = 9;
1189 timing_int_v86 = 46;
1190 timing_int_pm = 21;
1191 timing_int_pm_outer = 32;
1192 timing_iret_rm = 7;
1193 timing_iret_v86 = 26;
1194 timing_iret_pm = 10;
1195 timing_iret_pm_outer = 26;
1196 timing_call_rm = 3;
1197 timing_call_pm = 4;
1198 timing_call_pm_gate = 15;
1199 timing_call_pm_gate_inner = 26;
1200 timing_retf_rm = 4;
1201 timing_retf_pm = 4;
1202 timing_retf_pm_outer = 23;
1203 timing_jmp_rm = 1;
1204 timing_jmp_pm = 4;
1205 timing_jmp_pm_gate = 14;
1206 timing_misaligned = 2;
1207 cpu_cyrix_alignment = 1;
1208 cpu_hasrdtsc = 1;
1209 msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
1210 cpu_hasMMX = 1;
1211 cpu_hasMSR = 1;
1212 cpu_hasCR4 = 1;
1213 cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE;
1214 codegen_timing_set(&codegen_timing_686);
1215 ccr4 = 0x80;
1216 break;
1217
1218 default:
1219 fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type);
1220 }
1221 }
1222
cpu_CPUID()1223 void cpu_CPUID()
1224 {
1225 switch (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type)
1226 {
1227 case CPU_i486DX:
1228 if (!EAX)
1229 {
1230 EAX = 0x00000001;
1231 EBX = 0x756e6547;
1232 EDX = 0x49656e69;
1233 ECX = 0x6c65746e;
1234 }
1235 else if (EAX == 1)
1236 {
1237 EAX = CPUID;
1238 EBX = ECX = 0;
1239 EDX = CPUID_FPU; /*FPU*/
1240 }
1241 else
1242 EAX = EBX = ECX = EDX = 0;
1243 break;
1244
1245 case CPU_iDX4:
1246 if (!EAX)
1247 {
1248 EAX = 0x00000001;
1249 EBX = 0x756e6547;
1250 EDX = 0x49656e69;
1251 ECX = 0x6c65746e;
1252 }
1253 else if (EAX == 1)
1254 {
1255 EAX = CPUID;
1256 EBX = ECX = 0;
1257 EDX = CPUID_FPU | CPUID_VME;
1258 }
1259 else
1260 EAX = EBX = ECX = EDX = 0;
1261 break;
1262
1263 case CPU_Am486SX:
1264 if (!EAX)
1265 {
1266 EAX = 1;
1267 EBX = 0x68747541;
1268 ECX = 0x444D4163;
1269 EDX = 0x69746E65;
1270 }
1271 else if (EAX == 1)
1272 {
1273 EAX = CPUID;
1274 EBX = ECX = EDX = 0; /*No FPU*/
1275 }
1276 else
1277 EAX = EBX = ECX = EDX = 0;
1278 break;
1279
1280 case CPU_Am486DX:
1281 if (!EAX)
1282 {
1283 EAX = 1;
1284 EBX = 0x68747541;
1285 ECX = 0x444D4163;
1286 EDX = 0x69746E65;
1287 }
1288 else if (EAX == 1)
1289 {
1290 EAX = CPUID;
1291 EBX = ECX = 0;
1292 EDX = CPUID_FPU; /*FPU*/
1293 }
1294 else
1295 EAX = EBX = ECX = EDX = 0;
1296 break;
1297
1298 case CPU_WINCHIP:
1299 if (!EAX)
1300 {
1301 EAX = 1;
1302 if (msr.fcr2 & (1 << 14))
1303 {
1304 EBX = msr.fcr3 >> 32;
1305 ECX = msr.fcr3 & 0xffffffff;
1306 EDX = msr.fcr2 >> 32;
1307 }
1308 else
1309 {
1310 EBX = 0x746e6543; /*CentaurHauls*/
1311 ECX = 0x736c7561;
1312 EDX = 0x48727561;
1313 }
1314 }
1315 else if (EAX == 1)
1316 {
1317 EAX = 0x540;
1318 EBX = ECX = 0;
1319 EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR;
1320 if (cpu_hasCX8)
1321 EDX |= CPUID_CMPXCHG8B;
1322 if (msr.fcr & (1 << 9))
1323 EDX |= CPUID_MMX;
1324 }
1325 else
1326 EAX = EBX = ECX = EDX = 0;
1327 break;
1328
1329 case CPU_PENTIUM:
1330 if (!EAX)
1331 {
1332 EAX = 0x00000001;
1333 EBX = 0x756e6547;
1334 EDX = 0x49656e69;
1335 ECX = 0x6c65746e;
1336 }
1337 else if (EAX == 1)
1338 {
1339 EAX = CPUID;
1340 EBX = ECX = 0;
1341 EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
1342 }
1343 else
1344 EAX = EBX = ECX = EDX = 0;
1345 break;
1346
1347 case CPU_PENTIUMMMX:
1348 if (!EAX)
1349 {
1350 EAX = 0x00000001;
1351 EBX = 0x756e6547;
1352 EDX = 0x49656e69;
1353 ECX = 0x6c65746e;
1354 }
1355 else if (EAX == 1)
1356 {
1357 EAX = CPUID;
1358 EBX = ECX = 0;
1359 EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX;
1360 }
1361 else
1362 EAX = EBX = ECX = EDX = 0;
1363 break;
1364
1365
1366 case CPU_Cx6x86:
1367 if (!EAX)
1368 {
1369 EAX = 0x00000001;
1370 EBX = 0x69727943;
1371 EDX = 0x736e4978;
1372 ECX = 0x64616574;
1373 }
1374 else if (EAX == 1)
1375 {
1376 EAX = CPUID;
1377 EBX = ECX = 0;
1378 EDX = CPUID_FPU;
1379 }
1380 else
1381 EAX = EBX = ECX = EDX = 0;
1382 break;
1383
1384
1385 case CPU_Cx6x86L:
1386 if (!EAX)
1387 {
1388 EAX = 0x00000001;
1389 EBX = 0x69727943;
1390 EDX = 0x736e4978;
1391 ECX = 0x64616574;
1392 }
1393 else if (EAX == 1)
1394 {
1395 EAX = CPUID;
1396 EBX = ECX = 0;
1397 EDX = CPUID_FPU | CPUID_CMPXCHG8B;
1398 }
1399 else
1400 EAX = EBX = ECX = EDX = 0;
1401 break;
1402
1403
1404 case CPU_CxGX1:
1405 if (!EAX)
1406 {
1407 EAX = 0x00000001;
1408 EBX = 0x69727943;
1409 EDX = 0x736e4978;
1410 ECX = 0x64616574;
1411 }
1412 else if (EAX == 1)
1413 {
1414 EAX = CPUID;
1415 EBX = ECX = 0;
1416 EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
1417 }
1418 else
1419 EAX = EBX = ECX = EDX = 0;
1420 break;
1421
1422
1423
1424 case CPU_Cx6x86MX:
1425 if (!EAX)
1426 {
1427 EAX = 0x00000001;
1428 EBX = 0x69727943;
1429 EDX = 0x736e4978;
1430 ECX = 0x64616574;
1431 }
1432 else if (EAX == 1)
1433 {
1434 EAX = CPUID;
1435 EBX = ECX = 0;
1436 EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX;
1437 }
1438 else
1439 EAX = EBX = ECX = EDX = 0;
1440 break;
1441
1442 }
1443 }
1444
cpu_RDMSR()1445 void cpu_RDMSR()
1446 {
1447 switch (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type)
1448 {
1449 case CPU_WINCHIP:
1450 EAX = EDX = 0;
1451 switch (ECX)
1452 {
1453 case 0x02:
1454 EAX = msr.tr1;
1455 break;
1456 case 0x0e:
1457 EAX = msr.tr12;
1458 break;
1459 case 0x10:
1460 EAX = tsc & 0xffffffff;
1461 EDX = tsc >> 32;
1462 break;
1463 case 0x11:
1464 EAX = msr.cesr;
1465 break;
1466 case 0x107:
1467 EAX = msr.fcr;
1468 break;
1469 case 0x108:
1470 EAX = msr.fcr2 & 0xffffffff;
1471 EDX = msr.fcr2 >> 32;
1472 break;
1473 case 0x10a:
1474 EAX = cpu_multi & 3;
1475 break;
1476 }
1477 break;
1478
1479 case CPU_PENTIUM:
1480 case CPU_PENTIUMMMX:
1481 EAX = EDX = 0;
1482 switch (ECX)
1483 {
1484 case 0x10:
1485 EAX = tsc & 0xffffffff;
1486 EDX = tsc >> 32;
1487 break;
1488 }
1489 break;
1490 case CPU_Cx6x86:
1491 case CPU_Cx6x86L:
1492 case CPU_CxGX1:
1493 case CPU_Cx6x86MX:
1494 switch (ECX)
1495 {
1496 case 0x10:
1497 EAX = tsc & 0xffffffff;
1498 EDX = tsc >> 32;
1499 break;
1500 }
1501 break;
1502 }
1503 }
1504
cpu_WRMSR()1505 void cpu_WRMSR()
1506 {
1507 switch (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type)
1508 {
1509 case CPU_WINCHIP:
1510 switch (ECX)
1511 {
1512 case 0x02:
1513 msr.tr1 = EAX & 2;
1514 break;
1515 case 0x0e:
1516 msr.tr12 = EAX & 0x228;
1517 break;
1518 case 0x10:
1519 tsc = EAX | ((uint64_t)EDX << 32);
1520 break;
1521 case 0x11:
1522 msr.cesr = EAX & 0xff00ff;
1523 break;
1524 case 0x107:
1525 msr.fcr = EAX;
1526 cpu_hasMMX = EAX & (1 << 9);
1527 if (EAX & (1 << 1))
1528 cpu_hasCX8 = 1;
1529 else
1530 cpu_hasCX8 = 0;
1531 if (EAX & (1 << 29))
1532 CPUID = 0;
1533 else
1534 CPUID = models[model].cpu[cpu_manufacturer].cpus[cpu].cpuid_model;
1535 break;
1536 case 0x108:
1537 msr.fcr2 = EAX | ((uint64_t)EDX << 32);
1538 break;
1539 case 0x109:
1540 msr.fcr3 = EAX | ((uint64_t)EDX << 32);
1541 break;
1542 }
1543 break;
1544
1545 case CPU_PENTIUM:
1546 case CPU_PENTIUMMMX:
1547 switch (ECX)
1548 {
1549 case 0x10:
1550 tsc = EAX | ((uint64_t)EDX << 32);
1551 break;
1552 }
1553 break;
1554 case CPU_Cx6x86:
1555 case CPU_Cx6x86L:
1556 case CPU_CxGX1:
1557 case CPU_Cx6x86MX:
1558 switch (ECX)
1559 {
1560 case 0x10:
1561 tsc = EAX | ((uint64_t)EDX << 32);
1562 break;
1563 }
1564 break;
1565 }
1566 }
1567
1568 static int cyrix_addr;
1569
cyrix_write(uint16_t addr,uint8_t val,void * priv)1570 void cyrix_write(uint16_t addr, uint8_t val, void *priv)
1571 {
1572 if (!(addr & 1))
1573 cyrix_addr = val;
1574 else switch (cyrix_addr)
1575 {
1576 case 0xc0: /*CCR0*/
1577 ccr0 = val;
1578 break;
1579 case 0xc1: /*CCR1*/
1580 ccr1 = val;
1581 break;
1582 case 0xc2: /*CCR2*/
1583 ccr2 = val;
1584 break;
1585 case 0xc3: /*CCR3*/
1586 ccr3 = val;
1587 break;
1588 case 0xe8: /*CCR4*/
1589 if ((ccr3 & 0xf0) == 0x10)
1590 {
1591 ccr4 = val;
1592 if (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type >= CPU_Cx6x86)
1593 {
1594 if (val & 0x80)
1595 CPUID = models[model].cpu[cpu_manufacturer].cpus[cpu].cpuid_model;
1596 else
1597 CPUID = 0;
1598 }
1599 }
1600 break;
1601 case 0xe9: /*CCR5*/
1602 if ((ccr3 & 0xf0) == 0x10)
1603 ccr5 = val;
1604 break;
1605 case 0xea: /*CCR6*/
1606 if ((ccr3 & 0xf0) == 0x10)
1607 ccr6 = val;
1608 break;
1609 }
1610 }
1611
cyrix_read(uint16_t addr,void * priv)1612 uint8_t cyrix_read(uint16_t addr, void *priv)
1613 {
1614 if (addr & 1)
1615 {
1616 switch (cyrix_addr)
1617 {
1618 case 0xc0: return ccr0;
1619 case 0xc1: return ccr1;
1620 case 0xc2: return ccr2;
1621 case 0xc3: return ccr3;
1622 case 0xe8: return ((ccr3 & 0xf0) == 0x10) ? ccr4 : 0xff;
1623 case 0xe9: return ((ccr3 & 0xf0) == 0x10) ? ccr5 : 0xff;
1624 case 0xea: return ((ccr3 & 0xf0) == 0x10) ? ccr6 : 0xff;
1625 case 0xfe: return models[model].cpu[cpu_manufacturer].cpus[cpu].cyrix_id & 0xff;
1626 case 0xff: return models[model].cpu[cpu_manufacturer].cpus[cpu].cyrix_id >> 8;
1627 }
1628 if ((cyrix_addr & ~0xf0) == 0xc0) return 0xff;
1629 if (cyrix_addr == 0x20 && models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_Cx5x86) return 0xff;
1630 }
1631 return 0xff;
1632 }
1633
x86_setopcodes(OpFn * opcodes,OpFn * opcodes_0f,OpFn * dynarec_opcodes,OpFn * dynarec_opcodes_0f)1634 void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f, OpFn *dynarec_opcodes, OpFn *dynarec_opcodes_0f)
1635 {
1636 x86_opcodes = opcodes;
1637 x86_opcodes_0f = opcodes_0f;
1638 x86_dynarec_opcodes = dynarec_opcodes;
1639 x86_dynarec_opcodes_0f = dynarec_opcodes_0f;
1640 }
1641
cpu_update_waitstates()1642 void cpu_update_waitstates()
1643 {
1644 cpu_s = &models[model].cpu[cpu_manufacturer].cpus[cpu];
1645
1646 if (is486)
1647 cpu_prefetch_width = 16;
1648 else
1649 cpu_prefetch_width = cpu_16bitbus ? 2 : 4;
1650
1651 if (cpu_cache_int_enabled)
1652 {
1653 /* Disable prefetch emulation */
1654 cpu_prefetch_cycles = 0;
1655 }
1656 else if (cpu_waitstates && (cpu_s->cpu_type >= CPU_286 && cpu_s->cpu_type <= CPU_386DX))
1657 {
1658 /* Waitstates override */
1659 cpu_prefetch_cycles = cpu_waitstates+1;
1660 cpu_cycles_read = cpu_waitstates+1;
1661 cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates+1);
1662 cpu_cycles_write = cpu_waitstates+1;
1663 cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates+1);
1664 }
1665 else if (cpu_cache_ext_enabled)
1666 {
1667 /* Use cache timings */
1668 cpu_prefetch_cycles = cpu_s->cache_read_cycles;
1669 cpu_cycles_read = cpu_s->cache_read_cycles;
1670 cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_read_cycles;
1671 cpu_cycles_write = cpu_s->cache_write_cycles;
1672 cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_write_cycles;
1673 }
1674 else
1675 {
1676 /* Use memory timings */
1677 cpu_prefetch_cycles = cpu_s->mem_read_cycles;
1678 cpu_cycles_read = cpu_s->mem_read_cycles;
1679 cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_read_cycles;
1680 cpu_cycles_write = cpu_s->mem_write_cycles;
1681 cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_write_cycles;
1682 }
1683 if (is486)
1684 cpu_prefetch_cycles = (cpu_prefetch_cycles * 11) / 16;
1685 cpu_mem_prefetch_cycles = cpu_prefetch_cycles;
1686 if (cpu_s->rspeed <= 8000000)
1687 cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles;
1688 }
1689
cpu_set_turbo(int turbo)1690 void cpu_set_turbo(int turbo)
1691 {
1692 if (cpu_turbo != turbo)
1693 {
1694 cpu_turbo = turbo;
1695
1696 cpu_s = &models[model].cpu[cpu_manufacturer].cpus[cpu];
1697 if (cpu_s->cpu_type >= CPU_286)
1698 {
1699 if (cpu_turbo)
1700 setpitclock(cpu_turbo_speed);
1701 else
1702 setpitclock(cpu_nonturbo_speed);
1703 }
1704 else
1705 setpitclock(14318184.0);
1706 }
1707 }
1708
cpu_get_speed()1709 int cpu_get_speed()
1710 {
1711 if (cpu_turbo)
1712 return cpu_turbo_speed;
1713 return cpu_nonturbo_speed;
1714 }
1715