summaryrefslogtreecommitdiff
path: root/lib/nes/sys/ppu.hh
diff options
context:
space:
mode:
Diffstat (limited to 'lib/nes/sys/ppu.hh')
-rw-r--r--lib/nes/sys/ppu.hh135
1 files changed, 68 insertions, 67 deletions
diff --git a/lib/nes/sys/ppu.hh b/lib/nes/sys/ppu.hh
index cdca0ae..013546a 100644
--- a/lib/nes/sys/ppu.hh
+++ b/lib/nes/sys/ppu.hh
@@ -1,6 +1,7 @@
#pragma once
#include "nes/sys/types/cycle-count.hh"
+#include "nes/common/types.hh"
namespace nes
{
@@ -17,40 +18,40 @@ namespace nes::sys
class ppu
{
- static constexpr auto sprite_max_count = unsigned{ 64 };
- static constexpr auto vram_size = std::size_t{ 0x800 };
- static constexpr auto oam_size = std::size_t{ sprite_max_count * 4 };
- static constexpr auto palette_buffer_size = std::size_t{ 0x20 };
- static constexpr auto tile_size = unsigned{ 8 };
+ static constexpr auto sprite_max_count = u32{ 64 };
+ static constexpr auto vram_size = u32{ 0x800 };
+ static constexpr auto oam_size = u32{ sprite_max_count * 4 };
+ static constexpr auto palette_buffer_size = u32{ 0x20 };
+ static constexpr auto tile_size = u32{ 8 };
// Writes to some registers are ignored until this clock cycle.
static constexpr auto boot_up_cycles = cycle_count::from_ppu(29658);
- enum class bitplane : unsigned { _0, _1 };
- enum class palette : unsigned { _0, _1, _2, _3 };
- enum class palette_color : unsigned { _0, _1, _2, _3 };
- enum class name_table : unsigned { _0, _1, _2, _3 };
- enum class role : unsigned { background, foreground };
- enum class pattern_table : unsigned { _0, _1 };
- enum class vram_increment : unsigned { forward, downward };
- enum class sprite_size : unsigned { single_height, double_height };
- enum class tile : std::uint8_t {};
- enum class color : std::uint8_t {};
+ enum class bitplane : u32 { _0, _1 };
+ enum class palette : u32 { _0, _1, _2, _3 };
+ enum class palette_color : u32 { _0, _1, _2, _3 };
+ enum class name_table : u32 { _0, _1, _2, _3 };
+ enum class role : u32 { background, foreground };
+ enum class pattern_table : u32 { _0, _1 };
+ enum class vram_increment : u32 { forward, downward };
+ enum class sprite_size : u32 { single_height, double_height };
+ enum class tile : u8 {};
+ enum class color : u8 {};
#define BITFIELD_VALIDATE(mask, offset_from_right) \
static_assert((mask & (1 << offset_from_right)) != 0); \
static_assert(offset_from_right == 0 || (mask & (1 << (offset_from_right - 1))) == 0);
#define BITFIELD_VALUE(name, base, mask, offset_from_right) \
BITFIELD_VALIDATE(mask, offset_from_right) \
- auto get_##name() const -> unsigned { return (base & mask) >> offset_from_right; } \
- auto set_##name(unsigned const v) -> void { base = (base & ~mask) | ((v << offset_from_right) & mask); }
+ auto get_##name() const -> u32 { return (base & mask) >> offset_from_right; } \
+ auto set_##name(u32 const v) -> void { base = (base & ~mask) | ((v << offset_from_right) & mask); }
#define BITFIELD_ENUM(name, type, base, mask, offset_from_right) \
BITFIELD_VALIDATE(mask, offset_from_right) \
auto get_##name() const -> type { return static_cast<type>((base & mask) >> offset_from_right); } \
- auto set_##name(type const v) -> void { base = (base & ~mask) | ((static_cast<unsigned>(v) << offset_from_right) & mask); }
+ auto set_##name(type const v) -> void { base = (base & ~mask) | ((static_cast<u32>(v) << offset_from_right) & mask); }
#define BITFIELD_FLAG(name, base, mask, offset_from_right) \
BITFIELD_VALIDATE(mask, offset_from_right) \
auto get_##name() const -> bool { return base & mask; } \
- auto set_##name(unsigned const v) -> void { base = (base & ~mask) | (v ? mask : 0); }
+ auto set_##name(u32 const v) -> void { base = (base & ~mask) | (v ? mask : 0); }
struct color_index
{
@@ -58,11 +59,11 @@ namespace nes::sys
BITFIELD_ENUM(palette, palette, value, 0b00001100, 2)
BITFIELD_ENUM(role, role, value, 0b00010000, 4)
- std::uint8_t value{};
+ u8 value{};
color_index() = default;
- explicit color_index(std::uint8_t const value)
+ explicit color_index(u8 const value)
: value{ value }
{
}
@@ -81,21 +82,21 @@ namespace nes::sys
BITFIELD_FLAG(flip_horizontal, value[2], 0b01000000, 6)
BITFIELD_FLAG(flip_vertical, value[2], 0b10000000, 7)
- auto get_y() const -> std::uint8_t { return value[0]; }
- auto get_tile_index() const -> std::uint8_t { return value[1]; }
- auto get_attributes() const -> std::uint8_t { return value[2]; }
- auto get_x() const -> std::uint8_t { return value[3]; }
+ auto get_y() const -> u8 { return value[0]; }
+ auto get_tile_index() const -> u8 { return value[1]; }
+ auto get_attributes() const -> u8 { return value[2]; }
+ auto get_x() const -> u8 { return value[3]; }
- auto set_y(std::uint8_t const v) -> void { value[0] = v; }
- auto set_tile_index(std::uint8_t const v) -> void { value[1] = v; }
- auto set_attributes(std::uint8_t const v) -> void { value[2] = v; }
- auto set_x(std::uint8_t const v) -> void { value[3] = v; }
+ auto set_y(u8 const v) -> void { value[0] = v; }
+ auto set_tile_index(u8 const v) -> void { value[1] = v; }
+ auto set_attributes(u8 const v) -> void { value[2] = v; }
+ auto set_x(u8 const v) -> void { value[3] = v; }
- std::uint8_t value[4]{};
+ u8 value[4]{};
explicit sprite() = default;
- explicit sprite(std::uint8_t const* data)
+ explicit sprite(u8 const* data)
: value{ data[0], data[1], data[2], data[3] }
{
}
@@ -109,7 +110,7 @@ namespace nes::sys
struct evaluated_sprite
{
tile_row pattern;
- std::uint8_t x{ 0 };
+ u8 x{ 0 };
bool is_in_front{ false };
bool is_sprite_zero{ false };
};
@@ -118,8 +119,8 @@ namespace nes::sys
cpu& cpu_;
cartridge& cartridge_;
display& display_;
- std::uint8_t vram_[vram_size]{};
- std::uint8_t oam_[oam_size]{};
+ u8 vram_[vram_size]{};
+ u8 oam_[oam_size]{};
color palette_buffer_[palette_buffer_size]
{
color{ 0x09 }, color{ 0x01 }, color{ 0x00 }, color{ 0x01 },
@@ -131,7 +132,7 @@ namespace nes::sys
color{ 0x08 }, color{ 0x3A }, color{ 0x00 }, color{ 0x02 },
color{ 0x00 }, color{ 0x20 }, color{ 0x2C }, color{ 0x08 },
};
- std::uint8_t latch_{}; // The last read/written IO register value, returned when reading write-only registers.
+ u8 latch_{}; // The last read/written IO register value, returned when reading write-only registers.
struct
{
BITFIELD_FLAG(sprite_overflow, value, 0b00100000, 5)
@@ -139,9 +140,9 @@ namespace nes::sys
BITFIELD_FLAG(vblank, value, 0b10000000, 7)
// Set the remaining (unused) bits based on the given value.
- auto set_remaining(std::uint8_t const v) -> void { value = (value & ~0b00011111) | (v & 0b00011111); }
+ auto set_remaining(u8 const v) -> void { value = (value & ~0b00011111) | (v & 0b00011111); }
- std::uint8_t value{ 0b00000000 };
+ u8 value{ 0b00000000 };
} status_{};
struct
{
@@ -160,7 +161,7 @@ namespace nes::sys
// Enable/disable vblank NMI.
BITFIELD_FLAG(vblank_nmi, value, 0b10000000, 7)
- std::uint8_t value{ 0b00000000 };
+ u8 value{ 0b00000000 };
} control_{};
struct
{
@@ -181,7 +182,7 @@ namespace nes::sys
// Emphasize blue.
BITFIELD_FLAG(emphasize_blue, value, 0b10000000, 7)
- std::uint8_t value{ 0b00000000 };
+ u8 value{ 0b00000000 };
} mask_{};
struct
{
@@ -201,15 +202,15 @@ namespace nes::sys
BITFIELD_VALUE(address_low, value, 0b0000000011111111, 0)
BITFIELD_VALUE(address_high, value, 0b0111111100000000, 8)
- std::uint16_t value{};
+ u16 value{};
} v{}, t{}; // Current and temporary VRAM address and scroll position (15 bits)
- std::uint8_t x{}; // Fine X scroll (3 bits)
+ u8 x{}; // Fine X scroll (3 bits)
bool w{}; // Second write toggle (1 bit)
} internal_{};
- std::uint8_t oamaddr_{}; // Address accessed by IO registers
- std::uint8_t ppudata_read_buffer_{}; // Delays PPUDATA reads by one.
- unsigned scanline_{ 240 };
- unsigned scanline_cycle_{ 340 };
+ u8 oamaddr_{}; // Address accessed by IO registers
+ u8 ppudata_read_buffer_{}; // Delays PPUDATA reads by one.
+ u32 scanline_{ 240 };
+ u32 scanline_cycle_{ 340 };
bool even_frame_{ true };
tile_row current_background_{};
tile_row next_background_{};
@@ -217,11 +218,11 @@ namespace nes::sys
{
tile tile{ 0 };
palette palette{ 0 };
- std::uint8_t bitplane_0{ 0 };
- std::uint8_t bitplane_1{ 0 };
+ u8 bitplane_0{ 0 };
+ u8 bitplane_1{ 0 };
} fetch_cycle_{}; // Data populated during the fetch cycle.
evaluated_sprite sprites_[8]{}; // Evaluated sprites.
- unsigned sprite_count_{ 0 }; // Number of evaluated sprites in sprites_.
+ u32 sprite_count_{ 0 }; // Number of evaluated sprites in sprites_.
#undef BITFIELD_VALIDATE
#undef BITFIELD_VALUE
@@ -242,30 +243,30 @@ namespace nes::sys
// Memory access
- auto read8(address) -> std::uint8_t;
- auto write8(address, std::uint8_t) -> void;
+ auto read8(address) -> u8;
+ auto write8(address, u8) -> void;
// IO registers
- auto read_latch() -> std::uint8_t;
- auto read_ppustatus() -> std::uint8_t;
- auto read_oamdata() -> std::uint8_t;
- auto read_ppudata() -> std::uint8_t;
+ auto read_latch() -> u8;
+ auto read_ppustatus() -> u8;
+ auto read_oamdata() -> u8;
+ auto read_ppudata() -> u8;
- auto write_latch(std::uint8_t) -> void;
- auto write_ppuctrl(std::uint8_t) -> void;
- auto write_ppuscroll(std::uint8_t) -> void;
- auto write_ppumask(std::uint8_t) -> void;
- auto write_ppuaddr(std::uint8_t) -> void;
- auto write_ppudata(std::uint8_t) -> void;
- auto write_oamaddr(std::uint8_t) -> void;
- auto write_oamdata(std::uint8_t) -> void;
- auto write_oamdma(std::uint8_t) -> void;
+ auto write_latch(u8) -> void;
+ auto write_ppuctrl(u8) -> void;
+ auto write_ppuscroll(u8) -> void;
+ auto write_ppumask(u8) -> void;
+ auto write_ppuaddr(u8) -> void;
+ auto write_ppudata(u8) -> void;
+ auto write_oamaddr(u8) -> void;
+ auto write_oamdata(u8) -> void;
+ auto write_oamdma(u8) -> void;
private:
auto render_pixel() -> void;
auto evaluate_sprites() -> void;
- auto fetch_sprite_pattern(sprite, unsigned row) -> tile_row;
+ auto fetch_sprite_pattern(sprite, u32 row) -> tile_row;
// Helpers
@@ -274,9 +275,9 @@ namespace nes::sys
auto increment_y() -> void;
auto copy_x() -> void;
auto copy_y() -> void;
- auto get_sprite_height() const -> unsigned;
- auto get_tile_bitplane(pattern_table, tile, unsigned row, bitplane) -> std::uint8_t;
- auto get_tile_row(palette, std::uint8_t bitplane_0, std::uint8_t bitplane_1) const -> tile_row;
+ auto get_sprite_height() const -> u32;
+ auto get_tile_bitplane(pattern_table, tile, u32 row, bitplane) -> u8;
+ auto get_tile_row(palette, u8 bitplane_0, u8 bitplane_1) const -> tile_row;
auto ref_color(color_index) -> color&;
auto resolve_color(color) const -> rgb;
};