1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
|
/*
* Gearboy - Nintendo Game Boy Emulator
* Copyright (C) 2012 Ignacio Sanchez
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/
*
*/
#ifndef PROCESSOR_H
#define PROCESSOR_H
#include <list>
#include "definitions.h"
#include "SixteenBitRegister.h"
class Memory;
class Processor
{
public:
enum Interrupts
{
None_Interrupt = 0x00,
VBlank_Interrupt = 0x01,
LCDSTAT_Interrupt = 0x02,
Timer_Interrupt = 0x04,
Serial_Interrupt = 0x08,
Joypad_Interrupt = 0x10
};
struct ProcessorState
{
SixteenBitRegister* AF;
SixteenBitRegister* BC;
SixteenBitRegister* DE;
SixteenBitRegister* HL;
SixteenBitRegister* SP;
SixteenBitRegister* PC;
bool* IME;
bool* Halt;
};
public:
Processor(Memory* pMemory);
~Processor();
void Init();
void Reset(bool bCGB, bool bGBA);
u8 RunFor(u8 ticks);
void RequestInterrupt(Interrupts interrupt);
void ResetTIMACycles();
void ResetDIVCycles();
bool Halted() const;
bool DuringOpCode() const;
bool CGBSpeed() const;
void AddCycles(unsigned int cycles);
bool InterruptIsAboutToRaise();
void SaveState(std::ostream& stream);
void LoadState(std::istream& stream);
void SetGameSharkCheat(const char* szCheat);
void ClearGameSharkCheats();
ProcessorState* GetState();
bool Disassemble(u16 address);
bool BreakpointHit();
void RequestMemoryBreakpoint();
void UpdateTimers(u8 ticks);
void UpdateSerial(u8 ticks);
private:
typedef void (Processor::*OPCptr) (void);
OPCptr m_OPCodes[256];
OPCptr m_OPCodesCB[256];
Memory* m_pMemory;
SixteenBitRegister AF;
SixteenBitRegister BC;
SixteenBitRegister DE;
SixteenBitRegister HL;
SixteenBitRegister SP;
SixteenBitRegister PC;
bool m_bIME;
bool m_bHalt;
bool m_bBranchTaken;
bool m_bSkipPCBug;
unsigned int m_iCurrentClockCycles;
unsigned int m_iDIVCycles;
unsigned int m_iTIMACycles;
int m_iSerialBit;
int m_iSerialCycles;
int m_iIMECycles;
int m_iUnhaltCycles;
bool m_bCGB;
int m_iInterruptDelayCycles;
bool m_bCGBSpeed;
int m_iSpeedMultiplier;
int m_iAccurateOPCodeState;
u8 m_iReadCache;
bool m_bBreakpointHit;
bool m_bRequestMemBreakpoint;
struct GameSharkCode
{
u8 type;
u16 address;
u8 value;
};
std::list<GameSharkCode> m_GameSharkList;
ProcessorState m_ProcessorState;
private:
Processor::Interrupts InterruptPending();
void ServeInterrupt(Interrupts interrupt);
void UpdateGameShark();
void ClearAllFlags();
void ToggleZeroFlagFromResult(u8 result);
void SetFlag(u8 flag);
void FlipFlag(u8 flag);
void ToggleFlag(u8 flag);
void UntoggleFlag(u8 flag);
bool IsSetFlag(u8 flag);
void StackPush(SixteenBitRegister* reg);
void StackPop(SixteenBitRegister* reg);
int AdjustedCycles(int cycles);
void InvalidOPCode();
void OPCodes_LD(u8* reg1, u8 reg2);
void OPCodes_LD(u8* reg, u16 address);
void OPCodes_LD(u16 address, u8 reg);
void OPCodes_OR(u8 number);
void OPCodes_XOR(u8 number);
void OPCodes_AND(u8 number);
void OPCodes_CP(u8 number);
void OPCodes_INC(u8* reg);
void OPCodes_INC_HL();
void OPCodes_DEC(u8* reg);
void OPCodes_DEC_HL();
void OPCodes_ADD(u8 number);
void OPCodes_ADC(u8 number);
void OPCodes_SUB(u8 number);
void OPCodes_SBC(u8 number);
void OPCodes_ADD_HL(u16 number);
void OPCodes_ADD_SP(s8 number);
void OPCodes_SWAP_Register(u8* reg);
void OPCodes_SWAP_HL();
void OPCodes_SLA(u8* reg);
void OPCodes_SLA_HL();
void OPCodes_SRA(u8* reg);
void OPCodes_SRA_HL();
void OPCodes_SRL(u8* reg);
void OPCodes_SRL_HL();
void OPCodes_RLC(u8* reg, bool isRegisterA = false);
void OPCodes_RLC_HL();
void OPCodes_RL(u8* reg, bool isRegisterA = false);
void OPCodes_RL_HL();
void OPCodes_RRC(u8* reg, bool isRegisterA = false);
void OPCodes_RRC_HL();
void OPCodes_RR(u8* reg, bool isRegisterA = false);
void OPCodes_RR_HL();
void OPCodes_BIT(u8* reg, int bit);
void OPCodes_BIT_HL(int bit);
void OPCodes_SET(u8* reg, int bit);
void OPCodes_SET_HL(int bit);
void OPCodes_RES(u8* reg, int bit);
void OPCodes_RES_HL(int bit);
void InitOPCodeFunctors();
void OPCode0x00();
void OPCode0x01();
void OPCode0x02();
void OPCode0x03();
void OPCode0x04();
void OPCode0x05();
void OPCode0x06();
void OPCode0x07();
void OPCode0x08();
void OPCode0x09();
void OPCode0x0A();
void OPCode0x0B();
void OPCode0x0C();
void OPCode0x0D();
void OPCode0x0E();
void OPCode0x0F();
void OPCode0x10();
void OPCode0x11();
void OPCode0x12();
void OPCode0x13();
void OPCode0x14();
void OPCode0x15();
void OPCode0x16();
void OPCode0x17();
void OPCode0x18();
void OPCode0x19();
void OPCode0x1A();
void OPCode0x1B();
void OPCode0x1C();
void OPCode0x1D();
void OPCode0x1E();
void OPCode0x1F();
void OPCode0x20();
void OPCode0x21();
void OPCode0x22();
void OPCode0x23();
void OPCode0x24();
void OPCode0x25();
void OPCode0x26();
void OPCode0x27();
void OPCode0x28();
void OPCode0x29();
void OPCode0x2A();
void OPCode0x2B();
void OPCode0x2C();
void OPCode0x2D();
void OPCode0x2E();
void OPCode0x2F();
void OPCode0x30();
void OPCode0x31();
void OPCode0x32();
void OPCode0x33();
void OPCode0x34();
void OPCode0x35();
void OPCode0x36();
void OPCode0x37();
void OPCode0x38();
void OPCode0x39();
void OPCode0x3A();
void OPCode0x3B();
void OPCode0x3C();
void OPCode0x3D();
void OPCode0x3E();
void OPCode0x3F();
void OPCode0x40();
void OPCode0x41();
void OPCode0x42();
void OPCode0x43();
void OPCode0x44();
void OPCode0x45();
void OPCode0x46();
void OPCode0x47();
void OPCode0x48();
void OPCode0x49();
void OPCode0x4A();
void OPCode0x4B();
void OPCode0x4C();
void OPCode0x4D();
void OPCode0x4E();
void OPCode0x4F();
void OPCode0x50();
void OPCode0x51();
void OPCode0x52();
void OPCode0x53();
void OPCode0x54();
void OPCode0x55();
void OPCode0x56();
void OPCode0x57();
void OPCode0x58();
void OPCode0x59();
void OPCode0x5A();
void OPCode0x5B();
void OPCode0x5C();
void OPCode0x5D();
void OPCode0x5E();
void OPCode0x5F();
void OPCode0x60();
void OPCode0x61();
void OPCode0x62();
void OPCode0x63();
void OPCode0x64();
void OPCode0x65();
void OPCode0x66();
void OPCode0x67();
void OPCode0x68();
void OPCode0x69();
void OPCode0x6A();
void OPCode0x6B();
void OPCode0x6C();
void OPCode0x6D();
void OPCode0x6E();
void OPCode0x6F();
void OPCode0x70();
void OPCode0x71();
void OPCode0x72();
void OPCode0x73();
void OPCode0x74();
void OPCode0x75();
void OPCode0x76();
void OPCode0x77();
void OPCode0x78();
void OPCode0x79();
void OPCode0x7A();
void OPCode0x7B();
void OPCode0x7C();
void OPCode0x7D();
void OPCode0x7E();
void OPCode0x7F();
void OPCode0x80();
void OPCode0x81();
void OPCode0x82();
void OPCode0x83();
void OPCode0x84();
void OPCode0x85();
void OPCode0x86();
void OPCode0x87();
void OPCode0x88();
void OPCode0x89();
void OPCode0x8A();
void OPCode0x8B();
void OPCode0x8C();
void OPCode0x8D();
void OPCode0x8E();
void OPCode0x8F();
void OPCode0x90();
void OPCode0x91();
void OPCode0x92();
void OPCode0x93();
void OPCode0x94();
void OPCode0x95();
void OPCode0x96();
void OPCode0x97();
void OPCode0x98();
void OPCode0x99();
void OPCode0x9A();
void OPCode0x9B();
void OPCode0x9C();
void OPCode0x9D();
void OPCode0x9E();
void OPCode0x9F();
void OPCode0xA0();
void OPCode0xA1();
void OPCode0xA2();
void OPCode0xA3();
void OPCode0xA4();
void OPCode0xA5();
void OPCode0xA6();
void OPCode0xA7();
void OPCode0xA8();
void OPCode0xA9();
void OPCode0xAA();
void OPCode0xAB();
void OPCode0xAC();
void OPCode0xAD();
void OPCode0xAE();
void OPCode0xAF();
void OPCode0xB0();
void OPCode0xB1();
void OPCode0xB2();
void OPCode0xB3();
void OPCode0xB4();
void OPCode0xB5();
void OPCode0xB6();
void OPCode0xB7();
void OPCode0xB8();
void OPCode0xB9();
void OPCode0xBA();
void OPCode0xBB();
void OPCode0xBC();
void OPCode0xBD();
void OPCode0xBE();
void OPCode0xBF();
void OPCode0xC0();
void OPCode0xC1();
void OPCode0xC2();
void OPCode0xC3();
void OPCode0xC4();
void OPCode0xC5();
void OPCode0xC6();
void OPCode0xC7();
void OPCode0xC8();
void OPCode0xC9();
void OPCode0xCA();
void OPCode0xCB();
void OPCode0xCC();
void OPCode0xCD();
void OPCode0xCE();
void OPCode0xCF();
void OPCode0xD0();
void OPCode0xD1();
void OPCode0xD2();
void OPCode0xD3();
void OPCode0xD4();
void OPCode0xD5();
void OPCode0xD6();
void OPCode0xD7();
void OPCode0xD8();
void OPCode0xD9();
void OPCode0xDA();
void OPCode0xDB();
void OPCode0xDC();
void OPCode0xDD();
void OPCode0xDE();
void OPCode0xDF();
void OPCode0xE0();
void OPCode0xE1();
void OPCode0xE2();
void OPCode0xE3();
void OPCode0xE4();
void OPCode0xE5();
void OPCode0xE6();
void OPCode0xE7();
void OPCode0xE8();
void OPCode0xE9();
void OPCode0xEA();
void OPCode0xEB();
void OPCode0xEC();
void OPCode0xED();
void OPCode0xEE();
void OPCode0xEF();
void OPCode0xF0();
void OPCode0xF1();
void OPCode0xF2();
void OPCode0xF3();
void OPCode0xF4();
void OPCode0xF5();
void OPCode0xF6();
void OPCode0xF7();
void OPCode0xF8();
void OPCode0xF9();
void OPCode0xFA();
void OPCode0xFB();
void OPCode0xFC();
void OPCode0xFD();
void OPCode0xFE();
void OPCode0xFF();
void OPCodeCB0x00();
void OPCodeCB0x01();
void OPCodeCB0x02();
void OPCodeCB0x03();
void OPCodeCB0x04();
void OPCodeCB0x05();
void OPCodeCB0x06();
void OPCodeCB0x07();
void OPCodeCB0x08();
void OPCodeCB0x09();
void OPCodeCB0x0A();
void OPCodeCB0x0B();
void OPCodeCB0x0C();
void OPCodeCB0x0D();
void OPCodeCB0x0E();
void OPCodeCB0x0F();
void OPCodeCB0x10();
void OPCodeCB0x11();
void OPCodeCB0x12();
void OPCodeCB0x13();
void OPCodeCB0x14();
void OPCodeCB0x15();
void OPCodeCB0x16();
void OPCodeCB0x17();
void OPCodeCB0x18();
void OPCodeCB0x19();
void OPCodeCB0x1A();
void OPCodeCB0x1B();
void OPCodeCB0x1C();
void OPCodeCB0x1D();
void OPCodeCB0x1E();
void OPCodeCB0x1F();
void OPCodeCB0x20();
void OPCodeCB0x21();
void OPCodeCB0x22();
void OPCodeCB0x23();
void OPCodeCB0x24();
void OPCodeCB0x25();
void OPCodeCB0x26();
void OPCodeCB0x27();
void OPCodeCB0x28();
void OPCodeCB0x29();
void OPCodeCB0x2A();
void OPCodeCB0x2B();
void OPCodeCB0x2C();
void OPCodeCB0x2D();
void OPCodeCB0x2E();
void OPCodeCB0x2F();
void OPCodeCB0x30();
void OPCodeCB0x31();
void OPCodeCB0x32();
void OPCodeCB0x33();
void OPCodeCB0x34();
void OPCodeCB0x35();
void OPCodeCB0x36();
void OPCodeCB0x37();
void OPCodeCB0x38();
void OPCodeCB0x39();
void OPCodeCB0x3A();
void OPCodeCB0x3B();
void OPCodeCB0x3C();
void OPCodeCB0x3D();
void OPCodeCB0x3E();
void OPCodeCB0x3F();
void OPCodeCB0x40();
void OPCodeCB0x41();
void OPCodeCB0x42();
void OPCodeCB0x43();
void OPCodeCB0x44();
void OPCodeCB0x45();
void OPCodeCB0x46();
void OPCodeCB0x47();
void OPCodeCB0x48();
void OPCodeCB0x49();
void OPCodeCB0x4A();
void OPCodeCB0x4B();
void OPCodeCB0x4C();
void OPCodeCB0x4D();
void OPCodeCB0x4E();
void OPCodeCB0x4F();
void OPCodeCB0x50();
void OPCodeCB0x51();
void OPCodeCB0x52();
void OPCodeCB0x53();
void OPCodeCB0x54();
void OPCodeCB0x55();
void OPCodeCB0x56();
void OPCodeCB0x57();
void OPCodeCB0x58();
void OPCodeCB0x59();
void OPCodeCB0x5A();
void OPCodeCB0x5B();
void OPCodeCB0x5C();
void OPCodeCB0x5D();
void OPCodeCB0x5E();
void OPCodeCB0x5F();
void OPCodeCB0x60();
void OPCodeCB0x61();
void OPCodeCB0x62();
void OPCodeCB0x63();
void OPCodeCB0x64();
void OPCodeCB0x65();
void OPCodeCB0x66();
void OPCodeCB0x67();
void OPCodeCB0x68();
void OPCodeCB0x69();
void OPCodeCB0x6A();
void OPCodeCB0x6B();
void OPCodeCB0x6C();
void OPCodeCB0x6D();
void OPCodeCB0x6E();
void OPCodeCB0x6F();
void OPCodeCB0x70();
void OPCodeCB0x71();
void OPCodeCB0x72();
void OPCodeCB0x73();
void OPCodeCB0x74();
void OPCodeCB0x75();
void OPCodeCB0x76();
void OPCodeCB0x77();
void OPCodeCB0x78();
void OPCodeCB0x79();
void OPCodeCB0x7A();
void OPCodeCB0x7B();
void OPCodeCB0x7C();
void OPCodeCB0x7D();
void OPCodeCB0x7E();
void OPCodeCB0x7F();
void OPCodeCB0x80();
void OPCodeCB0x81();
void OPCodeCB0x82();
void OPCodeCB0x83();
void OPCodeCB0x84();
void OPCodeCB0x85();
void OPCodeCB0x86();
void OPCodeCB0x87();
void OPCodeCB0x88();
void OPCodeCB0x89();
void OPCodeCB0x8A();
void OPCodeCB0x8B();
void OPCodeCB0x8C();
void OPCodeCB0x8D();
void OPCodeCB0x8E();
void OPCodeCB0x8F();
void OPCodeCB0x90();
void OPCodeCB0x91();
void OPCodeCB0x92();
void OPCodeCB0x93();
void OPCodeCB0x94();
void OPCodeCB0x95();
void OPCodeCB0x96();
void OPCodeCB0x97();
void OPCodeCB0x98();
void OPCodeCB0x99();
void OPCodeCB0x9A();
void OPCodeCB0x9B();
void OPCodeCB0x9C();
void OPCodeCB0x9D();
void OPCodeCB0x9E();
void OPCodeCB0x9F();
void OPCodeCB0xA0();
void OPCodeCB0xA1();
void OPCodeCB0xA2();
void OPCodeCB0xA3();
void OPCodeCB0xA4();
void OPCodeCB0xA5();
void OPCodeCB0xA6();
void OPCodeCB0xA7();
void OPCodeCB0xA8();
void OPCodeCB0xA9();
void OPCodeCB0xAA();
void OPCodeCB0xAB();
void OPCodeCB0xAC();
void OPCodeCB0xAD();
void OPCodeCB0xAE();
void OPCodeCB0xAF();
void OPCodeCB0xB0();
void OPCodeCB0xB1();
void OPCodeCB0xB2();
void OPCodeCB0xB3();
void OPCodeCB0xB4();
void OPCodeCB0xB5();
void OPCodeCB0xB6();
void OPCodeCB0xB7();
void OPCodeCB0xB8();
void OPCodeCB0xB9();
void OPCodeCB0xBA();
void OPCodeCB0xBB();
void OPCodeCB0xBC();
void OPCodeCB0xBD();
void OPCodeCB0xBE();
void OPCodeCB0xBF();
void OPCodeCB0xC0();
void OPCodeCB0xC1();
void OPCodeCB0xC2();
void OPCodeCB0xC3();
void OPCodeCB0xC4();
void OPCodeCB0xC5();
void OPCodeCB0xC6();
void OPCodeCB0xC7();
void OPCodeCB0xC8();
void OPCodeCB0xC9();
void OPCodeCB0xCA();
void OPCodeCB0xCB();
void OPCodeCB0xCC();
void OPCodeCB0xCD();
void OPCodeCB0xCE();
void OPCodeCB0xCF();
void OPCodeCB0xD0();
void OPCodeCB0xD1();
void OPCodeCB0xD2();
void OPCodeCB0xD3();
void OPCodeCB0xD4();
void OPCodeCB0xD5();
void OPCodeCB0xD6();
void OPCodeCB0xD7();
void OPCodeCB0xD8();
void OPCodeCB0xD9();
void OPCodeCB0xDA();
void OPCodeCB0xDB();
void OPCodeCB0xDC();
void OPCodeCB0xDD();
void OPCodeCB0xDE();
void OPCodeCB0xDF();
void OPCodeCB0xE0();
void OPCodeCB0xE1();
void OPCodeCB0xE2();
void OPCodeCB0xE3();
void OPCodeCB0xE4();
void OPCodeCB0xE5();
void OPCodeCB0xE6();
void OPCodeCB0xE7();
void OPCodeCB0xE8();
void OPCodeCB0xE9();
void OPCodeCB0xEA();
void OPCodeCB0xEB();
void OPCodeCB0xEC();
void OPCodeCB0xED();
void OPCodeCB0xEE();
void OPCodeCB0xEF();
void OPCodeCB0xF0();
void OPCodeCB0xF1();
void OPCodeCB0xF2();
void OPCodeCB0xF3();
void OPCodeCB0xF4();
void OPCodeCB0xF5();
void OPCodeCB0xF6();
void OPCodeCB0xF7();
void OPCodeCB0xF8();
void OPCodeCB0xF9();
void OPCodeCB0xFA();
void OPCodeCB0xFB();
void OPCodeCB0xFC();
void OPCodeCB0xFD();
void OPCodeCB0xFE();
void OPCodeCB0xFF();
};
#include "Processor_inline.h"
#endif /* PROCESSOR_H */
|