Skip to content

Commit

Permalink
Merge PPUMemory into Memory (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
kremi151 committed Dec 29, 2020
1 parent 1b9ea21 commit 5966fef
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 166 deletions.
2 changes: 0 additions & 2 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ set(SOURCES
source/cartridge/mbc1.cpp
source/cartridge/mbc2.cpp
source/cartridge/mbc_none.cpp
source/memory/ppu_memory.cpp
source/operands/instruction_context.cpp
source/operands/alu.cpp
source/operands/loads.cpp
Expand Down Expand Up @@ -69,7 +68,6 @@ set(HEADERS
source/cartridge/mbc1.h
source/cartridge/mbc2.h
source/cartridge/mbc_none.h
source/memory/ppu_memory.h
source/operands/instruction_context.h
source/operands/alu.h
source/operands/loads.h
Expand Down
6 changes: 3 additions & 3 deletions core/source/emulator/emulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ using namespace FunkyBoy;

Emulator::Emulator(GameBoyType gbType, const Controller::ControllersPtr& controllers)
: controllers(controllers)
, ppuMemory()
, memory(controllers, ppuMemory)
, memory(controllers)
, cpu(std::make_shared<CPU>(gbType))
, ppu(cpu, controllers, ppuMemory)
, ppu(cpu, controllers)
{
// Initialize registers
cpu->powerUpInit(memory);
ppu.powerUpInit(memory);
}

Emulator::Emulator(FunkyBoy::GameBoyType gbType): Emulator(
Expand Down
2 changes: 0 additions & 2 deletions core/source/emulator/emulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#include <util/debug.h>
#include <controllers/controllers.h>
#include <memory/memory.h>
#include <memory/ppu_memory.h>
#include <memory>
#include <iostream>

Expand All @@ -36,7 +35,6 @@ namespace FunkyBoy {
test_public:
Controller::ControllersPtr controllers;

PPUMemory ppuMemory;
Memory memory;
CPUPtr cpu;
PPU ppu;
Expand Down
46 changes: 24 additions & 22 deletions core/source/emulator/ppu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,26 +51,28 @@

using namespace FunkyBoy;

PPU::PPU(CPUPtr cpu, Controller::ControllersPtr controllers, const PPUMemory &ppuMemory)
PPU::PPU(CPUPtr cpu, Controller::ControllersPtr controllers)
: cpu(std::move(cpu))
, controllers(std::move(controllers))
, ppuMemory(ppuMemory)
, gpuMode(GPUMode::GPUMode_2)
, modeClocks(0)
, scanLineBuffer(new u8[FB_GB_DISPLAY_WIDTH])
, bgColorIndexes(new u8[FB_GB_DISPLAY_WIDTH])
{
this->ppuMemory.setAccessibilityFromMMU(
this->gpuMode != GPUMode::GPUMode_3,
this->gpuMode != GPUMode::GPUMode_2 && this->gpuMode != GPUMode::GPUMode_3
);
}

PPU::~PPU() {
delete[] scanLineBuffer;
delete[] bgColorIndexes;
}

void PPU::powerUpInit(Memory &memory) {
memory.setAccessibilityFromMMU(
this->gpuMode != GPUMode::GPUMode_3,
this->gpuMode != GPUMode::GPUMode_2 && this->gpuMode != GPUMode::GPUMode_3
);
}

// GPU Lifecycle:
//
// Period 1: Scanline (Accessing OAM) | GPU mode 2 | 80 clocks
Expand Down Expand Up @@ -110,14 +112,14 @@ ret_code PPU::doClocks(u8 clocks, Memory &memory) {
if (__fb_stat_isVBlankInterrupt(stat)) {
cpu->requestInterrupt(InterruptType::LCD_STAT, memory);
}
ppuMemory.setAccessibilityFromMMU(true, true);
memory.setAccessibilityFromMMU(true, true);
result |= FB_RET_NEW_FRAME;
} else {
gpuMode = GPUMode::GPUMode_2;
if (__fb_stat_isOAMInterrupt(stat)) {
cpu->requestInterrupt(InterruptType::LCD_STAT, memory);
}
ppuMemory.setAccessibilityFromMMU(true, false);
memory.setAccessibilityFromMMU(true, false);
}
if (__fb_stat_isLYCInterrupt(stat) && ly == memory.getLYC()) {
cpu->requestInterrupt(InterruptType::LCD_STAT, memory);
Expand All @@ -132,7 +134,7 @@ ret_code PPU::doClocks(u8 clocks, Memory &memory) {
if (__fb_stat_isOAMInterrupt(stat)) {
cpu->requestInterrupt(InterruptType::LCD_STAT, memory);
}
ppuMemory.setAccessibilityFromMMU(true, false);
memory.setAccessibilityFromMMU(true, false);
ly = 0;
} else if (modeClocks % 204 == 0) {
ly++;
Expand All @@ -146,7 +148,7 @@ ret_code PPU::doClocks(u8 clocks, Memory &memory) {
if (modeClocks >= 80) {
modeClocks = 0;
gpuMode = GPUMode::GPUMode_3;
ppuMemory.setAccessibilityFromMMU(false, false);
memory.setAccessibilityFromMMU(false, false);
}
break;
}
Expand All @@ -157,7 +159,7 @@ ret_code PPU::doClocks(u8 clocks, Memory &memory) {
if (__fb_stat_isHBlankInterrupt(stat)) {
cpu->requestInterrupt(InterruptType::LCD_STAT, memory);
}
ppuMemory.setAccessibilityFromMMU(true, true);
memory.setAccessibilityFromMMU(true, true);
renderScanline(ly, memory);
result |= FB_RET_NEW_SCANLINE;
}
Expand Down Expand Up @@ -194,18 +196,18 @@ void PPU::renderScanline(u8 ly, Memory &memory) {
memory_address tileMapAddr = __fb_lcdc_bgTileMapDisplaySelect(lcdc);
tileMapAddr += ((y & 255u) / 8) * 32;
palette = memory.getBGP();
tile = ppuMemory.getVRAMByte(tileMapAddr + tileOffsetX);
tile = memory.getVRAMByte(tileMapAddr + tileOffsetX);
u8 &scanLineX = it; // alias for it
for (scanLineX = 0 ; scanLineX < FB_GB_DISPLAY_WIDTH ; scanLineX++) {
tileLine = ppuMemory.readVRAM16Bits(tileSetAddr + __fb_getTileSetOffset(lcdc, tile) + (yInTile * 2));
tileLine = memory.readVRAM16Bits(tileSetAddr + __fb_getTileSetOffset(lcdc, tile) + (yInTile * 2));
colorIndex = (tileLine >> (15 - xInTile)) & 1u
| ((tileLine >> (7 - xInTile)) & 1u) << 1;
scanLineBuffer[scanLineX] = (palette >> (colorIndex * 2u)) & 3u;
bgColorIndexes[scanLineX] = colorIndex;
if (++xInTile >= 8) {
xInTile = 0;
tileOffsetX = (tileOffsetX + 1) & 31;
tile = ppuMemory.getVRAMByte(tileMapAddr + tileOffsetX);
tile = memory.getVRAMByte(tileMapAddr + tileOffsetX);
}
}
} else {
Expand All @@ -226,10 +228,10 @@ void PPU::renderScanline(u8 ly, Memory &memory) {
u8 yInObj;
u8 &objIdx = it; // alias for it
for (objIdx = 0 ; objIdx < 40 ; objIdx++) {
objY = ppuMemory.getOAMByte(objAddr++) - 16;
objX = ppuMemory.getOAMByte(objAddr++);
tile = ppuMemory.getOAMByte(objAddr++);
objFlags = ppuMemory.getOAMByte(objAddr++);
objY = memory.getOAMByte(objAddr++) - 16;
objX = memory.getOAMByte(objAddr++);
tile = memory.getOAMByte(objAddr++);
objFlags = memory.getOAMByte(objAddr++);
if (ly < objY || ly >= objY + objHeight) {
continue;
}
Expand All @@ -247,7 +249,7 @@ void PPU::renderScanline(u8 ly, Memory &memory) {
// In 8x16 mode, the least significant bit of the tile number is treated as '0'
tile &= 0b11111110u;
}
tileLine = ppuMemory.readVRAM16Bits(FB_TILE_DATA_LOWER + (tile * FB_SIZEOF_TILE) + (yInObj * 2));
tileLine = memory.readVRAM16Bits(FB_TILE_DATA_LOWER + (tile * FB_SIZEOF_TILE) + (yInObj * 2));
for (u8 xOnObj = 0 ; xOnObj < 8 ; xOnObj++) {
u8 x = objX + xOnObj - 8;
if (x >= FB_GB_DISPLAY_WIDTH) {
Expand Down Expand Up @@ -280,17 +282,17 @@ void PPU::renderScanline(u8 ly, Memory &memory) {
memory_address tileMapAddr = __fb_lcdc_windowTileMapDisplaySelect(lcdc);
tileMapAddr += ((y & 255u) / 8) * 32;
palette = memory.getBGP();
tile = ppuMemory.getVRAMByte(tileMapAddr + tileOffsetX);
tile = memory.getVRAMByte(tileMapAddr + tileOffsetX);
u8 &scanLineX = it; // alias for it
for (scanLineX = wx ; scanLineX < FB_GB_DISPLAY_WIDTH ; scanLineX++) {
tileLine = ppuMemory.readVRAM16Bits(tileSetAddr + __fb_getTileSetOffset(lcdc, tile) + (yInTile * 2));
tileLine = memory.readVRAM16Bits(tileSetAddr + __fb_getTileSetOffset(lcdc, tile) + (yInTile * 2));
colorIndex = (tileLine >> (15 - xInTile)) & 1u
| ((tileLine >> (7 - xInTile)) & 1u) << 1;
scanLineBuffer[scanLineX] = (palette >> (colorIndex * 2u)) & 3u;
if (++xInTile >= 8) {
xInTile = 0;
tileOffsetX = (tileOffsetX + 1) & 31;
tile = ppuMemory.getVRAMByte(tileMapAddr + tileOffsetX);
tile = memory.getVRAMByte(tileMapAddr + tileOffsetX);
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions core/source/emulator/ppu.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include <controllers/controllers.h>
#include <emulator/cpu.h>
#include <memory/memory.h>
#include <memory/ppu_memory.h>
#include <util/gpumode.h>
#include <util/typedefs.h>

Expand All @@ -30,7 +29,6 @@ namespace FunkyBoy {
private:
CPUPtr cpu;
Controller::ControllersPtr controllers;
PPUMemory ppuMemory;

GPUMode gpuMode;

Expand All @@ -42,9 +40,11 @@ namespace FunkyBoy {
void renderScanline(u8 ly, Memory &memory);
void updateStat(u8 &stat, u8 ly, bool lcdOn, Memory &memory);
public:
PPU(CPUPtr cpu, Controller::ControllersPtr controllers, const PPUMemory &ppuMemory);
PPU(CPUPtr cpu, Controller::ControllersPtr controllers);
~PPU();

void powerUpInit(Memory &memory);

ret_code doClocks(u8 clocks, Memory &memory);
};

Expand Down
32 changes: 21 additions & 11 deletions core/source/memory/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,16 @@ using namespace FunkyBoy;

#define FB_INTERNAL_RAM_BANK_SIZE (4 * 1024)

Memory::Memory(Controller::ControllersPtr controllers, const PPUMemory &ppuMemory)
Memory::Memory(Controller::ControllersPtr controllers)
: controllers(std::move(controllers))
, sys_counter_lsb(0)
, sys_counter_msb(0)
, hwIO(new u8[128]{})
, ppuMemory(ppuMemory)
, interruptEnableRegister(0)
, vram(new u8[8192]{})
, oam(new u8[160]{})
, vramAccessible(true)
, oamAccessible(true)
, dmaStarted(false)
, rom(nullptr)
, cram(nullptr)
Expand All @@ -57,6 +60,8 @@ Memory::~Memory() {
delete[] hram;
delete[] rom;
delete[] cram;
delete[] vram;
delete[] oam;
delete[] hwIO;
}

Expand Down Expand Up @@ -318,6 +323,11 @@ u8 Memory::handleIOMemoryRead(u8 offset) {
}
}

void Memory::setAccessibilityFromMMU(bool accessVram, bool accessOam) {
vramAccessible = accessVram;
oamAccessible = accessOam;
}

#define FB_MEMORY_NIBBLE_RANGE(x) \
case 0x ## x ## 0: case 0x ## x ## 1: case 0x ## x ## 2: case 0x ## x ## 3: case 0x ## x ## 4: case 0x ## x ## 5: \
case 0x ## x ## 6: case 0x ## x ## 7: case 0x ## x ## 8: case 0x ## x ## 9: case 0x ## x ## A: case 0x ## x ## B: \
Expand Down Expand Up @@ -365,8 +375,8 @@ u8 Memory::read8BitsAt(memory_address offset) {
FB_MEMORY_CARTRIDGE:
return mbc->readFromROMAt(offset, rom);
FB_MEMORY_VRAM:
return ppuMemory.isVRAMAccessibleFromMMU()
? ppuMemory.getVRAMByte(offset - 0x8000)
return vramAccessible
? getVRAMByte(offset - 0x8000)
: 0xFF;
FB_MEMORY_CARTRIDGE_RAM:
return mbc->readFromRAMAt(offset - 0xA000, cram);
Expand All @@ -381,8 +391,8 @@ u8 Memory::read8BitsAt(memory_address offset) {
return *(dynamicRamBank + (offset - 0xF000));
FB_MEMORY_OAM: {
if (offset < 0xFEA0) {
return ppuMemory.isOAMAccessibleFromMMU()
? ppuMemory.getOAMByte(offset - 0xFE00)
return oamAccessible
? getOAMByte(offset - 0xFE00)
: 0xFF;
} else {
// Not usable
Expand Down Expand Up @@ -420,8 +430,8 @@ void Memory::write8BitsTo(memory_address offset, u8 val) {
mbc->interceptROMWrite(offset, val);
break;
FB_MEMORY_VRAM: {
if (ppuMemory.isVRAMAccessibleFromMMU()) {
ppuMemory.getVRAMByte(offset - 0x8000) = val;
if (vramAccessible) {
getVRAMByte(offset - 0x8000) = val;
}
break;
}
Expand All @@ -443,8 +453,8 @@ void Memory::write8BitsTo(memory_address offset, u8 val) {
break;
FB_MEMORY_OAM: {
if (offset < 0xFEA0) {
if (ppuMemory.isOAMAccessibleFromMMU()) {
ppuMemory.getOAMByte(offset - 0xFE00) = val;
if (oamAccessible) {
getOAMByte(offset - 0xFE00) = val;
}
} else {
// Not usable
Expand Down Expand Up @@ -488,7 +498,7 @@ void Memory::doDMA() {
if (!dmaStarted) {
return;
}
ppuMemory.getOAMByte(dmaLsb) = read8BitsAt(Util::compose16Bits(dmaLsb, dmaMsb));
getOAMByte(dmaLsb) = read8BitsAt(Util::compose16Bits(dmaLsb, dmaMsb));
if (++dmaLsb > 0x9F) {
dmaStarted = false;
}
Expand Down
24 changes: 21 additions & 3 deletions core/source/memory/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
#include <util/typedefs.h>
#include <cartridge/status.h>
#include <controllers/controllers.h>
#include <memory/ppu_memory.h>
#include <cartridge/mbc.h>

#include <iostream>
#include <cartridge/header.h>
#include <util/testing.h>
#include <util/endianness.h>

#define FB_REG_P1 0xFF00
#define FB_REG_SB 0xFF01
Expand Down Expand Up @@ -75,16 +75,20 @@ namespace FunkyBoy {
class Memory {
private:
Controller::ControllersPtr controllers;
PPUMemory ppuMemory;

u8 *internalRam;
u8 *hwIO;
u8 *hram;
u8 *vram;
u8 *oam;
u8 interruptEnableRegister;

u8 dmaMsb{}, dmaLsb{};
bool dmaStarted;

bool vramAccessible;
bool oamAccessible;

u8 *cram;
size_t ramSizeInBytes;
size_t romSize;
Expand All @@ -107,7 +111,7 @@ namespace FunkyBoy {
u8 sys_counter_msb;

public:
Memory(Controller::ControllersPtr controllers, const PPUMemory &ppuMemory);
Memory(Controller::ControllersPtr controllers);
~Memory();

Memory(const Memory &other) = delete;
Expand Down Expand Up @@ -206,6 +210,20 @@ namespace FunkyBoy {
return interruptEnableRegister;
}

inline u8 &getVRAMByte(memory_address vramOffset) {
return *(vram + vramOffset);
}

inline u16 readVRAM16Bits(memory_address vramOffset) {
return Util::compose16Bits(*(vram + vramOffset), *(vram + vramOffset + 1));
}

inline u8 &getOAMByte(memory_address oamOffset) {
return *(oam + oamOffset);
}

void setAccessibilityFromMMU(bool accessVram, bool accessOam);

friend class CPU;
};

Expand Down
Loading

0 comments on commit 5966fef

Please sign in to comment.