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