musiccode
Make sure to set the magic value in vector table :
#include <stdint.h> __attribute__((interrupt_handler)) __attribute__((section(".smallfunc"))) void doNothing(void) { /*asm volatile ("nop");*/ } __attribute__((noreturn)) __attribute__((interrupt_handler)) __attribute__((section(".smallfunc"))) void halt(void) { while(1); } #define RESERVED halt // Vector table laid out according to SH7021 datasheet tables 4.2, 5.3. __attribute__((section (".vectors"), used)) void (* const vector_table[])(void) = { /* Reset vectors */ /* Never used, BIOS has its own at address 0 */ // Power-on reset RESERVED, RESERVED, // Manual reset RESERVED, RESERVED, /* CPU interrupts */ /* Always active, except User Break masked at level 15 */ // General illegal instruction halt, // (Reserved for system use) RESERVED, // Illegal slot instruction halt, // (Reserved for system use) RESERVED, RESERVED, // CPU address error halt, // DMA address error halt, // NMI doNothing, // User Break doNothing, // (Reserved for system use) RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, // Trap instruction (user vectors) doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, /* IRQ and on-chip module interrupts */ /* Set nonzero, nonmasked priority in IPRA-IPRB to enable */ // IRQ0..IRQ7 doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, // DMAC0..DMAC3 (DEI, Reserved) doNothing, RESERVED, doNothing, RESERVED, doNothing, RESERVED, doNothing, RESERVED, // ITU0..ITU4 (IMIA, IMIB, OVI, Reserved) ((const void (*)(void))0x648C), doNothing, doNothing, RESERVED, doNothing, doNothing, doNothing, RESERVED, doNothing, doNothing, doNothing, RESERVED, doNothing, doNothing, doNothing, RESERVED, doNothing, doNothing, doNothing, RESERVED, // SCI0..SCI1 (ERI, RxI, TxI, TEI) serial_ERI0, serial_RxI0, doNothing, doNothing, doNothing, doNothing, doNothing, doNothing, // PRT PEI doNothing, // Reserved RESERVED, RESERVED, RESERVED, // WDT halt, // REF CMI halt, // Reserved RESERVED, RESERVED };
Code for playing music
#include <stdint.h> #include "loopy.h" #include "tracksong2.h" volatile void (*BiosVsync)(void) = (void (*)(void))0x6A5A; uint16_t soundState[128]; void **biosSoundState = (void **) 0x0900003C; void (*const BiosSoundDemo)(void) = (void (*)())0x6B86; void (*const BiosInitSoundTransmission)() = (void (*)())0x613C; void (*const BiosSoundChannels)(int) = (void (*)(int))0x6AC0; void (*const BiosSoundVolume)(int, int) = (void (*)(int, int))0x6B50; void (*const BiosPlayBGM)(void*, int, int, void**) = (void (*)(void*, int, int, void**))0x61A0; const void *trackList[] = { (const void*)_track_song2 }; int main() { *biosSoundState = &soundState[0]; DMAOR = 0x0001; IPRC = (IPRC & 0xFF0F) | 0x0080; // Enable Timer Interrupt maskInterrupts(0); BiosSoundChannels(2); BiosSoundVolume(0, 2); BiosSoundVolume(1, 2); BiosInitSoundTransmission(); BiosPlayBGM((void *)soundState, 0xFF, 0, (void **)trackList); VDP_BMn_SCROLLX[0] = 0xEA; VDP_BMn_SCROLLX[0] = 0xAE; while(1) { BiosVsync(); } return 0; }
Example song
#ifndef TRACK_SONG2_H #define TRACK_SONG2_H #include <stdint.h> // Example boot logo track data (bytes given in hex) const uint8_t _track_song2[] = { 0x87, 0xA2, // Timer rate 144 BPM 0x08, 0xA0, // Control value (ch2/3 high volume, ch4 mid volume) 0x00, // Delay 0 0x0F, // MidiData 15 bytes 0xC0, 0x60, // ProgramChange Channel=1 Instrument=60h 0x90, 0x38, 0x40, // NoteOn Channel=1 Note=38h Velocity=40h 0xC1, 0x5C, // ProgramChange Channel=2 Instrument=5Ch 0x91, 0x38, 0x40, // NoteOn Channel=2 Note=38h Velocity=40h 0xC3, 0x50, // ProgramChange Channel=4 Instrument=50h 0x93, 0x38, 0x40, // NoteOn Channel=4 Note=38h Velocity=40h 0x04, // Delay 4 0x03, // MidiData 3 bytes 0x90, 0x38, 0x00, // NoteOn Channel=1 Note=38h Velocity=OFF 0x07, // Delay 7 0x03, // MidiData 3 bytes 0x91, 0x38, 0x00, // NoteOn Channel=2 Note=38h Velocity=OFF 0x01, // Delay 1 0x06, // MidiData 6 bytes 0x90, 0x3C, 0x40, // NoteOn Channel=1 Note=3Ch Velocity=40h 0x91, 0x3C, 0x40, // NoteOn Channel=2 Note=3Ch Velocity=40h 0x04, // Delay 4 0x03, // MidiData 3 bytes 0x90, 0x3C, 0x00, // NoteOn Channel=1 Note=3Ch Velocity=OFF 0x05, // Delay 5 0x03, // MidiData 3 bytes 0x91, 0x3C, 0x00, // NoteOn Channel=2 Note=3Ch Velocity=OFF 0x03, // Delay 3 0x06, // MidiData 6 bytes 0x90, 0x3F, 0x40, // NoteOn Channel=1 Note=3Fh Velocity=40h 0x91, 0x3F, 0x40, // NoteOn Channel=2 Note=3Fh Velocity=40h 0x04, // Delay 4 0x03, // MidiData 3 bytes 0x90, 0x3F, 0x00, // NoteOn Channel=1 Note=3Fh Velocity=OFF 0x02, // Delay 2 0x03, // MidiData 3 bytes 0x91, 0x3F, 0x00, // NoteOn Channel=2 Note=3Fh Velocity=OFF 0x06, // Delay 6 0x06, // MidiData 6 bytes 0x90, 0x46, 0x40, // NoteOn Channel=1 Note=46h Velocity=40h 0x91, 0x46, 0x40, // NoteOn Channel=2 Note=46h Velocity=40h 0x04, // Delay 4 0x03, // MidiData 3 bytes 0x90, 0x46, 0x00, // NoteOn Channel=1 Note=46h Velocity=OFF 0x04, // Delay 4 0x03, // MidiData 3 bytes 0x91, 0x46, 0x00, // NoteOn Channel=2 Note=46h Velocity=OFF 0x04, // Delay 4 0x0C, // MidiData 12 bytes 0x90, 0x4B, 0x40, // NoteOn Channel=1 Note=4Bh Velocity=40h 0x91, 0x4B, 0x40, // NoteOn Channel=2 Note=4Bh Velocity=40h 0x93, 0x38, 0x00, // NoteOn Channel=4 Note=38h Velocity=OFF 0x93, 0x3A, 0x40, // NoteOn Channel=4 Note=3Ah Velocity=40h 0x04, // Delay 4 0x03, // MidiData 3 bytes 0x90, 0x4B, 0x00, // NoteOn Channel=1 Note=4Bh Velocity=OFF 0x04, // Delay 4 0x03, // MidiData 3 bytes 0x91, 0x4B, 0x00, // NoteOn Channel=2 Note=4Bh Velocity=OFF 0x05, // Delay 5 0x06, // MidiData 6 bytes 0x90, 0x4F, 0x40, // NoteOn Channel=1 Note=4Fh Velocity=40h 0x91, 0x4F, 0x40, // NoteOn Channel=2 Note=4Fh Velocity=40h 0x04, // Delay 4 0x03, // MidiData 3 bytes 0x90, 0x4F, 0x00, // NoteOn Channel=1 Note=4Fh Velocity=OFF 0x04, // Delay 4 0x03, // MidiData 3 bytes 0x91, 0x4F, 0x00, // NoteOn Channel=2 Note=4Fh Velocity=OFF 0x8D, // Delay 141 0x03, // MidiData 3 bytes 0x93, 0x3A, 0x00, // NoteOn Channel=4 Note=3Ah Velocity=OFF 0x00, // Delay 0 0xFE, 0xFF, 0xFF // TrackChange, Index=STOP }; #endif // TRACK_SONG2_H
musiccode.txt · Last modified: 2025/01/28 00:17 by gbb