Make sure to set the magic value in vector table :
#include
__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
#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
// 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