diff --git a/Debugger/CpuDebugger.cpp b/Debugger/CpuDebugger.cpp index 376f259..c4e8537 100644 --- a/Debugger/CpuDebugger.cpp +++ b/Debugger/CpuDebugger.cpp @@ -9,7 +9,7 @@ CpuDebugger::CpuDebugger() : instructionJump( false ) { - breakpoints.insert( 0xF109 ); + breakpoints.insert( 0xF1CE ); } void CpuDebugger::GenerateDisassemblerInstructionMask( Memory &memory ) diff --git a/Debugger/VideoDebugger.cpp b/Debugger/VideoDebugger.cpp index 4698035..77ee943 100644 --- a/Debugger/VideoDebugger.cpp +++ b/Debugger/VideoDebugger.cpp @@ -62,14 +62,12 @@ void VideoDebugger::CreateTextures( const Video &video ) void VideoDebugger::ComposeView( u32 cycles, const Video &video, const Memory &memory ) { - UpdatePatternTable( video, 0x0000, leftPatternTableBuffer ); - ImGui::SetNextWindowSize( ImVec2( 560, 510 ), ImGuiCond_FirstUseEver ); ImGui::Begin( "FrameBuffer" ); ImGui::Image( frameBufferTextureID, ImVec2( 512, 480 ) ); ImGui::End(); - + UpdatePatternTable( video, 0x0000, leftPatternTableBuffer ); ImGui::SetNextWindowSize( ImVec2( 560, 560 ), ImGuiCond_FirstUseEver ); ImGui::Begin( "VRAM Left" ); ImGui::Image( leftPatternTableTextureID, ImVec2( 512, 512 ) ); @@ -118,7 +116,7 @@ void VideoDebugger::ComposeView( u32 cycles, const Video &video, const Memory &m UpdateNameTable( video, memory, 0x2000, nametableTextureBuffer ); ImGui::SetNextWindowSize( ImVec2( 560, 560 ), ImGuiCond_FirstUseEver ); ImGui::Begin( "Nametable 0" ); - ImGui::Image( nametableTextureBuffer, ImVec2( 512, 500 ) ); + ImGui::Image( nametableTextureID, ImVec2( 512, 500 ) ); ImGui::End(); } @@ -129,8 +127,8 @@ void VideoDebugger::UpdatePatternTable( const Video &video, word address, RGB *b assert( ppuMemory != nullptr ); u32 vramPosition = 0; - for ( u32 tile = 0; tile < 256; ++tile ) - { + for ( u32 tile = 0; tile < Video::NES_PATTERN_TILE_AMOUNT; ++tile ) + { const u32 tileAddress = ( tile * 0x10 ) + address; u32 localvramPosition = vramPosition; @@ -146,7 +144,7 @@ void VideoDebugger::UpdatePatternTable( const Video &video, word address, RGB *b const byte value2 = ( firstByte & mask ) >> column; const byte finalValue = value | value2; - buffer[ localvramPosition + ( 7 - column ) ] = palette[ finalValue ]; + buffer[ localvramPosition + ( 7 - column ) ] = NES_PALETTE_COLORS[ palette[ finalValue ] ]; } localvramPosition += 128; } @@ -183,7 +181,7 @@ void VideoDebugger::UpdateTexturesOfCurrentPalettes( const Video &video, word ad assert( ppuMemory != nullptr ); assert( buffer != nullptr ); - u32 paletteAddress = address; + word paletteAddress = address; for ( byte index = 0; index < 4; ++index ) { for ( byte i = 0; i < 3; ++i ) @@ -198,6 +196,7 @@ void VideoDebugger::UpdateTexturesOfCurrentPalettes( const Video &video, word ad void VideoDebugger::UpdateNameTable( const Video &video, const Memory &memory, word nametableAddress, RGB *buffer ) { + /* We use the mal directly since reading some of the values in the map through memory.Read() has side effects */ const byte *const memoryMap = memory.GetMemoryMap(); assert( memoryMap != nullptr ); @@ -207,15 +206,15 @@ void VideoDebugger::UpdateNameTable( const Video &video, const Memory &memory, w /* Traverse the nametable and construct the background */ u32 initialAddress = nametableAddress; - for ( u32 row = 0; row < 30; ++row ) + for ( u32 row = 0; row < Video::NES_VIDEO_HEIGHT; ++row ) { - for ( u32 column = 0; column < 32; ++column ) + for ( u32 column = 0; column < Video::NES_VIDEO_WIDTH; ++column ) { const byte tileOffset = video.Read( nametableAddress ); ++nametableAddress; /* Update the background buffer */ - const byte tileAddress = patternTableAddress + tileOffset; + const u32 tileAddress = patternTableAddress + tileOffset; u32 localvramPosition = tileAddress; for ( byte tileRow = 0; tileRow < 8; ++tileRow ) { @@ -224,12 +223,13 @@ void VideoDebugger::UpdateNameTable( const Video &video, const Memory &memory, w for ( byte tileColumn = 0; tileColumn < 8; ++tileColumn ) { - byte mask = 0x01 << tileColumn; + const byte mask = 0x01 << tileColumn; const byte value = ( ( secondByte & mask ) >> tileColumn ) << 1; const byte value2 = ( firstByte & mask ) >> tileColumn; const byte finalValue = value | value2; - buffer[ localvramPosition + ( 7 - tileColumn ) ] = palette[ finalValue ]; + const u32 textureIndex = column + row * Video::NES_VIDEO_WIDTH; + buffer[ textureIndex ] = NES_PALETTE_COLORS[ palette[ finalValue ] ]; } localvramPosition += 128; } diff --git a/Debugger/VideoDebugger.h b/Debugger/VideoDebugger.h index e453d6d..a480b53 100644 --- a/Debugger/VideoDebugger.h +++ b/Debugger/VideoDebugger.h @@ -15,8 +15,8 @@ class VideoDebugger void ComposeView( u32 cycles, const Video &video, const Memory &memory ); private: - constexpr static RGB palette[4] = { { 255,255,255 },{ 0xCC,0xCC,0xCC },{ 0x77,0x77,0x77 }, { 0x0,0x0,0x0 } }; - + constexpr static byte palette[4] = { 0x0F, 0x2C, 0x38, 0x12 }; + using ImTextureID = void *; /* Textures */ @@ -43,10 +43,10 @@ class VideoDebugger ImTextureID nametableTextureID; RGB *nametableTextureBuffer; - void UpdatePatternTable( const Video &video, word address, RGB *buffer ); void GenerateNesPaletteTexture(); void UpdateUniversalBackgroundColour( const Video &video ); void UpdateTexturesOfCurrentPalettes( const Video &video, word address, RGB **buffer ); void UpdateNameTable( const Video &video, const Memory &memory, word nametableAddress, RGB *buffer ); + void DrawTile( RGB *buffer ); }; \ No newline at end of file diff --git a/Memory.cpp b/Memory.cpp index 2f8871f..e39bed1 100644 --- a/Memory.cpp +++ b/Memory.cpp @@ -78,10 +78,8 @@ void Memory::Write( word address, byte data ) if ( address >= 0x2000 && address <= 0x3FFF ) { const word ppuRegister = ( address % 8 ) + 0x2000; - if ( ppuRegister == Video::PPUDATA_ADDRESS ) + if ( ppuRegister == Video::PPUADDR_REGISTER ) { - const word address = map[ Video::PPUADDR_REGISTER ]; - if ( IsAddressLatchClear ) { IsAddressLatchClear = false; @@ -91,11 +89,24 @@ void Memory::Write( word address, byte data ) { currentVRamAddress = data | currentVRamAddress; } - map[ Video::PPUDATA_ADDRESS ] = data; + map[ Video::PPUADDR_REGISTER ] = data; + + } + else if ( ppuRegister == Video::PPUDATA_ADDRESS ) + { + const word address = currentVRamAddress; + video->Write( address, data ); const byte ppuControlRegister = map[ Video::PPUCTRL_REGISTER ]; - const byte incrementAmount = ( ppuControlRegister | 0b0000'0100 ) >> 2; - map[ Video::PPUADDR_REGISTER ] = incrementAmount; + const byte incrementType = ( ppuControlRegister & 0b0000'0100 ) >> 2; + if ( incrementType == 0 ) + { + currentVRamAddress++; + } + else + { + currentVRamAddress += 32; + } } else { diff --git a/Types.h b/Types.h index 73c0ede..635894d 100644 --- a/Types.h +++ b/Types.h @@ -33,7 +33,10 @@ struct RGB } }; -constexpr RGB PINK = { 0xFF, 0x00, 0x80 }; +namespace color +{ + constexpr RGB PINK = { 0xFF, 0x00, 0x80 }; +} /* Operators */ diff --git a/Video.cpp b/Video.cpp index be8a486..7eadf0c 100644 --- a/Video.cpp +++ b/Video.cpp @@ -28,7 +28,7 @@ void Video::Reset() for ( u32 i = 0; i < NES_VIDEO_RESOLUTION; ++i ) { - frameBuffer[ i ] = PINK; + frameBuffer[ i ] = color::PINK; } MapCartridgeCHRToPPU(); diff --git a/Video.h b/Video.h index 5b01a25..0ba7361 100644 --- a/Video.h +++ b/Video.h @@ -48,7 +48,13 @@ class Video { public: - static constexpr u32 NES_VIDEO_RESOLUTION = 256 * 240; + /* NES frame buffer constants */ + static constexpr u32 NES_VIDEO_WIDTH = 256; + static constexpr u32 NES_VIDEO_HEIGHT = 240; + static constexpr u32 NES_VIDEO_RESOLUTION = NES_VIDEO_HEIGHT * NES_VIDEO_WIDTH; + + /* NES tiles and objects constants */ + static constexpr u32 NES_PATTERN_TILE_AMOUNT = 256; /* PPU Register addresses */ static constexpr word PPUCTRL_REGISTER = 0x2000;