pcecd: initial support.
This commit is contained in:
1
Makefile
1
Makefile
@@ -36,6 +36,7 @@ CPP_SRC = $(wildcard *.cpp) \
|
||||
$(wildcard ./support/neogeo/*.cpp) \
|
||||
$(wildcard ./support/arcade/*.cpp) \
|
||||
$(wildcard ./support/megacd/*.cpp) \
|
||||
$(wildcard ./support/pcecd/*.cpp) \
|
||||
$(wildcard ./support/c64/*.cpp) \
|
||||
lib/lodepng/lodepng.cpp
|
||||
|
||||
|
||||
@@ -86,6 +86,8 @@
|
||||
<ClCompile Include="support\minimig\minimig_fdd.cpp" />
|
||||
<ClCompile Include="support\minimig\minimig_hdd.cpp" />
|
||||
<ClCompile Include="support\neogeo\loader.cpp" />
|
||||
<ClCompile Include="support\pcecd\pcecd.cpp" />
|
||||
<ClCompile Include="support\pcecd\pcecdd.cpp" />
|
||||
<ClCompile Include="support\sharpmz\sharpmz.cpp" />
|
||||
<ClCompile Include="support\snes\snes.cpp" />
|
||||
<ClCompile Include="support\st\st_tos.cpp" />
|
||||
@@ -98,6 +100,7 @@
|
||||
<ClInclude Include="battery.h" />
|
||||
<ClInclude Include="bootcore.h" />
|
||||
<ClInclude Include="brightness.h" />
|
||||
<ClInclude Include="cd.h" />
|
||||
<ClInclude Include="cfg.h" />
|
||||
<ClInclude Include="charrom.h" />
|
||||
<ClInclude Include="cheats.h" />
|
||||
@@ -142,6 +145,7 @@
|
||||
<ClInclude Include="support\minimig\minimig_hdd.h" />
|
||||
<ClInclude Include="support\minimig\minimig_hdd_internal.h" />
|
||||
<ClInclude Include="support\neogeo\loader.h" />
|
||||
<ClInclude Include="support\pcecd\pcecd.h" />
|
||||
<ClInclude Include="support\sharpmz\sharpmz.h" />
|
||||
<ClInclude Include="support\snes\snes.h" />
|
||||
<ClInclude Include="support\st\st_tos.h" />
|
||||
|
||||
@@ -184,6 +184,12 @@
|
||||
<ClCompile Include="support\c64\c64.cpp">
|
||||
<Filter>Source Files\support</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="support\pcecd\pcecd.cpp">
|
||||
<Filter>Source Files\support</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="support\pcecd\pcecdd.cpp">
|
||||
<Filter>Source Files\support</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="battery.h">
|
||||
@@ -348,5 +354,11 @@
|
||||
<ClInclude Include="support\c64\c64.h">
|
||||
<Filter>Header Files\support</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="cd.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="support\pcecd\pcecd.h">
|
||||
<Filter>Header Files\support</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
31
cd.h
Normal file
31
cd.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef CD_H
|
||||
#define CD_H
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fileTYPE f;
|
||||
int offset;
|
||||
int start;
|
||||
int end;
|
||||
int type;
|
||||
} track_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int end;
|
||||
int last;
|
||||
track_t tracks[100];
|
||||
// fileTYPE sub;
|
||||
} toc_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t m;
|
||||
uint8_t s;
|
||||
uint8_t f;
|
||||
} msf_t;
|
||||
|
||||
|
||||
typedef int (*SendDataFunc) (uint8_t* buf, int len, uint8_t index);
|
||||
|
||||
#endif
|
||||
6
menu.cpp
6
menu.cpp
@@ -1758,6 +1758,10 @@ void HandleUI(void)
|
||||
}
|
||||
mcd_set_image(ioctl_index, SelectedPath);
|
||||
}
|
||||
else if (is_pce())
|
||||
{
|
||||
pcecd_set_image(ioctl_index, SelectedPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
user_io_set_index(user_io_ext_idx(SelectedPath, fs_pFileExt) << 6 | (menusub + 1));
|
||||
@@ -3545,7 +3549,7 @@ void HandleUI(void)
|
||||
char type = flist_SelectedItem()->de.d_type;
|
||||
memcpy(name, flist_SelectedItem()->de.d_name, sizeof(name));
|
||||
|
||||
if ((fs_Options & SCANO_UMOUNT) && is_megacd() && type == DT_DIR && strcmp(flist_SelectedItem()->de.d_name, ".."))
|
||||
if ((fs_Options & SCANO_UMOUNT) && (is_megacd() || is_pce()) && type == DT_DIR && strcmp(flist_SelectedItem()->de.d_name, ".."))
|
||||
{
|
||||
int len = strlen(SelectedPath);
|
||||
strcat(SelectedPath, "/");
|
||||
|
||||
1
osd.cpp
1
osd.cpp
@@ -704,6 +704,7 @@ void OsdUpdate()
|
||||
spi_write(osdbuf + i * 256, 256, 0);
|
||||
DisableOsd();
|
||||
if (is_megacd()) mcd_poll();
|
||||
if (is_pce()) pcecd_poll();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,3 +30,6 @@
|
||||
|
||||
// C64 support
|
||||
#include "support/c64/c64.h"
|
||||
|
||||
// PCECD support
|
||||
#include "support/pcecd/pcecd.h"
|
||||
|
||||
@@ -642,7 +642,7 @@ void cdd_t::CommandExec() {
|
||||
/* DATA track */
|
||||
FileSeek(&this->toc.tracks[0].f, lba_ * this->sectorSize, SEEK_SET);
|
||||
}
|
||||
else if (cdd.toc.tracks[index].f.opened())
|
||||
else if (this->toc.tracks[index].f.opened())
|
||||
{
|
||||
/* PCM AUDIO track */
|
||||
FileSeek(&this->toc.tracks[index].f, (lba_ * 2352) - this->toc.tracks[index].offset, SEEK_SET);
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#define SAVE_IO_INDEX 5 // fake download to trigger save loading
|
||||
|
||||
int loaded = 0, unloaded = 0, need_reset=0;
|
||||
static int loaded = 0, unloaded = 0, need_reset=0;
|
||||
static uint8_t has_command = 0;
|
||||
|
||||
void mcd_poll()
|
||||
|
||||
@@ -35,31 +35,7 @@
|
||||
#define CD_COMM_TRAY_CLOSE 0x0C
|
||||
#define CD_COMM_TRAY_OPEN 0x0D
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fileTYPE f;
|
||||
int offset;
|
||||
int start;
|
||||
int end;
|
||||
int type;
|
||||
} track_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int end;
|
||||
int last;
|
||||
track_t tracks[100];
|
||||
// fileTYPE sub;
|
||||
} toc_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t m;
|
||||
uint8_t s;
|
||||
uint8_t f;
|
||||
} msf_t;
|
||||
|
||||
typedef int (*SendDataFunc) (uint8_t* buf, int len, uint8_t index);
|
||||
#include "../../cd.h"
|
||||
|
||||
class cdd_t
|
||||
{
|
||||
|
||||
136
support/pcecd/pcecd.cpp
Normal file
136
support/pcecd/pcecd.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
|
||||
#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 "pcecd.h"
|
||||
|
||||
|
||||
static int /*loaded = 0, unloaded = 0,*/ need_reset=0;
|
||||
static uint8_t has_command = 0;
|
||||
|
||||
void pcecd_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;
|
||||
|
||||
if (pcecdd.has_status) {
|
||||
uint16_t s;
|
||||
pcecdd.GetStatus((uint8_t*)&s);
|
||||
|
||||
spi_uio_cmd_cont(UIO_CD_SET);
|
||||
spi_w(s);
|
||||
DisableIO();
|
||||
|
||||
pcecdd.has_status = 0;
|
||||
|
||||
printf("\x1b[32mPCECD: Send status = %02X, message = %02X\n\x1b[0m", s&0xFF, s >> 8);
|
||||
}
|
||||
|
||||
pcecdd.Update();
|
||||
}
|
||||
|
||||
|
||||
uint8_t req = spi_uio_cmd_cont(UIO_CD_GET);
|
||||
if (req != last_req)
|
||||
{
|
||||
last_req = req;
|
||||
|
||||
uint16_t data_in[6];
|
||||
data_in[0] = spi_w(0);
|
||||
data_in[1] = spi_w(0);
|
||||
data_in[2] = spi_w(0);
|
||||
data_in[3] = spi_w(0);
|
||||
data_in[4] = spi_w(0);
|
||||
data_in[5] = spi_w(0);
|
||||
DisableIO();
|
||||
|
||||
if (need_reset) {
|
||||
need_reset = 0;
|
||||
pcecdd.Reset();
|
||||
}
|
||||
|
||||
if (!((uint8_t*)data_in)[11]) {
|
||||
pcecdd.SetCommand((uint8_t*)data_in);
|
||||
pcecdd.CommandExec();
|
||||
has_command = 1;
|
||||
}
|
||||
else {
|
||||
pcecdd.can_read_next = true;
|
||||
}
|
||||
|
||||
|
||||
//printf("\x1b[32mMCD: 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 pcecd_reset() {
|
||||
need_reset = 1;
|
||||
}
|
||||
|
||||
static void notify_mount(int load)
|
||||
{
|
||||
spi_uio_cmd16(UIO_SET_SDINFO, load);
|
||||
spi_uio_cmd8(UIO_SET_SDSTAT, 1);
|
||||
|
||||
if (!load)
|
||||
{
|
||||
user_io_8bit_set_status(UIO_STATUS_RESET, UIO_STATUS_RESET);
|
||||
usleep(100000);
|
||||
user_io_8bit_set_status(0, UIO_STATUS_RESET);
|
||||
}
|
||||
}
|
||||
|
||||
void pcecd_set_image(int num, const char *filename)
|
||||
{
|
||||
(void)num;
|
||||
|
||||
pcecdd.Unload();
|
||||
pcecdd.status = CD_STAT_OPEN;
|
||||
|
||||
if (strlen(filename)) {
|
||||
static char path[1024];
|
||||
|
||||
if (pcecdd.Load(filename) > 0) {
|
||||
pcecdd.status = pcecdd.loaded ? CD_STAT_STOP : CD_STAT_NO_DISC;
|
||||
pcecdd.latency = 10;
|
||||
pcecdd.SendData = pcecd_send_data;
|
||||
|
||||
// load CD BIOS
|
||||
sprintf(path, "%s/cd.rom", user_io_get_core_path());
|
||||
user_io_file_tx(path, 0);
|
||||
notify_mount(1);
|
||||
}
|
||||
else {
|
||||
notify_mount(0);
|
||||
pcecdd.status = CD_STAT_NO_DISC;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pcecdd.Unload();
|
||||
notify_mount(0);
|
||||
pcecdd.status = CD_STAT_NO_DISC;
|
||||
}
|
||||
}
|
||||
|
||||
int pcecd_send_data(uint8_t* buf, int len, uint8_t index) {
|
||||
user_io_set_index(index);
|
||||
user_io_set_download(1);
|
||||
user_io_file_tx_write(buf, len);
|
||||
user_io_set_download(0);
|
||||
return 1;
|
||||
}
|
||||
104
support/pcecd/pcecd.h
Normal file
104
support/pcecd/pcecd.h
Normal file
@@ -0,0 +1,104 @@
|
||||
#ifndef PCECD_H
|
||||
#define PCECD_H
|
||||
|
||||
|
||||
// CDD status
|
||||
#define CD_STAT_STOP 0x00
|
||||
#define CD_STAT_PLAY 0x01
|
||||
#define CD_STAT_SEEK 0x02
|
||||
#define CD_STAT_SCAN 0x03
|
||||
#define CD_STAT_PAUSE 0x04
|
||||
#define CD_STAT_OPEN 0x05
|
||||
#define CD_STAT_NO_VALID_CHK 0x06
|
||||
#define CD_STAT_NO_VALID_CMD 0x07
|
||||
#define CD_STAT_ERROR 0x08
|
||||
#define CD_STAT_TOC 0x09
|
||||
#define CD_STAT_TRACK_MOVE 0x0A
|
||||
#define CD_STAT_NO_DISC 0x0B
|
||||
#define CD_STAT_END 0x0C
|
||||
#define CD_STAT_TRAY 0x0E
|
||||
#define CD_STAT_TEST 0x0F
|
||||
|
||||
// CDD command
|
||||
#define PCECD_COMM_TESTUNIT 0x00
|
||||
#define PCECD_COMM_REQUESTSENSE 0x03
|
||||
#define PCECD_COMM_READ6 0x08
|
||||
#define PCECD_COMM_SAPSP 0xD8
|
||||
#define PCECD_COMM_SAPEP 0xD9
|
||||
#define PCECD_COMM_PAUSE 0xDA
|
||||
#define PCECD_COMM_READSUBQ 0xDD
|
||||
#define PCECD_COMM_GETDIRINFO 0xDE
|
||||
|
||||
#define PCECD_STATE_IDLE 0
|
||||
#define PCECD_STATE_READ 1
|
||||
#define PCECD_STATE_PLAY 2
|
||||
#define PCECD_STATE_PAUSE 3
|
||||
|
||||
|
||||
#include "../../cd.h"
|
||||
|
||||
|
||||
class pcecdd_t
|
||||
{
|
||||
public:
|
||||
uint32_t latency;
|
||||
uint8_t status;
|
||||
uint8_t isData;
|
||||
int loaded;
|
||||
SendDataFunc SendData;
|
||||
int has_status;
|
||||
bool can_read_next;
|
||||
|
||||
pcecdd_t();
|
||||
int Load(const char *filename);
|
||||
void Unload();
|
||||
void Reset();
|
||||
void Update();
|
||||
void CommandExec();
|
||||
int GetStatus(uint8_t* buf);
|
||||
int SetCommand(uint8_t* buf);
|
||||
|
||||
private:
|
||||
toc_t toc;
|
||||
int index;
|
||||
int lba;
|
||||
int cnt;
|
||||
uint16_t sectorSize;
|
||||
int scanOffset;
|
||||
int audioLength;
|
||||
int audioOffset;
|
||||
uint8_t state;
|
||||
int CDDAStart;
|
||||
int CDDAEnd;
|
||||
|
||||
uint8_t stat[2];
|
||||
uint8_t comm[12];
|
||||
|
||||
uint8_t sec_buf[2352 + 2];
|
||||
|
||||
int LoadCUE(const char* filename);
|
||||
int SectorSend(uint8_t* header);
|
||||
void ReadData(uint8_t *buf);
|
||||
int ReadCDDA(uint8_t *buf);
|
||||
void 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);
|
||||
int GetTrackByLBA(int lba, toc_t* toc);
|
||||
};
|
||||
|
||||
#define BCD(v) ((uint8_t)((((v)/10) << 4) | ((v)%10)))
|
||||
#define U8(v) ((uint8_t)(((((v)&0xF0) >> 4) * 10) + ((v)&0x0F)))
|
||||
|
||||
#define CD_SCAN_SPEED 30
|
||||
|
||||
//pcecdd.cpp
|
||||
extern pcecdd_t pcecdd;
|
||||
|
||||
|
||||
void pcecd_poll();
|
||||
void pcecd_set_image(int num, const char *filename);
|
||||
int pcecd_send_data(uint8_t* buf, int len, uint8_t index);
|
||||
void pcecd_reset();
|
||||
|
||||
#endif
|
||||
872
support/pcecd/pcecdd.cpp
Normal file
872
support/pcecd/pcecdd.cpp
Normal file
@@ -0,0 +1,872 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "../../file_io.h"
|
||||
|
||||
#include "pcecd.h"
|
||||
|
||||
#define PCECD_DATA_IO_INDEX 2
|
||||
|
||||
pcecdd_t pcecdd;
|
||||
|
||||
pcecdd_t::pcecdd_t() {
|
||||
latency = 10;
|
||||
loaded = 0;
|
||||
index = 0;
|
||||
lba = 0;
|
||||
scanOffset = 0;
|
||||
isData = 1;
|
||||
status = CD_STAT_NO_DISC;
|
||||
audioLength = 0;
|
||||
audioOffset = 0;
|
||||
SendData = NULL;
|
||||
has_status = 0;
|
||||
CDDAStart = 0;
|
||||
CDDAEnd = 0;
|
||||
state = PCECD_STATE_IDLE;
|
||||
|
||||
stat[0] = 0xB;
|
||||
stat[1] = 0x0;
|
||||
}
|
||||
|
||||
static int sgets(char *out, int sz, char **in)
|
||||
{
|
||||
*out = 0;
|
||||
do
|
||||
{
|
||||
char *instr = *in;
|
||||
int cnt = 0;
|
||||
|
||||
while (*instr && *instr != 10)
|
||||
{
|
||||
if (*instr == 13)
|
||||
{
|
||||
instr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cnt < sz - 1)
|
||||
{
|
||||
out[cnt++] = *instr;
|
||||
out[cnt] = 0;
|
||||
}
|
||||
|
||||
instr++;
|
||||
}
|
||||
|
||||
if(*instr == 10) instr++;
|
||||
*in = instr;
|
||||
}
|
||||
while (!*out && **in);
|
||||
|
||||
return *out;
|
||||
}
|
||||
|
||||
int pcecdd_t::LoadCUE(const char* filename) {
|
||||
static char fname[1024 + 10];
|
||||
static char line[128];
|
||||
char *ptr, *lptr;
|
||||
static char toc[100 * 1024];
|
||||
|
||||
strcpy(fname, filename);
|
||||
|
||||
memset(toc, 0, sizeof(toc));
|
||||
if (!FileLoad(fname, toc, sizeof(toc) - 1)) return 1;
|
||||
|
||||
printf("\x1b[32mPCECD: Open CUE: %s\n\x1b[0m", fname);
|
||||
|
||||
int mm, ss, bb, pregap = 0;
|
||||
|
||||
char *buf = toc;
|
||||
while (sgets(line, sizeof(line), &buf))
|
||||
{
|
||||
lptr = line;
|
||||
while (*lptr == 0x20) lptr++;
|
||||
|
||||
/* decode FILE commands */
|
||||
if (!(memcmp(lptr, "FILE", 4)))
|
||||
{
|
||||
ptr = fname + strlen(fname) - 1;
|
||||
while ((ptr - fname) && (*ptr != '/') && (*ptr != '\\')) ptr--;
|
||||
if (ptr - fname) ptr++;
|
||||
|
||||
lptr += 4;
|
||||
while (*lptr == 0x20) lptr++;
|
||||
|
||||
if (*lptr == '\"')
|
||||
{
|
||||
lptr++;
|
||||
while ((*lptr != '\"') && (lptr <= (line + 128)) && (ptr < (fname + 1023)))
|
||||
*ptr++ = *lptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((*lptr != 0x20) && (lptr <= (line + 128)) && (ptr < (fname + 1023)))
|
||||
*ptr++ = *lptr++;
|
||||
}
|
||||
*ptr = 0;
|
||||
|
||||
if(!FileOpen(&this->toc.tracks[this->toc.last].f, fname)) return -1;
|
||||
|
||||
printf("\x1b[32mPCECD: Open track file: %s\n\x1b[0m", fname);
|
||||
|
||||
pregap = 0;
|
||||
|
||||
this->toc.tracks[this->toc.last].offset = 0;
|
||||
|
||||
if (!strstr(lptr, "BINARY") && !strstr(lptr, "MOTOROLA") && !strstr(lptr, "WAVE"))
|
||||
{
|
||||
FileClose(&this->toc.tracks[this->toc.last].f);
|
||||
printf("\x1b[32mPCECD: unsupported file: %s\n\x1b[0m", fname);
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* decode TRACK commands */
|
||||
else if ((sscanf(lptr, "TRACK %02d %*s", &bb)) || (sscanf(lptr, "TRACK %d %*s", &bb)))
|
||||
{
|
||||
if (bb != (this->toc.last + 1))
|
||||
{
|
||||
FileClose(&this->toc.tracks[this->toc.last].f);
|
||||
printf("\x1b[32mPCECD: missing tracks: %s\n\x1b[0m", fname);
|
||||
break;
|
||||
}
|
||||
|
||||
//if (!this->toc.last)
|
||||
{
|
||||
if (strstr(lptr, "MODE1/2048"))
|
||||
{
|
||||
this->sectorSize = 2048;
|
||||
this->toc.tracks[this->toc.last].type = 1;
|
||||
}
|
||||
else if (strstr(lptr, "MODE1/2352"))
|
||||
{
|
||||
this->sectorSize = 2352;
|
||||
this->toc.tracks[this->toc.last].type = 1;
|
||||
|
||||
FileSeek(&this->toc.tracks[this->toc.last].f, 0x10, SEEK_SET);
|
||||
}
|
||||
else if (strstr(lptr, "AUDIO"))
|
||||
{
|
||||
this->sectorSize = 2352;
|
||||
this->toc.tracks[this->toc.last].type = 0;
|
||||
|
||||
FileSeek(&this->toc.tracks[this->toc.last].f, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
/*if (this->sectorSize)
|
||||
{
|
||||
this->toc.tracks[0].type = 1;
|
||||
|
||||
FileReadAdv(&this->toc.tracks[0].f, header, 0x210);
|
||||
FileSeek(&this->toc.tracks[0].f, 0, SEEK_SET);
|
||||
}*/
|
||||
}
|
||||
|
||||
if (this->toc.last)
|
||||
{
|
||||
if (!this->toc.tracks[this->toc.last].f.opened())
|
||||
{
|
||||
this->toc.tracks[this->toc.last - 1].end = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* decode PREGAP commands */
|
||||
else if (sscanf(lptr, "PREGAP %02d:%02d:%02d", &mm, &ss, &bb) == 3)
|
||||
{
|
||||
pregap += bb + ss * 75 + mm * 60 * 75;
|
||||
}
|
||||
|
||||
/* decode INDEX commands */
|
||||
else if ((sscanf(lptr, "INDEX 00 %02d:%02d:%02d", &mm, &ss, &bb) == 3) ||
|
||||
(sscanf(lptr, "INDEX 0 %02d:%02d:%02d", &mm, &ss, &bb) == 3))
|
||||
{
|
||||
if (this->toc.last && !this->toc.tracks[this->toc.last - 1].end)
|
||||
{
|
||||
this->toc.tracks[this->toc.last - 1].end = bb + ss * 75 + mm * 60 * 75 + pregap;
|
||||
}
|
||||
}
|
||||
else if ((sscanf(lptr, "INDEX 01 %02d:%02d:%02d", &mm, &ss, &bb) == 3) ||
|
||||
(sscanf(lptr, "INDEX 1 %02d:%02d:%02d", &mm, &ss, &bb) == 3))
|
||||
{
|
||||
this->toc.tracks[this->toc.last].offset += pregap * 2352;
|
||||
|
||||
if (!this->toc.tracks[this->toc.last].f.opened())
|
||||
{
|
||||
FileOpen(&this->toc.tracks[this->toc.last].f, fname);
|
||||
this->toc.tracks[this->toc.last].start = bb + ss * 75 + mm * 60 * 75 + pregap;
|
||||
if (this->toc.last && !this->toc.tracks[this->toc.last - 1].end)
|
||||
{
|
||||
this->toc.tracks[this->toc.last - 1].end = this->toc.tracks[this->toc.last].start;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FileSeek(&this->toc.tracks[this->toc.last].f, 0, SEEK_SET);
|
||||
|
||||
this->toc.tracks[this->toc.last].start = this->toc.end + pregap;
|
||||
this->toc.tracks[this->toc.last].offset += this->toc.end * 2352;
|
||||
|
||||
int sectorSize = 2352;
|
||||
if (this->toc.tracks[this->toc.last].type) sectorSize = this->sectorSize;
|
||||
this->toc.tracks[this->toc.last].end = this->toc.tracks[this->toc.last].start + ((this->toc.tracks[this->toc.last].f.size + sectorSize - 1) / sectorSize);
|
||||
|
||||
this->toc.tracks[this->toc.last].start += (bb + ss * 75 + mm * 60 * 75);
|
||||
this->toc.end = this->toc.tracks[this->toc.last].end;
|
||||
}
|
||||
|
||||
this->toc.last++;
|
||||
if (this->toc.last == 99) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->toc.last && !this->toc.tracks[this->toc.last - 1].end)
|
||||
{
|
||||
this->toc.end += pregap;
|
||||
this->toc.tracks[this->toc.last - 1].end = this->toc.end;
|
||||
}
|
||||
|
||||
for (int i = 0; i < this->toc.last; i++)
|
||||
{
|
||||
printf("\x1b[32mPCECD: Track = %u, start = %u, end = %u, offset = %u, type = %u\n\x1b[0m", i, this->toc.tracks[i].start, this->toc.tracks[i].end, this->toc.tracks[i].offset, this->toc.tracks[i].type);
|
||||
}
|
||||
|
||||
FileClose(&this->toc.tracks[this->toc.last].f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pcecdd_t::Load(const char *filename)
|
||||
{
|
||||
//char fname[1024 + 10];
|
||||
static char header[1024];
|
||||
fileTYPE *fd_img;
|
||||
|
||||
Unload();
|
||||
|
||||
if (LoadCUE(filename)) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
fd_img = &this->toc.tracks[0].f;
|
||||
|
||||
FileSeek(fd_img, 0, SEEK_SET);
|
||||
FileReadAdv(fd_img, header, 0x10);
|
||||
|
||||
if (!memcmp("SEGADISCSYSTEM", header, 14))
|
||||
{
|
||||
this->sectorSize = 2048;
|
||||
}
|
||||
else
|
||||
{
|
||||
FileReadAdv(fd_img, header, 0x10);
|
||||
if (!memcmp("SEGADISCSYSTEM", header, 14))
|
||||
{
|
||||
this->sectorSize = 2352;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->sectorSize)
|
||||
{
|
||||
FileReadAdv(fd_img, header + 0x10, 0x200);
|
||||
FileSeek(fd_img, 0, SEEK_SET);
|
||||
}
|
||||
else
|
||||
{
|
||||
FileClose(fd_img);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
printf("\x1b[32mPCECD: Sector size = %u, Track 0 end = %u\n\x1b[0m", this->sectorSize, this->toc.tracks[0].end);
|
||||
|
||||
if (this->toc.last)
|
||||
{
|
||||
this->toc.tracks[this->toc.last].start = this->toc.end;
|
||||
this->loaded = 1;
|
||||
|
||||
//memcpy(&fname[strlen(fname) - 4], ".sub", 4);
|
||||
//this->toc.sub = fopen(getFullPath(fname), "r");
|
||||
|
||||
printf("\x1b[32mPCECD: CD mounted , last track = %u\n\x1b[0m", this->toc.last);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pcecdd_t::Unload()
|
||||
{
|
||||
if (this->loaded)
|
||||
{
|
||||
for (int i = 0; i < this->toc.last; i++)
|
||||
{
|
||||
FileClose(&this->toc.tracks[i].f);
|
||||
}
|
||||
|
||||
//if (this->toc.sub) fclose(this->toc.sub);
|
||||
|
||||
this->loaded = 0;
|
||||
}
|
||||
|
||||
memset(&this->toc, 0x00, sizeof(this->toc));
|
||||
this->sectorSize = 0;
|
||||
}
|
||||
|
||||
void pcecdd_t::Reset() {
|
||||
latency = 10;
|
||||
index = 0;
|
||||
lba = 0;
|
||||
scanOffset = 0;
|
||||
isData = 1;
|
||||
status = loaded ? CD_STAT_STOP : CD_STAT_NO_DISC;
|
||||
audioLength = 0;
|
||||
audioOffset = 0;
|
||||
has_status = 0;
|
||||
CDDAStart = 0;
|
||||
CDDAEnd = 0;
|
||||
state = PCECD_STATE_IDLE;
|
||||
|
||||
stat[0] = 0xB;
|
||||
stat[1] = 0x0;
|
||||
}
|
||||
|
||||
void pcecdd_t::Update() {
|
||||
/*if (this->status == CD_STAT_STOP || this->status == CD_STAT_TRAY || this->status == CD_STAT_OPEN)
|
||||
{
|
||||
if (this->latency > 0)
|
||||
{
|
||||
this->latency--;
|
||||
return;
|
||||
}
|
||||
this->status = this->loaded ? CD_STAT_TOC : CD_STAT_NO_DISC;
|
||||
}
|
||||
else if (this->status == CD_STAT_SEEK)
|
||||
{
|
||||
if (this->latency > 0)
|
||||
{
|
||||
this->latency--;
|
||||
return;
|
||||
}
|
||||
this->status = CD_STAT_PAUSE;
|
||||
}
|
||||
else*/ if (this->state == PCECD_STATE_READ)
|
||||
{
|
||||
if (this->latency > 0)
|
||||
{
|
||||
this->latency--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->index >= this->toc.last)
|
||||
{
|
||||
this->state = PCECD_STATE_IDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this->can_read_next)
|
||||
return;
|
||||
|
||||
this->can_read_next = false;
|
||||
|
||||
//if (this->toc.sub) mcd_sub_send();
|
||||
|
||||
if (this->toc.tracks[this->index].type)
|
||||
{
|
||||
// CD-ROM (Mode 1)
|
||||
sec_buf[0] = 0x00;
|
||||
sec_buf[1] = 0x08 | 0x80;
|
||||
ReadData(sec_buf + 2);
|
||||
|
||||
if (SendData)
|
||||
SendData(sec_buf, 2048 + 2, PCECD_DATA_IO_INDEX);
|
||||
|
||||
printf("\x1b[32mPCECD: Data sector send = %i\n\x1b[0m", this->lba);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->lba >= this->toc.tracks[this->index].start)
|
||||
{
|
||||
this->isData = 0x00;
|
||||
}
|
||||
|
||||
//SectorSend(0);
|
||||
}
|
||||
|
||||
this->cnt--;
|
||||
|
||||
if (!this->cnt) {
|
||||
stat[0] = 0;
|
||||
stat[1] = 0;
|
||||
has_status = 1;
|
||||
|
||||
this->state = PCECD_STATE_IDLE;
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
|
||||
this->lba++;
|
||||
if (this->lba >= this->toc.tracks[this->index].end)
|
||||
{
|
||||
this->index++;
|
||||
|
||||
this->isData = 0x01;
|
||||
|
||||
if (this->toc.tracks[this->index].f.opened())
|
||||
{
|
||||
FileSeek(&this->toc.tracks[this->index].f, (this->toc.tracks[this->index].start * 2352) - this->toc.tracks[this->index].offset, SEEK_SET);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this->state == PCECD_STATE_PLAY) {
|
||||
if (this->latency > 0)
|
||||
{
|
||||
this->latency--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->index >= this->toc.last)
|
||||
{
|
||||
this->state = PCECD_STATE_IDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->toc.tracks[this->index].type)
|
||||
return;
|
||||
|
||||
FileSeek(&this->toc.tracks[index].f, (this->lba * 2352) - this->toc.tracks[index].offset, SEEK_SET);
|
||||
|
||||
sec_buf[0] = 0x30;
|
||||
sec_buf[1] = 0x09;
|
||||
ReadCDDA(sec_buf + 2);
|
||||
|
||||
if (SendData)
|
||||
SendData(sec_buf, 2352 + 2, PCECD_DATA_IO_INDEX);
|
||||
|
||||
//printf("\x1b[32mPCECD: Audio sector send = %i, track = %i, offset = %i\n\x1b[0m", this->lba, this->index, (this->lba * 2352) - this->toc.tracks[index].offset);
|
||||
|
||||
this->lba++;
|
||||
if (this->lba > this->CDDAEnd)
|
||||
{
|
||||
this->state = PCECD_STATE_IDLE;
|
||||
}
|
||||
|
||||
}
|
||||
//else if (this->status == CD_STAT_SCAN)
|
||||
//{
|
||||
// this->lba += this->scanOffset;
|
||||
|
||||
// if (this->lba >= this->toc.tracks[this->index].end)
|
||||
// {
|
||||
// this->index++;
|
||||
// if (this->index < this->toc.last)
|
||||
// {
|
||||
// this->lba = this->toc.tracks[this->index].start;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// this->lba = this->toc.end;
|
||||
// this->status = CD_STAT_END;
|
||||
// this->isData = 0x01;
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// else if (this->lba < this->toc.tracks[this->index].start)
|
||||
// {
|
||||
// if (this->index > 0)
|
||||
// {
|
||||
// this->index--;
|
||||
// this->lba = this->toc.tracks[this->index].end;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// this->lba = 0;
|
||||
// }
|
||||
// }
|
||||
|
||||
// this->isData = this->toc.tracks[this->index].type;
|
||||
|
||||
// //if (this->toc.sub) fseek(this->toc.sub, this->lba * 96, SEEK_SET);
|
||||
|
||||
// if (this->toc.tracks[this->index].type)
|
||||
// {
|
||||
// // DATA track
|
||||
// FileSeek(&this->toc.tracks[0].f, this->lba * this->sectorSize, SEEK_SET);
|
||||
// }
|
||||
// else if (this->toc.tracks[this->index].f.opened())
|
||||
// {
|
||||
// // AUDIO track
|
||||
// FileSeek(&this->toc.tracks[this->index].f, (this->lba * 2352) - this->toc.tracks[this->index].offset, SEEK_SET);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
void pcecdd_t::CommandExec() {
|
||||
msf_t msf;
|
||||
int lba_ = 0;
|
||||
uint8_t buf[16];
|
||||
|
||||
memset(buf, 0, 16);
|
||||
|
||||
switch (comm[0]) {
|
||||
case PCECD_COMM_TESTUNIT:
|
||||
stat[0] = 0;
|
||||
stat[1] = 0;
|
||||
has_status = 1;
|
||||
printf("\x1b[32mPCECD: Command TESTUNIT\n\x1b[0m");
|
||||
break;
|
||||
|
||||
case PCECD_COMM_GETDIRINFO: {
|
||||
int len = 0;
|
||||
switch (comm[1]) {
|
||||
case 0:
|
||||
default:
|
||||
buf[0] = 2;
|
||||
buf[1] = 0 | 0x80;
|
||||
buf[2] = 1;
|
||||
buf[3] = BCD(this->toc.last);
|
||||
len = 2 + 2;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
lba_ = this->toc.end + 150;
|
||||
LBAToMSF(lba_, &msf);
|
||||
|
||||
buf[0] = 4;
|
||||
buf[1] = 0 | 0x80;
|
||||
buf[2] = BCD(msf.m);
|
||||
buf[3] = BCD(msf.s);
|
||||
buf[4] = BCD(msf.f);
|
||||
buf[5] = 0;
|
||||
len = 4 + 2;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
int track = U8(comm[2]);
|
||||
lba_ = this->toc.tracks[track - 1].start + 150;
|
||||
LBAToMSF(lba_, &msf);
|
||||
|
||||
buf[0] = 4;
|
||||
buf[1] = 0 | 0x80;
|
||||
buf[2] = BCD(msf.m);
|
||||
buf[3] = BCD(msf.s);
|
||||
buf[4] = BCD(msf.f);
|
||||
buf[5] = this->toc.tracks[track - 1].type << 2;
|
||||
len = 4 + 2;
|
||||
break;
|
||||
}
|
||||
|
||||
stat[0] = 0;
|
||||
stat[1] = 0;
|
||||
has_status = 1;
|
||||
|
||||
printf("\x1b[32mPCECD: Command GETDIRINFO, [1] = %02X, [2] = %02X\n\x1b[0m", comm[1], comm[2]);
|
||||
|
||||
if (SendData && len)
|
||||
SendData(buf, len, PCECD_DATA_IO_INDEX);
|
||||
|
||||
printf("\x1b[32mPCECD: Send data, len = %u, [2] = %02X, [3] = %02X, [4] = %02X, [5] = %02X\n\x1b[0m", len, buf[2], buf[3], buf[4], buf[5]);
|
||||
}
|
||||
break;
|
||||
|
||||
case PCECD_COMM_READ6: {
|
||||
lba_ = ((comm[1] << 16) | (comm[2] << 8) | comm[3]) & 0x1FFFFF;
|
||||
int cnt_ = comm[4];
|
||||
|
||||
this->lba = lba_;
|
||||
this->cnt = cnt_;
|
||||
|
||||
int index = GetTrackByLBA(lba_, &this->toc);
|
||||
|
||||
this->index = index;
|
||||
if (lba_ < this->toc.tracks[index].start)
|
||||
{
|
||||
lba_ = this->toc.tracks[index].start;
|
||||
}
|
||||
|
||||
if (this->toc.tracks[index].type)
|
||||
{
|
||||
FileSeek(&this->toc.tracks[0].f, lba_ * this->sectorSize, SEEK_SET);
|
||||
}
|
||||
else if (this->toc.tracks[index].f.opened())
|
||||
{
|
||||
FileSeek(&this->toc.tracks[index].f, (lba_ * 2352) - this->toc.tracks[index].offset, SEEK_SET);
|
||||
}
|
||||
|
||||
this->audioOffset = 0;
|
||||
|
||||
//if (this->toc.sub) fseek(this->toc.sub, lba_ * 96, SEEK_SET);
|
||||
|
||||
//this->isData = 1;
|
||||
this->can_read_next = true;
|
||||
this->state = PCECD_STATE_READ;
|
||||
|
||||
printf("\x1b[32mPCECD: Command READ6, lba = %u, cnt = %u\n\x1b[0m", this->lba, this->cnt);
|
||||
}
|
||||
break;
|
||||
|
||||
case PCECD_COMM_SAPSP: {
|
||||
int lba_ = 0;
|
||||
switch (comm[9] & 0xc0)
|
||||
{
|
||||
default:
|
||||
case 0x00:
|
||||
lba_ = (comm[3] << 16) | (comm[4] << 8) | comm[5];
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
MSFToLBA(&lba_, U8(comm[2]), U8(comm[3]), U8(comm[4]));
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
{
|
||||
int track = U8(comm[2]);
|
||||
|
||||
if (!track)
|
||||
track = 1;
|
||||
else if (track > toc.last)
|
||||
track = toc.last;
|
||||
lba_ = this->toc.tracks[track - 1].start;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this->CDDAStart = lba_;
|
||||
this->lba = lba_;
|
||||
int index = GetTrackByLBA(lba_, &this->toc);
|
||||
|
||||
this->index = index;
|
||||
/*if (lba_ < this->toc.tracks[index].start)
|
||||
{
|
||||
lba_ = this->toc.tracks[index].start;
|
||||
}*/
|
||||
|
||||
this->CDDAEnd = this->toc.tracks[index].end;
|
||||
|
||||
//this->isData = 0;
|
||||
this->state = PCECD_STATE_PLAY;
|
||||
|
||||
FileSeek(&this->toc.tracks[index].f, (this->lba * 2352) - this->toc.tracks[index].offset, SEEK_SET);
|
||||
|
||||
sec_buf[0] = 0x30;
|
||||
sec_buf[1] = 0x09;
|
||||
ReadCDDA(sec_buf + 2);
|
||||
|
||||
if (SendData)
|
||||
SendData(sec_buf, 2352 + 2, PCECD_DATA_IO_INDEX);
|
||||
|
||||
this->lba++;
|
||||
|
||||
stat[0] = 0;
|
||||
stat[1] = 0;
|
||||
has_status = 1;
|
||||
}
|
||||
printf("\x1b[32mPCECD: Command SAPSP, start = %i, [9] = %02X\n\x1b[0m", this->CDDAStart, comm[9]);
|
||||
break;
|
||||
|
||||
case PCECD_COMM_SAPEP: {
|
||||
int lba_ = 0;
|
||||
switch (comm[9] & 0xc0)
|
||||
{
|
||||
default:
|
||||
case 0x00:
|
||||
lba_ = (comm[3] << 16) | (comm[4] << 8) | comm[5];
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
MSFToLBA(&lba_, U8(comm[2]), U8(comm[3]), U8(comm[4]));
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
{
|
||||
int track = U8(comm[2]);
|
||||
|
||||
if (!track)
|
||||
track = 1;
|
||||
else if (track > toc.last)
|
||||
track = toc.last;
|
||||
lba_ = this->toc.tracks[track - 1].start + 150;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this->CDDAEnd = lba_;
|
||||
|
||||
stat[0] = 0;
|
||||
stat[1] = 0;
|
||||
has_status = 1;
|
||||
}
|
||||
printf("\x1b[32mPCECD: Command SAPEP, end = %i, [9] = %02X\n\x1b[0m", this->CDDAEnd, comm[9]);
|
||||
break;
|
||||
|
||||
case PCECD_COMM_PAUSE: {
|
||||
this->state = PCECD_STATE_PAUSE;
|
||||
|
||||
stat[0] = 0;
|
||||
stat[1] = 0;
|
||||
has_status = 1;
|
||||
}
|
||||
printf("\x1b[32mPCECD: Command PAUSE, current lba = %i\n\x1b[0m", this->lba);
|
||||
break;
|
||||
|
||||
case PCECD_COMM_READSUBQ: {
|
||||
int lba_rel = this->toc.tracks[this->index].start - this->toc.tracks[this->index].offset + 150;
|
||||
lba_ = this->toc.tracks[this->index].start + 150;
|
||||
|
||||
buf[0] = 0x0A;
|
||||
buf[1] = 0 | 0x80;
|
||||
buf[2] = this->state == PCECD_STATE_PLAY ? 0 : 3;
|
||||
buf[3] = 0;
|
||||
buf[4] = this->index + 1;
|
||||
buf[5] = this->index;
|
||||
|
||||
LBAToMSF(lba_rel, &msf);
|
||||
buf[6] = BCD(msf.m);
|
||||
buf[7] = BCD(msf.s);
|
||||
buf[8] = BCD(msf.f);
|
||||
|
||||
LBAToMSF(lba_, &msf);
|
||||
buf[9] = BCD(msf.m);
|
||||
buf[10] = BCD(msf.s);
|
||||
buf[11] = BCD(msf.f);
|
||||
|
||||
stat[0] = 0;
|
||||
stat[1] = 0;
|
||||
has_status = 1;
|
||||
|
||||
printf("\x1b[32mPCECD: Command READSUBQ, [1] = %02X, track = %i, index = %i, lba_rel = %i, lba_abs = %i\n\x1b[0m", comm[1], this->index + 1, this->index, lba_rel, lba_);
|
||||
|
||||
if (SendData)
|
||||
SendData(buf, 10 + 2, PCECD_DATA_IO_INDEX);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
//stat[0] = this->status;
|
||||
|
||||
printf("\x1b[32mPCECD: Command undefined, [0] = %02X, [1] = %02X, [2] = %02X, [3] = %02X, [4] = %02X, [5] = %02X\n\x1b[0m", comm[0], comm[1], comm[2], comm[3], comm[4], comm[5]);
|
||||
break;
|
||||
}
|
||||
|
||||
/*if (buf[0] || buf[1]) {
|
||||
int len = ((int)buf[1] * 256) + buf[0] + 2;
|
||||
if (SendData)
|
||||
SendData(buf, len, PCECD_DATA_IO_INDEX);
|
||||
|
||||
printf("\x1b[32mPCECD: Send data, len = %u, [2] = %02X, [3] = %02X, [4] = %02X, [5] = %02X\n\x1b[0m", len, buf[2], buf[3], buf[4], buf[5]);
|
||||
}*/
|
||||
}
|
||||
|
||||
int pcecdd_t::GetStatus(uint8_t* buf) {
|
||||
memcpy(buf, stat, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pcecdd_t::SetCommand(uint8_t* buf) {
|
||||
memcpy(comm, buf, 12);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pcecdd_t::LBAToMSF(int lba, msf_t* msf) {
|
||||
msf->m = (lba / 75) / 60;
|
||||
msf->s = (lba / 75) % 60;
|
||||
msf->f = (lba % 75);
|
||||
}
|
||||
|
||||
void pcecdd_t::MSFToLBA(int* lba, uint8_t m, uint8_t s, uint8_t f) {
|
||||
*lba = f + s * 75 + m * 60 * 75;
|
||||
}
|
||||
|
||||
void pcecdd_t::MSFToLBA(int* lba, msf_t* msf) {
|
||||
*lba = msf->f + msf->s * 75 + msf->m * 60 * 75;
|
||||
}
|
||||
|
||||
int pcecdd_t::GetTrackByLBA(int lba, toc_t* toc) {
|
||||
int index = 0;
|
||||
while ((toc->tracks[index].end <= lba) && (index < toc->last)) index++;
|
||||
return index;
|
||||
}
|
||||
|
||||
void pcecdd_t::ReadData(uint8_t *buf)
|
||||
{
|
||||
if (this->toc.tracks[this->index].type && (this->lba >= 0))
|
||||
{
|
||||
if (this->sectorSize == 2048)
|
||||
{
|
||||
FileSeek(&this->toc.tracks[0].f, this->lba * 2048, SEEK_SET);
|
||||
}
|
||||
else
|
||||
{
|
||||
FileSeek(&this->toc.tracks[0].f, this->lba * 2352 + 16, SEEK_SET);
|
||||
}
|
||||
|
||||
FileReadAdv(&this->toc.tracks[0].f, buf, 2048);
|
||||
}
|
||||
}
|
||||
|
||||
int pcecdd_t::ReadCDDA(uint8_t *buf)
|
||||
{
|
||||
this->audioLength = 2352;// 2352 + 2352 - this->audioOffset;
|
||||
this->audioOffset = 0;// 2352;
|
||||
|
||||
if (this->toc.tracks[this->index].f.opened())
|
||||
{
|
||||
FileReadAdv(&this->toc.tracks[this->index].f, buf, this->audioLength);
|
||||
}
|
||||
|
||||
return this->audioLength;
|
||||
}
|
||||
|
||||
void pcecdd_t::ReadSubcode(uint16_t* buf)
|
||||
{
|
||||
(void)buf;
|
||||
/*
|
||||
uint8_t subc[96];
|
||||
int i, j, n;
|
||||
|
||||
fread(subc, 96, 1, this->toc.sub);
|
||||
|
||||
for (i = 0, n = 0; i < 96; i += 2, n++)
|
||||
{
|
||||
int code = 0;
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
int bits = (subc[(j * 12) + (i / 8)] >> (6 - (i & 6))) & 3;
|
||||
code |= ((bits & 1) << (7 - j));
|
||||
code |= ((bits >> 1) << (15 - j));
|
||||
}
|
||||
|
||||
buf[n] = code;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
int pcecdd_t::SectorSend(uint8_t* header)
|
||||
{
|
||||
uint8_t buf[2352 + 2352];
|
||||
int len = 2352;
|
||||
|
||||
if (header) {
|
||||
memcpy(buf + 12, header, 4);
|
||||
ReadData(buf + 16);
|
||||
}
|
||||
else {
|
||||
len = ReadCDDA(buf);
|
||||
}
|
||||
|
||||
if (SendData)
|
||||
return SendData(buf, len, PCECD_DATA_IO_INDEX);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
10
user_io.cpp
10
user_io.cpp
@@ -239,6 +239,13 @@ char is_megacd()
|
||||
return (is_megacd_type == 1);
|
||||
}
|
||||
|
||||
static int is_pce_type = 0;
|
||||
char is_pce()
|
||||
{
|
||||
if (!is_pce_type) is_pce_type = strcasecmp(core_name, "TGFX16") ? 2 : 1;
|
||||
return (is_pce_type == 1);
|
||||
}
|
||||
|
||||
static int is_archie_type = 0;
|
||||
char is_archie()
|
||||
{
|
||||
@@ -294,6 +301,7 @@ static void user_io_read_core_name()
|
||||
is_neogeo_type = 0;
|
||||
is_minimig_type = 0;
|
||||
is_megacd_type = 0;
|
||||
is_pce_type = 0;
|
||||
is_archie_type = 0;
|
||||
is_gba_type = 0;
|
||||
is_c64_type = 0;
|
||||
@@ -1985,6 +1993,7 @@ void user_io_send_buttons(char force)
|
||||
if (is_archie()) fpga_load_rbf(name[0] ? name : "Archie.rbf");
|
||||
if (is_minimig()) minimig_reset();
|
||||
if (is_megacd()) mcd_reset();
|
||||
if (is_pce()) pcecd_reset();
|
||||
}
|
||||
|
||||
key_map = map;
|
||||
@@ -2647,6 +2656,7 @@ void user_io_poll()
|
||||
}
|
||||
|
||||
if (is_megacd()) mcd_poll();
|
||||
if (is_pce()) pcecd_poll();
|
||||
process_ss(0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user