diff --git a/src/include/F256/sound_f256.h b/src/include/F256/sound_f256.h index ed25345..2a2762a 100644 --- a/src/include/F256/sound_f256.h +++ b/src/include/F256/sound_f256.h @@ -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 @@ -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 diff --git a/src/snd/Makefile b/src/snd/Makefile index d8eb1c5..cc834b3 100644 --- a/src/snd/Makefile +++ b/src/snd/Makefile @@ -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 diff --git a/src/snd/psg.c b/src/snd/psg.c index d7c0778..7d66138 100644 --- a/src/snd/psg.c +++ b/src/snd/psg.c @@ -2,10 +2,61 @@ * Definitions for the SN76489 PSG */ +#include + #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,35 +81,16 @@ 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; - } -#endif - - *port = (unsigned char)(0x90 | ((voice & 0x03) << 5) | (attenuation & 0x0f)); + volatile uint8_t * port = psg_port(chip); + if (port) { + *port = (uint8_t)(0x90 | ((voice & 0x03) << 5) | (attenuation & 0x0f)); + } } diff --git a/src/snd/sid.c b/src/snd/sid.c index 2c953fe..bfbc757 100644 --- a/src/snd/sid.c +++ b/src/snd/sid.c @@ -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; } } diff --git a/src/toolbox.c b/src/toolbox.c index 2714b57..0bfeda8 100644 --- a/src/toolbox.c +++ b/src/toolbox.c @@ -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);