This commit is contained in:
2024-03-26 21:05:48 +01:00
parent 73d2bbc730
commit 9989a52c38
5 changed files with 115 additions and 68 deletions

View File

@ -1,84 +1,97 @@
#include <stdbool.h>
#include "psg.h" #include "psg.h"
#include "sequencer.h" #include "sequencer.h"
const t_tone notes[] = { const t_tone notes[] = {
{ .octave = e_O_2, .note = e_G, .length = e_L_1_2 }, { .octave = e_O_3, .note = e_G, .length = e_L_1_4, .legato = false },
{ .octave = e_O_2, .note = e_D, .length = e_L_1_4 }, { .octave = e_O_3, .note = e_D, .length = e_L_1_8, .legato = false },
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4 }, { .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = false },
{ .octave = e_O_2, .note = e_F, .length = e_L_1_2 }, { .octave = e_O_3, .note = e_F, .length = e_L_1_4, .legato = false },
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4 }, { .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = false },
{ .octave = e_O_2, .note = e_D, .length = e_L_1_4}, { .octave = e_O_3, .note = e_D, .length = e_L_1_8, .legato = false },
{ .octave = e_O_2, .note = e_C, .length = e_L_1_2}, { .octave = e_O_3, .note = e_C, .length = e_L_1_4, .legato = false },
{ .octave = e_O_2, .note = e_C, .length = e_L_1_4}, { .octave = e_O_3, .note = e_C, .length = e_L_1_8, .legato = false },
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4}, { .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = false },
{ .octave = e_O_2, .note = e_G, .length = e_L_1_2}, { .octave = e_O_3, .note = e_G, .length = e_L_1_4, .legato = false },
{ .octave = e_O_2, .note = e_F, .length = e_L_1_4}, { .octave = e_O_3, .note = e_F, .length = e_L_1_8, .legato = false },
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4}, { .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = false },
{ .octave = e_O_2, .note = e_D, .length = e_L_1_2}, { .octave = e_O_3, .note = e_D, .length = e_L_1_4, .legato = true },
{ .octave = e_O_2, .note = e_D, .length = e_L_1_4}, { .octave = e_O_3, .note = e_D, .length = e_L_1_8, .legato = false },
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4}, { .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = false },
{ .octave = e_O_2, .note = e_F, .length = e_L_1_2}, { .octave = e_O_3, .note = e_F, .length = e_L_1_4, .legato = false },
{ .octave = e_O_2, .note = e_G, .length = e_L_1_2}, { .octave = e_O_3, .note = e_G, .length = e_L_1_4, .legato = false },
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_2}, { .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = true },
{ .octave = e_O_2, .note = e_C, .length = e_L_1_2}, { .octave = e_O_3, .note = e_Dis, .length = e_L_1_16, .legato = false },
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_16, .legato = false },
{ .octave = e_O_3, .note = e_C, .length = e_L_1_8, .legato = true },
{ .octave = e_O_3, .note = e_C, .length = e_L_1_16, .legato = false },
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_16, .legato = false },
{ .octave = e_O_2, .note = e_C, .length = e_L_1_2}, { .octave = e_O_3, .note = e_C, .length = e_L_1_4, .legato = false },
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_4, .legato = false },
{ .octave = e_O_2, .note = e_F, .length = e_L_1_4},
{ .octave = e_O_2, .note = e_F, .length = e_L_1_4},
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_4},
{ .octave = e_O_3, .note = e_C, .length = e_L_1_2}, { .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false },
{ .octave = e_O_2, .note = e_Ais, .length = e_L_1_4}, { .octave = e_O_3, .note = e_F, .length = e_L_1_8, .legato = true },
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_4}, { .octave = e_O_3, .note = e_F, .length = e_L_1_8, .legato = false },
{ .octave = e_O_3, .note = e_Gis, .length = e_L_1_8, .legato = false },
{ .octave = e_O_2, .note = e_G, .length = e_L_1_2}, { .octave = e_O_4, .note = e_C, .length = e_L_1_4, .legato = false },
{ .octave = e_O_2, .note = e_G, .length = e_L_1_4}, { .octave = e_O_3, .note = e_Ais, .length = e_L_1_8, .legato = false },
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4}, { .octave = e_O_3, .note = e_Gis, .length = e_L_1_8, .legato = false },
{ .octave = e_O_2, .note = e_G, .length = e_L_1_2}, { .octave = e_O_3, .note = e_G, .length = e_L_1_4, .legato = true },
{ .octave = e_O_2, .note = e_F, .length = e_L_1_4}, { .octave = e_O_3, .note = e_G, .length = e_L_1_8, .legato = false },
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4}, { .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = false },
{ .octave = e_O_2, .note = e_D, .length = e_L_1_2}, { .octave = e_O_3, .note = e_G, .length = e_L_1_4, .legato = false },
{ .octave = e_O_2, .note = e_D, .length = e_L_1_4}, { .octave = e_O_3, .note = e_F, .length = e_L_1_8, .legato = false },
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4}, { .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = false },
{ .octave = e_O_2, .note = e_F, .length = e_L_1_2}, { .octave = e_O_3, .note = e_D, .length = e_L_1_4, .legato = false },
{ .octave = e_O_2, .note = e_G, .length = e_L_1_2}, { .octave = e_O_3, .note = e_D, .length = e_L_1_8, .legato = false },
{ .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = false },
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_2}, { .octave = e_O_3, .note = e_F, .length = e_L_1_4, .legato = false },
{ .octave = e_O_2, .note = e_C, .length = e_L_1_2}, { .octave = e_O_3, .note = e_G, .length = e_L_1_4, .legato = false },
{ .octave = e_O_2, .note = e_C, .length = e_L_1_2}, { .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = true },
{ .octave = e_O_3, .note = e_Dis, .length = e_L_1_16, .legato = false },
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_16, .legato = false },
{ .octave = e_O_3, .note = e_C, .length = e_L_1_8, .legato = true },
{ .octave = e_O_3, .note = e_C, .length = e_L_1_16, .legato = false },
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_16, .legato = false },
{ .octave = e_O_2, .note = e_C, .length = e_L_EndMark }, { .octave = e_O_3, .note = e_C, .length = e_L_1_4, .legato = false },
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_4, .legato = false },
{ .octave = e_O_Null, .note = e_Null, .length = e_L_EndMark, .legato = false },
}; };
/* /*
const t_tone ladder[16] = { const t_tone ladder[16] = {
{ .octave = e_O_2, .note = e_C, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_D, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_E, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_F, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_G, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_A, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_H, .length = e_L_1_4 },
{ .octave = e_O_3, .note = e_C, .length = e_L_1_4 }, { .octave = e_O_3, .note = e_C, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_H, .length = e_L_1_4 }, { .octave = e_O_3, .note = e_D, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_A, .length = e_L_1_4 }, { .octave = e_O_3, .note = e_E, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_G, .length = e_L_1_4 }, { .octave = e_O_3, .note = e_F, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_F, .length = e_L_1_4 }, { .octave = e_O_3, .note = e_G, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_E, .length = e_L_1_4 }, { .octave = e_O_3, .note = e_A, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_D, .length = e_L_1_4 }, { .octave = e_O_3, .note = e_H, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_H, .length = e_L_EndMark }, { .octave = e_O_4, .note = e_C, .length = e_L_1_4 },
{ .octave = e_O_3, .note = e_H, .length = e_L_1_4 },
{ .octave = e_O_3, .note = e_A, .length = e_L_1_4 },
{ .octave = e_O_3, .note = e_G, .length = e_L_1_4 },
{ .octave = e_O_3, .note = e_F, .length = e_L_1_4 },
{ .octave = e_O_3, .note = e_E, .length = e_L_1_4 },
{ .octave = e_O_3, .note = e_D, .length = e_L_1_4 },
{ .octave = e_O_3, .note = e_H, .length = e_L_EndMark },
}; };
*/ */

View File

@ -39,6 +39,8 @@ const uint16_t frequencyCodes[8][12] = {
#define R14 014 #define R14 014
#define R15 015 #define R15 015
uint8_t psgShadowRegisters[14];
inline static void BUS_OP_NACT() { inline static void BUS_OP_NACT() {
BUS_CTRL_REG &= ~(BDIR | BC1); BUS_CTRL_REG &= ~(BDIR | BC1);
} }
@ -61,7 +63,13 @@ asm volatile (
); );
} }
uint8_t psgReadShadow(uint8_t address) {
return psgShadowRegisters[address];
}
void psgWrite(uint8_t address, uint8_t data) { void psgWrite(uint8_t address, uint8_t data) {
psgShadowRegisters[address] = data;
// according to "State Timing" (p. 15) of datasheet // according to "State Timing" (p. 15) of datasheet
// put bus into inactive state // put bus into inactive state
@ -92,8 +100,13 @@ void psgWriteFrequency(uint8_t channel, uint16_t frequencyCode) {
} }
void psgPlayTone(uint8_t channel, t_octave octave, t_note note) { void psgPlayTone(uint8_t channel, t_octave octave, t_note note) {
if (note == e_Pause) {
psgWrite(R7, psgReadShadow(R7) | (1 << channel));
} else {
psgWrite(R7, psgReadShadow(R7) & ~(1 << channel));
psgWriteFrequency(channel, frequencyCodes[octave][note]); psgWriteFrequency(channel, frequencyCodes[octave][note]);
} }
}
void playSomething(void *handle) { void playSomething(void *handle) {
static uint8_t state = 0; static uint8_t state = 0;

View File

@ -11,7 +11,8 @@ typedef enum {
e_O_5, e_O_5,
e_O_6, e_O_6,
e_O_7, e_O_7,
e_O_8 e_O_8,
e_O_Null
} t_octave; } t_octave;
typedef enum { typedef enum {
@ -26,7 +27,9 @@ typedef enum {
e_Gis, e_Gis,
e_A, e_A,
e_Ais, e_Ais,
e_H e_H,
e_Pause,
e_Null
} t_note; } t_note;
@ -34,5 +37,6 @@ void psgInit();
void psgPlayTone(uint8_t channel, t_octave octave, t_note note); void psgPlayTone(uint8_t channel, t_octave octave, t_note note);
void psgWriteFrequency(uint8_t channel, uint16_t frequencyCode); void psgWriteFrequency(uint8_t channel, uint16_t frequencyCode);
void psgWrite(uint8_t address, uint8_t data); void psgWrite(uint8_t address, uint8_t data);
uint8_t psgReadShadow(uint8_t address);
#endif // _PSG_H_ #endif // _PSG_H_

View File

@ -9,7 +9,8 @@ void sequencerInit() {
void sequencerExec(void *handle) { void sequencerExec(void *handle) {
t_melody *melody = (t_melody*) handle; t_melody *melody = (t_melody*) handle;
if (melody->lengthCnt == 0) { switch (melody->state) {
case 0:
if (melody->tones[melody->idx].length == e_L_EndMark) { if (melody->tones[melody->idx].length == e_L_EndMark) {
melody->idx = 0; melody->idx = 0;
} }
@ -17,16 +18,29 @@ void sequencerExec(void *handle) {
psgPlayTone(melody->channel, melody->tones[melody->idx].octave, melody->tones[melody->idx].note); psgPlayTone(melody->channel, melody->tones[melody->idx].octave, melody->tones[melody->idx].note);
melody->lengthCnt = melody->tones[melody->idx].length; melody->lengthCnt = melody->tones[melody->idx].length;
melody->idx += 1; melody->state = 1;
} break;
case 1:
melody->lengthCnt -= 1; melody->lengthCnt -= 1;
if (melody->lengthCnt == 0) {
melody->state = 2;
}
break;
case 2:
if (! (melody->tones[melody->idx].legato)) {
psgPlayTone(melody->channel, e_O_Null, e_Pause);
}
melody->idx += 1;
melody->state = 0;
break;
}
} }
uint8_t sequencerPlayMelody(t_melody *melody) { uint8_t sequencerPlayMelody(t_melody *melody) {
melody->idx = 0; melody->idx = 0;
melody->lengthCnt = 0; melody->lengthCnt = 0;
schAdd(sequencerExec, (void*) melody, 0, 25); melody->state = 0;
schAdd(sequencerExec, (void*) melody, 0, 10);
return 0; return 0;
} }

View File

@ -3,6 +3,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#include "psg.h" #include "psg.h"
typedef enum { typedef enum {
@ -18,11 +19,13 @@ typedef struct {
t_octave octave; t_octave octave;
t_note note; t_note note;
t_noteLength length; t_noteLength length;
bool legato;
} t_tone; } t_tone;
typedef struct { typedef struct {
uint16_t idx; uint16_t idx;
uint8_t lengthCnt; uint8_t lengthCnt;
uint8_t state;
uint8_t channel; uint8_t channel;
const t_tone *tones; const t_tone *tones;
} t_melody; } t_melody;