platform ps2, handle audio similar to psp
[picodrive.git] / pico / cd / cdc.c
... / ...
CommitLineData
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
71enum 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 */
80typedef 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
97static cdc_t cdc;
98
99void cdc_init(void)
100{
101 memset(&cdc, 0, sizeof(cdc_t));
102}
103
104void 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
134int 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
170int 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
203int 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
248static 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
336update_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
348void 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
398int 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
463void 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
716unsigned 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
808unsigned 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