Skip to content

Commit

Permalink
Implement address latch and ppu data/address registers
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonazan2 committed Oct 16, 2019
1 parent 83e00ab commit b207b87
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 41 deletions.
85 changes: 65 additions & 20 deletions Memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
#include "Video.h"


Memory::Memory( const Cartridge *cartridge )
Memory::Memory( const Cartridge *cartridge, Video *video )
: cartridge( cartridge )
, video ( video )
{
map = new byte[ 64_KB ];
Reset();
Expand All @@ -24,14 +25,47 @@ void Memory::Reset()
memset( map, 0x00, 64_KB );

MapCartridge();

map[ Video::PPUCTRL_REGISTER, 0x00 ];
map[ Video::PPUMASK_REGISTER, 0x00 ];
map[ Video::PPUSTATUS_REGISTER, 0b1010'0000 ];
map[ Video::OAMA_REGISTER, 0x00 ];
map[ Video::OAMADATA_REGISTER, 0x00 ];
map[ Video::PPUSCROLL_REGISTER, 0x00 ];
map[ Video::PPUDATA_ADDRESS, 0x00 ];
}

void Memory::MapCartridge()
{
assert( cartridge != nullptr );

/* For now only support NROM with PRG ROM of 16KB and no ram */
Cartridge::Header header = cartridge->GetHeader();
assert( header.mapper == 0x00 && header.prgRomSizeKB == 16 && !header.hasPRGRam);

const byte * const rom = cartridge->GetRom();

/* Map the PRG ROM to 0x8000 */
memcpy(&map[0x8000], &rom[0x0010], 16_KB );

/* Mirror the PRG ROM in 0xC000 */
memcpy(&map[0xC000], &rom[0x0010], 16_KB );
}

byte Memory::Read( word address ) const
byte Memory::Read( word address )
{
if ( address >= 0x2000 && address <= 0x3FFF )
{
const word mirroredAddress = ( address % 8 ) + 0x2000;
return map[ mirroredAddress ];
const word ppuRegister = ( address % 8 ) + 0x2000;

if ( ppuRegister == Video::PPUSTATUS_REGISTER )
{
ResetAddressLatch();
const byte ppuStatus = map[ Video::PPUSTATUS_REGISTER ];
byte newPpuStatus = ppuStatus ^ 0b1000'0000;
Write( Video::PPUSTATUS_REGISTER, newPpuStatus );
}
return map[ ppuRegister ];
}
else
{
Expand All @@ -43,8 +77,30 @@ void Memory::Write( word address, byte data )
{
if ( address >= 0x2000 && address <= 0x3FFF )
{
const word mirroredAddress = ( address % 8 ) + 0x2000;
map[ mirroredAddress ] = data;
const word ppuRegister = ( address % 8 ) + 0x2000;
if ( ppuRegister == Video::PPUDATA_ADDRESS )
{
const word address = map[ Video::PPUADDR_REGISTER ];

if ( IsAddressLatchClear )
{
IsAddressLatchClear = false;
currentVRamAddress = ( data | currentVRamAddress ) << 8;
}
else
{
currentVRamAddress = data | currentVRamAddress;
}
map[ Video::PPUDATA_ADDRESS ] = data;

const byte ppuControlRegister = map[ Video::PPUCTRL_REGISTER ];
const byte incrementAmount = ( ppuControlRegister | 0b0000'0100 ) >> 2;
map[ Video::PPUADDR_REGISTER ] = incrementAmount;
}
else
{
map[ ppuRegister ] = data;
}
}
else
{
Expand All @@ -57,19 +113,8 @@ const byte *const Memory::GetMemoryMap() const
return map;
}

void Memory::MapCartridge()
void Memory::ResetAddressLatch()
{
assert( cartridge != nullptr );

/* For now only support NROM with PRG ROM of 16KB and no ram */
Cartridge::Header header = cartridge->GetHeader();
assert( header.mapper == 0x00 && header.prgRomSizeKB == 16 && !header.hasPRGRam);

const byte * const rom = cartridge->GetRom();

/* Map the PRG ROM to 0x8000 */
memcpy(&map[0x8000], &rom[0x0010], 16_KB );

/* Mirror the PRG ROM in 0xC000 */
memcpy(&map[0xC000], &rom[0x0010], 16_KB );
IsAddressLatchClear = true;
currentVRamAddress = 0x00;
}
8 changes: 6 additions & 2 deletions Memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ class Memory
{
public:

Memory( const Cartridge *cartridge );
Memory( const Cartridge *cartridge, Video *video );
~Memory();

void Reset();

/* Memory management */
byte Read( word address ) const;
byte Read( word address );
void Write( word address, byte data );

const byte *const GetMemoryMap() const;
Expand All @@ -56,10 +56,14 @@ class Memory

/* Associated NES systems */
const Cartridge *cartridge;
Video *video;

/* NES memory map */
byte *map;

bool IsAddressLatchClear;
word currentVRamAddress;

void MapCartridge();
void ResetAddressLatch();
};
16 changes: 2 additions & 14 deletions Video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@
#include <assert.h>

#include "Cartridge.h"
#include "Memory.h"


Video::Video( Cartridge *cartridge, Memory *cpuMemory )
Video::Video( Cartridge *cartridge )
: cartridge( cartridge )
, cpuMemory( cpuMemory )
{
memory = new byte[ 16_KB ];
frameBuffer = new RGB[ NES_VIDEO_RESOLUTION ];
Expand All @@ -35,14 +33,6 @@ 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()
Expand All @@ -55,8 +45,6 @@ void Video::MapCartridgeCHRToPPU()
const u32 offset = (header.prgRomSizeKB * 1_KB) + 0x0010;
const u32 dataSize = header.chrRomSizeKB * 1_KB;
memcpy( memory, &cartridgeRom[ offset ], dataSize );

memory[ PPUSTATUS_REGISTER ] = 0b1010'0000;
}

RGB* Video::GetFrameBuffer() const
Expand All @@ -81,5 +69,5 @@ void Video::Write( word address, byte data )

void Video::Update( u32 cycles )
{

// We do nothing here for now
}
4 changes: 1 addition & 3 deletions Video.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@


class Cartridge;
class Memory;

class Video
{
Expand All @@ -62,7 +61,7 @@ class Video
static constexpr word PPUDATA_ADDRESS = 0x2007;


Video( Cartridge *cartridge, Memory *cpuMemory );
Video( Cartridge *cartridge );
~Video();

void Reset();
Expand All @@ -80,7 +79,6 @@ class Video
private:
/* Associated Systems */
Cartridge *cartridge;
Memory *cpuMemory;

/* PPU memory layout */
byte *memory;
Expand Down
4 changes: 2 additions & 2 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ int main(int argc, char** argv)

cartridge.PrintDetails();

Memory memory( &cartridge );
Video video( &cartridge, &memory );
Video video( &cartridge );
Memory memory( &cartridge, &video );
Cpu cpu( &memory );

Debugger debugger( &cpu, &memory, &video );
Expand Down

0 comments on commit b207b87

Please sign in to comment.