NeoGeo CD updates (#787)
- Add Unibios and CDZ support - Ask FPGA before sending sector - 1-4x CD speed
This commit is contained in:
2
menu.cpp
2
menu.cpp
@@ -2269,7 +2269,7 @@ void HandleUI(void)
|
||||
if (fs_Options & SCANO_NEOGEO)
|
||||
{
|
||||
neocd_set_en(0);
|
||||
neogeo_romset_tx(selPath);
|
||||
neogeo_romset_tx(selPath, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -153,6 +153,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;
|
||||
|
||||
if (!same_game)
|
||||
{
|
||||
|
||||
@@ -49,6 +49,7 @@ public:
|
||||
uint8_t isData;
|
||||
int loaded;
|
||||
SendDataFunc SendData;
|
||||
int (*CanSendData)(uint8_t type);
|
||||
|
||||
cdd_t();
|
||||
int Load(const char *filename);
|
||||
@@ -79,7 +80,7 @@ private:
|
||||
int SubcodeSend();
|
||||
void ReadData(uint8_t *buf);
|
||||
int ReadCDDA(uint8_t *buf);
|
||||
void ReadSubcode(uint16_t* buf);
|
||||
int ReadSubcode(uint16_t* buf);
|
||||
void LBAToMSF(int lba, msf_t* msf);
|
||||
void MSFToLBA(int* lba, msf_t* msf);
|
||||
void MSFToLBA(int* lba, uint8_t m, uint8_t s, uint8_t f);
|
||||
|
||||
@@ -23,6 +23,7 @@ cdd_t::cdd_t() {
|
||||
chd_hunkbuf = NULL;
|
||||
chd_hunknum = -1;
|
||||
SendData = NULL;
|
||||
CanSendData = NULL;
|
||||
|
||||
stat[0] = 0xB;
|
||||
stat[1] = 0x0;
|
||||
@@ -371,7 +372,12 @@ void cdd_t::Update() {
|
||||
this->latency--;
|
||||
return;
|
||||
}
|
||||
this->status = this->loaded ? CD_STAT_TOC : CD_STAT_NO_DISC;
|
||||
// Neo Geo CDZ does not like the status changing to TOC here.
|
||||
//this->status = this->loaded ? CD_STAT_TOC : CD_STAT_NO_DISC;
|
||||
if (!this->loaded)
|
||||
{
|
||||
this->status = CD_STAT_NO_DISC;
|
||||
}
|
||||
}
|
||||
else if (this->status == CD_STAT_SEEK)
|
||||
{
|
||||
@@ -396,6 +402,11 @@ void cdd_t::Update() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (CanSendData && !CanSendData(this->toc.tracks[this->index].type))
|
||||
{
|
||||
// Not ready yet to receive sector
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->toc.tracks[this->index].type)
|
||||
{
|
||||
@@ -409,7 +420,6 @@ void cdd_t::Update() {
|
||||
header[3] = 0x01;
|
||||
|
||||
SectorSend(header);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -551,6 +561,9 @@ void cdd_t::CommandExec() {
|
||||
break;
|
||||
|
||||
case CD_COMM_TOC:
|
||||
if (this->status == CD_STAT_STOP) {
|
||||
this->status = CD_STAT_TOC;
|
||||
}
|
||||
switch (comm[3]) {
|
||||
case 0: {
|
||||
int lba_ = this->lba + 150;
|
||||
@@ -980,8 +993,9 @@ void InterleaveSubcode(uint8_t *subc_data, uint16_t *buf)
|
||||
}
|
||||
}
|
||||
|
||||
void cdd_t::ReadSubcode(uint16_t* buf)
|
||||
int cdd_t::ReadSubcode(uint16_t* buf)
|
||||
{
|
||||
int err = 0;
|
||||
uint8_t subc[96];
|
||||
if (this->toc.chd_f)
|
||||
{
|
||||
@@ -991,11 +1005,17 @@ void cdd_t::ReadSubcode(uint16_t* buf)
|
||||
} else if (this->toc.tracks[this->index].sbc_type == SUBCODE_RW) {
|
||||
mister_chd_read_sector(this->toc.chd_f, this->chd_audio_read_lba + this->toc.tracks[this->index].offset, 0, CD_MAX_SECTOR_DATA, 96, subc, this->chd_hunkbuf, &this->chd_hunknum);
|
||||
InterleaveSubcode(subc, buf);
|
||||
} else {
|
||||
err = -1;
|
||||
}
|
||||
} else if (this->toc.sub.opened()) {
|
||||
FileReadAdv(&this->toc.sub, subc, 96);
|
||||
InterleaveSubcode(subc, buf);
|
||||
} else {
|
||||
err = -1;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -1024,9 +1044,9 @@ int cdd_t::SubcodeSend()
|
||||
{
|
||||
uint16_t buf[98 / 2];
|
||||
|
||||
ReadSubcode(buf);
|
||||
int err = ReadSubcode(buf);
|
||||
|
||||
if (SendData)
|
||||
if (!err && SendData)
|
||||
return SendData((uint8_t*)buf, 98, MCD_SUB_IO_INDEX);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1053,17 +1053,18 @@ void load_neo(char *path)
|
||||
}
|
||||
}
|
||||
|
||||
int neogeo_romset_tx(char* name)
|
||||
int neogeo_romset_tx(char* name, int cd_en)
|
||||
{
|
||||
char *romset = strrchr(name, '/');
|
||||
if (!romset) return 0;
|
||||
romset++;
|
||||
|
||||
int system_type;
|
||||
int system_mvs, system_cdz;
|
||||
static char full_path[1024];
|
||||
|
||||
system_type = user_io_status_get("[2:1]") & 3;
|
||||
printf("System type: %u\n", system_type);
|
||||
system_mvs = user_io_status_get("[1]") & 1;
|
||||
system_cdz = user_io_status_get("[2]") & 1;
|
||||
printf("System MVS: %u, CDZ: %u, CD: %u\n", system_mvs, system_cdz, cd_en);
|
||||
|
||||
spi_uio_cmd_cont(UIO_GET_OSDMASK);
|
||||
uint16_t mask = spi_w(0);
|
||||
@@ -1078,8 +1079,12 @@ int neogeo_romset_tx(char* name)
|
||||
|
||||
const char* home = HomeDir();
|
||||
|
||||
// Send cd_en to the FPGA before loading files
|
||||
set_config((cd_en & 1) << 31, 1 << 31);
|
||||
notify_conf();
|
||||
|
||||
// Look for the romset's file list in romsets.xml
|
||||
if (!(system_type & 2))
|
||||
if (!cd_en)
|
||||
{
|
||||
char *p = strrchr(name, '.');
|
||||
if (p && !strcasecmp(p, ".neo"))
|
||||
@@ -1118,31 +1123,36 @@ int neogeo_romset_tx(char* name)
|
||||
// Load system ROMs
|
||||
if (strcmp(romset, "debug")) {
|
||||
// Not loading the special 'debug' romset
|
||||
if (!(system_type & 2)) {
|
||||
if (!cd_en) {
|
||||
sprintf(full_path, "%s/uni-bios.rom", home);
|
||||
if (!(mask & 0x8000) && FileExists(full_path)) {
|
||||
// Autoload Unibios for cart systems if present
|
||||
neogeo_tx(home, "uni-bios.rom", NEO_FILE_RAW, 0, 0, 0x20000);
|
||||
} else {
|
||||
// Otherwise load normal system roms
|
||||
if (system_type == 0)
|
||||
if (!system_mvs)
|
||||
neogeo_tx(home, "neo-epo.sp1", NEO_FILE_RAW, 0, 0, 0x20000);
|
||||
else
|
||||
neogeo_tx(home, "sp-s2.sp1", NEO_FILE_RAW, 0, 0, 0x20000);
|
||||
}
|
||||
} else if (system_type == 2) {
|
||||
// NeoGeo CD
|
||||
neogeo_tx(home, "top-sp1.bin", NEO_FILE_RAW, 0, 0, 0x80000);
|
||||
} else {
|
||||
// NeoGeo CDZ
|
||||
neogeo_tx(home, "neocd.bin", NEO_FILE_RAW, 0, 0, 0x80000);
|
||||
sprintf(full_path, "%s/uni-bioscd.rom", home);
|
||||
if (!(mask & 0x8000) && FileExists(full_path)) {
|
||||
neogeo_tx(home, "uni-bioscd.rom", NEO_FILE_RAW, 0, 0, 0x80000);
|
||||
} else if (!system_cdz) {
|
||||
// NeoGeo CD
|
||||
neogeo_tx(home, "top-sp1.bin", NEO_FILE_RAW, 0, 0, 0x80000);
|
||||
} else {
|
||||
// NeoGeo CDZ
|
||||
neogeo_tx(home, "neocd.bin", NEO_FILE_RAW, 0, 0, 0x80000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//flush CROM if any.
|
||||
neogeo_tx(NULL, NULL, 0, -1, 0, 0);
|
||||
|
||||
if (!(system_type & 2)) neogeo_tx(home, "sfix.sfix", NEO_FILE_FIX, 2, 0, 0);
|
||||
if (!cd_en) neogeo_tx(home, "sfix.sfix", NEO_FILE_FIX, 2, 0, 0);
|
||||
neogeo_file_tx(home, "000-lo.lo", NEO_FILE_8BIT, 1, 0, 0x10000);
|
||||
|
||||
if (crom_start < 0x300000) crom_start = 0x300000;
|
||||
@@ -1156,7 +1166,7 @@ int neogeo_romset_tx(char* name)
|
||||
|
||||
notify_conf();
|
||||
|
||||
FileGenerateSavePath((system_type & 2) ? "ngcd" : name, (char*)full_path);
|
||||
FileGenerateSavePath(cd_en ? "ngcd" : name, (char*)full_path);
|
||||
user_io_file_mount((char*)full_path, 0, 1);
|
||||
|
||||
user_io_status_set("[0]", 0); // Release reset
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
#define NEO_FILE_FIX 2
|
||||
#define NEO_FILE_SPR 3
|
||||
|
||||
int neogeo_romset_tx(char* name);
|
||||
int neogeo_romset_tx(char* name, int cd_en);
|
||||
int neogeo_scan_xml(char *path);
|
||||
char *neogeo_get_altname(char *path, char *name, char *altname);
|
||||
|
||||
@@ -17,21 +17,24 @@
|
||||
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_AUDIO_IO_INDEX 4
|
||||
|
||||
#define NEOCD_GET_CMD 0
|
||||
#define NEOCD_GET_SEND_DATA 1
|
||||
|
||||
void neocd_poll()
|
||||
{
|
||||
static uint32_t poll_timer = 0;
|
||||
static uint8_t last_req = 255;
|
||||
static uint8_t adj = 0;
|
||||
|
||||
if (!poll_timer || CheckTimer(poll_timer))
|
||||
{
|
||||
poll_timer = GetTimer(13 + (!adj ? 1 : 0));
|
||||
if (++adj >= 3) adj = 0;
|
||||
|
||||
set_poll_timer();
|
||||
|
||||
if (has_command) {
|
||||
spi_uio_cmd_cont(UIO_CD_SET);
|
||||
@@ -56,6 +59,8 @@ void neocd_poll()
|
||||
{
|
||||
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);
|
||||
@@ -68,6 +73,8 @@ void neocd_poll()
|
||||
cdd.Reset();
|
||||
}
|
||||
|
||||
cd_speed = (data_in[2] >> 8) & 3;
|
||||
|
||||
uint64_t c = *((uint64_t*)(data_in));
|
||||
cdd.SetCommand(c, CRC_START);
|
||||
cdd.CommandExec();
|
||||
@@ -79,6 +86,32 @@ void neocd_poll()
|
||||
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();
|
||||
@@ -86,13 +119,14 @@ void neocd_set_image(char *filename)
|
||||
|
||||
if (*filename)
|
||||
{
|
||||
neogeo_romset_tx(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
|
||||
{
|
||||
@@ -133,3 +167,14 @@ int neocd_is_en() {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ void neocd_poll();
|
||||
void neocd_set_image(char *filename);
|
||||
void neocd_reset();
|
||||
int neocd_send_data(uint8_t* buf, int len, uint8_t index);
|
||||
int neocd_can_send_data(uint8_t type);
|
||||
int neocd_is_en();
|
||||
void neocd_set_en(int enable);
|
||||
void set_poll_timer();
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user