cd: switch to CD drive emu code from genplus
[picodrive.git] / pico / cd / cdc.c
CommitLineData
3f23709e 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
70enum dma_type {
71 word_ram_0_dma_w = 1,
72 word_ram_1_dma_w = 2,
73 word_ram_2M_dma_w = 3,
74 pcm_ram_dma_w = 4,
75 prg_ram_dma_w = 5,
76};
77
78/* CDC hardware */
79typedef struct
80{
81 uint8 ifstat;
82 uint8 ifctrl;
83 reg16_t dbc;
84 reg16_t dac;
85 reg16_t pt;
86 reg16_t wa;
87 uint8 ctrl[2];
88 uint8 head[2][4];
89 uint8 stat[4];
90 int cycles;
91 //void (*dma_w)(unsigned int words);
92 int dma_w;
93 uint8 ram[0x4000 + 2352]; /* 16K external RAM (with one block overhead to handle buffer overrun) */
94} cdc_t;
95
96static cdc_t cdc;
97
98void cdc_init(void)
99{
100 memset(&cdc, 0, sizeof(cdc_t));
101}
102
103void cdc_reset(void)
104{
105 /* reset CDC register index */
106 Pico_mcd->regs[0x04>>1].byte.l = 0x00;
107
108 /* reset CDC registers */
109 cdc.ifstat = 0xff;
110 cdc.ifctrl = 0x00;
111 cdc.ctrl[0] = 0x00;
112 cdc.ctrl[1] = 0x00;
113 cdc.stat[0] = 0x00;
114 cdc.stat[1] = 0x00;
115 cdc.stat[2] = 0x00;
116 cdc.stat[3] = 0x80;
117 cdc.head[0][0] = 0x00;
118 cdc.head[0][1] = 0x00;
119 cdc.head[0][2] = 0x00;
120 cdc.head[0][3] = 0x01;
121 cdc.head[1][0] = 0x00;
122 cdc.head[1][1] = 0x00;
123 cdc.head[1][2] = 0x00;
124 cdc.head[1][3] = 0x00;
125
126 /* reset CDC cycle counter */
127 cdc.cycles = 0;
128
129 /* DMA transfer disabled */
130 cdc.dma_w = 0;
131}
132
133int cdc_context_save(uint8 *state)
134{
135 uint8 tmp8;
136 int bufferptr = 0;
137
138 if (cdc.dma_w == pcm_ram_dma_w)
139 {
140 tmp8 = 1;
141 }
142 else if (cdc.dma_w == prg_ram_dma_w)
143 {
144 tmp8 = 2;
145 }
146 else if (cdc.dma_w == word_ram_0_dma_w)
147 {
148 tmp8 = 3;
149 }
150 else if (cdc.dma_w == word_ram_1_dma_w)
151 {
152 tmp8 = 4;
153 }
154 else if (cdc.dma_w == word_ram_2M_dma_w)
155 {
156 tmp8 = 5;
157 }
158 else
159 {
160 tmp8 = 0;
161 }
162
163 save_param(&cdc, sizeof(cdc));
164 save_param(&tmp8, 1);
165
166 return bufferptr;
167}
168
169int cdc_context_load(uint8 *state)
170{
171 uint8 tmp8;
172 int bufferptr = 0;
173
174 load_param(&cdc, sizeof(cdc));
175 load_param(&tmp8, 1);
176
177 switch (tmp8)
178 {
179 case 1:
180 cdc.dma_w = pcm_ram_dma_w;
181 break;
182 case 2:
183 cdc.dma_w = prg_ram_dma_w;
184 break;
185 case 3:
186 cdc.dma_w = word_ram_0_dma_w;
187 break;
188 case 4:
189 cdc.dma_w = word_ram_1_dma_w;
190 break;
191 case 5:
192 cdc.dma_w = word_ram_2M_dma_w;
193 break;
194 default:
195 cdc.dma_w = 0;
196 break;
197 }
198
199 return bufferptr;
200}
201
202int cdc_context_load_old(uint8 *state)
203{
204#define old_load(v, ofs) \
205 memcpy(&cdc.v, state + ofs, sizeof(cdc.v))
206
207 memcpy(cdc.ram, state, 0x4000);
208 old_load(ifstat, 67892);
209 old_load(ifctrl, 67924);
210 old_load(dbc, 67896);
211 old_load(dac, 67900);
212 old_load(pt, 67908);
213 old_load(wa, 67912);
214 old_load(ctrl, 67928);
215 old_load(head[0], 67904);
216 old_load(stat, 67916);
217
218 cdc.dma_w = 0;
219 switch (Pico_mcd->regs[0x04>>1].byte.h & 0x07)
220 {
221 case 4: /* PCM RAM DMA */
222 cdc.dma_w = pcm_ram_dma_w;
223 break;
224 case 5: /* PRG-RAM DMA */
225 cdc.dma_w = prg_ram_dma_w;
226 break;
227 case 7: /* WORD-RAM DMA */
228 if (Pico_mcd->regs[0x02 >> 1].byte.l & 0x04)
229 {
230 if (Pico_mcd->regs[0x02 >> 1].byte.l & 0x01)
231 cdc.dma_w = word_ram_0_dma_w;
232 else
233 cdc.dma_w = word_ram_1_dma_w;
234 }
235 else
236 {
237 if (Pico_mcd->regs[0x02 >> 1].byte.l & 0x02)
238 cdc.dma_w = word_ram_2M_dma_w;
239 }
240 break;
241 }
242
243 return 0x10960; // sizeof(old_cdc)
244#undef old_load
245}
246
247static void do_dma(enum dma_type type, int words_in)
248{
249 int dma_addr = (Pico_mcd->s68k_regs[0x0a] << 8) | Pico_mcd->s68k_regs[0x0b];
250 int src_addr = cdc.dac.w & 0x3ffe;
251 int dst_addr = dma_addr;
252 int words = words_in;
253 int dst_limit = 0;
254 uint8 *dst;
255 int len;
256
257 elprintf(EL_CD, "dma %d %04x->%04x %x",
258 type, cdc.dac.w, dst_addr, words_in);
259
260 switch (type)
261 {
262 case pcm_ram_dma_w:
263 dst_addr = (dst_addr << 2) & 0xffc;
264 if (dst_addr + words * 2 > 0x1000) {
265 elprintf(EL_ANOMALY, "pcm dma oflow: %x %x", dst_addr, words);
266 words = (0x1000 - dst_addr) / 2;
267 }
268 dst = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank];
269 dst = dst + dst_addr;
270 while (words > 0)
271 {
272 if (src_addr + words * 2 > 0x4000) {
273 len = 0x4000 - src_addr;
274 memcpy(dst, cdc.ram + src_addr, len);
275 dst += len;
276 src_addr = 0;
277 words -= len / 2;
278 continue;
279 }
280 memcpy(dst, cdc.ram + src_addr, words * 2);
281 break;
282 }
283 goto update_dma;
284
285 case prg_ram_dma_w:
286 dst_addr <<= 3;
287 dst = Pico_mcd->prg_ram + dst_addr;
288 dst_limit = 0x80000;
289 break;
290
291 case word_ram_0_dma_w:
292 dst_addr = (dst_addr << 3) & 0x1fffe;
293 dst = Pico_mcd->word_ram1M[0] + dst_addr;
294 dst_limit = 0x20000;
295 break;
296
297 case word_ram_1_dma_w:
298 dst_addr = (dst_addr << 3) & 0x1fffe;
299 dst = Pico_mcd->word_ram1M[1] + dst_addr;
300 dst_limit = 0x20000;
301 break;
302
303 case word_ram_2M_dma_w:
304 dst_addr = (dst_addr << 3) & 0x3fffe;
305 dst = Pico_mcd->word_ram2M + dst_addr;
306 dst_limit = 0x40000;
307 break;
308
309 default:
310 elprintf(EL_ANOMALY, "invalid dma: %d", type);
311 goto update_dma;
312 }
313
314 if (dst_addr + words * 2 > dst_limit) {
315 elprintf(EL_ANOMALY, "cd dma %d oflow: %x %x", type, dst_addr, words);
316 words = (dst_limit - dst_addr) / 2;
317 }
318 while (words > 0)
319 {
320 if (src_addr + words * 2 > 0x4000) {
321 len = 0x4000 - src_addr;
322 memcpy16bswap((void *)dst, cdc.ram + src_addr, len / 2);
323 dst += len;
324 src_addr = 0;
325 words -= len / 2;
326 continue;
327 }
328 memcpy16bswap((void *)dst, cdc.ram + src_addr, words);
329 break;
330 }
331
332update_dma:
333 /* update DMA addresses */
334 cdc.dac.w += words_in * 2;
335 if (type == pcm_ram_dma_w)
336 dma_addr += words_in >> 1;
337 else
338 dma_addr += words_in >> 2;
339
340 Pico_mcd->s68k_regs[0x0a] = dma_addr >> 8;
341 Pico_mcd->s68k_regs[0x0b] = dma_addr;
342}
343
3f23709e 344void cdc_dma_update(void)
345{
346 /* end of DMA transfer ? */
347 //if (cdc.dbc.w < DMA_BYTES_PER_LINE)
348 {
349 /* transfer remaining words using 16-bit DMA */
350 //cdc.dma_w((cdc.dbc.w + 1) >> 1);
351 do_dma(cdc.dma_w, (cdc.dbc.w + 1) >> 1);
352
353 /* reset data byte counter (DBCH bits 4-7 should be set to 1) */
354 cdc.dbc.w = 0xf000;
355
356 /* clear !DTEN and !DTBSY */
357 cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
358
359 /* pending Data Transfer End interrupt */
360 cdc.ifstat &= ~BIT_DTEI;
361
362 /* Data Transfer End interrupt enabled ? */
363 if (cdc.ifctrl & BIT_DTEIEN)
364 {
365 /* level 5 interrupt enabled ? */
366 if (Pico_mcd->regs[0x32>>1].byte.l & PCDS_IEN5)
367 {
368 /* update IRQ level */
369 elprintf(EL_INTS, "cdc DTE irq 5");
370 SekInterruptS68k(5);
371 }
372 }
373
374 /* clear DSR bit & set EDT bit (SCD register $04) */
375 Pico_mcd->regs[0x04>>1].byte.h = (Pico_mcd->regs[0x04>>1].byte.h & 0x07) | 0x80;
376
377 /* disable DMA transfer */
378 cdc.dma_w = 0;
379 }
380#if 0
381 else
382 {
383 /* transfer all words using 16-bit DMA */
384 cdc.dma_w(DMA_BYTES_PER_LINE >> 1);
385
386 /* decrement data byte counter */
387 cdc.dbc.w -= length;
388 }
389#endif
390}
391
392int cdc_decoder_update(uint8 header[4])
393{
394 /* data decoding enabled ? */
395 if (cdc.ctrl[0] & BIT_DECEN)
396 {
397 /* update HEAD registers */
398 memcpy(cdc.head[0], header, sizeof(cdc.head[0]));
399
400 /* set !VALST */
401 cdc.stat[3] = 0x00;
402
403 /* pending decoder interrupt */
404 cdc.ifstat &= ~BIT_DECI;
405
406 /* decoder interrupt enabled ? */
407 if (cdc.ifctrl & BIT_DECIEN)
408 {
409 /* level 5 interrupt enabled ? */
410 if (Pico_mcd->regs[0x32>>1].byte.l & PCDS_IEN5)
411 {
412 /* update IRQ level */
413 elprintf(EL_INTS, "cdc DEC irq 5");
414 SekInterruptS68k(5);
415 }
416 }
417
418 /* buffer RAM write enabled ? */
419 if (cdc.ctrl[0] & BIT_WRRQ)
420 {
421 uint16 offset;
422
423 /* increment block pointer */
424 cdc.pt.w += 2352;
425
426 /* increment write address */
427 cdc.wa.w += 2352;
428
429 /* CDC buffer address */
430 offset = cdc.pt.w & 0x3fff;
431
432 /* write CDD block header (4 bytes) */
433 memcpy(cdc.ram + offset, header, 4);
434
435 /* write CDD block data (2048 bytes) */
436 cdd_read_data(cdc.ram + 4 + offset);
437
438 /* take care of buffer overrun */
439 if (offset > (0x4000 - 2048 - 4))
440 {
441 /* data should be written at the start of buffer */
442 memcpy(cdc.ram, cdc.ram + 0x4000, offset + 2048 + 4 - 0x4000);
443 }
444
445 /* read next data block */
446 return 1;
447 }
448 }
449
450 /* keep decoding same data block if Buffer Write is disabled */
451 return 0;
452}
453
454void cdc_reg_w(unsigned char data)
455{
456#ifdef LOG_CDC
457 elprintf(EL_STATUS, "CDC register %X write 0x%04x", Pico_mcd->regs[0x04>>1].byte.l & 0x0F, data);
458#endif
459 switch (Pico_mcd->regs[0x04>>1].byte.l & 0x0F)
460 {
461 case 0x01: /* IFCTRL */
462 {
463 /* pending interrupts ? */
464 if (((data & BIT_DTEIEN) && !(cdc.ifstat & BIT_DTEI)) ||
465 ((data & BIT_DECIEN) && !(cdc.ifstat & BIT_DECI)))
466 {
467 /* level 5 interrupt enabled ? */
468 if (Pico_mcd->regs[0x32>>1].byte.l & PCDS_IEN5)
469 {
470 /* update IRQ level */
471 elprintf(EL_INTS, "cdc pending irq 5");
472 SekInterruptS68k(5);
473 }
474 }
475 else // if (scd.pending & (1 << 5))
476 {
477 /* clear pending level 5 interrupts */
478 SekInterruptClearS68k(5);
479 }
480
481 /* abort any data transfer if data output is disabled */
482 if (!(data & BIT_DOUTEN))
483 {
484 /* clear !DTBSY and !DTEN */
485 cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
486 }
487
488 cdc.ifctrl = data;
489 Pico_mcd->regs[0x04>>1].byte.l = 0x02;
490 break;
491 }
492
493 case 0x02: /* DBCL */
494 cdc.dbc.byte.l = data;
495 Pico_mcd->regs[0x04>>1].byte.l = 0x03;
496 break;
497
498 case 0x03: /* DBCH */
499 cdc.dbc.byte.h = data;
500 Pico_mcd->regs[0x04>>1].byte.l = 0x04;
501 break;
502
503 case 0x04: /* DACL */
504 cdc.dac.byte.l = data;
505 Pico_mcd->regs[0x04>>1].byte.l = 0x05;
506 break;
507
508 case 0x05: /* DACH */
509 cdc.dac.byte.h = data;
510 Pico_mcd->regs[0x04>>1].byte.l = 0x06;
511 break;
512
513 case 0x06: /* DTRG */
514 {
515 /* start data transfer if data output is enabled */
516 if (cdc.ifctrl & BIT_DOUTEN)
517 {
518 /* set !DTBSY */
519 cdc.ifstat &= ~BIT_DTBSY;
520
521 /* clear DBCH bits 4-7 */
522 cdc.dbc.byte.h &= 0x0f;
523
524 /* clear EDT & DSR bits (SCD register $04) */
525 Pico_mcd->regs[0x04>>1].byte.h &= 0x07;
526
527 cdc.dma_w = 0;
528
529 /* setup data transfer destination */
530 switch (Pico_mcd->regs[0x04>>1].byte.h & 0x07)
531 {
532 case 2: /* MAIN-CPU host read */
533 case 3: /* SUB-CPU host read */
534 {
535 /* set !DTEN */
536 cdc.ifstat &= ~BIT_DTEN;
537
538 /* set DSR bit (register $04) */
539 Pico_mcd->regs[0x04>>1].byte.h |= 0x40;
540 break;
541 }
542
543 case 4: /* PCM RAM DMA */
544 {
545 cdc.dma_w = pcm_ram_dma_w;
546 break;
547 }
548
549 case 5: /* PRG-RAM DMA */
550 {
551 cdc.dma_w = prg_ram_dma_w;
552 break;
553 }
554
555 case 7: /* WORD-RAM DMA */
556 {
557 /* check memory mode */
558 if (Pico_mcd->regs[0x02 >> 1].byte.l & 0x04)
559 {
560 /* 1M mode */
561 if (Pico_mcd->regs[0x02 >> 1].byte.l & 0x01)
562 {
563 /* Word-RAM bank 0 is assigned to SUB-CPU */
564 cdc.dma_w = word_ram_0_dma_w;
565 }
566 else
567 {
568 /* Word-RAM bank 1 is assigned to SUB-CPU */
569 cdc.dma_w = word_ram_1_dma_w;
570 }
571 }
572 else
573 {
574 /* 2M mode */
575 if (Pico_mcd->regs[0x02 >> 1].byte.l & 0x02)
576 {
577 /* only process DMA if Word-RAM is assigned to SUB-CPU */
578 cdc.dma_w = word_ram_2M_dma_w;
579 }
580 }
581 break;
582 }
583
584 default: /* invalid */
585 {
586 elprintf(EL_ANOMALY, "invalid CDC tranfer destination (%d)",
587 Pico_mcd->regs[0x04>>1].byte.h & 0x07);
588 break;
589 }
590 }
591
592 if (cdc.dma_w)
593 pcd_event_schedule_s68k(PCD_EVENT_DMA, cdc.dbc.w / 2);
594 }
595
596 Pico_mcd->regs[0x04>>1].byte.l = 0x07;
597 break;
598 }
599
600 case 0x07: /* DTACK */
601 {
602 /* clear pending data transfer end interrupt */
603 cdc.ifstat |= BIT_DTEI;
604
605 /* clear DBCH bits 4-7 */
606 cdc.dbc.byte.h &= 0x0f;
607
608#if 0
609 /* no pending decoder interrupt ? */
610 if ((cdc.ifstat | BIT_DECI) || !(cdc.ifctrl & BIT_DECIEN))
611 {
612 /* clear pending level 5 interrupt */
613 SekInterruptClearS68k(5);
614 }
615#endif
616 Pico_mcd->regs[0x04>>1].byte.l = 0x08;
617 break;
618 }
619
620 case 0x08: /* WAL */
621 cdc.wa.byte.l = data;
622 Pico_mcd->regs[0x04>>1].byte.l = 0x09;
623 break;
624
625 case 0x09: /* WAH */
626 cdc.wa.byte.h = data;
627 Pico_mcd->regs[0x04>>1].byte.l = 0x0a;
628 break;
629
630 case 0x0a: /* CTRL0 */
631 {
632 /* set CRCOK bit only if decoding is enabled */
633 cdc.stat[0] = data & BIT_DECEN;
634
635 /* update decoding mode */
636 if (data & BIT_AUTORQ)
637 {
638 /* set MODE bit according to CTRL1 register & clear FORM bit */
639 cdc.stat[2] = cdc.ctrl[1] & BIT_MODRQ;
640 }
641 else
642 {
643 /* set MODE & FORM bits according to CTRL1 register */
644 cdc.stat[2] = cdc.ctrl[1] & (BIT_MODRQ | BIT_FORMRQ);
645 }
646
647 cdc.ctrl[0] = data;
648 Pico_mcd->regs[0x04>>1].byte.l = 0x0b;
649 break;
650 }
651
652 case 0x0b: /* CTRL1 */
653 {
654 /* update decoding mode */
655 if (cdc.ctrl[0] & BIT_AUTORQ)
656 {
657 /* set MODE bit according to CTRL1 register & clear FORM bit */
658 cdc.stat[2] = data & BIT_MODRQ;
659 }
660 else
661 {
662 /* set MODE & FORM bits according to CTRL1 register */
663 cdc.stat[2] = data & (BIT_MODRQ | BIT_FORMRQ);
664 }
665
666 cdc.ctrl[1] = data;
667 Pico_mcd->regs[0x04>>1].byte.l = 0x0c;
668 break;
669 }
670
671 case 0x0c: /* PTL */
672 cdc.pt.byte.l = data;
673 Pico_mcd->regs[0x04>>1].byte.l = 0x0d;
674 break;
675
676 case 0x0d: /* PTH */
677 cdc.pt.byte.h = data;
678 Pico_mcd->regs[0x04>>1].byte.l = 0x0e;
679 break;
680
681 case 0x0e: /* CTRL2 (unused) */
682 Pico_mcd->regs[0x04>>1].byte.l = 0x0f;
683 break;
684
685 case 0x0f: /* RESET */
686 cdc_reset();
687 break;
688
689 default: /* by default, SBOUT is not used */
690 break;
691 }
692}
693
694unsigned char cdc_reg_r(void)
695{
696 switch (Pico_mcd->regs[0x04>>1].byte.l & 0x0F)
697 {
698 case 0x01: /* IFSTAT */
699 Pico_mcd->regs[0x04>>1].byte.l = 0x02;
700 return cdc.ifstat;
701
702 case 0x02: /* DBCL */
703 Pico_mcd->regs[0x04>>1].byte.l = 0x03;
704 return cdc.dbc.byte.l;
705
706 case 0x03: /* DBCH */
707 Pico_mcd->regs[0x04>>1].byte.l = 0x04;
708 return cdc.dbc.byte.h;
709
710 case 0x04: /* HEAD0 */
711 Pico_mcd->regs[0x04>>1].byte.l = 0x05;
712 return cdc.head[cdc.ctrl[1] & BIT_SHDREN][0];
713
714 case 0x05: /* HEAD1 */
715 Pico_mcd->regs[0x04>>1].byte.l = 0x06;
716 return cdc.head[cdc.ctrl[1] & BIT_SHDREN][1];
717
718 case 0x06: /* HEAD2 */
719 Pico_mcd->regs[0x04>>1].byte.l = 0x07;
720 return cdc.head[cdc.ctrl[1] & BIT_SHDREN][2];
721
722 case 0x07: /* HEAD3 */
723 Pico_mcd->regs[0x04>>1].byte.l = 0x08;
724 return cdc.head[cdc.ctrl[1] & BIT_SHDREN][3];
725
726 case 0x08: /* PTL */
727 Pico_mcd->regs[0x04>>1].byte.l = 0x09;
728 return cdc.pt.byte.l;
729
730 case 0x09: /* PTH */
731 Pico_mcd->regs[0x04>>1].byte.l = 0x0a;
732 return cdc.pt.byte.h;
733
734 case 0x0a: /* WAL */
735 Pico_mcd->regs[0x04>>1].byte.l = 0x0b;
736 return cdc.wa.byte.l;
737
738 case 0x0b: /* WAH */
739 Pico_mcd->regs[0x04>>1].byte.l = 0x0c;
740 return cdc.wa.byte.h;
741
742 case 0x0c: /* STAT0 */
743 Pico_mcd->regs[0x04>>1].byte.l = 0x0d;
744 return cdc.stat[0];
745
746 case 0x0d: /* STAT1 (always return 0) */
747 Pico_mcd->regs[0x04>>1].byte.l = 0x0e;
748 return 0x00;
749
750 case 0x0e: /* STAT2 */
751 Pico_mcd->regs[0x04>>1].byte.l = 0x0f;
752 return cdc.stat[2];
753
754 case 0x0f: /* STAT3 */
755 {
756 uint8 data = cdc.stat[3];
757
758 /* clear !VALST (note: this is not 100% correct but BIOS do not seem to care) */
759 cdc.stat[3] = BIT_VALST;
760
761 /* clear pending decoder interrupt */
762 cdc.ifstat |= BIT_DECI;
763
764#if 0
765 /* no pending data transfer end interrupt */
766 if ((cdc.ifstat | BIT_DTEI) || !(cdc.ifctrl & BIT_DTEIEN))
767 {
768 /* clear pending level 5 interrupt */
769 SekInterruptClearS68k(5);
770 }
771#endif
772
773 Pico_mcd->regs[0x04>>1].byte.l = 0x00;
774 return data;
775 }
776
777 default: /* by default, COMIN is always empty */
778 return 0xff;
779 }
780}
781
782unsigned short cdc_host_r(void)
783{
784 /* check if data is available */
785 if (!(cdc.ifstat & BIT_DTEN))
786 {
787 /* read data word from CDC RAM buffer */
788 uint8 *datap = cdc.ram + (cdc.dac.w & 0x3ffe);
789 uint16 data = (datap[0] << 8) | datap[1];
790
791#ifdef LOG_CDC
792 error("CDC host read 0x%04x -> 0x%04x (dbc=0x%x) (%X)\n", cdc.dac.w, data, cdc.dbc.w, s68k.pc);
793#endif
794
795 /* increment data address counter */
796 cdc.dac.w += 2;
797
798 /* decrement data byte counter */
799 cdc.dbc.w -= 2;
800
801 /* end of transfer ? */
802 if ((int16)cdc.dbc.w <= 0)
803 {
804 /* reset data byte counter (DBCH bits 4-7 should be set to 1) */
805 cdc.dbc.w = 0xf000;
806
807 /* clear !DTEN and !DTBSY */
808 cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
809
810 /* pending Data Transfer End interrupt */
811 cdc.ifstat &= ~BIT_DTEI;
812
813 /* Data Transfer End interrupt enabled ? */
814 if (cdc.ifctrl & BIT_DTEIEN)
815 {
816 /* level 5 interrupt enabled ? */
817 if (Pico_mcd->regs[0x32>>1].byte.l & PCDS_IEN5)
818 {
819 /* update IRQ level */
820 elprintf(EL_INTS, "cdc DTE irq 5");
821 SekInterruptS68k(5);
822 }
823 }
824
825 /* clear DSR bit & set EDT bit (SCD register $04) */
826 Pico_mcd->regs[0x04>>1].byte.h = (Pico_mcd->regs[0x04>>1].byte.h & 0x07) | 0x80;
827 }
828
829 return data;
830 }
831
832#ifdef LOG_CDC
833 error("error reading CDC host (data transfer disabled)\n");
834#endif
835 return 0xffff;
836}
837
838// vim:shiftwidth=2:ts=2:expandtab