From 53f1ca18e8c4168915f10c250c023124bbcd1672 Mon Sep 17 00:00:00 2001 From: paulb-nl Date: Mon, 10 Jul 2023 21:41:14 +0200 Subject: [PATCH] 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 --- support/megacd/megacd.cpp | 32 +++++++++++++++++++++++++++++--- support/megacd/megacd.h | 2 ++ support/megacd/megacdd.cpp | 8 +++++++- support/neogeo/neogeocd.cpp | 13 +------------ 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/support/megacd/megacd.cpp b/support/megacd/megacd.cpp index 70b2135..d64e2c7 100644 --- a/support/megacd/megacd.cpp +++ b/support/megacd/megacd.cpp @@ -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); +} diff --git a/support/megacd/megacd.h b/support/megacd/megacd.h index 8475b65..1ced67f 100644 --- a/support/megacd/megacd.h +++ b/support/megacd/megacd.h @@ -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 @@ -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 diff --git a/support/megacd/megacdd.cpp b/support/megacd/megacdd.cpp index f9eda47..257aed7 100644 --- a/support/megacd/megacdd.cpp +++ b/support/megacd/megacdd.cpp @@ -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; } diff --git a/support/neogeo/neogeocd.cpp b/support/neogeo/neogeocd.cpp index fd68963..7dce841 100644 --- a/support/neogeo/neogeocd.cpp +++ b/support/neogeo/neogeocd.cpp @@ -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);