cscg22-gearboy

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

Memory_inline.h (4892B)


      1#ifndef MEMORY_INLINE_H
      2#define	MEMORY_INLINE_H
      3
      4#include "CommonMemoryRule.h"
      5#include "IORegistersMemoryRule.h"
      6
      7inline u8 Memory::Read(u16 address)
      8{
      9    #ifndef GEARBOY_DISABLE_DISASSEMBLER
     10    CheckBreakpoints(address, false);
     11    #endif
     12
     13    switch (address & 0xE000)
     14    {
     15        case 0x0000:
     16        {
     17            if (!m_bBootromRegistryDisabled)
     18            {
     19                if (m_bCGB)
     20                {
     21                    if (m_bBootromGBCEnabled && m_bBootromGBCLoaded && ((address < 0x0100) || (address < 0x0900 && address > 0x01FF)))
     22                        return m_pBootromGBC[address];
     23                }
     24                else
     25                {
     26                    if (m_bBootromDMGEnabled && m_bBootromDMGLoaded && (address < 0x0100))
     27                        return m_pBootromDMG[address];
     28                }
     29            }
     30
     31            return m_pCurrentMemoryRule->PerformRead(address);
     32        }
     33        case 0x2000:
     34        case 0x4000:
     35        case 0x6000:
     36        {
     37            return m_pCurrentMemoryRule->PerformRead(address);
     38        }
     39        case 0x8000:
     40        {
     41            return m_pCommonMemoryRule->PerformRead(address);
     42        }
     43        case 0xA000:
     44        {
     45            return m_pCurrentMemoryRule->PerformRead(address);
     46        }
     47        case 0xC000:
     48        case 0xE000:
     49        {
     50            if (address < 0xFF00)
     51                return m_pCommonMemoryRule->PerformRead(address);
     52            else
     53                return m_pIORegistersMemoryRule->PerformRead(address);
     54        }
     55        default:
     56        {
     57            return Retrieve(address);
     58        }
     59    }
     60}
     61
     62inline void Memory::Write(u16 address, u8 value)
     63{
     64    #ifndef GEARBOY_DISABLE_DISASSEMBLER
     65    CheckBreakpoints(address, true);
     66    #endif
     67
     68    switch (address & 0xE000)
     69    {
     70        case 0x0000:
     71        case 0x2000:
     72        case 0x4000:
     73        case 0x6000:
     74        {
     75            m_pCurrentMemoryRule->PerformWrite(address, value);
     76            break;
     77        }
     78        case 0x8000:
     79        {
     80            m_pCommonMemoryRule->PerformWrite(address, value);
     81            break;
     82        }
     83        case 0xA000:
     84        {
     85            m_pCurrentMemoryRule->PerformWrite(address, value);
     86            break;
     87        }
     88        case 0xC000:
     89        case 0xE000:
     90        {
     91            if (address < 0xFF00)
     92                m_pCommonMemoryRule->PerformWrite(address, value);
     93            else
     94                m_pIORegistersMemoryRule->PerformWrite(address, value);
     95            break;
     96        }
     97        default:
     98        {
     99            Load(address, value);
    100            break;
    101        }
    102    }
    103}
    104
    105inline u8 Memory::ReadCGBWRAM(u16 address)
    106{
    107    if (address < 0xD000)
    108        return m_pWRAMBanks[(address - 0xC000)];
    109    else
    110        return m_pWRAMBanks[(address - 0xD000) + (0x1000 * m_iCurrentWRAMBank)];
    111}
    112
    113inline void Memory::WriteCGBWRAM(u16 address, u8 value)
    114{
    115    if (address < 0xD000)
    116        m_pWRAMBanks[(address - 0xC000)] = value;
    117    else
    118        m_pWRAMBanks[(address - 0xD000) + (0x1000 * m_iCurrentWRAMBank)] = value;
    119}
    120
    121inline void Memory::SwitchCGBWRAM(u8 value)
    122{
    123    m_iCurrentWRAMBank = value;
    124
    125    if (m_iCurrentWRAMBank == 0)
    126        m_iCurrentWRAMBank = 1;
    127}
    128
    129inline u8 Memory::ReadCGBLCDRAM(u16 address, bool forceBank1)
    130{
    131    if (forceBank1 || (m_iCurrentLCDRAMBank == 1))
    132        return m_pLCDRAMBank1[address - 0x8000];
    133    else
    134        return Retrieve(address);
    135}
    136
    137inline void Memory::WriteCGBLCDRAM(u16 address, u8 value)
    138{
    139    if (m_iCurrentLCDRAMBank == 1)
    140        m_pLCDRAMBank1[address - 0x8000] = value;
    141    else
    142        Load(address, value);
    143}
    144
    145inline void Memory::SwitchCGBLCDRAM(u8 value)
    146{
    147    m_iCurrentLCDRAMBank = value;
    148}
    149
    150inline u8 Memory::Retrieve(u16 address)
    151{
    152    return m_pMap[address];
    153}
    154
    155inline void Memory::Load(u16 address, u8 value)
    156{
    157    m_pMap[address] = value;
    158}
    159
    160inline Memory::stDisassembleRecord** Memory::GetDisassembledMemoryMap()
    161{
    162    return m_pDisassembledMap;
    163}
    164
    165inline Memory::stDisassembleRecord** Memory::GetDisassembledROMMemoryMap()
    166{
    167    return m_pDisassembledROMMap;
    168}
    169
    170inline void Memory::CheckBreakpoints(u16 address, bool write)
    171{
    172    std::size_t size = m_BreakpointsMem.size();
    173
    174    for (std::size_t b = 0; b < size; b++)
    175    {
    176        if (write && !m_BreakpointsMem[b].write)
    177            continue;
    178
    179        if (!write && !m_BreakpointsMem[b].read)
    180            continue;
    181
    182        bool proceed = false;
    183
    184        if (m_BreakpointsMem[b].range)
    185        {
    186            if ((address >= m_BreakpointsMem[b].address1) && (address <= m_BreakpointsMem[b].address2))
    187            {
    188                proceed = true;
    189            }
    190        }
    191        else
    192        {
    193            if (m_BreakpointsMem[b].address1 == address)
    194            {
    195                proceed = true;
    196            }
    197        }
    198
    199        if (proceed)
    200        {
    201            m_pProcessor->RequestMemoryBreakpoint();
    202            break;
    203        }
    204    }
    205}
    206
    207#endif	/* MEMORY_INLINE_H */