cscg22-gearboy

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

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}