summaryrefslogtreecommitdiff
path: root/mknes.h
blob: 5997bc8825ae60079ecfa6d89a4988c422a09984 (plain)
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158




// #define PPU_CTRL_NMI_ENABLE         0x80
// #define PPU_CTRL_MASTER_SLAVE       0x40
// #define PPU_CTRL_SPRITE_HEIGHT      0x20
// #define PPU_CTRL_BG_TILE_SELECT     0x10
// #define PPU_CTRL_SPRITE_TILE_SELECT 0x08
// #define PPU_CTRL_NT_SELECT_Y        0x04
// #define PPU_CTRL_NT_SELECT_X        0x02
// #define PPU_CTRL_VRAM_INCREMENT     0x01

// #define PPU_MASK_SHOW_BG            0x08
// #define PPU_MASK_SHOW_SPRITES       0x10

// #define PPU_STATUS_VBLANK           0x80
// #define PPU_STATUS_SPRITE0_HIT      0x40
// #define PPU_STATUS_OVERFLOW         0x20

#define PPU_CTRL_BG_TILE_SELECT     0x10
#define PPU_CTRL_SPRITE_TILE_SELECT 0x08
#define PPU_CTRL_NMI                0x80
#define PPU_CTRL_VRAM_INCREMENT     0x04

// Define constants for PPU control and mask bits
#define PPU_CTRL_NMI               0x80
#define PPU_CTRL_VRAM_INCREMENT    0x04
#define PPU_CTRL_SPRITE_HEIGHT     0x20
#define PPU_CTRL_SPRITE_TILE       0x08

#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 nes_state;



struct ppu_state {
	uint8_t pixels[256 * 240];

	uint8_t oam[256];
	uint8_t oam_addr;
	uint8_t oam_data;
	uint8_t secondary_oam[32];

	uint8_t reg_ctrl;
	uint8_t reg_mask;
	uint8_t reg_status;
	uint8_t reg_scroll[2];
	uint8_t reg_addr[2];
	uint8_t reg_latch;

	uint32_t vram_addr;
	uint32_t temp_addr;
	uint32_t fine_x;

	uint8_t vram_read_buffer;
	uint8_t write_latch;

	uint8_t ciram[0x800];
	uint8_t palette[0x20];

	uint32_t scanline;
	uint32_t dot;
	uint8_t even_frame;
	uint8_t frame_ready;

	uint8_t sprite_indexes[8];
	uint8_t sprite_zero_hit_possible;
	uint8_t sprite_count;
	uint32_t sprite_patterns[8];
	uint8_t sprite_positions[8];
	uint8_t sprite_priorities[8];
	uint8_t sprite_shift_lo[8];
	uint8_t sprite_shift_hi[8];

	uint32_t bg_shift_pattern_low;
	uint32_t bg_shift_pattern_high;
	uint32_t bg_shift_attrib_low;
	uint32_t bg_shift_attrib_high;

	uint8_t bg_next_tile_id;
	uint8_t bg_next_tile_attrib;
	uint8_t bg_next_tile_lsb;
	uint8_t bg_next_tile_msb;
};


struct cpu_state {
	uint32_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)
	uint8_t d;		// Decimal Flag
	uint8_t i;		// Interrupt Disable Flag
	uint8_t z;		// Zero Flag
	uint8_t c;		// Carry Flag
// --
	uint8_t die;	// KIL instruction found!
};


struct ines_state {
	uint32_t mapper;
	uint8_t mirroring;	// 0 = H, 1 = V, 2 = 4-screen
	uint32_t prg_size;
	uint32_t chr_size;
};

struct mapper {
	void (*init)(struct nes_state *state);
	uint8_t (*read)(struct nes_state *state, uint32_t addr);
	void (*write)(struct nes_state *state, uint32_t addr, uint8_t value);
	void (*tick)(struct nes_state *state);
};

union mapper_data {
	// struct nrom_mapper nrom;
	// struct mmc1_mapper mmc1;
	// ... others
};

struct nes_state {
	struct ines_state ines;
	struct cpu_state cpu;
	struct ppu_state ppu;
	struct mapper mapper;
	union mapper_data map;
	size_t cycle;
	uint8_t ram[2048];
	uint8_t rom[4 * 1024 * 1024];
	uint8_t chrrom[4 * 1024 * 1024];
	uint8_t irq_pending;
	uint8_t nmi_pending;
};

static uint32_t nes_palette[64] = {
	0x757575ff, 0x271a75ff, 0x3b0072ff, 0x4c0f64ff, 0x400048ff, 0x600027ff, 0x600000ff, 0x500f00ff,
	0x783a00ff, 0x755c00ff, 0x406c00ff, 0x504764ff, 0x005468ff, 0x000000ff, 0x000000ff, 0x000000ff,
	0xbfbfbfff, 0x273aa7ff, 0x5c14a7ff, 0x7514a7ff, 0x751468ff, 0x982727ff, 0xa03a00ff, 0x986c00ff,
	0x888800ff, 0x689800ff, 0x3aa700ff, 0x6c6c6cff, 0x007878ff, 0x000000ff, 0x000000ff, 0x000000ff,
	0xffffffff, 0x3ab5ffff, 0x5cb5ffff, 0x9888ffff, 0xa778ffff, 0xc87878ff, 0xf05c00ff, 0xf08800ff,
	0xe0a700ff, 0xb8b800ff, 0x88c800ff, 0xcccc68ff, 0x00e0d8ff, 0x000000ff, 0x000000ff, 0x000000ff,
	0xffffffff, 0xa7e0ffff, 0xb8d8ffff, 0xc8c8ffff, 0xd8b8ffff, 0xd8a7a7ff, 0xf0d0b8ff, 0xf0d898ff,
	0xf0c878ff, 0xd8d878ff, 0xb8e078ff, 0xd0e0b8ff, 0xb8f0f0ff, 0x000000ff, 0x000000ff, 0x000000ff
};