diff --git a/Makefile b/Makefile index 7acfb93..b7be8d7 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ NESE_SRC_SRCS = f6502.c f6502_opcodes.c NESE_SRC_SRCS += nese.c nes.c cart.c mapper.c NESE_SRC_SRCS += ppu.c NESE_SRC_SRCS += $(OS)/port.c -NESE_MAP_SRCS = $(notdir $(wildcard $(MAPDIR)/*)) +NESE_MAP_SRCS = $(notdir $(wildcard $(MAPDIR)/*.c)) NESE_DEBUG = CART diff --git a/src/input.h b/src/input.h new file mode 100644 index 0000000..3d223a7 --- /dev/null +++ b/src/input.h @@ -0,0 +1,29 @@ +#ifndef NESE_INPUT_H_ +#define NESE_INPUT_H_ + + +#define nes_controller_bus_mask (0b11111000) + + +typedef enum { + Button_A = 0, + Button_B, + Button_Select, + Button_Start, + Button_Up, + Button_Down, + Button_Left, + Button_Right, +} nes_Input_Button; + +typedef struct { + uint8_t buttons; + int8_t shift; +} nes_Gamepad; + +typedef struct { + nes_Gamepad gamepads[2]; +} nes_Input; + + +#endif // NESE_INPUT_H_ diff --git a/src/linux/port.c b/src/linux/port.c index 368b8d9..79c0da1 100644 --- a/src/linux/port.c +++ b/src/linux/port.c @@ -1,6 +1,7 @@ #include #include +#include #include #include "nese.h" @@ -24,6 +25,37 @@ int nese_unmap_file(void* addr, int size) { return munmap(addr, size); } +int nese_frame_ready() { +/* + static int frame = 0; + static int ignore = 1; + static struct timespec t_last = {0}; + struct timespec t_now = {0}; + + ++frame; + clock_gettime(CLOCK_MONOTONIC, &t_now); + + if (t_now.tv_sec > t_last.tv_sec) { + if (!ignore) printf("%d\n", frame); + frame = 0; + ignore = 0; + } + + t_last = t_now; +*/ + + // TODO: Render frame + // TODO: Time sync + // TODO: Handle quit signal + // TODO: Perform menu actions + return 0; +} + +int nese_update_input(nes_Input* input) { + // TODO: Populate the gamepad states + return 0; +} + static nes sys = {0}; diff --git a/src/nes.c b/src/nes.c index 758108f..b88daa4 100644 --- a/src/nes.c +++ b/src/nes.c @@ -1,6 +1,7 @@ #include #include "nes.h" +#include "port.h" void nes_init(nes* sys) { @@ -11,19 +12,54 @@ void nes_done(nes* sys) { // TODO: deallocate RAM, etc. } +static int nes_vsync(nes* sys) { + int status = 0; + + // TODO: PPU Set VBlank flag + // TODO: APU Sync + // TODO: APU Frame IRQ + + nes_Memory* mem = &sys->core.memory; + if (0 == status && NULL != mem->mapper.vsync) { + mem->mapper.vsync(&mem->mapper); + status = nese_update_input(&sys->input); + } + + // TODO: NMI + + return status; +} + static int nes_hsync(nes* sys) { + int status = 0; + // TODO: APU sync + // TODO: PPU Update H Bytes & Select Nametable // TODO: PPU draw line if visible - // TODO: PPU update regs - // TODO: Increment scanline + sys->ppu.scanline++; + if (nes_ppu_frame_end_line == sys->ppu.scanline) { + sys->ppu.scanline = 0; + } - // TODO: Scanline region updates - // TODO: nese_vsync called in nes_vsync + switch (sys->ppu.scanline) { + case nes_ppu_prerender_line: + // TODO: Reset PPU Status + // TODO: Get Sprite 0 Hit + break; - return 0; + case nes_ppu_postrender_line: + status = nese_frame_ready(); + break; + + case nes_ppu_vblank_line: + status = nes_vsync(sys); + break; + } + + return status; } int nes_loop(nes* sys) { @@ -37,9 +73,6 @@ int nes_loop(nes* sys) { dot += 3 * f6502_step(&sys->core, cpu_cycles); dot -= nes_ppu_scanline_dots; // TODO: Validate dot >= 0? - - // TODO: Frame IRQ - nes_Memory* mem = &sys->core.memory; if (NULL != mem->mapper.hsync) { mem->mapper.hsync(&mem->mapper); diff --git a/src/nes.h b/src/nes.h index d06d130..2c3b333 100644 --- a/src/nes.h +++ b/src/nes.h @@ -2,15 +2,18 @@ #define NES_H_ #include "ines.h" +#include "input.h" #include "f6502.h" +#include "ppu.h" typedef struct { const ines_Header* cart_header; f6502_Core core; + nes_PPU ppu; // TODO: PPU // TODO: APU - // TODO: Input + nes_Input input; } nes; void nes_init(nes*); diff --git a/src/port.h b/src/port.h index 9e611bd..aa0f2e5 100644 --- a/src/port.h +++ b/src/port.h @@ -1,9 +1,16 @@ #ifndef NESE_PORT_H_ #define NESE_PORT_H_ +#include + +#include "input.h" + void* nese_map_file(FILE* file, int size); int nese_unmap_file(void* addr, int size); +int nese_frame_ready(); +int nese_update_input(nes_Input*); + #endif // NESE_PORT_H_ diff --git a/src/ppu.h b/src/ppu.h index 8df7505..1d1b2d4 100644 --- a/src/ppu.h +++ b/src/ppu.h @@ -5,6 +5,7 @@ #define nes_ppu_scanline_dots (341U) +#define nes_ppu_prerender_line (0U) #define nes_ppu_visible_line (1U) #define nes_ppu_postrender_line (241U) #define nes_ppu_vblank_line (242U) @@ -53,4 +54,9 @@ void nes_PPU_set_mirroring(nes_PPU_Memory* mem, nes_Nametable_Mirroring mirror); +typedef struct { + int scanline; +} nes_PPU; + + #endif // NESE_PPU_H_