mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-09-07 15:54:26 +00:00
114 lines
17 KiB
C
114 lines
17 KiB
C
|
|
||
|
#include <string.h>
|
||
|
|
||
|
typedef unsigned char byte;
|
||
|
typedef unsigned short word;
|
||
|
typedef signed char sbyte;
|
||
|
|
||
|
volatile byte __at (0x800f) vidframe;
|
||
|
byte __at (0x8980) watchdog;
|
||
|
|
||
|
struct {
|
||
|
struct {
|
||
|
byte f; // freq
|
||
|
byte c; // ctrl
|
||
|
} aud[4]; // channel registers
|
||
|
byte audctl; // audio control
|
||
|
byte _unused[7];
|
||
|
} __at (0x8000) pokey[2];
|
||
|
|
||
|
//
|
||
|
|
||
|
void main();
|
||
|
|
||
|
void start() {
|
||
|
__asm
|
||
|
LD SP,#0x0
|
||
|
DI
|
||
|
__endasm;
|
||
|
main();
|
||
|
}
|
||
|
|
||
|
void delay(byte i) {
|
||
|
while (i--) {
|
||
|
byte v = vidframe;
|
||
|
while (v == vidframe) ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// MUSIC ROUTINES
|
||
|
//
|
||
|
|
||
|
#define NV 4
|
||
|
|
||
|
// python mknotes.py -f 894895 -b 7
|
||
|
const word note_table[64] = {
|
||
|
35271, 33291, 31423, 29659, 27994, 26422, 24939, 23539, 22217, 20970, 19792, 18681, 17632, 16642, 15708, 14826, 13993, 13207, 12466, 11766, 11105, 10481, 9893, 9337, 8813, 8318, 7850, 7409, 6993, 6600, 6229, 5879, 5549, 5237, 4943, 4665, 4403, 4155, 3922, 3701, 3493, 3297, 3111, 2936, 2771, 2615, 2468, 2329, 2198, 2074, 1957, 1847, 1743, 1645, 1552, 1465, 1382, 1304, 1230, 1161, 1095, 1034, 975, 920, };
|
||
|
|
||
|
struct {
|
||
|
byte volume;
|
||
|
} voice[NV];
|
||
|
|
||
|
byte cur_duration;
|
||
|
|
||
|
const byte music1[] = {
|
||
|
0x35,0x8a,0x37,0x8a,0x33,0x3f,0x8a,0x30,0x3c,0x94,0x3e,0x32,0x8a,0x3a,0x2e,0x94,0x35,0x29,0x8a,0x37,0x2b,0x8a,0x33,0x27,0x8a,0x30,0x24,0x94,0x32,0x26,0x8a,0x2e,0x22,0x94,0x29,0x1d,0x8a,0x2b,0x1f,0x8a,0x27,0x1b,0x8a,0x24,0x18,0x94,0x1a,0x26,0x8a,0x18,0x24,0x8a,0x17,0x23,0x8a,0x16,0x22,0xa8,0x3a,0x35,0x32,0x94,0x29,0x26,0x22,0x8a,0x2a,0x8a,0x2b,0x1b,0x8a,0x33,0x8a,0x22,0x1f,0x27,0x8a,0x2b,0x8a,0x33,0x22,0x16,0x94,0x2b,0x27,0x25,0x8a,0x33,0x8a,0x20,0x14,0x94,0x27,0x24,0x94,0x1f,0x13,0x8a,0x3f,0x37,0x33,0x8a,0x38,0x35,0x27,0x8a,0x39,0x36,0x8a,0x3a,0x37,0x16,0x8a,0x3f,0x37,0x33,0x8a,0x35,0x38,0x22,0x8a,0x3a,0x37,0x8a,0x16,0x8a,0x3e,0x35,0x32,0x8a,0x38,0x35,0x26,0x94,0x3f,0x33,0x37,0x94,0x1f,0x22,0x27,0x94,0x27,0x22,0x1f,0x94,0x29,0x26,0x22,0x8a,0x2a,0x8a,0x2b,0x1b,0x8a,0x33,0x8a,0x1f,0x22,0x27,0x8a,0x2b,0x8a,0x33,0x22,0x16,0x94,0x2b,0x27,0x25,0x8a,0x33,0x8a,0x20,0x14,0x94,0x24,0x27,0x94,0x1f,0x13,0x94,0x3c,0x33,0x30,0x8a,0x3a,0x33,0x2e,0x8a,0x39,0x33,0x2d,0x8a,0x3c,0x30,0x8a,0x3f,0x33,0x1d,0x8a,0x37,0x8a,0x1d,0x8a,0x35,0x8a,0x3f,0x33,0x27,0x8a,0x3c,0x30,0x8a,0x35,0x38,0x26,0x94,0x22,0x16,0x94,0x24,0x18,0x94,0x29,0x26,0x1a,0x8a,0x2a,0x8a,0x2b,0x1b,0x8a,0x33,0x8a,0x27,0x22,0x1f,0x8a,0x2b,0x8a,0x33,0x16,0x22,0x94,0x2b,0x27,0x25,0x8a,0x33,0x8a,0x20,0x14,0x94,0x27,0x24,0x94,0x13,0x1f,0x8a,0x3f,0x33,0x37,0x8a,0x38,0x35,0x27,0x8a,0x39,0x36,0x8a,0x37,0x3a,0x16,0x8a,0x3f,0x37,0x33,0x8a,0x38,0x35,0x27,0x8a,0x3a,0x37,0x8a,0x16,0x8a,0x3e,0x35,0x32,0x8a,0x38,0x35,0x20,0x94,0x3f,0x37,0x33,0x94,0x27,0x22,0x1f,0x94,0x2b,0x27,0x22,0x94,0x3f,0x33,0x8a,0x35,0x8a,0x37,0x27,0x1b,0x8a,0x3f,0x33,0x8a,0x35,0x2b,0x22,0x8a,0x37,0x8a,0x25,0x19,0x8a,0x3f,0x33,0x8a,0x35,0x2b,0x27,0x8a,0x3f,0x33,0x8a,0x37,0x24,0x18,0x8a,0x3f,0x33,0x8a,0x35,0x2c,0x27,0x8a,0x37,0x8a,0x23,0x17,0x8a,0x3f,0x33,0x8a,0x35,0x2c,0x27,0x8a,0x3f,0x33,0x8a,0x3a,0x37,0x22,0x8a,0x3f,0x37,0x33,0x8a,0x38,0x35,0x2b,0x8a,0x3a,0x37,0x8a,0x16,0x8a,0x3e,0x32,0x35,0x8a,0x35,0x38,0x26,0x94,0x3f,0x33,0x37,0x94,0x22,0x16,0x94,0x24,0x18,0x94,0x29,0x26,0x1a,0x8a,0x2a,0x8a,0x2b,0x1b,0x8a,0x33,0x8a,0x27,0x22,0x1f,0x8a,0x2b,0x8a,0x33,0x22,0x16,0x94,0x2b,0x25,0x22,0x8a,0x33,0x8a,0x20,0x14,0x94,0x27,0x24,0x94,0x1f,0x13,0x8a,0x3f,0x37,0x33,0x8a,0x35,0x38,0x27,0x8a,0x39,0x36,0x8a,0x3a,0x37,0x16,0x8a,0x3f,0x37,0x33,0x8a,0x38,0x35,0x27,0x8a,0x3a,0x37,0x8a,0x16,0x8a,0x3e,0x35,0x32,0x8a,0x35,0x38,0x20,0x94,0x37,0x33,0x3f,0x94,0x27,0x22,0x1f,0x94,0x27,0x22,0x1f,0x94,0x29,0x26,0x22,0x8a,0x2a,0x8a,0x2b,0x1b,0x8a,0x33,0x8a,0x22,0x1f,0x27,0x8a,0x2b,0x8a,0x33,0x22,0x16,0x94,0x2b,0x27,0x25,0x8a,0x33,0x8a,0x20,0x14,0x94,0x27,0x24,0x94,0x1f,0x13,0x94,0x3c,0x33,0x30,0x8a,0x3a,0x33,0x2e,0x8a,0x2d,0x33,0x39,0x8a,0x3c,0x30,0x8a,0x3f,0x33,0x27,0x8a,0x37,0x8a,0x1d,0x8a,0x35,0x8a,0x33,0x3f,0x27,0x8a,0x3c,0x30,0x8a,0x38,0x35,0x26,0x94,0x22,0x16,0x94,0x24,0x18,0x94,0x29,0x26,0x1a,0x8a,0x2a,0x8a,0x2b,0x1b,0x8a,0x33,0x8a,0x22,0x27,0x1f,0x8a,0x2b,0x8a,0x33,0x22,0x16,0x94,0x2b,0x27,0x25,0x8a,0x33,0x8a,0x20,0x14,0x94,0x24,0x27,0x94,0x1f,0x13,0x8a,0x3f,0x37,0x33,0x8a,0x38,0x35,0x27,0x8a,0x36,0x39,0x8a,0x3a,0x37,0x16,0x8a,0x3f,0x37,0x33,0x8a,0x38,0x35,0x27,0x8a,0x37,0x3a,0x8a,0x16,0x8a,0x3e,0x35,0x32,0x8a,0x38,0x35,0x22,0x94,0x33,0x37,0x3f,0x94,0x27,0x22,0x1f,0x94,0x22,0x27,0x2b,0x94,0x3f,0x33,0x8a,0x35,0x8a,0x37,0x27,0x1b,0x8a,0x3f,0x33,0x8a,0x35,0x2b,0x27,0x8a,0x37,0x8a,0x25,0x19,0x8a,0x3f,0x33,0x8a,0x35,0x2b,0x22,0x8a,0x3f,0x33,0x8a,0x37,0x24,0x18,0x8a,0x33,0x3f,0x8a,0x35,0x2c,0x27,0x8a,0x37,0x8a,0x23,0x17,0x8a,0x3f,0x33,0x8a,0x35,0x2c,0x27,0x8a,0x3f,0x33,0x8a,0x3a,0x37,0x22,0x8a,0x3f,0x37,0x33,0x8a,0x38,0x35,0x2b,0x8a,0x37,0x3a,0x8a,0x16,0x8a,0x3e,0x35,0x32,0x8a,0x38,0x35,0x22,0x94,0x33,0x37,0x3f,0x94,0x22,0x16,0x94,0x1b,0x0f,0x8a,0x37,0x2b,0x33,0x8a,0x38,0x2c,0x35,0x8a,0x39,0x36,0x2d,0x8a,0x3a,0x37,0x2e,0x94,0x3c,0x37,0x30,0x8a,0x3a,0x2e,0x37,0x8a,0x16,0x8a,0x37,0x33,0x2b,0x8a,0x2c,0x38,0x35,0x8a,0x39,0x36,0x2d,0x8a,0x3a,0x37,0x2e,0x94,0x3c,0x37,0x30,0x8a,0x2e,0x37,0x3a,0x8a,0x16,0x8a,0x37,0x8a,0x33,0x27,0x2b,0x8a,0x2e,0x8a,0x30,0x14,0x8a,0x32,0x8a,0x33,0x2c,0x27,0x8a,0x35,0x8a,0x37,0x20,0x8a,0x35,0x8a,0x33,0x2c,0x27,0x8a,0x35,
|
||
|
};
|
||
|
|
||
|
static const byte* music_ptr = music1;
|
||
|
|
||
|
inline byte next_music_byte() {
|
||
|
return *music_ptr++;
|
||
|
}
|
||
|
|
||
|
void play_music() {
|
||
|
byte ch;
|
||
|
byte freech = 0;
|
||
|
for (ch=0; ch<NV; ch++) {
|
||
|
if (voice[ch].volume) {
|
||
|
byte reg = (ch<<1)&2;
|
||
|
pokey[ch>>1].aud[1+reg].c = 0xa0 | --voice[ch].volume;
|
||
|
} else {
|
||
|
freech = ch;
|
||
|
}
|
||
|
}
|
||
|
if (music_ptr) {
|
||
|
ch = freech;
|
||
|
while (cur_duration == 0) {
|
||
|
byte note = next_music_byte();
|
||
|
if ((note & 0x80) == 0) {
|
||
|
byte reg = (ch<<1)&2;
|
||
|
word period = note_table[note & 63];
|
||
|
pokey[ch>>1].aud[0+reg].f = period;
|
||
|
pokey[ch>>1].aud[1+reg].f = period >> 8;
|
||
|
voice[ch].volume = 15;
|
||
|
ch = ch ? ch-1 : NV-1;
|
||
|
} else {
|
||
|
if (note == 0xff)
|
||
|
music_ptr = NULL;
|
||
|
cur_duration = note & 63;
|
||
|
}
|
||
|
}
|
||
|
cur_duration--;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void start_music(const byte* music) {
|
||
|
music_ptr = music;
|
||
|
cur_duration == 0;
|
||
|
}
|
||
|
|
||
|
void main() {
|
||
|
music_ptr = 0;
|
||
|
cur_duration = 0;
|
||
|
pokey[0].audctl = 0b01111000;
|
||
|
pokey[1].audctl = 0b01111000;
|
||
|
while (1) {
|
||
|
if (!music_ptr) start_music(music1);
|
||
|
play_music();
|
||
|
delay(1);
|
||
|
watchdog++;
|
||
|
}
|
||
|
}
|