#include #include #include #include #include "../../file_io.h" #include "../../user_io.h" #include "../../spi.h" #include "../../hardware.h" #include "megacd.h" int loaded = 0, unloaded = 0; static uint8_t has_command = 0; void mcd_poll() { static uint32_t poll_timer = 0, stat_timer = 0; static uint8_t last_req = 255; static uint8_t adj = 0; if (!stat_timer || CheckTimer(stat_timer)) { stat_timer = GetTimer(15); if (has_command) { spi_uio_cmd_cont(UIO_CD_SET); uint64_t s = cdd.GetStatus(); spi_w((s >> 0) & 0xFFFF); spi_w((s >> 16) & 0xFFFF); spi_w(((s >> 32) & 0x00FF) | (cdd.isData ? 0x01 << 8 : 0x00 << 8)); DisableIO(); has_command = 0; //printf("\x1b[32mMCD: Send status, status = %04X%04X%04X, frame = %u\n\x1b[0m", (uint16_t)((s >> 32) & 0x00FF), (uint16_t)((s >> 16) & 0xFFFF), (uint16_t)((s >> 0) & 0xFFFF), frame); } } uint8_t req = spi_uio_cmd_cont(UIO_CD_GET); if (req != last_req) { last_req = req; uint16_t data_in[4]; data_in[0] = spi_w(0); data_in[1] = spi_w(0); data_in[2] = spi_w(0); DisableIO(); uint64_t c = *((uint64_t*)(data_in)); cdd.SetCommand(c); cdd.CommandExec(); has_command = 1; //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(); if (!poll_timer || CheckTimer(poll_timer)) { poll_timer = GetTimer(13 + (!adj ? 1 : 0)); if (++adj >= 3) adj = 0; cdd.Update(); } //static uint8_t state = 0; // //if (!poll_timer || CheckTimer(poll_timer)) //{ // if (!state) { // poll_timer = GetTimer(5 + (!adj ? 1 : 0)); // if (++adj >= 4) adj = 0; // if (has_command) { // uint64_t s = cdd.GetStatus(); // spi_uio_cmd_cont(UIO_CD_SET); // spi_w((s >> 0) & 0xFFFF); // spi_w((s >> 16) & 0xFFFF); // spi_w(((s >> 32) & 0x00FF) | (cdd.isData ? 0x01 << 8 : 0x00 << 8)); // DisableIO(); // //printf("\x1b[32mMCD: Send status, status = %02X%08X, frame = %u\n\x1b[0m", (uint32_t)(status >> 32), (uint32_t)status, frame); // } // frame++; // } // else { // poll_timer = GetTimer(8); // cdd.Update(); // uint16_t data_in[4]; // uint8_t req = spi_uio_cmd_cont(UIO_CD_GET); // //get the data from FPGA // data_in[0] = spi_w(0); // data_in[1] = spi_w(0); // data_in[2] = spi_w(0); // DisableIO(); // has_command = 0; // if (req != last_req) // { // last_req = req; // uint64_t c = *((uint64_t*)(data_in)); // cdd.CommandExec(c); // has_command = 1; // //printf("\x1b[32mMCD: Receive command, command = %02X%08X, frame = %u\n\x1b[0m", (uint32_t)(c >> 32), (uint32_t)c, frame); // } // } // state = ~state; //} } void mcd_set_image(int num, const char *filename) { (void)num; if (*filename) { if (cdd.Load(filename) > 0) { loaded = 1; cdd.status = cdd.loaded ? CD_STAT_STOP : CD_STAT_NO_DISC; cdd.latency = 10; //status = MakeStatus(CD_STAT_STOP, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0); } else { cdd.status = CD_STAT_NO_DISC; } } else { cdd.Unload(); unloaded = 1; cdd.status = CD_STAT_OPEN; } } int cdd_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); } // set index byte user_io_set_index(CD_DATA_IO_INDEX); // prepare transmission of new file EnableFpga(); spi8(UIO_FILE_TX); spi8(0xff); DisableFpga(); EnableFpga(); spi8(UIO_FILE_TX_DAT); spi_write(buf, len, 1); DisableFpga(); // signal end of transmission EnableFpga(); spi8(UIO_FILE_TX); spi8(0x00); DisableFpga(); return 1; } int cdd_t::SubcodeSend() { uint16_t buf[98/2]; ReadSubcode(buf); // set index byte user_io_set_index(CD_SUB_IO_INDEX); // prepare transmission of new file EnableFpga(); spi8(UIO_FILE_TX); spi8(0xff); DisableFpga(); EnableFpga(); spi8(UIO_FILE_TX_DAT); spi_write((uint8_t*)buf, 98, 1); DisableFpga(); // signal end of transmission EnableFpga(); spi8(UIO_FILE_TX); spi8(0x00); DisableFpga(); return 1; }