cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

opcodes.cpp (30105B)


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