Getting PSG and SID code working

Code is mainly there to let us silence those parts on boot.
This commit is contained in:
pweingar 2024-07-16 14:46:00 -04:00
parent bdd2cb4929
commit 2e966e481d
5 changed files with 137 additions and 78 deletions

View file

@ -2,8 +2,8 @@
* Sound device register definitions for the F256K
*/
#ifndef __SOUND_C256_H
#define __SOUND_C256_H
#ifndef __SOUND_F256_H
#define __SOUND_F256_H
#include <stdint.h>
@ -20,8 +20,33 @@
* Internal SID
*/
struct s_sid_voice {
uint16_t frequency;
uint16_t pulse_width;
uint8_t control;
uint8_t attack_decay;
uint8_t sustain_release;
};
struct s_sid {
struct s_sid_voice v1;
struct s_sid_voice v2;
struct s_sid_voice v3;
uint16_t filter_frequency;
uint8_t resonance_filter;
uint8_t mode_volume;
uint8_t pot_x;
uint8_t pot_y;
uint8_t osc3;
uint8_t env3;
};
#define SID_INT_N_V1_FREQ_LO ((volatile __attribute__((far)) uint8_t *)0xf01480)
#define SID_INT_L_V1_FREQ_LO ((volatile __attribute__((far)) uint8_t *)0xf01400)
#define SID_INT_R_V1_FREQ_LO ((volatile __attribute__((far)) uint8_t *)0xf01500)
#define SID_INT_N ((volatile __attribute__((far)) struct s_sid *)0xf01480)
#endif

View file

@ -37,7 +37,7 @@ else ifeq ($(UNIT),F256)
AS=as65816
AR=nlib
SRCS_FOR_UNIT=psg.c codec_c256.c # sid.c
SRCS_FOR_UNIT=psg.c codec_c256.c sid.c
CFLAGS_FOR_UNIT=-DMODEL=2 -DCPU=255 --code-model large --data-model large
endif

View file

@ -2,10 +2,61 @@
* Definitions for the SN76489 PSG
*/
#include <stdint.h>
#include "psg.h"
#include "sound_reg.h"
#include "log.h"
/**
* @brief Return the I/O base address of the PSG chip
*
* @param chip the number of the chip
* @return uint8_t* pointer to the first register
*/
static volatile uint8_t * psg_port(short chip) {
volatile uint8_t * port = 0;
#if MODEL == MODEL_FOENIX_A2560K || MODEL == MODEL_FOENIX_GENX || MODEL == MODEL_FOENIX_A2560X
switch (chip) {
case 1:
port = (uint8_t *)PSG_INT_L_PORT;
break;
case 2:
port = (uint8_t *)PSG_INT_R_PORT;
break;
case 3:
port = (uint8_t *)PSG_INT_S_PORT;
break;
default:
port = (uint8_t *)PSG_PORT;
break;
}
#elif MODEL == MODEL_FOENIX_F256 || MODEL == MODEL_FOENIX_F256K || MODEL == MODEL_FOENIX_F256K2
switch (chip) {
case 1:
port = PSG_PORT_L;
break;
case 2:
port = PSG_PORT_R;
break;
case 3:
port = PSG_PORT;
break;
default:
break;
}
#endif
return port;
}
/*
* Mute all voices on the PSG
*/
@ -30,34 +81,15 @@ void psg_mute_all() {
* frequency = the frequency
*/
void psg_tone(short chip, unsigned short voice, int frequency) {
volatile unsigned char * port = PSG_PORT; /* By default: external */
if (voice < 3) {
#if MODEL == MODEL_FOENIX_A2560K || MODEL == MODEL_FOENIX_GENX || MODEL == MODEL_FOENIX_A2560X
switch (chip) {
case 1:
port = PSG_INT_L_PORT;
break;
case 2:
port = PSG_INT_R_PORT;
break;
case 3:
port = PSG_INT_S_PORT;
break;
default:
break;
}
#endif
volatile uint8_t * port = psg_port(chip);
if (port) {
int n = 0;
if (frequency != 0) {
n = 357954500 / (32 * frequency);
n = 11320 / frequency;
// n = 3579545 / (32 * frequency);
}
*port = (unsigned char)(0x80 | ((voice & 0x03) << 5) | (n & 0x0f));
*port = (unsigned char)((n & 0x3f0) >> 4);
*port = (uint8_t)(0x80 | ((voice & 0x03) << 5) | (n & 0x0f));
*port = (uint8_t)((n & 0x3f0) >> 4);
}
}
@ -70,26 +102,8 @@ void psg_tone(short chip, unsigned short voice, int frequency) {
* attenuation = volume level 0 = loudest, 15 = silent
*/
void psg_attenuation(short chip, unsigned short voice, short attenuation) {
volatile unsigned char * port = PSG_PORT; /* By default: external */
#if ( MODEL == MODEL_FOENIX_A2560K || MODEL == MODEL_FOENIX_GENX || MODEL == MODEL_FOENIX_A2560X )
switch (chip) {
case 1:
port = PSG_INT_L_PORT;
break;
case 2:
port = PSG_INT_R_PORT;
break;
case 3:
port = PSG_INT_S_PORT;
break;
default:
break;
volatile uint8_t * port = psg_port(chip);
if (port) {
*port = (uint8_t)(0x90 | ((voice & 0x03) << 5) | (attenuation & 0x0f));
}
#endif
*port = (unsigned char)(0x90 | ((voice & 0x03) << 5) | (attenuation & 0x0f));
}

View file

@ -73,7 +73,7 @@ void sid_init_all() {
}
#if MODEL == MODEL_FOENIX_FMX || MODEL == MODEL_FOENIX_C256U || MODEL == MODEL_FOENIX_C256U_PLUS
#if MODEL == MODEL_FOENIX_FMX || MODEL == MODEL_FOENIX_C256U || MODEL == MODEL_FOENIX_C256U_PLUS || MODEL == MODEL_FOENIX_F256 || MODEL == MODEL_FOENIX_F256K || MODEL == MODEL_FOENIX_F256K2
/*
* Test the internal SID implementation
*/
@ -82,6 +82,8 @@ void sid_test_internal() {
sid = (struct s_sid *)sid_get_base(0);
if (sid) {
long jiffies = 0;
sid->v1.attack_decay = 0x29;
sid->v2.attack_decay = 0x29;
sid->v2.attack_decay = 0x29;
@ -95,32 +97,32 @@ void sid_test_internal() {
sid->v1.frequency = 0x1660;
sid->v1.control = 0x11;
// jiffies = rtc_get_jiffies() + 3;
// while (jiffies > rtc_get_jiffies());
jiffies = rtc_get_jiffies() + 3;
while (jiffies > rtc_get_jiffies());
// sid->v2.frequency = 0x0831;
// sid->v2.control = 0x11;
sid->v2.frequency = 0x0831;
sid->v2.control = 0x11;
// jiffies = rtc_get_jiffies() + 3;
// while (jiffies > rtc_get_jiffies());
jiffies = rtc_get_jiffies() + 3;
while (jiffies > rtc_get_jiffies());
// sid->v3.frequency = 0x2187;
// sid->v3.control = 0x11;
sid->v3.frequency = 0x2187;
sid->v3.control = 0x11;
// jiffies = rtc_get_jiffies() + 25;
// while (jiffies > rtc_get_jiffies());
jiffies = rtc_get_jiffies() + 25;
while (jiffies > rtc_get_jiffies());
// sid->v1.control = 0x10;
// jiffies = rtc_get_jiffies() + 3;
// while (jiffies > rtc_get_jiffies());
sid->v1.control = 0x10;
jiffies = rtc_get_jiffies() + 3;
while (jiffies > rtc_get_jiffies());
// sid->v2.control = 0x10;
// jiffies = rtc_get_jiffies() + 3;
// while (jiffies > rtc_get_jiffies());
sid->v2.control = 0x10;
jiffies = rtc_get_jiffies() + 3;
while (jiffies > rtc_get_jiffies());
// sid->v3.control = 0x10;
sid->v3.control = 0x10;
// sid->mode_volume = 0;
sid->mode_volume = 0;
}
}

View file

@ -154,8 +154,8 @@ void initialize() {
psg_mute_all();
INFO("PSG Muted.");
// /* Initialize and mute the SID chips */
// sid_init_all();
/* Initialize and mute the SID chips */
sid_init_all();
// // /* Initialize the Yamaha sound chips (well, turn their volume down at least) */
// // ym_init();
@ -184,15 +184,12 @@ void initialize() {
rtc_init();
INFO("Real time clock initialized");
// target_jiffies = timers_jiffies() + 300; /* 5 seconds minimum */
// DEBUG1("target_jiffies assigned: %d", target_jiffies);
/* Enable all interrupts */
int_enable_all();
TRACE("Interrupts enabled");
INFO("Interrupts enabled");
// // /* Play the SID test bong on the Gideon SID implementation */
// // sid_test_internal();
// /* Play the SID test bong on the Gideon SID implementation */
// sid_test_internal();
#if HAS_PATA
if ((res = pata_install())) {
@ -427,6 +424,26 @@ void test_kbd() {
printf("\n\n");
}
void test_psg() {
long target_time = rtc_get_jiffies() + (long)(60 * 2);
psg_tone(3, 0, 262);
psg_tone(3, 1, 262 * 2);
psg_tone(3, 2, 262 * 4);
psg_attenuation(3, 0, 0);
psg_attenuation(3, 1, 15);
psg_attenuation(3, 2, 15);
while (target_time > rtc_get_jiffies()) {
;
}
psg_attenuation(3, 0, 15);
psg_attenuation(3, 1, 15);
psg_attenuation(3, 2, 15);
}
void test_sysinfo() {
// 8 x 22 region
t_rect region;
@ -464,6 +481,7 @@ int main(int argc, char * argv[]) {
kbd_init();
test_sysinfo();
// test_psg();
test_kbd();
long jiffies = timers_jiffies();
printf("Jiffies: %ld\n", jiffies);