1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-02 00:41:42 +00:00
kickc/src/test/kc/examples/mega65/raster65.c
2024-01-02 19:21:16 +01:00

321 lines
13 KiB
C

// Raster65 Demo re-implementation in C by Jesper Gravgaard
// Based on RASTER65 assembler demo made in 2015 and updated in 2020 by DEFT
// https://mega.scryptos.com/sharefolder/MEGA/MEGA65+filehost
// https://www.forum64.de/index.php?thread/104591-xemu-vic-iv-implementation-update/&postID=1560511#post1560511
#pragma target(mega65_c64)
#include <mega65.h>
#include <string.h>
// The screen address
char * const SCREEN = DEFAULT_SCREEN;
// Logo start screen row
char const LOGO_ROW = 3;
// Scroll screen row
char const SCROLL_ROW = 13;
// Greeting screen row
char const GREET_ROW = 20;
// y rasterline where IRQ starts
const char IRQ_Y = 0x16;
// y rasterline where scrolly starts
const char SCROLL_Y = 0x66;
// size of raster behind scrolly
const char SCROLL_BLACKBARS = 19;
// The number of raster lines
const char RASTER_LINES = 0xd8;
// Music at an absolute address
__address(0x0fc0) char SONG[] = kickasm(resource "DiscoZak_2SID_patched.prg") {{
.import c64 "DiscoZak_2SID_patched.prg"
}};
// Sine Values 0-183
__address(0x2c00) char SINE[256] = kickasm {{
.fill 256, 91.5 + 91.5*sin(i*2*PI/256)
}};
// Moving Raster Bars
__address(0x3000) char rasters[RASTER_LINES];
typedef void (*PROC_PTR)();
// Pointer to the song init routine
PROC_PTR songInit = (PROC_PTR) SONG;
// Pointer to the song play routine
PROC_PTR songPlay = (PROC_PTR) SONG+3;
void main() {
// Enable MEGA65 features
VICIII->KEY = 0x47;
VICIII->KEY = 0x53;
// Enable 48MHz fast mode
VICIV->CONTROLB |= 0x40;
VICIV->CONTROLC |= 0x40;
// Initialize music
asm { lda #0 }
(*songInit)();
// Clear screen
memset(SCREEN, ' ', 40*25);
// Put MEGA logo on screen
for( char i=0; i<sizeof(MEGA_LOGO); i++) {
(SCREEN + LOGO_ROW*40)[i] = MEGA_LOGO[i];
}
// Put '*' as default greeting
for( char i=0;i<40;i++)
(SCREEN + GREET_ROW*40)[i] = '*';
// Set up 256 color palette
char i=0;
do {
PALETTE_RED[i] = PAL_RED[i];
PALETTE_GREEN[i] = PAL_GREEN[i];
PALETTE_BLUE[i] = PAL_BLUE[i];
} while(++i!=0);
// Set up raster interrupts C64 style
asm { sei }
// Disable CIA 1 Timer IRQ
CIA1->INTERRUPT = CIA_INTERRUPT_CLEAR_ALL;
// Set raster line to 0x16
VICII->RASTER = IRQ_Y;
VICII->CONTROL1 &= 0x7f;
// Enable Raster Interrupt
VICII->IRQ_ENABLE = IRQ_RASTER;
// Set the IRQ routine
*HARDWARE_IRQ = &irq;
// no kernal or BASIC rom visible
*PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK;
*PROCPORT = PROCPORT_RAM_IO;
// open sideborder
VICIV->SIDBDRWD_LO = 1;
// Enable IRQ
asm { cli }
// Loop forever
for(;;) ;
}
// Sine Position (used across effects)
volatile char sin_idx;
// scroll soft position of text scrolly (0-7)
volatile char scroll_soft = 7;
// scroll text pointer to next char
char * volatile scroll_ptr = SCROLL_TEXT;
// Zoom Position
volatile char greet_zoomx;
// The greeting currently being shown
volatile char greet_idx;
// BIG INTERRUPT LOOP
__interrupt(hardware_clobber) void irq() {
// force NTSC every frame (hehe)
VICIV->RASLINE0 |= 0x80;
// Acknowledge the IRQ
VICII->IRQ_STATUS = IRQ_RASTER;
// reset x scroll
VICII->CONTROL2 = 0;
// Generate Raster Bars and more
char wobble_idx = ++sin_idx;
for(char line=0;line!=RASTER_LINES;line++) {
char col = rasters[line];
VICIII->BORDER_COLOR = col;
VICIII->BG_COLOR = col;
if(line < SCROLL_Y) {
// if raster position < SCROLL_Y pos do wobble Logo!
VICIV->TEXTXPOS_LO = SINE[wobble_idx++];
// No zooming
VICIV->CHRXSCL = 0x66;
} else if(line == SCROLL_Y) {
// if raster position = SCROLL_Y pos do scroll
// no wobbling from this point
VICIV->TEXTXPOS_LO = 0x50;
// set softscroll
VICII->CONTROL2 = scroll_soft;
} else if(line == SCROLL_Y+SCROLL_BLACKBARS) {
// if raster position > SCROLL_Y pos do nozoom
// default value
VICIV->TEXTXPOS_LO = 0x50;
} else if(line == SCROLL_Y+SCROLL_BLACKBARS+1) {
// if raster position > SCROLL_Y pos do zoom
char zoomval = SINE[greet_zoomx++];
VICIV->CHRXSCL = zoomval;
VICIV->TEXTXPOS_LO = zoomval+1;
if(greet_zoomx==0) {
// Advance greetings
if(++greet_idx == GREET_COUNT)
greet_idx = 0;
}
}
// Wait for the next raster line
char raster = VICII->RASTER;
while(raster == VICII->RASTER) ;
}
// play music
(*songPlay)();
// Set up colors behind logo, scroll and greets
char sin_col = sin_idx;
for(char i=0;i<40;i++) {
// Greeting colors
char col = SINE[sin_col]/4;
(COLORRAM + GREET_ROW*40)[i] = col;
// Logo colors
col /= 2;
(COLORRAM + LOGO_ROW*40 + 0*40 - 1)[i] = col;
(COLORRAM + LOGO_ROW*40 + 1*40 - 2)[i] = col;
(COLORRAM + LOGO_ROW*40 + 2*40 - 3)[i] = col;
(COLORRAM + LOGO_ROW*40 + 3*40 - 4)[i] = col;
(COLORRAM + LOGO_ROW*40 + 4*40 - 5)[i] = col;
(COLORRAM + LOGO_ROW*40 + 5*40 - 6)[i] = col;
// Scroll colors
(COLORRAM + SCROLL_ROW*40)[i] = PAL_GREEN[sin_col];
sin_col++;
}
// Set all raster bars to black
for(char l=0;l!=RASTER_LINES;l++)
rasters[l] = 0;
// Big block of bars (16)
char sin_bar = sin_idx;
for(char barcnt=0; barcnt<16; barcnt++) {
char idx = SINE[sin_bar];
char barcol = barcnt*16;
for(char i=0;i<16;i++)
rasters[idx++] = barcol++;
for(char i=0;i<15;i++)
rasters[idx++] = --barcol;
sin_bar += 10;
}
// Produce dark area behind text
for(char i=0;i<19;i++)
rasters[SCROLL_Y+i] = rasters[SCROLL_Y+i] /2 & 7;
// Set up greetings
char greet_offset = greet_idx*16;
for(char i=0;i<16;i++)
(SCREEN + GREET_ROW*40 + 13)[i] = GREETING[greet_offset++] & 0xbf;
// Little smooth scroll
if(--scroll_soft == 0xff) {
scroll_soft = 7;
// Move scroll on screen
for(char i=0;i<39;i++)
(SCREEN + SCROLL_ROW*40)[i] = (SCREEN + SCROLL_ROW*40 + 1)[i];
// Show next char
char nxt = *(scroll_ptr++);
if(nxt == 0) {
scroll_ptr = SCROLL_TEXT;
nxt = *scroll_ptr;
}
*(SCREEN + SCROLL_ROW*40 + 39) = nxt & 0xbf;
}
}
// A MEGA logo
char MEGA_LOGO[] = {
0x20,0x20,0x20,0x20,0x20,0xcf,0xcf,0xcf,0x20,0xcf,0xcf,0x20,0x20,0xcf,0xcf,0xcf,0x20,0x20,0xcf,0xcf,
0xcf,0x20,0x20,0x20,0xcf,0xcf,0xcf,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0x20,0x20,0x20,0x20,0xcf,0xcf,0x20,0xcf,0xcf,0x20,0xcf,0x20,0xcf,0x20,0x20,0x20,0xcf,0xcf,0x20,0x20,
0x20,0x20,0xcf,0xcf,0x20,0x20,0x20,0xcf,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0x20,0x20,0x20,0x20,0xcf,0xcf,0x20,0x20,0xcf,0x20,0xcf,0xcf,0xcf,0xcf,0xcf,0x20,0xcf,0xcf,0x20,0xcf,
0xcf,0xcf,0xcf,0xcf,0x20,0x20,0x20,0xcf,0xcf,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0x20,0x20,0x20,0x20,0xcf,0xcf,0xcf,0x20,0x20,0x20,0xcf,0xcf,0xcf,0x20,0x20,0x20,0x20,0xcf,0x20,0x20,
0x20,0xcf,0xcf,0xcf,0x20,0xcf,0xcf,0xcf,0xcf,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0x20,0x20,0x20,0x20,0x20,0xcf,0x20,0x20,0x20,0x20,0xcf,0xcf,0x20,0xcf,0xcf,0xcf,0x20,0x20,0xcf,0xcf,
0xcf,0x20,0x20,0xcf,0x20,0x20,0x20,0xcf
};
__address(0x2d00) char PAL_RED[] = {
0x00,0xf3,0xd4,0xb5,0xa6,0x97,0x88,0x79,0x1a,0xfa,0xeb,0xec,0xbd,0xbe,0xaf,0xff,
0x16,0xc6,0xa7,0x88,0x49,0x5a,0x2b,0x1c,0xac,0xad,0x8e,0x8f,0xff,0xff,0xff,0xff,
0xc6,0x77,0x48,0x29,0xe9,0xfa,0xcb,0xcc,0x5d,0x4e,0x2f,0xff,0xff,0xff,0xff,0xff,
0x57,0x18,0xf8,0xd9,0xaa,0x8b,0x6c,0x5d,0xed,0xde,0xcf,0xff,0xff,0xff,0xff,0xff,
0x26,0xe6,0xb7,0xa8,0x69,0x5a,0x3b,0x3c,0xdc,0xcd,0xae,0x9f,0xff,0xff,0xff,0xff,
0x65,0x16,0x17,0xf7,0xd8,0xb9,0x9a,0x8b,0x2c,0x0d,0xfd,0xee,0xcf,0xff,0xff,0xff,
0x64,0x15,0x06,0xe6,0xc7,0xa8,0x99,0x8a,0x1b,0x0c,0xfc,0xfd,0xee,0xcf,0xff,0xff,
0x12,0xd2,0xd3,0xb4,0x95,0x86,0x77,0x78,0x09,0x69,0xea,0xfb,0xdc,0xad,0xae,0xaf,
0xf0,0xc1,0xc2,0xa3,0x84,0x85,0x76,0x67,0x08,0xf8,0xe9,0xda,0xdb,0xbc,0xbd,0xae,
0x40,0x11,0x12,0xf2,0xe3,0xd4,0xc5,0xc6,0x47,0x38,0x39,0x2a,0x1b,0x0c,0x0d,0xed,
0x00,0x00,0xf0,0xd1,0xc2,0xb3,0xa4,0x95,0x36,0x27,0x28,0x29,0xf9,0xea,0xeb,0xec,
0x70,0x41,0x22,0x23,0xf3,0xf4,0xe5,0xe6,0x77,0x78,0x69,0x7a,0x3b,0x3c,0x3d,0x3e,
0xa1,0x82,0x63,0x54,0x35,0x26,0x07,0x08,0x98,0x99,0x8a,0x7b,0x5c,0x5d,0x3e,0x3f,
0x33,0x04,0xd4,0xd5,0xa6,0xa7,0x88,0x89,0x1a,0xab,0xfb,0xec,0xcd,0xbe,0xaf,0xff,
0xb4,0x85,0x56,0x47,0x18,0x09,0xf9,0xea,0x7b,0x7c,0x5d,0x5e,0x2f,0xef,0xff,0xff,
0x06,0xd6,0xa7,0x98,0x59,0x4a,0x2b,0x2c,0xbc,0xad,0x8e,0x8f,0xff,0xff,0xff,0xff
};
__address(0x2e00) char PAL_GREEN[] = {
0x00,0xe3,0xc4,0xb5,0x96,0x87,0x78,0x79,0x0a,0xfa,0xeb,0xdc,0xbd,0xae,0xaf,0xff,
0xe2,0xb3,0xa4,0x85,0x76,0x67,0x48,0x49,0xd9,0xda,0xbb,0xbc,0x8d,0x8e,0x7f,0xff,
0x42,0x03,0x04,0xe4,0xd5,0xc6,0xb7,0xa8,0x39,0x3a,0x1b,0x2c,0xfc,0xfd,0xde,0xdf,
0x61,0x32,0x13,0x04,0xe4,0xe5,0xd6,0xd7,0x78,0x59,0x4a,0x4b,0x2c,0x1d,0x0e,0xfe,
0xe0,0xb1,0xa2,0x93,0x74,0x75,0x56,0x57,0xe7,0xd8,0x79,0xca,0xab,0x9c,0x9d,0x8e,
0xf0,0xd1,0xc2,0xa3,0x84,0x85,0x76,0x77,0x08,0x09,0xf9,0xfa,0xdb,0xcc,0xbd,0xae,
0x61,0x22,0x23,0x14,0xf4,0xe5,0xd6,0xc7,0x58,0x59,0x3a,0x3b,0x1c,0x0d,0xfd,0xfe,
0x92,0x53,0x44,0x35,0x16,0xf6,0xe7,0xe8,0x79,0x6a,0x5b,0x4c,0x2d,0x3e,0x1f,0xef,
0x53,0x14,0x05,0xe5,0xc6,0xb7,0xa8,0x99,0x2a,0x2b,0x0c,0x0d,0xdd,0xce,0xcf,0xff,
0xf3,0xb4,0x95,0x86,0x57,0x38,0x29,0x1a,0xba,0xab,0x9c,0x8d,0x6e,0x5f,0xff,0xff,
0x95,0x56,0x27,0x18,0xe8,0xd9,0xca,0xbb,0x4c,0x3d,0x2e,0x1f,0xef,0xff,0xff,0xff,
0xc5,0x86,0x57,0x38,0x19,0x0a,0xea,0xdb,0x6c,0x5d,0x3e,0x3f,0xef,0xff,0xff,0xff,
0x65,0x26,0x07,0xe7,0xc8,0xb9,0x9a,0x9b,0x2c,0x1d,0xfd,0xfe,0xcf,0xff,0xff,0xff,
0xb4,0x75,0x56,0x37,0x28,0x19,0xe9,0xea,0x7b,0x6c,0x5d,0x4e,0x2f,0xff,0xff,0xff,
0xc3,0x94,0x75,0x56,0x47,0x38,0x19,0x1a,0xaa,0xab,0x7c,0x7d,0x5e,0x4f,0xff,0xff,
0xe2,0xa3,0x94,0x85,0x76,0x67,0x38,0x49,0xd9,0xca,0xab,0xbc,0x7d,0x7e,0x6f,0xff
};
__address(0x2f00) char PAL_BLUE[] = {
0x00,0xf3,0xd4,0xb5,0xa6,0x97,0x88,0x79,0x1a,0xfa,0xeb,0xec,0xbd,0xbe,0xaf,0xff,
0x00,0x00,0x00,0x00,0xc0,0xb1,0xa2,0xa3,0x34,0x35,0x26,0x27,0xf7,0xf8,0xf9,0xea,
0x00,0x00,0x30,0x11,0x22,0x13,0x14,0x05,0xb5,0x96,0x97,0x98,0x79,0x6a,0x5b,0x4c,
0x81,0x42,0x43,0x34,0x05,0x06,0xf6,0xf7,0x78,0x69,0x5a,0x5b,0x4c,0x3d,0x1e,0x0f,
0x17,0xc7,0xa8,0x89,0x5a,0x5b,0x3c,0x1d,0xad,0x9e,0x7f,0xff,0xff,0xff,0xff,0xff,
0x78,0x09,0xe9,0xca,0xab,0x7c,0x5d,0x5e,0xde,0xcf,0xff,0xff,0xff,0xff,0xff,0xff,
0x59,0x0a,0xca,0xbb,0x8c,0x6d,0x3e,0x2f,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x49,0xf9,0xda,0xab,0x7c,0x5d,0x2e,0x2f,0xaf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x48,0xd8,0xb9,0xaa,0x7b,0x5c,0x2d,0x2e,0xbe,0x9f,0xff,0xff,0xff,0xff,0xff,0xff,
0x07,0x97,0x88,0x69,0x4a,0x2b,0x1c,0x2d,0x9d,0x7e,0x6f,0xff,0xff,0xff,0xff,0xff,
0x81,0x62,0x53,0x44,0x05,0x06,0xf6,0xe7,0x78,0x69,0x5a,0x5b,0x3c,0x2d,0x2e,0x1f,
0x00,0x00,0x00,0x00,0xb0,0xb1,0xa2,0xb3,0x44,0x35,0x36,0x37,0x08,0xf8,0x0a,0x0b,
0x00,0x00,0x00,0x00,0x00,0x70,0x61,0x62,0xf2,0xe3,0xd4,0xc5,0xb6,0xb7,0xb8,0x99,
0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xf1,0x82,0x83,0x84,0x85,0x66,0x57,0x58,0x59,
0x00,0x00,0x00,0x00,0x00,0x70,0x61,0x62,0xe2,0xe3,0xd4,0xd5,0xb6,0xa7,0xb8,0xa9,
0x00,0x00,0x00,0x00,0xa0,0xb1,0xa2,0xa3,0x44,0x35,0x26,0x37,0xf7,0x19,0xf9,0xfa
};
// Greetings
char GREETING[] =
" DOUBLEFLASH "
" ADTBM "
" SY2002 "
" TAYGER "
" SERIOUSLY "
"LIBI IN PARADIZE"
" LGB "
" BLUEWAYSW "
" SAUSAGE "
" BIT SHIFTER "
" INDIOCOLIFA "
" GRUMPYNINJA "
" 0-LIMITS "
" CHEVERON "
" DR. COMMODORE "
;
// The number of greetings
const char GREET_COUNT = 15;
// Scroll text
char SCROLL_TEXT[] =
" THIS SMALL MEGA65 RASTER INTRO ... WAS MADE BY DEFT IN 2015 ... "
"AND BROUGHT BACK TO LIFE 5 YEARS LATER IN 2020 ... BECAUSE "
"THE MEGA65 HARDWARE CHANGED SO MUCH IN THE PAST 5 YEARS ... "
"UNFORTUNATELY MY ASSEMBLER SKILLS DID NOT SO THIS IS THE FIRST "
"APPROACH TO GET BETTER ... HOPEFULLY DR.MUTTI WILL HAVE TO SCOLD ME LESS ... "
"THE PAST 5 YEARS HAVE BEEN AN UNFORGETTABLE & UNIQUE RIDE ... "
"IF YOU DO WATCH THIS DEMO ON YOUR VERY OWN MEGA65 THERE "
"IS ENOUGH EVIDENCE OF WHAT WE ACTUALLY ACHIEVED ... "
"BELOW ARE THE GREETINGS TO DEAR AND VERY SPECIAL PEOPLE WHO HELPED "
"TO GET THERE ... THANK YOU SO MUCH FOR YOUR SUPPORT AND FOR NOT GIVING UP "
"... DUAL SID TUNE BY RAYDEN OF ALPHA FLIGHT ... THIS SCROLLY WILL NOW RESTART "
" *WRAP* "
;