From 16fcf3388132578769cadb90222d8b1a4c72f0ba Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Mon, 20 Nov 2023 15:29:51 -0600 Subject: [PATCH] c64: presets --- presets/c64/musicplayer.c | 92 ++++++++++++++++++++++----------------- presets/c64/siddemo.c | 11 ++++- presets/c64/test_setirq.c | 60 +++++++++++++++++++++++++ src/platform/c64.ts | 3 +- 4 files changed, 122 insertions(+), 44 deletions(-) create mode 100644 presets/c64/test_setirq.c diff --git a/presets/c64/musicplayer.c b/presets/c64/musicplayer.c index 46f5d064..a713269b 100644 --- a/presets/c64/musicplayer.c +++ b/presets/c64/musicplayer.c @@ -9,6 +9,7 @@ A simple music player. #include "sidmacros.h" #include +#include <6502.h> // SID frequency table (PAL version) const int note_table_pal[96] = { @@ -149,7 +150,7 @@ void drawParams() { } } -void setParamValues() { +void setSIDRegisters() { char i; word val; char buf[30]; @@ -179,57 +180,61 @@ void setParamValues() { music_wavebits = buf[0x04]; } -void tick(int i) { - while (i--) { - wait_vblank(); - play_music(); - } +char music_update() { + if (!music_ptr) start_music(music1); + play_music(); + return IRQ_NOT_HANDLED; } void handleInput() { char key = 0; char joy = joy_read(0); + if (joy == 0) return; if (JOY_UP(joy)) key = 'i'; if (JOY_DOWN(joy)) key = 'k'; if (JOY_LEFT(joy)) key = 'j'; if (JOY_RIGHT(joy)) key = 'l'; - switch (key) { - case 'i': // UP - if (currentParam > 0) { - --currentParam; - drawValue(currentParam+1); - drawValue(currentParam); - tick(3); - } - break; - case 'k': // DOWN - if (currentParam < NPARAMS - 1) { - ++currentParam; - drawValue(currentParam-1); - drawValue(currentParam); - tick(3); - } - break; - case 'j': // LEFT - if (paramValues[currentParam] > SID_PARAMS[currentParam].low) { - paramValues[currentParam]--; - drawValue(currentParam); - setParamValues(); - } - break; - case 'l': // RIGHT - if (paramValues[currentParam] < SID_PARAMS[currentParam].high) { - paramValues[currentParam]++; - drawValue(currentParam); - setParamValues(); - } - break; - } + switch (key) { + case 'i': // UP + if (currentParam > 0) { + --currentParam; + drawValue(currentParam+1); + drawValue(currentParam); + } + break; + case 'k': // DOWN + if (currentParam < NPARAMS - 1) { + ++currentParam; + drawValue(currentParam-1); + drawValue(currentParam); + } + break; + case 'j': // LEFT + if (paramValues[currentParam] > SID_PARAMS[currentParam].low) { + paramValues[currentParam]--; + drawValue(currentParam); + setSIDRegisters(); + } + break; + case 'l': // RIGHT + if (paramValues[currentParam] < SID_PARAMS[currentParam].high) { + paramValues[currentParam]++; + drawValue(currentParam); + setSIDRegisters(); + } + break; + } + // delay a few frames to slow down movement + waitvsync(); + waitvsync(); + waitvsync(); } void main(void) { joy_install (joy_static_stddrv); + + // set initial SID parameters paramValues[0] = 15; paramValues[1] = 8; paramValues[2] = 8; @@ -237,14 +242,19 @@ void main(void) paramValues[4] = 4; paramValues[5] = 4; paramValues[7] = 1; // pulse + setSIDRegisters(); + + // draw the UI drawParams(); - setParamValues(); + // set IRQ routine called every frame + set_irq(music_update, (void*)0x9f00, 0x100); + + // main loop to handle UI music_ptr = 0; while (1) { + waitvsync(); handleInput(); - if (!music_ptr) start_music(music1); - tick(1); } } diff --git a/presets/c64/siddemo.c b/presets/c64/siddemo.c index a09af023..7f79c015 100644 --- a/presets/c64/siddemo.c +++ b/presets/c64/siddemo.c @@ -3,6 +3,7 @@ //#link "common.c" #include +#include <6502.h> //#resource "c64-sid.cfg" #define CFGFILE c64-sid.cfg @@ -57,6 +58,11 @@ void show_envelope() { if (++sweep == 320) sweep = 0; } +char music_update() { + sid_update(); + return IRQ_NOT_HANDLED; +} + void main(void) { // install TGI graphics driver tgi_install(tgi_static_stddrv); @@ -71,6 +77,9 @@ void main(void) { // install joystick driver joy_install(joy_static_stddrv); + // set IRQ routine called every frame + set_irq(music_update, (void*)0x9f00, 0x100); + while (1) { // play sound effect when joystick is moved byte joy = joy_read(0); @@ -81,8 +90,6 @@ void main(void) { } // sync with frame rate waitvsync(); - // update SID player - sid_update(); // update graphs show_envelope(); show_signal(); diff --git a/presets/c64/test_setirq.c b/presets/c64/test_setirq.c new file mode 100644 index 00000000..34064b4a --- /dev/null +++ b/presets/c64/test_setirq.c @@ -0,0 +1,60 @@ + +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +//#link "common.c" + +#include <6502.h> +#include + +char interrupt_handler() { + // only needed if CIA interupts are still active + if (!(VIC.irr & VIC_IRR_IRST)) return IRQ_NOT_HANDLED; + // change colors so we can see where the IRQ fired + VIC.bgcolor0++; + VIC.bordercolor++; + // reading VIC.rasterline returns the current line + // setting it changes the line where the IRQ fires + if (VIC.rasterline >= 245) { + VIC.rasterline = 40; + } else { + VIC.rasterline = 245; + } + // acknowledge VIC raster interrupt (bit 0) + VIC.irr = 1; + // change colors back to where they were + VIC.bgcolor0--; + VIC.bordercolor--; + return IRQ_HANDLED; +} + +void set_frame_irq(char scanline) { + // deactivate CIA interrupts (keyboard, etc) + CIA1.icr = 0x7f; + // set raster line for interrupt + VIC.ctrl1 &= 0x7f; // clear raster line bit 8 + VIC.rasterline = scanline; + // activate VIC raster interrupts + VIC.imr = 1; +} + +void main(void) { + clrscr(); + printf("\nHello World!\n"); + + // set interrupt routine + set_irq(interrupt_handler, (void*)0x9f00, 0x100); + + // disable CIA interrupt, activate VIC interrupt + set_frame_irq(255); + + while (1) { + printf("%d ", VIC.rasterline); + } +} diff --git a/src/platform/c64.ts b/src/platform/c64.ts index 070c156b..e73e4a99 100644 --- a/src/platform/c64.ts +++ b/src/platform/c64.ts @@ -10,7 +10,8 @@ const C64_PRESETS : Preset[] = [ {id:'joymove.c', name:'Sprite Movement'}, {id:'sprite_collision.c', name:'Sprite Collision'}, {id:'scroll1.c', name:'Scrolling (Single Buffer)'}, - {id:'test_display_list.c', name:'Display List / Raster IRQ'}, + {id:'test_setirq.c', name:'Raster Interrupts'}, + {id:'test_display_list.c', name:'Raster IRQ Library'}, {id:'scrolling_text.c', name:'Big Scrolling Text'}, {id:'side_scroller.c', name:'Side-Scrolling Game'}, {id:'scroll2.c', name:'Scrolling (Double Buffer)'},