~ubuntu-branches/debian/experimental/mednafen/experimental

« back to all changes in this revision

Viewing changes to src/psx/cdc.cpp

  • Committer: Package Import Robot
  • Author(s): Stephen Kitt
  • Date: 2012-11-19 07:00:37 UTC
  • mfrom: (1.2.12)
  • Revision ID: package-import@ubuntu.com-20121119070037-jvknrm13zvim88oc
Tags: 0.9.26-1
* New upstream WIP version.
* Change priority to "extra" to match libvorbisidec1's.
* Drop "DM-Upload-Allowed" since it is no longer appropriate.
* Refresh patches, replacing MPC_STATUS_FAIL constant from older mpcdec
  versions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
81
81
   PendingCommandPhase = 0;
82
82
  }
83
83
 
 
84
  HeaderBufValid = false;
84
85
  DriveStatus = DS_STOPPED;
85
86
  ClearAIP();
86
87
 }
87
88
 else
88
89
 {
 
90
  HeaderBufValid = false;
89
91
  DiscStartupDelay = (int64)1000 * 33868800 / 1000;
90
92
  DiscChanged = true;
91
93
 
168
170
 
169
171
 Mode = 0;
170
172
 
 
173
 HeaderBufValid = false;
171
174
 DriveStatus = DS_STOPPED;
172
175
 ClearAIP();
173
176
 StatusAfterSeek = DS_STOPPED;
677
680
 
678
681
   if(DiscStartupDelay <= 0)
679
682
   {
680
 
    DriveStatus = DS_PAUSED;
 
683
    DriveStatus = DS_PAUSED;    // or is it supposed to be DS_STANDBY?
681
684
   }
682
685
  }
683
686
 
715
718
     CurSector = 0;
716
719
     CommandLoc = 0;
717
720
 
718
 
     DriveStatus = DS_PAUSED;
 
721
     DriveStatus = DS_PAUSED;   // or DS_STANDBY?
719
722
     ClearAIP();
720
723
    }
721
724
    else if(DriveStatus == DS_SEEKING)
726
729
 
727
730
     DriveStatus = StatusAfterSeek;
728
731
 
729
 
     if(DriveStatus != DS_PAUSED)
 
732
     if(DriveStatus != DS_PAUSED && DriveStatus != DS_STANDBY)
730
733
     {
731
734
      PSRCounter = 33868800 / (75 * ((Mode & MODE_SPEED) ? 2 : 1));
732
735
     }
740
743
 
741
744
     DriveStatus = StatusAfterSeek;
742
745
 
743
 
     if(DriveStatus != DS_PAUSED)
 
746
     if(DriveStatus != DS_PAUSED && DriveStatus != DS_STANDBY)
744
747
     {
745
748
      PSRCounter = 33868800 / (75 * ((Mode & MODE_SPEED) ? 2 : 1));
746
749
     }
766
769
      DecodeSubQ(buf + 2352);
767
770
 
768
771
      memcpy(HeaderBuf, buf + 12, 12);
 
772
      HeaderBufValid = true;
769
773
 
770
774
      if((Mode & MODE_STRSND) && (buf[12 + 3] == 0x2) && (buf[12 + 6] & 0x20) && (buf[12 + 6] & 0x04))
771
775
      {
825
829
    {
826
830
     if(CurSector >= (int32)toc.tracks[100].lba)
827
831
     {
 
832
      HeaderBufValid = false;
828
833
      DriveStatus = DS_STOPPED;
829
834
      SetAIP(CDCIRQ_DISC_ERROR, MakeStatus() | 0x04, 0x04);     // TODO: Verify
830
835
     }
1287
1292
 return(0);
1288
1293
}
1289
1294
 
1290
 
static int32 CalcSeekTime(int32 initial, int32 target, bool motor_on, bool paused)
 
1295
int32 PS_CDC::CalcSeekTime(int32 initial, int32 target, bool motor_on, bool paused)
1291
1296
{
1292
1297
 int32 ret = 0;
1293
1298
 
1302
1307
 if(abs(initial - target) >= 2250)
1303
1308
  ret += (int64)33868800 * 300 / 1000;
1304
1309
 else if(paused)
1305
 
  ret += (int64)33868800 * 150 / 1000;
 
1310
 {
 
1311
  // The delay to restart from a Pause state is...very....WEIRD.  The time it takes is related to the amount of time that has passed since the pause, and
 
1312
  // where on the disc the laser head is, with generally more time passed = longer to resume, except that there's a window of time where it takes a
 
1313
  // ridiculous amount of time when not much time has passed.
 
1314
  // 
 
1315
  // What we have here will be EXTREMELY simplified.
 
1316
 
 
1317
  //
 
1318
  //
 
1319
 
 
1320
  //if(time_passed >= 67737)
 
1321
  //{
 
1322
  //}
 
1323
  //else
 
1324
  {
 
1325
   // Take twice as long for 1x mode.
 
1326
   ret += 1247952 * ((Mode & MODE_SPEED) ? 1 : 2);
 
1327
  }
 
1328
 }
1306
1329
 
1307
1330
 printf("%d\n", ret);
1308
1331
 
1371
1394
  printf("[CDC] Play track: %d\n", track);
1372
1395
  SeekTarget = toc.tracks[track].lba;
1373
1396
  PSRCounter = CalcSeekTime(CurSector, SeekTarget, DriveStatus != DS_STOPPED, DriveStatus == DS_PAUSED);
 
1397
  HeaderBufValid = false;
1374
1398
  PreSeekHack(SeekTarget);
1375
1399
 
1376
1400
  DriveStatus = DS_SEEKING;
1378
1402
 }
1379
1403
 else
1380
1404
 {
1381
 
  if(CommandLoc_Dirty || (DriveStatus != DS_PLAYING && DriveStatus != DS_PAUSED))
 
1405
  if(CommandLoc_Dirty || (DriveStatus != DS_PLAYING && DriveStatus != DS_PAUSED && DriveStatus != DS_STANDBY))
1382
1406
  {
1383
1407
   ClearAudioBuffers();
1384
1408
   SeekTarget = CommandLoc;
1385
1409
   PlayTrackMatch = -1;
1386
1410
 
1387
1411
   PSRCounter = CalcSeekTime(CurSector, SeekTarget, DriveStatus != DS_STOPPED, DriveStatus == DS_PAUSED);
 
1412
   HeaderBufValid = false;
1388
1413
   PreSeekHack(SeekTarget);
1389
1414
 
1390
1415
   DriveStatus = DS_SEEKING;
1397
1422
   PlayTrackMatch = -1;
1398
1423
 
1399
1424
   PSRCounter = CalcSeekTime(CurSector, SeekTarget, DriveStatus != DS_STOPPED, DriveStatus == DS_PAUSED);
 
1425
   HeaderBufValid = false;
1400
1426
   PreSeekHack(SeekTarget);
1401
1427
 
1402
1428
   DriveStatus = DS_SEEKING;
1466
1492
  SeekTarget = CommandLoc;
1467
1493
 
1468
1494
  PSRCounter = CalcSeekTime(CurSector, SeekTarget, DriveStatus != DS_STOPPED, DriveStatus == DS_PAUSED);
 
1495
  HeaderBufValid = false;
1469
1496
  PreSeekHack(SeekTarget);
1470
1497
 
1471
1498
  DriveStatus = DS_SEEKING_LOGICAL;
1485
1512
 return 0;
1486
1513
}
1487
1514
 
1488
 
 
1489
 
#if 0
1490
 
int32 PS_CDC::Command_Standby(const int arg_count, const uint8 *args)
1491
 
{
1492
 
 return(0);
1493
 
}
1494
 
#endif
1495
 
 
1496
1515
int32 PS_CDC::Command_Stop(const int arg_count, const uint8 *args)
1497
1516
{
1498
1517
 if(!CommandCheckDiscPresent())
1510
1529
  ClearAudioBuffers();
1511
1530
  ClearAIP();
1512
1531
  DriveStatus = DS_STOPPED;
 
1532
  HeaderBufValid = false;
1513
1533
 
1514
1534
  return(33868);        // FIXME, should be much higher.
1515
1535
 }
1525
1545
 return(0);
1526
1546
}
1527
1547
 
1528
 
 
1529
 
// TODO: Pause speed depends on speed(1x/2x) and current position.  Also check restart(for ReadN/ReadS and Play) 'delay'.
 
1548
int32 PS_CDC::Command_Standby(const int arg_count, const uint8 *args)
 
1549
{
 
1550
 if(!CommandCheckDiscPresent())
 
1551
  return(0);
 
1552
 
 
1553
 if(DriveStatus != DS_STOPPED)
 
1554
 {
 
1555
  WriteResult(MakeStatus(true));
 
1556
  WriteResult(0x20);
 
1557
  WriteIRQ(CDCIRQ_DISC_ERROR);
 
1558
  return(0);
 
1559
 }
 
1560
 
 
1561
 WriteResult(MakeStatus());
 
1562
 WriteIRQ(CDCIRQ_ACKNOWLEDGE);
 
1563
 
 
1564
 ClearAudioBuffers();
 
1565
 ClearAIP();
 
1566
 DriveStatus = DS_STANDBY;
 
1567
 
 
1568
 return((int64)33868800 * 100 / 1000);  // No idea, FIXME.
 
1569
}
 
1570
 
 
1571
int32 PS_CDC::Command_Standby_Part2(void)
 
1572
{
 
1573
 PSRCounter = 0;
 
1574
 
 
1575
 WriteResult(MakeStatus());
 
1576
 WriteIRQ(CDCIRQ_COMPLETE);
 
1577
 
 
1578
 return(0);
 
1579
}
 
1580
 
1530
1581
int32 PS_CDC::Command_Pause(const int arg_count, const uint8 *args)
1531
1582
{
1532
1583
 if(!CommandCheckDiscPresent())
1546
1597
  ClearAIP();
1547
1598
  DriveStatus = DS_PAUSED;
1548
1599
 
1549
 
  return((int64)33868800 * 100 / 1000);
 
1600
  // An approximation.
 
1601
  return((1124584 + ((int64)CurSector * 42596 / (75 * 60))) * ((Mode & MODE_SPEED) ? 1 : 2));
1550
1602
 }
1551
1603
}
1552
1604
 
1567
1619
 
1568
1620
 if(DriveStatus != DS_RESETTING)
1569
1621
 {
 
1622
  HeaderBufValid = false;
1570
1623
  DriveStatus = DS_RESETTING;
1571
1624
  PSRCounter = 1136000;
1572
1625
 }
1637
1690
 if(!CommandCheckDiscPresent())
1638
1691
  return(0);
1639
1692
 
1640
 
 if(DriveStatus != DS_READING)
 
1693
 if(!HeaderBufValid)
1641
1694
 {
1642
1695
  WriteResult(MakeStatus(true));
1643
1696
  WriteResult(0x80);
1749
1802
 
1750
1803
 SeekTarget = CommandLoc;
1751
1804
 
1752
 
 PSRCounter = CalcSeekTime(CurSector, SeekTarget, DriveStatus != DS_STOPPED, false); //DriveStatus == DS_PAUSED);
 
1805
 PSRCounter = CalcSeekTime(CurSector, SeekTarget, DriveStatus != DS_STOPPED, DriveStatus == DS_PAUSED);
 
1806
 HeaderBufValid = false;
1753
1807
 PreSeekHack(SeekTarget);
1754
1808
 DriveStatus = DS_SEEKING_LOGICAL;
1755
 
 StatusAfterSeek = DS_PAUSED;
 
1809
 StatusAfterSeek = DS_STANDBY;
1756
1810
 ClearAIP();
1757
1811
 
1758
1812
 return(PSRCounter);
1768
1822
 
1769
1823
 SeekTarget = CommandLoc;
1770
1824
 
1771
 
 PSRCounter = CalcSeekTime(CurSector, SeekTarget, DriveStatus != DS_STOPPED, false); //DriveStatus == DS_PAUSED);
 
1825
 PSRCounter = CalcSeekTime(CurSector, SeekTarget, DriveStatus != DS_STOPPED, DriveStatus == DS_PAUSED);
 
1826
 HeaderBufValid = false;
1772
1827
 PreSeekHack(SeekTarget);
1773
1828
 DriveStatus = DS_SEEKING;
1774
 
 StatusAfterSeek = DS_PAUSED;
 
1829
 StatusAfterSeek = DS_STANDBY;
1775
1830
 ClearAIP();
1776
1831
 
1777
1832
 return(PSRCounter);
1779
1834
 
1780
1835
int32 PS_CDC::Command_Seek_PartN(void)
1781
1836
{
1782
 
 if(DriveStatus == DS_PAUSED)
 
1837
 if(DriveStatus == DS_STANDBY)
1783
1838
 {
1784
1839
  BeginResults();
1785
1840
  WriteResult(MakeStatus());
1928
1983
 WriteResult(MakeStatus());
1929
1984
 WriteIRQ(CDCIRQ_ACKNOWLEDGE);
1930
1985
 
 
1986
 HeaderBufValid = false;
1931
1987
 PSRCounter = 0;
1932
 
 DriveStatus = DS_PAUSED;
 
1988
 DriveStatus = DS_PAUSED;       // or DS_STANDBY?
1933
1989
 ClearAIP();
1934
1990
 
1935
1991
 return(33868);
1984
2040
 //if(!CommandCheckDiscPresent())
1985
2041
 // return(0);
1986
2042
 
 
2043
 HeaderBufValid = false;
1987
2044
 WriteResult(MakeStatus());
1988
2045
 WriteIRQ(CDCIRQ_ACKNOWLEDGE);
1989
2046
 
1992
2049
 
1993
2050
int32 PS_CDC::Command_ReadTOC_Part2(void)
1994
2051
{
1995
 
 DriveStatus = DS_PAUSED;
 
2052
 DriveStatus = DS_PAUSED;       // or DS_STANDBY?
1996
2053
 ClearAIP();
1997
2054
 
1998
2055
 WriteResult(MakeStatus());
2017
2074
 { /* 0x04, */ 0, 0, "Forward", &PS_CDC::Command_Forward, NULL },
2018
2075
 { /* 0x05, */ 0, 0, "Backward", &PS_CDC::Command_Backward, NULL },
2019
2076
 { /* 0x06, */ 0, 0, "ReadN", &PS_CDC::Command_ReadN, NULL },
2020
 
 { /* 0x07, */ 0, 0, "Standby", &PS_CDC::Command_Pause, &PS_CDC::Command_Pause_Part2 },
 
2077
 { /* 0x07, */ 0, 0, "Standby", &PS_CDC::Command_Standby, &PS_CDC::Command_Standby_Part2 },
2021
2078
 { /* 0x08, */ 0, 0, "Stop", &PS_CDC::Command_Stop, &PS_CDC::Command_Stop_Part2 },
2022
2079
 { /* 0x09, */ 0, 0, "Pause", &PS_CDC::Command_Pause, &PS_CDC::Command_Pause_Part2 },
2023
2080
 { /* 0x0A, */ 0, 0, "Reset", &PS_CDC::Command_Reset, NULL },