1163cb28afda3b48b1debb243f3e469f2ab5deef
[picodrive.git] / pico / cd / cdc.c
1 /***************************************************************************************
2  *  Genesis Plus
3  *  CD data controller (LC89510 compatible)
4  *
5  *  Copyright (C) 2012  Eke-Eke (Genesis Plus GX)
6  *
7  *  Redistribution and use of this code or any derivative works are permitted
8  *  provided that the following conditions are met:
9  *
10  *   - Redistributions may not be sold, nor may they be used in a commercial
11  *     product or activity.
12  *
13  *   - Redistributions that are modified from the original source must include the
14  *     complete source code, including the source code for all components used by a
15  *     binary built from the modified sources. However, as a special exception, the
16  *     source code distributed need not include anything that is normally distributed
17  *     (in either source or binary form) with the major components (compiler, kernel,
18  *     and so on) of the operating system on which the executable runs, unless that
19  *     component itself accompanies the executable.
20  *
21  *   - Redistributions must reproduce the above copyright notice, this list of
22  *     conditions and the following disclaimer in the documentation and/or other
23  *     materials provided with the distribution.
24  *
25  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  *  POSSIBILITY OF SUCH DAMAGE.
36  *
37  ****************************************************************************************/
38
39 #include "../pico_int.h"
40 #include "genplus_macros.h"
41
42 /* IFSTAT register bitmasks */
43 #define BIT_DTEI  0x40
44 #define BIT_DECI  0x20
45 #define BIT_DTBSY 0x08
46 #define BIT_DTEN  0x02
47
48 /* IFCTRL register bitmasks */
49 #define BIT_DTEIEN  0x40
50 #define BIT_DECIEN  0x20
51 #define BIT_DOUTEN  0x02
52
53 /* CTRL0 register bitmasks */
54 #define BIT_DECEN   0x80
55 #define BIT_E01RQ   0x20
56 #define BIT_AUTORQ  0x10
57 #define BIT_WRRQ    0x04
58
59 /* CTRL1 register bitmasks */
60 #define BIT_MODRQ   0x08
61 #define BIT_FORMRQ  0x04
62 #define BIT_SHDREN  0x01
63
64 /* CTRL2 register bitmask */
65 #define BIT_VALST   0x80
66
67 /* PicoDrive: doing DMA at once, not using callbacks */
68 //#define DMA_BYTES_PER_LINE 512
69 #define DMA_CYCLES_PER_BYTE 4   // or 6?
70
71 enum dma_type {
72   word_ram_0_dma_w = 1,
73   word_ram_1_dma_w = 2,
74   word_ram_2M_dma_w = 3,
75   pcm_ram_dma_w = 4,
76   prg_ram_dma_w = 5,
77 };
78
79 /* CDC hardware */
80 typedef struct
81 {
82   uint8 ifstat;
83   uint8 ifctrl;
84   uint16 dbc;
85   uint16 dac;
86   uint16 pt;
87   uint16 wa;
88   uint8 ctrl[2];
89   uint8 head[2][4];
90   uint8 stat[4];
91   int cycles;
92   //void (*dma_w)(unsigned int words);
93   int dma_w;
94   uint8 ram[0x4000 + 2352]; /* 16K external RAM (with one block overhead to handle buffer overrun) */
95 } cdc_t; 
96
97 static cdc_t cdc;
98
99 void cdc_init(void)
100 {
101   memset(&cdc, 0, sizeof(cdc_t));
102 }
103
104 void cdc_reset(void)
105 {
106   /* reset CDC register index */
107   Pico_mcd->s68k_regs[0x04+1] = 0x00;
108
109   /* reset CDC registers */
110   cdc.ifstat  = 0xff;
111   cdc.ifctrl  = 0x00;
112   cdc.ctrl[0] = 0x00;
113   cdc.ctrl[1] = 0x00;
114   cdc.stat[0] = 0x00;
115   cdc.stat[1] = 0x00;
116   cdc.stat[2] = 0x00;
117   cdc.stat[3] = 0x80;
118   cdc.head[0][0] = 0x00;
119   cdc.head[0][1] = 0x00;
120   cdc.head[0][2] = 0x00;
121   cdc.head[0][3] = 0x01;
122   cdc.head[1][0] = 0x00;
123   cdc.head[1][1] = 0x00;
124   cdc.head[1][2] = 0x00;
125   cdc.head[1][3] = 0x00;
126
127   /* reset CDC cycle counter */
128   cdc.cycles = 0;
129
130   /* DMA transfer disabled */
131   cdc.dma_w = 0;
132 }
133
134 int cdc_context_save(uint8 *state)
135 {
136   uint8 tmp8;
137   int bufferptr = 0;
138
139   if (cdc.dma_w == pcm_ram_dma_w)
140   {
141     tmp8 = 1;
142   }
143   else if (cdc.dma_w == prg_ram_dma_w)
144   {
145     tmp8 = 2;
146   }
147   else if (cdc.dma_w == word_ram_0_dma_w)
148   {
149     tmp8 = 3;
150   }
151   else if (cdc.dma_w == word_ram_1_dma_w)
152   {
153     tmp8 = 4;
154   }
155   else if (cdc.dma_w == word_ram_2M_dma_w)
156   {
157     tmp8 = 5;
158   }
159   else
160   {
161     tmp8 = 0;
162   }
163
164   save_param(&cdc, sizeof(cdc));
165   save_param(&tmp8, 1);
166
167   return bufferptr;
168 }
169
170 int cdc_context_load(uint8 *state)
171 {
172   uint8 tmp8;
173   int bufferptr = 0;
174
175   load_param(&cdc, sizeof(cdc));
176   load_param(&tmp8, 1);
177
178   switch (tmp8)
179   {
180     case 1:
181       cdc.dma_w = pcm_ram_dma_w;
182       break;
183     case 2:
184       cdc.dma_w = prg_ram_dma_w;
185       break;
186     case 3:
187       cdc.dma_w = word_ram_0_dma_w;
188       break;
189     case 4:
190       cdc.dma_w = word_ram_1_dma_w;
191       break;
192     case 5:
193       cdc.dma_w = word_ram_2M_dma_w;
194       break;
195     default:
196       cdc.dma_w = 0;
197       break;
198   }
199
200   return bufferptr;
201 }
202
203 int cdc_context_load_old(uint8 *state)
204 {
205 #define old_load(v, ofs) \
206   memcpy(&cdc.v, state + ofs, sizeof(cdc.v))
207
208   memcpy(cdc.ram, state, 0x4000);
209   old_load(ifstat, 67892);
210   old_load(ifctrl, 67924);
211   old_load(dbc, 67896);
212   old_load(dac, 67900);
213   old_load(pt, 67908);
214   old_load(wa, 67912);
215   old_load(ctrl, 67928);
216   old_load(head[0], 67904);
217   old_load(stat, 67916);
218
219   cdc.dma_w = 0;
220   switch (Pico_mcd->s68k_regs[0x04+0] & 0x07)
221   {
222     case 4: /* PCM RAM DMA */
223       cdc.dma_w = pcm_ram_dma_w;
224       break;
225     case 5: /* PRG-RAM DMA */
226       cdc.dma_w = prg_ram_dma_w;
227       break;
228     case 7: /* WORD-RAM DMA */
229       if (Pico_mcd->s68k_regs[0x02+1] & 0x04)
230       {
231         if (Pico_mcd->s68k_regs[0x02+1] & 0x01)
232           cdc.dma_w = word_ram_0_dma_w;
233         else
234           cdc.dma_w = word_ram_1_dma_w;
235       }
236       else
237       {
238         if (Pico_mcd->s68k_regs[0x02+1] & 0x02)
239           cdc.dma_w = word_ram_2M_dma_w;
240       }
241       break;
242   }
243
244   return 0x10960; // sizeof(old_cdc)
245 #undef old_load
246 }
247
248 static void do_dma(enum dma_type type, int bytes_in)
249 {
250   int dma_addr = (Pico_mcd->s68k_regs[0x0a] << 8) | Pico_mcd->s68k_regs[0x0b];
251   int src_addr = cdc.dac & 0x3ffe;
252   int dst_addr = dma_addr;
253   int bytes = bytes_in;
254   int words = bytes_in >> 1;
255   int dst_limit = 0;
256   uint8 *dst;
257   int len;
258
259   elprintf(EL_CD, "dma %d %04x->%04x %x",
260     type, cdc.dac, dst_addr, bytes_in);
261
262   switch (type)
263   {
264     case pcm_ram_dma_w:
265       dst_addr = (dst_addr << 2) & 0xffc;
266       if (dst_addr + bytes > 0x1000) {
267         elprintf(EL_ANOMALY, "pcm dma oflow: %x %x", dst_addr, words);
268         bytes = 0x1000 - dst_addr;
269       }
270       dst = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank];
271       dst = dst + dst_addr;
272       while (bytes > 0)
273       {
274         if (src_addr + bytes > 0x4000) {
275           len = 0x4000 - src_addr;
276           memcpy(dst, cdc.ram + src_addr, len);
277           dst += len;
278           src_addr = 0;
279           bytes -= len;
280           continue;
281         }
282         memcpy(dst, cdc.ram + src_addr, bytes);
283         break;
284       }
285       goto update_dma;
286
287     case prg_ram_dma_w:
288       dst_addr <<= 3;
289       dst = Pico_mcd->prg_ram + dst_addr;
290       dst_limit = 0x80000;
291       break;
292
293     case word_ram_0_dma_w:
294       dst_addr = (dst_addr << 3) & 0x1fffe;
295       dst = Pico_mcd->word_ram1M[0] + dst_addr;
296       dst_limit = 0x20000;
297       break;
298
299     case word_ram_1_dma_w:
300       dst_addr = (dst_addr << 3) & 0x1fffe;
301       dst = Pico_mcd->word_ram1M[1] + dst_addr;
302       dst_limit = 0x20000;
303       break;
304
305     case word_ram_2M_dma_w:
306       dst_addr = (dst_addr << 3) & 0x3fffe;
307       dst = Pico_mcd->word_ram2M + dst_addr;
308       dst_limit = 0x40000;
309       break;
310
311     default:
312       elprintf(EL_ANOMALY, "invalid dma: %d", type);
313       goto update_dma;
314   }
315
316   if (dst_addr + words * 2 > dst_limit) {
317     elprintf(EL_ANOMALY, "cd dma %d oflow: %x %x", type, dst_addr, words);
318     words = (dst_limit - dst_addr) / 2;
319   }
320   while (words > 0)
321   {
322     if (src_addr + words * 2 > 0x4000) {
323       len = 0x4000 - src_addr;
324       memcpy16bswap((void *)dst, cdc.ram + src_addr, len / 2);
325       dst += len;
326       src_addr = 0;
327       words -= len / 2;
328       continue;
329     }
330     memcpy16bswap((void *)dst, cdc.ram + src_addr, words);
331     break;
332   }
333
334   bytes_in &= ~1; // Todo leftover byte?
335
336 update_dma:
337   /* update DMA addresses */
338   cdc.dac += bytes_in;
339   if (type == pcm_ram_dma_w)
340     dma_addr += bytes_in >> 2;
341   else
342     dma_addr += bytes_in >> 3;
343
344   Pico_mcd->s68k_regs[0x0a] = dma_addr >> 8;
345   Pico_mcd->s68k_regs[0x0b] = dma_addr;
346 }
347
348 void cdc_dma_update(void)
349 {
350   /* end of DMA transfer ? */
351   //if (cdc.dbc < DMA_BYTES_PER_LINE)
352   {
353     /* transfer remaining words using 16-bit DMA */
354     //cdc.dma_w((cdc.dbc + 1) >> 1);
355     do_dma(cdc.dma_w, cdc.dbc + 1);
356
357     /* reset data byte counter (DBCH bits 4-7 should be set to 1) */
358     cdc.dbc = 0xffff;
359
360     /* clear !DTEN and !DTBSY */
361     cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
362
363     /* clear DSR bit & set EDT bit (SCD register $04) */
364     Pico_mcd->s68k_regs[0x04+0] = (Pico_mcd->s68k_regs[0x04+0] & 0x07) | 0x80;
365
366     if (cdc.ifstat & BIT_DTEI) {
367       /* pending Data Transfer End interrupt */
368       cdc.ifstat &= ~BIT_DTEI;
369
370       /* Data Transfer End interrupt enabled ? */
371       if (cdc.ifctrl & BIT_DTEIEN)
372       {
373         /* level 5 interrupt enabled ? */
374         if (Pico_mcd->s68k_regs[0x32+1] & PCDS_IEN5)
375         {
376           /* update IRQ level */
377           elprintf(EL_INTS, "cdc DTE irq 5");
378           pcd_irq_s68k(5, 1);
379         }
380       }
381     }
382
383     /* disable DMA transfer */
384     cdc.dma_w = 0;
385   }
386 #if 0
387   else
388   {
389     /* transfer all words using 16-bit DMA */
390     cdc.dma_w(DMA_BYTES_PER_LINE >> 1);
391
392     /* decrement data byte counter */
393     cdc.dbc -= length;
394   }
395 #endif
396 }
397
398 int cdc_decoder_update(uint8 header[4])
399 {
400   /* data decoding enabled ? */
401   if (cdc.ctrl[0] & BIT_DECEN)
402   {
403     /* update HEAD registers */
404     memcpy(cdc.head[0], header, sizeof(cdc.head[0]));
405
406     /* set !VALST */
407     cdc.stat[3] = 0x00;
408
409     /* set CRCOK bit */
410     cdc.stat[0] = BIT_DECEN;
411
412     /* pending decoder interrupt */
413     cdc.ifstat &= ~BIT_DECI;
414
415     /* decoder interrupt enabled ? */
416     if (cdc.ifctrl & BIT_DECIEN)
417     {
418       /* level 5 interrupt enabled ? */
419       if (Pico_mcd->s68k_regs[0x32+1] & PCDS_IEN5)
420       {
421         /* update IRQ level */
422         elprintf(EL_INTS, "cdc DEC irq 5");
423         pcd_irq_s68k(5, 1);
424       }
425     }
426
427     /* buffer RAM write enabled ? */
428     if (cdc.ctrl[0] & BIT_WRRQ)
429     {
430       uint16 offset;
431
432       /* increment block pointer  */
433       cdc.pt += 2352;
434
435       /* increment write address */
436       cdc.wa += 2352;
437
438       /* CDC buffer address */
439       offset = cdc.pt & 0x3fff;
440
441       /* write CDD block header (4 bytes) */
442       memcpy(cdc.ram + offset, header, 4);
443
444       /* write CDD block data (2048 bytes) */
445       cdd_read_data(cdc.ram + 4 + offset);
446
447       /* take care of buffer overrun */
448       if (offset > (0x4000 - 2048 - 4))
449       {
450         /* data should be written at the start of buffer */
451         memcpy(cdc.ram, cdc.ram + 0x4000, offset + 2048 + 4 - 0x4000);
452       }
453
454       /* read next data block */
455       return 1;
456     }
457   }
458   
459   /* keep decoding same data block if Buffer Write is disabled */
460   return 0;
461 }
462
463 void cdc_reg_w(unsigned char data)
464 {
465 #ifdef LOG_CDC
466   elprintf(EL_STATUS, "CDC register %X write 0x%04x", Pico_mcd->s68k_regs[0x04+1] & 0x0F, data);
467 #endif
468   switch (Pico_mcd->s68k_regs[0x04+1] & 0x1F)
469   {
470     case 0x00:
471       break;
472
473     case 0x01:  /* IFCTRL */
474     {
475       /* pending interrupts ? */
476       if (((data & BIT_DTEIEN) && !(cdc.ifstat & BIT_DTEI)) ||
477           ((data & BIT_DECIEN) && !(cdc.ifstat & BIT_DECI)))
478       {
479         /* level 5 interrupt enabled ? */
480         if (Pico_mcd->s68k_regs[0x32+1] & PCDS_IEN5)
481         {
482           /* update IRQ level */
483           elprintf(EL_INTS, "cdc pending irq 5");
484           pcd_irq_s68k(5, 1);
485         }
486       }
487       else // if (scd.pending & (1 << 5))
488       {
489         /* clear pending level 5 interrupts */
490         pcd_irq_s68k(5, 0);
491       }
492
493       /* abort any data transfer if data output is disabled */
494       if (!(data & BIT_DOUTEN))
495       {
496         /* clear !DTBSY and !DTEN */
497         cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
498       }
499
500       cdc.ifctrl = data;
501       Pico_mcd->s68k_regs[0x04+1] = 0x02;
502       break;
503     }
504
505     case 0x02:  /* DBCL */
506       cdc.dbc &= 0xff00;
507       cdc.dbc |= data;
508       Pico_mcd->s68k_regs[0x04+1] = 0x03;
509       break;
510
511     case 0x03:  /* DBCH */
512       cdc.dbc &= 0x00ff;
513       cdc.dbc |= (data & 0x0f) << 8;
514       Pico_mcd->s68k_regs[0x04+1] = 0x04;
515       break;
516
517     case 0x04:  /* DACL */
518       cdc.dac &= 0xff00;
519       cdc.dac |= data;
520       Pico_mcd->s68k_regs[0x04+1] = 0x05;
521       break;
522
523     case 0x05:  /* DACH */
524       cdc.dac &= 0x00ff;
525       cdc.dac |= data << 8;
526       Pico_mcd->s68k_regs[0x04+1] = 0x06;
527       break;
528
529     case 0x06:  /* DTRG */
530     {
531       /* start data transfer if data output is enabled */
532       if (cdc.ifctrl & BIT_DOUTEN)
533       {
534         /* set !DTBSY */
535         cdc.ifstat &= ~BIT_DTBSY;
536
537         /* clear DBCH bits 4-7 */
538         cdc.dbc &= 0x0fff;
539
540         /* clear EDT & DSR bits (SCD register $04) */
541         Pico_mcd->s68k_regs[0x04+0] &= 0x07;
542
543         cdc.dma_w = 0;
544
545         /* setup data transfer destination */
546         switch (Pico_mcd->s68k_regs[0x04+0] & 0x07)
547         {
548           case 2: /* MAIN-CPU host read */
549           case 3: /* SUB-CPU host read */
550           {
551             /* set !DTEN */
552             cdc.ifstat &= ~BIT_DTEN;
553
554             /* set DSR bit (register $04) */
555             Pico_mcd->s68k_regs[0x04+0] |= 0x40;
556             break;
557           }
558
559           case 4: /* PCM RAM DMA */
560           {
561             cdc.dma_w = pcm_ram_dma_w;
562             break;
563           }
564
565           case 5: /* PRG-RAM DMA */
566           {
567             cdc.dma_w = prg_ram_dma_w;
568             break;
569           }
570
571           case 7: /* WORD-RAM DMA */
572           {
573             /* check memory mode */
574             if (Pico_mcd->s68k_regs[0x02+1] & 0x04)
575             {
576               /* 1M mode */
577               if (Pico_mcd->s68k_regs[0x02+1] & 0x01)
578               {
579                 /* Word-RAM bank 0 is assigned to SUB-CPU */
580                 cdc.dma_w = word_ram_0_dma_w;
581               }
582               else
583               {
584                 /* Word-RAM bank 1 is assigned to SUB-CPU */
585                 cdc.dma_w = word_ram_1_dma_w;
586               }
587             }
588             else
589             {
590               /* 2M mode */
591               if (Pico_mcd->s68k_regs[0x02+1] & 0x02)
592               {
593                 /* only process DMA if Word-RAM is assigned to SUB-CPU */
594                 cdc.dma_w = word_ram_2M_dma_w;
595               }
596             }
597             break;
598           }
599
600           default: /* invalid */
601           {
602             elprintf(EL_ANOMALY, "invalid CDC tranfer destination (%d)",
603               Pico_mcd->s68k_regs[0x04+0] & 0x07);
604             break;
605           }
606         }
607
608         if (cdc.dma_w)
609           pcd_event_schedule_s68k(PCD_EVENT_DMA, cdc.dbc * DMA_CYCLES_PER_BYTE);
610       }
611
612       Pico_mcd->s68k_regs[0x04+1] = 0x07;
613       break;
614     }
615
616     case 0x07:  /* DTACK */
617     {
618       /* clear pending data transfer end interrupt */
619       cdc.ifstat |= BIT_DTEI;
620
621       /* clear DBCH bits 4-7 */
622       cdc.dbc &= 0x0fff;
623
624 #if 0
625       /* no pending decoder interrupt ? */
626       if ((cdc.ifstat | BIT_DECI) || !(cdc.ifctrl & BIT_DECIEN))
627       {
628         /* clear pending level 5 interrupt */
629         pcd_irq_s68k(5, 0);
630       }
631 #endif
632       Pico_mcd->s68k_regs[0x04+1] = 0x08;
633       break;
634     }
635
636     case 0x08:  /* WAL */
637       cdc.wa &= 0xff00;
638       cdc.wa |= data;
639       Pico_mcd->s68k_regs[0x04+1] = 0x09;
640       break;
641
642     case 0x09:  /* WAH */
643       cdc.wa &= 0x00ff;
644       cdc.wa |= data << 8;
645       Pico_mcd->s68k_regs[0x04+1] = 0x0a;
646       break;
647
648     case 0x0a:  /* CTRL0 */
649     {
650       /* reset DECI if decoder turned off */
651       if (!(data & BIT_DECEN))
652         cdc.ifstat |= BIT_DECI;
653
654       /* update decoding mode */
655       if (data & BIT_AUTORQ)
656       {
657         /* set MODE bit according to CTRL1 register & clear FORM bit */
658         cdc.stat[2] = cdc.ctrl[1] & BIT_MODRQ;
659       }
660       else 
661       {
662         /* set MODE & FORM bits according to CTRL1 register */
663         cdc.stat[2] = cdc.ctrl[1] & (BIT_MODRQ | BIT_FORMRQ);
664       }
665
666       cdc.ctrl[0] = data;
667       Pico_mcd->s68k_regs[0x04+1] = 0x0b;
668       break;
669     }
670
671     case 0x0b:  /* CTRL1 */
672     {
673       /* update decoding mode */
674       if (cdc.ctrl[0] & BIT_AUTORQ)
675       {
676         /* set MODE bit according to CTRL1 register & clear FORM bit */
677         cdc.stat[2] = data & BIT_MODRQ;
678       }
679       else 
680       {
681         /* set MODE & FORM bits according to CTRL1 register */
682         cdc.stat[2] = data & (BIT_MODRQ | BIT_FORMRQ);
683       }
684
685       cdc.ctrl[1] = data;
686       Pico_mcd->s68k_regs[0x04+1] = 0x0c;
687       break;
688     }
689
690     case 0x0c:  /* PTL */
691       cdc.pt &= 0xff00;
692       cdc.pt |= data;
693       Pico_mcd->s68k_regs[0x04+1] = 0x0d;
694       break;
695   
696     case 0x0d:  /* PTH */
697       cdc.pt &= 0x00ff;
698       cdc.pt |= data << 8;
699       Pico_mcd->s68k_regs[0x04+1] = 0x0e;
700       break;
701
702     case 0x0e:  /* CTRL2 (unused) */
703       Pico_mcd->s68k_regs[0x04+1] = 0x0f;
704       break;
705
706     case 0x0f:  /* RESET */
707       cdc_reset();
708       break;
709
710     default:  /* by default, SBOUT is not used */
711       Pico_mcd->s68k_regs[0x04+1] = (Pico_mcd->s68k_regs[0x04+1] + 1) & 0x1f;
712       break;
713   }
714 }
715
716 unsigned char cdc_reg_r(void)
717 {
718   switch (Pico_mcd->s68k_regs[0x04+1] & 0x1F)
719   {
720     case 0x00:
721       return 0xff;
722
723     case 0x01:  /* IFSTAT */
724       Pico_mcd->s68k_regs[0x04+1] = 0x02;
725       return cdc.ifstat;
726
727     case 0x02:  /* DBCL */
728       Pico_mcd->s68k_regs[0x04+1] = 0x03;
729       return cdc.dbc & 0xff;
730
731     case 0x03:  /* DBCH */
732       Pico_mcd->s68k_regs[0x04+1] = 0x04;
733       return (cdc.dbc >> 8) & 0xff;
734
735     case 0x04:  /* HEAD0 */
736       Pico_mcd->s68k_regs[0x04+1] = 0x05;
737       return cdc.head[cdc.ctrl[1] & BIT_SHDREN][0];
738
739     case 0x05:  /* HEAD1 */
740       Pico_mcd->s68k_regs[0x04+1] = 0x06;
741       return cdc.head[cdc.ctrl[1] & BIT_SHDREN][1];
742
743     case 0x06:  /* HEAD2 */
744       Pico_mcd->s68k_regs[0x04+1] = 0x07;
745       return cdc.head[cdc.ctrl[1] & BIT_SHDREN][2];
746
747     case 0x07:  /* HEAD3 */
748       Pico_mcd->s68k_regs[0x04+1] = 0x08;
749       return cdc.head[cdc.ctrl[1] & BIT_SHDREN][3];
750
751     case 0x08:  /* PTL */
752       Pico_mcd->s68k_regs[0x04+1] = 0x09;
753       return cdc.pt & 0xff;
754
755     case 0x09:  /* PTH */
756       Pico_mcd->s68k_regs[0x04+1] = 0x0a;
757       return (cdc.pt >> 8) & 0xff;
758
759     case 0x0a:  /* WAL */
760       Pico_mcd->s68k_regs[0x04+1] = 0x0b;
761       return cdc.wa & 0xff;
762
763     case 0x0b:  /* WAH */
764       Pico_mcd->s68k_regs[0x04+1] = 0x0c;
765       return (cdc.wa >> 8) & 0xff;
766
767     case 0x0c: /* STAT0 */
768       Pico_mcd->s68k_regs[0x04+1] = 0x0d;
769       return cdc.stat[0];
770
771     case 0x0d: /* STAT1 (always return 0) */
772       Pico_mcd->s68k_regs[0x04+1] = 0x0e;
773       return 0x00;
774
775     case 0x0e:  /* STAT2 */
776       Pico_mcd->s68k_regs[0x04+1] = 0x0f;
777       return cdc.stat[2];
778
779     case 0x0f:  /* STAT3 */
780     {
781       uint8 data = cdc.stat[3];
782
783       /* clear !VALST (note: this is not 100% correct but BIOS do not seem to care) */
784       cdc.stat[3] = BIT_VALST;
785
786       /* clear pending decoder interrupt */
787       cdc.ifstat |= BIT_DECI;
788       
789 #if 0
790       /* no pending data transfer end interrupt */
791       if ((cdc.ifstat | BIT_DTEI) || !(cdc.ifctrl & BIT_DTEIEN))
792       {
793         /* clear pending level 5 interrupt */
794         pcd_irq_s68k(5, 0);
795       }
796 #endif
797
798       Pico_mcd->s68k_regs[0x04+1] = 0x10;
799       return data;
800     }
801
802     default:  /* by default, COMIN is always empty */
803       Pico_mcd->s68k_regs[0x04+1] = (Pico_mcd->s68k_regs[0x04+1] + 1) & 0x1f;
804       return 0xff;
805   }
806 }
807
808 unsigned short cdc_host_r(void)
809 {
810   /* check if data is available */
811   if (!(cdc.ifstat & BIT_DTEN))
812   {
813     /* read data word from CDC RAM buffer */
814     uint8 *datap = cdc.ram + (cdc.dac & 0x3ffe);
815     uint16 data = (datap[0] << 8) | datap[1];
816
817 #ifdef LOG_CDC
818     error("CDC host read 0x%04x -> 0x%04x (dbc=0x%x) (%X)\n", cdc.dac, data, cdc.dbc, s68k.pc);
819 #endif
820  
821     /* increment data address counter */
822     cdc.dac += 2;
823
824     /* decrement data byte counter */
825     cdc.dbc -= 2;
826
827     /* end of transfer ? */
828     if ((int16)cdc.dbc <= 0)
829     {
830       /* reset data byte counter (DBCH bits 4-7 should be set to 1) */
831       cdc.dbc = 0xffff;
832
833       /* clear !DTEN and !DTBSY */
834       cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
835
836       /* clear DSR bit & set EDT bit (SCD register $04) */
837       Pico_mcd->s68k_regs[0x04+0] = (Pico_mcd->s68k_regs[0x04+0] & 0x07) | 0x80;
838
839     } else if ((int16)cdc.dbc <= 2)
840     {
841       if (cdc.ifstat & BIT_DTEI) {
842         /* pending Data Transfer End interrupt */
843         cdc.ifstat &= ~BIT_DTEI;
844
845         /* Data Transfer End interrupt enabled ? */
846         if (cdc.ifctrl & BIT_DTEIEN)
847         {
848           /* level 5 interrupt enabled ? */
849           if (Pico_mcd->s68k_regs[0x32+1] & PCDS_IEN5)
850           {
851             /* update IRQ level */
852             elprintf(EL_INTS, "cdc DTE irq 5");
853             pcd_irq_s68k(5, 1);
854           }
855         }
856       }
857       /* set DSR and EDT bit (SCD register $04) */
858       Pico_mcd->s68k_regs[0x04+0] = (Pico_mcd->s68k_regs[0x04+0] & 0x07) | 0xc0;
859     }
860
861     return data;
862   }
863
864 #ifdef LOG_CDC
865   error("error reading CDC host (data transfer disabled)\n");
866 #endif
867   return 0xffff;
868 }
869
870 // vim:shiftwidth=2:ts=2:expandtab