From e8ff6bf2ab9982c5e5ab8d8f4e7adcc5207d079d Mon Sep 17 00:00:00 2001 From: Peter Fors Date: Sat, 29 Mar 2025 19:57:00 +0100 Subject: first mknes commit --- mknes.h | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 mknes.h (limited to 'mknes.h') diff --git a/mknes.h b/mknes.h new file mode 100644 index 0000000..1f82ae1 --- /dev/null +++ b/mknes.h @@ -0,0 +1,146 @@ + + + +// PPUSTATUS ($2002) flags +#define PPU_STATUS_VBLANK 0x80 +#define PPU_STATUS_SPRITE0_HIT 0x40 +#define PPU_STATUS_OVERFLOW 0x20 + +// PPUMASK ($2001) flags +#define PPU_MASK_SHOW_BG 0x08 +#define PPU_MASK_SHOW_SPRITES 0x10 + +// PPUCTRL ($2000) flags +#define PPU_CTRL_NMI_ENABLE 0x80 +#define PPU_CTRL_MASTER_SLAVE 0x40 +#define PPU_CTRL_SPRITE_HEIGHT 0x20 +#define PPU_CTRL_BG_TABLE 0x10 +#define PPU_CTRL_SPRITE_TABLE 0x08 +#define PPU_CTRL_INCREMENT 0x04 +#define PPU_CTRL_NT_SELECT_Y 0x02 +#define PPU_CTRL_NT_SELECT_X 0x01 + + +struct nes_state; + +struct ppu_state { + uint8_t pixels[240*256]; + uint8_t sprite_pixels[256]; // Sprite pixel color indexes (BG priority resolved) + uint8_t sprite_zero_flags[256]; // 1 if pixel came from sprite #0 and is nonzero + // Sprite memory + uint8_t oam[256]; + uint8_t sec_oam[32]; + + uint8_t oam_addr; + uint8_t read_buffer; + + uint32_t scanline; // 0–261 + uint32_t dot; // 0–340 + + // Scroll state + uint32_t coarse_x_offs; + uint32_t coarse_y_offs; + uint32_t fine_x; + uint32_t fine_y; + uint32_t nt_base_x; + uint32_t nt_base_y; + + // Latch state for $2005/$2006 + uint8_t write_toggle; + uint32_t temp_coarse_x_offs; + uint32_t temp_coarse_y_offs; + uint32_t temp_fine_x; + uint32_t temp_fine_y; + uint32_t temp_nt_base_x; + uint32_t temp_nt_base_y; + + // Background shift registers + uint32_t bg_tile_lsb; + uint32_t bg_tile_msb; + uint32_t bg_attr_lsb; + uint32_t bg_attr_msb; + + // Tile fetch latches + uint8_t nt_byte; + uint8_t attr_byte; + uint8_t tile_lsb; + uint8_t tile_msb; + + // Control and status + uint8_t ctrl; // $2000 + uint8_t mask; // $2001 + uint8_t status; // $2002 + + // Flags + uint8_t frame_even; + uint8_t nmi_occurred; + uint8_t nmi_output; + +}; + + +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 { + uint16_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, uint16_t addr); + void (*write)(struct nes_state *state, uint16_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 ciram[2048]; + uint8_t palette[0x20]; + uint8_t irq_pending; + uint8_t nmi_pending; +}; + +static const uint32_t nes_palette_argb[64] = { + 0xff757575, 0xff8f1b27, 0xffab0000, 0xff9f0047, 0xff77008f, 0xff1300ab, 0xff0000a7, 0xff000b7f, + 0xff002f43, 0xff004700, 0xff005100, 0xff173f00, 0xff5f3f1b, 0xff000000, 0xff000000, 0xff000000, + 0xffbcbcbc, 0xffef7300, 0xffef3b23, 0xfff30083, 0xffbf00bf, 0xff5b00e7, 0xff002bdb, 0xff0f4fcb, + 0xff00738b, 0xff009700, 0xff00ab00, 0xff3b9300, 0xff8b8300, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xffffbf3f, 0xffff975f, 0xfffd8ba7, 0xffff7bff, 0xffb777ff, 0xff6377ff, 0xff3b9bff, + 0xff3fbff3, 0xff13d383, 0xff4bdf4f, 0xff98f858, 0xffdbeb00, 0xff000000, 0xff000000, 0xff000000, + 0xffffffff, 0xffffe7ab, 0xffffd7c7, 0xffffcbd7, 0xffffc7ff, 0xffdbc7ff, 0xffb3bfff, 0xffabdbff, + 0xffa3e7ff, 0xff83f7c7, 0xffb3ffbf, 0xffcfffb3, 0xfff3ff9f, 0xff000000, 0xff000000, 0xff000000 +}; -- cgit v1.2.3