ref: 23948daf66d70fd666f2b0da138f3dfec25a92e4
parent: 6c85f2833023e575b3a4678c687f650be2d8bbeb
author: allkern <lisandroaalarcon@gmail.com>
date: Thu May 9 17:46:43 EDT 2024
Improved T2 IRQ emulation Implemented CDROM volume registers
--- a/psx/dev/cdrom.c
+++ b/psx/dev/cdrom.c
@@ -1678,23 +1678,30 @@
}
void cdrom_write_lcdlspuv(psx_cdrom_t* cdrom, uint8_t value) {
- log_fatal("Volume registers unimplemented");
+ cdrom->vapp[0] = value;
}
void cdrom_write_rcdrspuv(psx_cdrom_t* cdrom, uint8_t value) {
- log_fatal("Volume registers unimplemented");
+ cdrom->vapp[3] = value;
}
void cdrom_write_rcdlspuv(psx_cdrom_t* cdrom, uint8_t value) {
- log_fatal("Volume registers unimplemented");
+ cdrom->vapp[2] = value;
}
void cdrom_write_lcdrspuv(psx_cdrom_t* cdrom, uint8_t value) {
- log_fatal("Volume registers unimplemented");
+ cdrom->vapp[1] = value;
}
void cdrom_write_volume(psx_cdrom_t* cdrom, uint8_t value) {
- log_fatal("Volume registers unimplemented");
+ cdrom->xa_mute = value & 1;
+
+ if (value & 0x20) {
+ cdrom->vol[0] = cdrom->vapp[0];
+ cdrom->vol[1] = cdrom->vapp[1];
+ cdrom->vol[2] = cdrom->vapp[2];
+ cdrom->vol[3] = cdrom->vapp[3];
+ }
}
psx_cdrom_read_function_t g_psx_cdrom_read_table[] = {
@@ -2120,6 +2127,20 @@
}
}
+void cdrom_apply_volume_settings(psx_cdrom_t* cdrom) {
+ int16_t* ptr = cdrom->cdda_buf;
+
+ float ll_vol = (((float)cdrom->vol[0]) / 255.0f);
+ float lr_vol = (((float)cdrom->vol[1]) / 255.0f);
+ float rl_vol = (((float)cdrom->vol[2]) / 255.0f);
+ float rr_vol = (((float)cdrom->vol[3]) / 255.0f);
+
+ for (int i = 0; i < CD_SECTOR_SIZE >> 1; i += 2) {
+ ptr[i ] = ptr[i ] * ll_vol + ptr[i+1] * rl_vol;
+ ptr[i+1] = ptr[i+1] * rr_vol + ptr[i ] * lr_vol;
+ }
+}
+
void psx_cdrom_get_cdda_samples(psx_cdrom_t* cdrom, void* buf, int size, psx_spu_t* spu) {
memset(buf, 0, size);
@@ -2162,18 +2183,31 @@
cdrom->xa_sample_idx = 0;
}
+ if (cdrom->xa_mute) {
+ *ptr++ = 0;
+ *ptr++ = 0;
+
+ return;
+ }
+
+ float ll_vol = (((float)cdrom->vol[0]) / 255.0f);
+ float rr_vol = (((float)cdrom->vol[3]) / 255.0f);
+
if (stereo) {
cdrom->xa_last_left_sample = cdrom->xa_left_resample_buf[cdrom->xa_sample_idx];
cdrom->xa_last_right_sample = cdrom->xa_right_resample_buf[cdrom->xa_sample_idx++];
- *ptr++ = cdrom->xa_last_left_sample;
- *ptr++ = cdrom->xa_last_right_sample;
+ float lr_vol = (((float)cdrom->vol[1]) / 255.0f);
+ float rl_vol = (((float)cdrom->vol[2]) / 255.0f);
+ *ptr++ = (cdrom->xa_last_left_sample * ll_vol) + (cdrom->xa_last_right_sample * rl_vol);
+ *ptr++ = (cdrom->xa_last_left_sample * lr_vol) + (cdrom->xa_last_right_sample * rr_vol);
+
} else {
cdrom->xa_last_mono_sample = cdrom->xa_mono_resample_buf[cdrom->xa_sample_idx++];
- *ptr++ = cdrom->xa_last_mono_sample;
- *ptr++ = cdrom->xa_last_mono_sample;
+ *ptr++ = cdrom->xa_last_mono_sample * ll_vol;
+ *ptr++ = cdrom->xa_last_mono_sample * rr_vol;
}
--cdrom->xa_remaining_samples;
@@ -2198,6 +2232,8 @@
// Increment sector
msf_add_f(&cdrom->cdda_msf, 1);
+
+ cdrom_apply_volume_settings(cdrom);
memcpy(buf, cdrom->cdda_buf, size);
--- a/psx/dev/cdrom.h
+++ b/psx/dev/cdrom.h
@@ -211,6 +211,7 @@
uint8_t* xa_sector_buf;
msf_t xa_msf;
int xa_playing;
+ int xa_mute;
uint8_t xa_file;
uint8_t xa_channel;
uint8_t xa_coding;
@@ -231,6 +232,8 @@
int16_t xa_last_left_sample;
int16_t xa_last_right_sample;
int16_t xa_last_mono_sample;
+ uint8_t vol[4];
+ uint8_t vapp[4];
const char* path;
psx_disc_t* disc;
--- a/psx/dev/gpu.c
+++ b/psx/dev/gpu.c
@@ -1752,6 +1752,23 @@
gpu->gpustat &= ~(1 << 31);
}
+ // HACK!! More games are fine with this
+ // but others, like Dead or Alive, will refuse
+ // to boot because this frequency is not fast
+ // enough. Sending T2 IRQs every line fixes DoA
+ // but breaks a bunch of games, so I'll keep this
+ // like this until I actually fix the timers
+ // Games that cared about T2:
+ // - Dead or Alive
+ // - NBA Jam
+ // - Doom
+ // - Devil Dice
+ // - Zanac x Zanac
+ // - Soukyugurentai
+ // - Mortal Kombat
+ // - PaRappa the Rapper
+ // - In The Hunt
+ // - etc.
if (!(gpu->line & 7))
psx_ic_irq(gpu->ic, IC_TIMER2);
} else {
--
⑨