more properly handling new haa semantics
[drnoksnes] / cpumacro.h
1 /*
2  * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3  *
4  * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and
5  *                           Jerremy Koot (jkoot@snes9x.com)
6  *
7  * Super FX C emulator code 
8  * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and
9  *                           Gary Henderson.
10  * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
11  *
12  * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson.
13  * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_.
14  * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com).
15  *
16  * DOS port code contains the works of other authors. See headers in
17  * individual files.
18  *
19  * Snes9x homepage: http://www.snes9x.com
20  *
21  * Permission to use, copy, modify and distribute Snes9x in both binary and
22  * source form, for non-commercial purposes, is hereby granted without fee,
23  * providing that this license information and copyright notice appear with
24  * all copies and any derived work.
25  *
26  * This software is provided 'as-is', without any express or implied
27  * warranty. In no event shall the authors be held liable for any damages
28  * arising from the use of this software.
29  *
30  * Snes9x is freeware for PERSONAL USE only. Commercial users should
31  * seek permission of the copyright holders first. Commercial use includes
32  * charging money for Snes9x or software derived from Snes9x.
33  *
34  * The copyright holders request that bug fixes and improvements to the code
35  * should be forwarded to them so everyone can benefit from the modifications
36  * in future versions.
37  *
38  * Super NES and Super Nintendo Entertainment System are trademarks of
39  * Nintendo Co., Limited and its subsidiary companies.
40  */
41 #ifndef _CPUMACRO_H_
42 #define _CPUMACRO_H_
43
44 #define SETZN16(W) \
45     ICPU._Zero = (W) != 0; \
46     ICPU._Negative = (uint8) ((W) >> 8);
47
48 #define SETZN8(W) \
49     ICPU._Zero = (W); \
50     ICPU._Negative = (W);
51
52 STATIC INLINE void FASTCALL ADC8 (long OpAddress)
53 {
54     uint8 Work8 = S9xGetByte (OpAddress);
55     
56     if (CheckDecimal())
57     {
58         uint8 A1 = (Registers.A.W) & 0xF;
59         uint8 A2 = (Registers.A.W >> 4) & 0xF;
60         uint8 W1 = Work8 & 0xF;
61         uint8 W2 = (Work8 >> 4) & 0xF;
62
63         A1 += W1 + CheckCarry();
64         if (A1 > 9)
65         {
66             A1 -= 10;
67             A2++;
68         }
69
70         A2 += W2;
71         if (A2 > 9)
72         {
73             A2 -= 10;
74             SetCarry ();
75         }
76         else
77         {
78             ClearCarry ();
79         }
80
81         uint8 Ans8 = (A2 << 4) | A1;
82         if (~(Registers.AL ^ Work8) &
83             (Work8 ^ Ans8) & 0x80)
84              SetOverflow ();
85         else
86             ClearOverflow();
87         Registers.AL = Ans8;
88         SETZN8 (Registers.AL);
89     }
90     else
91     {
92         uint16 Ans16 = Registers.AL + Work8 + CheckCarry();
93
94         ICPU._Carry = Ans16 >= 0x100;
95
96         if (~(Registers.AL ^ Work8) & 
97              (Work8 ^ (uint8) Ans16) & 0x80)
98             SetOverflow();
99         else
100             ClearOverflow();
101         Registers.AL = (uint8) Ans16;
102         SETZN8 (Registers.AL);
103
104     }
105 }
106
107 STATIC INLINE void FASTCALL ADC16 (long OpAddress)
108 {
109     uint16 Work16 = S9xGetWord (OpAddress);
110
111     if (CheckDecimal())
112     {
113         uint8 A1 = (Registers.A.W) & 0xF;
114         uint8 A2 = (Registers.A.W >> 4) & 0xF;
115         uint8 A3 = (Registers.A.W >> 8) & 0xF;
116         uint8 A4 = (Registers.A.W >> 12) & 0xF;
117         uint8 W1 = Work16 & 0xF;
118         uint8 W2 = (Work16 >> 4) & 0xF;
119         uint8 W3 = (Work16 >> 8) & 0xF;
120         uint8 W4 = (Work16 >> 12) & 0xF;
121
122         A1 += W1 + CheckCarry ();
123         if (A1 > 9)
124         {
125             A1 -= 10;
126             A2++;
127         }
128
129         A2 += W2;
130         if (A2 > 9)
131         {
132             A2 -= 10;
133             A3++;
134         }
135
136         A3 += W3;
137         if (A3 > 9)
138         {
139             A3 -= 10;
140             A4++;
141         }
142
143         A4 += W4;
144         if (A4 > 9)
145         {
146             A4 -= 10;
147             SetCarry ();
148         }
149         else
150         {
151             ClearCarry ();
152         }
153
154         uint16 Ans16 = (A4 << 12) | (A3 << 8) | (A2 << 4) | (A1);
155         if (~(Registers.A.W ^ Work16) &
156             (Work16 ^ Ans16) & 0x8000)
157             SetOverflow();
158         else
159             ClearOverflow();
160         Registers.A.W = Ans16;
161         SETZN16 (Registers.A.W);
162     }
163     else
164     {
165         uint32 Ans32 = Registers.A.W + Work16 + CheckCarry();
166
167         ICPU._Carry = Ans32 >= 0x10000;
168
169         if (~(Registers.A.W ^ Work16) &
170             (Work16 ^ (uint16) Ans32) & 0x8000)
171             SetOverflow();
172         else
173             ClearOverflow();
174         Registers.A.W = (uint16) Ans32;
175         SETZN16 (Registers.A.W);
176     }
177 }
178
179 STATIC INLINE void FASTCALL AND16 (long OpAddress)
180 {
181     Registers.A.W &= S9xGetWord (OpAddress);
182     SETZN16 (Registers.A.W);
183 }
184
185 STATIC INLINE void FASTCALL AND8 (long OpAddress)
186 {
187     Registers.AL &= S9xGetByte (OpAddress);
188     SETZN8 (Registers.AL);
189 }
190
191 STATIC INLINE void FASTCALL A_ASL16 ()
192 {
193 #ifdef VAR_CYCLES
194     CPU.Cycles += ONE_CYCLE;
195 #endif
196     ICPU._Carry = (Registers.AH & 0x80) != 0;
197     Registers.A.W <<= 1;
198     SETZN16 (Registers.A.W);
199 }
200
201 STATIC INLINE void FASTCALL A_ASL8 ()
202 {
203 #ifdef VAR_CYCLES
204     CPU.Cycles += ONE_CYCLE;
205 #endif
206     ICPU._Carry = (Registers.AL & 0x80) != 0;
207     Registers.AL <<= 1;
208     SETZN8 (Registers.AL);
209 }
210
211 STATIC INLINE void FASTCALL ASL16 (long OpAddress)
212 {
213 #ifdef VAR_CYCLES
214     CPU.Cycles += ONE_CYCLE;
215 #endif
216     uint16 Work16 = S9xGetWord (OpAddress);
217     ICPU._Carry = (Work16 & 0x8000) != 0;
218     Work16 <<= 1;
219     S9xSetWord (Work16, OpAddress);
220     SETZN16 (Work16);
221 }
222
223 STATIC INLINE void FASTCALL ASL8 (long OpAddress)
224 {
225 #ifdef VAR_CYCLES
226     CPU.Cycles += ONE_CYCLE;
227 #endif
228     uint8 Work8 = S9xGetByte (OpAddress);
229     ICPU._Carry = (Work8 & 0x80) != 0;
230     Work8 <<= 1;
231     S9xSetByte (Work8, OpAddress);
232     SETZN8 (Work8);
233 }
234
235 STATIC INLINE void FASTCALL BIT16 (long OpAddress)
236 {
237     uint16 Work16 = S9xGetWord (OpAddress);
238     ICPU._Overflow = (Work16 & 0x4000) != 0;
239     ICPU._Negative = (uint8) (Work16 >> 8);
240     ICPU._Zero = (Work16 & Registers.A.W) != 0;
241 }
242
243 STATIC INLINE void FASTCALL BIT8 (long OpAddress)
244 {
245     uint8 Work8 = S9xGetByte (OpAddress);
246     ICPU._Overflow = (Work8 & 0x40) != 0;
247     ICPU._Negative = Work8;
248     ICPU._Zero = Work8 & Registers.AL;
249 }
250
251 STATIC INLINE void FASTCALL CMP16 (long OpAddress)
252 {
253     int32 Int32 = (long) Registers.A.W -
254             (long) S9xGetWord (OpAddress);
255     ICPU._Carry = Int32 >= 0;
256     SETZN16 ((uint16) Int32);
257 }
258
259 STATIC INLINE void FASTCALL CMP8 (long OpAddress)
260 {
261     int32 Int32 = (short) Registers.AL -
262             (short) S9xGetByte (OpAddress);
263     ICPU._Carry = Int32 >= 0;
264     SETZN8 ((uint8) Int32);
265 }
266
267 STATIC INLINE void FASTCALL CMX16 (long OpAddress)
268 {
269     int32 Int32 = (long) Registers.X.W -
270             (long) S9xGetWord (OpAddress);
271     ICPU._Carry = Int32 >= 0;
272     SETZN16 ((uint16) Int32);
273 }
274
275 STATIC INLINE void FASTCALL CMX8 (long OpAddress)
276 {
277     int32 Int32 = (short) Registers.XL -
278             (short) S9xGetByte (OpAddress);
279     ICPU._Carry = Int32 >= 0;
280     SETZN8 ((uint8) Int32);
281 }
282
283 STATIC INLINE void FASTCALL CMY16 (long OpAddress)
284 {
285     int32 Int32 = (long) Registers.Y.W -
286             (long) S9xGetWord (OpAddress);
287     ICPU._Carry = Int32 >= 0;
288     SETZN16 ((uint16) Int32);
289 }
290
291 STATIC INLINE void FASTCALL CMY8 (long OpAddress)
292 {
293     int32 Int32 = (short) Registers.YL -
294             (short) S9xGetByte (OpAddress);
295     ICPU._Carry = Int32 >= 0;
296     SETZN8 ((uint8) Int32);
297 }
298
299 STATIC INLINE void FASTCALL A_DEC16 ()
300 {
301 #ifdef VAR_CYCLES
302     CPU.Cycles += ONE_CYCLE;
303 #endif
304 #ifdef CPU_SHUTDOWN
305     CPU.WaitAddress = NULL;
306 #endif
307
308     Registers.A.W--;
309     SETZN16 (Registers.A.W);
310 }
311
312 STATIC INLINE void FASTCALL A_DEC8 ()
313 {
314 #ifdef VAR_CYCLES
315     CPU.Cycles += ONE_CYCLE;
316 #endif
317 #ifdef CPU_SHUTDOWN
318     CPU.WaitAddress = NULL;
319 #endif
320
321     Registers.AL--;
322     SETZN8 (Registers.AL);
323 }
324
325 STATIC INLINE void FASTCALL DEC16 (long OpAddress)
326 {
327 #ifdef VAR_CYCLES
328     CPU.Cycles += ONE_CYCLE;
329 #endif
330 #ifdef CPU_SHUTDOWN
331     CPU.WaitAddress = NULL;
332 #endif
333
334     uint16 Work16 = S9xGetWord (OpAddress) - 1;
335     S9xSetWord (Work16, OpAddress);
336     SETZN16 (Work16);
337 }
338
339 STATIC INLINE void FASTCALL DEC8 (long OpAddress)
340 {
341 #ifdef VAR_CYCLES
342     CPU.Cycles += ONE_CYCLE;
343 #endif
344 #ifdef CPU_SHUTDOWN
345     CPU.WaitAddress = NULL;
346 #endif
347
348     uint8 Work8 = S9xGetByte (OpAddress) - 1;
349     S9xSetByte (Work8, OpAddress);
350     SETZN8 (Work8);
351 }
352
353 STATIC INLINE void FASTCALL EOR16 (long OpAddress)
354 {
355     Registers.A.W ^= S9xGetWord (OpAddress);
356     SETZN16 (Registers.A.W);
357 }
358
359 STATIC INLINE void FASTCALL EOR8 (long OpAddress)
360 {
361     Registers.AL ^= S9xGetByte (OpAddress);
362     SETZN8 (Registers.AL);
363 }
364
365 STATIC INLINE void FASTCALL A_INC16 ()
366 {
367 #ifdef VAR_CYCLES
368     CPU.Cycles += ONE_CYCLE;
369 #endif
370 #ifdef CPU_SHUTDOWN
371     CPU.WaitAddress = NULL;
372 #endif
373
374     Registers.A.W++;
375     SETZN16 (Registers.A.W);
376 }
377
378 STATIC INLINE void FASTCALL A_INC8 ()
379 {
380 #ifdef VAR_CYCLES
381     CPU.Cycles += ONE_CYCLE;
382 #endif
383 #ifdef CPU_SHUTDOWN
384     CPU.WaitAddress = NULL;
385 #endif
386
387     Registers.AL++;
388     SETZN8 (Registers.AL);
389 }
390
391 STATIC INLINE void FASTCALL INC16 (long OpAddress)
392 {
393 #ifdef VAR_CYCLES
394     CPU.Cycles += ONE_CYCLE;
395 #endif
396 #ifdef CPU_SHUTDOWN
397     CPU.WaitAddress = NULL;
398 #endif
399
400     uint16 Work16 = S9xGetWord (OpAddress) + 1;
401     S9xSetWord (Work16, OpAddress);
402     SETZN16 (Work16);
403 }
404
405 STATIC INLINE void FASTCALL INC8 (long OpAddress)
406 {
407 #ifdef VAR_CYCLES
408     CPU.Cycles += ONE_CYCLE;
409 #endif
410 #ifdef CPU_SHUTDOWN
411     CPU.WaitAddress = NULL;
412 #endif
413
414     uint8 Work8 = S9xGetByte (OpAddress) + 1;
415     S9xSetByte (Work8, OpAddress);
416     SETZN8 (Work8);
417 }
418
419 STATIC INLINE void FASTCALL LDA16 (long OpAddress)
420 {
421     Registers.A.W = S9xGetWord (OpAddress);
422     SETZN16 (Registers.A.W);
423 }
424
425 STATIC INLINE void FASTCALL LDA8 (long OpAddress)
426 {
427     Registers.AL = S9xGetByte (OpAddress);
428     SETZN8 (Registers.AL);
429 }
430
431 STATIC INLINE void FASTCALL LDX16 (long OpAddress)
432 {
433     Registers.X.W = S9xGetWord (OpAddress);
434     SETZN16 (Registers.X.W);
435 }
436
437 STATIC INLINE void FASTCALL LDX8 (long OpAddress)
438 {
439     Registers.XL = S9xGetByte (OpAddress);
440     SETZN8 (Registers.XL);
441 }
442
443 STATIC INLINE void FASTCALL LDY16 (long OpAddress)
444 {
445     Registers.Y.W = S9xGetWord (OpAddress);
446     SETZN16 (Registers.Y.W);
447 }
448
449 STATIC INLINE void FASTCALL LDY8 (long OpAddress)
450 {
451     Registers.YL = S9xGetByte (OpAddress);
452     SETZN8 (Registers.YL);
453 }
454
455 STATIC INLINE void FASTCALL A_LSR16 ()
456 {
457 #ifdef VAR_CYCLES
458     CPU.Cycles += ONE_CYCLE;
459 #endif
460     ICPU._Carry = Registers.AL & 1;
461     Registers.A.W >>= 1;
462     SETZN16 (Registers.A.W);
463 }
464
465 STATIC INLINE void FASTCALL A_LSR8 ()
466 {
467 #ifdef VAR_CYCLES
468     CPU.Cycles += ONE_CYCLE;
469 #endif
470     ICPU._Carry = Registers.AL & 1;
471     Registers.AL >>= 1;
472     SETZN8 (Registers.AL);
473 }
474
475 STATIC INLINE void FASTCALL LSR16 (long OpAddress)
476 {
477 #ifdef VAR_CYCLES
478     CPU.Cycles += ONE_CYCLE;
479 #endif
480     uint16 Work16 = S9xGetWord (OpAddress);
481     ICPU._Carry = Work16 & 1;
482     Work16 >>= 1;
483     S9xSetWord (Work16, OpAddress);
484     SETZN16 (Work16);
485 }
486
487 STATIC INLINE void FASTCALL LSR8 (long OpAddress)
488 {
489 #ifdef VAR_CYCLES
490     CPU.Cycles += ONE_CYCLE;
491 #endif
492     uint8 Work8 = S9xGetByte (OpAddress);
493     ICPU._Carry = Work8 & 1;
494     Work8 >>= 1;
495     S9xSetByte (Work8, OpAddress);
496     SETZN8 (Work8);
497 }
498
499 STATIC INLINE void FASTCALL ORA16 (long OpAddress)
500 {
501     Registers.A.W |= S9xGetWord (OpAddress);
502     SETZN16 (Registers.A.W);
503 }
504
505 STATIC INLINE void FASTCALL ORA8 (long OpAddress)
506 {
507     Registers.AL |= S9xGetByte (OpAddress);
508     SETZN8 (Registers.AL);
509 }
510
511 STATIC INLINE void FASTCALL A_ROL16 ()
512 {
513 #ifdef VAR_CYCLES
514     CPU.Cycles += ONE_CYCLE;
515 #endif
516     uint32 Work32 = (Registers.A.W << 1) | CheckCarry();
517     ICPU._Carry = Work32 >= 0x10000;
518     Registers.A.W = (uint16) Work32;
519     SETZN16 ((uint16) Work32);
520 }
521
522 STATIC INLINE void FASTCALL A_ROL8 ()
523 {
524 #ifdef VAR_CYCLES
525     CPU.Cycles += ONE_CYCLE;
526 #endif
527     uint16 Work16 = Registers.AL;
528     Work16 <<= 1;
529     Work16 |= CheckCarry();
530     ICPU._Carry = Work16 >= 0x100;
531     Registers.AL = (uint8) Work16;
532     SETZN8 ((uint8) Work16);
533 }
534
535 STATIC INLINE void FASTCALL ROL16 (long OpAddress)
536 {
537 #ifdef VAR_CYCLES
538     CPU.Cycles += ONE_CYCLE;
539 #endif
540     uint32 Work32 = S9xGetWord (OpAddress);
541     Work32 <<= 1;
542     Work32 |= CheckCarry();
543     ICPU._Carry = Work32 >= 0x10000;
544     S9xSetWord ((uint16) Work32, OpAddress);
545     SETZN16 ((uint16) Work32);
546 }
547
548 STATIC INLINE void FASTCALL ROL8 (long OpAddress)
549 {
550 #ifdef VAR_CYCLES
551     CPU.Cycles += ONE_CYCLE;
552 #endif
553     uint16 Work16 = S9xGetByte (OpAddress);
554     Work16 <<= 1;
555     Work16 |= CheckCarry ();
556     ICPU._Carry = Work16 >= 0x100;
557     S9xSetByte ((uint8) Work16, OpAddress);
558     SETZN8 ((uint8) Work16);
559 }
560
561 STATIC INLINE void FASTCALL A_ROR16 ()
562 {
563 #ifdef VAR_CYCLES
564     CPU.Cycles += ONE_CYCLE;
565 #endif
566     uint32 Work32 = Registers.A.W;
567     Work32 |= (int) CheckCarry() << 16;
568     ICPU._Carry = (uint8) (Work32 & 1);
569     Work32 >>= 1;
570     Registers.A.W = (uint16) Work32;
571     SETZN16 ((uint16) Work32);
572 }
573
574 STATIC INLINE void FASTCALL A_ROR8 ()
575 {
576 #ifdef VAR_CYCLES
577     CPU.Cycles += ONE_CYCLE;
578 #endif
579     uint16 Work16 = Registers.AL | ((uint16) CheckCarry() << 8);
580     ICPU._Carry = (uint8) Work16 & 1;
581     Work16 >>= 1;
582     Registers.AL = (uint8) Work16;
583     SETZN8 ((uint8) Work16);
584 }
585
586 STATIC INLINE void FASTCALL ROR16 (long OpAddress)
587 {
588 #ifdef VAR_CYCLES
589     CPU.Cycles += ONE_CYCLE;
590 #endif
591     uint32 Work32 = S9xGetWord (OpAddress);
592     Work32 |= (int) CheckCarry() << 16;
593     ICPU._Carry = (uint8) (Work32 & 1);
594     Work32 >>= 1;
595     S9xSetWord ((uint16) Work32, OpAddress);
596     SETZN16 ((uint16) Work32);
597 }
598
599 STATIC INLINE void FASTCALL ROR8 (long OpAddress)
600 {
601 #ifdef VAR_CYCLES
602     CPU.Cycles += ONE_CYCLE;
603 #endif
604     uint16 Work16 = S9xGetByte (OpAddress);
605     Work16 |= (int) CheckCarry () << 8;
606     ICPU._Carry = (uint8) (Work16 & 1);
607     Work16 >>= 1;
608     S9xSetByte ((uint8) Work16, OpAddress);
609     SETZN8 ((uint8) Work16);
610 }
611
612 STATIC INLINE void FASTCALL SBC16 (long OpAddress)
613 {
614     uint16 Work16 = S9xGetWord (OpAddress);
615
616     if (CheckDecimal())
617     {
618         uint8 A1 = (Registers.A.W) & 0xF;
619         uint8 A2 = (Registers.A.W >> 4) & 0xF;
620         uint8 A3 = (Registers.A.W >> 8) & 0xF;
621         uint8 A4 = (Registers.A.W >> 12) & 0xF;
622         uint8 W1 = Work16 & 0xF;
623         uint8 W2 = (Work16 >> 4) & 0xF;
624         uint8 W3 = (Work16 >> 8) & 0xF;
625         uint8 W4 = (Work16 >> 12) & 0xF;
626
627         A1 -= W1 + !CheckCarry ();
628         A2 -= W2;
629         A3 -= W3;
630         A4 -= W4;
631         if (A1 > 9)
632         {
633             A1 += 10;
634             A2--;
635         }
636         if (A2 > 9)
637         {
638             A2 += 10;
639             A3--;
640         }
641         if (A3 > 9)
642         {
643             A3 += 10;
644             A4--;
645         }
646         if (A4 > 9)
647         {
648             A4 += 10;
649             ClearCarry ();
650         }
651         else
652         {
653             SetCarry ();
654         }
655
656         uint16 Ans16 = (A4 << 12) | (A3 << 8) | (A2 << 4) | (A1);
657         if ((Registers.A.W ^ Work16) &
658             (Registers.A.W ^ Ans16) & 0x8000)
659             SetOverflow();
660         else
661             ClearOverflow();
662         Registers.A.W = Ans16;
663         SETZN16 (Registers.A.W);
664     }
665     else
666     {
667
668         int32 Int32 = (long) Registers.A.W - (long) Work16 + (long) CheckCarry() - 1;
669
670         ICPU._Carry = Int32 >= 0;
671
672         if ((Registers.A.W ^ Work16) &
673             (Registers.A.W ^ (uint16) Int32) & 0x8000)
674             SetOverflow();
675         else
676             ClearOverflow ();
677         Registers.A.W = (uint16) Int32;
678         SETZN16 (Registers.A.W);
679     }
680 }
681
682 STATIC INLINE void FASTCALL SBC8 (long OpAddress)
683 {
684     uint8 Work8 = S9xGetByte (OpAddress);
685     if (CheckDecimal())
686     {
687         uint8 A1 = (Registers.A.W) & 0xF;
688         uint8 A2 = (Registers.A.W >> 4) & 0xF;
689         uint8 W1 = Work8 & 0xF;
690         uint8 W2 = (Work8 >> 4) & 0xF;
691
692         A1 -= W1 + !CheckCarry ();
693         A2 -= W2;
694         if (A1 > 9)
695         {
696             A1 += 10;
697             A2--;
698         }
699         if (A2 > 9)
700         {
701             A2 += 10;
702             ClearCarry ();
703         }
704         else
705         {
706             SetCarry ();
707         }
708
709         uint8 Ans8 = (A2 << 4) | A1;
710         if ((Registers.AL ^ Work8) &
711             (Registers.AL ^ Ans8) & 0x80)
712             SetOverflow ();
713         else
714             ClearOverflow ();
715         Registers.AL = Ans8;
716         SETZN8 (Registers.AL);
717     }
718     else
719     {
720         int32 Int32 = (short) Registers.AL - (short) Work8 + (short) CheckCarry() - 1;
721
722         ICPU._Carry = Int32 >= 0;
723         if ((Registers.AL ^ Work8) &
724             (Registers.AL ^ (uint8) Int32) & 0x80)
725             SetOverflow ();
726         else
727             ClearOverflow ();
728         Registers.AL = (uint8) Int32;
729         SETZN8 (Registers.AL);
730     }
731 }
732
733 STATIC INLINE void FASTCALL STA16 (long OpAddress)
734 {
735     S9xSetWord (Registers.A.W, OpAddress);
736 }
737
738 STATIC INLINE void FASTCALL STA8 (long OpAddress)
739 {
740     S9xSetByte (Registers.AL, OpAddress);
741 }
742
743 STATIC INLINE void FASTCALL STX16 (long OpAddress)
744 {
745     S9xSetWord (Registers.X.W, OpAddress);
746 }
747
748 STATIC INLINE void FASTCALL STX8 (long OpAddress)
749 {
750     S9xSetByte (Registers.XL, OpAddress);
751 }
752
753 STATIC INLINE void FASTCALL STY16 (long OpAddress)
754 {
755     S9xSetWord (Registers.Y.W, OpAddress);
756 }
757
758 STATIC INLINE void FASTCALL STY8 (long OpAddress)
759 {
760     S9xSetByte (Registers.YL, OpAddress);
761 }
762
763 STATIC INLINE void FASTCALL STZ16 (long OpAddress)
764 {
765     S9xSetWord (0, OpAddress);
766 }
767
768 STATIC INLINE void FASTCALL STZ8 (long OpAddress)
769 {
770     S9xSetByte (0, OpAddress);
771 }
772
773 STATIC INLINE void FASTCALL TSB16 (long OpAddress)
774 {
775 #ifdef VAR_CYCLES
776     CPU.Cycles += ONE_CYCLE;
777 #endif
778     uint16 Work16 = S9xGetWord (OpAddress);
779     ICPU._Zero = (Work16 & Registers.A.W) != 0;
780     Work16 |= Registers.A.W;
781     S9xSetWord (Work16, OpAddress);
782 }
783
784 STATIC INLINE void FASTCALL TSB8 (long OpAddress)
785 {
786 #ifdef VAR_CYCLES
787     CPU.Cycles += ONE_CYCLE;
788 #endif
789     uint8 Work8 = S9xGetByte (OpAddress);
790     ICPU._Zero = Work8 & Registers.AL;
791     Work8 |= Registers.AL;
792     S9xSetByte (Work8, OpAddress);
793 }
794
795 STATIC INLINE void FASTCALL TRB16 (long OpAddress)
796 {
797 #ifdef VAR_CYCLES
798     CPU.Cycles += ONE_CYCLE;
799 #endif
800     uint16 Work16 = S9xGetWord (OpAddress);
801     ICPU._Zero = (Work16 & Registers.A.W) != 0;
802     Work16 &= ~Registers.A.W;
803     S9xSetWord (Work16, OpAddress);
804 }
805
806 STATIC INLINE void FASTCALL TRB8 (long OpAddress)
807 {
808 #ifdef VAR_CYCLES
809     CPU.Cycles += ONE_CYCLE;
810 #endif
811     uint8 Work8 = S9xGetByte (OpAddress);
812     ICPU._Zero = Work8 & Registers.AL;
813     Work8 &= ~Registers.AL;
814     S9xSetByte (Work8, OpAddress);
815 }
816 #endif