Skip to content

Commit

Permalink
Fix input segfault, Add MBC1 (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
r41k0u committed Jan 5, 2024
1 parent 0a1f11c commit 3c777f6
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 28 deletions.
2 changes: 1 addition & 1 deletion src/gameBoy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ GBE::GBE()
printf("boot rom file not opened");

// Open the Game ROM
if ((gameROM = fopen("../tests/halt_bug.gb", "rb")) == NULL)
if ((gameROM = fopen("../tests/hugo.gb", "rb")) == NULL)
printf("game rom file not opened");

// Set the Boot ROM
Expand Down
11 changes: 5 additions & 6 deletions src/graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ PPU::PPU()
currentLine = 0x00;
hiddenWindowLineCounter = 0x00;
ppuMode = 0x02;
event = new SDL_Event();

ppuMode = 0;
currentClock = modeClocks[ppuMode];
Expand Down Expand Up @@ -101,11 +100,11 @@ bool PPU::init()
// And process them
bool PPU::pollEvents()
{
while (SDL_PollEvent(event))
while (SDL_PollEvent(&event))
{
if (event->key.type == SDL_KEYDOWN)
if (event.key.type == SDL_KEYDOWN)
{
switch (event->key.keysym.sym)
switch (event.key.keysym.sym)
{
case SDLK_LEFT:
*(mMap->joyPadState) &= 0xFD;
Expand Down Expand Up @@ -137,9 +136,9 @@ bool PPU::pollEvents()
break;
}
}
else if (event->key.type == SDL_KEYUP)
else if (event.key.type == SDL_KEYUP)
{
switch (event->key.keysym.sym)
switch (event.key.keysym.sym)
{
case SDLK_LEFT:
*(mMap->joyPadState) |= 0x02;
Expand Down
2 changes: 1 addition & 1 deletion src/graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class PPU
SDL_Window* window;
SDL_Renderer* renderer;
SDL_Texture* texture;
SDL_Event* event;
SDL_Event event;

// renderArray to be converted to texture
// stores 4 copies of texture for wrapping of screen
Expand Down
163 changes: 145 additions & 18 deletions src/mmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,10 @@ MemoryMap::MemoryMap()
romBank0 = new Byte[0x4000];
memset(romBank0, 0x00, 0x4000);

// 16kb ROM bank 1
romBank1 = new Byte[0x4000];
memset(romBank1, 0x00, 0x4000);

// 8kb Video RAM
// 8kb External RAM
videoRam = new Byte[0x2000];
memset(videoRam, 0x00, 0x2000);

// 8kb External RAM
externalRam = new Byte[0x2000];
memset(externalRam, 0x00, 0x2000);

// 8kb Work RAM
workRam = new Byte[0x2000];
memset(workRam, 0x00, 0x2000);
Expand All @@ -44,6 +36,21 @@ MemoryMap::MemoryMap()
highRam = new Byte[0x007F];
memset(highRam, 0x00, 0x007F);

// MBC mode
romMBCMode = 0x0;

// ROM Bank Number
romBankNumber = 0x1;

// RAM Bank Number
ramBankNumber = 0x0;

// Enable RAM Flag
enableRAM = 0x0;

// ROM/RAM Mode Select
romRAMModeSelect = 0x0;

// 1 byte Interrupt Enable Register
interruptEnableRegister = new Byte;

Expand Down Expand Up @@ -103,17 +110,62 @@ MemoryMap::MemoryMap()

bootRomFile = nullptr;
romFile = nullptr;
}

mbcMode = 0x0;
// Check writes to ROM
void MemoryMap::checkRomWrite(Word address, Byte value)
{
switch (romMBCMode)
{
case MBC0:
printf("Writing to ROM is not allowed! Write attempted at %04X", address);
break;
case MBC1:
{
if (address < 0x2000)
{
// Enable/Disable RAM
if ((value & 0x1F) == 0x0A)
enableRAM = 0xFF;
else
enableRAM = 0x00;
}
else if (address < 0x4000)
{
romBankNumber &= 0x60;
romBankNumber |= (value & 0x1F);
}
else if (address < 0x6000)
{
if (romRAMModeSelect)
{
ramBankNumber = value & 0x03;
romBankNumber &= 0x1F;
romBankNumber |= ((value & 0x03) << 5);
}
}
else if (address < 0x8000)
{
romRAMModeSelect = value & 0x01;
}
else
{
printf("Invalid address");
}
break;
}
default:
printf("Invalid MBC mode");
break;
}
}

// Write to memory
// TODO: Make emulation memory secure
bool MemoryMap::writeMemory(Word address, Byte value)
{
if (address < 0x8000)
{
printf("Writing to ROM is not allowed! Write attempted at %04X", address);
checkRomWrite(address, value);
return false;
}
else if (address < 0xA000)
Expand All @@ -124,7 +176,19 @@ bool MemoryMap::writeMemory(Word address, Byte value)
else if (address < 0xC000)
{
// Write to External RAM
externalRam[address - 0xA000] = value;
switch (romMBCMode)
{
case MBC0:
externalRam[address - 0xA000] = value;
break;
case MBC1:
if (enableRAM)
externalRam[address - 0xA000 + (ramBankNumber * 0x2000)] = value;
break;
default:
externalRam[address - 0xA000] = value;
break;
}
}
else if (address < 0xE000)
{
Expand Down Expand Up @@ -206,12 +270,34 @@ Byte MemoryMap::readMemory(Word address)
if (address < 0x4000)
{
// Read from ROM bank 0
return romBank0[address];
switch (romMBCMode)
{
case MBC0:
return romBank0[address];
case MBC1:
if (!(romBankNumber & 0x60))
return romBank0[address];
else
return romBank1[address + (((romBankNumber & 0x60) - 1) * 0x4000)];
default:
return romBank0[address];
}
}
else if (address < 0x8000)
{
// Read from ROM bank 1
return romBank1[address - 0x4000];
switch (romMBCMode)
{
case MBC0:
return romBank1[address - 0x4000];
case MBC1:
if (!(romBankNumber & 0x1F))
return romBank1[(address - 0x4000) + (romBankNumber * 0x4000)];
else
return romBank1[(address - 0x4000) + ((romBankNumber - 1) * 0x4000)];
default:
return romBank1[address - 0x4000];
}
}
else if (address < 0xA000)
{
Expand All @@ -221,7 +307,18 @@ Byte MemoryMap::readMemory(Word address)
else if (address < 0xC000)
{
// Read from External RAM
return externalRam[address - 0xA000];
switch (romMBCMode)
{
case MBC0:
return externalRam[address - 0xA000];
case MBC1:
if (enableRAM)
return externalRam[address - 0xA000 + (ramBankNumber * 0x2000)];
else
return 0xFF;
default:
return externalRam[address - 0xA000];
}
}
else if (address < 0xE000)
{
Expand Down Expand Up @@ -310,10 +407,40 @@ void MemoryMap::mapRom()
fseek(romFile, 0x100, SEEK_SET);

fread(romBank0 + 0x100, 1, 16128, romFile);
fread(romBank1, 1, 16384, romFile);

// Find the size of the ROM
fseek(romFile, 0, SEEK_END);
int romSize = ftell(romFile);

// Allocate memory for ROM Bank 1
romBank1 = new Byte[romSize - 0x4000];

// Load the ROM Bank 1
fseek(romFile, 0x4000, SEEK_SET);
fread(romBank1, 1, romSize - 0x4000, romFile);

// Check 0x147 for MBC mode
mbcMode = romBank0[0x147];
romMBCMode = romBank0[0x147];
switch (romMBCMode)
{
case 0x00:
// No MBC
romMBCMode = MBC0;
externalRam = new Byte[0x2000];
memset(externalRam, 0x00, 0x2000);
break;
case 0x01:
case 0x02:
case 0x03:
// MBC1
romMBCMode = MBC1;
externalRam = new Byte[0x8000];
memset(externalRam, 0x00, 0x8000);
break;
default:
printf("Invalid MBC mode");
break;
}
}

void MemoryMap::unloadBootRom()
Expand Down
27 changes: 25 additions & 2 deletions src/mmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,31 @@
class MemoryMap
{
private:
Byte mbcMode;

FILE* bootRomFile;
FILE* romFile;

// MBC Mode Enum
enum MBC
{
MBC0,
MBC1
};

// ROM MBC Mode
Byte romMBCMode;

// ROM Bank Number
Byte romBankNumber;

// RAM Bank Number
Byte ramBankNumber;

// Enable RAM Flag
Byte enableRAM;

// ROM/RAM Mode Select
Byte romRAMModeSelect;

// First ROM Bank
// 16 KB 0x0000 - 0x3FFF
// Contains the first 16 KB of the ROM
Expand Down Expand Up @@ -137,6 +157,9 @@ class MemoryMap
// Stays in the I/O Ports at 0xFF4B
Byte* reg_WX;

// set the rom bank offset
void checkRomWrite(Word address, Byte value);

public:
Byte* joyPadState;

Expand Down

0 comments on commit 3c777f6

Please sign in to comment.