MultiMBC1MemoryRule.cpp (5435B)
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 "MultiMBC1MemoryRule.h" 21#include "MBC1MemoryRule.h" 22#include "Video.h" 23#include "Memory.h" 24#include "Processor.h" 25#include "Input.h" 26#include "Cartridge.h" 27 28MultiMBC1MemoryRule::MultiMBC1MemoryRule(Processor* pProcessor, 29 Memory* pMemory, Video* pVideo, Input* pInput, 30 Cartridge* pCartridge, Audio* pAudio) : MemoryRule(pProcessor, 31pMemory, pVideo, pInput, pCartridge, pAudio) 32{ 33 Reset(false); 34} 35 36MultiMBC1MemoryRule::~MultiMBC1MemoryRule() 37{ 38 39} 40 41void MultiMBC1MemoryRule::Reset(bool bCGB) 42{ 43 m_bCGB = bCGB; 44 m_iMulticartMode = 0; 45 m_iROMBankHi = 0; 46 m_iROMBankLo = 1; 47 SetROMBanks(); 48} 49 50u8 MultiMBC1MemoryRule::PerformRead(u16 address) 51{ 52 switch (address & 0xE000) 53 { 54 case 0x0000: 55 case 0x2000: 56 { 57 u8* pROM = m_pCartridge->GetTheROM(); 58 59 if (m_iMulticartMode == 0) 60 { 61 return pROM[address]; 62 } 63 else 64 { 65 int bank_addr = (m_iMBC1MBank_0 * 0x4000) + address; 66 return pROM[bank_addr]; 67 } 68 } 69 case 0x4000: 70 case 0x6000: 71 { 72 u8* pROM = m_pCartridge->GetTheROM(); 73 74 if (m_iMulticartMode == 0) 75 { 76 int bank_addr = (m_iMBC1Bank_1 * 0x4000) + (address & 0x3FFF); 77 return pROM[bank_addr]; 78 } 79 else 80 { 81 int bank_addr = (m_iMBC1MBank_1 * 0x4000) + (address & 0x3FFF); 82 return pROM[bank_addr]; 83 } 84 } 85 default: 86 { 87 return 0xFF; 88 } 89 } 90} 91 92void MultiMBC1MemoryRule::PerformWrite(u16 address, u8 value) 93{ 94 switch (address & 0xE000) 95 { 96 case 0x2000: 97 { 98 m_iROMBankLo = value & 0x1F; 99 SetROMBanks(); 100 break; 101 } 102 case 0x4000: 103 { 104 m_iROMBankHi = value & 0x03; 105 SetROMBanks(); 106 break; 107 } 108 case 0x6000: 109 { 110 m_iMulticartMode = value & 0x01; 111 break; 112 } 113 default: 114 { 115 Log("--> ** Attempting to write on invalid address %X %X", address, value); 116 break; 117 } 118 } 119} 120 121void MultiMBC1MemoryRule::SetROMBanks() 122{ 123 int full_bank = (m_iROMBankHi << 5) | m_iROMBankLo; 124 125 m_iMBC1Bank_1 = full_bank; 126 127 if (full_bank == 0x00 || full_bank == 0x20 || full_bank == 0x40 || full_bank == 0x60) 128 m_iMBC1Bank_1 = full_bank + 1; 129 130 m_iMBC1MBank_0 = ((full_bank >> 1) & 0x30); 131 m_iMBC1MBank_1 = ((full_bank >> 1) & 0x30) | (full_bank & 0x0F); 132} 133 134size_t MultiMBC1MemoryRule::GetRamSize() 135{ 136 return 0; 137} 138 139u8* MultiMBC1MemoryRule::GetRamBanks() 140{ 141 return 0; 142} 143 144u8* MultiMBC1MemoryRule::GetCurrentRamBank() 145{ 146 return m_pMemory->GetMemoryMap() + 0xA000; 147} 148 149int MultiMBC1MemoryRule::GetCurrentRamBankIndex() 150{ 151 return 0; 152} 153 154u8* MultiMBC1MemoryRule::GetRomBank0() 155{ 156 u8* pROM = m_pCartridge->GetTheROM(); 157 158 if (m_iMulticartMode == 0) 159 return pROM; 160 else 161 return pROM + (m_iMBC1MBank_0 * 0x4000); 162} 163 164int MultiMBC1MemoryRule::GetCurrentRomBank0Index() 165{ 166 return m_iMBC1MBank_0; 167} 168 169u8* MultiMBC1MemoryRule::GetCurrentRomBank1() 170{ 171 u8* pROM = m_pCartridge->GetTheROM(); 172 173 if (m_iMulticartMode == 0) 174 return &pROM[m_iMBC1Bank_1 * 0x4000]; 175 else 176 return &pROM[m_iMBC1MBank_1 * 0x4000]; 177} 178 179int MultiMBC1MemoryRule::GetCurrentRomBank1Index() 180{ 181 return m_iMBC1Bank_1; 182} 183 184void MultiMBC1MemoryRule::SaveState(std::ostream& stream) 185{ 186 using namespace std; 187 188 stream.write(reinterpret_cast<const char*> (&m_iMulticartMode), sizeof(m_iMulticartMode)); 189 stream.write(reinterpret_cast<const char*> (&m_iROMBankHi), sizeof(m_iROMBankHi)); 190 stream.write(reinterpret_cast<const char*> (&m_iROMBankLo), sizeof(m_iROMBankLo)); 191 stream.write(reinterpret_cast<const char*> (&m_iMBC1Bank_1), sizeof(m_iMBC1Bank_1)); 192 stream.write(reinterpret_cast<const char*> (&m_iMBC1MBank_0), sizeof(m_iMBC1MBank_0)); 193 stream.write(reinterpret_cast<const char*> (&m_iMBC1MBank_1), sizeof(m_iMBC1MBank_1)); 194} 195 196void MultiMBC1MemoryRule::LoadState(std::istream& stream) 197{ 198 using namespace std; 199 200 stream.read(reinterpret_cast<char*> (&m_iMulticartMode), sizeof(m_iMulticartMode)); 201 stream.read(reinterpret_cast<char*> (&m_iROMBankHi), sizeof(m_iROMBankHi)); 202 stream.read(reinterpret_cast<char*> (&m_iROMBankLo), sizeof(m_iROMBankLo)); 203 stream.read(reinterpret_cast<char*> (&m_iMBC1Bank_1), sizeof(m_iMBC1Bank_1)); 204 stream.read(reinterpret_cast<char*> (&m_iMBC1MBank_0), sizeof(m_iMBC1MBank_0)); 205 stream.read(reinterpret_cast<char*> (&m_iMBC1MBank_1), sizeof(m_iMBC1MBank_1)); 206}