Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
folium-app
GitHub Repository: folium-app/Folium
Path: blob/a-new-beginning/Cherry/Core/opcodes.cpp
2 views
1
/*
2
* Gearcoleco - ColecoVision Emulator
3
* Copyright (C) 2021 Ignacio Sanchez
4
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* any later version.
9
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
14
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see http://www.gnu.org/licenses/
17
*
18
*/
19
20
#include "Processor.h"
21
#include "CVMemory.h"
22
#include "opcode_timing.h"
23
#include "opcode_daa.h"
24
25
void Processor::OPCode0x00()
26
{
27
// NOP
28
}
29
30
void Processor::OPCode0x01()
31
{
32
// LD BC,nn
33
OPCodes_LD(BC.GetLowRegister(), PC.GetValue());
34
PC.Increment();
35
OPCodes_LD(BC.GetHighRegister(), PC.GetValue());
36
PC.Increment();
37
}
38
39
void Processor::OPCode0x02()
40
{
41
// LD (BC),A
42
OPCodes_LD(BC.GetValue(), AF.GetHigh());
43
WZ.SetLow((BC.GetValue() + 1) & 0xFF);
44
WZ.SetHigh(AF.GetHigh());
45
}
46
47
void Processor::OPCode0x03()
48
{
49
// INC BC
50
BC.Increment();
51
}
52
53
void Processor::OPCode0x04()
54
{
55
// INC B
56
OPCodes_INC(BC.GetHighRegister());
57
}
58
59
void Processor::OPCode0x05()
60
{
61
// DEC B
62
OPCodes_DEC(BC.GetHighRegister());
63
}
64
65
void Processor::OPCode0x06()
66
{
67
// LD B,n
68
OPCodes_LD(BC.GetHighRegister(), PC.GetValue());
69
PC.Increment();
70
}
71
72
void Processor::OPCode0x07()
73
{
74
// RLCA
75
OPCodes_RLC(AF.GetHighRegister(), true);
76
}
77
78
void Processor::OPCode0x08()
79
{
80
// EX AF,AF’
81
OPCodes_EX(&AF, &AF2);
82
}
83
84
void Processor::OPCode0x09()
85
{
86
// ADD HL,BC
87
OPCodes_ADD_HL(BC.GetValue());
88
}
89
90
void Processor::OPCode0x0A()
91
{
92
// LD A,(BC)
93
OPCodes_LD(AF.GetHighRegister(), BC.GetValue());
94
WZ.SetValue(BC.GetValue() + 1);
95
}
96
97
void Processor::OPCode0x0B()
98
{
99
// DEC BC
100
BC.Decrement();
101
}
102
103
void Processor::OPCode0x0C()
104
{
105
// INC C
106
OPCodes_INC(BC.GetLowRegister());
107
}
108
109
void Processor::OPCode0x0D()
110
{
111
// DEC C
112
OPCodes_DEC(BC.GetLowRegister());
113
}
114
115
void Processor::OPCode0x0E()
116
{
117
// LD C,n
118
OPCodes_LD(BC.GetLowRegister(), PC.GetValue());
119
PC.Increment();
120
}
121
122
void Processor::OPCode0x0F()
123
{
124
// RRCA
125
OPCodes_RRC(AF.GetHighRegister(), true);
126
}
127
128
void Processor::OPCode0x10()
129
{
130
// DJNZ (PC+e)
131
u8* b = BC.GetHighRegister();
132
*b = *b - 1;
133
OPCodes_JR_n_conditional(BC.GetHigh() != 0);
134
}
135
136
void Processor::OPCode0x11()
137
{
138
// LD DE,nn
139
OPCodes_LD(DE.GetLowRegister(), PC.GetValue());
140
PC.Increment();
141
OPCodes_LD(DE.GetHighRegister(), PC.GetValue());
142
PC.Increment();
143
}
144
145
void Processor::OPCode0x12()
146
{
147
// LD (DE),A
148
OPCodes_LD(DE.GetValue(), AF.GetHigh());
149
WZ.SetLow((DE.GetValue() + 1) & 0xFF);
150
WZ.SetHigh(AF.GetHigh());
151
}
152
153
void Processor::OPCode0x13()
154
{
155
// INC DE
156
DE.Increment();
157
}
158
159
void Processor::OPCode0x14()
160
{
161
// INC D
162
OPCodes_INC(DE.GetHighRegister());
163
}
164
165
void Processor::OPCode0x15()
166
{
167
// DEC D
168
OPCodes_DEC(DE.GetHighRegister());
169
}
170
171
void Processor::OPCode0x16()
172
{
173
// LD D,n
174
OPCodes_LD(DE.GetHighRegister(), PC.GetValue());
175
PC.Increment();
176
}
177
178
void Processor::OPCode0x17()
179
{
180
// RLA
181
OPCodes_RL(AF.GetHighRegister(), true);
182
}
183
184
void Processor::OPCode0x18()
185
{
186
// JR n
187
OPCodes_JR_n();
188
}
189
190
void Processor::OPCode0x19()
191
{
192
// ADD HL,DE
193
OPCodes_ADD_HL(DE.GetValue());
194
}
195
196
void Processor::OPCode0x1A()
197
{
198
// LD A,(DE)
199
OPCodes_LD(AF.GetHighRegister(), DE.GetValue());
200
WZ.SetValue(DE.GetValue() + 1);
201
}
202
203
void Processor::OPCode0x1B()
204
{
205
// DEC DE
206
DE.Decrement();
207
}
208
209
void Processor::OPCode0x1C()
210
{
211
// INC E
212
OPCodes_INC(DE.GetLowRegister());
213
}
214
215
void Processor::OPCode0x1D()
216
{
217
// DEC E
218
OPCodes_DEC(DE.GetLowRegister());
219
}
220
221
void Processor::OPCode0x1E()
222
{
223
// LD E,n
224
OPCodes_LD(DE.GetLowRegister(), PC.GetValue());
225
PC.Increment();
226
}
227
228
void Processor::OPCode0x1F()
229
{
230
// RRA
231
OPCodes_RR(AF.GetHighRegister(), true);
232
}
233
234
void Processor::OPCode0x20()
235
{
236
// JR NZ,n
237
OPCodes_JR_n_conditional(!IsSetFlag(FLAG_ZERO));
238
}
239
240
void Processor::OPCode0x21()
241
{
242
// LD HL,nn
243
SixteenBitRegister* reg = GetPrefixedRegister();
244
OPCodes_LD(reg->GetLowRegister(), PC.GetValue());
245
PC.Increment();
246
OPCodes_LD(reg->GetHighRegister(), PC.GetValue());
247
PC.Increment();
248
}
249
250
void Processor::OPCode0x22()
251
{
252
// LD (nn),HL
253
OPCodes_LD_nn_dd(GetPrefixedRegister());
254
}
255
256
void Processor::OPCode0x23()
257
{
258
// INC HL
259
GetPrefixedRegister()->Increment();
260
}
261
262
void Processor::OPCode0x24()
263
{
264
// INC H
265
OPCodes_INC(GetPrefixedRegister()->GetHighRegister());
266
}
267
268
void Processor::OPCode0x25()
269
{
270
// DEC H
271
OPCodes_DEC(GetPrefixedRegister()->GetHighRegister());
272
}
273
274
void Processor::OPCode0x26()
275
{
276
// LD H,n
277
OPCodes_LD(GetPrefixedRegister()->GetHighRegister(), PC.GetValue());
278
PC.Increment();
279
}
280
281
void Processor::OPCode0x27()
282
{
283
// DAA
284
int idx = AF.GetHigh();
285
if (IsSetFlag(FLAG_CARRY))
286
idx |= 0x100;
287
if (IsSetFlag(FLAG_HALF))
288
idx |= 0x200;
289
if (IsSetFlag(FLAG_NEGATIVE))
290
idx |= 0x400;
291
AF.SetValue(kOPCodeDAATable[idx]);
292
}
293
294
void Processor::OPCode0x28()
295
{
296
// JR Z,n
297
OPCodes_JR_n_conditional(IsSetFlag(FLAG_ZERO));
298
}
299
300
void Processor::OPCode0x29()
301
{
302
// ADD HL,HL
303
SixteenBitRegister* reg = GetPrefixedRegister();
304
OPCodes_ADD_HL(reg->GetValue());
305
}
306
307
void Processor::OPCode0x2A()
308
{
309
// LD HL,(nn)
310
OPCodes_LD_dd_nn(GetPrefixedRegister());
311
}
312
313
void Processor::OPCode0x2B()
314
{
315
// DEC HL
316
GetPrefixedRegister()->Decrement();
317
}
318
319
void Processor::OPCode0x2C()
320
{
321
// INC L
322
OPCodes_INC(GetPrefixedRegister()->GetLowRegister());
323
}
324
325
void Processor::OPCode0x2D()
326
{
327
// DEC L
328
OPCodes_DEC(GetPrefixedRegister()->GetLowRegister());
329
}
330
331
void Processor::OPCode0x2E()
332
{
333
// LD L,n
334
OPCodes_LD(GetPrefixedRegister()->GetLowRegister(), PC.GetValue());
335
PC.Increment();
336
337
}
338
339
void Processor::OPCode0x2F()
340
{
341
// CPL
342
AF.SetHigh(~AF.GetHigh());
343
ToggleFlag(FLAG_HALF);
344
ToggleFlag(FLAG_NEGATIVE);
345
ToggleXYFlagsFromResult(AF.GetHigh());
346
}
347
348
void Processor::OPCode0x30()
349
{
350
// JR NC,n
351
OPCodes_JR_n_conditional(!IsSetFlag(FLAG_CARRY));
352
}
353
354
void Processor::OPCode0x31()
355
{
356
// LD SP,nn
357
SP.SetLow(m_pMemory->Read(PC.GetValue()));
358
PC.Increment();
359
SP.SetHigh(m_pMemory->Read(PC.GetValue()));
360
PC.Increment();
361
}
362
363
void Processor::OPCode0x32()
364
{
365
// LD (nn),A
366
u16 address = FetchArg16();
367
m_pMemory->Write(address, AF.GetHigh());
368
WZ.SetLow((address + 1) & 0xFF);
369
WZ.SetHigh(AF.GetHigh());
370
}
371
372
void Processor::OPCode0x33()
373
{
374
// INC SP
375
SP.Increment();
376
}
377
378
void Processor::OPCode0x34()
379
{
380
// INC (HL)
381
OPCodes_INC_HL();
382
}
383
384
void Processor::OPCode0x35()
385
{
386
// DEC (HL)
387
OPCodes_DEC_HL();
388
}
389
390
void Processor::OPCode0x36()
391
{
392
// LD (HL),n
393
if (m_CurrentPrefix == 0xDD)
394
{
395
u8 d = m_pMemory->Read(PC.GetValue());
396
u8 n = m_pMemory->Read(PC.GetValue() + 1);
397
u16 address = IX.GetValue() + static_cast<s8> (d);
398
m_pMemory->Write(address, n);
399
PC.Increment();
400
}
401
else if (m_CurrentPrefix == 0xFD)
402
{
403
u8 d = m_pMemory->Read(PC.GetValue());
404
u8 n = m_pMemory->Read(PC.GetValue() + 1);
405
u16 address = IY.GetValue() + static_cast<s8> (d);
406
m_pMemory->Write(address, n);
407
PC.Increment();
408
}
409
else
410
m_pMemory->Write(HL.GetValue(), m_pMemory->Read(PC.GetValue()));
411
PC.Increment();
412
}
413
414
void Processor::OPCode0x37()
415
{
416
// SCF
417
ToggleFlag(FLAG_CARRY);
418
ClearFlag(FLAG_HALF);
419
ClearFlag(FLAG_NEGATIVE);
420
ToggleXYFlagsFromResult(AF.GetHigh());
421
}
422
423
void Processor::OPCode0x38()
424
{
425
// JR C,n
426
OPCodes_JR_n_conditional(IsSetFlag(FLAG_CARRY));
427
}
428
429
void Processor::OPCode0x39()
430
{
431
// ADD HL,SP
432
OPCodes_ADD_HL(SP.GetValue());
433
}
434
435
void Processor::OPCode0x3A()
436
{
437
// LD A,(nn)
438
u16 address = FetchArg16();
439
*(AF.GetHighRegister()) = m_pMemory->Read(address);
440
WZ.SetValue(address + 1);
441
}
442
443
void Processor::OPCode0x3B()
444
{
445
// DEC SP
446
SP.Decrement();
447
}
448
449
void Processor::OPCode0x3C()
450
{
451
// INC A
452
OPCodes_INC(AF.GetHighRegister());
453
}
454
455
void Processor::OPCode0x3D()
456
{
457
// DEC A
458
OPCodes_DEC(AF.GetHighRegister());
459
}
460
461
void Processor::OPCode0x3E()
462
{
463
// LD A,n
464
OPCodes_LD(AF.GetHighRegister(), PC.GetValue());
465
PC.Increment();
466
}
467
468
void Processor::OPCode0x3F()
469
{
470
// CCF
471
bool half = IsSetFlag(FLAG_CARRY);
472
FlipFlag(FLAG_CARRY);
473
if (half)
474
ToggleFlag(FLAG_HALF);
475
else
476
ClearFlag(FLAG_HALF);
477
ClearFlag(FLAG_NEGATIVE);
478
ToggleXYFlagsFromResult(AF.GetHigh());
479
}
480
481
void Processor::OPCode0x40()
482
{
483
// LD B,B
484
OPCodes_LD(BC.GetHighRegister(), BC.GetHigh());
485
}
486
487
void Processor::OPCode0x41()
488
{
489
// LD B,C
490
OPCodes_LD(BC.GetHighRegister(), BC.GetLow());
491
}
492
493
void Processor::OPCode0x42()
494
{
495
// LD B,D
496
OPCodes_LD(BC.GetHighRegister(), DE.GetHigh());
497
}
498
499
void Processor::OPCode0x43()
500
{
501
// LD B,E
502
OPCodes_LD(BC.GetHighRegister(), DE.GetLow());
503
}
504
505
void Processor::OPCode0x44()
506
{
507
// LD B,H
508
OPCodes_LD(BC.GetHighRegister(), GetPrefixedRegister()->GetHigh());
509
}
510
511
void Processor::OPCode0x45()
512
{
513
// LD B,L
514
OPCodes_LD(BC.GetHighRegister(), GetPrefixedRegister()->GetLow());
515
}
516
517
void Processor::OPCode0x46()
518
{
519
// LD B,(HL)
520
OPCodes_LD(BC.GetHighRegister(), GetEffectiveAddress());
521
}
522
523
void Processor::OPCode0x47()
524
{
525
// LD B,A
526
OPCodes_LD(BC.GetHighRegister(), AF.GetHigh());
527
}
528
529
void Processor::OPCode0x48()
530
{
531
// LD C,B
532
OPCodes_LD(BC.GetLowRegister(), BC.GetHigh());
533
}
534
535
void Processor::OPCode0x49()
536
{
537
// LD C,C
538
OPCodes_LD(BC.GetLowRegister(), BC.GetLow());
539
}
540
541
void Processor::OPCode0x4A()
542
{
543
// LD C,D
544
OPCodes_LD(BC.GetLowRegister(), DE.GetHigh());
545
}
546
547
void Processor::OPCode0x4B()
548
{
549
// LD C,E
550
OPCodes_LD(BC.GetLowRegister(), DE.GetLow());
551
}
552
553
void Processor::OPCode0x4C()
554
{
555
// LD C,H
556
OPCodes_LD(BC.GetLowRegister(), GetPrefixedRegister()->GetHigh());
557
}
558
559
void Processor::OPCode0x4D()
560
{
561
// LD C,L
562
OPCodes_LD(BC.GetLowRegister(), GetPrefixedRegister()->GetLow());
563
}
564
565
void Processor::OPCode0x4E()
566
{
567
// LD C,(HL)
568
OPCodes_LD(BC.GetLowRegister(), GetEffectiveAddress());
569
}
570
571
void Processor::OPCode0x4F()
572
{
573
// LD C,A
574
OPCodes_LD(BC.GetLowRegister(), AF.GetHigh());
575
}
576
577
void Processor::OPCode0x50()
578
{
579
// LD D,B
580
OPCodes_LD(DE.GetHighRegister(), BC.GetHigh());
581
}
582
583
void Processor::OPCode0x51()
584
{
585
// LD D,C
586
OPCodes_LD(DE.GetHighRegister(), BC.GetLow());
587
}
588
589
void Processor::OPCode0x52()
590
{
591
// LD D,D
592
OPCodes_LD(DE.GetHighRegister(), DE.GetHigh());
593
}
594
595
void Processor::OPCode0x53()
596
{
597
// LD D,E
598
OPCodes_LD(DE.GetHighRegister(), DE.GetLow());
599
}
600
601
void Processor::OPCode0x54()
602
{
603
// LD D,H
604
OPCodes_LD(DE.GetHighRegister(), GetPrefixedRegister()->GetHigh());
605
}
606
607
void Processor::OPCode0x55()
608
{
609
// LD D,L
610
OPCodes_LD(DE.GetHighRegister(), GetPrefixedRegister()->GetLow());
611
}
612
613
void Processor::OPCode0x56()
614
{
615
// LD D,(HL)
616
OPCodes_LD(DE.GetHighRegister(), GetEffectiveAddress());
617
}
618
619
void Processor::OPCode0x57()
620
{
621
// LD D,A
622
OPCodes_LD(DE.GetHighRegister(), AF.GetHigh());
623
}
624
625
void Processor::OPCode0x58()
626
{
627
// LD E,B
628
OPCodes_LD(DE.GetLowRegister(), BC.GetHigh());
629
}
630
631
void Processor::OPCode0x59()
632
{
633
// LD E,C
634
OPCodes_LD(DE.GetLowRegister(), BC.GetLow());
635
}
636
637
void Processor::OPCode0x5A()
638
{
639
// LD E,D
640
OPCodes_LD(DE.GetLowRegister(), DE.GetHigh());
641
}
642
643
void Processor::OPCode0x5B()
644
{
645
// LD E,E
646
OPCodes_LD(DE.GetLowRegister(), DE.GetLow());
647
}
648
649
void Processor::OPCode0x5C()
650
{
651
// LD E,H
652
OPCodes_LD(DE.GetLowRegister(), GetPrefixedRegister()->GetHigh());
653
}
654
655
void Processor::OPCode0x5D()
656
{
657
// LD E,L
658
OPCodes_LD(DE.GetLowRegister(), GetPrefixedRegister()->GetLow());
659
}
660
661
void Processor::OPCode0x5E()
662
{
663
// LD E,(HL)
664
OPCodes_LD(DE.GetLowRegister(), GetEffectiveAddress());
665
}
666
667
void Processor::OPCode0x5F()
668
{
669
// LD E,A
670
OPCodes_LD(DE.GetLowRegister(), AF.GetHigh());
671
}
672
673
void Processor::OPCode0x60()
674
{
675
// LD H,B
676
OPCodes_LD(GetPrefixedRegister()->GetHighRegister(), BC.GetHigh());
677
}
678
679
void Processor::OPCode0x61()
680
{
681
// LD H,C
682
OPCodes_LD(GetPrefixedRegister()->GetHighRegister(), BC.GetLow());
683
}
684
685
void Processor::OPCode0x62()
686
{
687
// LD H,D
688
OPCodes_LD(GetPrefixedRegister()->GetHighRegister(), DE.GetHigh());
689
}
690
691
void Processor::OPCode0x63()
692
{
693
// LD H,E
694
OPCodes_LD(GetPrefixedRegister()->GetHighRegister(), DE.GetLow());
695
}
696
697
void Processor::OPCode0x64()
698
{
699
// LD H,H
700
OPCodes_LD(GetPrefixedRegister()->GetHighRegister(), GetPrefixedRegister()->GetHigh());
701
}
702
703
void Processor::OPCode0x65()
704
{
705
// LD H,L
706
OPCodes_LD(GetPrefixedRegister()->GetHighRegister(), GetPrefixedRegister()->GetLow());
707
}
708
709
void Processor::OPCode0x66()
710
{
711
// LD H,(HL)
712
OPCodes_LD(HL.GetHighRegister(), GetEffectiveAddress());
713
}
714
715
void Processor::OPCode0x67()
716
{
717
// LD H,A
718
OPCodes_LD(GetPrefixedRegister()->GetHighRegister(), AF.GetHigh());
719
}
720
721
void Processor::OPCode0x68()
722
{
723
// LD L,B
724
OPCodes_LD(GetPrefixedRegister()->GetLowRegister(), BC.GetHigh());
725
}
726
727
void Processor::OPCode0x69()
728
{
729
// LD L,C
730
OPCodes_LD(GetPrefixedRegister()->GetLowRegister(), BC.GetLow());
731
}
732
733
void Processor::OPCode0x6A()
734
{
735
// LD L,D
736
OPCodes_LD(GetPrefixedRegister()->GetLowRegister(), DE.GetHigh());
737
}
738
739
void Processor::OPCode0x6B()
740
{
741
// LD L,E
742
OPCodes_LD(GetPrefixedRegister()->GetLowRegister(), DE.GetLow());
743
}
744
745
void Processor::OPCode0x6C()
746
{
747
// LD L,H
748
OPCodes_LD(GetPrefixedRegister()->GetLowRegister(), GetPrefixedRegister()->GetHigh());
749
}
750
751
void Processor::OPCode0x6D()
752
{
753
// LD L,L
754
OPCodes_LD(GetPrefixedRegister()->GetLowRegister(), GetPrefixedRegister()->GetLow());
755
}
756
757
void Processor::OPCode0x6E()
758
{
759
// LD L,(HL)
760
OPCodes_LD(HL.GetLowRegister(), GetEffectiveAddress());
761
}
762
763
void Processor::OPCode0x6F()
764
{
765
// LD L,A
766
OPCodes_LD(GetPrefixedRegister()->GetLowRegister(), AF.GetHigh());
767
}
768
769
void Processor::OPCode0x70()
770
{
771
// LD (HL),B
772
OPCodes_LD(GetEffectiveAddress(), BC.GetHigh());
773
}
774
775
void Processor::OPCode0x71()
776
{
777
// LD (HL),C
778
OPCodes_LD(GetEffectiveAddress(), BC.GetLow());
779
}
780
781
void Processor::OPCode0x72()
782
{
783
// LD (HL),D
784
OPCodes_LD(GetEffectiveAddress(), DE.GetHigh());
785
}
786
787
void Processor::OPCode0x73()
788
{
789
// LD (HL),E
790
OPCodes_LD(GetEffectiveAddress(), DE.GetLow());
791
}
792
793
void Processor::OPCode0x74()
794
{
795
// LD (HL),H
796
OPCodes_LD(GetEffectiveAddress(), HL.GetHigh());
797
}
798
799
void Processor::OPCode0x75()
800
{
801
// LD (HL),L
802
OPCodes_LD(GetEffectiveAddress(), HL.GetLow());
803
}
804
805
void Processor::OPCode0x76()
806
{
807
// HALT
808
m_bHalt = true;
809
PC.Decrement();
810
}
811
812
void Processor::OPCode0x77()
813
{
814
// LD (HL),A
815
OPCodes_LD(GetEffectiveAddress(), AF.GetHigh());
816
}
817
818
void Processor::OPCode0x78()
819
{
820
// LD A,B
821
OPCodes_LD(AF.GetHighRegister(), BC.GetHigh());
822
}
823
824
void Processor::OPCode0x79()
825
{
826
// LD A,C
827
OPCodes_LD(AF.GetHighRegister(), BC.GetLow());
828
}
829
830
void Processor::OPCode0x7A()
831
{
832
// LD A,D
833
OPCodes_LD(AF.GetHighRegister(), DE.GetHigh());
834
}
835
836
void Processor::OPCode0x7B()
837
{
838
// LD A,E
839
OPCodes_LD(AF.GetHighRegister(), DE.GetLow());
840
841
}
842
843
void Processor::OPCode0x7C()
844
{
845
// LD A,H
846
OPCodes_LD(AF.GetHighRegister(), GetPrefixedRegister()->GetHigh());
847
}
848
849
void Processor::OPCode0x7D()
850
{
851
// LD A,L
852
OPCodes_LD(AF.GetHighRegister(), GetPrefixedRegister()->GetLow());
853
}
854
855
void Processor::OPCode0x7E()
856
{
857
// LD A,(HL)
858
OPCodes_LD(AF.GetHighRegister(), GetEffectiveAddress());
859
}
860
861
void Processor::OPCode0x7F()
862
{
863
// LD A,A
864
OPCodes_LD(AF.GetHighRegister(), AF.GetHigh());
865
}
866
867
void Processor::OPCode0x80()
868
{
869
// ADD A,B
870
OPCodes_ADD(BC.GetHigh());
871
}
872
873
void Processor::OPCode0x81()
874
{
875
// ADD A,C
876
OPCodes_ADD(BC.GetLow());
877
}
878
879
void Processor::OPCode0x82()
880
{
881
// ADD A,D
882
OPCodes_ADD(DE.GetHigh());
883
}
884
885
void Processor::OPCode0x83()
886
{
887
// ADD A,E
888
OPCodes_ADD(DE.GetLow());
889
}
890
891
void Processor::OPCode0x84()
892
{
893
// ADD A,H
894
OPCodes_ADD(GetPrefixedRegister()->GetHigh());
895
}
896
897
void Processor::OPCode0x85()
898
{
899
// ADD A,L
900
OPCodes_ADD(GetPrefixedRegister()->GetLow());
901
}
902
903
void Processor::OPCode0x86()
904
{
905
// ADD A,(HL)
906
OPCodes_ADD(m_pMemory->Read(GetEffectiveAddress()));
907
}
908
909
void Processor::OPCode0x87()
910
{
911
// ADD A,A
912
OPCodes_ADD(AF.GetHigh());
913
}
914
915
void Processor::OPCode0x88()
916
{
917
// ADC A,B
918
OPCodes_ADC(BC.GetHigh());
919
}
920
921
void Processor::OPCode0x89()
922
{
923
// ADC A,C
924
OPCodes_ADC(BC.GetLow());
925
}
926
927
void Processor::OPCode0x8A()
928
{
929
// ADC A,D
930
OPCodes_ADC(DE.GetHigh());
931
}
932
933
void Processor::OPCode0x8B()
934
{
935
// ADC A,E
936
OPCodes_ADC(DE.GetLow());
937
}
938
939
void Processor::OPCode0x8C()
940
{
941
// ADC A,H
942
OPCodes_ADC(GetPrefixedRegister()->GetHigh());
943
}
944
945
void Processor::OPCode0x8D()
946
{
947
// ADC A,L
948
OPCodes_ADC(GetPrefixedRegister()->GetLow());
949
}
950
951
void Processor::OPCode0x8E()
952
{
953
// ADC A,(HL)
954
OPCodes_ADC(m_pMemory->Read(GetEffectiveAddress()));
955
}
956
957
void Processor::OPCode0x8F()
958
{
959
// ADC A,A
960
OPCodes_ADC(AF.GetHigh());
961
}
962
963
void Processor::OPCode0x90()
964
{
965
// SUB B
966
OPCodes_SUB(BC.GetHigh());
967
}
968
969
void Processor::OPCode0x91()
970
{
971
// SUB C
972
OPCodes_SUB(BC.GetLow());
973
}
974
975
void Processor::OPCode0x92()
976
{
977
// SUB D
978
OPCodes_SUB(DE.GetHigh());
979
}
980
981
void Processor::OPCode0x93()
982
{
983
// SUB E
984
OPCodes_SUB(DE.GetLow());
985
}
986
987
void Processor::OPCode0x94()
988
{
989
// SUB H
990
OPCodes_SUB(GetPrefixedRegister()->GetHigh());
991
}
992
993
void Processor::OPCode0x95()
994
{
995
// SUB L
996
OPCodes_SUB(GetPrefixedRegister()->GetLow());
997
}
998
999
void Processor::OPCode0x96()
1000
{
1001
// SUB (HL)
1002
OPCodes_SUB(m_pMemory->Read(GetEffectiveAddress()));
1003
}
1004
1005
void Processor::OPCode0x97()
1006
{
1007
// SUB A
1008
OPCodes_SUB(AF.GetHigh());
1009
}
1010
1011
void Processor::OPCode0x98()
1012
{
1013
// SBC B
1014
OPCodes_SBC(BC.GetHigh());
1015
}
1016
1017
void Processor::OPCode0x99()
1018
{
1019
// SBC C
1020
OPCodes_SBC(BC.GetLow());
1021
}
1022
1023
void Processor::OPCode0x9A()
1024
{
1025
// SBC D
1026
OPCodes_SBC(DE.GetHigh());
1027
}
1028
1029
void Processor::OPCode0x9B()
1030
{
1031
// SBC E
1032
OPCodes_SBC(DE.GetLow());
1033
}
1034
1035
void Processor::OPCode0x9C()
1036
{
1037
// SBC H
1038
OPCodes_SBC(GetPrefixedRegister()->GetHigh());
1039
}
1040
1041
void Processor::OPCode0x9D()
1042
{
1043
// SBC L
1044
OPCodes_SBC(GetPrefixedRegister()->GetLow());
1045
}
1046
1047
void Processor::OPCode0x9E()
1048
{
1049
// SBC (HL)
1050
OPCodes_SBC(m_pMemory->Read(GetEffectiveAddress()));
1051
}
1052
1053
void Processor::OPCode0x9F()
1054
{
1055
// SBC A
1056
OPCodes_SBC(AF.GetHigh());
1057
}
1058
1059
void Processor::OPCode0xA0()
1060
{
1061
// AND B
1062
OPCodes_AND(BC.GetHigh());
1063
}
1064
1065
void Processor::OPCode0xA1()
1066
{
1067
// AND C
1068
OPCodes_AND(BC.GetLow());
1069
}
1070
1071
void Processor::OPCode0xA2()
1072
{
1073
// AND D
1074
OPCodes_AND(DE.GetHigh());
1075
}
1076
1077
void Processor::OPCode0xA3()
1078
{
1079
// AND E
1080
OPCodes_AND(DE.GetLow());
1081
}
1082
1083
void Processor::OPCode0xA4()
1084
{
1085
// AND H
1086
OPCodes_AND(GetPrefixedRegister()->GetHigh());
1087
}
1088
1089
void Processor::OPCode0xA5()
1090
{
1091
// AND L
1092
OPCodes_AND(GetPrefixedRegister()->GetLow());
1093
}
1094
1095
void Processor::OPCode0xA6()
1096
{
1097
// AND (HL)
1098
OPCodes_AND(m_pMemory->Read(GetEffectiveAddress()));
1099
}
1100
1101
void Processor::OPCode0xA7()
1102
{
1103
// AND A
1104
OPCodes_AND(AF.GetHigh());
1105
}
1106
1107
void Processor::OPCode0xA8()
1108
{
1109
// XOR B
1110
OPCodes_XOR(BC.GetHigh());
1111
}
1112
1113
void Processor::OPCode0xA9()
1114
{
1115
// XOR C
1116
OPCodes_XOR(BC.GetLow());
1117
}
1118
1119
void Processor::OPCode0xAA()
1120
{
1121
// XOR D
1122
OPCodes_XOR(DE.GetHigh());
1123
}
1124
1125
void Processor::OPCode0xAB()
1126
{
1127
// XOR E
1128
OPCodes_XOR(DE.GetLow());
1129
}
1130
1131
void Processor::OPCode0xAC()
1132
{
1133
// XOR H
1134
OPCodes_XOR(GetPrefixedRegister()->GetHigh());
1135
}
1136
1137
void Processor::OPCode0xAD()
1138
{
1139
// XOR L
1140
OPCodes_XOR(GetPrefixedRegister()->GetLow());
1141
}
1142
1143
void Processor::OPCode0xAE()
1144
{
1145
// XOR (HL)
1146
OPCodes_XOR(m_pMemory->Read(GetEffectiveAddress()));
1147
}
1148
1149
void Processor::OPCode0xAF()
1150
{
1151
// XOR A
1152
OPCodes_XOR(AF.GetHigh());
1153
}
1154
1155
void Processor::OPCode0xB0()
1156
{
1157
// OR B
1158
OPCodes_OR(BC.GetHigh());
1159
}
1160
1161
void Processor::OPCode0xB1()
1162
{
1163
// OR C
1164
OPCodes_OR(BC.GetLow());
1165
}
1166
1167
void Processor::OPCode0xB2()
1168
{
1169
// OR D
1170
OPCodes_OR(DE.GetHigh());
1171
}
1172
1173
void Processor::OPCode0xB3()
1174
{
1175
// OR E
1176
OPCodes_OR(DE.GetLow());
1177
1178
}
1179
1180
void Processor::OPCode0xB4()
1181
{
1182
// OR H
1183
OPCodes_OR(GetPrefixedRegister()->GetHigh());
1184
}
1185
1186
void Processor::OPCode0xB5()
1187
{
1188
// OR L
1189
OPCodes_OR(GetPrefixedRegister()->GetLow());
1190
}
1191
1192
void Processor::OPCode0xB6()
1193
{
1194
// OR (HL)
1195
OPCodes_OR(m_pMemory->Read(GetEffectiveAddress()));
1196
}
1197
1198
void Processor::OPCode0xB7()
1199
{
1200
// OR A
1201
OPCodes_OR(AF.GetHigh());
1202
}
1203
1204
void Processor::OPCode0xB8()
1205
{
1206
// CP B
1207
OPCodes_CP(BC.GetHigh());
1208
}
1209
1210
void Processor::OPCode0xB9()
1211
{
1212
// CP C
1213
OPCodes_CP(BC.GetLow());
1214
}
1215
1216
void Processor::OPCode0xBA()
1217
{
1218
// CP D
1219
OPCodes_CP(DE.GetHigh());
1220
}
1221
1222
void Processor::OPCode0xBB()
1223
{
1224
// CP E
1225
OPCodes_CP(DE.GetLow());
1226
}
1227
1228
void Processor::OPCode0xBC()
1229
{
1230
// CP H
1231
OPCodes_CP(GetPrefixedRegister()->GetHigh());
1232
}
1233
1234
void Processor::OPCode0xBD()
1235
{
1236
// CP L
1237
OPCodes_CP(GetPrefixedRegister()->GetLow());
1238
}
1239
1240
void Processor::OPCode0xBE()
1241
{
1242
// CP (HL)
1243
OPCodes_CP(m_pMemory->Read(GetEffectiveAddress()));
1244
}
1245
1246
void Processor::OPCode0xBF()
1247
{
1248
// CP A
1249
OPCodes_CP(AF.GetHigh());
1250
}
1251
1252
void Processor::OPCode0xC0()
1253
{
1254
// RET NZ
1255
OPCodes_RET_Conditional(!IsSetFlag(FLAG_ZERO));
1256
}
1257
1258
void Processor::OPCode0xC1()
1259
{
1260
// POP BC
1261
StackPop(&BC);
1262
}
1263
1264
void Processor::OPCode0xC2()
1265
{
1266
// JP NZ,nn
1267
OPCodes_JP_nn_Conditional(!IsSetFlag(FLAG_ZERO));
1268
}
1269
1270
void Processor::OPCode0xC3()
1271
{
1272
// JP nn
1273
OPCodes_JP_nn();
1274
}
1275
1276
void Processor::OPCode0xC4()
1277
{
1278
// CALL NZ,nn
1279
OPCodes_CALL_nn_Conditional(!IsSetFlag(FLAG_ZERO));
1280
}
1281
1282
void Processor::OPCode0xC5()
1283
{
1284
// PUSH BC
1285
StackPush(&BC);
1286
}
1287
1288
void Processor::OPCode0xC6()
1289
{
1290
// ADD A,n
1291
OPCodes_ADD(m_pMemory->Read(PC.GetValue()));
1292
PC.Increment();
1293
}
1294
1295
void Processor::OPCode0xC7()
1296
{
1297
// RST 00H
1298
OPCodes_RST(0x0000);
1299
}
1300
1301
void Processor::OPCode0xC8()
1302
{
1303
// RET Z
1304
OPCodes_RET_Conditional(IsSetFlag(FLAG_ZERO));
1305
}
1306
1307
void Processor::OPCode0xC9()
1308
{
1309
// RET
1310
OPCodes_RET();
1311
}
1312
1313
void Processor::OPCode0xCA()
1314
{
1315
// JP Z,nn
1316
OPCodes_JP_nn_Conditional(IsSetFlag(FLAG_ZERO));
1317
}
1318
1319
void Processor::OPCode0xCB()
1320
{
1321
// CB prefixed instruction
1322
InvalidOPCode();
1323
}
1324
1325
void Processor::OPCode0xCC()
1326
{
1327
// CALL Z,nn
1328
OPCodes_CALL_nn_Conditional(IsSetFlag(FLAG_ZERO));
1329
}
1330
1331
void Processor::OPCode0xCD()
1332
{
1333
// CALL nn
1334
OPCodes_CALL_nn();
1335
}
1336
1337
void Processor::OPCode0xCE()
1338
{
1339
// ADC A,n
1340
OPCodes_ADC(m_pMemory->Read(PC.GetValue()));
1341
PC.Increment();
1342
}
1343
1344
void Processor::OPCode0xCF()
1345
{
1346
// RST 08H
1347
OPCodes_RST(0x0008);
1348
}
1349
1350
void Processor::OPCode0xD0()
1351
{
1352
// RET NC
1353
OPCodes_RET_Conditional(!IsSetFlag(FLAG_CARRY));
1354
}
1355
1356
void Processor::OPCode0xD1()
1357
{
1358
// POP DE
1359
StackPop(&DE);
1360
}
1361
1362
void Processor::OPCode0xD2()
1363
{
1364
// JP NC,nn
1365
OPCodes_JP_nn_Conditional(!IsSetFlag(FLAG_CARRY));
1366
}
1367
1368
void Processor::OPCode0xD3()
1369
{
1370
// OUT (n),A
1371
u8 port = m_pMemory->Read(PC.GetValue());
1372
PC.Increment();
1373
m_pIOPorts->Out(port, AF.GetHigh());
1374
WZ.SetLow((port + 1) & 0xFF);
1375
WZ.SetHigh(AF.GetHigh());
1376
}
1377
1378
void Processor::OPCode0xD4()
1379
{
1380
// CALL NC,nn
1381
OPCodes_CALL_nn_Conditional(!IsSetFlag(FLAG_CARRY));
1382
}
1383
1384
void Processor::OPCode0xD5()
1385
{
1386
// PUSH DE
1387
StackPush(&DE);
1388
}
1389
1390
void Processor::OPCode0xD6()
1391
{
1392
// SUB n
1393
OPCodes_SUB(m_pMemory->Read(PC.GetValue()));
1394
PC.Increment();
1395
}
1396
1397
void Processor::OPCode0xD7()
1398
{
1399
// RST 10H
1400
OPCodes_RST(0x0010);
1401
}
1402
1403
void Processor::OPCode0xD8()
1404
{
1405
// RET C
1406
OPCodes_RET_Conditional(IsSetFlag(FLAG_CARRY));
1407
}
1408
1409
void Processor::OPCode0xD9()
1410
{
1411
// EXX
1412
OPCodes_EX(&BC, &BC2);
1413
OPCodes_EX(&DE, &DE2);
1414
OPCodes_EX(&HL, &HL2);
1415
}
1416
1417
void Processor::OPCode0xDA()
1418
{
1419
// JP C,nn
1420
OPCodes_JP_nn_Conditional(IsSetFlag(FLAG_CARRY));
1421
}
1422
1423
void Processor::OPCode0xDB()
1424
{
1425
// IN A,(n)
1426
if (m_bInputLastCycle)
1427
{
1428
u8 a = AF.GetHigh();
1429
u8 port = m_pMemory->Read(PC.GetValue());
1430
PC.Increment();
1431
AF.SetHigh(m_pIOPorts->In(port));
1432
WZ.SetValue((a << 8) | (port + 1));
1433
m_iTStates -= 10;
1434
m_bInputLastCycle = false;
1435
}
1436
else
1437
{
1438
PC.Decrement();
1439
m_iTStates -= 1;
1440
m_bInputLastCycle = true;
1441
}
1442
}
1443
1444
void Processor::OPCode0xDC()
1445
{
1446
// CALL C,nn
1447
OPCodes_CALL_nn_Conditional(IsSetFlag(FLAG_CARRY));
1448
}
1449
1450
void Processor::OPCode0xDD()
1451
{
1452
// DD prefixed instruction
1453
InvalidOPCode();
1454
}
1455
1456
void Processor::OPCode0xDE()
1457
{
1458
// SBC n
1459
OPCodes_SBC(m_pMemory->Read(PC.GetValue()));
1460
PC.Increment();
1461
}
1462
1463
void Processor::OPCode0xDF()
1464
{
1465
// RST 18H
1466
OPCodes_RST(0x0018);
1467
}
1468
1469
void Processor::OPCode0xE0()
1470
{
1471
// RET PO
1472
OPCodes_RET_Conditional(!IsSetFlag(FLAG_PARITY));
1473
}
1474
1475
void Processor::OPCode0xE1()
1476
{
1477
// POP HL
1478
StackPop(GetPrefixedRegister());
1479
}
1480
1481
void Processor::OPCode0xE2()
1482
{
1483
// JP PO,nn
1484
OPCodes_JP_nn_Conditional(!IsSetFlag(FLAG_PARITY));
1485
}
1486
1487
void Processor::OPCode0xE3()
1488
{
1489
// EX (SP),HL
1490
SixteenBitRegister* reg = GetPrefixedRegister();
1491
u8 l = reg->GetLow();
1492
u8 h = reg->GetHigh();
1493
reg->SetLow(m_pMemory->Read(SP.GetValue()));
1494
reg->SetHigh(m_pMemory->Read(SP.GetValue() + 1));
1495
m_pMemory->Write(SP.GetValue(), l);
1496
m_pMemory->Write(SP.GetValue() + 1, h);
1497
WZ.SetValue(reg->GetValue());
1498
}
1499
1500
void Processor::OPCode0xE4()
1501
{
1502
// CALL PO,nn
1503
OPCodes_CALL_nn_Conditional(!IsSetFlag(FLAG_PARITY));
1504
}
1505
1506
void Processor::OPCode0xE5()
1507
{
1508
// PUSH HL
1509
StackPush(GetPrefixedRegister());
1510
}
1511
1512
void Processor::OPCode0xE6()
1513
{
1514
// AND n
1515
OPCodes_AND(m_pMemory->Read(PC.GetValue()));
1516
PC.Increment();
1517
}
1518
1519
void Processor::OPCode0xE7()
1520
{
1521
// RST 20H
1522
OPCodes_RST(0x0020);
1523
}
1524
1525
void Processor::OPCode0xE8()
1526
{
1527
// RET PE
1528
OPCodes_RET_Conditional(IsSetFlag(FLAG_PARITY));
1529
}
1530
1531
void Processor::OPCode0xE9()
1532
{
1533
// JP (HL)
1534
PC.SetValue(GetPrefixedRegister()->GetValue());
1535
}
1536
1537
void Processor::OPCode0xEA()
1538
{
1539
// JP PE,nn
1540
OPCodes_JP_nn_Conditional(IsSetFlag(FLAG_PARITY));
1541
}
1542
1543
void Processor::OPCode0xEB()
1544
{
1545
// EX DE,HL
1546
OPCodes_EX(&DE, &HL);
1547
}
1548
1549
void Processor::OPCode0xEC()
1550
{
1551
// CALL PE,nn
1552
OPCodes_CALL_nn_Conditional(IsSetFlag(FLAG_PARITY));
1553
}
1554
1555
void Processor::OPCode0xED()
1556
{
1557
// ED prefixed instruction
1558
InvalidOPCode();
1559
}
1560
1561
void Processor::OPCode0xEE()
1562
{
1563
// XOR n
1564
OPCodes_XOR(m_pMemory->Read(PC.GetValue()));
1565
PC.Increment();
1566
}
1567
1568
void Processor::OPCode0xEF()
1569
{
1570
// RST 28H
1571
OPCodes_RST(0x28);
1572
}
1573
1574
void Processor::OPCode0xF0()
1575
{
1576
// RET P
1577
OPCodes_RET_Conditional(!IsSetFlag(FLAG_SIGN));
1578
}
1579
1580
void Processor::OPCode0xF1()
1581
{
1582
// POP AF
1583
StackPop(&AF);
1584
}
1585
1586
void Processor::OPCode0xF2()
1587
{
1588
// JP P,nn
1589
OPCodes_JP_nn_Conditional(!IsSetFlag(FLAG_SIGN));
1590
}
1591
1592
void Processor::OPCode0xF3()
1593
{
1594
// DI
1595
m_bIFF1 = false;
1596
m_bIFF2 = false;
1597
}
1598
1599
void Processor::OPCode0xF4()
1600
{
1601
// CALL P,nn
1602
OPCodes_CALL_nn_Conditional(!IsSetFlag(FLAG_SIGN));
1603
}
1604
1605
void Processor::OPCode0xF5()
1606
{
1607
// PUSH AF
1608
StackPush(&AF);
1609
}
1610
1611
void Processor::OPCode0xF6()
1612
{
1613
// OR n
1614
OPCodes_OR(m_pMemory->Read(PC.GetValue()));
1615
PC.Increment();
1616
}
1617
1618
void Processor::OPCode0xF7()
1619
{
1620
// RST 30H
1621
OPCodes_RST(0x0030);
1622
}
1623
1624
void Processor::OPCode0xF8()
1625
{
1626
// RET M
1627
OPCodes_RET_Conditional(IsSetFlag(FLAG_SIGN));
1628
}
1629
1630
void Processor::OPCode0xF9()
1631
{
1632
// LD SP,HL
1633
SP.SetValue(GetPrefixedRegister()->GetValue());
1634
}
1635
1636
void Processor::OPCode0xFA()
1637
{
1638
// JP M,nn
1639
OPCodes_JP_nn_Conditional(IsSetFlag(FLAG_SIGN));
1640
}
1641
1642
void Processor::OPCode0xFB()
1643
{
1644
// EI
1645
m_bIFF1 = true;
1646
m_bIFF2 = true;
1647
m_bAfterEI = true;
1648
}
1649
1650
void Processor::OPCode0xFC()
1651
{
1652
// CALL M,nn
1653
OPCodes_CALL_nn_Conditional(IsSetFlag(FLAG_SIGN));
1654
}
1655
1656
void Processor::OPCode0xFD()
1657
{
1658
// FD prefixed instruction
1659
InvalidOPCode();
1660
}
1661
1662
void Processor::OPCode0xFE()
1663
{
1664
// CP n
1665
OPCodes_CP(m_pMemory->Read(PC.GetValue()));
1666
PC.Increment();
1667
}
1668
1669
void Processor::OPCode0xFF()
1670
{
1671
// RST 38H
1672
OPCodes_RST(0x0038);
1673
}
1674
1675