static void ReadTrack(const u8 *time) { unsigned char tmp[3]; struct SubQ *subq; u16 crc; tmp[0] = itob(time[0]); tmp[1] = itob(time[1]); tmp[2] = itob(time[2]); if (memcmp(cdr.Prev, tmp, 3) == 0) return; CDR_LOG("ReadTrack *** %02x:%02x:%02x\n", tmp[0], tmp[1], tmp[2]); cdr.RErr = CDR_readTrack(tmp); memcpy(cdr.Prev, tmp, 3); //senquack - PPF patch file support; not yet added (TODO?) #if 0 if (CheckSBI(time)) return; #endif subq = (struct SubQ *)CDR_getBufferSub(); if (subq != NULL && cdr.CurTrack == 1) { crc = calcCrc((u8 *)subq + 12, 10); if (crc == (((u16)subq->CRC[0] << 8) | subq->CRC[1])) { cdr.subq.Track = subq->TrackNumber; cdr.subq.Index = subq->IndexNumber; memcpy(cdr.subq.Relative, subq->TrackRelativeAddress, 3); memcpy(cdr.subq.Absolute, subq->AbsoluteAddress, 3); } else { CDR_LOG_I("subq bad crc @%02x:%02x:%02x\n", tmp[0], tmp[1], tmp[2]); } } else { generate_subq(time); } CDR_LOG(" -> %02x,%02x %02x:%02x:%02x %02x:%02x:%02x\n", cdr.subq.Track, cdr.subq.Index, cdr.subq.Relative[0], cdr.subq.Relative[1], cdr.subq.Relative[2], cdr.subq.Absolute[0], cdr.subq.Absolute[1], cdr.subq.Absolute[2]); }
void cdrInterrupt() { int i; unsigned char Irq = cdr.Irq; if (cdr.Stat) { CDR_INT(0x800); return; } cdr.Irq = 0xff; cdr.Ctrl&=~0x80; switch (Irq) { case CdlSync: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; break; case CdlNop: SetResultSize(1); cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; i = stat.Status; if (CDR_getStatus(&stat) != -1) { if (stat.Type == 0xff) cdr.Stat = DiskError; if (stat.Status & 0x10) { cdr.Stat = DiskError; cdr.Result[0]|= 0x11; cdr.Result[0]&=~0x02; } else if (i & 0x10) { cdr.StatP |= 0x2; cdr.Result[0]|= 0x2; CheckCdrom(); } } break; case CdlSetloc: cdr.CmdProcess = 0; SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; break; case CdlPlay: cdr.CmdProcess = 0; SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; cdr.StatP|= 0x80; // if ((cdr.Mode & 0x5) == 0x5) AddIrqQueue(REPPLAY, cdReadTime); break; case CdlForward: cdr.CmdProcess = 0; SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; break; case CdlBackward: cdr.CmdProcess = 0; SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; break; case CdlStandby: cdr.CmdProcess = 0; SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; break; case CdlStop: cdr.CmdProcess = 0; SetResultSize(1); cdr.StatP&=~0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; // cdr.Stat = Acknowledge; break; case CdlPause: SetResultSize(1); cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; AddIrqQueue(CdlPause + 0x20, 0x800); cdr.Ctrl|= 0x80; break; case CdlPause + 0x20: SetResultSize(1); cdr.StatP&=~0x20; cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; break; case CdlInit: SetResultSize(1); cdr.StatP = 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; // if (!cdr.Init) { AddIrqQueue(CdlInit + 0x20, 0x800); // } break; case CdlInit + 0x20: SetResultSize(1); cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; cdr.Init = 1; break; case CdlMute: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; break; case CdlDemute: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; break; case CdlSetfilter: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; break; case CdlSetmode: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; break; case CdlGetmode: SetResultSize(6); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Result[1] = cdr.Mode; cdr.Result[2] = cdr.File; cdr.Result[3] = cdr.Channel; cdr.Result[4] = 0; cdr.Result[5] = 0; cdr.Stat = Acknowledge; break; case CdlGetlocL: SetResultSize(8); // for (i=0; i<8; i++) cdr.Result[i] = itob(cdr.Transfer[i]); for (i=0; i<8; i++) cdr.Result[i] = cdr.Transfer[i]; cdr.Stat = Acknowledge; break; case CdlGetlocP: SetResultSize(8); subq = (struct SubQ*) CDR_getBufferSub(); if (subq != NULL) { cdr.Result[0] = subq->TrackNumber; cdr.Result[1] = subq->IndexNumber; memcpy(cdr.Result+2, subq->TrackRelativeAddress, 3); memcpy(cdr.Result+5, subq->AbsoluteAddress, 3); } else { cdr.Result[0] = 1; cdr.Result[1] = 1; cdr.Result[2] = cdr.Prev[0]; cdr.Result[3] = itob((btoi(cdr.Prev[1])) - 2); cdr.Result[4] = cdr.Prev[2]; memcpy(cdr.Result+5, cdr.Prev, 3); } cdr.Stat = Acknowledge; break; case CdlGetTN: cdr.CmdProcess = 0; SetResultSize(3); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; if (CDR_getTN(cdr.ResultTN) == -1) { cdr.Stat = DiskError; cdr.Result[0]|= 0x01; } else { cdr.Stat = Acknowledge; cdr.Result[1] = itob(cdr.ResultTN[0]); cdr.Result[2] = itob(cdr.ResultTN[1]); } break; case CdlGetTD: cdr.CmdProcess = 0; cdr.Track = btoi(cdr.Param[0]); SetResultSize(4); cdr.StatP|= 0x2; if (CDR_getTD(cdr.Track, cdr.ResultTD) == -1) { cdr.Stat = DiskError; cdr.Result[0]|= 0x01; } else { cdr.Stat = Acknowledge; cdr.Result[0] = cdr.StatP; cdr.Result[1] = itob(cdr.ResultTD[2]); cdr.Result[2] = itob(cdr.ResultTD[1]); cdr.Result[3] = itob(cdr.ResultTD[0]); } break; case CdlSeekL: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.StatP|= 0x40; cdr.Stat = Acknowledge; cdr.Seeked = 1; AddIrqQueue(CdlSeekL + 0x20, 0x800); break; case CdlSeekL + 0x20: SetResultSize(1); cdr.StatP|= 0x2; cdr.StatP&=~0x40; cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; break; case CdlSeekP: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.StatP|= 0x40; cdr.Stat = Acknowledge; AddIrqQueue(CdlSeekP + 0x20, 0x800); break; case CdlSeekP + 0x20: SetResultSize(1); cdr.StatP|= 0x2; cdr.StatP&=~0x40; cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; break; case CdlTest: cdr.Stat = Acknowledge; switch (cdr.Param[0]) { case 0x20: // System Controller ROM Version SetResultSize(4); memcpy(cdr.Result, Test20, 4); break; case 0x22: SetResultSize(8); memcpy(cdr.Result, Test22, 4); break; case 0x23: case 0x24: SetResultSize(8); memcpy(cdr.Result, Test23, 4); break; } break; case CdlID: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; AddIrqQueue(CdlID + 0x20, 0x800); break; case CdlID + 0x20: SetResultSize(8); if (CDR_getStatus(&stat) == -1) { cdr.Result[0] = 0x00; // 0x00 Game CD cdr.Result[1] = 0x00; // 0x00 loads CD } else { if (stat.Type == 2) { cdr.Result[0] = 0x08; // 0x08 audio cd cdr.Result[1] = 0x10; // 0x10 enter cd player } else { cdr.Result[0] = 0x00; // 0x00 game CD cdr.Result[1] = 0x00; // 0x00 loads CD } } if (!LoadCdBios) cdr.Result[1] |= 0x80; //0x80 leads to the menu in the bios cdr.Result[2] = 0x00; cdr.Result[3] = 0x00; // strncpy((char *)&cdr.Result[4], "PCSX", 4); #ifdef HW_RVL strncpy((char *)&cdr.Result[4], "WSX ", 4); #else strncpy((char *)&cdr.Result[4], "GCSX", 4); #endif cdr.Stat = Complete; break; case CdlReset: SetResultSize(1); cdr.StatP = 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; break; case CdlReadToc: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; AddIrqQueue(CdlReadToc + 0x20, 0x800); break; case CdlReadToc + 0x20: SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = Complete; break; case AUTOPAUSE: cdr.OCUP = 0; /* SetResultSize(1); StopCdda(); StopReading(); cdr.OCUP = 0; cdr.StatP&=~0x20; cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; cdr.Stat = DataEnd; */ AddIrqQueue(CdlPause, 0x400); break; case READ_ACK: if (!cdr.Reading) return; SetResultSize(1); cdr.StatP|= 0x2; cdr.Result[0] = cdr.StatP; if (cdr.Seeked == 0) { cdr.Seeked = 1; cdr.StatP|= 0x40; } cdr.StatP|= 0x20; cdr.Stat = Acknowledge; ReadTrack(); // CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); CDREAD_INT(0x40000); break; case REPPLAY_ACK: cdr.Stat = Acknowledge; cdr.Result[0] = cdr.StatP; SetResultSize(1); AddIrqQueue(REPPLAY, cdReadTime); break; case REPPLAY: if ((cdr.Mode & 5) != 5) break; /* if (CDR_getStatus(&stat) == -1) { cdr.Result[0] = 0; cdr.Result[1] = 0; cdr.Result[2] = 0; cdr.Result[3] = 0; cdr.Result[4] = 0; cdr.Result[5] = 0; cdr.Result[6] = 0; cdr.Result[7] = 0; } else memcpy(cdr.Result, &stat.Track, 8); cdr.Stat = 1; SetResultSize(8); AddIrqQueue(REPPLAY_ACK, cdReadTime); */ break; case 0xff: return; default: cdr.Stat = Complete; break; } if (cdr.Stat != NoIntr && cdr.Reg2 != 0x18) { psxHu32ref(0x1070)|= SWAP32((u32)0x4); psxRegs.interrupt|= 0x80000000; } #ifdef CDR_LOG CDR_LOG("cdrInterrupt() Log: CDR Interrupt IRQ %x\n", Irq); #endif }