Previous 199869 Revisions Next

r22506 Monday 22nd April, 2013 at 18:58:43 UTC by Carl
(mess) Further cdrom work, main functional change is better sector buffer handling [Carl]
[src/mess/machine]psxcd.c psxcd.h

trunk/src/mess/machine/psxcd.c
r22505r22506
22#include "psxcd.h"
33#include "debugger.h"
44
5//
6//
7//
5#define VERBOSE_LEVEL ( 0 )
86
9//#define debug_cdrom
10//#define debug_cdrom_registers
11//#define skip_reads
12//#define dump_subheader
7INLINE void ATTR_PRINTF(3,4) verboselog( running_machine& machine, int n_level, const char *s_fmt, ... )
8{
9   if( VERBOSE_LEVEL >= n_level )
10   {
11      va_list v;
12      char buf[ 32768 ];
13      va_start( v, s_fmt );
14      vsprintf( buf, s_fmt, v );
15      va_end( v );
16      logerror( "%s: %s", machine.describe_context(), buf );
17   }
18}
1319
14//
15//
16//
17
1820enum cdrom_events
1921{
2022   event_cmd_complete=0,
21   event_preread_sector,
2223   event_read_sector,
2324   event_play_sector,
2425   event_change_disk
2526};
2627
27//
28//
29//
30
3128enum intr_status
3229{
3330   intr_nointr=0,
r22505r22506
4441   mode_adpcm=0x40,
4542   mode_size=0x20,
4643   mode_size2=0x10,
47   mode_size_shift=4,
48   mode_size_mask=(3<<mode_size_shift),
44   mode_size_mask=0x30,
4945   mode_channel=0x08,
5046   mode_report=0x04,
5147   mode_autopause=0x02,
r22505r22506
6662
6763struct subheader
6864{
69   unsigned char file,
70                        channel,
71                        submode,
72                        coding;
65   UINT8 file, channel, submode, coding;
7366};
7467
7568enum submode_flags
r22505r22506
8477   submode_eor=0x01
8578};
8679
87//
88//
89//
90
9180//**************************************************************************
9281//  DEVICE DEFINITIONS
9382//**************************************************************************
r22505r22506
123112
124113   m_sysclock = sysclk;
125114
126   secleft = 0;
127   secsize = 2048;
128115   res_queue = NULL;
129   cur_res = NULL;
130   streaming = false;
131   sechead = 0;
132   sectail = 0;
133   secskip = 0;
134   next_read_event = -1;
135   cbp = cmdbuf;
136   m_mute = false;
137
138116   status=status_shellopen;
139   sr=8|1;
140   res=0;
141   ir=0;
142117   mode=0;
143118
144119   for (int i = 0; i < MAX_PSXCD_TIMERS; i++)
r22505r22506
146121      m_timers[i] = timer_alloc(i);
147122      m_timerinuse[i] = false;
148123   }
149
150   curpos.w = 0;
151   m_param_count = 0;
152124}
153125
154//
155//
156//
157
158126void psxcd_device::device_reset()
159127{
160128   stop_read();
r22505r22506
168136   if(m_cdrom_handle)
169137      add_system_event(event_change_disk, m_sysclock, NULL);
170138
171   next_read_event = -1;
172
173   if(cur_res)
174   {
175      global_free(cur_res);
176      cur_res = NULL;
177   }
178
179139   while(res_queue)
180140   {
181      cur_res = res_queue->next;
141      command_result *res = res_queue->next;
182142      global_free(res_queue);
183      res_queue = cur_res;
143      res_queue = res;
184144   }
185145
186146   m_param_count = 0;
147   m_regs.sr = 0x18;
148   m_regs.ir = 0;
149   m_regs.imr = 0x1f;
150   sechead = 0;
151   sectail = 0;
152   next_read_event = -1;
153   m_mute = false;
154   m_dmaload = false;
155   curpos.w = 0;
187156}
188157
189//
190//
191//
192
193158bool psxcd_device::call_load()
194159{
195160   bool ret = cdrom_image_device::call_load();
r22505r22506
210175
211176READ8_MEMBER( psxcd_device::read )
212177{
213   unsigned char ret = 0;
214
215   switch (offset&3)
178   UINT8 ret = 0;
179   switch (offset & 3)
216180   {
217181      /*
218182      x--- ---- command/parameter busy flag
r22505r22506
222186      ---- x--- parameter fifo empty (active high)
223187      ---- --xx cmd mode
224188      */
225      case 0: ret=sr; break;
189      case 0:
190         ret = m_regs.sr;
191         break;
192
226193      case 1:
227         ret=res;
228         if ((cur_res) && (rdp<cur_res->sz))
194         if ((res_queue) && (rdp < res_queue->sz))
229195         {
230            res=cur_res->data[rdp++];
231            sr|=(1<<5);
232         } else
196            ret = res_queue->data[rdp++];
197            if(rdp == res_queue->sz)
198               m_regs.sr &= ~0x20;
199            else
200               m_regs.sr |= 0x20;
201         }
202         else
203            ret = 0;
204         break;
205
206      case 2:
207         if(!m_dmaload)
208            ret = 0;
209         else
233210         {
234            if ((cur_res) && (cur_res->res&0x10))
211            ret = m_transbuf[m_transcurr++];
212            if(m_transcurr >= raw_sector_size)
235213            {
236               global_free(cur_res);
237               cur_res=NULL;
214               m_dmaload = false;
215               m_regs.sr &= ~0x40;
238216            }
239
240            sr&=~(1<<5);
241217         }
242218         break;
243      case 2: ret=0; break;
244      case 3: ret=ir; break;
219
220      case 3:
221         if(m_regs.sr & 1)
222            ret = m_regs.ir | 0xe0;
223         else
224            ret = m_regs.imr | 0xe0;
225         break;
245226   }
246227
247   #ifdef debug_cdrom_registers
248      printf("cdrom: read byte %08x = %02x (PC=%08x)\n",offset,ret,space.device().safe_pc());
249   #endif
228   verboselog(machine(), 2, "psxcd: read byte %08x = %02x\n",offset,ret);
250229
251230   return ret;
252231}
253232
254//
255//
256//
257
258233WRITE8_MEMBER( psxcd_device::write )
259234{
260   #ifdef debug_cdrom_registers
261      printf("cdrom: write byte %08x = %02x (PC=%08x)\n",offset,data,space.device().safe_pc());
262   #endif
235   verboselog(machine(), 2, "psxcd: write byte %08x = %02x\n",offset,data);
263236
264   switch (offset&3)
237   switch ((offset & 3) | ((m_regs.sr & 3) << 4))
265238   {
266      case 0:
267         //if(data & 2)
268         //  popmessage("cmdmode = %02x, contact MESSdev",data);
239      case 0x00:
240      case 0x10:
241      case 0x20:
242      case 0x30:
243         m_regs.sr = (m_regs.sr & ~3) | (data & 3);
244         break;
269245
270         cmdmode=data&1;
271         if (cmdmode==0)
272         {
273            cbp=cmdbuf;
274         } else
275         {
276            if (! cur_res)
277            {
278               if (cur_res) global_free(cur_res);
246      case 0x01:
247         write_command(data);
248         break;
279249
280               if (res_queue)
281               {
282                  #ifdef debug_cdrom_registers
283                     printf("cdrom: nextres\n");
284                  #endif
250      case 0x11:
251      case 0x21:
252         break;
285253
286                  cur_res=res_queue;
287                  res_queue=res_queue->next;
288                  ir=cur_res->res&0xf;
289                  rdp=0;
254      case 0x31:
255         m_regs.vol.rr = data;
256         break;
290257
291                  if (cur_res->sz)
292                  {
293                     res=cur_res->data[rdp++];
294                     sr|=(1<<5);
295                  } else
296                  {
297                     sr&=~(1<<5);
298                  }
299               } else
300               {
301                  //ir=0;
302                  cur_res=NULL;
303               }
304            }
305            /*else
306            {
307                if (rdp>=cur_res->sz)
308                {
309                    sr&=~(1<<5);
310                } else
311                {
312                    sr|=~(1<<5);
313                    res=cur_res->data[rdp++];
314                }
315            }
316            */
317         }
258      case 0x02:
259         cmdbuf[m_param_count] = data;
260         m_param_count++;
318261         break;
319262
320      case 1:
321         if (cmdmode==0)
322         {
323            write_command(data);
324         }
263      case 0x12:
264         m_regs.imr = data & 0x1f;
325265         break;
326266
327      case 2:
328         if (cmdmode==0)
329         {
330            *cbp++=data;
331            m_param_count++;
332         } else
333         {
334            // ?flush buffer?
335            //if(data & 0xf8)
336            //popmessage("Interrupt enable register mode 1 [%02x] -> %02x",offset,data);
337         }
267      case 0x22:
268         m_regs.vol.ll = data;
338269         break;
339270
271      case 0x32:
272         m_regs.vol.rl = data;
273         break;
340274      /*
341275      x--- ---- unknown
342276      -x-- ---- Reset parameter FIFO
r22505r22506
344278      ---x ---- Command start
345279      ---- -xxx Response received
346280      */
347      case 3:
348         //if(data & 0x78)
349         //  popmessage("IRQ flag = %02x, contact MESSdev",data);
281      case 0x03:
282         if((data & 0x80) && !m_dmaload)
283         {
284            if(sechead == sectail)
285               break;
350286
351         if (data==0x07)
287            m_dmaload = true;
288            memcpy(m_transbuf, secbuf[sechead], raw_sector_size);
289            m_regs.sr |= 0x40;
290            sechead++;
291            sechead %= sector_buffer_size;
292
293            switch(mode & mode_size_mask)
294            {
295               case 0x00:
296               default:
297                  m_transcurr = 24;
298                  break;
299               case 0x10:
300                  m_transcurr = 24;
301                  break;
302               case 0x20:
303                  m_transcurr = 12;
304                  break;
305            }
306#if (VERBOSE_LEVEL > 0)
307            char str[1024];
308            for (int i=0; i<12; i++)
309               sprintf(&str[i*4], "%02x  ", m_transbuf[i+12]);
310            verboselog(machine(), 1, "psxcd: request data=%s\n",str);
311#endif
312         }
313         else if(!(data & 0x80))
352314         {
353            if (cur_res)
315            m_dmaload = false;
316            m_regs.sr &= ~0x40;
317         }
318         break;
319
320      case 0x13:
321         if(data & 0x1f)
322         {
323            m_regs.ir &= ~(data & 0x1f);
324            if(m_regs.ir)
325               break;
326
327            if (res_queue)
354328            {
355               global_free(cur_res);
356               cur_res=NULL;
357               sr&=~(1<<5);
329               command_result *res = res_queue;
330               res_queue = res->next;
331               global_free(res);
332               m_regs.sr &= ~0x20;
333               rdp = 0;
334               if(res_queue)
335               {
336                  m_regs.sr |= 0x20;
337                  m_regs.ir = res_queue->res;
338               }
339               verboselog(machine(), 1, "psxcd: nextres\n");
358340            }
359            ir=0;
360341         }
342         if(data & 0x40)
343            m_param_count = 0;
344         break;
345
346      case 0x23:
347         m_regs.vol.lr = data;
348         break;
349
350      case 0x33:
351         break;
361352   }
362353}
363354
364psxcd_device::command_info psxcd_device::cmd_table[num_commands]=
355const psxcd_device::cdcmd psxcd_device::cmd_table[]=
365356{
366   { &psxcd_device::cdcmd_sync,                "sync"          },  // 00
367   { &psxcd_device::cdcmd_nop,             "nop"               },  // 01
368   { &psxcd_device::cdcmd_setloc,          "setloc"        },  // 02
369   { &psxcd_device::cdcmd_play,                "play"          },  // 03
370   { &psxcd_device::cdcmd_forward,     "forward"       },  // 04
371   { &psxcd_device::cdcmd_backward,        "backward"  },  // 05
372   { &psxcd_device::cdcmd_readn,           "readn"         },  // 06
373   { &psxcd_device::cdcmd_standby,     "standby"       },  // 07
374   { &psxcd_device::cdcmd_stop,                "stop"          },  // 08
375   { &psxcd_device::cdcmd_pause,           "pause"         },  // 09
376   { &psxcd_device::cdcmd_init,                "init"          },  // 0a
377   { &psxcd_device::cdcmd_mute,                "mute"          },  // 0b
378   { &psxcd_device::cdcmd_demute,          "demute"        },  // 0c
379   { &psxcd_device::cdcmd_setfilter,   "setfilter" },  // 0d
380   { &psxcd_device::cdcmd_setmode,     "setmode"       },  // 0e
381   { &psxcd_device::cdcmd_getparam,        "getparam"  },  // 0f
382   { &psxcd_device::cdcmd_getlocl,     "getlocl"       },  // 10
383   { &psxcd_device::cdcmd_getlocp,     "getlocp"       },  // 11
384   { &psxcd_device::cdcmd_illegal,     "illegal"       },  // 12
385   { &psxcd_device::cdcmd_gettn,           "gettn"         },  // 13
386   { &psxcd_device::cdcmd_gettd,           "gettd"         },  // 14
387   { &psxcd_device::cdcmd_seekl,           "seekl"         },  // 15
388   { &psxcd_device::cdcmd_seekp,           "seekp"         },  // 16
389   { &psxcd_device::cdcmd_illegal,     "illegal"       },  // 17
390   { &psxcd_device::cdcmd_illegal,     "illegal"       },  // 18
391   { &psxcd_device::cdcmd_test,                "test"          },  // 19
392   { &psxcd_device::cdcmd_id,                  "id"                },  // 1a
393   { &psxcd_device::cdcmd_reads,           "reads"         },  // 1b
394   { &psxcd_device::cdcmd_reset,           "reset"         },  // 1c
395   { &psxcd_device::cdcmd_illegal,     "illegal"       },  // 1d
396   { &psxcd_device::cdcmd_readtoc,     "readtoc"       },  // 1e
357   &psxcd_device::cdcmd_sync,
358   &psxcd_device::cdcmd_nop,
359   &psxcd_device::cdcmd_setloc,
360   &psxcd_device::cdcmd_play,
361   &psxcd_device::cdcmd_forward,
362   &psxcd_device::cdcmd_backward,
363   &psxcd_device::cdcmd_readn,
364   &psxcd_device::cdcmd_standby,
365   &psxcd_device::cdcmd_stop,
366   &psxcd_device::cdcmd_pause,
367   &psxcd_device::cdcmd_init,
368   &psxcd_device::cdcmd_mute,
369   &psxcd_device::cdcmd_demute,
370   &psxcd_device::cdcmd_setfilter,
371   &psxcd_device::cdcmd_setmode,
372   &psxcd_device::cdcmd_getparam,
373   &psxcd_device::cdcmd_getlocl,
374   &psxcd_device::cdcmd_getlocp,
375   &psxcd_device::cdcmd_unknown12,
376   &psxcd_device::cdcmd_gettn,
377   &psxcd_device::cdcmd_gettd,
378   &psxcd_device::cdcmd_seekl,
379   &psxcd_device::cdcmd_seekp,
380   &psxcd_device::cdcmd_illegal17,
381   &psxcd_device::cdcmd_illegal18,
382   &psxcd_device::cdcmd_test,
383   &psxcd_device::cdcmd_id,
384   &psxcd_device::cdcmd_reads,
385   &psxcd_device::cdcmd_reset,
386   &psxcd_device::cdcmd_illegal1d,
387   &psxcd_device::cdcmd_readtoc
397388};
398389
399//
400//
401//
402
403void psxcd_device::write_command(const unsigned char byte)
390void psxcd_device::write_command(UINT8 byte)
404391{
405   assert(byte<num_commands);
406   (this->*cmd_table[byte].func)();
392   if(byte > 31)
393      illegalcmd(byte);
394   else
395      (this->*cmd_table[byte])();
407396   m_param_count = 0;
408397}
409398
410//
411//
412//
413
414399void psxcd_device::cdcmd_sync()
415400{
416   #ifdef debug_cdrom
417      printf("cdrom: sync\n");
418   #endif
401   verboselog(machine(), 1, "psxcd: sync\n");
419402
420403   stop_read();
421404   send_result(intr_acknowledge);
r22505r22506
423406
424407void psxcd_device::cdcmd_nop()
425408{
426   #ifdef debug_cdrom
427      printf("cdrom: nop\n");
428   #endif
409   verboselog(machine(), 1, "psxcd: nop\n");
429410
430   //stop_read();
431
432411   if (!open)
433412      status &= ~status_shellopen;
434413
r22505r22506
437416
438417void psxcd_device::cdcmd_setloc()
439418{
440   #ifdef debug_cdrom
441      printf("cdrom: setloc %08x:%08x:%08x\n",
442            cmdbuf[0],
443            cmdbuf[1],
444            cmdbuf[2]);
445   #endif
419   verboselog(machine(), 1, "psxcd: setloc %08x:%08x:%08x\n", cmdbuf[0], cmdbuf[1], cmdbuf[2]);
446420
447421   stop_read();
448422
r22505r22506
455429   if ((l.b[M]>0) || (l.b[S]>=2))
456430      loc.w=l.w;
457431   else
458      logerror("setloc out of range: %02d:%02d:%02d\n",l.b[M],l.b[S],l.b[F]);
432      verboselog(machine(), 0, "psxcd: setloc out of range: %02d:%02d:%02d\n",l.b[M],l.b[S],l.b[F]);
459433
460434   send_result(intr_complete);
461435}
r22505r22506
469443   if (!curpos.w)
470444      curpos.b[S] = 2;
471445
472#ifdef debug_cdrom
473   printf("cdrom: play %02x %02x %02x => %d\n", loc.b[M], loc.b[S], loc.b[F], msf_to_lba_ps(loc.w));
474#endif
446   verboselog(machine(), 1, "psxcd: play %02x %02x %02x => %d\n", loc.b[M], loc.b[S], loc.b[F], msf_to_lba_ps(loc.w));
475447
476448   stop_read();
477449   start_play();
r22505r22506
480452
481453void psxcd_device::cdcmd_forward()
482454{
483   #ifdef debug_cdrom
484      printf("cdrom: forward\n");
485   #endif
455   verboselog(machine(), 1, "psxcd: forward\n");
486456}
487457
488458void psxcd_device::cdcmd_backward()
489459{
490   #ifdef debug_cdrom
491      printf("cdrom: backward\n");
492   #endif
460   verboselog(machine(), 1, "psxcd: backward\n");
493461}
494462
495463void psxcd_device::cdcmd_readn()
496464{
497465   if(!open)
498466   {
499      #ifdef debug_cdrom
500         printf("cdrom: readn\n");
501      #endif
467      verboselog(machine(), 1, "psxcd: readn\n");
502468
503469      curpos.w=loc.w;
504470
505471      stop_read();
506472      start_read();
507      send_result(intr_complete);
508473   } else
509474   {
510475      send_result(intr_diskerror);
r22505r22506
513478
514479void psxcd_device::cdcmd_standby()
515480{
516   #ifdef debug_cdrom
517      printf("cdrom: standby\n");
518   #endif
481   verboselog(machine(), 1, "psxcd: standby\n");
519482
520483   stop_read();
521484   send_result(intr_acknowledge);
r22505r22506
523486
524487void psxcd_device::cdcmd_stop()
525488{
526   #ifdef debug_cdrom
527      printf("cdrom: stop\n");
528   #endif
489   verboselog(machine(), 1, "psxcd: stop\n");
529490
530491   stop_read();
531492   send_result(intr_acknowledge);
r22505r22506
533494
534495void psxcd_device::cdcmd_pause()
535496{
536   #ifdef debug_cdrom
537      printf("cdrom: pause\n");
538   #endif
497   verboselog(machine(), 1, "psxcd: pause\n");
539498
540499   stop_read();
541500
r22505r22506
544503
545504void psxcd_device::cdcmd_init()
546505{
547   #ifdef debug_cdrom
548      printf("cdrom: init\n");
549   #endif
506   verboselog(machine(), 1, "psxcd: init\n");
550507
551508   stop_read();
552509   mode=0;
553   sr|=0x10;
510   m_regs.sr |= 0x10;
554511
555512   send_result(intr_acknowledge);
556513}
557514
558515void psxcd_device::cdcmd_mute()
559516{
560   #ifdef debug_cdrom
561      printf("cdrom: mute\n");
562   #endif
517   verboselog(machine(), 1, "psxcd: mute\n");
563518
564519   m_mute = true;
565520   send_result(intr_acknowledge);
r22505r22506
567522
568523void psxcd_device::cdcmd_demute()
569524{
570   #ifdef debug_cdrom
571      printf("cdrom: demute\n");
572   #endif
525   verboselog(machine(), 1, "psxcd: demute\n");
573526
574527   m_mute = false;
575528   send_result(intr_acknowledge);
r22505r22506
577530
578531void psxcd_device::cdcmd_setfilter()
579532{
580   #ifdef debug_cdrom
581      printf("cdrom: setfilter %08x,%08x\n",cmdbuf[0],cmdbuf[1]);
582   #endif
533   verboselog(machine(), 1, "psxcd: setfilter %08x,%08x\n",cmdbuf[0],cmdbuf[1]);
583534
584535   filter_file=cmdbuf[0];
585536   filter_channel=cmdbuf[1];
r22505r22506
589540
590541void psxcd_device::cdcmd_setmode()
591542{
592   #ifdef debug_cdrom
593      printf("cdrom: setmode %08x\n",cmdbuf[0]);
594   #endif
543   verboselog(machine(), 1, "psxcd: setmode %08x\n",cmdbuf[0]);
595544
596545   mode=cmdbuf[0];
597
598   switch ((mode&mode_size_mask)>>mode_size_shift)
599   {
600      case 1:
601         secsize=2328;
602         secskip=24;
603         break;
604
605      case 2:
606         secsize=2340;
607         secskip=12;
608         break;
609
610      default:
611         secsize=2048;
612         secskip=24;
613         break;
614   }
615
616546   send_result(intr_complete);
617547}
618548
r22505r22506
628558      0
629559   };
630560
631   #ifdef debug_cdrom
632      printf("cdrom: getparam [%02x %02x %02x %02x %02x %02x]\n",
633                           data[0],
634                           data[1],
635                           data[2],
636                           data[3],
637                           data[4],
638                           data[5]);
639   #endif
561   verboselog(machine(), 1, "psxcd: getparam [%02x %02x %02x %02x %02x %02x]\n",
562                        data[0], data[1], data[2], data[3], data[4], data[5]);
640563
641564   send_result(intr_complete,data,6);
642565}
r22505r22506
662585
663586void psxcd_device::cdcmd_getlocl()
664587{
665   #ifdef debug_cdrom
666      printf("cdrom: getlocl\n");
667   #endif
588   verboselog(machine(), 1, "psxcd: getlocl [%02x %02x %02x %02x %02x %02x %02x %02x]\n",
589                     lastsechdr[0], lastsechdr[1], lastsechdr[2], lastsechdr[3],
590                     lastsechdr[4], lastsechdr[5], lastsechdr[6], lastsechdr[7]);
668591
669   #ifdef debug_cdrom
670      printf("cdrom: getlocl [%02x %02x %02x %02x %02x %02x %02x %02x]\n",
671                           lastsechdr[0],
672                           lastsechdr[1],
673                           lastsechdr[2],
674                           lastsechdr[3],
675                           lastsechdr[4],
676                           lastsechdr[5],
677                           lastsechdr[6],
678                           lastsechdr[7]);
679   #endif
680
681592   send_result(intr_complete,lastsechdr,8);
682593}
683594
r22505r22506
700611      decimal_to_bcd(loc.b[F])  // aframe
701612   };
702613
703   //unsigned char data[8]={ 2,1,0,0xff,0xff,0xff,0xff,0xff };
614      verboselog(machine(), 1, "psxcd: getlocp [%02x %02x %02x %02x %02x %02x %02x %02x]\n",
615                     data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
704616
705   #ifdef debug_cdrom
706      printf("cdrom: getlocp [%02x %02x %02x %02x %02x %02x %02x %02x]\n",
707                           data[0],
708                           data[1],
709                           data[2],
710                           data[3],
711                           data[4],
712                           data[5],
713                           data[6],
714                           data[7]);
715   #endif
716
717617   send_result(intr_complete,data,8);
718618}
719619
720void psxcd_device::cdcmd_illegal()
721{
722   assert(0);
723}
724
725620void psxcd_device::cdcmd_gettn()
726621{
727   #ifdef debug_cdrom
728      printf("cdrom: gettn\n");
729   #endif
622   verboselog(machine(), 1, "psxcd: gettn\n");
730623
731624
732625   if(!open)
r22505r22506
738631            decimal_to_bcd(cdrom_get_last_track(m_cdrom_handle))
739632      };
740633
741      //stop_read();
742634      send_result(intr_complete,data,3);
743635   }
744636   else
r22505r22506
767659         decimal_to_bcd(trkstart.b[S])
768660      };
769661
770      #ifdef debug_cdrom
771         printf("cdrom: gettd %02x [%02x %02x %02x]\n",
772                                          cmdbuf[0],
773                                          data[0],
774                                          data[1],
775                                          data[2]);
776      #endif
662      verboselog(machine(), 1, "psxcd: gettd %02x [%02x %02x %02x]\n", cmdbuf[0], data[0], data[1], data[2]);
777663
778      //stop_read();
779664      send_result(intr_acknowledge,data,3);
780665   }
781666   else
r22505r22506
787672
788673void psxcd_device::cdcmd_seekl()
789674{
790   #ifdef debug_cdrom
791      printf("cdrom: seekl [%02d:%02d:%02d]\n",loc.b[M],loc.b[S],loc.b[F]);
792   #endif
675   verboselog(machine(), 1, "psxcd: seekl [%02d:%02d:%02d]\n", loc.b[M], loc.b[S], loc.b[F]);
793676
794677   curpos.w=loc.w;
795678
r22505r22506
798681
799682void psxcd_device::cdcmd_seekp()
800683{
801   #ifdef debug_cdrom
802      printf("cdrom: seekp\n");
803   #endif
684   verboselog(machine(), 1, "psxcd: seekp\n");
804685
805686   curpos.w=loc.w;
806687
r22505r22506
809690
810691void psxcd_device::cdcmd_test()
811692{
812   #ifdef debug_cdrom
813      printf("cdrom: test %08x\n",cmdbuf[0]);
814   #endif
693   verboselog(machine(), 1, "psxcd: test %08x\n",cmdbuf[0]);
815694
816695   static unsigned char data[4]=
817696   {
r22505r22506
826705
827706void psxcd_device::cdcmd_id()
828707{
829   #ifdef debug_cdrom
830      printf("cdrom: id\n");
831   #endif
708   verboselog(machine(), 1, "psxcd: id\n");
832709
833710   if (!open)
834711   {
r22505r22506
854731
855732void psxcd_device::cdcmd_reads()
856733{
857   curpos.w=loc.w;
734   if(!open)
735   {
736      verboselog(machine(), 1, "psxcd: reads\n");
858737
859   #ifdef skip_reads
860      #ifdef debug_cdrom
861         log("cdrom: reads [SKIPPING - RETURN COMPLETE]\n");
862      #endif
738      curpos.w=loc.w;
863739
864      send_result(intr_complete);
865   #else
866      #ifdef debug_cdrom
867         printf("cdrom: reads\n");
868      #endif
869
870740      stop_read();
871      start_streaming();
872   #endif
741      start_read();
742   } else
743   {
744      send_result(intr_diskerror);
745   }
873746}
874747
875748void psxcd_device::cdcmd_reset()
876749{
877   #ifdef debug_cdrom
878      printf("cdrom: reset\n");
879   #endif
750   verboselog(machine(), 1, "psxcd: reset\n");
880751}
881752
882753void psxcd_device::cdcmd_readtoc()
883754{
884   #ifdef debug_cdrom
885      printf("cdrom: readtoc\n");
886   #endif
755   verboselog(machine(), 1, "psxcd: readtoc\n");
887756
888   static unsigned char data[4]=
889   {
890      0x00,
891      0x00,
892      0xff,
893      0xfe
894   };
895
896   send_result(intr_complete|0x10,data,2);
757   send_result(intr_complete);
897758}
898759
899//
900//
901//
902
903void psxcd_device::cmd_complete(command_result *res)
760void psxcd_device::cdcmd_unknown12()
904761{
905   bool doint=((res->res&0x10)==0);
906   #ifdef debug_cdrom
907   command_result *rf;
908   #endif
909
910   if (doint)
762   verboselog(machine(), 1, "psxcd: unknown 12\n");
763   // set session? readt?
764   if(cmdbuf[0] == 1)
765      send_result(intr_complete);
766   else
911767   {
912      m_irq_handler(1);
768      status |= status_error;
769      send_result(intr_diskerror);
913770   }
771}
914772
915   add_result(res);
773void psxcd_device::cdcmd_illegal17()
774{
775   illegalcmd(0x17); // set clock?
776}
916777
917   #ifdef debug_cdrom
918      if (doint)
919      {
920         printf("cdrom: irq [");
921         for (rf=res_queue; ((rf) && (rf->next)); rf=rf->next);
922            printf("%d ",rf->res);
923         printf("]\n");
924      }
925   #endif
778void psxcd_device::cdcmd_illegal18()
779{
780   illegalcmd(0x18); // get clock?
926781}
927782
928//
929//
930//
783void psxcd_device::cdcmd_illegal1d()
784{
785   illegalcmd(0x1d); // read q subchannel
786}
931787
932void psxcd_device::add_result(command_result *res)
788void psxcd_device::illegalcmd(UINT8 cmd)
933789{
790   verboselog(machine(), 0, "psxcd: unimplemented cd command %02x\n", cmd);
791   command_result *res=global_alloc(command_result);
792   res->res=intr_diskerror;
793   res->data[0]=status | status_error;
794   res->data[1]=0x40; //invalid command
795   res->sz=2;
796   cmd_complete(res);
797}
798
799void psxcd_device::cmd_complete(command_result *res)
800{
934801   command_result *rf;
935802
803   verboselog(machine(), 1, "psxcd: irq [%d]\n", res->res);
804
936805   if (res_queue)
937806   {
938807      for (rf=res_queue; rf->next; rf=rf->next);
939808      rf->next=res;
940   } else
809   }
810   else
941811   {
942      res_queue=res;
812      res_queue = res;
813      m_regs.ir = res_queue->res & m_regs.imr; // or should it not trigger a masked irq?
814      if(m_regs.ir)
815         m_irq_handler(1);
816      m_regs.sr |= 0x20;
943817   }
944
945   res->next=NULL;
818   res->next = NULL;
946819}
947820
948//
949//
950//
951
952void psxcd_device::send_result(const unsigned int res,
953                                          const unsigned char *data,
954                                          const unsigned int sz,
955                                             const unsigned int delay)
821void psxcd_device::send_result(UINT8 res, UINT8 *data, int sz, int delay)
956822{
957823   command_result *cr=global_alloc(command_result);
958824
r22505r22506
982848   add_system_event(event_cmd_complete, delay, (void *)cr);
983849}
984850
985//
986//
987//
988
989851void psxcd_device::start_dma(UINT8 *mainram, UINT32 size)
990852{
991   if ((int)size>secleft)
992   {
993      logerror("cdrom: dma past end of sector (secleft=%d sz=%d)\n",secleft,size);
994   }
853   verboselog(machine(), 1, "psxcd: start dma %d bytes at %d\n", size, m_transcurr);
995854
996//  printf("cdrom: start dma %d bytes, %d remaining, secptr %p\n", size, secleft, secptr);
997   #ifdef debug_cdrom
998   if (size==12)
999   {
1000      char poo[1024],*pp=poo;
1001      for (unsigned int i=0; i<12; i++)
1002      {
1003         sprintf(pp,"%02x ",secptr[i]);
1004         pp+=3;
1005      }
1006      printf("cdrom: data=%s\n",poo);
1007   }
1008   #endif
855   if(!m_dmaload)
856      return;
1009857
1010   memcpy(mainram, secptr, size);
1011   memset(secptr, 0xff, size);
858   if(size > (raw_sector_size - m_transcurr))
859      size = (raw_sector_size - m_transcurr);
1012860
1013   secptr += size;
1014   secleft -= size;
1015
1016   if (secleft<0) secleft=0;
1017   if (secleft==0) sr&=~0x40;
861   memcpy(mainram, &m_transbuf[m_transcurr], size);
862   m_transcurr += size;
863   if(raw_sector_size <= m_transcurr)
864      m_regs.sr &= ~0x40;
1018865}
1019866
1020bool psxcd_device::read_next_sector()
1021{
1022   UINT32 pos=msf_to_lba_ps(curpos.w);
1023   unsigned char *buf=secbuf[sechead];
1024
1025//  printf("read_next_sector: sec %d, sechead %d, raw_sector_size %d\n", pos, sechead, raw_sector_size);
1026   if (cdrom_read_data(m_cdrom_handle, pos, buf, CD_TRACK_RAW_DONTCARE))
1027   {
1028//      printf("buf contents = %02x %02x | %02x %02x\n", buf[0], buf[1], buf[0x20], buf[0x21]);
1029
1030      sechead=(sechead+1)&(sector_buffer_size-1);
1031
1032      memcpy(lastsechdr,&secbuf[sectail][12],8);
1033
1034      return true;
1035   } else
1036   {
1037      return false;
1038   }
1039}
1040
1041//
1042//
1043//
1044
1045867void psxcd_device::read_sector()
1046868{
1047869   next_read_event=-1;
1048870
1049871   if (status & status_reading)
1050872   {
1051      bool isend=false;
1052
1053      if (read_next_sector())
873      bool isend = false;
874      UINT32 sector = msf_to_lba_ps(curpos.w);
875      UINT8 *buf = secbuf[sectail];
876      if (cdrom_read_data(m_cdrom_handle, sector, buf, CD_TRACK_RAW_DONTCARE))
1054877      {
1055         unsigned char *rawsec;
878         subheader *sub=(subheader *)(buf+16);
879         memcpy(lastsechdr, buf+12, 8);
1056880
1057         if ((mode&mode_adpcm) && (streaming))
881         verboselog(machine(), 2, "psxcd: subheader file=%02x chan=%02x submode=%02x coding=%02x [%02x%02x%02x%02x]\n",
882                  sub->file, sub->channel, sub->submode, sub->coding, buf[0xc], buf[0xd], buf[0xe], buf[0xf]);
883
884         if ((mode & mode_adpcm) && (sub->submode & submode_audio))
1058885         {
1059            rawsec=secbuf[sectail];
1060            secptr=rawsec+24;
1061            secleft=2048;
886            if ((sub->submode & submode_eof) && (mode & mode_autopause))
887            {
888               isend=true;
889               //printf("end of file\n");
890            }
891            if((!(mode & mode_channel) ||
892                  ((sub->file == filter_file) && (sub->channel == filter_channel))) && !m_mute)
893               m_spu->play_xa(0,buf+16);
1062894         }
1063895         else
1064896         {
1065            rawsec=secbuf[sectail];
1066            secptr=rawsec+secskip;
1067            secleft=secsize;
1068         }
897            command_result *res=global_alloc(command_result);
898            res->res=intr_dataready;
899            res->data[0]=status;
900            res->sz=1;
901            cmd_complete(res);
902            sectail++;
903            sectail %= sector_buffer_size;
1069904
1070         sectail=(sectail+1)&(sector_buffer_size-1);
1071
1072         subheader *sub=(subheader *)(rawsec+16);
1073
1074         #ifdef dump_subheader
1075            printf("cdrom: subheader file=%02x chan=%02x submode=%02x coding=%02x [%02x%02x%02x%02x]\n",
1076                  sub->file,
1077                  sub->channel,
1078                  sub->submode,
1079                  sub->coding,
1080                  rawsec[0xc],
1081                  rawsec[0xd],
1082                  rawsec[0xe],
1083                  rawsec[0xf]);
1084         #endif
1085
1086         status&=~status_playing;
1087         bool isxa=((mode&mode_adpcm) && (sub->submode&submode_audio));
1088
1089         if (((mode&mode_channel)==0) ||
1090               ((sub->file==filter_file) && (sub->channel==filter_channel)))
1091         {
1092            if (isxa)
1093            {
1094               if (sub->submode&submode_eof)
1095               {
1096                  isend=true;
1097                  //printf("end of file\n");
1098               }
1099               m_spu->play_xa(0,rawsec+16);
1100
1101               status|=status_playing;
1102            }
905            if(sectail == sechead)
906               verboselog(machine(), 0, "psxcd: sector buffer overrun\n");
1103907         }
1104908
1105         if ((mode&mode_autopause)==0)
1106            isend=false;
1107
1108         //
1109
1110909         curpos.b[F]++;
1111910         if (curpos.b[F]==75)
1112911         {
r22505r22506
1120919         }
1121920
1122921         loc.w=curpos.w;
1123
1124         sr|=0x40;
1125
1126         if(!(streaming && isxa))
1127         {
1128            command_result *res=global_alloc(command_result);
1129            res->res=isend?intr_dataend:intr_dataready;
1130            res->data[0]=status;
1131            res->sz=1;
1132            cmd_complete(res);
1133         }
1134922      }
923      else
924         isend = true;
1135925
1136926      if (! isend)
1137927      {
r22505r22506
1141931         next_sector_t+=cyc;
1142932
1143933         next_read_event = add_system_event(event_read_sector, cyc, NULL);
1144
1145         //read_next_sector();
1146934      } else
1147935      {
1148#ifdef debug_cdrom
1149         printf("autopause xa\n");
1150#endif
936         verboselog(machine(), 1, "psxcd: autopause xa\n");
937
938         command_result *res=global_alloc(command_result);
939         res->res=intr_dataend;
940         res->data[0]=status;
941         res->sz=1;
942         cmd_complete(res);
1151943         stop_read();
1152944      }
1153945   }
1154946}
1155947
1156//
1157//
1158//
1159
1160948void psxcd_device::play_sector()
1161949{
1162950   next_read_event=-1;
1163951
1164952   if (status&status_playing)
1165953   {
1166      if(!m_mute)
1167         m_spu->play_cdda(0,secbuf[sectail]);
1168      sectail=(sectail+1)&(sector_buffer_size-1);
954      UINT32 sector = msf_to_lba_ps(curpos.w);
1169955
956      if(cdrom_read_data(m_cdrom_handle, sector, secbuf[sectail], CD_TRACK_AUDIO))
957      {
958         if(!m_mute)
959            m_spu->play_cdda(0, secbuf[sectail]);
960      }
961      else
962      {
963         if(!cdrom_read_data(m_cdrom_handle, sector, secbuf[sectail], CD_TRACK_RAW_DONTCARE))
964         {
965            stop_read(); // assume we've reached the end
966            command_result *res=global_alloc(command_result);
967            res->res=intr_dataend;
968            res->data[0]=status;
969            res->sz=1;
970            cmd_complete(res);
971            return;
972         }
973      }
974
1170975      curpos.b[F]++;
1171976      if (curpos.b[F]==75)
1172977      {
r22505r22506
1180985      }
1181986
1182987      loc.w=curpos.w;
988      sector++;
989      sectail++;
990      sectail %= sector_buffer_size;
1183991
1184      //
1185
1186      UINT32 sector = msf_to_lba_ps(loc.w);
1187
1188992      if (mode&mode_autopause)
1189993      {
1190994         if (sector>=autopause_sector)
1191995         {
1192#ifdef debug_cdrom
1193            printf("autopause cdda\n");
1194#endif
996            verboselog(machine(), 1, "psxcd: autopause cdda\n");
997
1195998            stop_read();
1196999            command_result *res=global_alloc(command_result);
11971000            res->res=intr_dataend;
r22505r22506
12371040      next_sector_t+=cyc>>1;
12381041
12391042      next_read_event = add_system_event(event_play_sector, next_sector_t - m_maincpu->total_cycles(), NULL);
1240
1241      if(!read_next_sector())
1242      {
1243         stop_read(); // assume we've reached the end
1244         command_result *res=global_alloc(command_result);
1245         res->res=intr_dataend;
1246         res->data[0]=status;
1247         res->sz=1;
1248         cmd_complete(res);
1249      }
12501043   }
12511044}
12521045
1253
1254//
1255//
1256//
1257
1258void psxcd_device::preread_sector()
1046void psxcd_device::start_read()
12591047{
1260   UINT64 next_clock;
1261   int type;
1262   next_read_event=-1;
1048   UINT32 sector = msf_to_lba_ps(curpos.w);
12631049
1264   UINT32 pos=msf_to_lba_ps(curpos.w);
1265   //
1266   if(!(mode & mode_cdda) && (cdrom_get_track_type(m_cdrom_handle, cdrom_get_track(m_cdrom_handle, pos + 150)) == CD_TRACK_AUDIO))
1050   assert((status&(status_reading|status_playing))==0);
1051
1052   if(!(mode & mode_cdda) && (cdrom_get_track_type(m_cdrom_handle, cdrom_get_track(m_cdrom_handle, sector + 150)) == CD_TRACK_AUDIO))
12671053   {
1054      stop_read();
12681055      command_result *res=global_alloc(command_result);
12691056      res->res=intr_diskerror;
12701057      res->data[0]=status | status_error;
r22505r22506
12731060      cmd_complete(res);
12741061      return;
12751062   }
1063   send_result(intr_complete);
1064   status |= status_reading;   
12761065
1277   unsigned char *buf=secbuf[sechead];
1278   if (! cdrom_read_data(m_cdrom_handle, pos, buf, CD_TRACK_RAW_DONTCARE))
1279   {
1280      next_clock=(m_sysclock/60);
1281      type=event_preread_sector;
1282
1283      unsigned int cyc=read_sector_cycles;
1284      if (mode&mode_double_speed) cyc>>=1;
1285      next_sector_t=next_clock+(cyc-preread_delay)+m_maincpu->total_cycles();
1286   } else
1287   {
1288      memcpy(lastsechdr,buf+12,8);
1289
1290      //
1291
1292      command_result *res=global_alloc(command_result);
1293      res->res=intr_complete;
1294      res->data[0]=status;
1295      res->sz=1;
1296
1297      #ifdef debug_cdrom
1298         printf("cdrom: read acknowledge\n");
1299      #endif
1300
1301      cmd_complete(res);
1302
1303      //
1304
1305      next_clock=next_sector_t - m_maincpu->total_cycles();
1306      type=event_read_sector;
1307
1308      //read_next_sector();
1309   }
1310
1311   next_read_event = add_system_event(type, next_clock, NULL);
1312}
1313
1314//
1315//
1316//
1317
1318void psxcd_device::start_read()
1319{
1320   #ifdef debug_cdrom
1321      printf("cdrom: start read\n");
1322   #endif
1323
1324   assert((status&(status_reading|status_playing))==0);
1325
1326   status|=status_reading;
1327
13281066   sechead=sectail=0;
13291067
13301068   unsigned int cyc=read_sector_cycles;
r22505r22506
13351073   systime+=start_read_delay;
13361074
13371075   next_sector_t=systime+cyc;
1338   next_read_event = add_system_event(event_preread_sector, start_read_delay+preread_delay, NULL);
1076   next_read_event = add_system_event(event_read_sector, start_read_delay+preread_delay, NULL);
13391077}
13401078
1341//
1342//
1343//
1344
1345void psxcd_device::start_streaming()
1346{
1347   assert(! streaming);
1348
1349   streaming=true;
1350   start_read();
1351}
1352
1353//
1354//
1355//
1356
13571079void psxcd_device::start_play()
13581080{
1359   #ifdef debug_cdrom
1360      printf("cdrom: start play\n");
1361   #endif
1081   UINT8 track = cdrom_get_track(m_cdrom_handle, msf_to_lba_ps(curpos.w) + 150);
13621082
1083   if(cdrom_get_track_type(m_cdrom_handle, track) != CD_TRACK_AUDIO)
1084      verboselog(machine(), 0, "psxcd: playing data track\n");
1085
13631086   status|=status_playing;
13641087
13651088   sechead=sectail=0;
13661089
13671090   if (mode&mode_autopause)
13681091   {
1369      UINT8 track = cdrom_get_track(m_cdrom_handle, msf_to_lba_ps(curpos.w) + 150);
13701092      autopause_sector = cdrom_get_track_start(m_cdrom_handle, track) + cdrom_get_toc(m_cdrom_handle)->tracks[track].frames;
13711093//      printf("pos=%d auto=%d\n",pos,autopause_sector);
13721094   }
r22505r22506
13781100   next_sector_t+=cyc>>1;
13791101
13801102   next_read_event = add_system_event(event_play_sector, next_sector_t - m_maincpu->total_cycles(), NULL);
1381
1382   read_next_sector();
13831103}
13841104
1385//
1386//
1387//
1388
13891105void psxcd_device::stop_read()
13901106{
1391   #ifdef debug_cdrom
1392      if (status&status_reading)
1393         printf("cdrom: stop read\n");
1394   #endif
1107   if (status & (status_reading|status_playing))
1108      verboselog(machine(), 1, "psxcd: stop read\n");
1109
13951110   status&=~(status_reading|status_playing);
1396   streaming=false;
13971111
13981112   if (next_read_event != -1)
13991113   {
r22505r22506
14071121   m_spu->flush_cdda(sector);
14081122}
14091123
1410//
1411//
1412//
14131124void psxcd_device::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr)
14141125{
14151126   if (!m_timerinuse[tid])
14161127   {
1417      printf("cdrom:: timer fired for free event\n");
1128      verboselog(machine(), 0, "psxcd: timer fired for free event\n");
14181129      return;
14191130   }
14201131
r22505r22506
14231134   {
14241135      case event_cmd_complete:
14251136      {
1426         #ifdef debug_cdrom
1427            printf("cdrom:: event cmd complete\n");
1428         #endif
1137         verboselog(machine(), 1, "psxcd: event cmd complete\n");
14291138
14301139         cmd_complete((command_result *)ptr);
14311140         break;
14321141      }
14331142
1434      case event_preread_sector:
1435         preread_sector();
1436         break;
1437
14381143      case event_read_sector:
14391144         read_sector();
14401145         break;
r22505r22506
14541159{
14551160   // t is in maincpu clock cycles
14561161   UINT32 hz = m_sysclock / t;
1457//  printf("add_system_event: event type %d for %d hz (using timer %d)\n", ev->type, hz, tnum);
14581162   for(int i = 0; i < MAX_PSXCD_TIMERS; i++)
14591163   {
14601164      if(!m_timerinuse[i])
trunk/src/mess/machine/psxcd.h
r22505r22506
55#include "sound/spu.h"
66
77#define MAX_PSXCD_TIMERS    (4)
8const int num_commands=0x20;
98
10//
11//
12//
13
149//**************************************************************************
1510//  INTERFACE CONFIGURATION MACROS
1611//**************************************************************************
r22505r22506
2419class psxcd_device : public cdrom_image_device
2520{
2621public:
27
2822   psxcd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
2923
3024   // static configuration helpers
3125   template<class _Object> static devcb2_base &set_irq_handler(device_t &device, _Object object) { return downcast<psxcd_device &>(device).m_irq_handler.set_callback(object); }
3226   static void static_set_devname(device_t &device, const char *devname);
27   virtual bool call_load();
28   virtual void call_unload();
29
30   DECLARE_WRITE8_MEMBER( write );
31   DECLARE_READ8_MEMBER( read );
32   void start_dma(UINT8 *mainram, UINT32 size);
33
34protected:
35   virtual void device_start();
36   virtual void device_reset();
37   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
38
3339private:
40   void write_command(UINT8 byte);
41
42   typedef void (psxcd_device::*cdcmd)();
3443   struct command_result
3544   {
36      unsigned char data[32], sz, res;
45      UINT8 data[32], sz, res;
3746      command_result *next;
3847   };
39
40   static const unsigned int sector_buffer_size=16, default_irq_delay=16000;   //480;  //8000; //2000<<2;
41   static const unsigned int raw_sector_size=2352;
42
43   unsigned char sr,res,ir,cmdmode,
44                        cmdbuf[64],*cbp,
45                        mode,
46                        secbuf[sector_buffer_size][raw_sector_size],
47                        *secptr,
48                        filter_file,
49                        filter_channel,
50                        lastsechdr[8],
51                        status;
52   int rdp,secsize,secleft,secskip,
53         sechead,sectail;
54   command_result *res_queue,
55                           *cur_res;
56
5748   union CDPOS {
5849      UINT8 b[4];
5950      UINT32 w;
6051   };
61   CDPOS loc, curpos;
6252
63#ifdef LSB_FIRST
64   enum {
65      M = 2,
66      S = 1,
67      F = 0
68   };
69#else
70   enum {
71      M = 1,
72      S = 2,
73      F = 3
74   };
75#endif
76
77   bool open, m_mute,
78            streaming;
79   device_timer_id next_read_event;
80   INT64 next_sector_t;
81   unsigned int autopause_sector;
82
83   unsigned int start_read_delay,
84                        read_sector_cycles,
85                        preread_delay;
86
87   void write_command(const unsigned char byte);
88
89   struct command_info
90   {
91      void (psxcd_device::*func)();
92      const char *name;
93   };
94
9553   void cdcmd_sync();
9654   void cdcmd_nop();
9755   void cdcmd_setloc();
r22505r22506
11068   void cdcmd_getparam();
11169   void cdcmd_getlocl();
11270   void cdcmd_getlocp();
113   void cdcmd_illegal();
11471   void cdcmd_gettn();
11572   void cdcmd_gettd();
11673   void cdcmd_seekl();
r22505r22506
12077   void cdcmd_reads();
12178   void cdcmd_reset();
12279   void cdcmd_readtoc();
80   void cdcmd_unknown12();
81   void cdcmd_illegal17();
82   void cdcmd_illegal18();
83   void cdcmd_illegal1d();
12384
124   static command_info cmd_table[num_commands];
85   static const cdcmd cmd_table[31];
86   void illegalcmd(UINT8 cmd);
12587
12688   void cmd_complete(command_result *res);
127   void add_result(command_result *res);
128   void send_result(const unsigned int res,
129                                 const unsigned char *data=NULL,
130                                 const unsigned int sz=0,
131                                 const unsigned int delay=default_irq_delay);
89   void send_result(UINT8 res, UINT8 *data=NULL, int sz=0, int delay=default_irq_delay);
13290
13391   void start_read();
13492   void start_play();
135   void start_streaming();
13693   void stop_read();
13794   void read_sector();
138   bool read_next_sector();
13995   void play_sector();
140   void preread_sector();
14196   UINT32 sub_loc(CDPOS src1, CDPOS src2);
97   int add_system_event(int type, UINT64 t, void *ptr);
14298
143public:
99   UINT8 bcd_to_decimal(const UINT8 bcd) { return ((bcd>>4)*10)+(bcd&0xf); }
100   UINT8 decimal_to_bcd(const UINT8 dec) { return ((dec/10)<<4)|(dec%10); }
101   UINT32 msf_to_lba_ps(UINT32 msf) { msf = msf_to_lba(msf); return (msf>150)?(msf-150):msf; }
102   UINT32 lba_to_msf_ps(UINT32 lba) { return lba_to_msf_alt(lba+150); }
144103
145   virtual void device_start();
146   virtual void device_reset();
147   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
148   virtual bool call_load();
149   virtual void call_unload();
104   static const unsigned int sector_buffer_size=16, default_irq_delay=16000;   //480;  //8000; //2000<<2;
105   static const unsigned int raw_sector_size=2352;
150106
151   void start_dma(UINT8 *mainram, UINT32 size);
107   UINT8 cmdbuf[64], mode, secbuf[sector_buffer_size][raw_sector_size];
108   UINT8 filter_file, filter_channel, lastsechdr[8], status;
109   int rdp;
110   UINT8 sechead, sectail;
111   UINT16 m_transcurr;
112   UINT8 m_transbuf[raw_sector_size];
113   command_result *res_queue;
152114
153   DECLARE_WRITE8_MEMBER( write );
154   DECLARE_READ8_MEMBER( read );
115   struct {
116      UINT8 sr, ir, imr;
117      struct {
118         UINT8 ll, lr, rl, rr;
119      } vol;
120   } m_regs;
155121
156private:
122   CDPOS loc, curpos;
123
124#ifdef LSB_FIRST
125   enum {
126      M = 2,
127      S = 1,
128      F = 0
129   };
130#else
131   enum {
132      M = 1,
133      S = 2,
134      F = 3
135   };
136#endif
137
138   bool open, m_mute, m_dmaload;
139   device_timer_id next_read_event;
140   INT64 next_sector_t;
141   unsigned int autopause_sector, start_read_delay, read_sector_cycles, preread_delay;
142
157143   UINT32 m_param_count;
158144   UINT32 m_sysclock;
159145   emu_timer *m_timers[MAX_PSXCD_TIMERS];
160146   bool m_timerinuse[MAX_PSXCD_TIMERS];
161147
162   int add_system_event(int type, UINT64 t, void *ptr);
163148
164149   devcb2_write_line m_irq_handler;
165150   cpu_device *m_maincpu;
166151   spu_device *m_spu;
167
168   UINT8 bcd_to_decimal(const UINT8 bcd) { return ((bcd>>4)*10)+(bcd&0xf); }
169   UINT8 decimal_to_bcd(const UINT8 dec) { return ((dec/10)<<4)|(dec%10); }
170   UINT32 msf_to_lba_ps(UINT32 msf) { msf = msf_to_lba(msf); return (msf>150)?(msf-150):msf; }
171   UINT32 lba_to_msf_ps(UINT32 lba) { return lba_to_msf_alt(lba+150); }
172
173152};
174153
175154// device type definition

Previous 199869 Revisions Next


© 1997-2024 The MAME Team