megacdd: cd audio fixes (#788)

- Send audio sectors faster so buffer stays filled
- Ask FPGA if it is ready to receive a sector
- Fix SCAN with CHD files
- Fix missing start of audio by sending with separate index
This commit is contained in:
paulb-nl
2023-07-10 21:41:14 +02:00
committed by GitHub
parent 4cee92ac1a
commit 53f1ca18e8
4 changed files with 39 additions and 16 deletions

View File

@@ -14,6 +14,9 @@
#define SAVE_IO_INDEX 5 // fake download to trigger save loading
#define MCD_GET_CMD 0
#define MCD_GET_SEND_DATA 1
static int need_reset=0;
static uint8_t has_command = 0;
@@ -25,8 +28,14 @@ void mcd_poll()
if (!poll_timer || CheckTimer(poll_timer))
{
poll_timer = GetTimer(13 + (!adj ? 1 : 0));
if (++adj >= 3) adj = 0;
if (!cdd.isData && cdd.status == CD_STAT_PLAY && cdd.latency == 0) {
// Send audio sectors faster so buffer stays filled
poll_timer = GetTimer(10);
adj = 0;
} else {
poll_timer = GetTimer(13 + (!adj ? 1 : 0));
if (++adj >= 3) adj = 0;
}
if (has_command) {
spi_uio_cmd_cont(UIO_CD_SET);
@@ -50,6 +59,8 @@ void mcd_poll()
{
last_req = req;
spi_w(MCD_GET_CMD);
uint16_t data_in[4];
data_in[0] = spi_w(0);
data_in[1] = spi_w(0);
@@ -153,7 +164,7 @@ void mcd_set_image(int num, const char *filename)
cdd.status = cdd.loaded ? CD_STAT_STOP : CD_STAT_NO_DISC;
cdd.latency = 10;
cdd.SendData = mcd_send_data;
cdd.CanSendData = NULL;
cdd.CanSendData = mcd_can_send_data;
if (!same_game)
{
@@ -269,3 +280,18 @@ void mcd_fill_blanksave(uint8_t *buffer, uint32_t lba)
memset(buffer, 0, 512);
}
}
int mcd_can_send_data(uint8_t type) {
if (type == 1) {
return 1;
}
// Ask the FPGA if it is ready to receive a sector
spi_uio_cmd_cont(UIO_CD_GET);
spi_w(MCD_GET_SEND_DATA | (type << 2));
uint16_t data = spi_w(0);
DisableIO();
return (data == 1);
}

View File

@@ -37,6 +37,7 @@
#define MCD_DATA_IO_INDEX 2
#define MCD_SUB_IO_INDEX 3
#define MCD_CDDA_IO_INDEX 4
#include "../../cd.h"
#include <libchdr/chd.h>
@@ -99,6 +100,7 @@ void mcd_poll();
void mcd_set_image(int num, const char *filename);
void mcd_reset();
int mcd_send_data(uint8_t* buf, int len, uint8_t index);
int mcd_can_send_data(uint8_t type);
void mcd_fill_blanksave(uint8_t *buffer, uint32_t lba);
#endif

View File

@@ -459,6 +459,7 @@ void cdd_t::Update() {
else
{
this->lba = this->toc.end;
this->chd_audio_read_lba = this->lba;
this->status = CD_STAT_END;
this->isData = 0x01;
return;
@@ -477,6 +478,8 @@ void cdd_t::Update() {
}
}
this->chd_audio_read_lba = this->lba;
this->isData = this->toc.tracks[this->index].type;
if (this->toc.sub.opened()) FileSeek(&this->toc.sub, this->lba * 96, SEEK_SET);
@@ -613,6 +616,7 @@ void cdd_t::CommandExec() {
stat[8] = 0;
//printf("\x1b[32mMCD: Command TOC 2, index = %i, command = %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X, status = %02X%08X, frame = %u\n\x1b[0m", this->index, comm[9], comm[8], comm[7], comm[6], comm[5], comm[4], comm[3], comm[2], comm[1], comm[0], (uint32_t)(GetStatus() >> 32), (uint32_t)GetStatus(), frame);
}
break;
@@ -1023,18 +1027,20 @@ int cdd_t::SectorSend(uint8_t* header)
{
uint8_t buf[2352 + 2352];
int len = 2352;
uint8_t index = MCD_DATA_IO_INDEX;
if (header) {
memcpy(buf + 12, header, 4);
ReadData(buf + 16);
}
else {
index = MCD_CDDA_IO_INDEX;
len = ReadCDDA(buf);
}
SubcodeSend();
if (SendData)
return SendData(buf, len, MCD_DATA_IO_INDEX);
return SendData(buf, len, index);
return 0;
}

View File

@@ -22,8 +22,6 @@ static uint8_t cd_speed = 0;
#define CRC_START 5
#define NEOCD_AUDIO_IO_INDEX 4
#define NEOCD_GET_CMD 0
#define NEOCD_GET_SEND_DATA 1
@@ -142,17 +140,8 @@ void neocd_reset() {
}
int neocd_send_data(uint8_t* buf, int len, uint8_t index) {
uint8_t idx = index;
if (idx == MCD_DATA_IO_INDEX && !cdd.isData)
{
// The MegaCD core sends the isData bit through the status to differentiate between data/audio.
// This requires that more commands come in after the initial play command.
// NeoGeo does not always send another command so use another index for audio.
idx = NEOCD_AUDIO_IO_INDEX;
}
// set index byte
user_io_set_index(idx);
user_io_set_index(index);
user_io_set_download(1);
user_io_file_tx_data(buf, len);