diff options
Diffstat (limited to 'gearboy/src/Memory_inline.h')
| -rw-r--r-- | gearboy/src/Memory_inline.h | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/gearboy/src/Memory_inline.h b/gearboy/src/Memory_inline.h new file mode 100644 index 00000000..9d605223 --- /dev/null +++ b/gearboy/src/Memory_inline.h @@ -0,0 +1,207 @@ +#ifndef MEMORY_INLINE_H +#define MEMORY_INLINE_H + +#include "CommonMemoryRule.h" +#include "IORegistersMemoryRule.h" + +inline u8 Memory::Read(u16 address) +{ + #ifndef GEARBOY_DISABLE_DISASSEMBLER + CheckBreakpoints(address, false); + #endif + + switch (address & 0xE000) + { + case 0x0000: + { + if (!m_bBootromRegistryDisabled) + { + if (m_bCGB) + { + if (m_bBootromGBCEnabled && m_bBootromGBCLoaded && ((address < 0x0100) || (address < 0x0900 && address > 0x01FF))) + return m_pBootromGBC[address]; + } + else + { + if (m_bBootromDMGEnabled && m_bBootromDMGLoaded && (address < 0x0100)) + return m_pBootromDMG[address]; + } + } + + return m_pCurrentMemoryRule->PerformRead(address); + } + case 0x2000: + case 0x4000: + case 0x6000: + { + return m_pCurrentMemoryRule->PerformRead(address); + } + case 0x8000: + { + return m_pCommonMemoryRule->PerformRead(address); + } + case 0xA000: + { + return m_pCurrentMemoryRule->PerformRead(address); + } + case 0xC000: + case 0xE000: + { + if (address < 0xFF00) + return m_pCommonMemoryRule->PerformRead(address); + else + return m_pIORegistersMemoryRule->PerformRead(address); + } + default: + { + return Retrieve(address); + } + } +} + +inline void Memory::Write(u16 address, u8 value) +{ + #ifndef GEARBOY_DISABLE_DISASSEMBLER + CheckBreakpoints(address, true); + #endif + + switch (address & 0xE000) + { + case 0x0000: + case 0x2000: + case 0x4000: + case 0x6000: + { + m_pCurrentMemoryRule->PerformWrite(address, value); + break; + } + case 0x8000: + { + m_pCommonMemoryRule->PerformWrite(address, value); + break; + } + case 0xA000: + { + m_pCurrentMemoryRule->PerformWrite(address, value); + break; + } + case 0xC000: + case 0xE000: + { + if (address < 0xFF00) + m_pCommonMemoryRule->PerformWrite(address, value); + else + m_pIORegistersMemoryRule->PerformWrite(address, value); + break; + } + default: + { + Load(address, value); + break; + } + } +} + +inline u8 Memory::ReadCGBWRAM(u16 address) +{ + if (address < 0xD000) + return m_pWRAMBanks[(address - 0xC000)]; + else + return m_pWRAMBanks[(address - 0xD000) + (0x1000 * m_iCurrentWRAMBank)]; +} + +inline void Memory::WriteCGBWRAM(u16 address, u8 value) +{ + if (address < 0xD000) + m_pWRAMBanks[(address - 0xC000)] = value; + else + m_pWRAMBanks[(address - 0xD000) + (0x1000 * m_iCurrentWRAMBank)] = value; +} + +inline void Memory::SwitchCGBWRAM(u8 value) +{ + m_iCurrentWRAMBank = value; + + if (m_iCurrentWRAMBank == 0) + m_iCurrentWRAMBank = 1; +} + +inline u8 Memory::ReadCGBLCDRAM(u16 address, bool forceBank1) +{ + if (forceBank1 || (m_iCurrentLCDRAMBank == 1)) + return m_pLCDRAMBank1[address - 0x8000]; + else + return Retrieve(address); +} + +inline void Memory::WriteCGBLCDRAM(u16 address, u8 value) +{ + if (m_iCurrentLCDRAMBank == 1) + m_pLCDRAMBank1[address - 0x8000] = value; + else + Load(address, value); +} + +inline void Memory::SwitchCGBLCDRAM(u8 value) +{ + m_iCurrentLCDRAMBank = value; +} + +inline u8 Memory::Retrieve(u16 address) +{ + return m_pMap[address]; +} + +inline void Memory::Load(u16 address, u8 value) +{ + m_pMap[address] = value; +} + +inline Memory::stDisassembleRecord** Memory::GetDisassembledMemoryMap() +{ + return m_pDisassembledMap; +} + +inline Memory::stDisassembleRecord** Memory::GetDisassembledROMMemoryMap() +{ + return m_pDisassembledROMMap; +} + +inline void Memory::CheckBreakpoints(u16 address, bool write) +{ + std::size_t size = m_BreakpointsMem.size(); + + for (std::size_t b = 0; b < size; b++) + { + if (write && !m_BreakpointsMem[b].write) + continue; + + if (!write && !m_BreakpointsMem[b].read) + continue; + + bool proceed = false; + + if (m_BreakpointsMem[b].range) + { + if ((address >= m_BreakpointsMem[b].address1) && (address <= m_BreakpointsMem[b].address2)) + { + proceed = true; + } + } + else + { + if (m_BreakpointsMem[b].address1 == address) + { + proceed = true; + } + } + + if (proceed) + { + m_pProcessor->RequestMemoryBreakpoint(); + break; + } + } +} + +#endif /* MEMORY_INLINE_H */ |
