Update Ppu and PpuRegisters, add observer behavior
This commit is contained in:
@@ -10,9 +10,9 @@ namespace yaze {
|
|||||||
namespace app {
|
namespace app {
|
||||||
namespace emu {
|
namespace emu {
|
||||||
|
|
||||||
using namespace PPURegisters;
|
using namespace PpuRegisters;
|
||||||
|
|
||||||
void PPU::Update() {
|
void Ppu::Update() {
|
||||||
auto cycles_to_run = clock_.GetCycleCount();
|
auto cycles_to_run = clock_.GetCycleCount();
|
||||||
|
|
||||||
UpdateInternalState(cycles_to_run);
|
UpdateInternalState(cycles_to_run);
|
||||||
@@ -27,8 +27,8 @@ void PPU::Update() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPU::UpdateInternalState(int cycles) {
|
void Ppu::UpdateInternalState(int cycles) {
|
||||||
// Update the PPU's internal state based on the number of cycles
|
// Update the Ppu's internal state based on the number of cycles
|
||||||
cycle_count_ += cycles;
|
cycle_count_ += cycles;
|
||||||
|
|
||||||
// Check if it's time to move to the next scanline
|
// Check if it's time to move to the next scanline
|
||||||
@@ -43,7 +43,7 @@ void PPU::UpdateInternalState(int cycles) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPU::RenderScanline() {
|
void Ppu::RenderScanline() {
|
||||||
for (int y = 0; y < 240; ++y) {
|
for (int y = 0; y < 240; ++y) {
|
||||||
for (int x = 0; x < 256; ++x) {
|
for (int x = 0; x < 256; ++x) {
|
||||||
// Calculate the color index based on the x and y coordinates
|
// Calculate the color index based on the x and y coordinates
|
||||||
@@ -86,25 +86,181 @@ void PPU::RenderScanline() {
|
|||||||
DisplayFrameBuffer();
|
DisplayFrameBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPU::Notify(uint32_t address, uint8_t data) {
|
void Ppu::Notify(uint32_t address, uint8_t data) {
|
||||||
// Handle communication in the PPU.
|
// Handle communication in the Ppu.
|
||||||
if (address >= 0x2100 && address <= 0x213F) {
|
if (address >= 0x2100 && address <= 0x213F) {
|
||||||
// Handle register notification
|
// Handle register notification
|
||||||
switch (address) {
|
switch (address) {
|
||||||
case PPURegisters::INIDISP:
|
case INIDISP:
|
||||||
enable_forced_blanking_ = (data >> 7) & 0x01;
|
enable_forced_blanking_ = (data >> 7) & 0x01;
|
||||||
break;
|
break;
|
||||||
case PPURegisters::BGMODE:
|
case OBJSEL:
|
||||||
// Update the PPU mode settings
|
oam_size_.base_selection = (data >> 2) & 0x03;
|
||||||
|
oam_size_.name_selection = (data >> 4) & 0x07;
|
||||||
|
oam_size_.object_size = data & 0x03;
|
||||||
|
break;
|
||||||
|
case OAMADDL:
|
||||||
|
oam_address_.oam_address_low = data;
|
||||||
|
break;
|
||||||
|
case OAMADDH:
|
||||||
|
oam_address_.oam_address_msb = data & 0x01;
|
||||||
|
oam_address_.oam_priority_rotation = (data >> 1) & 0x01;
|
||||||
|
break;
|
||||||
|
case OAMDATA:
|
||||||
|
// Write the data to OAM
|
||||||
|
break;
|
||||||
|
case BGMODE:
|
||||||
|
// Update the Ppu mode settings
|
||||||
UpdateModeSettings();
|
UpdateModeSettings();
|
||||||
break;
|
break;
|
||||||
|
case MOSAIC:
|
||||||
|
mosaic_.bg_enable = (data >> 7) & 0x01;
|
||||||
|
mosaic_.mosaic_size = data & 0x0F;
|
||||||
|
break;
|
||||||
|
case BG1SC:
|
||||||
|
bgsc_[0] = BGSC(data);
|
||||||
|
break;
|
||||||
|
case BG2SC:
|
||||||
|
bgsc_[1] = BGSC(data);
|
||||||
|
break;
|
||||||
|
case BG3SC:
|
||||||
|
bgsc_[2] = BGSC(data);
|
||||||
|
break;
|
||||||
|
case BG4SC:
|
||||||
|
bgsc_[3] = BGSC(data);
|
||||||
|
break;
|
||||||
|
case BG12NBA:
|
||||||
|
bgnba_[0] = BGNBA(data);
|
||||||
|
break;
|
||||||
|
case BG34NBA:
|
||||||
|
bgnba_[1] = BGNBA(data);
|
||||||
|
break;
|
||||||
|
case BG1HOFS:
|
||||||
|
bghofs_[0].horizontal_scroll = data;
|
||||||
|
break;
|
||||||
|
case BG2HOFS:
|
||||||
|
bghofs_[1].horizontal_scroll = data;
|
||||||
|
break;
|
||||||
|
case BG3HOFS:
|
||||||
|
bghofs_[2].horizontal_scroll = data;
|
||||||
|
break;
|
||||||
|
case BG4HOFS:
|
||||||
|
bghofs_[3].horizontal_scroll = data;
|
||||||
|
break;
|
||||||
|
case BG1VOFS:
|
||||||
|
bgvofs_[0].vertical_scroll = data;
|
||||||
|
break;
|
||||||
|
case BG2VOFS:
|
||||||
|
bgvofs_[1].vertical_scroll = data;
|
||||||
|
break;
|
||||||
|
case BG3VOFS:
|
||||||
|
bgvofs_[2].vertical_scroll = data;
|
||||||
|
break;
|
||||||
|
case BG4VOFS:
|
||||||
|
bgvofs_[3].vertical_scroll = data;
|
||||||
|
break;
|
||||||
|
case VMAIN:
|
||||||
|
vmain_.increment_size = data & 0x03;
|
||||||
|
vmain_.remapping = (data >> 2) & 0x03;
|
||||||
|
vmain_.address_increment_mode = (data >> 4) & 0x01;
|
||||||
|
break;
|
||||||
|
case VMADDL:
|
||||||
|
vmaddl_.address_low = data;
|
||||||
|
break;
|
||||||
|
case VMADDH:
|
||||||
|
vmaddh_.address_high = data;
|
||||||
|
break;
|
||||||
|
case M7SEL:
|
||||||
|
m7sel_.flip_horizontal = data & 0x01;
|
||||||
|
m7sel_.flip_vertical = (data >> 1) & 0x01;
|
||||||
|
m7sel_.fill = (data >> 2) & 0x01;
|
||||||
|
m7sel_.tilemap_repeat = (data >> 3) & 0x01;
|
||||||
|
break;
|
||||||
|
case M7A:
|
||||||
|
m7a_.matrix_a = data;
|
||||||
|
break;
|
||||||
|
case M7B:
|
||||||
|
m7b_.matrix_b = data;
|
||||||
|
break;
|
||||||
|
case M7C:
|
||||||
|
m7c_.matrix_c = data;
|
||||||
|
break;
|
||||||
|
case M7D:
|
||||||
|
m7d_.matrix_d = data;
|
||||||
|
break;
|
||||||
|
case M7X:
|
||||||
|
m7x_.center_x = data;
|
||||||
|
break;
|
||||||
|
case M7Y:
|
||||||
|
m7y_.center_y = data;
|
||||||
|
break;
|
||||||
|
case CGADD:
|
||||||
|
cgadd_.address = data;
|
||||||
|
break;
|
||||||
|
case CGDATA:
|
||||||
|
// Write the data to CGRAM
|
||||||
|
break;
|
||||||
|
case W12SEL:
|
||||||
|
w12sel_.enable_bg1_a = data & 0x01;
|
||||||
|
w12sel_.invert_bg1_a = (data >> 1) & 0x01;
|
||||||
|
w12sel_.enable_bg1_b = (data >> 2) & 0x01;
|
||||||
|
w12sel_.invert_bg1_b = (data >> 3) & 0x01;
|
||||||
|
w12sel_.enable_bg2_c = (data >> 4) & 0x01;
|
||||||
|
w12sel_.invert_bg2_c = (data >> 5) & 0x01;
|
||||||
|
w12sel_.enable_bg2_d = (data >> 6) & 0x01;
|
||||||
|
w12sel_.invert_bg2_d = (data >> 7) & 0x01;
|
||||||
|
break;
|
||||||
|
case W34SEL:
|
||||||
|
w34sel_.enable_bg3_e = data & 0x01;
|
||||||
|
w34sel_.invert_bg3_e = (data >> 1) & 0x01;
|
||||||
|
w34sel_.enable_bg3_f = (data >> 2) & 0x01;
|
||||||
|
w34sel_.invert_bg3_f = (data >> 3) & 0x01;
|
||||||
|
w34sel_.enable_bg4_g = (data >> 4) & 0x01;
|
||||||
|
w34sel_.invert_bg4_g = (data >> 5) & 0x01;
|
||||||
|
w34sel_.enable_bg4_h = (data >> 6) & 0x01;
|
||||||
|
w34sel_.invert_bg4_h = (data >> 7) & 0x01;
|
||||||
|
break;
|
||||||
|
case WOBJSEL:
|
||||||
|
wobjsel_.enable_obj_i = data & 0x01;
|
||||||
|
wobjsel_.invert_obj_i = (data >> 1) & 0x01;
|
||||||
|
wobjsel_.enable_obj_j = (data >> 2) & 0x01;
|
||||||
|
wobjsel_.invert_obj_j = (data >> 3) & 0x01;
|
||||||
|
wobjsel_.enable_color_k = (data >> 4) & 0x01;
|
||||||
|
wobjsel_.invert_color_k = (data >> 5) & 0x01;
|
||||||
|
wobjsel_.enable_color_l = (data >> 6) & 0x01;
|
||||||
|
wobjsel_.invert_color_l = (data >> 7) & 0x01;
|
||||||
|
break;
|
||||||
|
case WH0:
|
||||||
|
wh0_.left_position = data;
|
||||||
|
break;
|
||||||
|
case WH1:
|
||||||
|
wh1_.right_position = data;
|
||||||
|
break;
|
||||||
|
case WH2:
|
||||||
|
wh2_.left_position = data;
|
||||||
|
break;
|
||||||
|
case WH3:
|
||||||
|
wh3_.right_position = data;
|
||||||
|
break;
|
||||||
|
case TM:
|
||||||
|
tm_.enable_layer = (data >> 5) & 0x01; //
|
||||||
|
break;
|
||||||
|
case TS:
|
||||||
|
ts_.enable_layer = (data >> 5) & 0x01;
|
||||||
|
break;
|
||||||
|
case TMW:
|
||||||
|
tmw_.enable_window = (data >> 5) & 0x01;
|
||||||
|
break;
|
||||||
|
case TSW:
|
||||||
|
tsw_.enable_window = (data >> 5) & 0x01;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPU::UpdateModeSettings() {
|
void Ppu::UpdateModeSettings() {
|
||||||
// Read the PPU mode settings from the PPU registers
|
// Read the Ppu mode settings from the Ppu registers
|
||||||
uint8_t modeRegister = memory_.ReadByte(PPURegisters::INIDISP);
|
uint8_t modeRegister = memory_.ReadByte(PpuRegisters::INIDISP);
|
||||||
|
|
||||||
// Mode is stored in the lower 3 bits
|
// Mode is stored in the lower 3 bits
|
||||||
auto mode = static_cast<BackgroundMode>(modeRegister & 0x07);
|
auto mode = static_cast<BackgroundMode>(modeRegister & 0x07);
|
||||||
@@ -149,14 +305,14 @@ void PPU::UpdateModeSettings() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the internal state of the PPU based on the mode settings
|
// Update the internal state of the Ppu based on the mode settings
|
||||||
// Update tile data, tilemaps, sprites, and palette based on the mode settings
|
// Update tile data, tilemaps, sprites, and palette based on the mode settings
|
||||||
UpdateTileData();
|
UpdateTileData();
|
||||||
UpdatePaletteData();
|
UpdatePaletteData();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal methods to handle PPU rendering and operations
|
// Internal methods to handle Ppu rendering and operations
|
||||||
void PPU::UpdateTileData() {
|
void Ppu::UpdateTileData() {
|
||||||
// Fetch tile data from VRAM and store it in the internal buffer
|
// Fetch tile data from VRAM and store it in the internal buffer
|
||||||
for (uint16_t address = 0; address < tile_data_size_; ++address) {
|
for (uint16_t address = 0; address < tile_data_size_; ++address) {
|
||||||
tile_data_[address] = memory_.ReadByte(vram_base_address_ + address);
|
tile_data_[address] = memory_.ReadByte(vram_base_address_ + address);
|
||||||
@@ -192,9 +348,7 @@ void PPU::UpdateTileData() {
|
|||||||
|
|
||||||
// Update the sprites based on the fetched tile data
|
// Update the sprites based on the fetched tile data
|
||||||
for (uint16_t spriteIndex = 0; spriteIndex < sprites_.size(); ++spriteIndex) {
|
for (uint16_t spriteIndex = 0; spriteIndex < sprites_.size(); ++spriteIndex) {
|
||||||
uint16_t spriteAddress =
|
uint16_t spriteAddress = spriteIndex * sizeof(SpriteAttributes);
|
||||||
oam_address_ + spriteIndex * sizeof(SpriteAttributes);
|
|
||||||
// Assume ReadWord reads a 16-bit value from VRAM
|
|
||||||
uint16_t spriteData = memory_.ReadWord(spriteAddress);
|
uint16_t spriteData = memory_.ReadWord(spriteAddress);
|
||||||
|
|
||||||
// Extract sprite attributes from the sprite data
|
// Extract sprite attributes from the sprite data
|
||||||
@@ -222,9 +376,9 @@ void PPU::UpdateTileData() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPU::UpdateTileMapData() {}
|
void Ppu::UpdateTileMapData() {}
|
||||||
|
|
||||||
void PPU::RenderBackground(int layer) {
|
void Ppu::RenderBackground(int layer) {
|
||||||
auto bg1_tilemap_info = BGSC(0);
|
auto bg1_tilemap_info = BGSC(0);
|
||||||
auto bg1_chr_data = BGNBA(0);
|
auto bg1_chr_data = BGNBA(0);
|
||||||
auto bg2_tilemap_info = BGSC(0);
|
auto bg2_tilemap_info = BGSC(0);
|
||||||
@@ -261,17 +415,15 @@ void PPU::RenderBackground(int layer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPU::RenderSprites() {
|
void Ppu::RenderSprites() {}
|
||||||
// ...
|
|
||||||
}
|
|
||||||
|
|
||||||
void PPU::UpdatePaletteData() {}
|
void Ppu::UpdatePaletteData() {}
|
||||||
|
|
||||||
void PPU::ApplyEffects() {}
|
void Ppu::ApplyEffects() {}
|
||||||
|
|
||||||
void PPU::ComposeLayers() {}
|
void Ppu::ComposeLayers() {}
|
||||||
|
|
||||||
void PPU::DisplayFrameBuffer() {
|
void Ppu::DisplayFrameBuffer() {
|
||||||
if (!screen_->IsActive()) {
|
if (!screen_->IsActive()) {
|
||||||
screen_->Create(256, 240, 24, frame_buffer_);
|
screen_->Create(256, 240, 24, frame_buffer_);
|
||||||
rom()->RenderBitmap(screen_.get());
|
rom()->RenderBitmap(screen_.get());
|
||||||
|
|||||||
@@ -14,20 +14,48 @@ namespace yaze {
|
|||||||
namespace app {
|
namespace app {
|
||||||
namespace emu {
|
namespace emu {
|
||||||
|
|
||||||
class IPPU {
|
using namespace yaze::app::emu::PpuRegisters;
|
||||||
public:
|
|
||||||
virtual ~IPPU() = default;
|
|
||||||
|
|
||||||
virtual void writeRegister(uint16_t address, uint8_t data) = 0;
|
class PpuInterface {
|
||||||
virtual uint8_t readRegister(uint16_t address) const = 0;
|
public:
|
||||||
virtual void setOAMData(const std::vector<uint8_t>& data) = 0;
|
virtual ~PpuInterface() = default;
|
||||||
virtual std::vector<uint8_t> getOAMData() const = 0;
|
|
||||||
virtual void setVRAMData(const std::vector<uint8_t>& data) = 0;
|
// Memory Interactions
|
||||||
virtual std::vector<uint8_t> getVRAMData() const = 0;
|
virtual void Write(uint16_t address, uint8_t data) = 0;
|
||||||
virtual void setCGRAMData(const std::vector<uint8_t>& data) = 0;
|
virtual uint8_t Read(uint16_t address) const = 0;
|
||||||
virtual std::vector<uint8_t> getCGRAMData() const = 0;
|
|
||||||
virtual void renderFrame() = 0;
|
// Rendering Controls
|
||||||
virtual std::vector<uint32_t> getFrameBuffer() const = 0;
|
virtual void RenderFrame() = 0;
|
||||||
|
virtual void RenderScanline() = 0;
|
||||||
|
virtual void RenderBackground(int layer) = 0;
|
||||||
|
virtual void RenderSprites() = 0;
|
||||||
|
|
||||||
|
// State Management
|
||||||
|
virtual void Init() = 0;
|
||||||
|
virtual void Reset() = 0;
|
||||||
|
virtual void Update(double deltaTime) = 0;
|
||||||
|
virtual void UpdateClock(double deltaTime) = 0;
|
||||||
|
virtual void UpdateInternalState(int cycles) = 0;
|
||||||
|
|
||||||
|
// Data Access
|
||||||
|
virtual const std::vector<uint8_t>& GetFrameBuffer() const = 0;
|
||||||
|
virtual std::shared_ptr<gfx::Bitmap> GetScreen() const = 0;
|
||||||
|
|
||||||
|
// Mode and Setting Updates
|
||||||
|
virtual void UpdateModeSettings() = 0;
|
||||||
|
virtual void UpdateTileData() = 0;
|
||||||
|
virtual void UpdateTileMapData() = 0;
|
||||||
|
virtual void UpdatePaletteData() = 0;
|
||||||
|
|
||||||
|
// Layer Composition
|
||||||
|
virtual void ApplyEffects() = 0;
|
||||||
|
virtual void ComposeLayers() = 0;
|
||||||
|
|
||||||
|
// Display Output
|
||||||
|
virtual void DisplayFrameBuffer() = 0;
|
||||||
|
|
||||||
|
// Notification (Observer pattern)
|
||||||
|
virtual void Notify(uint32_t address, uint8_t data) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Enum representing different background modes
|
// Enum representing different background modes
|
||||||
@@ -235,10 +263,10 @@ struct BackgroundLayer {
|
|||||||
|
|
||||||
const int kPpuClockSpeed = 5369318; // 5.369318 MHz
|
const int kPpuClockSpeed = 5369318; // 5.369318 MHz
|
||||||
|
|
||||||
class PPU : public Observer, public SharedROM {
|
class Ppu : public Observer, public SharedROM {
|
||||||
public:
|
public:
|
||||||
// Initializes the PPU with the necessary resources and dependencies
|
// Initializes the PPU with the necessary resources and dependencies
|
||||||
PPU(Memory& memory, Clock& clock) : memory_(memory), clock_(clock) {}
|
Ppu(Memory& memory, Clock& clock) : memory_(memory), clock_(clock) {}
|
||||||
|
|
||||||
// Initialize the frame buffer
|
// Initialize the frame buffer
|
||||||
void Init() {
|
void Init() {
|
||||||
@@ -299,6 +327,43 @@ class PPU : public Observer, public SharedROM {
|
|||||||
Memory& memory_;
|
Memory& memory_;
|
||||||
Clock& clock_;
|
Clock& clock_;
|
||||||
|
|
||||||
|
// PPU registers
|
||||||
|
OAMSize oam_size_;
|
||||||
|
OAMAddress oam_address_;
|
||||||
|
Mosaic mosaic_;
|
||||||
|
std::array<BGSC, 4> bgsc_;
|
||||||
|
std::array<BGNBA, 4> bgnba_;
|
||||||
|
std::array<BGHOFS, 4> bghofs_;
|
||||||
|
std::array<BGVOFS, 4> bgvofs_;
|
||||||
|
struct VMAIN vmain_;
|
||||||
|
struct VMADDL vmaddl_;
|
||||||
|
struct VMADDH vmaddh_;
|
||||||
|
// struct VMDATAL vmdatal_;
|
||||||
|
// struct VMDATAH vmdatah_;
|
||||||
|
struct M7SEL m7sel_;
|
||||||
|
struct M7A m7a_;
|
||||||
|
struct M7B m7b_;
|
||||||
|
struct M7C m7c_;
|
||||||
|
struct M7D m7d_;
|
||||||
|
struct M7X m7x_;
|
||||||
|
struct M7Y m7y_;
|
||||||
|
struct CGADD cgadd_;
|
||||||
|
struct CGDATA cgdata_;
|
||||||
|
struct W12SEL w12sel_;
|
||||||
|
struct W34SEL w34sel_;
|
||||||
|
struct WOBJSEL wobjsel_;
|
||||||
|
struct WH0 wh0_;
|
||||||
|
struct WH1 wh1_;
|
||||||
|
struct WH2 wh2_;
|
||||||
|
struct WH3 wh3_;
|
||||||
|
struct WBGLOG wbglog_;
|
||||||
|
struct WOBJLOG wobjlog_;
|
||||||
|
struct TM tm_;
|
||||||
|
struct TS ts_;
|
||||||
|
struct TSW tsw_;
|
||||||
|
struct TMW tmw_;
|
||||||
|
struct SETINI setini_;
|
||||||
|
|
||||||
Tilemap tilemap_;
|
Tilemap tilemap_;
|
||||||
BackgroundMode bg_mode_;
|
BackgroundMode bg_mode_;
|
||||||
std::array<BackgroundLayer, 4> bg_layers_;
|
std::array<BackgroundLayer, 4> bg_layers_;
|
||||||
@@ -307,11 +372,9 @@ class PPU : public Observer, public SharedROM {
|
|||||||
std::vector<uint8_t> frame_buffer_;
|
std::vector<uint8_t> frame_buffer_;
|
||||||
std::shared_ptr<gfx::Bitmap> screen_;
|
std::shared_ptr<gfx::Bitmap> screen_;
|
||||||
|
|
||||||
uint16_t oam_address_;
|
|
||||||
uint16_t tile_data_size_;
|
uint16_t tile_data_size_;
|
||||||
uint16_t vram_base_address_;
|
uint16_t vram_base_address_;
|
||||||
uint16_t tilemap_base_address_;
|
uint16_t tilemap_base_address_;
|
||||||
|
|
||||||
uint16_t screen_brightness_ = 0x00;
|
uint16_t screen_brightness_ = 0x00;
|
||||||
|
|
||||||
bool enable_forced_blanking_ = false;
|
bool enable_forced_blanking_ = false;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace yaze {
|
|||||||
namespace app {
|
namespace app {
|
||||||
namespace emu {
|
namespace emu {
|
||||||
|
|
||||||
namespace PPURegisters {
|
namespace PpuRegisters {
|
||||||
|
|
||||||
constexpr uint16_t INIDISP = 0x2100;
|
constexpr uint16_t INIDISP = 0x2100;
|
||||||
|
|
||||||
@@ -143,12 +143,14 @@ struct BGMODE {
|
|||||||
uint8_t tile_size : 4;
|
uint8_t tile_size : 4;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MOSAIC {
|
struct Mosaic {
|
||||||
uint8_t bg_enable : 4;
|
uint8_t bg_enable : 4;
|
||||||
uint8_t mosaic_size : 4;
|
uint8_t mosaic_size : 4;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BGSC {
|
struct BGSC {
|
||||||
|
BGSC() = default;
|
||||||
|
~BGSC() = default;
|
||||||
explicit BGSC(uint8_t value)
|
explicit BGSC(uint8_t value)
|
||||||
: horizontal_tilemap_count(value & 0x01),
|
: horizontal_tilemap_count(value & 0x01),
|
||||||
vertical_tilemap_count((value >> 1) & 0x01),
|
vertical_tilemap_count((value >> 1) & 0x01),
|
||||||
@@ -159,6 +161,8 @@ struct BGSC {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct BGNBA {
|
struct BGNBA {
|
||||||
|
BGNBA() = default;
|
||||||
|
~BGNBA() = default;
|
||||||
explicit BGNBA(uint8_t value)
|
explicit BGNBA(uint8_t value)
|
||||||
: chr_base_address_2(value & 0x0F),
|
: chr_base_address_2(value & 0x0F),
|
||||||
chr_base_address_1((value >> 4) & 0x0F) {}
|
chr_base_address_1((value >> 4) & 0x0F) {}
|
||||||
@@ -409,7 +413,7 @@ struct STAT78 {
|
|||||||
uint8_t unused : 1;
|
uint8_t unused : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace PPURegisters
|
} // namespace PpuRegisters
|
||||||
|
|
||||||
} // namespace emu
|
} // namespace emu
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
|||||||
Reference in New Issue
Block a user