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