mirror of
https://github.com/MiSTer-devel/Main_MiSTer.git
synced 2026-04-12 03:04:02 +00:00
- 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
170 lines
3.1 KiB
C++
170 lines
3.1 KiB
C++
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <inttypes.h>
|
|
|
|
#include "../../file_io.h"
|
|
#include "../../user_io.h"
|
|
#include "../../spi.h"
|
|
#include "../../hardware.h"
|
|
#include "../../menu.h"
|
|
#include "../../cheats.h"
|
|
#include "../megacd/megacd.h"
|
|
#include "neogeocd.h"
|
|
#include "neogeo_loader.h"
|
|
|
|
static int need_reset=0;
|
|
static uint8_t has_command = 0;
|
|
static uint8_t neo_cd_en = 0;
|
|
static uint32_t poll_timer = 0;
|
|
static uint8_t cd_speed = 0;
|
|
|
|
#define CRC_START 5
|
|
|
|
#define NEOCD_GET_CMD 0
|
|
#define NEOCD_GET_SEND_DATA 1
|
|
|
|
void neocd_poll()
|
|
{
|
|
static uint8_t last_req = 255;
|
|
|
|
if (!poll_timer || CheckTimer(poll_timer))
|
|
{
|
|
|
|
set_poll_timer();
|
|
|
|
if (has_command) {
|
|
spi_uio_cmd_cont(UIO_CD_SET);
|
|
uint64_t s = cdd.GetStatus(CRC_START);
|
|
spi_w((s >> 0) & 0xFFFF);
|
|
spi_w((s >> 16) & 0xFFFF);
|
|
spi_w((s >> 32) & 0x00FF);
|
|
DisableIO();
|
|
|
|
has_command = 0;
|
|
|
|
//printf("\x1b[32mNEOCD: Send status, status = %04X%04X%04X \n\x1b[0m", (uint16_t)((s >> 32) & 0x00FF), (uint16_t)((s >> 16) & 0xFFFF), (uint16_t)((s >> 0) & 0xFFFF));
|
|
}
|
|
|
|
cdd.Update();
|
|
}
|
|
|
|
|
|
uint8_t req = spi_uio_cmd_cont(UIO_CD_GET);
|
|
|
|
if (req != last_req)
|
|
{
|
|
last_req = req;
|
|
|
|
spi_w(NEOCD_GET_CMD);
|
|
|
|
uint16_t data_in[4];
|
|
data_in[0] = spi_w(0);
|
|
data_in[1] = spi_w(0);
|
|
data_in[2] = spi_w(0);
|
|
DisableIO();
|
|
|
|
if (need_reset || data_in[0] == 0xFF) {
|
|
printf("NEOCD: request to reset\n");
|
|
need_reset = 0;
|
|
cdd.Reset();
|
|
}
|
|
|
|
cd_speed = (data_in[2] >> 8) & 3;
|
|
|
|
uint64_t c = *((uint64_t*)(data_in));
|
|
cdd.SetCommand(c, CRC_START);
|
|
cdd.CommandExec();
|
|
has_command = 1;
|
|
|
|
//printf("\x1b[32mNEOCD: Get command, command = %04X%04X%04X, has_command = %u\n\x1b[0m", data_in[2], data_in[1], data_in[0], has_command);
|
|
}
|
|
else
|
|
DisableIO();
|
|
}
|
|
|
|
void set_poll_timer()
|
|
{
|
|
int speed = cd_speed;
|
|
int interval = 10; // Slightly faster so the buffers stay filled when playing
|
|
|
|
if (!cdd.isData || cdd.status != CD_STAT_PLAY || cdd.latency != 0)
|
|
{
|
|
speed = 0;
|
|
}
|
|
|
|
if (speed == 1)
|
|
{
|
|
interval = 5;
|
|
}
|
|
else if (speed == 2)
|
|
{
|
|
interval = 4;
|
|
}
|
|
else if (speed == 3)
|
|
{
|
|
interval = 2;
|
|
}
|
|
|
|
poll_timer = GetTimer(interval);
|
|
}
|
|
|
|
void neocd_set_image(char *filename)
|
|
{
|
|
cdd.Unload();
|
|
cdd.status = CD_STAT_OPEN;
|
|
|
|
if (*filename)
|
|
{
|
|
neogeo_romset_tx(filename, 1);
|
|
|
|
if (cdd.Load(filename) > 0)
|
|
{
|
|
cdd.status = cdd.loaded ? CD_STAT_STOP : CD_STAT_NO_DISC;
|
|
cdd.latency = 10;
|
|
cdd.SendData = neocd_send_data;
|
|
cdd.CanSendData = neocd_can_send_data;
|
|
}
|
|
else
|
|
{
|
|
cdd.status = CD_STAT_NO_DISC;
|
|
}
|
|
}
|
|
|
|
neocd_reset();
|
|
}
|
|
|
|
void neocd_reset() {
|
|
need_reset = 1;
|
|
}
|
|
|
|
int neocd_send_data(uint8_t* buf, int len, uint8_t index) {
|
|
// set index byte
|
|
user_io_set_index(index);
|
|
|
|
user_io_set_download(1);
|
|
user_io_file_tx_data(buf, len);
|
|
user_io_set_download(0);
|
|
return 1;
|
|
}
|
|
|
|
int neocd_is_en() {
|
|
return (neo_cd_en == 1);
|
|
}
|
|
|
|
void neocd_set_en(int enable) {
|
|
neo_cd_en = enable;
|
|
}
|
|
|
|
int neocd_can_send_data(uint8_t type) {
|
|
// Ask the FPGA if it is ready to receive a sector
|
|
spi_uio_cmd_cont(UIO_CD_GET);
|
|
spi_w(NEOCD_GET_SEND_DATA | (type << 2));
|
|
|
|
uint16_t data = spi_w(0);
|
|
DisableIO();
|
|
|
|
return (data == 1);
|
|
}
|