diff --git a/Memory.cpp b/Memory.cpp index 2d4c8c9..7b424d2 100644 --- a/Memory.cpp +++ b/Memory.cpp @@ -7,9 +7,8 @@ #include "Video.h" -Memory::Memory( const Cartridge &cartridge, Video &video ) +Memory::Memory( const Cartridge *cartridge ) : cartridge( cartridge ) - , video( video ) { map = new byte[ 64_KB ]; Reset(); @@ -24,15 +23,15 @@ void Memory::Reset() { memset( map, 0x00, 64_KB ); - MapCartridge( cartridge ); + MapCartridge(); } byte Memory::Read( word address ) const { - if ( address >= 0x2000 && address <= 0x2007 ) + if ( address >= 0x2000 && address <= 0x3FFF ) { - /* PPU memory */ - return video.Read( address ); + const word mirroredAddress = ( address % 8 ) + 0x2000; + return map[ mirroredAddress ]; } else { @@ -42,10 +41,10 @@ byte Memory::Read( word address ) const void Memory::Write( word address, byte data ) { - if ( address >= 0x2000 && address <= 0x2007 ) + if ( address >= 0x2000 && address <= 0x3FFF ) { - /* PPU memory */ - video.Write( address, data ); + const word mirroredAddress = ( address % 8 ) + 0x2000; + map[ mirroredAddress ] = data; } else { @@ -58,13 +57,15 @@ const byte *const Memory::GetMemoryMap() const return map; } -void Memory::MapCartridge( const Cartridge &cartridge ) +void Memory::MapCartridge() { + assert( cartridge != nullptr ); + /* For now only support NROM with PRG ROM of 16KB and no ram */ - Cartridge::Header header = cartridge.GetHeader(); + Cartridge::Header header = cartridge->GetHeader(); assert( header.mapper == 0x00 && header.prgRomSizeKB == 16 && !header.hasPRGRam); - const byte * const rom = cartridge.GetRom(); + const byte * const rom = cartridge->GetRom(); /* Map the PRG ROM to 0x8000 */ memcpy(&map[0x8000], &rom[0x0010], 16_KB ); diff --git a/Memory.h b/Memory.h index d5106de..5c020cb 100644 --- a/Memory.h +++ b/Memory.h @@ -41,7 +41,7 @@ class Memory { public: - Memory( const Cartridge &cartridge, Video &video ); + Memory( const Cartridge *cartridge ); ~Memory(); void Reset(); @@ -55,12 +55,11 @@ class Memory private: /* Associated NES systems */ - const Cartridge &cartridge; - Video &video; + const Cartridge *cartridge; /* NES memory map */ byte *map; - void MapCartridge( const Cartridge &cartridge ); + void MapCartridge(); }; \ No newline at end of file diff --git a/Video.cpp b/Video.cpp index 6a62354..4cad3b1 100644 --- a/Video.cpp +++ b/Video.cpp @@ -4,10 +4,12 @@ #include #include "Cartridge.h" +#include "Memory.h" -Video::Video( Cartridge *cartridge ) +Video::Video( Cartridge *cartridge, Memory *cpuMemory ) : cartridge( cartridge ) + , cpuMemory( cpuMemory ) { memory = new byte[ 16_KB ]; frameBuffer = new RGB[ NES_VIDEO_RESOLUTION ]; @@ -32,6 +34,15 @@ void Video::Reset() } MapCartridgeCHRToPPU(); + + cpuMemory->Write( PPUCTRL_REGISTER, 0x00 ); + cpuMemory->Write( PPUMASK_REGISTER, 0x00 ); + cpuMemory->Write( PPUSTATUS_REGISTER, 0b1010'0000 ); + cpuMemory->Write( OAMA_REGISTER, 0x00 ); + cpuMemory->Write( OAMADATA_REGISTER, 0x00 ); + cpuMemory->Write( PPUSCROLL_REGISTER, 0x00 ); + cpuMemory->Write( PPUADDR_REGISTER, 0x00 ); + cpuMemory->Write( PPUDATA_ADDRESS, 0x00 ); } void Video::MapCartridgeCHRToPPU() @@ -67,3 +78,8 @@ void Video::Write( word address, byte data ) { memory[ address ] = data; } + +void Video::Update( u32 cycles ) +{ + +} diff --git a/Video.h b/Video.h index 4ce58bd..9a2b2ae 100644 --- a/Video.h +++ b/Video.h @@ -13,13 +13,21 @@ | | | | 0x1000 - 0x1FFF | Pattern table 1 | | | | - | 0x2000 - 0x23FF | Nametable 0 | + | 0x2000 - 0x23BF | Nametable 0 | | | | - | 0x2400 - 0x27FF | Nametable 1 | + | 0x23C0 - 0x23FF | Attribute table 0 | + | | | + | 0x2400 - 0x27BF | Nametable 1 | + | | | + | 0x27C0 - 0x27FF | Attribute table 1 | | | | | 0x2800 - 0x2BFF | Nametable 2 | | | | - | 0x2C00 - 0x2FFF | Nametable 3 | + | 0x2BC0 - 0x2BFF | Attribute table 2 | + | | | + | 0x2C00 - 0x2FBF | Nametable 3 | + | | | + | 0x2FC0 - 0x2FFF | Attribute table 3 | | | | | 0x3000 - 0x3EFF | Mirrors of 0x2000 0x2EFF | | | | @@ -35,6 +43,7 @@ class Cartridge; +class Memory; class Video { @@ -42,11 +51,24 @@ class Video static constexpr u32 NES_VIDEO_RESOLUTION = 256 * 240; - Video( Cartridge *memory ); + /* PPU Register addresses */ + static constexpr word PPUCTRL_REGISTER = 0x2000; + static constexpr word PPUMASK_REGISTER = 0x2001; + static constexpr word PPUSTATUS_REGISTER = 0x2002; + static constexpr word OAMA_REGISTER = 0x2003; + static constexpr word OAMADATA_REGISTER = 0x2004; + static constexpr word PPUSCROLL_REGISTER = 0x2005; + static constexpr word PPUADDR_REGISTER = 0x2006; + static constexpr word PPUDATA_ADDRESS = 0x2007; + + + Video( Cartridge *cartridge, Memory *cpuMemory ); ~Video(); void Reset(); + void Update( u32 cycles ); + /* PPU memory management */ const byte * const GetPPUMemory() const; byte Read( word address ) const; @@ -56,20 +78,9 @@ class Video RGB* GetFrameBuffer() const; private: - - /* PPU Register addresses */ - static constexpr word PPUCTRL_REGISTER = 0x2000; - static constexpr word PPUMASK_REGISTER = 0x2001; - static constexpr word PPUSTATUS_REGISTER = 0x2002; - static constexpr word OAMA_REGISTER = 0x2003; - static constexpr word OAMADATA_REGISTER = 0x2004; - static constexpr word PPUSCROLL_REGISTER = 0x2005; - static constexpr word PPUADDR_REGISTER = 0x2006; - static constexpr word PPUDATA_ADDRESS = 0x2007; - - /* Associated Systems */ Cartridge *cartridge; + Memory *cpuMemory; /* PPU memory layout */ byte *memory; diff --git a/main.cpp b/main.cpp index 68cc28e..2047917 100644 --- a/main.cpp +++ b/main.cpp @@ -28,21 +28,21 @@ int main(int argc, char** argv) cartridge.PrintDetails(); - Video video( &cartridge ); - Memory memory( cartridge, video ); + Memory memory( &cartridge ); + Video video( &cartridge, &memory ); Cpu cpu( &memory ); Debugger debugger( &cpu, &memory, &video ); debugger.StartDebugger(); - /* Run a few frames for now */ bool quit = false; u32 currentCycles = 0; - while ( currentCycles < AVERAGE_CYCLES_PER_FRAME && !quit ) + while ( !quit ) { currentCycles += cpu.Update(); - DebuggerUpdateResult result = debugger.Update( 0.f, currentCycles ); + video.Update( currentCycles ); + const DebuggerUpdateResult result = debugger.Update( 0.f, currentCycles ); switch ( result ) { case DebuggerUpdateResult::QUIT: @@ -60,6 +60,11 @@ int main(int argc, char** argv) } break; } + + if ( currentCycles >= AVERAGE_CYCLES_PER_FRAME ) + { + currentCycles = 0; + } } return 0;