1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-08-07 06:30:04 +00:00
Files
kickc/src/test/kc/examples/mega65/banked-music.c
2020-09-26 13:30:48 +02:00

101 lines
3.1 KiB
C

// SID music located in another bank being played in a raster IRQ using memory mapping on the MEGA65
// Music is Cybernoid II by Jeroen Tel released in 1988 by Hewson https://csdb.dk/sid/?id=28140
// SID relocated using http://www.linusakesson.net/software/sidreloc/index.php
#pragma target(mega65)
#pragma link("mega65_banked.ld")
#include <mega65.h>
#include <mega65-dma.h>
void main() {
// Stop IRQ's
asm { sei }
// Map memory to BANK 0 : 0x00XXXX - giving access to I/O
memoryRemap(0,0,0);
// Enable MEGA65 features
VICIII->KEY = 0x47;
VICIII->KEY = 0x53;
// Enable 48MHz fast mode
VICIV->CONTROLB |= 0x40;
VICIV->CONTROLC |= 0x40;
// no kernal or BASIC rom visible
*PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK;
*PROCPORT = PROCPORT_RAM_IO;
// open sideborder
VICIV->SIDBDRWD_LO = 1;
// Transfer banked code/data to upper memory ($10000)
memcpy_dma4(1, 0x0000, 0, upperCodeData, MUSIC_END-MUSIC);
// Remap [$4000-$5fff] to point to [$10000-$11fff]
memoryRemapBlock(0x40, 0x100);
// Initialize SID
asm { lda #0 }
(*musicInit)();
// Reset memory mapping
memoryRemap(0,0,0);
// Set up raster interrupts C64 style
// Disable CIA 1 Timer IRQ
CIA1->INTERRUPT = CIA_INTERRUPT_CLEAR;
// Set raster line to 0xff
VICII->RASTER = 0xff;
VICII->CONTROL1 &= 0x7f;
// Enable Raster Interrupt
VICII->IRQ_ENABLE = IRQ_RASTER;
// Set the IRQ routine
*HARDWARE_IRQ = &irq;
// Enable IRQ
asm { cli }
// Loop forever - while destroying and showing unmapped MUSIC memory to screen (to demonstrate that mapping works)
char mem_destroy_i = 0;
for(;;) {
// Overwrite unmapped MUSIC memory
MUSIC[mem_destroy_i++]++;
// Show unmapped MUSIC memory
for(char i=0;i<240;i++)
DEFAULT_SCREEN[i] = MUSIC[i];
}
}
// Raster IRQ routine
interrupt(hardware_stack) void irq() {
// Acknowledge the IRQ
VICII->IRQ_STATUS = IRQ_RASTER;
// Color border
(VICII->BORDER_COLOR)++;
// Remap memory to put music at $4000
memoryRemapBlock(0x40, 0x100);
// Play remapped SID
(*musicPlay)();
// Reset memory mapping
memoryRemap(0,0,0);
// Wait for the next raster line
char raster = VICII->RASTER;
while(VICII->RASTER==raster) ;
// Color border
(VICII->BORDER_COLOR)--;
}
// Array containing the banked upper memory code/data to be transferred to upper memory before execution
char upperCodeData[] = kickasm {{
.segmentout [segments="Banked"]
}};
// Code and data to be put into upper memory, which will be banked into $4000 by mempry mapping
#pragma code_seg(CodeBanked)
#pragma data_seg(DataBanked)
// SID tune at an absolute address
__address(0x4000) char MUSIC[] = kickasm(resource "Cybernoid_II_4000.sid") {{
.const music = LoadSid("Cybernoid_II_4000.sid")
.fill music.size, music.getData(i)
}};
// Address after the end of the music
char * const MUSIC_END = 0x5200;
// Pointer to the music init routine
void()* musicInit = (void()*) MUSIC;
// Pointer to the music play routine
void()* musicPlay = (void()*) MUSIC+3;