Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
RishiRecon
GitHub Repository: RishiRecon/exploits
Path: blob/main/misc/emulator/xnes/snes9x/cpumacro.h
28515 views
1
/***********************************************************************************
2
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3
4
(c) Copyright 1996 - 2002 Gary Henderson ([email protected]),
5
Jerremy Koot ([email protected])
6
7
(c) Copyright 2002 - 2004 Matthew Kendora
8
9
(c) Copyright 2002 - 2005 Peter Bortas ([email protected])
10
11
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
12
13
(c) Copyright 2001 - 2006 John Weidman ([email protected])
14
15
(c) Copyright 2002 - 2006 funkyass ([email protected]),
16
Kris Bleakley ([email protected])
17
18
(c) Copyright 2002 - 2010 Brad Jorsch ([email protected]),
19
Nach ([email protected]),
20
21
(c) Copyright 2002 - 2011 zones ([email protected])
22
23
(c) Copyright 2006 - 2007 nitsuja
24
25
(c) Copyright 2009 - 2011 BearOso,
26
OV2
27
28
29
BS-X C emulator code
30
(c) Copyright 2005 - 2006 Dreamer Nom,
31
zones
32
33
C4 x86 assembler and some C emulation code
34
(c) Copyright 2000 - 2003 _Demo_ ([email protected]),
35
Nach,
36
zsKnight ([email protected])
37
38
C4 C++ code
39
(c) Copyright 2003 - 2006 Brad Jorsch,
40
Nach
41
42
DSP-1 emulator code
43
(c) Copyright 1998 - 2006 _Demo_,
44
Andreas Naive ([email protected]),
45
Gary Henderson,
46
Ivar ([email protected]),
47
John Weidman,
48
Kris Bleakley,
49
Matthew Kendora,
50
Nach,
51
neviksti ([email protected])
52
53
DSP-2 emulator code
54
(c) Copyright 2003 John Weidman,
55
Kris Bleakley,
56
Lord Nightmare ([email protected]),
57
Matthew Kendora,
58
neviksti
59
60
DSP-3 emulator code
61
(c) Copyright 2003 - 2006 John Weidman,
62
Kris Bleakley,
63
Lancer,
64
z80 gaiden
65
66
DSP-4 emulator code
67
(c) Copyright 2004 - 2006 Dreamer Nom,
68
John Weidman,
69
Kris Bleakley,
70
Nach,
71
z80 gaiden
72
73
OBC1 emulator code
74
(c) Copyright 2001 - 2004 zsKnight,
75
pagefault ([email protected]),
76
Kris Bleakley
77
Ported from x86 assembler to C by sanmaiwashi
78
79
SPC7110 and RTC C++ emulator code used in 1.39-1.51
80
(c) Copyright 2002 Matthew Kendora with research by
81
zsKnight,
82
John Weidman,
83
Dark Force
84
85
SPC7110 and RTC C++ emulator code used in 1.52+
86
(c) Copyright 2009 byuu,
87
neviksti
88
89
S-DD1 C emulator code
90
(c) Copyright 2003 Brad Jorsch with research by
91
Andreas Naive,
92
John Weidman
93
94
S-RTC C emulator code
95
(c) Copyright 2001 - 2006 byuu,
96
John Weidman
97
98
ST010 C++ emulator code
99
(c) Copyright 2003 Feather,
100
John Weidman,
101
Kris Bleakley,
102
Matthew Kendora
103
104
Super FX x86 assembler emulator code
105
(c) Copyright 1998 - 2003 _Demo_,
106
pagefault,
107
zsKnight
108
109
Super FX C emulator code
110
(c) Copyright 1997 - 1999 Ivar,
111
Gary Henderson,
112
John Weidman
113
114
Sound emulator code used in 1.5-1.51
115
(c) Copyright 1998 - 2003 Brad Martin
116
(c) Copyright 1998 - 2006 Charles Bilyue'
117
118
Sound emulator code used in 1.52+
119
(c) Copyright 2004 - 2007 Shay Green ([email protected])
120
121
SH assembler code partly based on x86 assembler code
122
(c) Copyright 2002 - 2004 Marcus Comstedt ([email protected])
123
124
2xSaI filter
125
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
126
127
HQ2x, HQ3x, HQ4x filters
128
(c) Copyright 2003 Maxim Stepin ([email protected])
129
130
NTSC filter
131
(c) Copyright 2006 - 2007 Shay Green
132
133
GTK+ GUI code
134
(c) Copyright 2004 - 2011 BearOso
135
136
Win32 GUI code
137
(c) Copyright 2003 - 2006 blip,
138
funkyass,
139
Matthew Kendora,
140
Nach,
141
nitsuja
142
(c) Copyright 2009 - 2011 OV2
143
144
Mac OS GUI code
145
(c) Copyright 1998 - 2001 John Stiles
146
(c) Copyright 2001 - 2011 zones
147
148
149
Specific ports contains the works of other authors. See headers in
150
individual files.
151
152
153
Snes9x homepage: http://www.snes9x.com/
154
155
Permission to use, copy, modify and/or distribute Snes9x in both binary
156
and source form, for non-commercial purposes, is hereby granted without
157
fee, providing that this license information and copyright notice appear
158
with all copies and any derived work.
159
160
This software is provided 'as-is', without any express or implied
161
warranty. In no event shall the authors be held liable for any damages
162
arising from the use of this software or it's derivatives.
163
164
Snes9x is freeware for PERSONAL USE only. Commercial users should
165
seek permission of the copyright holders first. Commercial use includes,
166
but is not limited to, charging money for Snes9x or software derived from
167
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
168
using Snes9x as a promotion for your commercial product.
169
170
The copyright holders request that bug fixes and improvements to the code
171
should be forwarded to them so everyone can benefit from the modifications
172
in future versions.
173
174
Super NES and Super Nintendo Entertainment System are trademarks of
175
Nintendo Co., Limited and its subsidiary companies.
176
***********************************************************************************/
177
178
179
#ifndef _CPUMACRO_H_
180
#define _CPUMACRO_H_
181
182
#define rOP8(OP, ADDR, WRAP, FUNC) \
183
static void Op##OP (void) \
184
{ \
185
uint8 val = OpenBus = S9xGetByte(ADDR(READ)); \
186
FUNC(val); \
187
}
188
189
#define rOP16(OP, ADDR, WRAP, FUNC) \
190
static void Op##OP (void) \
191
{ \
192
uint16 val = S9xGetWord(ADDR(READ), WRAP); \
193
OpenBus = (uint8) (val >> 8); \
194
FUNC(val); \
195
}
196
197
#define rOPC(OP, COND, ADDR, WRAP, FUNC) \
198
static void Op##OP (void) \
199
{ \
200
if (Check##COND()) \
201
{ \
202
uint8 val = OpenBus = S9xGetByte(ADDR(READ)); \
203
FUNC(val); \
204
} \
205
else \
206
{ \
207
uint16 val = S9xGetWord(ADDR(READ), WRAP); \
208
OpenBus = (uint8) (val >> 8); \
209
FUNC(val); \
210
} \
211
}
212
213
#define rOPM(OP, ADDR, WRAP, FUNC) \
214
rOPC(OP, Memory, ADDR, WRAP, FUNC)
215
216
#define rOPX(OP, ADDR, WRAP, FUNC) \
217
rOPC(OP, Index, ADDR, WRAP, FUNC)
218
219
#define wOP8(OP, ADDR, WRAP, FUNC) \
220
static void Op##OP (void) \
221
{ \
222
FUNC##8(ADDR(WRITE)); \
223
}
224
225
#define wOP16(OP, ADDR, WRAP, FUNC) \
226
static void Op##OP (void) \
227
{ \
228
FUNC##16(ADDR(WRITE), WRAP); \
229
}
230
231
#define wOPC(OP, COND, ADDR, WRAP, FUNC) \
232
static void Op##OP (void) \
233
{ \
234
if (Check##COND()) \
235
FUNC##8(ADDR(WRITE)); \
236
else \
237
FUNC##16(ADDR(WRITE), WRAP); \
238
}
239
240
#define wOPM(OP, ADDR, WRAP, FUNC) \
241
wOPC(OP, Memory, ADDR, WRAP, FUNC)
242
243
#define wOPX(OP, ADDR, WRAP, FUNC) \
244
wOPC(OP, Index, ADDR, WRAP, FUNC)
245
246
#define mOP8(OP, ADDR, WRAP, FUNC) \
247
static void Op##OP (void) \
248
{ \
249
FUNC##8(ADDR(MODIFY)); \
250
}
251
252
#define mOP16(OP, ADDR, WRAP, FUNC) \
253
static void Op##OP (void) \
254
{ \
255
FUNC##16(ADDR(MODIFY), WRAP); \
256
}
257
258
#define mOPC(OP, COND, ADDR, WRAP, FUNC) \
259
static void Op##OP (void) \
260
{ \
261
if (Check##COND()) \
262
FUNC##8(ADDR(MODIFY)); \
263
else \
264
FUNC##16(ADDR(MODIFY), WRAP); \
265
}
266
267
#define mOPM(OP, ADDR, WRAP, FUNC) \
268
mOPC(OP, Memory, ADDR, WRAP, FUNC)
269
270
#define bOP(OP, REL, COND, CHK, E) \
271
static void Op##OP (void) \
272
{ \
273
pair newPC; \
274
newPC.W = REL(JUMP); \
275
if (COND) \
276
{ \
277
AddCycles(ONE_CYCLE); \
278
if (E && Registers.PCh != newPC.B.h) \
279
AddCycles(ONE_CYCLE); \
280
if ((Registers.PCw & ~MEMMAP_MASK) != (newPC.W & ~MEMMAP_MASK)) \
281
S9xSetPCBase(ICPU.ShiftedPB + newPC.W); \
282
else \
283
Registers.PCw = newPC.W; \
284
} \
285
}
286
287
288
static inline void SetZN (uint16 Work16)
289
{
290
ICPU._Zero = Work16 != 0;
291
ICPU._Negative = (uint8) (Work16 >> 8);
292
}
293
294
static inline void SetZN (uint8 Work8)
295
{
296
ICPU._Zero = Work8;
297
ICPU._Negative = Work8;
298
}
299
300
static inline void ADC (uint16 Work16)
301
{
302
if (CheckDecimal())
303
{
304
uint16 A1 = Registers.A.W & 0x000F;
305
uint16 A2 = Registers.A.W & 0x00F0;
306
uint16 A3 = Registers.A.W & 0x0F00;
307
uint32 A4 = Registers.A.W & 0xF000;
308
uint16 W1 = Work16 & 0x000F;
309
uint16 W2 = Work16 & 0x00F0;
310
uint16 W3 = Work16 & 0x0F00;
311
uint16 W4 = Work16 & 0xF000;
312
313
A1 += W1 + CheckCarry();
314
if (A1 > 0x0009)
315
{
316
A1 -= 0x000A;
317
A1 &= 0x000F;
318
A2 += 0x0010;
319
}
320
321
A2 += W2;
322
if (A2 > 0x0090)
323
{
324
A2 -= 0x00A0;
325
A2 &= 0x00F0;
326
A3 += 0x0100;
327
}
328
329
A3 += W3;
330
if (A3 > 0x0900)
331
{
332
A3 -= 0x0A00;
333
A3 &= 0x0F00;
334
A4 += 0x1000;
335
}
336
337
A4 += W4;
338
if (A4 > 0x9000)
339
{
340
A4 -= 0xA000;
341
A4 &= 0xF000;
342
SetCarry();
343
}
344
else
345
ClearCarry();
346
347
uint16 Ans16 = A4 | A3 | A2 | A1;
348
349
if (~(Registers.A.W ^ Work16) & (Work16 ^ Ans16) & 0x8000)
350
SetOverflow();
351
else
352
ClearOverflow();
353
354
Registers.A.W = Ans16;
355
SetZN(Registers.A.W);
356
}
357
else
358
{
359
uint32 Ans32 = Registers.A.W + Work16 + CheckCarry();
360
361
ICPU._Carry = Ans32 >= 0x10000;
362
363
if (~(Registers.A.W ^ Work16) & (Work16 ^ (uint16) Ans32) & 0x8000)
364
SetOverflow();
365
else
366
ClearOverflow();
367
368
Registers.A.W = (uint16) Ans32;
369
SetZN(Registers.A.W);
370
}
371
}
372
373
static inline void ADC (uint8 Work8)
374
{
375
if (CheckDecimal())
376
{
377
uint8 A1 = Registers.A.W & 0x0F;
378
uint16 A2 = Registers.A.W & 0xF0;
379
uint8 W1 = Work8 & 0x0F;
380
uint8 W2 = Work8 & 0xF0;
381
382
A1 += W1 + CheckCarry();
383
if (A1 > 0x09)
384
{
385
A1 -= 0x0A;
386
A1 &= 0x0F;
387
A2 += 0x10;
388
}
389
390
A2 += W2;
391
if (A2 > 0x90)
392
{
393
A2 -= 0xA0;
394
A2 &= 0xF0;
395
SetCarry();
396
}
397
else
398
ClearCarry();
399
400
uint8 Ans8 = A2 | A1;
401
402
if (~(Registers.AL ^ Work8) & (Work8 ^ Ans8) & 0x80)
403
SetOverflow();
404
else
405
ClearOverflow();
406
407
Registers.AL = Ans8;
408
SetZN(Registers.AL);
409
}
410
else
411
{
412
uint16 Ans16 = Registers.AL + Work8 + CheckCarry();
413
414
ICPU._Carry = Ans16 >= 0x100;
415
416
if (~(Registers.AL ^ Work8) & (Work8 ^ (uint8) Ans16) & 0x80)
417
SetOverflow();
418
else
419
ClearOverflow();
420
421
Registers.AL = (uint8) Ans16;
422
SetZN(Registers.AL);
423
}
424
}
425
426
static inline void AND (uint16 Work16)
427
{
428
Registers.A.W &= Work16;
429
SetZN(Registers.A.W);
430
}
431
432
static inline void AND (uint8 Work8)
433
{
434
Registers.AL &= Work8;
435
SetZN(Registers.AL);
436
}
437
438
static inline void ASL16 (uint32 OpAddress, s9xwrap_t w)
439
{
440
uint16 Work16 = S9xGetWord(OpAddress, w);
441
ICPU._Carry = (Work16 & 0x8000) != 0;
442
Work16 <<= 1;
443
AddCycles(ONE_CYCLE);
444
S9xSetWord(Work16, OpAddress, w, WRITE_10);
445
OpenBus = Work16 & 0xff;
446
SetZN(Work16);
447
}
448
449
static inline void ASL8 (uint32 OpAddress)
450
{
451
uint8 Work8 = S9xGetByte(OpAddress);
452
ICPU._Carry = (Work8 & 0x80) != 0;
453
Work8 <<= 1;
454
AddCycles(ONE_CYCLE);
455
S9xSetByte(Work8, OpAddress);
456
OpenBus = Work8;
457
SetZN(Work8);
458
}
459
460
static inline void BIT (uint16 Work16)
461
{
462
ICPU._Overflow = (Work16 & 0x4000) != 0;
463
ICPU._Negative = (uint8) (Work16 >> 8);
464
ICPU._Zero = (Work16 & Registers.A.W) != 0;
465
}
466
467
static inline void BIT (uint8 Work8)
468
{
469
ICPU._Overflow = (Work8 & 0x40) != 0;
470
ICPU._Negative = Work8;
471
ICPU._Zero = Work8 & Registers.AL;
472
}
473
474
static inline void CMP (uint16 val)
475
{
476
int32 Int32 = (int32) Registers.A.W - (int32) val;
477
ICPU._Carry = Int32 >= 0;
478
SetZN((uint16) Int32);
479
}
480
481
static inline void CMP (uint8 val)
482
{
483
int16 Int16 = (int16) Registers.AL - (int16) val;
484
ICPU._Carry = Int16 >= 0;
485
SetZN((uint8) Int16);
486
}
487
488
static inline void CPX (uint16 val)
489
{
490
int32 Int32 = (int32) Registers.X.W - (int32) val;
491
ICPU._Carry = Int32 >= 0;
492
SetZN((uint16) Int32);
493
}
494
495
static inline void CPX (uint8 val)
496
{
497
int16 Int16 = (int16) Registers.XL - (int16) val;
498
ICPU._Carry = Int16 >= 0;
499
SetZN((uint8) Int16);
500
}
501
502
static inline void CPY (uint16 val)
503
{
504
int32 Int32 = (int32) Registers.Y.W - (int32) val;
505
ICPU._Carry = Int32 >= 0;
506
SetZN((uint16) Int32);
507
}
508
509
static inline void CPY (uint8 val)
510
{
511
int16 Int16 = (int16) Registers.YL - (int16) val;
512
ICPU._Carry = Int16 >= 0;
513
SetZN((uint8) Int16);
514
}
515
516
static inline void DEC16 (uint32 OpAddress, s9xwrap_t w)
517
{
518
uint16 Work16 = S9xGetWord(OpAddress, w) - 1;
519
AddCycles(ONE_CYCLE);
520
S9xSetWord(Work16, OpAddress, w, WRITE_10);
521
OpenBus = Work16 & 0xff;
522
SetZN(Work16);
523
}
524
525
static inline void DEC8 (uint32 OpAddress)
526
{
527
uint8 Work8 = S9xGetByte(OpAddress) - 1;
528
AddCycles(ONE_CYCLE);
529
S9xSetByte(Work8, OpAddress);
530
OpenBus = Work8;
531
SetZN(Work8);
532
}
533
534
static inline void EOR (uint16 val)
535
{
536
Registers.A.W ^= val;
537
SetZN(Registers.A.W);
538
}
539
540
static inline void EOR (uint8 val)
541
{
542
Registers.AL ^= val;
543
SetZN(Registers.AL);
544
}
545
546
static inline void INC16 (uint32 OpAddress, s9xwrap_t w)
547
{
548
uint16 Work16 = S9xGetWord(OpAddress, w) + 1;
549
AddCycles(ONE_CYCLE);
550
S9xSetWord(Work16, OpAddress, w, WRITE_10);
551
OpenBus = Work16 & 0xff;
552
SetZN(Work16);
553
}
554
555
static inline void INC8 (uint32 OpAddress)
556
{
557
uint8 Work8 = S9xGetByte(OpAddress) + 1;
558
AddCycles(ONE_CYCLE);
559
S9xSetByte(Work8, OpAddress);
560
OpenBus = Work8;
561
SetZN(Work8);
562
}
563
564
static inline void LDA (uint16 val)
565
{
566
Registers.A.W = val;
567
SetZN(Registers.A.W);
568
}
569
570
static inline void LDA (uint8 val)
571
{
572
Registers.AL = val;
573
SetZN(Registers.AL);
574
}
575
576
static inline void LDX (uint16 val)
577
{
578
Registers.X.W = val;
579
SetZN(Registers.X.W);
580
}
581
582
static inline void LDX (uint8 val)
583
{
584
Registers.XL = val;
585
SetZN(Registers.XL);
586
}
587
588
static inline void LDY (uint16 val)
589
{
590
Registers.Y.W = val;
591
SetZN(Registers.Y.W);
592
}
593
594
static inline void LDY (uint8 val)
595
{
596
Registers.YL = val;
597
SetZN(Registers.YL);
598
}
599
600
static inline void LSR16 (uint32 OpAddress, s9xwrap_t w)
601
{
602
uint16 Work16 = S9xGetWord(OpAddress, w);
603
ICPU._Carry = Work16 & 1;
604
Work16 >>= 1;
605
AddCycles(ONE_CYCLE);
606
S9xSetWord(Work16, OpAddress, w, WRITE_10);
607
OpenBus = Work16 & 0xff;
608
SetZN(Work16);
609
}
610
611
static inline void LSR8 (uint32 OpAddress)
612
{
613
uint8 Work8 = S9xGetByte(OpAddress);
614
ICPU._Carry = Work8 & 1;
615
Work8 >>= 1;
616
AddCycles(ONE_CYCLE);
617
S9xSetByte(Work8, OpAddress);
618
OpenBus = Work8;
619
SetZN(Work8);
620
}
621
622
static inline void ORA (uint16 val)
623
{
624
Registers.A.W |= val;
625
SetZN(Registers.A.W);
626
}
627
628
static inline void ORA (uint8 val)
629
{
630
Registers.AL |= val;
631
SetZN(Registers.AL);
632
}
633
634
static inline void ROL16 (uint32 OpAddress, s9xwrap_t w)
635
{
636
uint32 Work32 = (((uint32) S9xGetWord(OpAddress, w)) << 1) | CheckCarry();
637
ICPU._Carry = Work32 >= 0x10000;
638
AddCycles(ONE_CYCLE);
639
S9xSetWord((uint16) Work32, OpAddress, w, WRITE_10);
640
OpenBus = Work32 & 0xff;
641
SetZN((uint16) Work32);
642
}
643
644
static inline void ROL8 (uint32 OpAddress)
645
{
646
uint16 Work16 = (((uint16) S9xGetByte(OpAddress)) << 1) | CheckCarry();
647
ICPU._Carry = Work16 >= 0x100;
648
AddCycles(ONE_CYCLE);
649
S9xSetByte((uint8) Work16, OpAddress);
650
OpenBus = Work16 & 0xff;
651
SetZN((uint8) Work16);
652
}
653
654
static inline void ROR16 (uint32 OpAddress, s9xwrap_t w)
655
{
656
uint32 Work32 = ((uint32) S9xGetWord(OpAddress, w)) | (((uint32) CheckCarry()) << 16);
657
ICPU._Carry = Work32 & 1;
658
Work32 >>= 1;
659
AddCycles(ONE_CYCLE);
660
S9xSetWord((uint16) Work32, OpAddress, w, WRITE_10);
661
OpenBus = Work32 & 0xff;
662
SetZN((uint16) Work32);
663
}
664
665
static inline void ROR8 (uint32 OpAddress)
666
{
667
uint16 Work16 = ((uint16) S9xGetByte(OpAddress)) | (((uint16) CheckCarry()) << 8);
668
ICPU._Carry = Work16 & 1;
669
Work16 >>= 1;
670
AddCycles(ONE_CYCLE);
671
S9xSetByte((uint8) Work16, OpAddress);
672
OpenBus = Work16 & 0xff;
673
SetZN((uint8) Work16);
674
}
675
676
static inline void SBC (uint16 Work16)
677
{
678
if (CheckDecimal())
679
{
680
uint16 A1 = Registers.A.W & 0x000F;
681
uint16 A2 = Registers.A.W & 0x00F0;
682
uint16 A3 = Registers.A.W & 0x0F00;
683
uint32 A4 = Registers.A.W & 0xF000;
684
uint16 W1 = Work16 & 0x000F;
685
uint16 W2 = Work16 & 0x00F0;
686
uint16 W3 = Work16 & 0x0F00;
687
uint16 W4 = Work16 & 0xF000;
688
689
A1 -= W1 + !CheckCarry();
690
A2 -= W2;
691
A3 -= W3;
692
A4 -= W4;
693
694
if (A1 > 0x000F)
695
{
696
A1 += 0x000A;
697
A1 &= 0x000F;
698
A2 -= 0x0010;
699
}
700
701
if (A2 > 0x00F0)
702
{
703
A2 += 0x00A0;
704
A2 &= 0x00F0;
705
A3 -= 0x0100;
706
}
707
708
if (A3 > 0x0F00)
709
{
710
A3 += 0x0A00;
711
A3 &= 0x0F00;
712
A4 -= 0x1000;
713
}
714
715
if (A4 > 0xF000)
716
{
717
A4 += 0xA000;
718
A4 &= 0xF000;
719
ClearCarry();
720
}
721
else
722
SetCarry();
723
724
uint16 Ans16 = A4 | A3 | A2 | A1;
725
726
if ((Registers.A.W ^ Work16) & (Registers.A.W ^ Ans16) & 0x8000)
727
SetOverflow();
728
else
729
ClearOverflow();
730
731
Registers.A.W = Ans16;
732
SetZN(Registers.A.W);
733
}
734
else
735
{
736
int32 Int32 = (int32) Registers.A.W - (int32) Work16 + (int32) CheckCarry() - 1;
737
738
ICPU._Carry = Int32 >= 0;
739
740
if ((Registers.A.W ^ Work16) & (Registers.A.W ^ (uint16) Int32) & 0x8000)
741
SetOverflow();
742
else
743
ClearOverflow();
744
745
Registers.A.W = (uint16) Int32;
746
SetZN(Registers.A.W);
747
}
748
}
749
750
static inline void SBC (uint8 Work8)
751
{
752
if (CheckDecimal())
753
{
754
uint8 A1 = Registers.A.W & 0x0F;
755
uint16 A2 = Registers.A.W & 0xF0;
756
uint8 W1 = Work8 & 0x0F;
757
uint8 W2 = Work8 & 0xF0;
758
759
A1 -= W1 + !CheckCarry();
760
A2 -= W2;
761
762
if (A1 > 0x0F)
763
{
764
A1 += 0x0A;
765
A1 &= 0x0F;
766
A2 -= 0x10;
767
}
768
769
if (A2 > 0xF0)
770
{
771
A2 += 0xA0;
772
A2 &= 0xF0;
773
ClearCarry();
774
}
775
else
776
SetCarry();
777
778
uint8 Ans8 = A2 | A1;
779
780
if ((Registers.AL ^ Work8) & (Registers.AL ^ Ans8) & 0x80)
781
SetOverflow();
782
else
783
ClearOverflow();
784
785
Registers.AL = Ans8;
786
SetZN(Registers.AL);
787
}
788
else
789
{
790
int16 Int16 = (int16) Registers.AL - (int16) Work8 + (int16) CheckCarry() - 1;
791
792
ICPU._Carry = Int16 >= 0;
793
794
if ((Registers.AL ^ Work8) & (Registers.AL ^ (uint8) Int16) & 0x80)
795
SetOverflow();
796
else
797
ClearOverflow();
798
799
Registers.AL = (uint8) Int16;
800
SetZN(Registers.AL);
801
}
802
}
803
804
static inline void STA16 (uint32 OpAddress, enum s9xwrap_t w)
805
{
806
S9xSetWord(Registers.A.W, OpAddress, w);
807
OpenBus = Registers.AH;
808
}
809
810
static inline void STA8 (uint32 OpAddress)
811
{
812
S9xSetByte(Registers.AL, OpAddress);
813
OpenBus = Registers.AL;
814
}
815
816
static inline void STX16 (uint32 OpAddress, enum s9xwrap_t w)
817
{
818
S9xSetWord(Registers.X.W, OpAddress, w);
819
OpenBus = Registers.XH;
820
}
821
822
static inline void STX8 (uint32 OpAddress)
823
{
824
S9xSetByte(Registers.XL, OpAddress);
825
OpenBus = Registers.XL;
826
}
827
828
static inline void STY16 (uint32 OpAddress, enum s9xwrap_t w)
829
{
830
S9xSetWord(Registers.Y.W, OpAddress, w);
831
OpenBus = Registers.YH;
832
}
833
834
static inline void STY8 (uint32 OpAddress)
835
{
836
S9xSetByte(Registers.YL, OpAddress);
837
OpenBus = Registers.YL;
838
}
839
840
static inline void STZ16 (uint32 OpAddress, enum s9xwrap_t w)
841
{
842
S9xSetWord(0, OpAddress, w);
843
OpenBus = 0;
844
}
845
846
static inline void STZ8 (uint32 OpAddress)
847
{
848
S9xSetByte(0, OpAddress);
849
OpenBus = 0;
850
}
851
852
static inline void TSB16 (uint32 OpAddress, enum s9xwrap_t w)
853
{
854
uint16 Work16 = S9xGetWord(OpAddress, w);
855
ICPU._Zero = (Work16 & Registers.A.W) != 0;
856
Work16 |= Registers.A.W;
857
AddCycles(ONE_CYCLE);
858
S9xSetWord(Work16, OpAddress, w, WRITE_10);
859
OpenBus = Work16 & 0xff;
860
}
861
862
static inline void TSB8 (uint32 OpAddress)
863
{
864
uint8 Work8 = S9xGetByte(OpAddress);
865
ICPU._Zero = Work8 & Registers.AL;
866
Work8 |= Registers.AL;
867
AddCycles(ONE_CYCLE);
868
S9xSetByte(Work8, OpAddress);
869
OpenBus = Work8;
870
}
871
872
static inline void TRB16 (uint32 OpAddress, enum s9xwrap_t w)
873
{
874
uint16 Work16 = S9xGetWord(OpAddress, w);
875
ICPU._Zero = (Work16 & Registers.A.W) != 0;
876
Work16 &= ~Registers.A.W;
877
AddCycles(ONE_CYCLE);
878
S9xSetWord(Work16, OpAddress, w, WRITE_10);
879
OpenBus = Work16 & 0xff;
880
}
881
882
static inline void TRB8 (uint32 OpAddress)
883
{
884
uint8 Work8 = S9xGetByte(OpAddress);
885
ICPU._Zero = Work8 & Registers.AL;
886
Work8 &= ~Registers.AL;
887
AddCycles(ONE_CYCLE);
888
S9xSetByte(Work8, OpAddress);
889
OpenBus = Work8;
890
}
891
892
#endif
893
894