1 /***************************************************************************************
3 * CD data controller (LC89510 compatible)
5 * Copyright (C) 2012 Eke-Eke (Genesis Plus GX)
7 * Redistribution and use of this code or any derivative works are permitted
8 * provided that the following conditions are met:
10 * - Redistributions may not be sold, nor may they be used in a commercial
11 * product or activity.
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.
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.
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.
37 ****************************************************************************************/
39 #include "../pico_int.h"
40 #include "genplus_macros.h"
42 /* IFSTAT register bitmasks */
45 #define BIT_DTBSY 0x08
48 /* IFCTRL register bitmasks */
49 #define BIT_DTEIEN 0x40
50 #define BIT_DECIEN 0x20
51 #define BIT_DOUTEN 0x02
53 /* CTRL0 register bitmasks */
54 #define BIT_DECEN 0x80
55 #define BIT_E01RQ 0x20
56 #define BIT_AUTORQ 0x10
59 /* CTRL1 register bitmasks */
60 #define BIT_MODRQ 0x08
61 #define BIT_FORMRQ 0x04
62 #define BIT_SHDREN 0x01
64 /* CTRL2 register bitmask */
65 #define BIT_VALST 0x80
67 /* PicoDrive: doing DMA at once, not using callbacks */
68 //#define DMA_BYTES_PER_LINE 512
73 word_ram_2M_dma_w = 3,
91 //void (*dma_w)(unsigned int words);
93 uint8 ram[0x4000 + 2352]; /* 16K external RAM (with one block overhead to handle buffer overrun) */
100 memset(&cdc, 0, sizeof(cdc_t));
105 /* reset CDC register index */
106 Pico_mcd->regs[0x04>>1].byte.l = 0x00;
108 /* reset CDC registers */
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;
126 /* reset CDC cycle counter */
129 /* DMA transfer disabled */
133 int cdc_context_save(uint8 *state)
138 if (cdc.dma_w == pcm_ram_dma_w)
142 else if (cdc.dma_w == prg_ram_dma_w)
146 else if (cdc.dma_w == word_ram_0_dma_w)
150 else if (cdc.dma_w == word_ram_1_dma_w)
154 else if (cdc.dma_w == word_ram_2M_dma_w)
163 save_param(&cdc, sizeof(cdc));
164 save_param(&tmp8, 1);
169 int cdc_context_load(uint8 *state)
174 load_param(&cdc, sizeof(cdc));
175 load_param(&tmp8, 1);
180 cdc.dma_w = pcm_ram_dma_w;
183 cdc.dma_w = prg_ram_dma_w;
186 cdc.dma_w = word_ram_0_dma_w;
189 cdc.dma_w = word_ram_1_dma_w;
192 cdc.dma_w = word_ram_2M_dma_w;
202 int cdc_context_load_old(uint8 *state)
204 #define old_load(v, ofs) \
205 memcpy(&cdc.v, state + ofs, sizeof(cdc.v))
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);
214 old_load(ctrl, 67928);
215 old_load(head[0], 67904);
216 old_load(stat, 67916);
219 switch (Pico_mcd->regs[0x04>>1].byte.h & 0x07)
221 case 4: /* PCM RAM DMA */
222 cdc.dma_w = pcm_ram_dma_w;
224 case 5: /* PRG-RAM DMA */
225 cdc.dma_w = prg_ram_dma_w;
227 case 7: /* WORD-RAM DMA */
228 if (Pico_mcd->regs[0x02 >> 1].byte.l & 0x04)
230 if (Pico_mcd->regs[0x02 >> 1].byte.l & 0x01)
231 cdc.dma_w = word_ram_0_dma_w;
233 cdc.dma_w = word_ram_1_dma_w;
237 if (Pico_mcd->regs[0x02 >> 1].byte.l & 0x02)
238 cdc.dma_w = word_ram_2M_dma_w;
243 return 0x10960; // sizeof(old_cdc)
247 static void do_dma(enum dma_type type, int words_in)
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;
257 elprintf(EL_CD, "dma %d %04x->%04x %x",
258 type, cdc.dac.w, dst_addr, words_in);
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;
268 dst = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank];
269 dst = dst + dst_addr;
272 if (src_addr + words * 2 > 0x4000) {
273 len = 0x4000 - src_addr;
274 memcpy(dst, cdc.ram + src_addr, len);
280 memcpy(dst, cdc.ram + src_addr, words * 2);
287 dst = Pico_mcd->prg_ram + dst_addr;
291 case word_ram_0_dma_w:
292 dst_addr = (dst_addr << 3) & 0x1fffe;
293 dst = Pico_mcd->word_ram1M[0] + dst_addr;
297 case word_ram_1_dma_w:
298 dst_addr = (dst_addr << 3) & 0x1fffe;
299 dst = Pico_mcd->word_ram1M[1] + dst_addr;
303 case word_ram_2M_dma_w:
304 dst_addr = (dst_addr << 3) & 0x3fffe;
305 dst = Pico_mcd->word_ram2M + dst_addr;
310 elprintf(EL_ANOMALY, "invalid dma: %d", type);
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;
320 if (src_addr + words * 2 > 0x4000) {
321 len = 0x4000 - src_addr;
322 memcpy16bswap((void *)dst, cdc.ram + src_addr, len / 2);
328 memcpy16bswap((void *)dst, cdc.ram + src_addr, words);
333 /* update DMA addresses */
334 cdc.dac.w += words_in * 2;
335 if (type == pcm_ram_dma_w)
336 dma_addr += words_in >> 1;
338 dma_addr += words_in >> 2;
340 Pico_mcd->s68k_regs[0x0a] = dma_addr >> 8;
341 Pico_mcd->s68k_regs[0x0b] = dma_addr;
345 static void cdd_read_data(uint8 *dst)
347 int lba = Pico_mcd->scd.Cur_LBA;
349 /* only read DATA track sectors */
350 if (0 <= lba && lba < Pico_mcd->TOC.Tracks[0].Length)
352 /* read sector data (Mode 1 = 2048 bytes) */
353 PicoCDBufferRead(dst, lba);
357 void cdc_dma_update(void)
359 /* end of DMA transfer ? */
360 //if (cdc.dbc.w < DMA_BYTES_PER_LINE)
362 /* transfer remaining words using 16-bit DMA */
363 //cdc.dma_w((cdc.dbc.w + 1) >> 1);
364 do_dma(cdc.dma_w, (cdc.dbc.w + 1) >> 1);
366 /* reset data byte counter (DBCH bits 4-7 should be set to 1) */
369 /* clear !DTEN and !DTBSY */
370 cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
372 /* pending Data Transfer End interrupt */
373 cdc.ifstat &= ~BIT_DTEI;
375 /* Data Transfer End interrupt enabled ? */
376 if (cdc.ifctrl & BIT_DTEIEN)
378 /* level 5 interrupt enabled ? */
379 if (Pico_mcd->regs[0x32>>1].byte.l & PCDS_IEN5)
381 /* update IRQ level */
382 elprintf(EL_INTS, "cdc DTE irq 5");
387 /* clear DSR bit & set EDT bit (SCD register $04) */
388 Pico_mcd->regs[0x04>>1].byte.h = (Pico_mcd->regs[0x04>>1].byte.h & 0x07) | 0x80;
390 /* disable DMA transfer */
396 /* transfer all words using 16-bit DMA */
397 cdc.dma_w(DMA_BYTES_PER_LINE >> 1);
399 /* decrement data byte counter */
405 int cdc_decoder_update(uint8 header[4])
407 /* data decoding enabled ? */
408 if (cdc.ctrl[0] & BIT_DECEN)
410 /* update HEAD registers */
411 memcpy(cdc.head[0], header, sizeof(cdc.head[0]));
416 /* pending decoder interrupt */
417 cdc.ifstat &= ~BIT_DECI;
419 /* decoder interrupt enabled ? */
420 if (cdc.ifctrl & BIT_DECIEN)
422 /* level 5 interrupt enabled ? */
423 if (Pico_mcd->regs[0x32>>1].byte.l & PCDS_IEN5)
425 /* update IRQ level */
426 elprintf(EL_INTS, "cdc DEC irq 5");
431 /* buffer RAM write enabled ? */
432 if (cdc.ctrl[0] & BIT_WRRQ)
436 /* increment block pointer */
439 /* increment write address */
442 /* CDC buffer address */
443 offset = cdc.pt.w & 0x3fff;
445 /* write CDD block header (4 bytes) */
446 memcpy(cdc.ram + offset, header, 4);
448 /* write CDD block data (2048 bytes) */
449 cdd_read_data(cdc.ram + 4 + offset);
451 /* take care of buffer overrun */
452 if (offset > (0x4000 - 2048 - 4))
454 /* data should be written at the start of buffer */
455 memcpy(cdc.ram, cdc.ram + 0x4000, offset + 2048 + 4 - 0x4000);
458 /* read next data block */
463 /* keep decoding same data block if Buffer Write is disabled */
467 void cdc_reg_w(unsigned char data)
470 elprintf(EL_STATUS, "CDC register %X write 0x%04x", Pico_mcd->regs[0x04>>1].byte.l & 0x0F, data);
472 switch (Pico_mcd->regs[0x04>>1].byte.l & 0x0F)
474 case 0x01: /* IFCTRL */
476 /* pending interrupts ? */
477 if (((data & BIT_DTEIEN) && !(cdc.ifstat & BIT_DTEI)) ||
478 ((data & BIT_DECIEN) && !(cdc.ifstat & BIT_DECI)))
480 /* level 5 interrupt enabled ? */
481 if (Pico_mcd->regs[0x32>>1].byte.l & PCDS_IEN5)
483 /* update IRQ level */
484 elprintf(EL_INTS, "cdc pending irq 5");
488 else // if (scd.pending & (1 << 5))
490 /* clear pending level 5 interrupts */
491 SekInterruptClearS68k(5);
494 /* abort any data transfer if data output is disabled */
495 if (!(data & BIT_DOUTEN))
497 /* clear !DTBSY and !DTEN */
498 cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
502 Pico_mcd->regs[0x04>>1].byte.l = 0x02;
506 case 0x02: /* DBCL */
507 cdc.dbc.byte.l = data;
508 Pico_mcd->regs[0x04>>1].byte.l = 0x03;
511 case 0x03: /* DBCH */
512 cdc.dbc.byte.h = data;
513 Pico_mcd->regs[0x04>>1].byte.l = 0x04;
516 case 0x04: /* DACL */
517 cdc.dac.byte.l = data;
518 Pico_mcd->regs[0x04>>1].byte.l = 0x05;
521 case 0x05: /* DACH */
522 cdc.dac.byte.h = data;
523 Pico_mcd->regs[0x04>>1].byte.l = 0x06;
526 case 0x06: /* DTRG */
528 /* start data transfer if data output is enabled */
529 if (cdc.ifctrl & BIT_DOUTEN)
532 cdc.ifstat &= ~BIT_DTBSY;
534 /* clear DBCH bits 4-7 */
535 cdc.dbc.byte.h &= 0x0f;
537 /* clear EDT & DSR bits (SCD register $04) */
538 Pico_mcd->regs[0x04>>1].byte.h &= 0x07;
542 /* setup data transfer destination */
543 switch (Pico_mcd->regs[0x04>>1].byte.h & 0x07)
545 case 2: /* MAIN-CPU host read */
546 case 3: /* SUB-CPU host read */
549 cdc.ifstat &= ~BIT_DTEN;
551 /* set DSR bit (register $04) */
552 Pico_mcd->regs[0x04>>1].byte.h |= 0x40;
556 case 4: /* PCM RAM DMA */
558 cdc.dma_w = pcm_ram_dma_w;
562 case 5: /* PRG-RAM DMA */
564 cdc.dma_w = prg_ram_dma_w;
568 case 7: /* WORD-RAM DMA */
570 /* check memory mode */
571 if (Pico_mcd->regs[0x02 >> 1].byte.l & 0x04)
574 if (Pico_mcd->regs[0x02 >> 1].byte.l & 0x01)
576 /* Word-RAM bank 0 is assigned to SUB-CPU */
577 cdc.dma_w = word_ram_0_dma_w;
581 /* Word-RAM bank 1 is assigned to SUB-CPU */
582 cdc.dma_w = word_ram_1_dma_w;
588 if (Pico_mcd->regs[0x02 >> 1].byte.l & 0x02)
590 /* only process DMA if Word-RAM is assigned to SUB-CPU */
591 cdc.dma_w = word_ram_2M_dma_w;
597 default: /* invalid */
599 elprintf(EL_ANOMALY, "invalid CDC tranfer destination (%d)",
600 Pico_mcd->regs[0x04>>1].byte.h & 0x07);
606 pcd_event_schedule_s68k(PCD_EVENT_DMA, cdc.dbc.w / 2);
609 Pico_mcd->regs[0x04>>1].byte.l = 0x07;
613 case 0x07: /* DTACK */
615 /* clear pending data transfer end interrupt */
616 cdc.ifstat |= BIT_DTEI;
618 /* clear DBCH bits 4-7 */
619 cdc.dbc.byte.h &= 0x0f;
622 /* no pending decoder interrupt ? */
623 if ((cdc.ifstat | BIT_DECI) || !(cdc.ifctrl & BIT_DECIEN))
625 /* clear pending level 5 interrupt */
626 SekInterruptClearS68k(5);
629 Pico_mcd->regs[0x04>>1].byte.l = 0x08;
634 cdc.wa.byte.l = data;
635 Pico_mcd->regs[0x04>>1].byte.l = 0x09;
639 cdc.wa.byte.h = data;
640 Pico_mcd->regs[0x04>>1].byte.l = 0x0a;
643 case 0x0a: /* CTRL0 */
645 /* set CRCOK bit only if decoding is enabled */
646 cdc.stat[0] = data & BIT_DECEN;
648 /* update decoding mode */
649 if (data & BIT_AUTORQ)
651 /* set MODE bit according to CTRL1 register & clear FORM bit */
652 cdc.stat[2] = cdc.ctrl[1] & BIT_MODRQ;
656 /* set MODE & FORM bits according to CTRL1 register */
657 cdc.stat[2] = cdc.ctrl[1] & (BIT_MODRQ | BIT_FORMRQ);
661 Pico_mcd->regs[0x04>>1].byte.l = 0x0b;
665 case 0x0b: /* CTRL1 */
667 /* update decoding mode */
668 if (cdc.ctrl[0] & BIT_AUTORQ)
670 /* set MODE bit according to CTRL1 register & clear FORM bit */
671 cdc.stat[2] = data & BIT_MODRQ;
675 /* set MODE & FORM bits according to CTRL1 register */
676 cdc.stat[2] = data & (BIT_MODRQ | BIT_FORMRQ);
680 Pico_mcd->regs[0x04>>1].byte.l = 0x0c;
685 cdc.pt.byte.l = data;
686 Pico_mcd->regs[0x04>>1].byte.l = 0x0d;
690 cdc.pt.byte.h = data;
691 Pico_mcd->regs[0x04>>1].byte.l = 0x0e;
694 case 0x0e: /* CTRL2 (unused) */
695 Pico_mcd->regs[0x04>>1].byte.l = 0x0f;
698 case 0x0f: /* RESET */
702 default: /* by default, SBOUT is not used */
707 unsigned char cdc_reg_r(void)
709 switch (Pico_mcd->regs[0x04>>1].byte.l & 0x0F)
711 case 0x01: /* IFSTAT */
712 Pico_mcd->regs[0x04>>1].byte.l = 0x02;
715 case 0x02: /* DBCL */
716 Pico_mcd->regs[0x04>>1].byte.l = 0x03;
717 return cdc.dbc.byte.l;
719 case 0x03: /* DBCH */
720 Pico_mcd->regs[0x04>>1].byte.l = 0x04;
721 return cdc.dbc.byte.h;
723 case 0x04: /* HEAD0 */
724 Pico_mcd->regs[0x04>>1].byte.l = 0x05;
725 return cdc.head[cdc.ctrl[1] & BIT_SHDREN][0];
727 case 0x05: /* HEAD1 */
728 Pico_mcd->regs[0x04>>1].byte.l = 0x06;
729 return cdc.head[cdc.ctrl[1] & BIT_SHDREN][1];
731 case 0x06: /* HEAD2 */
732 Pico_mcd->regs[0x04>>1].byte.l = 0x07;
733 return cdc.head[cdc.ctrl[1] & BIT_SHDREN][2];
735 case 0x07: /* HEAD3 */
736 Pico_mcd->regs[0x04>>1].byte.l = 0x08;
737 return cdc.head[cdc.ctrl[1] & BIT_SHDREN][3];
740 Pico_mcd->regs[0x04>>1].byte.l = 0x09;
741 return cdc.pt.byte.l;
744 Pico_mcd->regs[0x04>>1].byte.l = 0x0a;
745 return cdc.pt.byte.h;
748 Pico_mcd->regs[0x04>>1].byte.l = 0x0b;
749 return cdc.wa.byte.l;
752 Pico_mcd->regs[0x04>>1].byte.l = 0x0c;
753 return cdc.wa.byte.h;
755 case 0x0c: /* STAT0 */
756 Pico_mcd->regs[0x04>>1].byte.l = 0x0d;
759 case 0x0d: /* STAT1 (always return 0) */
760 Pico_mcd->regs[0x04>>1].byte.l = 0x0e;
763 case 0x0e: /* STAT2 */
764 Pico_mcd->regs[0x04>>1].byte.l = 0x0f;
767 case 0x0f: /* STAT3 */
769 uint8 data = cdc.stat[3];
771 /* clear !VALST (note: this is not 100% correct but BIOS do not seem to care) */
772 cdc.stat[3] = BIT_VALST;
774 /* clear pending decoder interrupt */
775 cdc.ifstat |= BIT_DECI;
778 /* no pending data transfer end interrupt */
779 if ((cdc.ifstat | BIT_DTEI) || !(cdc.ifctrl & BIT_DTEIEN))
781 /* clear pending level 5 interrupt */
782 SekInterruptClearS68k(5);
786 Pico_mcd->regs[0x04>>1].byte.l = 0x00;
790 default: /* by default, COMIN is always empty */
795 unsigned short cdc_host_r(void)
797 /* check if data is available */
798 if (!(cdc.ifstat & BIT_DTEN))
800 /* read data word from CDC RAM buffer */
801 uint8 *datap = cdc.ram + (cdc.dac.w & 0x3ffe);
802 uint16 data = (datap[0] << 8) | datap[1];
805 error("CDC host read 0x%04x -> 0x%04x (dbc=0x%x) (%X)\n", cdc.dac.w, data, cdc.dbc.w, s68k.pc);
808 /* increment data address counter */
811 /* decrement data byte counter */
814 /* end of transfer ? */
815 if ((int16)cdc.dbc.w <= 0)
817 /* reset data byte counter (DBCH bits 4-7 should be set to 1) */
820 /* clear !DTEN and !DTBSY */
821 cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
823 /* pending Data Transfer End interrupt */
824 cdc.ifstat &= ~BIT_DTEI;
826 /* Data Transfer End interrupt enabled ? */
827 if (cdc.ifctrl & BIT_DTEIEN)
829 /* level 5 interrupt enabled ? */
830 if (Pico_mcd->regs[0x32>>1].byte.l & PCDS_IEN5)
832 /* update IRQ level */
833 elprintf(EL_INTS, "cdc DTE irq 5");
838 /* clear DSR bit & set EDT bit (SCD register $04) */
839 Pico_mcd->regs[0x04>>1].byte.h = (Pico_mcd->regs[0x04>>1].byte.h & 0x07) | 0x80;
846 error("error reading CDC host (data transfer disabled)\n");
851 // vim:shiftwidth=2:ts=2:expandtab