This commit is contained in:
Wolfgang Hottgenroth 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 "sequencer.h"
const t_tone notes[] = {
{ .octave = e_O_2, .note = e_G, .length = e_L_1_2 },
{ .octave = e_O_2, .note = e_D, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4 },
{ .octave = e_O_3, .note = e_G, .length = e_L_1_4, .legato = false },
{ .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_F, .length = e_L_1_2 },
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_D, .length = e_L_1_4},
{ .octave = e_O_3, .note = e_F, .length = e_L_1_4, .legato = false },
{ .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = false },
{ .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_2, .note = e_C, .length = e_L_1_4},
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4},
{ .octave = e_O_3, .note = e_C, .length = e_L_1_4, .legato = false },
{ .octave = e_O_3, .note = e_C, .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_G, .length = e_L_1_2},
{ .octave = e_O_2, .note = e_F, .length = e_L_1_4},
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4},
{ .octave = e_O_3, .note = e_G, .length = e_L_1_4, .legato = false },
{ .octave = e_O_3, .note = e_F, .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_D, .length = e_L_1_2},
{ .octave = e_O_2, .note = e_D, .length = e_L_1_4},
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4},
{ .octave = e_O_3, .note = e_D, .length = e_L_1_4, .legato = true },
{ .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_F, .length = e_L_1_2},
{ .octave = e_O_2, .note = e_G, .length = e_L_1_2},
{ .octave = e_O_3, .note = e_F, .length = e_L_1_4, .legato = false },
{ .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_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_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_2, .note = e_Ais, .length = e_L_1_4},
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_4},
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false },
{ .octave = e_O_3, .note = e_F, .length = e_L_1_8, .legato = true },
{ .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_2, .note = e_G, .length = e_L_1_4},
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4},
{ .octave = e_O_4, .note = e_C, .length = e_L_1_4, .legato = false },
{ .octave = e_O_3, .note = e_Ais, .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_2, .note = e_F, .length = e_L_1_4},
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4},
{ .octave = e_O_3, .note = e_G, .length = e_L_1_4, .legato = true },
{ .octave = e_O_3, .note = e_G, .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_D, .length = e_L_1_2},
{ .octave = e_O_2, .note = e_D, .length = e_L_1_4},
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4},
{ .octave = e_O_3, .note = e_G, .length = e_L_1_4, .legato = false },
{ .octave = e_O_3, .note = e_F, .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_F, .length = e_L_1_2},
{ .octave = e_O_2, .note = e_G, .length = e_L_1_2},
{ .octave = e_O_3, .note = e_D, .length = e_L_1_4, .legato = false },
{ .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_2, .note = e_C, .length = e_L_1_2},
{ .octave = e_O_3, .note = e_F, .length = e_L_1_4, .legato = false },
{ .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] = {
{ .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_2, .note = e_H, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_A, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_G, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_F, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_E, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_D, .length = e_L_1_4 },
{ .octave = e_O_2, .note = e_H, .length = e_L_EndMark },
{ .octave = e_O_3, .note = e_D, .length = e_L_1_4 },
{ .octave = e_O_3, .note = e_E, .length = e_L_1_4 },
{ .octave = e_O_3, .note = e_F, .length = e_L_1_4 },
{ .octave = e_O_3, .note = e_G, .length = e_L_1_4 },
{ .octave = e_O_3, .note = e_A, .length = e_L_1_4 },
{ .octave = e_O_3, .note = e_H, .length = e_L_1_4 },
{ .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 R15 015
uint8_t psgShadowRegisters[14];
inline static void BUS_OP_NACT() {
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) {
psgShadowRegisters[address] = data;
// according to "State Timing" (p. 15) of datasheet
// put bus into inactive state
@ -92,7 +100,12 @@ void psgWriteFrequency(uint8_t channel, uint16_t frequencyCode) {
}
void psgPlayTone(uint8_t channel, t_octave octave, t_note note) {
psgWriteFrequency(channel, frequencyCodes[octave][note]);
if (note == e_Pause) {
psgWrite(R7, psgReadShadow(R7) | (1 << channel));
} else {
psgWrite(R7, psgReadShadow(R7) & ~(1 << channel));
psgWriteFrequency(channel, frequencyCodes[octave][note]);
}
}
void playSomething(void *handle) {

View File

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

View File

@ -9,24 +9,38 @@ void sequencerInit() {
void sequencerExec(void *handle) {
t_melody *melody = (t_melody*) handle;
if (melody->lengthCnt == 0) {
if (melody->tones[melody->idx].length == e_L_EndMark) {
melody->idx = 0;
}
switch (melody->state) {
case 0:
if (melody->tones[melody->idx].length == e_L_EndMark) {
melody->idx = 0;
}
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->idx += 1;
melody->lengthCnt = melody->tones[melody->idx].length;
melody->state = 1;
break;
case 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;
}
melody->lengthCnt -= 1;
}
uint8_t sequencerPlayMelody(t_melody *melody) {
melody->idx = 0;
melody->lengthCnt = 0;
schAdd(sequencerExec, (void*) melody, 0, 25);
melody->state = 0;
schAdd(sequencerExec, (void*) melody, 0, 10);
return 0;
}

View File

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