1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
#define PPU_CTRL_BG_TILE_SELECT 0x10
#define PPU_CTRL_SPRITE_TILE_SELECT 0x08
// Define constants for PPU control and mask bits
#define PPU_CTRL_NMI 0x80
#define PPU_CTRL_SPRITE_HEIGHT 0x20
#define PPU_CTRL_SPRITE_TILE 0x08
#define PPU_CTRL_VRAM_INCREMENT 0x04
#define PPU_MASK_SHOW_BG 0x08
#define PPU_MASK_SHOW_SPRITES 0x10
// Define mirroring modes
#define MIRROR_HORIZONTAL 0
#define MIRROR_VERTICAL 1
#define MIRROR_FOURSCREEN 2
struct ppu_state {
uint16_t bg_shift_pattern_low;
uint16_t bg_shift_pattern_high;
uint16_t bg_shift_attrib_low;
uint16_t bg_shift_attrib_high;
uint16_t scanline;
uint16_t dot;
uint16_t vram_addr;
uint16_t temp_addr;
uint8_t fine_x;
uint8_t bg_next_tile_id;
uint8_t bg_next_tile_attrib;
uint8_t bg_next_tile_lsb;
uint8_t bg_next_tile_msb;
uint8_t oam_addr;
uint8_t oam_data;
uint8_t even_frame;
uint8_t reg_ctrl;
uint8_t reg_mask;
uint8_t reg_status;
uint8_t write_latch;
uint8_t vram_read_buffer;
uint8_t open_bus;
uint8_t sprite_count;
uint8_t palette[32];
// NOTE(peter): one byte left on cacheline
// NOTE(peter): CACHELINE 2 start here!
uint8_t sprite_indexes[8];
uint8_t sprite_positions[8];
uint8_t sprite_priorities[8];
uint8_t sprite_shift_lo[8];
uint8_t sprite_shift_hi[8];
uint8_t secondary_oam[32];
uint8_t oam[256];
uint8_t input[2]; // Controller 1 & 2
uint8_t input_latch[2]; // Latched inputs after strobe
uint8_t input_bit[2]; // Current bit position being shifted out
uint8_t input_strobe; // Control bit (0 or 1)
uint8_t frame_ready;
} __attribute__((packed, aligned(64)));
struct apu_state {
uint32_t frame_cycle;
uint8_t mode;
uint8_t irq_inhibit;
uint8_t irq_pending;
uint8_t dmc_dma_enabled;
uint32_t dmc_sample_timer;
} __attribute__((packed, aligned(64)));
struct cpu_state {
size_t cycles;
uint16_t pc; // Program Counter
uint8_t sp; // Stack Pointer
uint8_t a; // Accumulator
uint8_t x; // X Register
uint8_t y; // Y Register
uint8_t p; // Processor Status Flags (this can be expanded with separate flags if needed)
uint8_t n; // Negative Flag
uint8_t v; // Overflow Flag
// uint8_t b; // Break Flag (Set by BRK instruction) -- does not exist outside the stack
uint8_t d; // Decimal Flag
uint8_t i; // Interrupt Disable Flag
uint8_t z; // Zero Flag
uint8_t c; // Carry Flag
// --
uint8_t irq_pending;
uint8_t nmi_pending;
} __attribute__((packed, aligned(64)));
struct ines_state {
uint8_t mapper;
uint8_t submapper;
uint8_t mirroring; // 0 = H, 1 = V, 2 = 4-screen
uint32_t prg_size;
uint32_t chr_size;
} __attribute__((packed, aligned(64)));
struct nes_state {
struct ppu_state ppu;
struct mapper_functions mapper_function;
union mapper_data mapper_data;
struct cpu_state cpu;
struct ines_state ines;
// struct apu_state apu;
uint8_t ram[RAM_SIZE] __attribute__((aligned(4096)));
uint8_t ciram[CIRAM_SIZE] __attribute__((aligned(4096)));
uint8_t prg_rom[PRG_ROM_SIZE] __attribute__((aligned(4096)));
uint8_t chr_rom[CHR_ROM_SIZE] __attribute__((aligned(4096)));
uint8_t chr_ram[CHR_RAM_SIZE] __attribute__((aligned(4096)));
uint8_t pixels[PIXELS_SIZE] __attribute__((aligned(4096)));
uint8_t sram[SRAM_SIZE] __attribute__((aligned(4096)));
} __attribute__((packed, aligned(4096)));
__attribute__((aligned(4096))) static uint32_t nes_palette[65] = {
0x585858ff, 0x00237cff, 0x0d1099ff, 0x300092ff, 0x4f006cff, 0x600035ff, 0x5c0500ff, 0x461800ff,
0x272d00ff, 0x093e00ff, 0x004500ff, 0x004106ff, 0x003545ff, 0x000000ff, 0x000000ff, 0x000000ff,
0xa1a1a1ff, 0x0b53d7ff, 0x3337feff, 0x6621f7ff, 0x9515beff, 0xac166eff, 0xa62721ff, 0x864300ff,
0x596200ff, 0x2d7a00ff, 0x0c8500ff, 0x007f2aff, 0x006d85ff, 0x000000ff, 0x000000ff, 0x000000ff,
0xffffffff, 0x51a5feff, 0x8084feff, 0xbc6afeff, 0xf15bfeff, 0xfe5ec4ff, 0xfe7269ff, 0xe19321ff,
0xadb600ff, 0x79d300ff, 0x51df21ff, 0x3ad974ff, 0x39c3dfff, 0x424242ff, 0x000000ff, 0x000000ff,
0xffffffff, 0xb5d9feff, 0xcacafeff, 0xe3befeff, 0xf9b8feff, 0xfebae7ff, 0xfec3bcff, 0xf4d199ff,
0xdee086ff, 0xc6ec87ff, 0xb2f29dff, 0xa7f0c3ff, 0xa8e7f0ff, 0xacacacff, 0x000000ff, 0x000000ff,
0xffffffff // one extra for debug-coloring...
};
|