pcecd: some additions

This commit is contained in:
Sergey Dvodnenko
2020-04-20 16:39:50 +03:00
committed by GitHub
parent e5ee53afa6
commit 8600659c39
4 changed files with 165 additions and 138 deletions

View File

@@ -1697,6 +1697,15 @@ void HandleUI(void)
mask = 1;
}
}
if (is_pce())
{
/*if (mask == 1) pcecd_set_image(0, "");
if (mask == 2)
{*/
pcecd_reset();
/*mask = 1;
}*/
}
uint32_t status = user_io_8bit_set_status(0, 0, ex);

View File

@@ -17,7 +17,7 @@ static uint8_t has_command = 0;
void pcecd_poll()
{
static uint32_t poll_timer = 0;
static uint8_t last_req = 255;
static uint8_t last_req = 0;
static uint8_t adj = 0;
if (!poll_timer || CheckTimer(poll_timer))
@@ -31,12 +31,23 @@ void pcecd_poll()
spi_uio_cmd_cont(UIO_CD_SET);
spi_w(s);
spi_w(0);
DisableIO();
pcecdd.has_status = 0;
printf("\x1b[32mPCECD: Send status = %02X, message = %02X\n\x1b[0m", s&0xFF, s >> 8);
}
else if (pcecdd.data_req) {
spi_uio_cmd_cont(UIO_CD_SET);
spi_w(0);
spi_w(1);
DisableIO();
pcecdd.data_req = false;
printf("\x1b[32mPCECD: Data request for MODESELECT6\n\x1b[0m");
}
pcecdd.Update();
}
@@ -48,26 +59,34 @@ void pcecd_poll()
last_req = req;
uint16_t data_in[6];
uint16_t data_mode;
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);
data_mode = spi_w(0);
DisableIO();
if (need_reset) {
need_reset = 0;
pcecdd.Reset();
}
if (!((uint8_t*)data_in)[11]) {
switch (data_mode & 0xFF)
{
case 0:
pcecdd.SetCommand((uint8_t*)data_in);
pcecdd.CommandExec();
has_command = 1;
}
else {
break;
case 1:
//TODO: process data
pcecdd.SendStatus(0, 0);
printf("\x1b[32mPCECD: Command MODESELECT6, received data\n\x1b[0m");
break;
default:
pcecdd.can_read_next = true;
break;
}
@@ -75,6 +94,13 @@ void pcecd_poll()
}
else
DisableIO();
if (need_reset) {
need_reset = 0;
pcecdd.Reset();
printf("\x1b[32mPCECD: Reset\n\x1b[0m");
}
}
void pcecd_reset() {
@@ -99,13 +125,13 @@ void pcecd_set_image(int num, const char *filename)
(void)num;
pcecdd.Unload();
pcecdd.status = CD_STAT_OPEN;
pcecdd.state = PCECD_STATE_NODISC;
if (strlen(filename)) {
static char path[1024];
if (pcecdd.Load(filename) > 0) {
pcecdd.status = pcecdd.loaded ? CD_STAT_STOP : CD_STAT_NO_DISC;
pcecdd.state = pcecdd.loaded ? PCECD_STATE_IDLE : PCECD_STATE_NODISC;
pcecdd.latency = 10;
pcecdd.SendData = pcecd_send_data;
@@ -116,14 +142,14 @@ void pcecd_set_image(int num, const char *filename)
}
else {
notify_mount(0);
pcecdd.status = CD_STAT_NO_DISC;
pcecdd.state = PCECD_STATE_NODISC;
}
}
else
{
pcecdd.Unload();
notify_mount(0);
pcecdd.status = CD_STAT_NO_DISC;
pcecdd.state = PCECD_STATE_NODISC;
}
}

View File

@@ -1,28 +1,11 @@
#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_MODESELECT6 0x15
#define PCECD_COMM_SAPSP 0xD8
#define PCECD_COMM_SAPEP 0xD9
#define PCECD_COMM_PAUSE 0xDA
@@ -30,23 +13,60 @@
#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
#define PCECD_STATE_NODISC 1
#define PCECD_STATE_READ 2
#define PCECD_STATE_PLAY 3
#define PCECD_STATE_PAUSE 4
#define PCECD_STATUS_GOOD 0
#define PCECD_STATUS_CHECK_COND 1
#define PCECD_STATUS_CONDITION_MET 2
#define PCECD_STATUS_BUSY 4
#define PCECD_STATUS_INTERMEDIATE 8
#define SENSEKEY_NO_SENSE 0x0
#define SENSEKEY_NOT_READY 0x2
#define SENSEKEY_MEDIUM_ERROR 0x3
#define SENSEKEY_HARDWARE_ERROR 0x4
#define SENSEKEY_ILLEGAL_REQUEST 0x5
#define SENSEKEY_UNIT_ATTENTION 0x6
#define SENSEKEY_ABORTED_COMMAND 0xB
#define NSE_NO_DISC 0x0B
#define NSE_TRAY_OPEN 0x0D
#define NSE_SEEK_ERROR 0x15
#define NSE_HEADER_READ_ERROR 0x16
#define NSE_NOT_AUDIO_TRACK 0x1C
#define NSE_NOT_DATA_TRACK 0x1D
#define NSE_INVALID_COMMAND 0x20
#define NSE_INVALID_ADDRESS 0x21
#define NSE_INVALID_PARAMETER 0x22
#define NSE_END_OF_VOLUME 0x25
#define NSE_INVALID_REQUEST_IN_CDB 0x27
#define NSE_DISC_CHANGED 0x28
#define NSE_AUDIO_NOT_PLAYING 0x2C
#include "../../cd.h"
typedef struct
{
uint8_t key;
uint8_t asc;
uint8_t ascq;
uint8_t fru;
} sense_t;
class pcecdd_t
{
public:
uint32_t latency;
uint8_t status;
uint8_t state;
uint8_t isData;
int loaded;
SendDataFunc SendData;
int has_status;
bool data_req;
bool can_read_next;
pcecdd_t();
@@ -57,6 +77,7 @@ public:
void CommandExec();
int GetStatus(uint8_t* buf);
int SetCommand(uint8_t* buf);
void SendStatus(uint8_t status, uint8_t message);
private:
toc_t toc;
@@ -67,9 +88,10 @@ private:
int scanOffset;
int audioLength;
int audioOffset;
uint8_t state;
//uint8_t state;
int CDDAStart;
int CDDAEnd;
sense_t sense;
uint8_t stat[2];
uint8_t comm[12];
@@ -85,6 +107,7 @@ private:
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);
void CommandError(uint8_t key, uint8_t asc, uint8_t ascq, uint8_t fru);
};
#define BCD(v) ((uint8_t)((((v)/10) << 4) | ((v)%10)))

View File

@@ -19,16 +19,17 @@ pcecdd_t::pcecdd_t() {
lba = 0;
scanOffset = 0;
isData = 1;
status = CD_STAT_NO_DISC;
state = PCECD_STATE_NODISC;
audioLength = 0;
audioOffset = 0;
SendData = NULL;
has_status = 0;
data_req = false;
can_read_next = false;
CDDAStart = 0;
CDDAEnd = 0;
state = PCECD_STATE_IDLE;
stat[0] = 0xB;
stat[0] = 0x0;
stat[1] = 0x0;
}
@@ -323,38 +324,21 @@ void pcecdd_t::Reset() {
lba = 0;
scanOffset = 0;
isData = 1;
status = loaded ? CD_STAT_STOP : CD_STAT_NO_DISC;
state = loaded ? PCECD_STATE_IDLE : PCECD_STATE_NODISC;
audioLength = 0;
audioOffset = 0;
has_status = 0;
data_req = false;
can_read_next = false;
CDDAStart = 0;
CDDAEnd = 0;
state = PCECD_STATE_IDLE;
stat[0] = 0xB;
stat[0] = 0x0;
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->state == PCECD_STATE_READ)
{
if (this->latency > 0)
{
@@ -457,68 +441,48 @@ void pcecdd_t::Update() {
}
}
//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];
static uint8_t buf[32];
memset(buf, 0, 16);
memset(buf, 0, 32);
switch (comm[0]) {
case PCECD_COMM_TESTUNIT:
stat[0] = 0;
stat[1] = 0;
has_status = 1;
printf("\x1b[32mPCECD: Command TESTUNIT\n\x1b[0m");
if (state == PCECD_STATE_NODISC) {
CommandError(SENSEKEY_NOT_READY, NSE_NO_DISC, 0, 0);
SendStatus(PCECD_STATUS_CHECK_COND, 0);
}
else {
SendStatus(PCECD_STATUS_GOOD, 0);
}
printf("\x1b[32mPCECD: Command TESTUNIT, state = %u\n\x1b[0m", state);
break;
case PCECD_COMM_REQUESTSENSE:
buf[0] = 18;
buf[1] = 0 | 0x80;
buf[2] = 0x70;
buf[4] = sense.key;
buf[9] = 0x0A;
buf[14] = sense.asc;
buf[15] = sense.ascq;
buf[16] = sense.fru;
sense.key = sense.asc = sense.ascq = sense.fru = 0;
SendStatus(PCECD_STATUS_GOOD, 0);
printf("\x1b[32mPCECD: Command REQUESTSENSE, key = %02X, asc = %02X, ascq = %02X, fru = %02X\n\x1b[0m", sense.key, sense.asc, sense.ascq, sense.fru);
if (SendData)
SendData(buf, 18+2, PCECD_DATA_IO_INDEX);
break;
case PCECD_COMM_GETDIRINFO: {
@@ -561,9 +525,7 @@ void pcecdd_t::CommandExec() {
break;
}
stat[0] = 0;
stat[1] = 0;
has_status = 1;
SendStatus(PCECD_STATUS_GOOD, 0);
printf("\x1b[32mPCECD: Command GETDIRINFO, [1] = %02X, [2] = %02X\n\x1b[0m", comm[1], comm[2]);
@@ -610,6 +572,18 @@ void pcecdd_t::CommandExec() {
}
break;
case PCECD_COMM_MODESELECT6:
if (comm[4]) {
data_req = true;
}
else {
SendStatus(PCECD_STATUS_GOOD, 0);
}
printf("\x1b[32mPCECD: Command MODESELECT6, cnt = %u\n\x1b[0m", comm[4]);
break;
case PCECD_COMM_SAPSP: {
int lba_ = 0;
switch (comm[9] & 0xc0)
@@ -662,9 +636,7 @@ void pcecdd_t::CommandExec() {
this->lba++;
stat[0] = 0;
stat[1] = 0;
has_status = 1;
SendStatus(PCECD_STATUS_GOOD, 0);
}
printf("\x1b[32mPCECD: Command SAPSP, start = %i, [9] = %02X\n\x1b[0m", this->CDDAStart, comm[9]);
break;
@@ -697,9 +669,7 @@ void pcecdd_t::CommandExec() {
this->CDDAEnd = lba_;
stat[0] = 0;
stat[1] = 0;
has_status = 1;
SendStatus(PCECD_STATUS_GOOD, 0);
}
printf("\x1b[32mPCECD: Command SAPEP, end = %i, [9] = %02X\n\x1b[0m", this->CDDAEnd, comm[9]);
break;
@@ -707,9 +677,7 @@ void pcecdd_t::CommandExec() {
case PCECD_COMM_PAUSE: {
this->state = PCECD_STATE_PAUSE;
stat[0] = 0;
stat[1] = 0;
has_status = 1;
SendStatus(PCECD_STATUS_GOOD, 0);
}
printf("\x1b[32mPCECD: Command PAUSE, current lba = %i\n\x1b[0m", this->lba);
break;
@@ -735,9 +703,7 @@ void pcecdd_t::CommandExec() {
buf[10] = BCD(msf.s);
buf[11] = BCD(msf.f);
stat[0] = 0;
stat[1] = 0;
has_status = 1;
SendStatus(PCECD_STATUS_GOOD, 0);
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_);
@@ -752,14 +718,6 @@ void pcecdd_t::CommandExec() {
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) {
@@ -772,6 +730,12 @@ int pcecdd_t::SetCommand(uint8_t* buf) {
return 0;
}
void pcecdd_t::SendStatus(uint8_t status, uint8_t message) {
stat[0] = status;
stat[1] = message;
has_status = 1;
}
void pcecdd_t::LBAToMSF(int lba, msf_t* msf) {
msf->m = (lba / 75) / 60;
msf->s = (lba / 75) % 60;
@@ -865,7 +829,12 @@ int pcecdd_t::SectorSend(uint8_t* header)
return 0;
}
void pcecdd_t::CommandError(uint8_t key, uint8_t asc, uint8_t ascq, uint8_t fru) {
sense.key = key;
sense.asc = asc;
sense.ascq = ascq;
sense.fru = fru;
}