1 enum
2 {
3 FLAGS_UNKNOWN,
4
5 FLAGS_ZN8,
6 FLAGS_ZN16,
7 FLAGS_ZN32,
8
9 FLAGS_ADD8,
10 FLAGS_ADD16,
11 FLAGS_ADD32,
12
13 FLAGS_SUB8,
14 FLAGS_SUB16,
15 FLAGS_SUB32,
16
17 FLAGS_SHL8,
18 FLAGS_SHL16,
19 FLAGS_SHL32,
20
21 FLAGS_SHR8,
22 FLAGS_SHR16,
23 FLAGS_SHR32,
24
25 FLAGS_SAR8,
26 FLAGS_SAR16,
27 FLAGS_SAR32,
28
29 FLAGS_INC8,
30 FLAGS_INC16,
31 FLAGS_INC32,
32
33 FLAGS_DEC8,
34 FLAGS_DEC16,
35 FLAGS_DEC32,
36 };
37
ZF_SET()38 static inline int ZF_SET()
39 {
40 switch (cpu_state.flags_op)
41 {
42 case FLAGS_ZN8:
43 case FLAGS_ZN16:
44 case FLAGS_ZN32:
45 case FLAGS_ADD8:
46 case FLAGS_ADD16:
47 case FLAGS_ADD32:
48 case FLAGS_SUB8:
49 case FLAGS_SUB16:
50 case FLAGS_SUB32:
51 case FLAGS_SHL8:
52 case FLAGS_SHL16:
53 case FLAGS_SHL32:
54 case FLAGS_SHR8:
55 case FLAGS_SHR16:
56 case FLAGS_SHR32:
57 case FLAGS_SAR8:
58 case FLAGS_SAR16:
59 case FLAGS_SAR32:
60 case FLAGS_INC8:
61 case FLAGS_INC16:
62 case FLAGS_INC32:
63 case FLAGS_DEC8:
64 case FLAGS_DEC16:
65 case FLAGS_DEC32:
66 return !cpu_state.flags_res;
67
68 case FLAGS_UNKNOWN:
69 return flags & Z_FLAG;
70 }
71 return 0;
72 }
73
NF_SET()74 static inline int NF_SET()
75 {
76 switch (cpu_state.flags_op)
77 {
78 case FLAGS_ZN8:
79 case FLAGS_ADD8:
80 case FLAGS_SUB8:
81 case FLAGS_SHL8:
82 case FLAGS_SHR8:
83 case FLAGS_SAR8:
84 case FLAGS_INC8:
85 case FLAGS_DEC8:
86 return cpu_state.flags_res & 0x80;
87
88 case FLAGS_ZN16:
89 case FLAGS_ADD16:
90 case FLAGS_SUB16:
91 case FLAGS_SHL16:
92 case FLAGS_SHR16:
93 case FLAGS_SAR16:
94 case FLAGS_INC16:
95 case FLAGS_DEC16:
96 return cpu_state.flags_res & 0x8000;
97
98 case FLAGS_ZN32:
99 case FLAGS_ADD32:
100 case FLAGS_SUB32:
101 case FLAGS_SHL32:
102 case FLAGS_SHR32:
103 case FLAGS_SAR32:
104 case FLAGS_INC32:
105 case FLAGS_DEC32:
106 return cpu_state.flags_res & 0x80000000;
107
108 case FLAGS_UNKNOWN:
109 return flags & N_FLAG;
110 }
111 return 0;
112 }
113
PF_SET()114 static inline int PF_SET()
115 {
116 switch (cpu_state.flags_op)
117 {
118 case FLAGS_ZN8:
119 case FLAGS_ZN16:
120 case FLAGS_ZN32:
121 case FLAGS_ADD8:
122 case FLAGS_ADD16:
123 case FLAGS_ADD32:
124 case FLAGS_SUB8:
125 case FLAGS_SUB16:
126 case FLAGS_SUB32:
127 case FLAGS_SHL8:
128 case FLAGS_SHL16:
129 case FLAGS_SHL32:
130 case FLAGS_SHR8:
131 case FLAGS_SHR16:
132 case FLAGS_SHR32:
133 case FLAGS_SAR8:
134 case FLAGS_SAR16:
135 case FLAGS_SAR32:
136 case FLAGS_INC8:
137 case FLAGS_INC16:
138 case FLAGS_INC32:
139 case FLAGS_DEC8:
140 case FLAGS_DEC16:
141 case FLAGS_DEC32:
142 return znptable8[cpu_state.flags_res & 0xff] & P_FLAG;
143
144 case FLAGS_UNKNOWN:
145 return flags & P_FLAG;
146 }
147 return 0;
148 }
149
VF_SET()150 static inline int VF_SET()
151 {
152 switch (cpu_state.flags_op)
153 {
154 case FLAGS_ZN8:
155 case FLAGS_ZN16:
156 case FLAGS_ZN32:
157 case FLAGS_SAR8:
158 case FLAGS_SAR16:
159 case FLAGS_SAR32:
160 return 0;
161
162 case FLAGS_ADD8:
163 case FLAGS_INC8:
164 return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80);
165 case FLAGS_ADD16:
166 case FLAGS_INC16:
167 return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x8000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000);
168 case FLAGS_ADD32:
169 case FLAGS_INC32:
170 return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80000000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000);
171
172 case FLAGS_SUB8:
173 case FLAGS_DEC8:
174 return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80);
175 case FLAGS_SUB16:
176 case FLAGS_DEC16:
177 return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000);
178 case FLAGS_SUB32:
179 case FLAGS_DEC32:
180 return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000);
181
182 case FLAGS_SHL8:
183 return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80);
184 case FLAGS_SHL16:
185 return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x8000);
186 case FLAGS_SHL32:
187 return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80000000);
188
189 case FLAGS_SHR8:
190 return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80));
191 case FLAGS_SHR16:
192 return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x8000));
193 case FLAGS_SHR32:
194 return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000));
195
196 case FLAGS_UNKNOWN:
197 return flags & V_FLAG;
198 }
199 return 0;
200 }
201
AF_SET()202 static inline int AF_SET()
203 {
204 switch (cpu_state.flags_op)
205 {
206 case FLAGS_ZN8:
207 case FLAGS_ZN16:
208 case FLAGS_ZN32:
209 case FLAGS_SHL8:
210 case FLAGS_SHL16:
211 case FLAGS_SHL32:
212 case FLAGS_SHR8:
213 case FLAGS_SHR16:
214 case FLAGS_SHR32:
215 case FLAGS_SAR8:
216 case FLAGS_SAR16:
217 case FLAGS_SAR32:
218 return 0;
219
220 case FLAGS_ADD8:
221 case FLAGS_ADD16:
222 case FLAGS_ADD32:
223 case FLAGS_INC8:
224 case FLAGS_INC16:
225 case FLAGS_INC32:
226 return ((cpu_state.flags_op1 & 0xF) + (cpu_state.flags_op2 & 0xF)) & 0x10;
227
228 case FLAGS_SUB8:
229 case FLAGS_SUB16:
230 case FLAGS_SUB32:
231 case FLAGS_DEC8:
232 case FLAGS_DEC16:
233 case FLAGS_DEC32:
234 return ((cpu_state.flags_op1 & 0xF) - (cpu_state.flags_op2 & 0xF)) & 0x10;
235
236 case FLAGS_UNKNOWN:
237 return flags & A_FLAG;
238 }
239 return 0;
240 }
241
CF_SET()242 static inline int CF_SET()
243 {
244 switch (cpu_state.flags_op)
245 {
246 case FLAGS_ADD8:
247 return (cpu_state.flags_op1 + cpu_state.flags_op2) & 0x100;
248 case FLAGS_ADD16:
249 return (cpu_state.flags_op1 + cpu_state.flags_op2) & 0x10000;
250 case FLAGS_ADD32:
251 return (cpu_state.flags_res < cpu_state.flags_op1);
252
253 case FLAGS_SUB8:
254 case FLAGS_SUB16:
255 case FLAGS_SUB32:
256 return (cpu_state.flags_op1 < cpu_state.flags_op2);
257
258 case FLAGS_SHL8:
259 return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80;
260 case FLAGS_SHL16:
261 return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x8000;
262 case FLAGS_SHL32:
263 return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80000000;
264
265 case FLAGS_SHR8:
266 case FLAGS_SHR16:
267 case FLAGS_SHR32:
268 return (cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1;
269
270 case FLAGS_SAR8:
271 return ((int8_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1;
272 case FLAGS_SAR16:
273 return ((int16_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1;
274 case FLAGS_SAR32:
275 return ((int32_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1;
276
277 case FLAGS_ZN8:
278 case FLAGS_ZN16:
279 case FLAGS_ZN32:
280 return 0;
281
282 case FLAGS_DEC8:
283 case FLAGS_DEC16:
284 case FLAGS_DEC32:
285 case FLAGS_INC8:
286 case FLAGS_INC16:
287 case FLAGS_INC32:
288 case FLAGS_UNKNOWN:
289 return flags & C_FLAG;
290 }
291 return 0;
292 }
293
294 //#define ZF_SET() (flags & Z_FLAG)
295 //#define NF_SET() (flags & N_FLAG)
296 //#define PF_SET() (flags & P_FLAG)
297 //#define VF_SET() (flags & V_FLAG)
298 //#define CF_SET() (flags & C_FLAG)
299 //#define AF_SET() (flags & A_FLAG)
300
flags_rebuild()301 static inline void flags_rebuild()
302 {
303 if (cpu_state.flags_op != FLAGS_UNKNOWN)
304 {
305 uint16_t tempf = 0;
306 if (CF_SET()) tempf |= C_FLAG;
307 if (PF_SET()) tempf |= P_FLAG;
308 if (AF_SET()) tempf |= A_FLAG;
309 if (ZF_SET()) tempf |= Z_FLAG;
310 if (NF_SET()) tempf |= N_FLAG;
311 if (VF_SET()) tempf |= V_FLAG;
312 flags = (flags & ~0x8d5) | tempf;
313 cpu_state.flags_op = FLAGS_UNKNOWN;
314 }
315 }
316
flags_extract()317 static inline void flags_extract()
318 {
319 cpu_state.flags_op = FLAGS_UNKNOWN;
320 }
321
flags_rebuild_c()322 static inline void flags_rebuild_c()
323 {
324 if (cpu_state.flags_op != FLAGS_UNKNOWN)
325 {
326 if (CF_SET())
327 flags |= C_FLAG;
328 else
329 flags &= ~C_FLAG;
330 }
331 }
332
setznp8(uint8_t val)333 static inline void setznp8(uint8_t val)
334 {
335 cpu_state.flags_op = FLAGS_ZN8;
336 cpu_state.flags_res = val;
337 }
setznp16(uint16_t val)338 static inline void setznp16(uint16_t val)
339 {
340 cpu_state.flags_op = FLAGS_ZN16;
341 cpu_state.flags_res = val;
342 }
setznp32(uint32_t val)343 static inline void setznp32(uint32_t val)
344 {
345 cpu_state.flags_op = FLAGS_ZN32;
346 cpu_state.flags_res = val;
347 }
348
349 #define set_flags_shift(op, orig, shift, res) \
350 cpu_state.flags_op = op; \
351 cpu_state.flags_res = res; \
352 cpu_state.flags_op1 = orig; \
353 cpu_state.flags_op2 = shift;
354
setadd8(uint8_t a,uint8_t b)355 static inline void setadd8(uint8_t a, uint8_t b)
356 {
357 cpu_state.flags_op1 = a;
358 cpu_state.flags_op2 = b;
359 cpu_state.flags_res = (a + b) & 0xff;
360 cpu_state.flags_op = FLAGS_ADD8;
361 }
setadd16(uint16_t a,uint16_t b)362 static inline void setadd16(uint16_t a, uint16_t b)
363 {
364 cpu_state.flags_op1 = a;
365 cpu_state.flags_op2 = b;
366 cpu_state.flags_res = (a + b) & 0xffff;
367 cpu_state.flags_op = FLAGS_ADD16;
368 }
setadd32(uint32_t a,uint32_t b)369 static inline void setadd32(uint32_t a, uint32_t b)
370 {
371 cpu_state.flags_op1 = a;
372 cpu_state.flags_op2 = b;
373 cpu_state.flags_res = a + b;
374 cpu_state.flags_op = FLAGS_ADD32;
375 }
setadd8nc(uint8_t a,uint8_t b)376 static inline void setadd8nc(uint8_t a, uint8_t b)
377 {
378 flags_rebuild_c();
379 cpu_state.flags_op1 = a;
380 cpu_state.flags_op2 = b;
381 cpu_state.flags_res = (a + b) & 0xff;
382 cpu_state.flags_op = FLAGS_INC8;
383 }
setadd16nc(uint16_t a,uint16_t b)384 static inline void setadd16nc(uint16_t a, uint16_t b)
385 {
386 flags_rebuild_c();
387 cpu_state.flags_op1 = a;
388 cpu_state.flags_op2 = b;
389 cpu_state.flags_res = (a + b) & 0xffff;
390 cpu_state.flags_op = FLAGS_INC16;
391 }
setadd32nc(uint32_t a,uint32_t b)392 static inline void setadd32nc(uint32_t a, uint32_t b)
393 {
394 flags_rebuild_c();
395 cpu_state.flags_op1 = a;
396 cpu_state.flags_op2 = b;
397 cpu_state.flags_res = a + b;
398 cpu_state.flags_op = FLAGS_INC32;
399 }
400
setsub8(uint8_t a,uint8_t b)401 static inline void setsub8(uint8_t a, uint8_t b)
402 {
403 cpu_state.flags_op1 = a;
404 cpu_state.flags_op2 = b;
405 cpu_state.flags_res = (a - b) & 0xff;
406 cpu_state.flags_op = FLAGS_SUB8;
407 }
setsub16(uint16_t a,uint16_t b)408 static inline void setsub16(uint16_t a, uint16_t b)
409 {
410 cpu_state.flags_op1 = a;
411 cpu_state.flags_op2 = b;
412 cpu_state.flags_res = (a - b) & 0xffff;
413 cpu_state.flags_op = FLAGS_SUB16;
414 }
setsub32(uint32_t a,uint32_t b)415 static inline void setsub32(uint32_t a, uint32_t b)
416 {
417 cpu_state.flags_op1 = a;
418 cpu_state.flags_op2 = b;
419 cpu_state.flags_res = a - b;
420 cpu_state.flags_op = FLAGS_SUB32;
421 }
422
setsub8nc(uint8_t a,uint8_t b)423 static inline void setsub8nc(uint8_t a, uint8_t b)
424 {
425 flags_rebuild_c();
426 cpu_state.flags_op1 = a;
427 cpu_state.flags_op2 = b;
428 cpu_state.flags_res = (a - b) & 0xff;
429 cpu_state.flags_op = FLAGS_DEC8;
430 }
setsub16nc(uint16_t a,uint16_t b)431 static inline void setsub16nc(uint16_t a, uint16_t b)
432 {
433 flags_rebuild_c();
434 cpu_state.flags_op1 = a;
435 cpu_state.flags_op2 = b;
436 cpu_state.flags_res = (a - b) & 0xffff;
437 cpu_state.flags_op = FLAGS_DEC16;
438 }
setsub32nc(uint32_t a,uint32_t b)439 static inline void setsub32nc(uint32_t a, uint32_t b)
440 {
441 flags_rebuild_c();
442 cpu_state.flags_op1 = a;
443 cpu_state.flags_op2 = b;
444 cpu_state.flags_res = a - b;
445 cpu_state.flags_op = FLAGS_DEC32;
446 }
447
setadc8(uint8_t a,uint8_t b)448 static inline void setadc8(uint8_t a, uint8_t b)
449 {
450 uint16_t c=(uint16_t)a+(uint16_t)b+tempc;
451 cpu_state.flags_op = FLAGS_UNKNOWN;
452 flags&=~0x8D5;
453 flags|=znptable8[c&0xFF];
454 if (c&0x100) flags|=C_FLAG;
455 if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG;
456 if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG;
457 }
setadc16(uint16_t a,uint16_t b)458 static inline void setadc16(uint16_t a, uint16_t b)
459 {
460 uint32_t c=(uint32_t)a+(uint32_t)b+tempc;
461 cpu_state.flags_op = FLAGS_UNKNOWN;
462 flags&=~0x8D5;
463 flags|=znptable16[c&0xFFFF];
464 if (c&0x10000) flags|=C_FLAG;
465 if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG;
466 if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG;
467 }
468
setsbc8(uint8_t a,uint8_t b)469 static inline void setsbc8(uint8_t a, uint8_t b)
470 {
471 uint16_t c=(uint16_t)a-(((uint16_t)b)+tempc);
472 cpu_state.flags_op = FLAGS_UNKNOWN;
473 flags&=~0x8D5;
474 flags|=znptable8[c&0xFF];
475 if (c&0x100) flags|=C_FLAG;
476 if ((a^b)&(a^c)&0x80) flags|=V_FLAG;
477 if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG;
478 }
setsbc16(uint16_t a,uint16_t b)479 static inline void setsbc16(uint16_t a, uint16_t b)
480 {
481 uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc);
482 cpu_state.flags_op = FLAGS_UNKNOWN;
483 flags&=~0x8D5;
484 flags|=(znptable16[c&0xFFFF]&~4);
485 flags|=(znptable8[c&0xFF]&4);
486 if (c&0x10000) flags|=C_FLAG;
487 if ((a^b)&(a^c)&0x8000) flags|=V_FLAG;
488 if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG;
489 }
490
setadc32(uint32_t a,uint32_t b)491 static inline void setadc32(uint32_t a, uint32_t b)
492 {
493 uint32_t c=(uint32_t)a+(uint32_t)b+tempc;
494 cpu_state.flags_op = FLAGS_UNKNOWN;
495 flags&=~0x8D5;
496 flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0));
497 flags|=(znptable8[c&0xFF]&P_FLAG);
498 if ((c<a) || (c==a && tempc)) flags|=C_FLAG;
499 if (!((a^b)&0x80000000)&&((a^c)&0x80000000)) flags|=V_FLAG;
500 if (((a&0xF)+(b&0xF)+tempc)&0x10) flags|=A_FLAG;
501 }
setsbc32(uint32_t a,uint32_t b)502 static inline void setsbc32(uint32_t a, uint32_t b)
503 {
504 uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc);
505 cpu_state.flags_op = FLAGS_UNKNOWN;
506 flags&=~0x8D5;
507 flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0));
508 flags|=(znptable8[c&0xFF]&P_FLAG);
509 if ((c>a) || (c==a && tempc)) flags|=C_FLAG;
510 if ((a^b)&(a^c)&0x80000000) flags|=V_FLAG;
511 if (((a&0xF)-((b&0xF)+tempc))&0x10) flags|=A_FLAG;
512 }
513
514