cscg22-gearboy

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

Processor.cpp (45789B)


      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 <algorithm>
     21#include <ctype.h>
     22#include "Processor.h"
     23#include "opcode_timing.h"
     24#include "opcode_names.h"
     25
     26Processor::Processor(Memory* pMemory)
     27{
     28    m_pMemory = pMemory;
     29    m_pMemory->SetProcessor(this);
     30    InitOPCodeFunctors();
     31    m_bIME = false;
     32    m_bHalt = false;
     33    m_bCGBSpeed = false;
     34    m_iSpeedMultiplier = 0;
     35    m_bBranchTaken = false;
     36    m_bSkipPCBug = false;
     37    m_iCurrentClockCycles = 0;
     38    m_iDIVCycles = 0;
     39    m_iTIMACycles = 0;
     40    m_iIMECycles = 0;
     41    m_iSerialBit = 0;
     42    m_iSerialCycles = 0;
     43    m_bCGB = false;
     44    m_iUnhaltCycles = 0;
     45    m_iInterruptDelayCycles = 0;
     46    m_iAccurateOPCodeState = 0;
     47    m_iReadCache = 0;
     48    m_bBreakpointHit = false;
     49    m_bRequestMemBreakpoint = false;
     50
     51    m_ProcessorState.AF = &AF;
     52    m_ProcessorState.BC = &BC;
     53    m_ProcessorState.DE = &DE;
     54    m_ProcessorState.HL = &HL;
     55    m_ProcessorState.SP = &SP;
     56    m_ProcessorState.PC = &PC;
     57    m_ProcessorState.IME = &m_bIME;
     58    m_ProcessorState.Halt = &m_bHalt;
     59}
     60
     61Processor::~Processor()
     62{
     63}
     64
     65void Processor::Init()
     66{
     67    Reset(false, false);
     68}
     69
     70void Processor::Reset(bool bCGB, bool bGBA)
     71{
     72    m_bCGB = bCGB;
     73    m_bIME = false;
     74    m_bHalt = false;
     75    m_bCGBSpeed = false;
     76    m_iSpeedMultiplier = 0;
     77    m_bBranchTaken = false;
     78    m_bSkipPCBug = false;
     79    m_iCurrentClockCycles = 0;
     80    m_iDIVCycles = 0;
     81    m_iTIMACycles = 0;
     82    m_iIMECycles = 0;
     83    m_iSerialBit = 0;
     84    m_iSerialCycles = 0;
     85    m_iUnhaltCycles = 0;
     86
     87    if(m_pMemory->IsBootromEnabled())
     88    {
     89        PC.SetValue(0);
     90        SP.SetValue(0);
     91        AF.SetValue(0);
     92        BC.SetValue(0);
     93        DE.SetValue(0);
     94        HL.SetValue(0);
     95    }
     96    else
     97    {
     98        m_pMemory->DisableBootromRegistry();
     99        PC.SetValue(0x100);
    100        SP.SetValue(0xFFFE);
    101
    102        if (m_bCGB)
    103        {
    104            if (bGBA)
    105            {
    106                AF.SetValue(0x1100);
    107                BC.SetValue(0x0100);
    108            }
    109            else
    110            {
    111                AF.SetValue(0x1180);
    112                BC.SetValue(0x0000);
    113            }
    114            DE.SetValue(0xFF56);
    115            HL.SetValue(0x000D);
    116        }
    117        else
    118        {
    119            AF.SetValue(0x01B0);
    120            BC.SetValue(0x0013);
    121            DE.SetValue(0x00D8);
    122            HL.SetValue(0x014D);
    123        }
    124    }
    125
    126    m_iInterruptDelayCycles = 0;
    127    m_iAccurateOPCodeState = 0;
    128    m_iReadCache = 0;
    129    m_GameSharkList.clear();
    130    m_bBreakpointHit = false;
    131    m_bRequestMemBreakpoint = false;
    132}
    133
    134u8 Processor::RunFor(u8 ticks)
    135{
    136    u8 executed = 0;
    137
    138    while (executed < ticks)
    139    {
    140        m_iCurrentClockCycles = 0;
    141        m_bBreakpointHit = false;
    142        m_bRequestMemBreakpoint = false;
    143
    144        if (m_iAccurateOPCodeState == 0 && m_bHalt)
    145        {
    146            m_iCurrentClockCycles += AdjustedCycles(4);
    147
    148            if (m_iUnhaltCycles > 0)
    149            {
    150                m_iUnhaltCycles -= m_iCurrentClockCycles;
    151
    152                if (m_iUnhaltCycles <= 0)
    153                {
    154                    m_iUnhaltCycles = 0;
    155                    m_bHalt = false;
    156                }
    157            }
    158
    159            if (m_bHalt && (InterruptPending() != None_Interrupt) && (m_iUnhaltCycles == 0))
    160            {
    161                m_iUnhaltCycles = AdjustedCycles(12);
    162            }
    163        }
    164
    165        bool interrupt_served = false;
    166
    167        if (!m_bHalt)
    168        {
    169            Interrupts interrupt = InterruptPending();
    170
    171            if (m_bIME && (interrupt != None_Interrupt) && (m_iAccurateOPCodeState == 0))
    172            {
    173                ServeInterrupt(interrupt);
    174                interrupt_served = true;
    175            }
    176            else
    177            {
    178                u8 opcode = m_pMemory->Read(PC.GetValue());
    179                PC.Increment();
    180
    181                if (m_bSkipPCBug)
    182                {
    183                    m_bSkipPCBug = false;
    184                    PC.Decrement();
    185                }
    186
    187                const u8* accurateOPcodes;
    188                const u8* machineCycles;
    189                OPCptr* opcodeTable;
    190                bool isCB = (opcode == 0xCB);
    191
    192                if (isCB)
    193                {
    194                    accurateOPcodes = kOPCodeCBAccurate;
    195                    machineCycles = kOPCodeCBMachineCycles;
    196                    opcodeTable = m_OPCodesCB;
    197
    198                    opcode = m_pMemory->Read(PC.GetValue());
    199                    PC.Increment();
    200
    201                    if (m_bSkipPCBug)
    202                    {
    203                        m_bSkipPCBug = false;
    204                        PC.Decrement();
    205                    }
    206                }
    207                else
    208                {
    209                    accurateOPcodes = kOPCodeAccurate;
    210                    machineCycles = kOPCodeMachineCycles;
    211                    opcodeTable = m_OPCodes;
    212                }
    213
    214                if ((accurateOPcodes[opcode] != 0) && (m_iAccurateOPCodeState == 0))
    215                {
    216                    int left_cycles = (accurateOPcodes[opcode] < 3 ? 2 : 3);
    217                    m_iCurrentClockCycles += (machineCycles[opcode] - left_cycles) * AdjustedCycles(4);
    218                    m_iAccurateOPCodeState = 1;
    219                    PC.Decrement();
    220                    if (isCB)
    221                        PC.Decrement();
    222                }
    223                else
    224                {
    225                    (this->*opcodeTable[opcode])();
    226
    227                    if (m_bBranchTaken)
    228                    {
    229                        m_bBranchTaken = false;
    230                        m_iCurrentClockCycles += kOPCodeBranchMachineCycles[opcode] * AdjustedCycles(4);
    231                    }
    232                    else
    233                    {
    234                        switch (m_iAccurateOPCodeState)
    235                        {
    236                        case 0:
    237                            m_iCurrentClockCycles += machineCycles[opcode] * AdjustedCycles(4);
    238                            break;
    239                        case 1:
    240                            if (accurateOPcodes[opcode] == 3)
    241                            {
    242                                m_iCurrentClockCycles += 1 * AdjustedCycles(4);
    243                                m_iAccurateOPCodeState = 2;
    244                                PC.Decrement();
    245                                if (isCB)
    246                                    PC.Decrement();
    247                            }
    248                            else
    249                            {
    250                                m_iCurrentClockCycles += 2 * AdjustedCycles(4);
    251                                m_iAccurateOPCodeState = 0;
    252                            }
    253                            break;
    254                        case 2:
    255                            m_iCurrentClockCycles += 2 * AdjustedCycles(4);
    256                            m_iAccurateOPCodeState = 0;
    257                            break;
    258                        }
    259                    }
    260                }
    261            }
    262
    263            #ifndef GEARBOY_DISABLE_DISASSEMBLER
    264            if (Disassemble(PC.GetValue()) || m_bRequestMemBreakpoint)
    265                m_bBreakpointHit = true;
    266            #endif
    267        }
    268
    269        if (!interrupt_served && (m_iInterruptDelayCycles > 0))
    270        {
    271            m_iInterruptDelayCycles -= m_iCurrentClockCycles;
    272        }
    273
    274        if (!interrupt_served && (m_iAccurateOPCodeState == 0) && (m_iIMECycles > 0))
    275        {
    276            m_iIMECycles -= m_iCurrentClockCycles;
    277
    278            if (m_iIMECycles <= 0)
    279            {
    280                m_iIMECycles = 0;
    281                m_bIME = true;
    282            }
    283        }
    284
    285        executed += m_iCurrentClockCycles;
    286    }
    287
    288    return executed;
    289}
    290
    291void Processor::ServeInterrupt(Interrupts interrupt)
    292{
    293    u8 if_reg = m_pMemory->Retrieve(0xFF0F);
    294    m_bIME = false;
    295    StackPush(&PC);
    296    m_iCurrentClockCycles += AdjustedCycles(20);
    297    
    298    switch (interrupt)
    299    {
    300        case VBlank_Interrupt:
    301            m_iInterruptDelayCycles= 0;
    302            m_pMemory->Load(0xFF0F, if_reg & 0xFE);
    303            PC.SetValue(0x0040);
    304            UpdateGameShark();
    305            break;
    306        case LCDSTAT_Interrupt:
    307            m_pMemory->Load(0xFF0F, if_reg & 0xFD);
    308            PC.SetValue(0x0048);
    309            break;
    310        case Timer_Interrupt:
    311            m_pMemory->Load(0xFF0F, if_reg & 0xFB);
    312            PC.SetValue(0x0050);
    313            break;
    314        case Serial_Interrupt:
    315            m_pMemory->Load(0xFF0F, if_reg & 0xF7);
    316            PC.SetValue(0x0058);
    317            break;
    318        case Joypad_Interrupt:
    319            m_pMemory->Load(0xFF0F, if_reg & 0xEF);
    320            PC.SetValue(0x0060);
    321            break;
    322        case None_Interrupt:
    323            break;
    324    }
    325}
    326
    327void Processor::UpdateTimers(u8 ticks)
    328{
    329    m_iDIVCycles += ticks;
    330
    331    unsigned int div_cycles = AdjustedCycles(256);
    332
    333    while (m_iDIVCycles >= div_cycles)
    334    {
    335        m_iDIVCycles -= div_cycles;
    336        u8 div = m_pMemory->Retrieve(0xFF04);
    337        div++;
    338        m_pMemory->Load(0xFF04, div);
    339    }
    340
    341    u8 tac = m_pMemory->Retrieve(0xFF07);
    342
    343    // if tima is running
    344    if (tac & 0x04)
    345    {
    346        m_iTIMACycles += ticks;
    347
    348        unsigned int freq = 0;
    349
    350        switch (tac & 0x03)
    351        {
    352            case 0:
    353                freq = AdjustedCycles(1024);
    354                break;
    355            case 1:
    356                freq = AdjustedCycles(16);
    357                break;
    358            case 2:
    359                freq = AdjustedCycles(64);
    360                break;
    361            case 3:
    362                freq = AdjustedCycles(256);
    363                break;
    364        }
    365
    366        while (m_iTIMACycles >= freq)
    367        {
    368            m_iTIMACycles -= freq;
    369            u8 tima = m_pMemory->Retrieve(0xFF05);
    370
    371            if (tima == 0xFF)
    372            {
    373                tima = m_pMemory->Retrieve(0xFF06);
    374                RequestInterrupt(Timer_Interrupt);
    375            }
    376            else
    377                tima++;
    378
    379            m_pMemory->Load(0xFF05, tima);
    380        }
    381    }
    382}
    383
    384void Processor::UpdateSerial(u8 ticks)
    385{
    386    u8 sc = m_pMemory->Retrieve(0xFF02);
    387
    388    if (IsSetBit(sc, 7) && IsSetBit(sc, 0))
    389    {
    390        m_iSerialCycles += ticks;
    391
    392        if (m_iSerialBit < 0)
    393        {
    394            m_iSerialBit = 0;
    395            m_iSerialCycles = 0;
    396            return;
    397        }
    398
    399        int serial_cycles = AdjustedCycles(512);
    400
    401        if (m_iSerialCycles >= serial_cycles)
    402        {
    403            if (m_iSerialBit > 7)
    404            {
    405                m_pMemory->Load(0xFF02, sc & 0x7F);
    406                RequestInterrupt(Serial_Interrupt);
    407                m_iSerialBit = -1;
    408
    409                return;
    410            }
    411
    412            u8 sb = m_pMemory->Retrieve(0xFF01);
    413            sb <<= 1;
    414            sb |= 0x01;
    415            m_pMemory->Load(0xFF01, sb);
    416
    417            m_iSerialCycles -= serial_cycles;
    418            m_iSerialBit++;
    419        }
    420    }
    421}
    422
    423void Processor::UpdateGameShark()
    424{
    425    std::list<GameSharkCode>::iterator it;
    426
    427    for (it = m_GameSharkList.begin(); it != m_GameSharkList.end(); it++)
    428    {
    429        if (it->type == 0x01)
    430        {
    431            m_pMemory->Write(it->address, it->value);
    432        }
    433    }
    434}
    435
    436bool Processor::Disassemble(u16 address)
    437{
    438    Memory::stDisassembleRecord** memoryMap = m_pMemory->GetDisassembledMemoryMap();
    439    Memory::stDisassembleRecord** romMap = m_pMemory->GetDisassembledROMMemoryMap();
    440
    441    Memory::stDisassembleRecord** map = NULL;
    442
    443    int offset = address;
    444    int bank = 0;
    445    bool rom = false;
    446
    447    if ((address & 0xC000) == 0x0000)
    448    {
    449        bank = m_pMemory->GetCurrentRule()->GetCurrentRomBank0Index();
    450        offset = (0x4000 * bank) + address;
    451        map = romMap;
    452        rom = true;
    453    }
    454    else if ((address & 0xC000) == 0x4000)
    455    {
    456        bank = m_pMemory->GetCurrentRule()->GetCurrentRomBank1Index();
    457        offset = (0x4000 * bank) + (address & 0x3FFF);
    458        map = romMap;
    459        rom = true;
    460    }
    461    else
    462    {
    463        map = memoryMap;
    464        rom = false;
    465    }
    466
    467    if (!IsValidPointer(map[offset]))
    468    {
    469        map[offset] = new Memory::stDisassembleRecord;
    470
    471        if (rom)
    472        {
    473            map[offset]->address = offset & 0x3FFF;
    474            map[offset]->bank = offset >> 14;
    475        }
    476        else
    477        {
    478            map[offset]->address = 0;
    479            map[offset]->bank = 0;
    480        }
    481
    482        map[offset]->name[0] = 0;
    483        map[offset]->bytes[0] = 0;
    484        map[offset]->size = 0;
    485        map[offset]->jump = false;
    486        map[offset]->jump_address = 0;
    487        for (int i = 0; i < 4; i++)
    488            map[offset]->opcodes[i] = 0;
    489    }
    490
    491    u8 opcodes[4];
    492    bool changed = false;
    493
    494    for (int i = 0; i < map[offset]->size; i++)
    495    {
    496        opcodes[i] = m_pMemory->Read(address + i);
    497
    498        if (opcodes[i] != map[offset]->opcodes[i])
    499            changed = true;
    500    }
    501
    502    if ((map[offset]->size == 0) || changed)
    503    {
    504        map[offset]->bank = bank;
    505        map[offset]->address = address;
    506
    507        for (int i = 0; i < 4; i++)
    508            map[offset]->opcodes[i] = m_pMemory->Read(address + i);
    509
    510        u8 opcode = map[offset]->opcodes[0];
    511        bool cb = false;
    512
    513        if (opcode == 0xCB)
    514        {
    515            cb = true;
    516            opcode = map[offset]->opcodes[1];
    517        }
    518
    519        stOPCodeInfo info = cb ? kOPCodeCBNames[opcode] : kOPCodeNames[opcode];
    520
    521        map[offset]->size = info.size;
    522
    523        map[offset]->bytes[0] = 0;
    524
    525        for (int i = 0; i < 4; i++)
    526        {
    527            if (i < info.size)
    528            {
    529                char value[8];
    530                sprintf(value, "%02X", map[offset]->opcodes[i]);
    531                strcat(map[offset]->bytes, value);
    532            }
    533            else
    534            {
    535                strcat(map[offset]->bytes, "  ");
    536            }
    537
    538            if (i < 3)
    539                strcat(map[offset]->bytes, " ");
    540        }
    541
    542        switch (info.type)
    543        {
    544            case 0:
    545                strcpy(map[offset]->name, info.name);
    546                break;
    547            case 1:
    548                sprintf(map[offset]->name, info.name, map[offset]->opcodes[1]);
    549                break;
    550            case 2:
    551                map[offset]->jump = true;
    552                map[offset]->jump_address = (map[offset]->opcodes[2] << 8) | map[offset]->opcodes[1];
    553                sprintf(map[offset]->name, info.name, map[offset]->jump_address);
    554                break;
    555            case 3:
    556                sprintf(map[offset]->name, info.name, (s8)map[offset]->opcodes[1]);
    557                break;
    558            case 4:
    559                map[offset]->jump = true;
    560                map[offset]->jump_address = address + info.size + (s8)map[offset]->opcodes[1];
    561                sprintf(map[offset]->name, info.name, map[offset]->jump_address, (s8)map[offset]->opcodes[1]);
    562                break;
    563            case 5:
    564                sprintf(map[offset]->name, info.name, map[offset]->opcodes[1], kRegisterNames[map[offset]->opcodes[1]]);
    565                break;
    566            default:
    567                strcpy(map[offset]->name, "PARSE ERROR");
    568        }
    569    }
    570
    571    Memory::stDisassembleRecord* runtobreakpoint = m_pMemory->GetRunToBreakpoint();
    572    std::vector<Memory::stDisassembleRecord*>* breakpoints = m_pMemory->GetBreakpointsCPU();
    573
    574    if (IsValidPointer(runtobreakpoint))
    575    {
    576        if (runtobreakpoint == map[offset])
    577        {
    578            m_pMemory->SetRunToBreakpoint(NULL);
    579            return true;
    580        }
    581        else
    582            return false;
    583    }
    584    else
    585    {
    586        std::size_t size = breakpoints->size();
    587
    588        for (std::size_t b = 0; b < size; b++)
    589        {
    590            if ((*breakpoints)[b] == map[offset])
    591            {
    592                return true;
    593            }
    594        }
    595    }
    596
    597    return false;
    598}
    599
    600bool Processor::BreakpointHit()
    601{
    602    return m_bBreakpointHit;
    603}
    604
    605void Processor::RequestMemoryBreakpoint()
    606{
    607    m_bRequestMemBreakpoint = true;
    608}
    609
    610void Processor::SaveState(std::ostream& stream)
    611{
    612    using namespace std;
    613
    614    u16 af = AF.GetValue();
    615    u16 bc = BC.GetValue();
    616    u16 de = DE.GetValue();
    617    u16 hl = HL.GetValue();
    618    u16 sp = SP.GetValue();
    619    u16 pc = PC.GetValue();
    620
    621    stream.write(reinterpret_cast<const char*> (&af), sizeof(af));
    622    stream.write(reinterpret_cast<const char*> (&bc), sizeof(bc));
    623    stream.write(reinterpret_cast<const char*> (&de), sizeof(de));
    624    stream.write(reinterpret_cast<const char*> (&hl), sizeof(hl));
    625    stream.write(reinterpret_cast<const char*> (&sp), sizeof(sp));
    626    stream.write(reinterpret_cast<const char*> (&pc), sizeof(pc));
    627
    628    stream.write(reinterpret_cast<const char*> (&m_bIME), sizeof(m_bIME));
    629    stream.write(reinterpret_cast<const char*> (&m_bHalt), sizeof(m_bHalt));
    630    stream.write(reinterpret_cast<const char*> (&m_bBranchTaken), sizeof(m_bBranchTaken));
    631    stream.write(reinterpret_cast<const char*> (&m_bSkipPCBug), sizeof(m_bSkipPCBug));
    632    stream.write(reinterpret_cast<const char*> (&m_iCurrentClockCycles), sizeof(m_iCurrentClockCycles));
    633    stream.write(reinterpret_cast<const char*> (&m_iDIVCycles), sizeof(m_iDIVCycles));
    634    stream.write(reinterpret_cast<const char*> (&m_iTIMACycles), sizeof(m_iTIMACycles));
    635    stream.write(reinterpret_cast<const char*> (&m_iSerialBit), sizeof(m_iSerialBit));
    636    stream.write(reinterpret_cast<const char*> (&m_iSerialCycles), sizeof(m_iSerialCycles));
    637    stream.write(reinterpret_cast<const char*> (&m_iIMECycles), sizeof(m_iIMECycles));
    638    stream.write(reinterpret_cast<const char*> (&m_iUnhaltCycles), sizeof(m_iUnhaltCycles));
    639    stream.write(reinterpret_cast<const char*> (&m_iInterruptDelayCycles), sizeof(m_iInterruptDelayCycles));
    640    stream.write(reinterpret_cast<const char*> (&m_bCGBSpeed), sizeof(m_bCGBSpeed));
    641    stream.write(reinterpret_cast<const char*> (&m_iSpeedMultiplier), sizeof(m_iSpeedMultiplier));
    642    stream.write(reinterpret_cast<const char*> (&m_iAccurateOPCodeState), sizeof(m_iAccurateOPCodeState));
    643    stream.write(reinterpret_cast<const char*> (&m_iReadCache), sizeof(m_iReadCache));
    644}
    645
    646void Processor::LoadState(std::istream& stream)
    647{
    648    using namespace std;
    649
    650    u16 af;
    651    u16 bc;
    652    u16 de;
    653    u16 hl;
    654    u16 sp;
    655    u16 pc;
    656
    657    stream.read(reinterpret_cast<char*> (&af), sizeof(af));
    658    stream.read(reinterpret_cast<char*> (&bc), sizeof(bc));
    659    stream.read(reinterpret_cast<char*> (&de), sizeof(de));
    660    stream.read(reinterpret_cast<char*> (&hl), sizeof(hl));
    661    stream.read(reinterpret_cast<char*> (&sp), sizeof(sp));
    662    stream.read(reinterpret_cast<char*> (&pc), sizeof(pc));
    663
    664    AF.SetValue(af);
    665    BC.SetValue(bc);
    666    DE.SetValue(de);
    667    HL.SetValue(hl);
    668    SP.SetValue(sp);
    669    PC.SetValue(pc);
    670
    671    stream.read(reinterpret_cast<char*> (&m_bIME), sizeof(m_bIME));
    672    stream.read(reinterpret_cast<char*> (&m_bHalt), sizeof(m_bHalt));
    673    stream.read(reinterpret_cast<char*> (&m_bBranchTaken), sizeof(m_bBranchTaken));
    674    stream.read(reinterpret_cast<char*> (&m_bSkipPCBug), sizeof(m_bSkipPCBug));
    675    stream.read(reinterpret_cast<char*> (&m_iCurrentClockCycles), sizeof(m_iCurrentClockCycles));
    676    stream.read(reinterpret_cast<char*> (&m_iDIVCycles), sizeof(m_iDIVCycles));
    677    stream.read(reinterpret_cast<char*> (&m_iTIMACycles), sizeof(m_iTIMACycles));
    678    stream.read(reinterpret_cast<char*> (&m_iSerialBit), sizeof(m_iSerialBit));
    679    stream.read(reinterpret_cast<char*> (&m_iSerialCycles), sizeof(m_iSerialCycles));
    680    stream.read(reinterpret_cast<char*> (&m_iIMECycles), sizeof(m_iIMECycles));
    681    stream.read(reinterpret_cast<char*> (&m_iUnhaltCycles), sizeof(m_iUnhaltCycles));
    682    stream.read(reinterpret_cast<char*> (&m_iInterruptDelayCycles), sizeof(m_iInterruptDelayCycles));
    683    stream.read(reinterpret_cast<char*> (&m_bCGBSpeed), sizeof(m_bCGBSpeed));
    684    stream.read(reinterpret_cast<char*> (&m_iSpeedMultiplier), sizeof(m_iSpeedMultiplier));
    685    stream.read(reinterpret_cast<char*> (&m_iAccurateOPCodeState), sizeof(m_iAccurateOPCodeState));
    686    stream.read(reinterpret_cast<char*> (&m_iReadCache), sizeof(m_iReadCache));
    687}
    688
    689void Processor::SetGameSharkCheat(const char* szCheat)
    690{
    691    std::string code(szCheat);
    692    for (std::string::iterator p = code.begin(); code.end() != p; ++p)
    693        *p = toupper(*p);
    694
    695    if (code.length() == 8)
    696    {
    697        GameSharkCode gsc;
    698
    699        gsc.type = AsHex(code[0]) << 4 | AsHex(code[1]);
    700        gsc.value = (AsHex(code[2]) << 4 | AsHex(code[3])) & 0xFF;
    701        gsc.address = (AsHex(code[4]) << 4 | AsHex(code[5]) | AsHex(code[6]) << 12 | AsHex(code[7]) << 8) & 0xFFFF;
    702
    703        m_GameSharkList.push_back(gsc);
    704    }
    705}
    706
    707void Processor::ClearGameSharkCheats()
    708{
    709    m_GameSharkList.clear();
    710}
    711
    712Processor::ProcessorState* Processor::GetState()
    713{
    714    return &m_ProcessorState;
    715}
    716
    717void Processor::InitOPCodeFunctors()
    718{
    719    m_OPCodes[0x00] = &Processor::OPCode0x00;
    720    m_OPCodes[0x01] = &Processor::OPCode0x01;
    721    m_OPCodes[0x02] = &Processor::OPCode0x02;
    722    m_OPCodes[0x03] = &Processor::OPCode0x03;
    723    m_OPCodes[0x04] = &Processor::OPCode0x04;
    724    m_OPCodes[0x05] = &Processor::OPCode0x05;
    725    m_OPCodes[0x06] = &Processor::OPCode0x06;
    726    m_OPCodes[0x07] = &Processor::OPCode0x07;
    727    m_OPCodes[0x08] = &Processor::OPCode0x08;
    728    m_OPCodes[0x09] = &Processor::OPCode0x09;
    729    m_OPCodes[0x0A] = &Processor::OPCode0x0A;
    730    m_OPCodes[0x0B] = &Processor::OPCode0x0B;
    731    m_OPCodes[0x0C] = &Processor::OPCode0x0C;
    732    m_OPCodes[0x0D] = &Processor::OPCode0x0D;
    733    m_OPCodes[0x0E] = &Processor::OPCode0x0E;
    734    m_OPCodes[0x0F] = &Processor::OPCode0x0F;
    735
    736    m_OPCodes[0x10] = &Processor::OPCode0x10;
    737    m_OPCodes[0x11] = &Processor::OPCode0x11;
    738    m_OPCodes[0x12] = &Processor::OPCode0x12;
    739    m_OPCodes[0x13] = &Processor::OPCode0x13;
    740    m_OPCodes[0x14] = &Processor::OPCode0x14;
    741    m_OPCodes[0x15] = &Processor::OPCode0x15;
    742    m_OPCodes[0x16] = &Processor::OPCode0x16;
    743    m_OPCodes[0x17] = &Processor::OPCode0x17;
    744    m_OPCodes[0x18] = &Processor::OPCode0x18;
    745    m_OPCodes[0x19] = &Processor::OPCode0x19;
    746    m_OPCodes[0x1A] = &Processor::OPCode0x1A;
    747    m_OPCodes[0x1B] = &Processor::OPCode0x1B;
    748    m_OPCodes[0x1C] = &Processor::OPCode0x1C;
    749    m_OPCodes[0x1D] = &Processor::OPCode0x1D;
    750    m_OPCodes[0x1E] = &Processor::OPCode0x1E;
    751    m_OPCodes[0x1F] = &Processor::OPCode0x1F;
    752
    753    m_OPCodes[0x20] = &Processor::OPCode0x20;
    754    m_OPCodes[0x21] = &Processor::OPCode0x21;
    755    m_OPCodes[0x22] = &Processor::OPCode0x22;
    756    m_OPCodes[0x23] = &Processor::OPCode0x23;
    757    m_OPCodes[0x24] = &Processor::OPCode0x24;
    758    m_OPCodes[0x25] = &Processor::OPCode0x25;
    759    m_OPCodes[0x26] = &Processor::OPCode0x26;
    760    m_OPCodes[0x27] = &Processor::OPCode0x27;
    761    m_OPCodes[0x28] = &Processor::OPCode0x28;
    762    m_OPCodes[0x29] = &Processor::OPCode0x29;
    763    m_OPCodes[0x2A] = &Processor::OPCode0x2A;
    764    m_OPCodes[0x2B] = &Processor::OPCode0x2B;
    765    m_OPCodes[0x2C] = &Processor::OPCode0x2C;
    766    m_OPCodes[0x2D] = &Processor::OPCode0x2D;
    767    m_OPCodes[0x2E] = &Processor::OPCode0x2E;
    768    m_OPCodes[0x2F] = &Processor::OPCode0x2F;
    769
    770    m_OPCodes[0x30] = &Processor::OPCode0x30;
    771    m_OPCodes[0x31] = &Processor::OPCode0x31;
    772    m_OPCodes[0x32] = &Processor::OPCode0x32;
    773    m_OPCodes[0x33] = &Processor::OPCode0x33;
    774    m_OPCodes[0x34] = &Processor::OPCode0x34;
    775    m_OPCodes[0x35] = &Processor::OPCode0x35;
    776    m_OPCodes[0x36] = &Processor::OPCode0x36;
    777    m_OPCodes[0x37] = &Processor::OPCode0x37;
    778    m_OPCodes[0x38] = &Processor::OPCode0x38;
    779    m_OPCodes[0x39] = &Processor::OPCode0x39;
    780    m_OPCodes[0x3A] = &Processor::OPCode0x3A;
    781    m_OPCodes[0x3B] = &Processor::OPCode0x3B;
    782    m_OPCodes[0x3C] = &Processor::OPCode0x3C;
    783    m_OPCodes[0x3D] = &Processor::OPCode0x3D;
    784    m_OPCodes[0x3E] = &Processor::OPCode0x3E;
    785    m_OPCodes[0x3F] = &Processor::OPCode0x3F;
    786
    787    m_OPCodes[0x40] = &Processor::OPCode0x40;
    788    m_OPCodes[0x41] = &Processor::OPCode0x41;
    789    m_OPCodes[0x42] = &Processor::OPCode0x42;
    790    m_OPCodes[0x43] = &Processor::OPCode0x43;
    791    m_OPCodes[0x44] = &Processor::OPCode0x44;
    792    m_OPCodes[0x45] = &Processor::OPCode0x45;
    793    m_OPCodes[0x46] = &Processor::OPCode0x46;
    794    m_OPCodes[0x47] = &Processor::OPCode0x47;
    795    m_OPCodes[0x48] = &Processor::OPCode0x48;
    796    m_OPCodes[0x49] = &Processor::OPCode0x49;
    797    m_OPCodes[0x4A] = &Processor::OPCode0x4A;
    798    m_OPCodes[0x4B] = &Processor::OPCode0x4B;
    799    m_OPCodes[0x4C] = &Processor::OPCode0x4C;
    800    m_OPCodes[0x4D] = &Processor::OPCode0x4D;
    801    m_OPCodes[0x4E] = &Processor::OPCode0x4E;
    802    m_OPCodes[0x4F] = &Processor::OPCode0x4F;
    803
    804    m_OPCodes[0x50] = &Processor::OPCode0x50;
    805    m_OPCodes[0x51] = &Processor::OPCode0x51;
    806    m_OPCodes[0x52] = &Processor::OPCode0x52;
    807    m_OPCodes[0x53] = &Processor::OPCode0x53;
    808    m_OPCodes[0x54] = &Processor::OPCode0x54;
    809    m_OPCodes[0x55] = &Processor::OPCode0x55;
    810    m_OPCodes[0x56] = &Processor::OPCode0x56;
    811    m_OPCodes[0x57] = &Processor::OPCode0x57;
    812    m_OPCodes[0x58] = &Processor::OPCode0x58;
    813    m_OPCodes[0x59] = &Processor::OPCode0x59;
    814    m_OPCodes[0x5A] = &Processor::OPCode0x5A;
    815    m_OPCodes[0x5B] = &Processor::OPCode0x5B;
    816    m_OPCodes[0x5C] = &Processor::OPCode0x5C;
    817    m_OPCodes[0x5D] = &Processor::OPCode0x5D;
    818    m_OPCodes[0x5E] = &Processor::OPCode0x5E;
    819    m_OPCodes[0x5F] = &Processor::OPCode0x5F;
    820
    821    m_OPCodes[0x60] = &Processor::OPCode0x60;
    822    m_OPCodes[0x61] = &Processor::OPCode0x61;
    823    m_OPCodes[0x62] = &Processor::OPCode0x62;
    824    m_OPCodes[0x63] = &Processor::OPCode0x63;
    825    m_OPCodes[0x64] = &Processor::OPCode0x64;
    826    m_OPCodes[0x65] = &Processor::OPCode0x65;
    827    m_OPCodes[0x66] = &Processor::OPCode0x66;
    828    m_OPCodes[0x67] = &Processor::OPCode0x67;
    829    m_OPCodes[0x68] = &Processor::OPCode0x68;
    830    m_OPCodes[0x69] = &Processor::OPCode0x69;
    831    m_OPCodes[0x6A] = &Processor::OPCode0x6A;
    832    m_OPCodes[0x6B] = &Processor::OPCode0x6B;
    833    m_OPCodes[0x6C] = &Processor::OPCode0x6C;
    834    m_OPCodes[0x6D] = &Processor::OPCode0x6D;
    835    m_OPCodes[0x6E] = &Processor::OPCode0x6E;
    836    m_OPCodes[0x6F] = &Processor::OPCode0x6F;
    837
    838    m_OPCodes[0x70] = &Processor::OPCode0x70;
    839    m_OPCodes[0x71] = &Processor::OPCode0x71;
    840    m_OPCodes[0x72] = &Processor::OPCode0x72;
    841    m_OPCodes[0x73] = &Processor::OPCode0x73;
    842    m_OPCodes[0x74] = &Processor::OPCode0x74;
    843    m_OPCodes[0x75] = &Processor::OPCode0x75;
    844    m_OPCodes[0x76] = &Processor::OPCode0x76;
    845    m_OPCodes[0x77] = &Processor::OPCode0x77;
    846    m_OPCodes[0x78] = &Processor::OPCode0x78;
    847    m_OPCodes[0x79] = &Processor::OPCode0x79;
    848    m_OPCodes[0x7A] = &Processor::OPCode0x7A;
    849    m_OPCodes[0x7B] = &Processor::OPCode0x7B;
    850    m_OPCodes[0x7C] = &Processor::OPCode0x7C;
    851    m_OPCodes[0x7D] = &Processor::OPCode0x7D;
    852    m_OPCodes[0x7E] = &Processor::OPCode0x7E;
    853    m_OPCodes[0x7F] = &Processor::OPCode0x7F;
    854
    855    m_OPCodes[0x80] = &Processor::OPCode0x80;
    856    m_OPCodes[0x81] = &Processor::OPCode0x81;
    857    m_OPCodes[0x82] = &Processor::OPCode0x82;
    858    m_OPCodes[0x83] = &Processor::OPCode0x83;
    859    m_OPCodes[0x84] = &Processor::OPCode0x84;
    860    m_OPCodes[0x85] = &Processor::OPCode0x85;
    861    m_OPCodes[0x86] = &Processor::OPCode0x86;
    862    m_OPCodes[0x87] = &Processor::OPCode0x87;
    863    m_OPCodes[0x88] = &Processor::OPCode0x88;
    864    m_OPCodes[0x89] = &Processor::OPCode0x89;
    865    m_OPCodes[0x8A] = &Processor::OPCode0x8A;
    866    m_OPCodes[0x8B] = &Processor::OPCode0x8B;
    867    m_OPCodes[0x8C] = &Processor::OPCode0x8C;
    868    m_OPCodes[0x8D] = &Processor::OPCode0x8D;
    869    m_OPCodes[0x8E] = &Processor::OPCode0x8E;
    870    m_OPCodes[0x8F] = &Processor::OPCode0x8F;
    871
    872    m_OPCodes[0x90] = &Processor::OPCode0x90;
    873    m_OPCodes[0x91] = &Processor::OPCode0x91;
    874    m_OPCodes[0x92] = &Processor::OPCode0x92;
    875    m_OPCodes[0x93] = &Processor::OPCode0x93;
    876    m_OPCodes[0x94] = &Processor::OPCode0x94;
    877    m_OPCodes[0x95] = &Processor::OPCode0x95;
    878    m_OPCodes[0x96] = &Processor::OPCode0x96;
    879    m_OPCodes[0x97] = &Processor::OPCode0x97;
    880    m_OPCodes[0x98] = &Processor::OPCode0x98;
    881    m_OPCodes[0x99] = &Processor::OPCode0x99;
    882    m_OPCodes[0x9A] = &Processor::OPCode0x9A;
    883    m_OPCodes[0x9B] = &Processor::OPCode0x9B;
    884    m_OPCodes[0x9C] = &Processor::OPCode0x9C;
    885    m_OPCodes[0x9D] = &Processor::OPCode0x9D;
    886    m_OPCodes[0x9E] = &Processor::OPCode0x9E;
    887    m_OPCodes[0x9F] = &Processor::OPCode0x9F;
    888
    889    m_OPCodes[0xA0] = &Processor::OPCode0xA0;
    890    m_OPCodes[0xA1] = &Processor::OPCode0xA1;
    891    m_OPCodes[0xA2] = &Processor::OPCode0xA2;
    892    m_OPCodes[0xA3] = &Processor::OPCode0xA3;
    893    m_OPCodes[0xA4] = &Processor::OPCode0xA4;
    894    m_OPCodes[0xA5] = &Processor::OPCode0xA5;
    895    m_OPCodes[0xA6] = &Processor::OPCode0xA6;
    896    m_OPCodes[0xA7] = &Processor::OPCode0xA7;
    897    m_OPCodes[0xA8] = &Processor::OPCode0xA8;
    898    m_OPCodes[0xA9] = &Processor::OPCode0xA9;
    899    m_OPCodes[0xAA] = &Processor::OPCode0xAA;
    900    m_OPCodes[0xAB] = &Processor::OPCode0xAB;
    901    m_OPCodes[0xAC] = &Processor::OPCode0xAC;
    902    m_OPCodes[0xAD] = &Processor::OPCode0xAD;
    903    m_OPCodes[0xAE] = &Processor::OPCode0xAE;
    904    m_OPCodes[0xAF] = &Processor::OPCode0xAF;
    905
    906    m_OPCodes[0xB0] = &Processor::OPCode0xB0;
    907    m_OPCodes[0xB1] = &Processor::OPCode0xB1;
    908    m_OPCodes[0xB2] = &Processor::OPCode0xB2;
    909    m_OPCodes[0xB3] = &Processor::OPCode0xB3;
    910    m_OPCodes[0xB4] = &Processor::OPCode0xB4;
    911    m_OPCodes[0xB5] = &Processor::OPCode0xB5;
    912    m_OPCodes[0xB6] = &Processor::OPCode0xB6;
    913    m_OPCodes[0xB7] = &Processor::OPCode0xB7;
    914    m_OPCodes[0xB8] = &Processor::OPCode0xB8;
    915    m_OPCodes[0xB9] = &Processor::OPCode0xB9;
    916    m_OPCodes[0xBA] = &Processor::OPCode0xBA;
    917    m_OPCodes[0xBB] = &Processor::OPCode0xBB;
    918    m_OPCodes[0xBC] = &Processor::OPCode0xBC;
    919    m_OPCodes[0xBD] = &Processor::OPCode0xBD;
    920    m_OPCodes[0xBE] = &Processor::OPCode0xBE;
    921    m_OPCodes[0xBF] = &Processor::OPCode0xBF;
    922
    923    m_OPCodes[0xC0] = &Processor::OPCode0xC0;
    924    m_OPCodes[0xC1] = &Processor::OPCode0xC1;
    925    m_OPCodes[0xC2] = &Processor::OPCode0xC2;
    926    m_OPCodes[0xC3] = &Processor::OPCode0xC3;
    927    m_OPCodes[0xC4] = &Processor::OPCode0xC4;
    928    m_OPCodes[0xC5] = &Processor::OPCode0xC5;
    929    m_OPCodes[0xC6] = &Processor::OPCode0xC6;
    930    m_OPCodes[0xC7] = &Processor::OPCode0xC7;
    931    m_OPCodes[0xC8] = &Processor::OPCode0xC8;
    932    m_OPCodes[0xC9] = &Processor::OPCode0xC9;
    933    m_OPCodes[0xCA] = &Processor::OPCode0xCA;
    934    m_OPCodes[0xCB] = &Processor::OPCode0xCB;
    935    m_OPCodes[0xCC] = &Processor::OPCode0xCC;
    936    m_OPCodes[0xCD] = &Processor::OPCode0xCD;
    937    m_OPCodes[0xCE] = &Processor::OPCode0xCE;
    938    m_OPCodes[0xCF] = &Processor::OPCode0xCF;
    939
    940    m_OPCodes[0xD0] = &Processor::OPCode0xD0;
    941    m_OPCodes[0xD1] = &Processor::OPCode0xD1;
    942    m_OPCodes[0xD2] = &Processor::OPCode0xD2;
    943    m_OPCodes[0xD3] = &Processor::OPCode0xD3;
    944    m_OPCodes[0xD4] = &Processor::OPCode0xD4;
    945    m_OPCodes[0xD5] = &Processor::OPCode0xD5;
    946    m_OPCodes[0xD6] = &Processor::OPCode0xD6;
    947    m_OPCodes[0xD7] = &Processor::OPCode0xD7;
    948    m_OPCodes[0xD8] = &Processor::OPCode0xD8;
    949    m_OPCodes[0xD9] = &Processor::OPCode0xD9;
    950    m_OPCodes[0xDA] = &Processor::OPCode0xDA;
    951    m_OPCodes[0xDB] = &Processor::OPCode0xDB;
    952    m_OPCodes[0xDC] = &Processor::OPCode0xDC;
    953    m_OPCodes[0xDD] = &Processor::OPCode0xDD;
    954    m_OPCodes[0xDE] = &Processor::OPCode0xDE;
    955    m_OPCodes[0xDF] = &Processor::OPCode0xDF;
    956
    957    m_OPCodes[0xE0] = &Processor::OPCode0xE0;
    958    m_OPCodes[0xE1] = &Processor::OPCode0xE1;
    959    m_OPCodes[0xE2] = &Processor::OPCode0xE2;
    960    m_OPCodes[0xE3] = &Processor::OPCode0xE3;
    961    m_OPCodes[0xE4] = &Processor::OPCode0xE4;
    962    m_OPCodes[0xE5] = &Processor::OPCode0xE5;
    963    m_OPCodes[0xE6] = &Processor::OPCode0xE6;
    964    m_OPCodes[0xE7] = &Processor::OPCode0xE7;
    965    m_OPCodes[0xE8] = &Processor::OPCode0xE8;
    966    m_OPCodes[0xE9] = &Processor::OPCode0xE9;
    967    m_OPCodes[0xEA] = &Processor::OPCode0xEA;
    968    m_OPCodes[0xEB] = &Processor::OPCode0xEB;
    969    m_OPCodes[0xEC] = &Processor::OPCode0xEC;
    970    m_OPCodes[0xED] = &Processor::OPCode0xED;
    971    m_OPCodes[0xEE] = &Processor::OPCode0xEE;
    972    m_OPCodes[0xEF] = &Processor::OPCode0xEF;
    973
    974    m_OPCodes[0xF0] = &Processor::OPCode0xF0;
    975    m_OPCodes[0xF1] = &Processor::OPCode0xF1;
    976    m_OPCodes[0xF2] = &Processor::OPCode0xF2;
    977    m_OPCodes[0xF3] = &Processor::OPCode0xF3;
    978    m_OPCodes[0xF4] = &Processor::OPCode0xF4;
    979    m_OPCodes[0xF5] = &Processor::OPCode0xF5;
    980    m_OPCodes[0xF6] = &Processor::OPCode0xF6;
    981    m_OPCodes[0xF7] = &Processor::OPCode0xF7;
    982    m_OPCodes[0xF8] = &Processor::OPCode0xF8;
    983    m_OPCodes[0xF9] = &Processor::OPCode0xF9;
    984    m_OPCodes[0xFA] = &Processor::OPCode0xFA;
    985    m_OPCodes[0xFB] = &Processor::OPCode0xFB;
    986    m_OPCodes[0xFC] = &Processor::OPCode0xFC;
    987    m_OPCodes[0xFD] = &Processor::OPCode0xFD;
    988    m_OPCodes[0xFE] = &Processor::OPCode0xFE;
    989    m_OPCodes[0xFF] = &Processor::OPCode0xFF;
    990
    991
    992    m_OPCodesCB[0x00] = &Processor::OPCodeCB0x00;
    993    m_OPCodesCB[0x01] = &Processor::OPCodeCB0x01;
    994    m_OPCodesCB[0x02] = &Processor::OPCodeCB0x02;
    995    m_OPCodesCB[0x03] = &Processor::OPCodeCB0x03;
    996    m_OPCodesCB[0x04] = &Processor::OPCodeCB0x04;
    997    m_OPCodesCB[0x05] = &Processor::OPCodeCB0x05;
    998    m_OPCodesCB[0x06] = &Processor::OPCodeCB0x06;
    999    m_OPCodesCB[0x07] = &Processor::OPCodeCB0x07;
   1000    m_OPCodesCB[0x08] = &Processor::OPCodeCB0x08;
   1001    m_OPCodesCB[0x09] = &Processor::OPCodeCB0x09;
   1002    m_OPCodesCB[0x0A] = &Processor::OPCodeCB0x0A;
   1003    m_OPCodesCB[0x0B] = &Processor::OPCodeCB0x0B;
   1004    m_OPCodesCB[0x0C] = &Processor::OPCodeCB0x0C;
   1005    m_OPCodesCB[0x0D] = &Processor::OPCodeCB0x0D;
   1006    m_OPCodesCB[0x0E] = &Processor::OPCodeCB0x0E;
   1007    m_OPCodesCB[0x0F] = &Processor::OPCodeCB0x0F;
   1008
   1009    m_OPCodesCB[0x10] = &Processor::OPCodeCB0x10;
   1010    m_OPCodesCB[0x11] = &Processor::OPCodeCB0x11;
   1011    m_OPCodesCB[0x12] = &Processor::OPCodeCB0x12;
   1012    m_OPCodesCB[0x13] = &Processor::OPCodeCB0x13;
   1013    m_OPCodesCB[0x14] = &Processor::OPCodeCB0x14;
   1014    m_OPCodesCB[0x15] = &Processor::OPCodeCB0x15;
   1015    m_OPCodesCB[0x16] = &Processor::OPCodeCB0x16;
   1016    m_OPCodesCB[0x17] = &Processor::OPCodeCB0x17;
   1017    m_OPCodesCB[0x18] = &Processor::OPCodeCB0x18;
   1018    m_OPCodesCB[0x19] = &Processor::OPCodeCB0x19;
   1019    m_OPCodesCB[0x1A] = &Processor::OPCodeCB0x1A;
   1020    m_OPCodesCB[0x1B] = &Processor::OPCodeCB0x1B;
   1021    m_OPCodesCB[0x1C] = &Processor::OPCodeCB0x1C;
   1022    m_OPCodesCB[0x1D] = &Processor::OPCodeCB0x1D;
   1023    m_OPCodesCB[0x1E] = &Processor::OPCodeCB0x1E;
   1024    m_OPCodesCB[0x1F] = &Processor::OPCodeCB0x1F;
   1025
   1026    m_OPCodesCB[0x20] = &Processor::OPCodeCB0x20;
   1027    m_OPCodesCB[0x21] = &Processor::OPCodeCB0x21;
   1028    m_OPCodesCB[0x22] = &Processor::OPCodeCB0x22;
   1029    m_OPCodesCB[0x23] = &Processor::OPCodeCB0x23;
   1030    m_OPCodesCB[0x24] = &Processor::OPCodeCB0x24;
   1031    m_OPCodesCB[0x25] = &Processor::OPCodeCB0x25;
   1032    m_OPCodesCB[0x26] = &Processor::OPCodeCB0x26;
   1033    m_OPCodesCB[0x27] = &Processor::OPCodeCB0x27;
   1034    m_OPCodesCB[0x28] = &Processor::OPCodeCB0x28;
   1035    m_OPCodesCB[0x29] = &Processor::OPCodeCB0x29;
   1036    m_OPCodesCB[0x2A] = &Processor::OPCodeCB0x2A;
   1037    m_OPCodesCB[0x2B] = &Processor::OPCodeCB0x2B;
   1038    m_OPCodesCB[0x2C] = &Processor::OPCodeCB0x2C;
   1039    m_OPCodesCB[0x2D] = &Processor::OPCodeCB0x2D;
   1040    m_OPCodesCB[0x2E] = &Processor::OPCodeCB0x2E;
   1041    m_OPCodesCB[0x2F] = &Processor::OPCodeCB0x2F;
   1042
   1043    m_OPCodesCB[0x30] = &Processor::OPCodeCB0x30;
   1044    m_OPCodesCB[0x31] = &Processor::OPCodeCB0x31;
   1045    m_OPCodesCB[0x32] = &Processor::OPCodeCB0x32;
   1046    m_OPCodesCB[0x33] = &Processor::OPCodeCB0x33;
   1047    m_OPCodesCB[0x34] = &Processor::OPCodeCB0x34;
   1048    m_OPCodesCB[0x35] = &Processor::OPCodeCB0x35;
   1049    m_OPCodesCB[0x36] = &Processor::OPCodeCB0x36;
   1050    m_OPCodesCB[0x37] = &Processor::OPCodeCB0x37;
   1051    m_OPCodesCB[0x38] = &Processor::OPCodeCB0x38;
   1052    m_OPCodesCB[0x39] = &Processor::OPCodeCB0x39;
   1053    m_OPCodesCB[0x3A] = &Processor::OPCodeCB0x3A;
   1054    m_OPCodesCB[0x3B] = &Processor::OPCodeCB0x3B;
   1055    m_OPCodesCB[0x3C] = &Processor::OPCodeCB0x3C;
   1056    m_OPCodesCB[0x3D] = &Processor::OPCodeCB0x3D;
   1057    m_OPCodesCB[0x3E] = &Processor::OPCodeCB0x3E;
   1058    m_OPCodesCB[0x3F] = &Processor::OPCodeCB0x3F;
   1059
   1060    m_OPCodesCB[0x40] = &Processor::OPCodeCB0x40;
   1061    m_OPCodesCB[0x41] = &Processor::OPCodeCB0x41;
   1062    m_OPCodesCB[0x42] = &Processor::OPCodeCB0x42;
   1063    m_OPCodesCB[0x43] = &Processor::OPCodeCB0x43;
   1064    m_OPCodesCB[0x44] = &Processor::OPCodeCB0x44;
   1065    m_OPCodesCB[0x45] = &Processor::OPCodeCB0x45;
   1066    m_OPCodesCB[0x46] = &Processor::OPCodeCB0x46;
   1067    m_OPCodesCB[0x47] = &Processor::OPCodeCB0x47;
   1068    m_OPCodesCB[0x48] = &Processor::OPCodeCB0x48;
   1069    m_OPCodesCB[0x49] = &Processor::OPCodeCB0x49;
   1070    m_OPCodesCB[0x4A] = &Processor::OPCodeCB0x4A;
   1071    m_OPCodesCB[0x4B] = &Processor::OPCodeCB0x4B;
   1072    m_OPCodesCB[0x4C] = &Processor::OPCodeCB0x4C;
   1073    m_OPCodesCB[0x4D] = &Processor::OPCodeCB0x4D;
   1074    m_OPCodesCB[0x4E] = &Processor::OPCodeCB0x4E;
   1075    m_OPCodesCB[0x4F] = &Processor::OPCodeCB0x4F;
   1076
   1077    m_OPCodesCB[0x50] = &Processor::OPCodeCB0x50;
   1078    m_OPCodesCB[0x51] = &Processor::OPCodeCB0x51;
   1079    m_OPCodesCB[0x52] = &Processor::OPCodeCB0x52;
   1080    m_OPCodesCB[0x53] = &Processor::OPCodeCB0x53;
   1081    m_OPCodesCB[0x54] = &Processor::OPCodeCB0x54;
   1082    m_OPCodesCB[0x55] = &Processor::OPCodeCB0x55;
   1083    m_OPCodesCB[0x56] = &Processor::OPCodeCB0x56;
   1084    m_OPCodesCB[0x57] = &Processor::OPCodeCB0x57;
   1085    m_OPCodesCB[0x58] = &Processor::OPCodeCB0x58;
   1086    m_OPCodesCB[0x59] = &Processor::OPCodeCB0x59;
   1087    m_OPCodesCB[0x5A] = &Processor::OPCodeCB0x5A;
   1088    m_OPCodesCB[0x5B] = &Processor::OPCodeCB0x5B;
   1089    m_OPCodesCB[0x5C] = &Processor::OPCodeCB0x5C;
   1090    m_OPCodesCB[0x5D] = &Processor::OPCodeCB0x5D;
   1091    m_OPCodesCB[0x5E] = &Processor::OPCodeCB0x5E;
   1092    m_OPCodesCB[0x5F] = &Processor::OPCodeCB0x5F;
   1093
   1094    m_OPCodesCB[0x60] = &Processor::OPCodeCB0x60;
   1095    m_OPCodesCB[0x61] = &Processor::OPCodeCB0x61;
   1096    m_OPCodesCB[0x62] = &Processor::OPCodeCB0x62;
   1097    m_OPCodesCB[0x63] = &Processor::OPCodeCB0x63;
   1098    m_OPCodesCB[0x64] = &Processor::OPCodeCB0x64;
   1099    m_OPCodesCB[0x65] = &Processor::OPCodeCB0x65;
   1100    m_OPCodesCB[0x66] = &Processor::OPCodeCB0x66;
   1101    m_OPCodesCB[0x67] = &Processor::OPCodeCB0x67;
   1102    m_OPCodesCB[0x68] = &Processor::OPCodeCB0x68;
   1103    m_OPCodesCB[0x69] = &Processor::OPCodeCB0x69;
   1104    m_OPCodesCB[0x6A] = &Processor::OPCodeCB0x6A;
   1105    m_OPCodesCB[0x6B] = &Processor::OPCodeCB0x6B;
   1106    m_OPCodesCB[0x6C] = &Processor::OPCodeCB0x6C;
   1107    m_OPCodesCB[0x6D] = &Processor::OPCodeCB0x6D;
   1108    m_OPCodesCB[0x6E] = &Processor::OPCodeCB0x6E;
   1109    m_OPCodesCB[0x6F] = &Processor::OPCodeCB0x6F;
   1110
   1111    m_OPCodesCB[0x70] = &Processor::OPCodeCB0x70;
   1112    m_OPCodesCB[0x71] = &Processor::OPCodeCB0x71;
   1113    m_OPCodesCB[0x72] = &Processor::OPCodeCB0x72;
   1114    m_OPCodesCB[0x73] = &Processor::OPCodeCB0x73;
   1115    m_OPCodesCB[0x74] = &Processor::OPCodeCB0x74;
   1116    m_OPCodesCB[0x75] = &Processor::OPCodeCB0x75;
   1117    m_OPCodesCB[0x76] = &Processor::OPCodeCB0x76;
   1118    m_OPCodesCB[0x77] = &Processor::OPCodeCB0x77;
   1119    m_OPCodesCB[0x78] = &Processor::OPCodeCB0x78;
   1120    m_OPCodesCB[0x79] = &Processor::OPCodeCB0x79;
   1121    m_OPCodesCB[0x7A] = &Processor::OPCodeCB0x7A;
   1122    m_OPCodesCB[0x7B] = &Processor::OPCodeCB0x7B;
   1123    m_OPCodesCB[0x7C] = &Processor::OPCodeCB0x7C;
   1124    m_OPCodesCB[0x7D] = &Processor::OPCodeCB0x7D;
   1125    m_OPCodesCB[0x7E] = &Processor::OPCodeCB0x7E;
   1126    m_OPCodesCB[0x7F] = &Processor::OPCodeCB0x7F;
   1127
   1128    m_OPCodesCB[0x80] = &Processor::OPCodeCB0x80;
   1129    m_OPCodesCB[0x81] = &Processor::OPCodeCB0x81;
   1130    m_OPCodesCB[0x82] = &Processor::OPCodeCB0x82;
   1131    m_OPCodesCB[0x83] = &Processor::OPCodeCB0x83;
   1132    m_OPCodesCB[0x84] = &Processor::OPCodeCB0x84;
   1133    m_OPCodesCB[0x85] = &Processor::OPCodeCB0x85;
   1134    m_OPCodesCB[0x86] = &Processor::OPCodeCB0x86;
   1135    m_OPCodesCB[0x87] = &Processor::OPCodeCB0x87;
   1136    m_OPCodesCB[0x88] = &Processor::OPCodeCB0x88;
   1137    m_OPCodesCB[0x89] = &Processor::OPCodeCB0x89;
   1138    m_OPCodesCB[0x8A] = &Processor::OPCodeCB0x8A;
   1139    m_OPCodesCB[0x8B] = &Processor::OPCodeCB0x8B;
   1140    m_OPCodesCB[0x8C] = &Processor::OPCodeCB0x8C;
   1141    m_OPCodesCB[0x8D] = &Processor::OPCodeCB0x8D;
   1142    m_OPCodesCB[0x8E] = &Processor::OPCodeCB0x8E;
   1143    m_OPCodesCB[0x8F] = &Processor::OPCodeCB0x8F;
   1144
   1145    m_OPCodesCB[0x90] = &Processor::OPCodeCB0x90;
   1146    m_OPCodesCB[0x91] = &Processor::OPCodeCB0x91;
   1147    m_OPCodesCB[0x92] = &Processor::OPCodeCB0x92;
   1148    m_OPCodesCB[0x93] = &Processor::OPCodeCB0x93;
   1149    m_OPCodesCB[0x94] = &Processor::OPCodeCB0x94;
   1150    m_OPCodesCB[0x95] = &Processor::OPCodeCB0x95;
   1151    m_OPCodesCB[0x96] = &Processor::OPCodeCB0x96;
   1152    m_OPCodesCB[0x97] = &Processor::OPCodeCB0x97;
   1153    m_OPCodesCB[0x98] = &Processor::OPCodeCB0x98;
   1154    m_OPCodesCB[0x99] = &Processor::OPCodeCB0x99;
   1155    m_OPCodesCB[0x9A] = &Processor::OPCodeCB0x9A;
   1156    m_OPCodesCB[0x9B] = &Processor::OPCodeCB0x9B;
   1157    m_OPCodesCB[0x9C] = &Processor::OPCodeCB0x9C;
   1158    m_OPCodesCB[0x9D] = &Processor::OPCodeCB0x9D;
   1159    m_OPCodesCB[0x9E] = &Processor::OPCodeCB0x9E;
   1160    m_OPCodesCB[0x9F] = &Processor::OPCodeCB0x9F;
   1161
   1162    m_OPCodesCB[0xA0] = &Processor::OPCodeCB0xA0;
   1163    m_OPCodesCB[0xA1] = &Processor::OPCodeCB0xA1;
   1164    m_OPCodesCB[0xA2] = &Processor::OPCodeCB0xA2;
   1165    m_OPCodesCB[0xA3] = &Processor::OPCodeCB0xA3;
   1166    m_OPCodesCB[0xA4] = &Processor::OPCodeCB0xA4;
   1167    m_OPCodesCB[0xA5] = &Processor::OPCodeCB0xA5;
   1168    m_OPCodesCB[0xA6] = &Processor::OPCodeCB0xA6;
   1169    m_OPCodesCB[0xA7] = &Processor::OPCodeCB0xA7;
   1170    m_OPCodesCB[0xA8] = &Processor::OPCodeCB0xA8;
   1171    m_OPCodesCB[0xA9] = &Processor::OPCodeCB0xA9;
   1172    m_OPCodesCB[0xAA] = &Processor::OPCodeCB0xAA;
   1173    m_OPCodesCB[0xAB] = &Processor::OPCodeCB0xAB;
   1174    m_OPCodesCB[0xAC] = &Processor::OPCodeCB0xAC;
   1175    m_OPCodesCB[0xAD] = &Processor::OPCodeCB0xAD;
   1176    m_OPCodesCB[0xAE] = &Processor::OPCodeCB0xAE;
   1177    m_OPCodesCB[0xAF] = &Processor::OPCodeCB0xAF;
   1178
   1179    m_OPCodesCB[0xB0] = &Processor::OPCodeCB0xB0;
   1180    m_OPCodesCB[0xB1] = &Processor::OPCodeCB0xB1;
   1181    m_OPCodesCB[0xB2] = &Processor::OPCodeCB0xB2;
   1182    m_OPCodesCB[0xB3] = &Processor::OPCodeCB0xB3;
   1183    m_OPCodesCB[0xB4] = &Processor::OPCodeCB0xB4;
   1184    m_OPCodesCB[0xB5] = &Processor::OPCodeCB0xB5;
   1185    m_OPCodesCB[0xB6] = &Processor::OPCodeCB0xB6;
   1186    m_OPCodesCB[0xB7] = &Processor::OPCodeCB0xB7;
   1187    m_OPCodesCB[0xB8] = &Processor::OPCodeCB0xB8;
   1188    m_OPCodesCB[0xB9] = &Processor::OPCodeCB0xB9;
   1189    m_OPCodesCB[0xBA] = &Processor::OPCodeCB0xBA;
   1190    m_OPCodesCB[0xBB] = &Processor::OPCodeCB0xBB;
   1191    m_OPCodesCB[0xBC] = &Processor::OPCodeCB0xBC;
   1192    m_OPCodesCB[0xBD] = &Processor::OPCodeCB0xBD;
   1193    m_OPCodesCB[0xBE] = &Processor::OPCodeCB0xBE;
   1194    m_OPCodesCB[0xBF] = &Processor::OPCodeCB0xBF;
   1195
   1196    m_OPCodesCB[0xC0] = &Processor::OPCodeCB0xC0;
   1197    m_OPCodesCB[0xC1] = &Processor::OPCodeCB0xC1;
   1198    m_OPCodesCB[0xC2] = &Processor::OPCodeCB0xC2;
   1199    m_OPCodesCB[0xC3] = &Processor::OPCodeCB0xC3;
   1200    m_OPCodesCB[0xC4] = &Processor::OPCodeCB0xC4;
   1201    m_OPCodesCB[0xC5] = &Processor::OPCodeCB0xC5;
   1202    m_OPCodesCB[0xC6] = &Processor::OPCodeCB0xC6;
   1203    m_OPCodesCB[0xC7] = &Processor::OPCodeCB0xC7;
   1204    m_OPCodesCB[0xC8] = &Processor::OPCodeCB0xC8;
   1205    m_OPCodesCB[0xC9] = &Processor::OPCodeCB0xC9;
   1206    m_OPCodesCB[0xCA] = &Processor::OPCodeCB0xCA;
   1207    m_OPCodesCB[0xCB] = &Processor::OPCodeCB0xCB;
   1208    m_OPCodesCB[0xCC] = &Processor::OPCodeCB0xCC;
   1209    m_OPCodesCB[0xCD] = &Processor::OPCodeCB0xCD;
   1210    m_OPCodesCB[0xCE] = &Processor::OPCodeCB0xCE;
   1211    m_OPCodesCB[0xCF] = &Processor::OPCodeCB0xCF;
   1212
   1213    m_OPCodesCB[0xD0] = &Processor::OPCodeCB0xD0;
   1214    m_OPCodesCB[0xD1] = &Processor::OPCodeCB0xD1;
   1215    m_OPCodesCB[0xD2] = &Processor::OPCodeCB0xD2;
   1216    m_OPCodesCB[0xD3] = &Processor::OPCodeCB0xD3;
   1217    m_OPCodesCB[0xD4] = &Processor::OPCodeCB0xD4;
   1218    m_OPCodesCB[0xD5] = &Processor::OPCodeCB0xD5;
   1219    m_OPCodesCB[0xD6] = &Processor::OPCodeCB0xD6;
   1220    m_OPCodesCB[0xD7] = &Processor::OPCodeCB0xD7;
   1221    m_OPCodesCB[0xD8] = &Processor::OPCodeCB0xD8;
   1222    m_OPCodesCB[0xD9] = &Processor::OPCodeCB0xD9;
   1223    m_OPCodesCB[0xDA] = &Processor::OPCodeCB0xDA;
   1224    m_OPCodesCB[0xDB] = &Processor::OPCodeCB0xDB;
   1225    m_OPCodesCB[0xDC] = &Processor::OPCodeCB0xDC;
   1226    m_OPCodesCB[0xDD] = &Processor::OPCodeCB0xDD;
   1227    m_OPCodesCB[0xDE] = &Processor::OPCodeCB0xDE;
   1228    m_OPCodesCB[0xDF] = &Processor::OPCodeCB0xDF;
   1229
   1230    m_OPCodesCB[0xE0] = &Processor::OPCodeCB0xE0;
   1231    m_OPCodesCB[0xE1] = &Processor::OPCodeCB0xE1;
   1232    m_OPCodesCB[0xE2] = &Processor::OPCodeCB0xE2;
   1233    m_OPCodesCB[0xE3] = &Processor::OPCodeCB0xE3;
   1234    m_OPCodesCB[0xE4] = &Processor::OPCodeCB0xE4;
   1235    m_OPCodesCB[0xE5] = &Processor::OPCodeCB0xE5;
   1236    m_OPCodesCB[0xE6] = &Processor::OPCodeCB0xE6;
   1237    m_OPCodesCB[0xE7] = &Processor::OPCodeCB0xE7;
   1238    m_OPCodesCB[0xE8] = &Processor::OPCodeCB0xE8;
   1239    m_OPCodesCB[0xE9] = &Processor::OPCodeCB0xE9;
   1240    m_OPCodesCB[0xEA] = &Processor::OPCodeCB0xEA;
   1241    m_OPCodesCB[0xEB] = &Processor::OPCodeCB0xEB;
   1242    m_OPCodesCB[0xEC] = &Processor::OPCodeCB0xEC;
   1243    m_OPCodesCB[0xED] = &Processor::OPCodeCB0xED;
   1244    m_OPCodesCB[0xEE] = &Processor::OPCodeCB0xEE;
   1245    m_OPCodesCB[0xEF] = &Processor::OPCodeCB0xEF;
   1246
   1247    m_OPCodesCB[0xF0] = &Processor::OPCodeCB0xF0;
   1248    m_OPCodesCB[0xF1] = &Processor::OPCodeCB0xF1;
   1249    m_OPCodesCB[0xF2] = &Processor::OPCodeCB0xF2;
   1250    m_OPCodesCB[0xF3] = &Processor::OPCodeCB0xF3;
   1251    m_OPCodesCB[0xF4] = &Processor::OPCodeCB0xF4;
   1252    m_OPCodesCB[0xF5] = &Processor::OPCodeCB0xF5;
   1253    m_OPCodesCB[0xF6] = &Processor::OPCodeCB0xF6;
   1254    m_OPCodesCB[0xF7] = &Processor::OPCodeCB0xF7;
   1255    m_OPCodesCB[0xF8] = &Processor::OPCodeCB0xF8;
   1256    m_OPCodesCB[0xF9] = &Processor::OPCodeCB0xF9;
   1257    m_OPCodesCB[0xFA] = &Processor::OPCodeCB0xFA;
   1258    m_OPCodesCB[0xFB] = &Processor::OPCodeCB0xFB;
   1259    m_OPCodesCB[0xFC] = &Processor::OPCodeCB0xFC;
   1260    m_OPCodesCB[0xFD] = &Processor::OPCodeCB0xFD;
   1261    m_OPCodesCB[0xFE] = &Processor::OPCodeCB0xFE;
   1262    m_OPCodesCB[0xFF] = &Processor::OPCodeCB0xFF;
   1263}