gbemu/lib/ppu_sm.c

90 lines
2.0 KiB
C
Raw Normal View History

2025-02-01 00:48:49 -07:00
#include <ppu.h>
#include <lcd.h>
#include <cpu.h>
#include <interrupts.h>
void increment_ly() {
lcd_get_context()->ly++;
if(lcd_get_context()->ly == lcd_get_context()->ly_compare) {
LCDS_LYC_SET(1);
if(LCDS_STAT_INT(SS_LYC)) {
cpu_request_interrupt(IT_LCD_STAT);
}
} else {
LCDS_LYC_SET(0);
}
}
void ppu_mode_oam() {
if(ppu_get_context()->line_ticks >= 80) {
LCDS_MODE_SET(MODE_XFER);
}
}
void ppu_mode_xfer() {
if(ppu_get_context()->line_ticks >= 80 + 172) {
LCDS_MODE_SET(MODE_HBLANK);
}
}
void ppu_mode_vblank() {
if(ppu_get_context()->line_ticks >= TICKS_PER_LINE) {
increment_ly();
if(lcd_get_context()->ly >= LINES_PER_FRAME) {
LCDS_MODE_SET(MODE_OAM);
lcd_get_context()->ly = 0;
}
ppu_get_context()->line_ticks = 0;
}
}
static u32 target_frame_time = 1000/60;
static long prev_frame_time = 0;
static long start_timer = 0;
static long frame_count = 0;
void ppu_mode_hblank() {
if (ppu_get_context()->line_ticks >= TICKS_PER_LINE) {
increment_ly();
if(lcd_get_context()->ly >= YRES) {
LCDS_MODE_SET(MODE_VBLANK);
cpu_request_interrupt(IT_VBLANK);
if(LCDS_STAT_INT(SS_VBLANK)) {
cpu_request_interrupt(IT_LCD_STAT);
}
ppu_get_context()->current_frame++;
//calc FPS...
u32 end = get_ticks();
u32 frame_time = end - prev_frame_time;
if(frame_time < target_frame_time) {
delay((target_frame_time - frame_time));
}
if (end - start_timer >= 1000) {
u32 fps = frame_count;
start_timer = end;
frame_count = 0;
printf("FPS: %ld\n", fps);
}
frame_count++;
prev_frame_time = get_ticks();
} else {
LCDS_MODE_SET(MODE_OAM);
}
ppu_get_context()->line_ticks = 0;
}
}