82 lines
2.3 KiB
C++
82 lines
2.3 KiB
C++
#include "mbc1.h"
|
|
#include "mem.h"
|
|
#include "sm83.h"
|
|
#include <stdlib.h>
|
|
#include <SDL2/SDL.h>
|
|
|
|
namespace mbc1
|
|
{
|
|
#define ROM_BANK_SIZE 0x4000
|
|
#define RAM_BANK_SIZE 0x2000
|
|
|
|
uint8_t *rom;
|
|
uint8_t exram[4 * RAM_BANK_SIZE];
|
|
|
|
uint8_t current_rom_bank = 1;
|
|
uint8_t current_ram_bank = 0;
|
|
bool ram_enabled = false;
|
|
bool banking_mode = false; // false = ROM banking mode, true = RAM banking mode
|
|
|
|
void reset()
|
|
{
|
|
for (int i=0; i<4*RAM_BANK_SIZE; ++i) { exram[i] = 0; }
|
|
}
|
|
|
|
uint8_t readRom(uint16_t address)
|
|
{
|
|
if (address < 0x4000) {
|
|
// ROM Bank 0
|
|
return rom[address];
|
|
} else {
|
|
// Switchable ROM bank
|
|
uint32_t banked_address = (current_rom_bank * ROM_BANK_SIZE) + (address - 0x4000);
|
|
return rom[banked_address];
|
|
}
|
|
}
|
|
|
|
void writeRom(uint16_t address, uint8_t value)
|
|
{
|
|
if (address < 0x2000) {
|
|
// Enable/disable RAM
|
|
ram_enabled = (value & 0x0F) == 0x0A;
|
|
} else if (address < 0x4000) {
|
|
// Select ROM bank
|
|
value &= 0x1F; // Lower 5 bits are used
|
|
if (value == 0) value = 1; // Bank 0 is not allowed
|
|
current_rom_bank = (current_rom_bank & 0x60) | value;
|
|
} else if (address < 0x6000) {
|
|
// Select RAM bank or upper bits of ROM bank
|
|
if (banking_mode) {
|
|
current_ram_bank = value & 0x03; // 2 bits for RAM bank
|
|
} else {
|
|
current_rom_bank = (current_rom_bank & 0x1F) | ((value & 0x03) << 5);
|
|
}
|
|
} else {
|
|
// Select banking mode
|
|
banking_mode = value & 0x01;
|
|
}
|
|
}
|
|
|
|
uint8_t readRam(uint16_t address)
|
|
{
|
|
if (ram_enabled) {
|
|
uint32_t banked_address = (current_ram_bank * RAM_BANK_SIZE) + (address - 0xa000);
|
|
return exram[banked_address];
|
|
}
|
|
return 0xff; // Return open bus value when RAM is disabled
|
|
}
|
|
|
|
void writeRam(uint16_t address, uint8_t value)
|
|
{
|
|
if (ram_enabled) {
|
|
uint32_t banked_address = (current_ram_bank * RAM_BANK_SIZE) + (address - 0xa000);
|
|
exram[banked_address] = value;
|
|
}
|
|
}
|
|
|
|
void init(uint8_t *rom, uint32_t rom_size, uint32_t ram_size)
|
|
{
|
|
mbc1::rom = rom;
|
|
reset();
|
|
}
|
|
} |