ref: 6d3047e01b59cc63a1f51db845d9bb091a95fd1e
parent: 716b378886c95a13f065faf063528d62046fb609
author: allkern <lisandroaalarcon@gmail.com>
date: Thu Dec 21 07:28:20 EST 2023
Implement mono XA-ADPCM
--- a/psx/dev/cdrom.c
+++ b/psx/dev/cdrom.c
@@ -1203,8 +1203,16 @@
cdrom->xa_channel
);
- cdrom->state = CD_STATE_RECV_CMD;
- cdrom->delayed_command = CDL_NONE;
+ int double_speed = cdrom->mode & MODE_SPEED;
+
+ cdrom->irq_delay = double_speed ? READ_DOUBLE_DELAY : READ_SINGLE_DELAY;
+ cdrom->state = CD_STATE_SEND_RESP2;
+ cdrom->delayed_command = CDL_READS;
+
+ if (cdrom->spin_delay) {+ cdrom->irq_delay += cdrom->spin_delay;
+ cdrom->spin_delay = 0;
+ }
}
int err = psx_disc_seek(cdrom->disc, msf);
@@ -1220,7 +1228,7 @@
return;
}
-
+
int double_speed = cdrom->mode & MODE_SPEED;
cdrom->irq_delay = double_speed ? READ_DOUBLE_DELAY : READ_SINGLE_DELAY;
@@ -1262,6 +1270,20 @@
cdrom->delayed_command = CDL_READS;
cdrom->dfifo_index = 0;
+ if (cdrom->mode & MODE_XA_ADPCM) {+ int double_speed = cdrom->mode & MODE_SPEED;
+
+ if (cdrom->dfifo[0x12] & 4) {+ cdrom->irq_delay = 10;
+ cdrom->irq_delay = double_speed ? READ_DOUBLE_DELAY : READ_SINGLE_DELAY;
+ cdrom->state = CD_STATE_SEND_RESP2;
+ cdrom->delayed_command = CDL_READS;
+ // cdrom->irq_disable = 1;
+
+ return;
+ }
+ }
+
SET_BITS(ifr, IFR_INT, IFR_INT1);
RESP_PUSH(GETSTAT_MOTOR | GETSTAT_READ);
} break;
@@ -1538,9 +1560,10 @@
cdrom->xa_left_buf = malloc(XA_STEREO_SAMPLES * sizeof(int16_t));
cdrom->xa_right_buf = malloc(XA_STEREO_SAMPLES * sizeof(int16_t));
cdrom->xa_mono_buf = malloc(XA_MONO_SAMPLES * sizeof(int16_t));
- cdrom->xa_upsample_buf = malloc((14112 + 6) * sizeof(int16_t));
+ cdrom->xa_upsample_buf = malloc(((14112 * 2) + 6) * sizeof(int16_t));
cdrom->xa_left_resample_buf = malloc(2352 * sizeof(int16_t));
cdrom->xa_right_resample_buf = malloc(2352 * sizeof(int16_t));
+ cdrom->xa_mono_resample_buf = malloc(XA_MONO_RESAMPLE_SIZE * sizeof(int16_t));
cdrom->xa_step = 6;
// We will use this whenever we implement proper
@@ -1550,9 +1573,10 @@
memset(cdrom->xa_left_buf, 0, XA_STEREO_SAMPLES * sizeof(int16_t));
memset(cdrom->xa_right_buf, 0, XA_STEREO_SAMPLES * sizeof(int16_t));
memset(cdrom->xa_mono_buf, 0, XA_MONO_SAMPLES * sizeof(int16_t));
- memset(cdrom->xa_upsample_buf, 0, (14112 + 6) * sizeof(int16_t));
+ memset(cdrom->xa_upsample_buf, 0, ((14112 * 2) + 6) * sizeof(int16_t));
memset(cdrom->xa_left_resample_buf, 0, 2352 * sizeof(int16_t));
memset(cdrom->xa_right_resample_buf, 0, 2352 * sizeof(int16_t));
+ memset(cdrom->xa_mono_resample_buf, 0, XA_MONO_RESAMPLE_SIZE * sizeof(int16_t));
}
uint32_t psx_cdrom_read32(psx_cdrom_t* cdrom, uint32_t offset) {@@ -1613,7 +1637,11 @@
cdrom->irq_delay -= cyc;
if (cdrom->irq_delay <= 0) {- psx_ic_irq(cdrom->ic, IC_CDROM);
+ if (!cdrom->irq_disable) {+ psx_ic_irq(cdrom->ic, IC_CDROM);
+ } else {+ cdrom->irq_disable = 0;
+ }
cdrom->irq_delay = 0;
@@ -1755,11 +1783,30 @@
0, 0, -52, -55, -60
};
-void cdrom_resample_xa_buf(psx_cdrom_t* cdrom, int16_t* dst, int16_t* src) {- // To-do: Account for 18KHz samples and mono
+void cdrom_resample_xa_buf(psx_cdrom_t* cdrom, int16_t* dst, int16_t* src, int stereo) {+ // To-do: Account for 18KHz samples
// int f18khz = ((cdrom->xa_sector_buf[0x13] >> 2) & 1) == 1;
- for (int i = 0; i < XA_STEREO_SAMPLES; i++) {+ if (stereo) {+ for (int i = 0; i < XA_STEREO_SAMPLES; i++) {+ int j = i * 7;
+
+ cdrom->xa_upsample_buf[j] = src[i];
+
+ // Nearest neighbor
+ for (int k = 0; k < 7; k++)
+ cdrom->xa_upsample_buf[j+k] = src[i];
+ }
+
+ for (int i = 0; i < XA_STEREO_RESAMPLE_SIZE; i++)
+ dst[i] = cdrom->xa_upsample_buf[i*6];
+
+ cdrom->xa_remaining_samples = XA_STEREO_RESAMPLE_SIZE;
+
+ return;
+ }
+
+ for (int i = 0; i < XA_MONO_SAMPLES; i++) {int j = i * 7;
cdrom->xa_upsample_buf[j] = src[i];
@@ -1769,10 +1816,10 @@
cdrom->xa_upsample_buf[j+k] = src[i];
}
- for (int i = 0; i < 2352; i++)
+ for (int i = 0; i < XA_MONO_RESAMPLE_SIZE; i++)
dst[i] = cdrom->xa_upsample_buf[i*6];
- cdrom->xa_remaining_samples = 2352;
+ cdrom->xa_remaining_samples = XA_MONO_RESAMPLE_SIZE;
}
void cdrom_decode_xa_block(psx_cdrom_t* cdrom, int idx, int blk, int nib, int16_t* buf, int16_t* h) {@@ -1878,17 +1925,41 @@
int16_t* ptr = (int16_t*)buf;
for (int i = 0; i < (size >> 2); i++) {+ int stereo = (cdrom->xa_sector_buf[0x13] & 1) == 1;
+
if (!cdrom->xa_remaining_samples) {cdrom_fetch_xa_sector(cdrom);
+
+ if (cdrom->xa_sector_buf[0x12] & 0x80) {+ SET_BITS(status, STAT_ADPBUSY_MASK, 0);
+
+ cdrom->xa_playing = 0;
+ cdrom->xa_remaining_samples = 0;
+
+ return;
+ }
+
+ stereo = (cdrom->xa_sector_buf[0x13] & 1) == 1;
+
cdrom_decode_xa_sector(cdrom, buf);
- cdrom_resample_xa_buf(cdrom, cdrom->xa_left_resample_buf, cdrom->xa_left_buf);
- cdrom_resample_xa_buf(cdrom, cdrom->xa_right_resample_buf, cdrom->xa_right_buf);
+ if (stereo) {+ cdrom_resample_xa_buf(cdrom, cdrom->xa_left_resample_buf, cdrom->xa_left_buf, stereo);
+ cdrom_resample_xa_buf(cdrom, cdrom->xa_right_resample_buf, cdrom->xa_right_buf, stereo);
+ } else {+ cdrom_resample_xa_buf(cdrom, cdrom->xa_mono_resample_buf, cdrom->xa_mono_buf, stereo);
+ }
+
cdrom->xa_sample_idx = 0;
}
- *ptr++ = cdrom->xa_left_resample_buf[(cdrom->xa_sample_idx) % 2352];
- *ptr++ = cdrom->xa_right_resample_buf[(cdrom->xa_sample_idx++) % 2352];
+ if (stereo) {+ *ptr++ = cdrom->xa_left_resample_buf[(cdrom->xa_sample_idx) % XA_STEREO_RESAMPLE_SIZE];
+ *ptr++ = cdrom->xa_right_resample_buf[(cdrom->xa_sample_idx++) % XA_STEREO_RESAMPLE_SIZE];
+ } else {+ *ptr++ = cdrom->xa_mono_resample_buf[(cdrom->xa_sample_idx) % XA_MONO_RESAMPLE_SIZE];
+ *ptr++ = cdrom->xa_mono_resample_buf[(cdrom->xa_sample_idx++) % XA_MONO_RESAMPLE_SIZE];
+ }
--cdrom->xa_remaining_samples;
}
--- a/psx/dev/cdrom.h
+++ b/psx/dev/cdrom.h
@@ -186,6 +186,7 @@
uint8_t mode;
int irq_delay;
+ int irq_disable;
uint8_t command;
uint8_t delayed_command;
uint8_t int_number;
@@ -218,8 +219,6 @@
int16_t* xa_decoded_buf;
int16_t* xa_left_ring_buf;
int16_t* xa_right_ring_buf;
- int16_t* xa_stereo_resample_buf;
- int16_t* xa_mono_resample_buf;
uint32_t xa_sample_idx;
int xa_remaining_samples;
uint32_t xa_step;
@@ -226,6 +225,7 @@
uint32_t xa_ringbuf_pos;
int16_t* xa_left_resample_buf;
int16_t* xa_right_resample_buf;
+ int16_t* xa_mono_resample_buf;
int16_t* xa_upsample_buf;
const char* path;
--- a/psx/dev/gpu.c
+++ b/psx/dev/gpu.c
@@ -116,13 +116,17 @@
uint16_t psx_gpu_read16(psx_gpu_t* gpu, uint32_t offset) { log_fatal("Unhandled 16-bit GPU read at offset %08x", offset);- exit(1);
+ return 0;
+
+ // exit(1);
}
uint8_t psx_gpu_read8(psx_gpu_t* gpu, uint32_t offset) { log_fatal("Unhandled 8-bit GPU read at offset %08x", offset);- exit(1);
+ return 0;
+
+ // exit(1);
}
int min(int x0, int x1) {@@ -1728,7 +1732,7 @@
}
void* psx_gpu_get_display_buffer(psx_gpu_t* gpu) {- return gpu->vram + (gpu->draw_x1 + (gpu->draw_y1 * 1024));
+ return gpu->vram + (gpu->disp_x + (gpu->disp_y * 1024));
}
void psx_gpu_destroy(psx_gpu_t* gpu) {--
⑨