+
+void cdrLidSeekInterrupt()
+{
+ // turn back on checking
+ if( cdr.LidCheck == 0x10 )
+ {
+ cdr.LidCheck = 0;
+ }
+
+ // official lid close
+ else if( cdr.LidCheck == 0x30 )
+ {
+ // GS CDX 3.3: $13
+ cdr.StatP |= STATUS_ROTATING;
+
+
+ // GS CDX 3.3 - ~50 getlocp tries
+ CDRLID_INT( cdReadTime * 3 );
+ cdr.LidCheck = 0x40;
+ }
+
+ // turn off ready
+ else if( cdr.LidCheck == 0x40 )
+ {
+ // GS CDX 3.3: $01
+ cdr.StatP &= ~STATUS_SHELLOPEN;
+ cdr.StatP &= ~STATUS_ROTATING;
+
+
+ // GS CDX 3.3 - ~50 getlocp tries
+ CDRLID_INT( cdReadTime * 3 );
+ cdr.LidCheck = 0x50;
+ }
+
+ // now seek
+ else if( cdr.LidCheck == 0x50 )
+ {
+ // GameShark Lite: Start seeking ($42)
+ cdr.StatP |= STATUS_SEEK;
+ cdr.StatP |= STATUS_ROTATING;
+ cdr.StatP &= ~STATUS_ERROR;
+
+
+ CDRLID_INT( cdReadTime * 3 );
+ cdr.LidCheck = 0x60;
+ }
+
+ // done = cd ready
+ else if( cdr.LidCheck == 0x60 )
+ {
+ // GameShark Lite: Seek detection done ($02)
+ cdr.StatP &= ~STATUS_SEEK;
+
+ cdr.LidCheck = 0;
+ }
+}
+
+static void Check_Shell( int Irq )
+{
+ // check case open/close
+ if (cdr.LidCheck > 0)
+ {
+#ifdef CDR_LOG
+ CDR_LOG( "LidCheck\n" );
+#endif
+
+ // $20 = check lid state
+ if( cdr.LidCheck == 0x20 )
+ {
+ u32 i;
+
+ i = stat.Status;
+ if (CDR_getStatus(&stat) != -1)
+ {
+ // BIOS hangs + BIOS error messages
+ //if (stat.Type == 0xff)
+ //cdr.Stat = DiskError;
+
+ // case now open
+ if (stat.Status & STATUS_SHELLOPEN)
+ {
+ // Vib Ribbon: pre-CD swap
+ StopCdda();
+
+
+ // GameShark Lite: Death if DiskError happens
+ //
+ // Vib Ribbon: Needs DiskError for CD swap
+
+ if (Irq != CdlNop)
+ {
+ cdr.Stat = DiskError;
+
+ cdr.StatP |= STATUS_ERROR;
+ cdr.Result[0] |= STATUS_ERROR;
+ }
+
+ // GameShark Lite: Wants -exactly- $10
+ cdr.StatP |= STATUS_SHELLOPEN;
+ cdr.StatP &= ~STATUS_ROTATING;
+
+
+ CDRLID_INT( cdReadTime * 3 );
+ cdr.LidCheck = 0x10;
+
+
+ // GS CDX 3.3 = $11
+ }
+
+ // case just closed
+ else if ( i & STATUS_SHELLOPEN )
+ {
+ cdr.StatP |= STATUS_ROTATING;
+
+ CheckCdrom();
+
+
+ if( cdr.Stat == NoIntr )
+ cdr.Stat = Acknowledge;
+
+ psxHu32ref(0x1070) |= SWAP32((u32)0x4);
+
+
+ // begin close-seek-ready cycle
+ CDRLID_INT( cdReadTime * 3 );
+ cdr.LidCheck = 0x30;
+
+
+ // GameShark Lite: Wants -exactly- $42, then $02
+ // GS CDX 3.3: Wants $11/$80, $13/$80, $01/$00
+ }
+
+ // case still closed - wait for recheck
+ else
+ {
+ CDRLID_INT( cdReadTime * 3 );
+ cdr.LidCheck = 0x10;
+ }
+ }
+ }
+
+
+ // GS CDX: clear all values but #1,#2
+ if( (cdr.LidCheck >= 0x30) || (cdr.StatP & STATUS_SHELLOPEN) )
+ {
+ SetResultSize(16);
+ memset( cdr.Result, 0, 16 );
+
+ cdr.Result[0] = cdr.StatP;
+
+
+ // GS CDX: special return value
+ if( cdr.StatP & STATUS_SHELLOPEN )
+ {
+ cdr.Result[1] = 0x80;
+ }
+
+
+ if( cdr.Stat == NoIntr )
+ cdr.Stat = Acknowledge;
+
+ psxHu32ref(0x1070) |= SWAP32((u32)0x4);
+ }
+ }
+}
+
+
+void Find_CurTrack() {
+ cdr.CurTrack = 0;
+
+ if (CDR_getTN(cdr.ResultTN) != -1) {
+ int lcv;
+
+ for( lcv = 1; lcv <= cdr.ResultTN[1]; lcv++ ) {
+ if (CDR_getTD((u8)(lcv), cdr.ResultTD) != -1) {
+ u32 sect1, sect2;
+
+#ifdef CDR_LOG___0
+ CDR_LOG( "curtrack %d %d %d | %d %d %d | %d\n",
+ cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2],
+ cdr.ResultTD[2], cdr.ResultTD[1], cdr.ResultTD[0],
+ cdr.CurTrack );
+#endif
+
+ // find next track boundary - only need m:s accuracy
+ sect1 = cdr.SetSectorPlay[0] * 60 * 75 + cdr.SetSectorPlay[1] * 75;
+ sect2 = cdr.ResultTD[2] * 60 * 75 + cdr.ResultTD[1] * 75;
+
+ // Twisted Metal 4 - psx cdda pregap (2-sec)
+ // - fix in-game music
+ sect2 -= 75 * 2;
+
+ if( sect1 >= sect2 ) {
+ cdr.CurTrack++;
+ continue;
+ }
+ }
+
+ break;
+ }
+ }
+}
+
+static void ReadTrack( u8 *time ) {
+ cdr.Prev[0] = itob( time[0] );
+ cdr.Prev[1] = itob( time[1] );
+ cdr.Prev[2] = itob( time[2] );