passing audio test 4
This commit is contained in:
parent
76dbf7984f
commit
d576bbca55
@ -20,6 +20,9 @@ typedef struct {
|
|||||||
bool ch4_dac;
|
bool ch4_dac;
|
||||||
|
|
||||||
bool ch1_len_fz;
|
bool ch1_len_fz;
|
||||||
|
bool ch2_len_fz;
|
||||||
|
bool ch3_len_fz;
|
||||||
|
bool ch4_len_fz;
|
||||||
|
|
||||||
u8 volume_left;
|
u8 volume_left;
|
||||||
u8 volume_right;
|
u8 volume_right;
|
||||||
|
125
lib/audio.c
125
lib/audio.c
@ -182,8 +182,8 @@ static int audio_callback(const void* input_uffer, void *output_buffer,
|
|||||||
if(dacs) {
|
if(dacs) {
|
||||||
left_out = left - left_cap;
|
left_out = left - left_cap;
|
||||||
right_out = right - right_cap;
|
right_out = right - right_cap;
|
||||||
left_cap = left - left_out * 0.996;
|
left_cap = left - left_out * 0.996f;
|
||||||
right_cap = right - right_out * 0.996;
|
right_cap = right - right_out * 0.996f;
|
||||||
}
|
}
|
||||||
|
|
||||||
*out++ = left_out;
|
*out++ = left_out;
|
||||||
@ -278,7 +278,7 @@ void sq1_sweep() {
|
|||||||
step = ctx.sq1_sweep_direction ? -step : step;
|
step = ctx.sq1_sweep_direction ? -step : step;
|
||||||
ctx.sq1_calc_period = ctx.sq1_sweep_period + step;
|
ctx.sq1_calc_period = ctx.sq1_sweep_period + step;
|
||||||
//overflow check
|
//overflow check
|
||||||
if(ctx.sq1_calc_period > 0x7FFF) {
|
if(ctx.sq1_calc_period > 0x7FF) {
|
||||||
ctx.sq1_enable = false;
|
ctx.sq1_enable = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -304,6 +304,7 @@ void audio_tick(){
|
|||||||
if(ctx.sq2_len >= 64) {
|
if(ctx.sq2_len >= 64) {
|
||||||
ctx.sq2_len = 0;
|
ctx.sq2_len = 0;
|
||||||
ctx.sq2_enable = false;
|
ctx.sq2_enable = false;
|
||||||
|
ctx.ch2_len_fz = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,6 +312,7 @@ void audio_tick(){
|
|||||||
ctx.ch3_len++;
|
ctx.ch3_len++;
|
||||||
if(ctx.ch3_len == 0) {
|
if(ctx.ch3_len == 0) {
|
||||||
ctx.ch3_enable = false;
|
ctx.ch3_enable = false;
|
||||||
|
ctx.ch3_len_fz = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,11 +321,12 @@ void audio_tick(){
|
|||||||
if(ctx.ch4_len >= 64) {
|
if(ctx.ch4_len >= 64) {
|
||||||
ctx.ch4_len = 0;
|
ctx.ch4_len = 0;
|
||||||
ctx.ch4_enable = false;
|
ctx.ch4_enable = false;
|
||||||
|
ctx.ch4_len_fz = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((prev_ticks & (1 << 3)) && !(ticks & (1 << 3))) {
|
if((prev_ticks & (1 << 2)) && !(ticks & (1 << 2))) {
|
||||||
if(ctx.sq1_env_pace != 0){
|
if(ctx.sq1_env_pace != 0){
|
||||||
ctx.sq1_env_timer++;
|
ctx.sq1_env_timer++;
|
||||||
if(ctx.sq1_env_timer >= ctx.sq1_env_pace) {
|
if(ctx.sq1_env_timer >= ctx.sq1_env_pace) {
|
||||||
@ -370,20 +373,20 @@ void audio_tick(){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if((prev_ticks & (1 << 2)) && !(ticks & (1 << 2))) {
|
if((prev_ticks & (1 << 1)) && !(ticks & (1 << 1))) {
|
||||||
ctx.sq1_sweep_timer++;
|
ctx.sq1_sweep_timer++;
|
||||||
if(ctx.sq1_sweep_timer >= ctx.sq1_sweep_pace) {
|
if(ctx.sq1_sweep_timer >= ctx.sq1_sweep_pace) {
|
||||||
ctx.sq1_sweep_timer = 0;
|
ctx.sq1_sweep_timer = 0;
|
||||||
if(ctx.sq1_enable && ctx.sq1_sweep_pace){
|
if(ctx.sq1_enable && ctx.sq1_sweep_pace > 0 && ctx.sq1_sweep_enabled){
|
||||||
sq1_sweep();
|
sq1_sweep();
|
||||||
if(ctx.sq1_calc_period <= 0x7FFF && ctx.sq1_sweep_step != 0) {
|
if(ctx.sq1_calc_period <= 0x7FF && ctx.sq1_sweep_step != 0) {
|
||||||
ctx.sq1_sweep_period = ctx.sq1_calc_period;
|
ctx.sq1_sweep_period = ctx.sq1_calc_period;
|
||||||
ctx.sq1_period_reset = ctx.sq1_calc_period;
|
ctx.sq1_period_reset = ctx.sq1_calc_period;
|
||||||
}
|
|
||||||
sq1_sweep();
|
sq1_sweep();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void enable_square1() {
|
void enable_square1() {
|
||||||
@ -396,8 +399,8 @@ void enable_square1() {
|
|||||||
ctx.sq1_sweep_timer = 0;
|
ctx.sq1_sweep_timer = 0;
|
||||||
ctx.sq1_env_direction = ctx.sq1_env_direction_buffer;
|
ctx.sq1_env_direction = ctx.sq1_env_direction_buffer;
|
||||||
ctx.sq1_env_pace = ctx.sq1_env_pace_buffer;
|
ctx.sq1_env_pace = ctx.sq1_env_pace_buffer;
|
||||||
ctx.sq1_sweep_enabled = (ctx.sq1_sweep_pace || ctx.sq1_sweep_step);
|
ctx.sq1_sweep_enabled = ((ctx.sq1_sweep_pace != 0) || (ctx.sq1_sweep_step != 0));
|
||||||
if(ctx.sq1_sweep_step) {
|
if(ctx.sq1_sweep_step != 0) {
|
||||||
sq1_sweep();
|
sq1_sweep();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -407,9 +410,6 @@ void enable_square2() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ctx.sq2_enable = true;
|
ctx.sq2_enable = true;
|
||||||
if(ctx.sq2_len >= 64) {
|
|
||||||
ctx.sq2_len = 0;
|
|
||||||
}
|
|
||||||
ctx.sq2_volume = ctx.sq2_initial_volume;
|
ctx.sq2_volume = ctx.sq2_initial_volume;
|
||||||
ctx.sq2_env_timer = 0;
|
ctx.sq2_env_timer = 0;
|
||||||
ctx.sq2_sample = 0;
|
ctx.sq2_sample = 0;
|
||||||
@ -423,13 +423,9 @@ void enable_wave() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ctx.ch3_enable = true;
|
ctx.ch3_enable = true;
|
||||||
if(ctx.ch3_len == 255) {
|
|
||||||
ctx.ch3_len = 0;
|
|
||||||
}
|
|
||||||
ctx.ch3_sample = 0;
|
ctx.ch3_sample = 0;
|
||||||
ctx.ch3_volume = ctx.ch3_initial_volume;
|
ctx.ch3_volume = ctx.ch3_initial_volume;
|
||||||
ctx.ch3_period_timer = ctx.ch3_period_reset;
|
ctx.ch3_period_timer = ctx.ch3_period_reset;
|
||||||
printf("channel 3 enabled\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void enable_noise() {
|
void enable_noise() {
|
||||||
@ -437,9 +433,6 @@ void enable_noise() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ctx.ch4_enable = true;
|
ctx.ch4_enable = true;
|
||||||
if(ctx.ch4_len >= 64) {
|
|
||||||
ctx.ch4_len = 0;
|
|
||||||
}
|
|
||||||
ctx.ch4_env_timer = 0;
|
ctx.ch4_env_timer = 0;
|
||||||
ctx.ch4_env_direction = ctx.ch4_env_direction_buffer;
|
ctx.ch4_env_direction = ctx.ch4_env_direction_buffer;
|
||||||
ctx.ch4_env_pace = ctx.ch4_env_pace_buffer;
|
ctx.ch4_env_pace = ctx.ch4_env_pace_buffer;
|
||||||
@ -454,7 +447,7 @@ u8 audio_read(u16 address) {
|
|||||||
return value | 0b01110000;
|
return value | 0b01110000;
|
||||||
}
|
}
|
||||||
if(address == 0xFF25) {
|
if(address == 0xFF25) {
|
||||||
u8 value;
|
u8 value = 0x0;
|
||||||
value |= ctx.ch4_left << 7;
|
value |= ctx.ch4_left << 7;
|
||||||
value |= ctx.ch3_left << 6;
|
value |= ctx.ch3_left << 6;
|
||||||
value |= ctx.ch2_left << 5;
|
value |= ctx.ch2_left << 5;
|
||||||
@ -464,6 +457,7 @@ u8 audio_read(u16 address) {
|
|||||||
value |= ctx.ch3_right << 2;
|
value |= ctx.ch3_right << 2;
|
||||||
value |= ctx.ch2_right << 1;
|
value |= ctx.ch2_right << 1;
|
||||||
value |= ctx.ch1_right;
|
value |= ctx.ch1_right;
|
||||||
|
//printf("read at %02X; Value: %02X\n", address, value);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -568,14 +562,14 @@ void reset_buffers(){
|
|||||||
ctx.ch1_dac = 0;
|
ctx.ch1_dac = 0;
|
||||||
ctx.ch2_dac = 0;
|
ctx.ch2_dac = 0;
|
||||||
ctx.ch3_dac = 0;
|
ctx.ch3_dac = 0;
|
||||||
ctx.ch1_left = 0;
|
ctx.ch1_left = false;
|
||||||
ctx.ch1_right = 0;
|
ctx.ch1_right = false;
|
||||||
ctx.ch2_left = 0;
|
ctx.ch2_left = false;
|
||||||
ctx.ch2_right = 0;
|
ctx.ch2_right = false;
|
||||||
ctx.ch3_left = 0;
|
ctx.ch3_left = false;
|
||||||
ctx.ch3_right = 0;
|
ctx.ch3_right = false;
|
||||||
ctx.ch4_left = 0;
|
ctx.ch4_left = false;
|
||||||
ctx.ch4_right = 0;
|
ctx.ch4_right = false;
|
||||||
ctx.volume_left = 0;
|
ctx.volume_left = 0;
|
||||||
ctx.volume_right = 0;
|
ctx.volume_right = 0;
|
||||||
ctx.vin_left = 0;
|
ctx.vin_left = 0;
|
||||||
@ -651,8 +645,9 @@ void audio_write(u16 address, u8 value){
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(address == 0xFF26) {
|
if(address == 0xFF26) {
|
||||||
ctx.audio_enabled = value & 0x80;
|
ctx.audio_enabled = (value & 0x80) == 0x80;
|
||||||
if(!ctx.audio_enabled) {
|
if(!ctx.audio_enabled) {
|
||||||
|
//printf("audio disabled\n");
|
||||||
reset_buffers();
|
reset_buffers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -671,6 +666,7 @@ void audio_write(u16 address, u8 value){
|
|||||||
ctx.ch3_right = value & 0b00000100;
|
ctx.ch3_right = value & 0b00000100;
|
||||||
ctx.ch2_right = value & 0b00000010;
|
ctx.ch2_right = value & 0b00000010;
|
||||||
ctx.ch1_right = value & 0b00000001;
|
ctx.ch1_right = value & 0b00000001;
|
||||||
|
//printf("write at %02X; Value: %02X\n", address, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(address == 0xFF24) {
|
if(address == 0xFF24) {
|
||||||
@ -691,8 +687,7 @@ void audio_write(u16 address, u8 value){
|
|||||||
ctx.sq1_duty = value >> 6;
|
ctx.sq1_duty = value >> 6;
|
||||||
ctx.sq1_initial_len = value & 0x3F;
|
ctx.sq1_initial_len = value & 0x3F;
|
||||||
ctx.sq1_len = ctx.sq1_initial_len;
|
ctx.sq1_len = ctx.sq1_initial_len;
|
||||||
static bool unfreeze;
|
ctx.ch1_len_fz = false;
|
||||||
unfreeze = true;
|
|
||||||
//printf("initial len: %02X\n", ctx.sq1_initial_len);
|
//printf("initial len: %02X\n", ctx.sq1_initial_len);
|
||||||
}
|
}
|
||||||
if(address == 0xFF12) {
|
if(address == 0xFF12) {
|
||||||
@ -729,7 +724,6 @@ void audio_write(u16 address, u8 value){
|
|||||||
ctx.sq1_len++;
|
ctx.sq1_len++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("Value: %02X\n", value);
|
|
||||||
ctx.sq1_len_enable = len_en;
|
ctx.sq1_len_enable = len_en;
|
||||||
if(value & 0x80) {
|
if(value & 0x80) {
|
||||||
enable_square1();
|
enable_square1();
|
||||||
@ -741,6 +735,7 @@ void audio_write(u16 address, u8 value){
|
|||||||
ctx.sq2_duty = value >> 6;
|
ctx.sq2_duty = value >> 6;
|
||||||
ctx.sq2_initial_len = value & 0x3F;
|
ctx.sq2_initial_len = value & 0x3F;
|
||||||
ctx.sq2_len = ctx.sq2_initial_len;
|
ctx.sq2_len = ctx.sq2_initial_len;
|
||||||
|
ctx.ch2_len_fz = false;
|
||||||
}
|
}
|
||||||
if(address == 0xFF17) {
|
if(address == 0xFF17) {
|
||||||
ctx.sq2_initial_volume = (value >> 4) & 0x0F;
|
ctx.sq2_initial_volume = (value >> 4) & 0x0F;
|
||||||
@ -759,9 +754,27 @@ void audio_write(u16 address, u8 value){
|
|||||||
//printf("period: %03X, old_period: %03X\n", ctx.sq2_period_reset, prev_period);
|
//printf("period: %03X, old_period: %03X\n", ctx.sq2_period_reset, prev_period);
|
||||||
}
|
}
|
||||||
if(address == 0xFF19) {
|
if(address == 0xFF19) {
|
||||||
|
if(ctx.sq2_len == 64) {
|
||||||
|
ctx.sq2_len = 0;
|
||||||
|
}
|
||||||
ctx.sq2_period_reset = (ctx.sq2_period_reset & 0x0FF) | ((value & 0b111) << 8);
|
ctx.sq2_period_reset = (ctx.sq2_period_reset & 0x0FF) | ((value & 0b111) << 8);
|
||||||
ctx.sq2_len_enable = (value & 0x40) == 0x40;
|
bool len_en = (value & 0x40) == 0x40;
|
||||||
if((value & 0x80) == 0x80) {
|
if((ticks % 2) == 0 && !ctx.ch2_len_fz && !ctx.sq2_len_enable && len_en){
|
||||||
|
ctx.sq2_len++;
|
||||||
|
if(ctx.sq2_len >= 64) {
|
||||||
|
ctx.sq2_len = 0;
|
||||||
|
ctx.sq2_enable = false;
|
||||||
|
ctx.ch2_len_fz = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if((ticks % 2) == 0 && ctx.ch2_len_fz && (value & 0x80) == 0x80){
|
||||||
|
ctx.ch2_len_fz = false;
|
||||||
|
if(len_en){
|
||||||
|
ctx.sq2_len++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.sq2_len_enable = len_en;
|
||||||
|
if(value & 0x80) {
|
||||||
enable_square2();
|
enable_square2();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -776,6 +789,7 @@ void audio_write(u16 address, u8 value){
|
|||||||
if(address == 0xFF1B) {
|
if(address == 0xFF1B) {
|
||||||
ctx.ch3_initial_len = value;
|
ctx.ch3_initial_len = value;
|
||||||
ctx.ch3_len = ctx.ch3_initial_len;
|
ctx.ch3_len = ctx.ch3_initial_len;
|
||||||
|
ctx.ch3_len_fz = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(address == 0xFF1C) {
|
if(address == 0xFF1C) {
|
||||||
@ -788,7 +802,23 @@ void audio_write(u16 address, u8 value){
|
|||||||
|
|
||||||
if(address == 0xFF1E) {
|
if(address == 0xFF1E) {
|
||||||
ctx.ch3_period_reset = (ctx.ch3_period_reset & 0x0FF) | ((value & 0b111) << 8);
|
ctx.ch3_period_reset = (ctx.ch3_period_reset & 0x0FF) | ((value & 0b111) << 8);
|
||||||
ctx.ch3_len_enable = (value & 0x40) == 0x40;
|
bool len_en = (value & 0x40) == 0x40;
|
||||||
|
if((ticks % 2) == 0 && !ctx.ch3_len_fz && !ctx.ch3_len_enable && len_en){
|
||||||
|
if(ctx.ch3_len >= 255) {
|
||||||
|
ctx.ch3_len = 0;
|
||||||
|
ctx.ch3_enable = false;
|
||||||
|
ctx.ch3_len_fz = true;
|
||||||
|
} else {
|
||||||
|
ctx.ch3_len++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if((ticks % 2) == 0 && ctx.ch3_len_fz && (value & 0x80) == 0x80){
|
||||||
|
ctx.ch3_len_fz = false;
|
||||||
|
if(len_en){
|
||||||
|
ctx.ch3_len++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.ch3_len_enable = len_en;
|
||||||
if(value & 0x80) {
|
if(value & 0x80) {
|
||||||
enable_wave();
|
enable_wave();
|
||||||
}
|
}
|
||||||
@ -797,6 +827,7 @@ void audio_write(u16 address, u8 value){
|
|||||||
if(address == 0xFF20) {
|
if(address == 0xFF20) {
|
||||||
ctx.ch4_initial_len = value & 0b111111;
|
ctx.ch4_initial_len = value & 0b111111;
|
||||||
ctx.ch4_len = ctx.ch4_initial_len;
|
ctx.ch4_len = ctx.ch4_initial_len;
|
||||||
|
ctx.ch4_len_fz = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(address == 0xFF21) {
|
if(address == 0xFF21) {
|
||||||
@ -821,8 +852,26 @@ void audio_write(u16 address, u8 value){
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(address == 0xFF23) {
|
if(address == 0xFF23) {
|
||||||
ctx.ch4_len_enable = (value & 0x40) == 0x40;
|
if(ctx.ch4_len == 64) {
|
||||||
if((value & 0x80) == 0x80) {
|
ctx.ch4_len = 0;
|
||||||
|
}
|
||||||
|
bool len_en = (value & 0x40) == 0x40;
|
||||||
|
if((ticks % 2) == 0 && !ctx.ch4_len_fz && !ctx.ch4_len_enable && len_en){
|
||||||
|
ctx.ch4_len++;
|
||||||
|
if(ctx.ch4_len >= 64) {
|
||||||
|
ctx.ch4_len = 0;
|
||||||
|
ctx.ch4_enable = false;
|
||||||
|
ctx.ch4_len_fz = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if((ticks % 2) == 0 && ctx.ch4_len_fz && (value & 0x80) == 0x80){
|
||||||
|
ctx.ch4_len_fz = false;
|
||||||
|
if(len_en){
|
||||||
|
ctx.ch4_len++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.ch4_len_enable = len_en;
|
||||||
|
if(value & 0x80) {
|
||||||
enable_noise();
|
enable_noise();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user