Passing audio test 1.

This commit is contained in:
Samuel Walker 2025-02-03 22:59:24 -07:00
parent 0518c079cc
commit 91b7d704cd
Signed by: piwalker
GPG Key ID: 616B1928705EA4C9
3 changed files with 233 additions and 17 deletions

View File

@ -5,6 +5,8 @@
"string.h": "c", "string.h": "c",
"common.h": "c", "common.h": "c",
"ppu.h": "c", "ppu.h": "c",
"profileapi.h": "c" "profileapi.h": "c",
"type_traits": "c",
"xtr1common": "c"
} }
} }

View File

@ -17,6 +17,8 @@ typedef struct {
u8 volume_left; u8 volume_left;
u8 volume_right; u8 volume_right;
bool vin_left;
bool vin_right;
u8 sq1_duty; u8 sq1_duty;
u8 sq1_volume; u8 sq1_volume;
@ -59,6 +61,7 @@ typedef struct {
u8 sq2_env_timer; u8 sq2_env_timer;
bool ch3_enable; bool ch3_enable;
bool ch3_dac;
u8 ch3_initial_len; u8 ch3_initial_len;
u8 ch3_len; u8 ch3_len;
u8 ch3_volume; u8 ch3_volume;

View File

@ -161,9 +161,10 @@ static int audio_callback(const void* input_uffer, void *output_buffer,
} }
} }
} }
u8 left_vol = ctx.volume_left == 0 ? 1 : ctx.volume_left;
left *= (float)ctx.volume_left/7.0f; u8 right_vol = ctx.volume_right == 0 ? 1 : ctx.volume_right;
right *= (float)ctx.volume_right/7.0f; left *= (float)left_vol/7.0f;
right *= (float)right_vol/7.0f;
left /= 4; left /= 4;
right /= 4; right /= 4;
@ -280,6 +281,7 @@ void audio_tick(){
if(ctx.sq1_len >= 64) { if(ctx.sq1_len >= 64) {
ctx.sq1_enable = false; ctx.sq1_enable = false;
} }
printf("Len: %02X\n", ctx.sq1_len);
} }
if(ctx.sq2_len_enable) { if(ctx.sq2_len_enable) {
@ -291,7 +293,7 @@ void audio_tick(){
if(ctx.ch3_len_enable) { if(ctx.ch3_len_enable) {
ctx.ch3_len++; ctx.ch3_len++;
if(ctx.ch3_len >= 64) { if(ctx.ch3_len >= 256) {
ctx.ch3_enable = false; ctx.ch3_enable = false;
} }
} }
@ -399,7 +401,7 @@ void enable_square2() {
void enable_wave() { void enable_wave() {
ctx.ch3_enable = true; ctx.ch3_enable = true;
if(ctx.ch3_len >= 64) { if(ctx.ch3_len >= 256) {
ctx.ch3_len = ctx.ch3_initial_len; ctx.ch3_len = ctx.ch3_initial_len;
} }
ctx.ch3_sample = 0; ctx.ch3_sample = 0;
@ -420,13 +422,216 @@ void enable_noise() {
} }
u8 audio_read(u16 address) { u8 audio_read(u16 address) {
return 0x00; printf("read at %02X\n", address);
if(address == 0xFF26) {
u8 value = (ctx.audio_enabled << 7) | (ctx.ch4_enable << 3) | (ctx.ch3_enable << 2) | (ctx.sq2_enable << 1) | (ctx.sq1_enable);
return value | 0b01110000;
}
if(address == 0xFF25) {
u8 value;
value |= ctx.ch4_left << 7;
value |= ctx.ch3_left << 6;
value |= ctx.ch2_left << 5;
value |= ctx.ch1_left << 4;
value |= ctx.ch4_right << 3;
value |= ctx.ch3_right << 2;
value |= ctx.ch2_right << 1;
value |= ctx.ch1_right;
return value;
}
if(address == 0xFF24) {
u8 value = (ctx.volume_left & 0b111) << 4;
value |= (ctx.volume_right & 0b111);
value |= (ctx.vin_left << 7);
value |= (ctx.vin_right << 3);
return value;
}
if(address == 0xFF10) {
u8 value = (ctx.sq1_sweep_pace & 0b111) << 4;
value |= (ctx.sq1_sweep_direction) << 3;
value |= ctx.sq1_sweep_step & 0b111;
return value | 0x80;
}
if(address == 0xFF11) {
u8 value = (ctx.sq1_duty & 0b11) << 6;
return value | 0b00111111;
}
if(address == 0xFF12) {
u8 value = (ctx.sq1_initial_volume & 0b1111) << 4;
value |= ctx.sq1_env_direction_buffer << 3;
value |= (ctx.sq1_env_pace_buffer & 0b111);
return value;
}
if(address == 0xFF13) {
return 0xFF;
}
if(address == 0xFF14) {
return (ctx.sq1_len_enable << 6) | 0b10111111;
}
if(address == 0xFF16) {
u8 value = (ctx.sq2_duty & 0b11) << 6;
return value | 0b00111111;
}
if(address == 0xFF17) {
u8 value = (ctx.sq2_initial_volume & 0b1111) << 4;
value |= ctx.sq2_env_direction_buffer << 3;
value |= (ctx.sq2_env_pace_buffer & 0b111);
return value;
}
if(address == 0xFF18) {
return 0xFF;
}
if(address == 0xFF19) {
return (ctx.sq2_len_enable << 6) | 0b10111111;
}
if(address == 0xFF1A) {
return (ctx.ch3_dac << 7) | 0b01111111;
}
if(address == 0xFF1B) {
return 0xFF;
}
if(address == 0xFF1C) {
return ((ctx.ch3_initial_volume & 0b11) << 5) | 0b10011111;
}
if(address == 0xFF1D) {
return 0xFF;
}
if(address == 0xFF1E) {
return (ctx.ch3_len_enable << 6) | 0b10111111;
}
if(address == 0xFF20) {
return 0xFF;
}
if(address == 0xFF21) {
u8 value = (ctx.ch4_initial_volume & 0b1111) << 4;
value |= ctx.ch4_env_direction_buffer << 3;
value |= (ctx.ch4_env_pace_buffer & 0b111);
return value;
}
if(address == 0xFF22) {
u8 value = (ctx.ch4_clock_shift & 0xF) << 4;
value |= ctx.ch4_lfsr_width << 3;
value |= (ctx.ch4_clock_divider & 0b111);
return value;
}
if(address == 0xFF23) {
return (ctx.ch4_len_enable << 6) | 0b10111111;
}
if(BETWEEN(address, 0xFF30, 0xFF3F)) {
return ctx.wave_ram[address - 0xFF30];
}
return 0xFF;
}
void reset_buffers(){
ctx.ch1_left = 0;
ctx.ch1_right = 0;
ctx.ch2_left = 0;
ctx.ch2_right = 0;
ctx.ch3_left = 0;
ctx.ch3_right = 0;
ctx.ch4_left = 0;
ctx.ch4_right = 0;
ctx.volume_left = 0;
ctx.volume_right = 0;
ctx.vin_left = 0;
ctx.vin_right = 0;
ctx.sq1_duty = 0;
ctx.sq1_volume = 0;
ctx.sq1_sample = 0;
ctx.sq1_period_reset = 0;
ctx.sq1_period_timer = 0;
ctx.sq1_enable = 0;
ctx.sq1_len_enable = 0;
ctx.sq1_sweep_pace = 0;
ctx.sq1_sweep_direction = 0;
ctx.sq1_initial_len = 0;
ctx.sq1_len = 0;
ctx.sq1_initial_volume = 0;
ctx.sq1_env_direction = 0;
ctx.sq1_env_direction_buffer = 0;
ctx.sq1_env_pace = 0;
ctx.sq1_env_pace_buffer = 0;
ctx.sq1_env_timer = 0;
ctx.sq1_sweep_step = 0;
ctx.sq1_sweep_timer = 0;
ctx.sq1_sweep_enabled = 0;
ctx.sq1_sweep_period = 0;
ctx.sq1_calc_period = 0;
ctx.sq2_duty = 0;
ctx.sq2_volume = 0;
ctx.sq2_sample = 0;
ctx.sq2_period_reset = 0;
ctx.sq2_period_timer = 0;
ctx.sq2_enable = 0;
ctx.sq2_len_enable = 0;
ctx.sq2_initial_len = 0;
ctx.sq2_len = 0;
ctx.sq2_initial_volume = 0;
ctx.sq2_env_direction = 0;
ctx.sq2_env_direction_buffer = 0;
ctx.sq2_env_pace = 0;
ctx.sq2_env_pace_buffer = 0;
ctx.sq2_env_timer = 0;
ctx.ch3_enable = 0;
ctx.ch3_dac = 0;
ctx.ch3_initial_len = 0;
ctx.ch3_len = 0;
ctx.ch3_volume = 0;
ctx.ch3_initial_volume = 0;
ctx.ch3_period_timer = 0;
ctx.ch3_period_reset = 0;
ctx.ch3_len_enable = 0;
ctx.ch3_last_sample = 0;
ctx.ch3_sample = 0;
ctx.ch4_enable = 0;
ctx.ch4_initial_len = 0;
ctx.ch4_len = 0;
ctx.ch4_initial_volume = 0;
ctx.ch4_volume = 0;
ctx.ch4_env_pace = 0;
ctx.ch4_env_pace_buffer = 0;
ctx.ch4_env_timer = 0;
ctx.ch4_env_direction = 0;
ctx.ch4_env_direction_buffer = 0;
ctx.ch4_clock_shift = 0;
ctx.ch4_lfsr_width = 0;
ctx.ch4_clock_divider = 0;
ctx.ch4_len_enable = 0;
ctx.ch4_lfsr = 0;
} }
void audio_write(u16 address, u8 value){ void audio_write(u16 address, u8 value){
if(BETWEEN(address, 0xFF30, 0xFF3F)) {
ctx.wave_ram[address - 0xFF30] = value;
}
if(address == 0xFF26) { if(address == 0xFF26) {
ctx.audio_enabled = value & 0x80; ctx.audio_enabled = value & 0x80;
if(!ctx.audio_enabled) {
reset_buffers();
} }
}
if(!ctx.audio_enabled){
return;
}
if(address == 0xFF25) { if(address == 0xFF25) {
ctx.ch4_left = value & 0b10000000; ctx.ch4_left = value & 0b10000000;
ctx.ch3_left = value & 0b01000000; ctx.ch3_left = value & 0b01000000;
@ -441,9 +646,11 @@ void audio_write(u16 address, u8 value){
if(address == 0xFF24) { if(address == 0xFF24) {
ctx.volume_left = (value >> 4) & 0b111; ctx.volume_left = (value >> 4) & 0b111;
if(ctx.volume_left == 0) ctx.volume_left = 1; //if(ctx.volume_left == 0) ctx.volume_left = 1;
ctx.volume_right = value & 0b111; ctx.volume_right = value & 0b111;
if(ctx.volume_right == 0) ctx.volume_right = 1; //if(ctx.volume_right == 0) ctx.volume_right = 1;
ctx.vin_left = value & 0x80;
ctx.vin_right = value & 0x8;
} }
if(address == 0xFF10) { if(address == 0xFF10) {
@ -454,10 +661,12 @@ void audio_write(u16 address, u8 value){
if(address == 0xFF11) { if(address == 0xFF11) {
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;
printf("initial len: %02X\n", ctx.sq1_initial_len);
} }
if(address == 0xFF12) { if(address == 0xFF12) {
ctx.sq1_initial_volume = (value >> 4) & 0x0F; ctx.sq1_initial_volume = (value >> 4) & 0x0F;
ctx.sq1_env_direction_buffer = (value & 0x8) == 0x80; ctx.sq1_env_direction_buffer = (value & 0x8) == 0x8;
ctx.sq1_env_pace_buffer = value & 0b111; ctx.sq1_env_pace_buffer = value & 0b111;
} }
if(address == 0xFF13) { if(address == 0xFF13) {
@ -475,10 +684,11 @@ void audio_write(u16 address, u8 value){
if(address == 0xFF16) { if(address == 0xFF16) {
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;
} }
if(address == 0xFF17) { if(address == 0xFF17) {
ctx.sq2_initial_volume = (value >> 4) & 0x0F; ctx.sq2_initial_volume = (value >> 4) & 0x0F;
ctx.sq2_env_direction_buffer = (value & 0x8) == 0x80; ctx.sq2_env_direction_buffer = (value & 0x8) == 0x8;
ctx.sq2_env_pace_buffer = value & 0b111; ctx.sq2_env_pace_buffer = value & 0b111;
if(ctx.sq2_env_direction == 0 && ctx.sq2_initial_volume == 0) { if(ctx.sq2_env_direction == 0 && ctx.sq2_initial_volume == 0) {
ctx.sq2_enable = false; ctx.sq2_enable = false;
@ -498,11 +708,15 @@ void audio_write(u16 address, u8 value){
} }
if(address == 0xFF1A) { if(address == 0xFF1A) {
//ctx.ch3_enable = (value & 0x80) == 0x80; ctx.ch3_dac = value & 0x80;
if(!ctx.ch3_dac){
ctx.ch3_enable = false;
}
} }
if(address == 0xFF1B) { if(address == 0xFF1B) {
ctx.ch3_initial_len = value; ctx.ch3_initial_len = value;
ctx.ch3_len = ctx.ch3_initial_len;
} }
if(address == 0xFF1C) { if(address == 0xFF1C) {
@ -523,11 +737,12 @@ 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;
} }
if(address == 0xFF21) { if(address == 0xFF21) {
ctx.ch4_initial_volume = (value >> 4) & 0x0F; ctx.ch4_initial_volume = (value >> 4) & 0x0F;
ctx.ch4_env_direction_buffer = (value & 0x8) == 0x80; ctx.ch4_env_direction_buffer = (value & 0x8) == 0x8;
ctx.ch4_env_pace_buffer = value & 0b111; ctx.ch4_env_pace_buffer = value & 0b111;
} }
@ -546,8 +761,4 @@ void audio_write(u16 address, u8 value){
enable_noise(); enable_noise();
} }
} }
if(BETWEEN(address, 0xFF30, 0xFF3F)) {
ctx.wave_ram[address - 0xFF30] = value;
}
} }