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

« back to all changes in this revision

Viewing changes to src/psx/cdc.h

  • Committer: Package Import Robot
  • Author(s): Stephen Kitt
  • Date: 2012-01-31 07:21:35 UTC
  • mfrom: (1.2.8)
  • Revision ID: package-import@ubuntu.com-20120131072135-es3dj12y00xcnrsk
Tags: 0.9.19-1
* New upstream WIP version.
* Update copyright information.
* Refresh use-system-tremor.patch and remove psx-big-endian-only.patch.
* Add spelling-fixes.patch based on Lintian's recommendations.
* Build-depend on debhelper 9 or later and remove corresponding Lintian
  override.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 
4
4
#include "../cdrom/cdromif.h"
5
5
#include "../cdrom/SimpleFIFO.h"
 
6
#include "../clamp.h"
6
7
 
7
8
namespace MDFN_IEN_PSX
8
9
{
9
10
 
 
11
struct CD_Audio_Buffer
 
12
{
 
13
 int16 Samples[2][0x1000];      // [0][...] = l, [1][...] = r
 
14
 int32 Size;
 
15
 uint32 Freq;
 
16
};
 
17
 
10
18
class PS_CDC
11
19
{
12
20
 public:
14
22
 PS_CDC();
15
23
 ~PS_CDC();
16
24
 
 
25
 void SetDisc(bool tray_open, CDIF *cdif, const char disc_id[4]);
 
26
 
17
27
 void Power(void);
18
28
 void ResetTS(void);
19
 
 void Update(const pscpu_timestamp_t timestamp);
 
29
 
 
30
 int32 CalcNextEvent(void);     // Returns in master cycles to next event.
 
31
 
 
32
 pscpu_timestamp_t Update(const pscpu_timestamp_t timestamp);
20
33
 
21
34
 void Write(const pscpu_timestamp_t timestamp, uint32 A, uint8 V);
22
35
 uint8 Read(const pscpu_timestamp_t timestamp, uint32 A);
23
36
 
24
37
 bool DMACanRead(void);
25
 
 bool DMARead(uint32 &data);
26
 
 
27
 
 INLINE bool GetCDDA(int32 &l, int32 &r)
28
 
 {
29
 
  if(CDDABuffer.CanRead())
30
 
  {
31
 
   l = (int16)(CDDABuffer.ReadByte() | (CDDABuffer.ReadByte() << 8));
32
 
   r = (int16)(CDDABuffer.ReadByte() | (CDDABuffer.ReadByte() << 8));
33
 
   return(true);
34
 
  }
35
 
 
36
 
  return(false);
37
 
 }
38
 
 
39
 
 private:
40
 
 
41
 
 uint8 Control;
 
38
 uint32 DMARead(void);
 
39
 
 
40
 INLINE uint32 GetCDAudioFreq(void)
 
41
 {
 
42
  if(AudioBuffer_UsedCount)
 
43
  {
 
44
   const unsigned wb = AudioBuffer_ReadPos >> 12;
 
45
   return AudioBuffer[wb].Freq;
 
46
  }
 
47
  return 0;
 
48
 }
 
49
 
 
50
 private:
 
51
 inline void ApplyVolume(int32 samples[2])
 
52
 {
 
53
  int32 left_source = samples[0]; //(int16)MDFN_de16lsb(&buf[i * sizeof(int16) * 2 + 0]);
 
54
  int32 right_source = samples[1]; //(int16)MDFN_de16lsb(&buf[i * sizeof(int16) * 2 + 2]);
 
55
  int32 left_out = ((left_source * DecodeVolume[0][0]) >> 7) + ((right_source * DecodeVolume[1][0]) >> 7);
 
56
  int32 right_out = ((left_source * DecodeVolume[0][1]) >> 7) + ((right_source * DecodeVolume[1][1]) >> 7);
 
57
 
 
58
  clamp(&left_out, -32768, 32767);
 
59
  clamp(&right_out, -32768, 32767);
 
60
 
 
61
  samples[0] = left_out;
 
62
  samples[1] = right_out;
 
63
 }
 
64
 public:
 
65
 
 
66
 INLINE void GetCDAudio(int32 &l, int32 &r)
 
67
 {
 
68
  if(AudioBuffer_UsedCount)
 
69
  {
 
70
   const unsigned wb = AudioBuffer_ReadPos >> 12;
 
71
   int32 samples[2] = { AudioBuffer[wb].Samples[0][AudioBuffer_ReadPos & 0xFFF], AudioBuffer[wb].Samples[1][AudioBuffer_ReadPos & 0xFFF] };
 
72
 
 
73
   ApplyVolume(samples);
 
74
 
 
75
   l = samples[0];
 
76
   r = samples[1];
 
77
 
 
78
   AudioBuffer_ReadPos = ((AudioBuffer_ReadPos + 1) & 0xFFF) | (AudioBuffer_ReadPos & ~0xFFF);
 
79
 
 
80
   if((AudioBuffer_ReadPos & 0xFFF) == (AudioBuffer[wb].Size & 0xFFF))
 
81
   {
 
82
    AudioBuffer_ReadPos = ((((AudioBuffer_ReadPos >> 12) + 1) % AudioBuffer_Count) << 12);
 
83
    AudioBuffer_UsedCount--;
 
84
   }
 
85
  }
 
86
 }
 
87
 
 
88
 private:
 
89
 
 
90
 void SoftReset(void);
 
91
 
 
92
 CDIF *Cur_CDIF;
 
93
 bool DiscChanged;
 
94
 int32 DiscStartupDelay;
 
95
 
 
96
 
 
97
 enum { AudioBuffer_Count = 2 };
 
98
 
 
99
 CD_Audio_Buffer AudioBuffer[AudioBuffer_Count];
 
100
 uint32 AudioBuffer_ReadPos;
 
101
 uint32 AudioBuffer_WritePos;
 
102
 uint32 AudioBuffer_UsedCount;
 
103
 
 
104
 uint8 Pending_DecodeVolume[2][2], DecodeVolume[2][2];          // [data_source][output_port]
 
105
 
 
106
 void ClearAudioBuffers(void);
 
107
 
 
108
 uint8 RegSelector;
42
109
 uint8 ArgsBuf[16];
43
 
 uint32 ArgsIn;
44
 
 
45
 
 SimpleFIFO<uint8> Results;
46
 
 
 
110
 uint32 ArgsIn;         // 5-bit(0 ... 31)
 
111
 
 
112
 uint8 ResultsBuffer[16];
 
113
 uint8 ResultsIn;       // 5-bit(0 ... 31)
 
114
 uint8 ResultsWP;       // Write position, 4 bit(0 ... 15).
 
115
 uint8 ResultsRP;       // Read position, 4 bit(0 ... 15).
 
116
 
 
117
 SimpleFIFO<uint8> DMABuffer;
47
118
 uint8 SB[2340];
48
 
 bool SB_In;
49
 
 uint32 SB_RP;
50
 
 
51
 
 SimpleFIFO<uint8> DMABuffer;
52
 
 
53
 
 SimpleFIFO<uint8> CDDABuffer;
 
119
 uint32 SB_In;
 
120
 
54
121
 
55
122
 uint8 SubQBuf[0xC];
56
123
 uint8 SubQBuf_Safe[0xC];
57
124
 bool SubQChecksumOK;
58
125
 
 
126
 uint8 HeaderBuf[12];
 
127
 
59
128
 void RecalcIRQ(void);
60
129
 enum
61
130
 {
66
135
  CDCIRQ_DATA_END = 4,
67
136
  CDCIRQ_DISC_ERROR = 5
68
137
 };
69
 
 SimpleFIFO<uint8> IRQQueue;
70
 
 
 
138
 
 
139
 // Names are just guessed for these based on what conditions cause them:
 
140
 enum
 
141
 {
 
142
  ERRCODE_BAD_ARGVAL  = 0x10,
 
143
  ERRCODE_BAD_NUMARGS = 0x20,
 
144
  ERRCODE_BAD_COMMAND = 0x40,
 
145
  ERRCODE_NOT_READY = 0x80,     // 0x80 (happens with getlocl when drive isn't reading, pause when tray is open, and MAYBE when trying to run an async
 
146
                                //       command while another async command is currently in its asynch phase being executed[pause when in readtoc, todo test more])
 
147
 };
 
148
 
 
149
 uint8 IRQBuffer;
 
150
 uint8 IRQOutTestMask;
 
151
 int32 CDCReadyReceiveCounter;  // IRQBuffer being non-zero prevents new results and new IRQ from coming in and erasing the current results,
 
152
                                // but apparently at least one CONFOUNDED game is clearing the IRQ state BEFORE reading the results, so we need to have a delay
 
153
                                // between IRQBuffer being cleared to when we allow new results to come in.  (The real thing should be like this too,
 
154
                                // but the mechanism is probably more nuanced and complex and ugly and I like anchovy pizza)
 
155
 
 
156
 void BeginResults(void);
71
157
 void WriteIRQ(uint8);
72
158
 void WriteResult(uint8);
 
159
 uint8 ReadResult(void);
73
160
 
74
161
 uint8 FilterFile;
75
162
 uint8 FilterChan;
79
166
 bool PendingCommandPhase;
80
167
 int32 PendingCommandCounter;
81
168
 
 
169
 int32 SPUCounter;
 
170
 
82
171
 enum { MODE_SPEED = 0x80 };
83
172
 enum { MODE_STRSND = 0x40 };
84
173
 enum { MODE_SIZE = 0x20 };
94
183
  DS_PAUSED = -1,
95
184
  DS_STOPPED = 0,
96
185
  DS_SEEKING,
 
186
  DS_SEEKING_LOGICAL,
97
187
  DS_PLAY_SEEKING,
98
188
  DS_PLAYING,
99
189
  DS_READING,
 
190
  DS_RESETTING
100
191
 };
101
192
 int DriveStatus;
 
193
 int StatusAfterSeek;
102
194
 bool Forward;
103
195
 bool Backward;
104
196
 bool Muted;
109
201
 
110
202
 int32 CurSector;
111
203
 
 
204
 unsigned AsyncIRQPending;
 
205
 uint8 AsyncResultsPending[16];
 
206
 uint8 AsyncResultsPendingCount;
 
207
 
 
208
 void ClearAIP(void);
 
209
 void CheckAIP(void);
 
210
 void SetAIP(unsigned irq, unsigned result_count, uint8 *r);
 
211
 void SetAIP(unsigned irq, uint8 result0);
 
212
 void SetAIP(unsigned irq, uint8 result0, uint8 result1);
 
213
 
112
214
 int32 SeekTarget;
113
215
 
114
216
 pscpu_timestamp_t lastts;
115
217
 
116
 
 CD_TOC toc;
 
218
 CDUtility::TOC toc;
117
219
 bool IsPSXDisc;
 
220
 uint8 DiscID[4];
118
221
 
119
222
 int32 CommandLoc;
 
223
 bool CommandLoc_Dirty;
120
224
 
121
225
 uint8 MakeStatus(bool cmd_error = false);
122
 
 void DecodeSubQ(uint8 *subpw);
 
226
 bool DecodeSubQ(uint8 *subpw);
 
227
 bool CommandCheckDiscPresent(void);
 
228
 
 
229
 bool XA_Test(const uint8 *sdata);
 
230
 void XA_ProcessSector(const uint8 *sdata, CD_Audio_Buffer *ab);
 
231
 int16 xa_previous[2][2];
123
232
 
124
233
 struct CDC_CTEntry
125
234
 {
126
 
  uint8 command;
127
 
  uint8 args_length;
 
235
  uint8 args_min;
 
236
  uint8 args_max;
128
237
  const char *name;
129
238
  int32 (PS_CDC::*func)(const int arg_count, const uint8 *args);
130
239
  int32 (PS_CDC::*func2)(void);
131
240
 };
132
241
 
133
 
 static CDC_CTEntry Commands[];
 
242
 void BeginSeek(uint32 target);
 
243
 void PreSeekHack(uint32 target);
 
244
 void ReadBase(void);
 
245
 
 
246
 static CDC_CTEntry Commands[0x20];
134
247
 
135
248
 int32 Command_Sync(const int arg_count, const uint8 *args);
136
249
 int32 Command_Nop(const int arg_count, const uint8 *args);
145
258
 int32 Command_Pause(const int arg_count, const uint8 *args);
146
259
 int32 Command_Pause_Part2(void);
147
260
 int32 Command_Reset(const int arg_count, const uint8 *args);
148
 
 int32 Command_Reset_Part2(void);
149
261
 int32 Command_Mute(const int arg_count, const uint8 *args);
150
262
 int32 Command_Demute(const int arg_count, const uint8 *args);
151
263
 int32 Command_Setfilter(const int arg_count, const uint8 *args);
160
272
 int32 Command_GetTN(const int arg_count, const uint8 *args);
161
273
 int32 Command_GetTD(const int arg_count, const uint8 *args);
162
274
 int32 Command_SeekL(const int arg_count, const uint8 *args);
163
 
 
164
275
 int32 Command_SeekP(const int arg_count, const uint8 *args);
 
276
 int32 Command_Seek_PartN(void);
 
277
 
165
278
 int32 Command_Test(const int arg_count, const uint8 *args);
166
279
 
167
280
 int32 Command_ID(const int arg_count, const uint8 *args);
171
284
 int32 Command_Init(const int arg_count, const uint8 *args);
172
285
 
173
286
 int32 Command_ReadTOC(const int arg_count, const uint8 *args);
 
287
 int32 Command_ReadTOC_Part2(void);
 
288
 
 
289
 int32 Command_0x1d(const int arg_count, const uint8 *args);
174
290
};
175
291
 
176
292
}