diff options
| author | spicyjpeg <thatspicyjpeg@gmail.com> | 2023-07-03 08:13:23 +0200 |
|---|---|---|
| committer | spicyjpeg <thatspicyjpeg@gmail.com> | 2023-07-03 08:13:23 +0200 |
| commit | 06e65bea3a778b2dae5af77a7935ae3868ddd4d3 (patch) | |
| tree | 3af954ebead7540c9478d0a026ca2e59f3cf7b64 /examples/system/timer | |
| parent | 472cf1c254ea5be5aff8a6c7067cbed2d467d85b (diff) | |
| download | psn00bsdk-06e65bea3a778b2dae5af77a7935ae3868ddd4d3.tar.gz | |
Fix setjmp.h, FntSort(), examples, rewrite system/timer
Diffstat (limited to 'examples/system/timer')
| -rw-r--r-- | examples/system/timer/main.c | 255 |
1 files changed, 124 insertions, 131 deletions
diff --git a/examples/system/timer/main.c b/examples/system/timer/main.c index eb62712..c424e84 100644 --- a/examples/system/timer/main.c +++ b/examples/system/timer/main.c @@ -1,156 +1,149 @@ -#include <sys/types.h> -#include <stdio.h> +/* + * PSn00bSDK hardware timer example + * (C) 2023 spicyjpeg - MPL licensed + */ + +#include <stdint.h> #include <psxgpu.h> -#include <psxapi.h> #include <psxetc.h> +#include <psxapi.h> #include <hwregs_c.h> -/* OT and Packet Buffer sizes */ -#define OT_LEN 256 -#define PACKET_LEN 1024 +/* Display/GPU context utilities */ -/* Screen resolution */ -#define SCREEN_XRES 320 -#define SCREEN_YRES 240 +#define SCREEN_XRES 320 +#define SCREEN_YRES 240 -/* Screen center position */ -#define CENTERX SCREEN_XRES>>1 -#define CENTERY SCREEN_YRES>>1 +#define BGCOLOR_R 48 +#define BGCOLOR_G 24 +#define BGCOLOR_B 0 +typedef struct { + DISPENV disp; + DRAWENV draw; +} Framebuffer; -/* Double buffer structure */ typedef struct { - DISPENV disp; /* Display environment */ - DRAWENV draw; /* Drawing environment */ -} DB; + Framebuffer db[2]; + int db_active; +} RenderContext; + +void init_context(RenderContext *ctx) { + Framebuffer *db; + + ResetGraph(0); + ctx->db_active = 0; + + db = &(ctx->db[0]); + SetDefDispEnv(&(db->disp), 0, 0, SCREEN_XRES, SCREEN_YRES); + SetDefDrawEnv(&(db->draw), SCREEN_XRES, 0, SCREEN_XRES, SCREEN_YRES); + setRGB0(&(db->draw), BGCOLOR_R, BGCOLOR_G, BGCOLOR_B); + db->draw.isbg = 1; + db->draw.dtd = 1; + + db = &(ctx->db[1]); + SetDefDispEnv(&(db->disp), SCREEN_XRES, 0, SCREEN_XRES, SCREEN_YRES); + SetDefDrawEnv(&(db->draw), 0, 0, SCREEN_XRES, SCREEN_YRES); + setRGB0(&(db->draw), BGCOLOR_R, BGCOLOR_G, BGCOLOR_B); + db->draw.isbg = 1; + db->draw.dtd = 1; + + PutDrawEnv(&(db->draw)); + //PutDispEnv(&(db->disp)); + + // Create a text stream at the top of the screen. + FntLoad(960, 0); + FntOpen(8, 16, 304, 208, 2, 512); +} + +void display(RenderContext *ctx) { + Framebuffer *db; + + DrawSync(0); + VSync(0); + ctx->db_active ^= 1; -/* Double buffer variables */ -DB db[2]; -int db_active = 0; + db = &(ctx->db[ctx->db_active]); + PutDrawEnv(&(db->draw)); + PutDispEnv(&(db->disp)); + SetDispMask(1); +} + +/* Interrupt handlers */ +typedef struct { + int irq_count, last_irq_count, irqs_per_sec; +} TimerState; -/* Function declarations */ -void init(); -void display(); +static volatile TimerState timer_state[3]; +static void timer0_handler(void) { + timer_state[0].irq_count++; +} -volatile int timer_calls = 0; +static void timer1_handler(void) { + timer_state[1].irq_count++; +} -void timer_func() -{ - timer_calls++; +static void timer2_handler(void) { + timer_state[2].irq_count++; } -volatile int vsync_count = 0; -volatile int tick_count = 0; -volatile int tick_value = 0; - -void vsync_func() -{ - vsync_count++; - if( vsync_count > 60 ) - { - tick_value = timer_calls-tick_count; - tick_count = timer_calls; - vsync_count = 0; +static void vblank_handler(void) { + int refresh_rate = (GetVideoMode() == MODE_PAL) ? 50 : 60; + + // Only update once per second (every 50 or 60 vblanks). + if (VSync(-1) % refresh_rate) + return; + + for (int i = 0; i < 3; i++) { + TimerState *state = &timer_state[i]; + + int count = state->irq_count; + state->irqs_per_sec = count - state->last_irq_count; + state->last_irq_count = count; } } -/* Main function */ -int main() { - - int counter; - - /* Init graphics and GTE */ - init(); - - +/* Main */ + +static RenderContext ctx; + +int main(int argc, const char* argv[]) { + init_context(&ctx); + + // Set up the timers and register callbacks for their interrupts. + TIMER_CTRL(0) = 0x0160; // Dotclock input, repeated IRQ on overflow + TIMER_CTRL(1) = 0x0160; // Hblank input, repeated IRQ on overflow + TIMER_CTRL(2) = 0x0260; // CLK/8 input, repeated IRQ on overflow + + __builtin_memset(timer_state, 0, sizeof(timer_state)); + EnterCriticalSection(); - //SetRCnt(RCntCNT2, 0xF040, RCntMdINTR); - - // NTSC clock base - counter = 4304000/560; - - // PAL clock base - //counter = 5163000/560; - - SetRCnt(RCntCNT2, counter, RCntMdINTR); - TIMER_CTRL(2) = 0x1E58; - InterruptCallback(6, timer_func); - StartRCnt(RCntCNT2); - ChangeClearRCnt(2, 0); + InterruptCallback(IRQ_TIMER0, &timer0_handler); + InterruptCallback(IRQ_TIMER1, &timer1_handler); + InterruptCallback(IRQ_TIMER2, &timer2_handler); + VSyncCallback(&vblank_handler); ExitCriticalSection(); - - VSyncCallback(vsync_func); - - /* Main loop */ - while( 1 ) { - - FntPrint(-1, "TIMER COUNT=%d\n", timer_calls); - FntPrint(-1, "TICKS/SEC=%d\n", tick_value); - - /* Swap buffers and draw text */ - display(); - + + while (1) { + FntPrint(-1, "HARDWARE TIMER EXAMPLE\n\n"); + + for (int i = 0; i < 3; i++) { + TimerState *state = &timer_state[i]; + + FntPrint(-1, "TIMER %d:\n", i); + FntPrint(-1, " VALUE: %d\n", TIMER_VALUE(i)); + FntPrint(-1, " IRQS: %d\n", state->irq_count); + FntPrint(-1, " IRQS/S: %d\n\n", state->irqs_per_sec); + } + + FntPrint(-1, "VBLANK COUNTER:\n"); + FntPrint(-1, " VALUE: %d\n\n", VSync(-1)); + + FntFlush(-1); + display(&ctx); } - - return 0; - -} -void init() { - - /* Reset the GPU, also installs a VSync event handler */ - ResetGraph( 0 ); - //SetVideoMode(MODE_PAL); - - /* Set display and draw environment areas */ - /* (display and draw areas must be separate, otherwise hello flicker) */ - SetDefDispEnv( &db[0].disp, 0, 0, SCREEN_XRES, SCREEN_YRES ); - SetDefDrawEnv( &db[0].draw, SCREEN_XRES, 0, SCREEN_XRES, SCREEN_YRES ); - - /* Enable draw area clear and dither processing */ - setRGB0( &db[0].draw, 63, 0, 127 ); - db[0].draw.isbg = 1; - db[0].draw.dtd = 1; - - - /* Define the second set of display/draw environments */ - SetDefDispEnv( &db[1].disp, SCREEN_XRES, 0, SCREEN_XRES, SCREEN_YRES ); - SetDefDrawEnv( &db[1].draw, 0, 0, SCREEN_XRES, SCREEN_YRES ); - - //db[0].disp.screen.y = 24; - //db[1].disp.screen.y = 24; - - setRGB0( &db[1].draw, 63, 0, 127 ); - db[1].draw.isbg = 1; - db[1].draw.dtd = 1; - - - /* Apply the drawing environment of the first double buffer */ - PutDrawEnv( &db[0].draw ); - - FntLoad(960, 0); - FntOpen(0, 8, 320, 216, 0, 100); - + return 0; } - -void display() { - - FntFlush(-1); - - /* Wait for GPU to finish drawing and vertical retrace */ - DrawSync( 0 ); - VSync( 0 ); - - /* Swap buffers */ - db_active ^= 1; - - /* Apply display/drawing environments */ - PutDrawEnv( &db[db_active].draw ); - PutDispEnv( &db[db_active].disp ); - - /* Enable display */ - SetDispMask( 1 ); - -}
\ No newline at end of file |
