Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
RishiRecon
GitHub Repository: RishiRecon/exploits
Path: blob/main/misc/emulator/xnes/snes9x/cpuaddr.h
28550 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 _CPUADDR_H_
180
#define _CPUADDR_H_
181
182
typedef enum
183
{
184
NONE = 0,
185
READ = 1,
186
WRITE = 2,
187
MODIFY = 3,
188
JUMP = 5,
189
JSR = 8
190
} AccessMode;
191
192
static inline uint8 Immediate8Slow (AccessMode a)
193
{
194
uint8 val = S9xGetByte(Registers.PBPC);
195
if (a & READ)
196
OpenBus = val;
197
Registers.PCw++;
198
199
return (val);
200
}
201
202
static inline uint8 Immediate8 (AccessMode a)
203
{
204
uint8 val = CPU.PCBase[Registers.PCw];
205
if (a & READ)
206
OpenBus = val;
207
AddCycles(CPU.MemSpeed);
208
Registers.PCw++;
209
210
return (val);
211
}
212
213
static inline uint16 Immediate16Slow (AccessMode a)
214
{
215
uint16 val = S9xGetWord(Registers.PBPC, WRAP_BANK);
216
if (a & READ)
217
OpenBus = (uint8) (val >> 8);
218
Registers.PCw += 2;
219
220
return (val);
221
}
222
223
static inline uint16 Immediate16 (AccessMode a)
224
{
225
uint16 val = READ_WORD(CPU.PCBase + Registers.PCw);
226
if (a & READ)
227
OpenBus = (uint8) (val >> 8);
228
AddCycles(CPU.MemSpeedx2);
229
Registers.PCw += 2;
230
231
return (val);
232
}
233
234
static inline uint32 RelativeSlow (AccessMode a) // branch $xx
235
{
236
int8 offset = Immediate8Slow(a);
237
238
return ((int16) Registers.PCw + offset) & 0xffff;
239
}
240
241
static inline uint32 Relative (AccessMode a) // branch $xx
242
{
243
int8 offset = Immediate8(a);
244
245
return ((int16) Registers.PCw + offset) & 0xffff;
246
}
247
248
static inline uint32 RelativeLongSlow (AccessMode a) // BRL $xxxx
249
{
250
int16 offset = Immediate16Slow(a);
251
252
return ((int32) Registers.PCw + offset) & 0xffff;
253
}
254
255
static inline uint32 RelativeLong (AccessMode a) // BRL $xxxx
256
{
257
int16 offset = Immediate16(a);
258
259
return ((int32) Registers.PCw + offset) & 0xffff;
260
}
261
262
static inline uint32 AbsoluteIndexedIndirectSlow (AccessMode a) // (a,X)
263
{
264
uint16 addr;
265
266
if (a & JSR)
267
{
268
// JSR (a,X) pushes the old address in the middle of loading the new.
269
// OpenBus needs to be set to account for this.
270
addr = Immediate8Slow(READ);
271
if (a == JSR)
272
OpenBus = Registers.PCl;
273
addr |= Immediate8Slow(READ) << 8;
274
}
275
else
276
addr = Immediate16Slow(READ);
277
278
AddCycles(ONE_CYCLE);
279
addr += Registers.X.W;
280
281
// Address load wraps within the bank
282
uint16 addr2 = S9xGetWord(ICPU.ShiftedPB | addr, WRAP_BANK);
283
OpenBus = addr2 >> 8;
284
285
return (addr2);
286
}
287
288
static inline uint32 AbsoluteIndexedIndirect (AccessMode a) // (a,X)
289
{
290
uint16 addr = Immediate16Slow(READ);
291
addr += Registers.X.W;
292
293
// Address load wraps within the bank
294
uint16 addr2 = S9xGetWord(ICPU.ShiftedPB | addr, WRAP_BANK);
295
OpenBus = addr2 >> 8;
296
297
return (addr2);
298
}
299
300
static inline uint32 AbsoluteIndirectLongSlow (AccessMode a) // [a]
301
{
302
uint16 addr = Immediate16Slow(READ);
303
304
// No info on wrapping, but it doesn't matter anyway due to mirroring
305
uint32 addr2 = S9xGetWord(addr);
306
OpenBus = addr2 >> 8;
307
addr2 |= (OpenBus = S9xGetByte(addr + 2)) << 16;
308
309
return (addr2);
310
}
311
312
static inline uint32 AbsoluteIndirectLong (AccessMode a) // [a]
313
{
314
uint16 addr = Immediate16(READ);
315
316
// No info on wrapping, but it doesn't matter anyway due to mirroring
317
uint32 addr2 = S9xGetWord(addr);
318
OpenBus = addr2 >> 8;
319
addr2 |= (OpenBus = S9xGetByte(addr + 2)) << 16;
320
321
return (addr2);
322
}
323
324
static inline uint32 AbsoluteIndirectSlow (AccessMode a) // (a)
325
{
326
// No info on wrapping, but it doesn't matter anyway due to mirroring
327
uint16 addr2 = S9xGetWord(Immediate16Slow(READ));
328
OpenBus = addr2 >> 8;
329
330
return (addr2);
331
}
332
333
static inline uint32 AbsoluteIndirect (AccessMode a) // (a)
334
{
335
// No info on wrapping, but it doesn't matter anyway due to mirroring
336
uint16 addr2 = S9xGetWord(Immediate16(READ));
337
OpenBus = addr2 >> 8;
338
339
return (addr2);
340
}
341
342
static inline uint32 AbsoluteSlow (AccessMode a) // a
343
{
344
return (ICPU.ShiftedDB | Immediate16Slow(a));
345
}
346
347
static inline uint32 Absolute (AccessMode a) // a
348
{
349
return (ICPU.ShiftedDB | Immediate16(a));
350
}
351
352
static inline uint32 AbsoluteLongSlow (AccessMode a) // l
353
{
354
uint32 addr = Immediate16Slow(READ);
355
356
// JSR l pushes the old bank in the middle of loading the new.
357
// OpenBus needs to be set to account for this.
358
if (a == JSR)
359
OpenBus = Registers.PB;
360
361
addr |= Immediate8Slow(a) << 16;
362
363
return (addr);
364
}
365
366
static inline uint32 AbsoluteLong (AccessMode a) // l
367
{
368
uint32 addr = READ_3WORD(CPU.PCBase + Registers.PCw);
369
AddCycles(CPU.MemSpeedx2 + CPU.MemSpeed);
370
if (a & READ)
371
OpenBus = addr >> 16;
372
Registers.PCw += 3;
373
374
return (addr);
375
}
376
377
static inline uint32 DirectSlow (AccessMode a) // d
378
{
379
uint16 addr = Immediate8Slow(a) + Registers.D.W;
380
if (Registers.DL != 0)
381
AddCycles(ONE_CYCLE);
382
383
return (addr);
384
}
385
386
static inline uint32 Direct (AccessMode a) // d
387
{
388
uint16 addr = Immediate8(a) + Registers.D.W;
389
if (Registers.DL != 0)
390
AddCycles(ONE_CYCLE);
391
392
return (addr);
393
}
394
395
static inline uint32 DirectIndirectSlow (AccessMode a) // (d)
396
{
397
uint32 addr = S9xGetWord(DirectSlow(READ), (!CheckEmulation() || Registers.DL) ? WRAP_BANK : WRAP_PAGE);
398
if (a & READ)
399
OpenBus = (uint8) (addr >> 8);
400
addr |= ICPU.ShiftedDB;
401
402
return (addr);
403
}
404
405
static inline uint32 DirectIndirectE0 (AccessMode a) // (d)
406
{
407
uint32 addr = S9xGetWord(Direct(READ));
408
if (a & READ)
409
OpenBus = (uint8) (addr >> 8);
410
addr |= ICPU.ShiftedDB;
411
412
return (addr);
413
}
414
415
static inline uint32 DirectIndirectE1 (AccessMode a) // (d)
416
{
417
uint32 addr = S9xGetWord(DirectSlow(READ), Registers.DL ? WRAP_BANK : WRAP_PAGE);
418
if (a & READ)
419
OpenBus = (uint8) (addr >> 8);
420
addr |= ICPU.ShiftedDB;
421
422
return (addr);
423
}
424
425
static inline uint32 DirectIndirectIndexedSlow (AccessMode a) // (d),Y
426
{
427
uint32 addr = DirectIndirectSlow(a);
428
if (a & WRITE || !CheckIndex() || (addr & 0xff) + Registers.YL >= 0x100)
429
AddCycles(ONE_CYCLE);
430
431
return (addr + Registers.Y.W);
432
}
433
434
static inline uint32 DirectIndirectIndexedE0X0 (AccessMode a) // (d),Y
435
{
436
uint32 addr = DirectIndirectE0(a);
437
AddCycles(ONE_CYCLE);
438
439
return (addr + Registers.Y.W);
440
}
441
442
static inline uint32 DirectIndirectIndexedE0X1 (AccessMode a) // (d),Y
443
{
444
uint32 addr = DirectIndirectE0(a);
445
if (a & WRITE || (addr & 0xff) + Registers.YL >= 0x100)
446
AddCycles(ONE_CYCLE);
447
448
return (addr + Registers.Y.W);
449
}
450
451
static inline uint32 DirectIndirectIndexedE1 (AccessMode a) // (d),Y
452
{
453
uint32 addr = DirectIndirectE1(a);
454
if (a & WRITE || (addr & 0xff) + Registers.YL >= 0x100)
455
AddCycles(ONE_CYCLE);
456
457
return (addr + Registers.Y.W);
458
}
459
460
static inline uint32 DirectIndirectLongSlow (AccessMode a) // [d]
461
{
462
uint16 addr = DirectSlow(READ);
463
uint32 addr2 = S9xGetWord(addr);
464
OpenBus = addr2 >> 8;
465
addr2 |= (OpenBus = S9xGetByte(addr + 2)) << 16;
466
467
return (addr2);
468
}
469
470
static inline uint32 DirectIndirectLong (AccessMode a) // [d]
471
{
472
uint16 addr = Direct(READ);
473
uint32 addr2 = S9xGetWord(addr);
474
OpenBus = addr2 >> 8;
475
addr2 |= (OpenBus = S9xGetByte(addr + 2)) << 16;
476
477
return (addr2);
478
}
479
480
static inline uint32 DirectIndirectIndexedLongSlow (AccessMode a) // [d],Y
481
{
482
return (DirectIndirectLongSlow(a) + Registers.Y.W);
483
}
484
485
static inline uint32 DirectIndirectIndexedLong (AccessMode a) // [d],Y
486
{
487
return (DirectIndirectLong(a) + Registers.Y.W);
488
}
489
490
static inline uint32 DirectIndexedXSlow (AccessMode a) // d,X
491
{
492
pair addr;
493
addr.W = DirectSlow(a);
494
if (!CheckEmulation() || Registers.DL)
495
addr.W += Registers.X.W;
496
else
497
addr.B.l += Registers.XL;
498
499
AddCycles(ONE_CYCLE);
500
501
return (addr.W);
502
}
503
504
static inline uint32 DirectIndexedXE0 (AccessMode a) // d,X
505
{
506
uint16 addr = Direct(a) + Registers.X.W;
507
AddCycles(ONE_CYCLE);
508
509
return (addr);
510
}
511
512
static inline uint32 DirectIndexedXE1 (AccessMode a) // d,X
513
{
514
if (Registers.DL)
515
return (DirectIndexedXE0(a));
516
else
517
{
518
pair addr;
519
addr.W = Direct(a);
520
addr.B.l += Registers.XL;
521
AddCycles(ONE_CYCLE);
522
523
return (addr.W);
524
}
525
}
526
527
static inline uint32 DirectIndexedYSlow (AccessMode a) // d,Y
528
{
529
pair addr;
530
addr.W = DirectSlow(a);
531
if (!CheckEmulation() || Registers.DL)
532
addr.W += Registers.Y.W;
533
else
534
addr.B.l += Registers.YL;
535
536
AddCycles(ONE_CYCLE);
537
538
return (addr.W);
539
}
540
541
static inline uint32 DirectIndexedYE0 (AccessMode a) // d,Y
542
{
543
uint16 addr = Direct(a) + Registers.Y.W;
544
AddCycles(ONE_CYCLE);
545
546
return (addr);
547
}
548
549
static inline uint32 DirectIndexedYE1 (AccessMode a) // d,Y
550
{
551
if (Registers.DL)
552
return (DirectIndexedYE0(a));
553
else
554
{
555
pair addr;
556
addr.W = Direct(a);
557
addr.B.l += Registers.YL;
558
AddCycles(ONE_CYCLE);
559
560
return (addr.W);
561
}
562
}
563
564
static inline uint32 DirectIndexedIndirectSlow (AccessMode a) // (d,X)
565
{
566
uint32 addr = S9xGetWord(DirectIndexedXSlow(READ), (!CheckEmulation() || Registers.DL) ? WRAP_BANK : WRAP_PAGE);
567
if (a & READ)
568
OpenBus = (uint8) (addr >> 8);
569
570
return (ICPU.ShiftedDB | addr);
571
}
572
573
static inline uint32 DirectIndexedIndirectE0 (AccessMode a) // (d,X)
574
{
575
uint32 addr = S9xGetWord(DirectIndexedXE0(READ));
576
if (a & READ)
577
OpenBus = (uint8) (addr >> 8);
578
579
return (ICPU.ShiftedDB | addr);
580
}
581
582
static inline uint32 DirectIndexedIndirectE1 (AccessMode a) // (d,X)
583
{
584
uint32 addr = S9xGetWord(DirectIndexedXE1(READ), Registers.DL ? WRAP_BANK : WRAP_PAGE);
585
if (a & READ)
586
OpenBus = (uint8) (addr >> 8);
587
588
return (ICPU.ShiftedDB | addr);
589
}
590
591
static inline uint32 AbsoluteIndexedXSlow (AccessMode a) // a,X
592
{
593
uint32 addr = AbsoluteSlow(a);
594
if (a & WRITE || !CheckIndex() || (addr & 0xff) + Registers.XL >= 0x100)
595
AddCycles(ONE_CYCLE);
596
597
return (addr + Registers.X.W);
598
}
599
600
static inline uint32 AbsoluteIndexedXX0 (AccessMode a) // a,X
601
{
602
uint32 addr = Absolute(a);
603
AddCycles(ONE_CYCLE);
604
605
return (addr + Registers.X.W);
606
}
607
608
static inline uint32 AbsoluteIndexedXX1 (AccessMode a) // a,X
609
{
610
uint32 addr = Absolute(a);
611
if (a & WRITE || (addr & 0xff) + Registers.XL >= 0x100)
612
AddCycles(ONE_CYCLE);
613
614
return (addr + Registers.X.W);
615
}
616
617
static inline uint32 AbsoluteIndexedYSlow (AccessMode a) // a,Y
618
{
619
uint32 addr = AbsoluteSlow(a);
620
if (a & WRITE || !CheckIndex() || (addr & 0xff) + Registers.YL >= 0x100)
621
AddCycles(ONE_CYCLE);
622
623
return (addr + Registers.Y.W);
624
}
625
626
static inline uint32 AbsoluteIndexedYX0 (AccessMode a) // a,Y
627
{
628
uint32 addr = Absolute(a);
629
AddCycles(ONE_CYCLE);
630
631
return (addr + Registers.Y.W);
632
}
633
634
static inline uint32 AbsoluteIndexedYX1 (AccessMode a) // a,Y
635
{
636
uint32 addr = Absolute(a);
637
if (a & WRITE || (addr & 0xff) + Registers.YL >= 0x100)
638
AddCycles(ONE_CYCLE);
639
640
return (addr + Registers.Y.W);
641
}
642
643
static inline uint32 AbsoluteLongIndexedXSlow (AccessMode a) // l,X
644
{
645
return (AbsoluteLongSlow(a) + Registers.X.W);
646
}
647
648
static inline uint32 AbsoluteLongIndexedX (AccessMode a) // l,X
649
{
650
return (AbsoluteLong(a) + Registers.X.W);
651
}
652
653
static inline uint32 StackRelativeSlow (AccessMode a) // d,S
654
{
655
uint16 addr = Immediate8Slow(a) + Registers.S.W;
656
AddCycles(ONE_CYCLE);
657
658
return (addr);
659
}
660
661
static inline uint32 StackRelative (AccessMode a) // d,S
662
{
663
uint16 addr = Immediate8(a) + Registers.S.W;
664
AddCycles(ONE_CYCLE);
665
666
return (addr);
667
}
668
669
static inline uint32 StackRelativeIndirectIndexedSlow (AccessMode a) // (d,S),Y
670
{
671
uint32 addr = S9xGetWord(StackRelativeSlow(READ));
672
if (a & READ)
673
OpenBus = (uint8) (addr >> 8);
674
addr = (addr + Registers.Y.W + ICPU.ShiftedDB) & 0xffffff;
675
AddCycles(ONE_CYCLE);
676
677
return (addr);
678
}
679
680
static inline uint32 StackRelativeIndirectIndexed (AccessMode a) // (d,S),Y
681
{
682
uint32 addr = S9xGetWord(StackRelative(READ));
683
if (a & READ)
684
OpenBus = (uint8) (addr >> 8);
685
addr = (addr + Registers.Y.W + ICPU.ShiftedDB) & 0xffffff;
686
AddCycles(ONE_CYCLE);
687
688
return (addr);
689
}
690
691
#endif
692
693