pandora: fix readme and pxml version
[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
691abdfa 69#define DMA_CYCLES_PER_BYTE 4 // or 6?
3f23709e 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;
f47d0a28 84 uint16 dbc;
85 uint16 dac;
86 uint16 pt;
87 uint16 wa;
3f23709e 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) */
dd7c8c05 95} cdc_t;
3f23709e 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 */
f47d0a28 107 Pico_mcd->s68k_regs[0x04+1] = 0x00;
3f23709e 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 */
dd7c8c05 128 cdc.cycles = SekCyclesDoneS68k();
3f23709e 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;
f47d0a28 220 switch (Pico_mcd->s68k_regs[0x04+0] & 0x07)
3f23709e 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 */
f47d0a28 229 if (Pico_mcd->s68k_regs[0x02+1] & 0x04)
3f23709e 230 {
f47d0a28 231 if (Pico_mcd->s68k_regs[0x02+1] & 0x01)
3f23709e 232 cdc.dma_w = word_ram_0_dma_w;
233 else
234 cdc.dma_w = word_ram_1_dma_w;
235 }
236 else
237 {
f47d0a28 238 if (Pico_mcd->s68k_regs[0x02+1] & 0x02)
3f23709e 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
dd7c8c05 248static int check_decoder_irq_pending(void)
249{
250 /* As per mcd-verificator, DECI is active for a phase of 49:72 per sector */
251 /* 12500000/75 * 49/(49+72) = ~67500, but it sometimes fails with that */
252 if (CYCLES_GE(SekCyclesDoneS68k(), cdc.cycles + 67250))
253 cdc.ifstat |= BIT_DECI;
254
255 return !(cdc.ifstat & BIT_DECI) && (cdc.ifctrl & BIT_DECIEN);
256}
257
178a9b68 258static void do_dma(enum dma_type type, int bytes_in)
3f23709e 259{
178a9b68 260 int dma_addr = (Pico_mcd->s68k_regs[0x0a] << 8) | Pico_mcd->s68k_regs[0x0b];
f47d0a28 261 int src_addr = cdc.dac & 0x3ffe;
3f23709e 262 int dst_addr = dma_addr;
178a9b68 263 int bytes = bytes_in;
264 int words = bytes_in >> 1;
3f23709e 265 int dst_limit = 0;
266 uint8 *dst;
267 int len;
268
269 elprintf(EL_CD, "dma %d %04x->%04x %x",
178a9b68 270 type, cdc.dac, dst_addr, bytes_in);
3f23709e 271
272 switch (type)
273 {
274 case pcm_ram_dma_w:
275 dst_addr = (dst_addr << 2) & 0xffc;
178a9b68 276 if (dst_addr + bytes > 0x1000) {
3f23709e 277 elprintf(EL_ANOMALY, "pcm dma oflow: %x %x", dst_addr, words);
178a9b68 278 bytes = 0x1000 - dst_addr;
3f23709e 279 }
280 dst = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank];
281 dst = dst + dst_addr;
178a9b68 282 while (bytes > 0)
3f23709e 283 {
178a9b68 284 if (src_addr + bytes > 0x4000) {
3f23709e 285 len = 0x4000 - src_addr;
286 memcpy(dst, cdc.ram + src_addr, len);
287 dst += len;
288 src_addr = 0;
178a9b68 289 bytes -= len;
3f23709e 290 continue;
291 }
178a9b68 292 memcpy(dst, cdc.ram + src_addr, bytes);
3f23709e 293 break;
294 }
295 goto update_dma;
296
297 case prg_ram_dma_w:
298 dst_addr <<= 3;
178a9b68 299 dst = Pico_mcd->prg_ram + dst_addr;
3f23709e 300 dst_limit = 0x80000;
301 break;
302
303 case word_ram_0_dma_w:
304 dst_addr = (dst_addr << 3) & 0x1fffe;
178a9b68 305 dst = Pico_mcd->word_ram1M[0] + dst_addr;
3f23709e 306 dst_limit = 0x20000;
307 break;
308
309 case word_ram_1_dma_w:
310 dst_addr = (dst_addr << 3) & 0x1fffe;
178a9b68 311 dst = Pico_mcd->word_ram1M[1] + dst_addr;
3f23709e 312 dst_limit = 0x20000;
313 break;
314
315 case word_ram_2M_dma_w:
316 dst_addr = (dst_addr << 3) & 0x3fffe;
178a9b68 317 dst = Pico_mcd->word_ram2M + dst_addr;
3f23709e 318 dst_limit = 0x40000;
319 break;
320
321 default:
322 elprintf(EL_ANOMALY, "invalid dma: %d", type);
323 goto update_dma;
324 }
325
326 if (dst_addr + words * 2 > dst_limit) {
327 elprintf(EL_ANOMALY, "cd dma %d oflow: %x %x", type, dst_addr, words);
328 words = (dst_limit - dst_addr) / 2;
329 }
330 while (words > 0)
331 {
332 if (src_addr + words * 2 > 0x4000) {
333 len = 0x4000 - src_addr;
334 memcpy16bswap((void *)dst, cdc.ram + src_addr, len / 2);
335 dst += len;
336 src_addr = 0;
337 words -= len / 2;
338 continue;
339 }
340 memcpy16bswap((void *)dst, cdc.ram + src_addr, words);
341 break;
342 }
343
178a9b68 344 bytes_in &= ~1; // Todo leftover byte?
345
3f23709e 346update_dma:
347 /* update DMA addresses */
178a9b68 348 cdc.dac += bytes_in;
3f23709e 349 if (type == pcm_ram_dma_w)
178a9b68 350 dma_addr += bytes_in >> 2;
3f23709e 351 else
178a9b68 352 dma_addr += bytes_in >> 3;
3f23709e 353
354 Pico_mcd->s68k_regs[0x0a] = dma_addr >> 8;
355 Pico_mcd->s68k_regs[0x0b] = dma_addr;
356}
357
3f23709e 358void cdc_dma_update(void)
359{
360 /* end of DMA transfer ? */
f47d0a28 361 //if (cdc.dbc < DMA_BYTES_PER_LINE)
3f23709e 362 {
363 /* transfer remaining words using 16-bit DMA */
f47d0a28 364 //cdc.dma_w((cdc.dbc + 1) >> 1);
178a9b68 365 do_dma(cdc.dma_w, cdc.dbc + 1);
3f23709e 366
367 /* reset data byte counter (DBCH bits 4-7 should be set to 1) */
691abdfa 368 cdc.dbc = 0xffff;
3f23709e 369
370 /* clear !DTEN and !DTBSY */
371 cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
372
178a9b68 373 /* clear DSR bit & set EDT bit (SCD register $04) */
374 Pico_mcd->s68k_regs[0x04+0] = (Pico_mcd->s68k_regs[0x04+0] & 0x07) | 0x80;
3f23709e 375
178a9b68 376 if (cdc.ifstat & BIT_DTEI) {
377 /* pending Data Transfer End interrupt */
378 cdc.ifstat &= ~BIT_DTEI;
379
380 /* Data Transfer End interrupt enabled ? */
dd7c8c05 381 if (!check_decoder_irq_pending() && (cdc.ifctrl & BIT_DTEIEN))
3f23709e 382 {
178a9b68 383 /* level 5 interrupt enabled ? */
384 if (Pico_mcd->s68k_regs[0x32+1] & PCDS_IEN5)
385 {
386 /* update IRQ level */
387 elprintf(EL_INTS, "cdc DTE irq 5");
388 pcd_irq_s68k(5, 1);
389 }
3f23709e 390 }
391 }
392
3f23709e 393 /* disable DMA transfer */
394 cdc.dma_w = 0;
395 }
396#if 0
397 else
398 {
399 /* transfer all words using 16-bit DMA */
400 cdc.dma_w(DMA_BYTES_PER_LINE >> 1);
401
402 /* decrement data byte counter */
f47d0a28 403 cdc.dbc -= length;
3f23709e 404 }
405#endif
406}
407
408int cdc_decoder_update(uint8 header[4])
409{
410 /* data decoding enabled ? */
411 if (cdc.ctrl[0] & BIT_DECEN)
412 {
413 /* update HEAD registers */
414 memcpy(cdc.head[0], header, sizeof(cdc.head[0]));
415
416 /* set !VALST */
417 cdc.stat[3] = 0x00;
418
691abdfa 419 /* set CRCOK bit */
420 cdc.stat[0] = BIT_DECEN;
421
3f23709e 422 /* pending decoder interrupt */
423 cdc.ifstat &= ~BIT_DECI;
dd7c8c05 424 cdc.cycles = SekCyclesDoneS68k();
3f23709e 425
426 /* decoder interrupt enabled ? */
dd7c8c05 427 if (((cdc.ifstat & BIT_DTEI) || !(cdc.ifctrl & BIT_DTEIEN)) && (cdc.ifctrl & BIT_DECIEN))
3f23709e 428 {
429 /* level 5 interrupt enabled ? */
f47d0a28 430 if (Pico_mcd->s68k_regs[0x32+1] & PCDS_IEN5)
3f23709e 431 {
432 /* update IRQ level */
433 elprintf(EL_INTS, "cdc DEC irq 5");
eb36d9c7 434 pcd_irq_s68k(5, 1);
3f23709e 435 }
436 }
437
438 /* buffer RAM write enabled ? */
439 if (cdc.ctrl[0] & BIT_WRRQ)
440 {
441 uint16 offset;
442
443 /* increment block pointer */
f47d0a28 444 cdc.pt += 2352;
3f23709e 445
446 /* increment write address */
f47d0a28 447 cdc.wa += 2352;
3f23709e 448
449 /* CDC buffer address */
f47d0a28 450 offset = cdc.pt & 0x3fff;
3f23709e 451
452 /* write CDD block header (4 bytes) */
453 memcpy(cdc.ram + offset, header, 4);
454
455 /* write CDD block data (2048 bytes) */
456 cdd_read_data(cdc.ram + 4 + offset);
457
458 /* take care of buffer overrun */
459 if (offset > (0x4000 - 2048 - 4))
460 {
461 /* data should be written at the start of buffer */
462 memcpy(cdc.ram, cdc.ram + 0x4000, offset + 2048 + 4 - 0x4000);
463 }
464
465 /* read next data block */
466 return 1;
467 }
468 }
dd7c8c05 469
3f23709e 470 /* keep decoding same data block if Buffer Write is disabled */
471 return 0;
472}
473
474void cdc_reg_w(unsigned char data)
475{
476#ifdef LOG_CDC
f47d0a28 477 elprintf(EL_STATUS, "CDC register %X write 0x%04x", Pico_mcd->s68k_regs[0x04+1] & 0x0F, data);
3f23709e 478#endif
178a9b68 479 switch (Pico_mcd->s68k_regs[0x04+1] & 0x1F)
3f23709e 480 {
178a9b68 481 case 0x00:
482 break;
483
3f23709e 484 case 0x01: /* IFCTRL */
485 {
486 /* pending interrupts ? */
dd7c8c05 487 check_decoder_irq_pending();
3f23709e 488 if (((data & BIT_DTEIEN) && !(cdc.ifstat & BIT_DTEI)) ||
489 ((data & BIT_DECIEN) && !(cdc.ifstat & BIT_DECI)))
490 {
491 /* level 5 interrupt enabled ? */
f47d0a28 492 if (Pico_mcd->s68k_regs[0x32+1] & PCDS_IEN5)
3f23709e 493 {
494 /* update IRQ level */
495 elprintf(EL_INTS, "cdc pending irq 5");
eb36d9c7 496 pcd_irq_s68k(5, 1);
3f23709e 497 }
498 }
499 else // if (scd.pending & (1 << 5))
500 {
501 /* clear pending level 5 interrupts */
eb36d9c7 502 pcd_irq_s68k(5, 0);
3f23709e 503 }
504
505 /* abort any data transfer if data output is disabled */
506 if (!(data & BIT_DOUTEN))
507 {
508 /* clear !DTBSY and !DTEN */
509 cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
510 }
511
512 cdc.ifctrl = data;
f47d0a28 513 Pico_mcd->s68k_regs[0x04+1] = 0x02;
3f23709e 514 break;
515 }
516
517 case 0x02: /* DBCL */
f47d0a28 518 cdc.dbc &= 0xff00;
519 cdc.dbc |= data;
520 Pico_mcd->s68k_regs[0x04+1] = 0x03;
3f23709e 521 break;
522
523 case 0x03: /* DBCH */
f47d0a28 524 cdc.dbc &= 0x00ff;
178a9b68 525 cdc.dbc |= (data & 0x0f) << 8;
f47d0a28 526 Pico_mcd->s68k_regs[0x04+1] = 0x04;
3f23709e 527 break;
528
529 case 0x04: /* DACL */
f47d0a28 530 cdc.dac &= 0xff00;
531 cdc.dac |= data;
532 Pico_mcd->s68k_regs[0x04+1] = 0x05;
3f23709e 533 break;
534
535 case 0x05: /* DACH */
f47d0a28 536 cdc.dac &= 0x00ff;
537 cdc.dac |= data << 8;
538 Pico_mcd->s68k_regs[0x04+1] = 0x06;
3f23709e 539 break;
540
541 case 0x06: /* DTRG */
542 {
543 /* start data transfer if data output is enabled */
544 if (cdc.ifctrl & BIT_DOUTEN)
545 {
546 /* set !DTBSY */
547 cdc.ifstat &= ~BIT_DTBSY;
548
549 /* clear DBCH bits 4-7 */
f47d0a28 550 cdc.dbc &= 0x0fff;
3f23709e 551
552 /* clear EDT & DSR bits (SCD register $04) */
f47d0a28 553 Pico_mcd->s68k_regs[0x04+0] &= 0x07;
3f23709e 554
555 cdc.dma_w = 0;
556
557 /* setup data transfer destination */
f47d0a28 558 switch (Pico_mcd->s68k_regs[0x04+0] & 0x07)
3f23709e 559 {
560 case 2: /* MAIN-CPU host read */
561 case 3: /* SUB-CPU host read */
562 {
563 /* set !DTEN */
564 cdc.ifstat &= ~BIT_DTEN;
565
566 /* set DSR bit (register $04) */
f47d0a28 567 Pico_mcd->s68k_regs[0x04+0] |= 0x40;
3f23709e 568 break;
569 }
570
571 case 4: /* PCM RAM DMA */
572 {
573 cdc.dma_w = pcm_ram_dma_w;
574 break;
575 }
576
577 case 5: /* PRG-RAM DMA */
578 {
579 cdc.dma_w = prg_ram_dma_w;
580 break;
581 }
582
583 case 7: /* WORD-RAM DMA */
584 {
585 /* check memory mode */
f47d0a28 586 if (Pico_mcd->s68k_regs[0x02+1] & 0x04)
3f23709e 587 {
588 /* 1M mode */
f47d0a28 589 if (Pico_mcd->s68k_regs[0x02+1] & 0x01)
3f23709e 590 {
591 /* Word-RAM bank 0 is assigned to SUB-CPU */
592 cdc.dma_w = word_ram_0_dma_w;
593 }
594 else
595 {
596 /* Word-RAM bank 1 is assigned to SUB-CPU */
597 cdc.dma_w = word_ram_1_dma_w;
598 }
599 }
600 else
601 {
602 /* 2M mode */
f47d0a28 603 if (Pico_mcd->s68k_regs[0x02+1] & 0x02)
3f23709e 604 {
605 /* only process DMA if Word-RAM is assigned to SUB-CPU */
606 cdc.dma_w = word_ram_2M_dma_w;
607 }
608 }
609 break;
610 }
611
612 default: /* invalid */
613 {
614 elprintf(EL_ANOMALY, "invalid CDC tranfer destination (%d)",
f47d0a28 615 Pico_mcd->s68k_regs[0x04+0] & 0x07);
3f23709e 616 break;
617 }
618 }
619
620 if (cdc.dma_w)
691abdfa 621 pcd_event_schedule_s68k(PCD_EVENT_DMA, cdc.dbc * DMA_CYCLES_PER_BYTE);
3f23709e 622 }
623
f47d0a28 624 Pico_mcd->s68k_regs[0x04+1] = 0x07;
3f23709e 625 break;
626 }
627
628 case 0x07: /* DTACK */
629 {
630 /* clear pending data transfer end interrupt */
631 cdc.ifstat |= BIT_DTEI;
632
633 /* clear DBCH bits 4-7 */
f47d0a28 634 cdc.dbc &= 0x0fff;
3f23709e 635
3f23709e 636 /* no pending decoder interrupt ? */
dd7c8c05 637 if (!check_decoder_irq_pending())
3f23709e 638 {
639 /* clear pending level 5 interrupt */
eb36d9c7 640 pcd_irq_s68k(5, 0);
3f23709e 641 }
dd7c8c05 642
f47d0a28 643 Pico_mcd->s68k_regs[0x04+1] = 0x08;
3f23709e 644 break;
645 }
646
647 case 0x08: /* WAL */
f47d0a28 648 cdc.wa &= 0xff00;
649 cdc.wa |= data;
650 Pico_mcd->s68k_regs[0x04+1] = 0x09;
3f23709e 651 break;
652
653 case 0x09: /* WAH */
f47d0a28 654 cdc.wa &= 0x00ff;
655 cdc.wa |= data << 8;
656 Pico_mcd->s68k_regs[0x04+1] = 0x0a;
3f23709e 657 break;
658
659 case 0x0a: /* CTRL0 */
660 {
178a9b68 661 /* reset DECI if decoder turned off */
dd7c8c05 662 if (!(data & BIT_DECEN)) {
178a9b68 663 cdc.ifstat |= BIT_DECI;
664
dd7c8c05 665 if ((cdc.ifstat & BIT_DTEI) || !(cdc.ifctrl & BIT_DTEIEN))
666 {
667 /* clear pending level 5 interrupt */
668 pcd_irq_s68k(5, 0);
669 }
670 }
671
3f23709e 672 /* update decoding mode */
673 if (data & BIT_AUTORQ)
674 {
675 /* set MODE bit according to CTRL1 register & clear FORM bit */
676 cdc.stat[2] = cdc.ctrl[1] & BIT_MODRQ;
677 }
dd7c8c05 678 else
3f23709e 679 {
680 /* set MODE & FORM bits according to CTRL1 register */
681 cdc.stat[2] = cdc.ctrl[1] & (BIT_MODRQ | BIT_FORMRQ);
682 }
683
684 cdc.ctrl[0] = data;
f47d0a28 685 Pico_mcd->s68k_regs[0x04+1] = 0x0b;
3f23709e 686 break;
687 }
688
689 case 0x0b: /* CTRL1 */
690 {
691 /* update decoding mode */
692 if (cdc.ctrl[0] & BIT_AUTORQ)
693 {
694 /* set MODE bit according to CTRL1 register & clear FORM bit */
695 cdc.stat[2] = data & BIT_MODRQ;
696 }
dd7c8c05 697 else
3f23709e 698 {
699 /* set MODE & FORM bits according to CTRL1 register */
700 cdc.stat[2] = data & (BIT_MODRQ | BIT_FORMRQ);
701 }
702
703 cdc.ctrl[1] = data;
f47d0a28 704 Pico_mcd->s68k_regs[0x04+1] = 0x0c;
3f23709e 705 break;
706 }
707
708 case 0x0c: /* PTL */
f47d0a28 709 cdc.pt &= 0xff00;
710 cdc.pt |= data;
711 Pico_mcd->s68k_regs[0x04+1] = 0x0d;
3f23709e 712 break;
dd7c8c05 713
3f23709e 714 case 0x0d: /* PTH */
f47d0a28 715 cdc.pt &= 0x00ff;
716 cdc.pt |= data << 8;
717 Pico_mcd->s68k_regs[0x04+1] = 0x0e;
3f23709e 718 break;
719
720 case 0x0e: /* CTRL2 (unused) */
f47d0a28 721 Pico_mcd->s68k_regs[0x04+1] = 0x0f;
3f23709e 722 break;
723
724 case 0x0f: /* RESET */
725 cdc_reset();
726 break;
727
728 default: /* by default, SBOUT is not used */
178a9b68 729 Pico_mcd->s68k_regs[0x04+1] = (Pico_mcd->s68k_regs[0x04+1] + 1) & 0x1f;
3f23709e 730 break;
731 }
732}
733
734unsigned char cdc_reg_r(void)
735{
02ff0254 736 switch (Pico_mcd->s68k_regs[0x04+1] & 0x1F)
3f23709e 737 {
178a9b68 738 case 0x00:
739 return 0xff;
740
3f23709e 741 case 0x01: /* IFSTAT */
f47d0a28 742 Pico_mcd->s68k_regs[0x04+1] = 0x02;
dd7c8c05 743 check_decoder_irq_pending();
3f23709e 744 return cdc.ifstat;
745
746 case 0x02: /* DBCL */
f47d0a28 747 Pico_mcd->s68k_regs[0x04+1] = 0x03;
748 return cdc.dbc & 0xff;
3f23709e 749
750 case 0x03: /* DBCH */
f47d0a28 751 Pico_mcd->s68k_regs[0x04+1] = 0x04;
752 return (cdc.dbc >> 8) & 0xff;
3f23709e 753
754 case 0x04: /* HEAD0 */
f47d0a28 755 Pico_mcd->s68k_regs[0x04+1] = 0x05;
3f23709e 756 return cdc.head[cdc.ctrl[1] & BIT_SHDREN][0];
757
758 case 0x05: /* HEAD1 */
f47d0a28 759 Pico_mcd->s68k_regs[0x04+1] = 0x06;
3f23709e 760 return cdc.head[cdc.ctrl[1] & BIT_SHDREN][1];
761
762 case 0x06: /* HEAD2 */
f47d0a28 763 Pico_mcd->s68k_regs[0x04+1] = 0x07;
3f23709e 764 return cdc.head[cdc.ctrl[1] & BIT_SHDREN][2];
765
766 case 0x07: /* HEAD3 */
f47d0a28 767 Pico_mcd->s68k_regs[0x04+1] = 0x08;
3f23709e 768 return cdc.head[cdc.ctrl[1] & BIT_SHDREN][3];
769
770 case 0x08: /* PTL */
f47d0a28 771 Pico_mcd->s68k_regs[0x04+1] = 0x09;
772 return cdc.pt & 0xff;
3f23709e 773
774 case 0x09: /* PTH */
f47d0a28 775 Pico_mcd->s68k_regs[0x04+1] = 0x0a;
776 return (cdc.pt >> 8) & 0xff;
3f23709e 777
778 case 0x0a: /* WAL */
f47d0a28 779 Pico_mcd->s68k_regs[0x04+1] = 0x0b;
780 return cdc.wa & 0xff;
3f23709e 781
782 case 0x0b: /* WAH */
f47d0a28 783 Pico_mcd->s68k_regs[0x04+1] = 0x0c;
784 return (cdc.wa >> 8) & 0xff;
3f23709e 785
786 case 0x0c: /* STAT0 */
f47d0a28 787 Pico_mcd->s68k_regs[0x04+1] = 0x0d;
3f23709e 788 return cdc.stat[0];
789
790 case 0x0d: /* STAT1 (always return 0) */
f47d0a28 791 Pico_mcd->s68k_regs[0x04+1] = 0x0e;
3f23709e 792 return 0x00;
793
794 case 0x0e: /* STAT2 */
f47d0a28 795 Pico_mcd->s68k_regs[0x04+1] = 0x0f;
3f23709e 796 return cdc.stat[2];
797
798 case 0x0f: /* STAT3 */
799 {
800 uint8 data = cdc.stat[3];
801
802 /* clear !VALST (note: this is not 100% correct but BIOS do not seem to care) */
803 cdc.stat[3] = BIT_VALST;
804
805 /* clear pending decoder interrupt */
806 cdc.ifstat |= BIT_DECI;
dd7c8c05 807
3f23709e 808 /* no pending data transfer end interrupt */
dd7c8c05 809 if ((cdc.ifstat & BIT_DTEI) || !(cdc.ifctrl & BIT_DTEIEN))
3f23709e 810 {
811 /* clear pending level 5 interrupt */
eb36d9c7 812 pcd_irq_s68k(5, 0);
3f23709e 813 }
3f23709e 814
178a9b68 815 Pico_mcd->s68k_regs[0x04+1] = 0x10;
3f23709e 816 return data;
817 }
818
819 default: /* by default, COMIN is always empty */
178a9b68 820 Pico_mcd->s68k_regs[0x04+1] = (Pico_mcd->s68k_regs[0x04+1] + 1) & 0x1f;
3f23709e 821 return 0xff;
822 }
823}
824
dd7c8c05 825unsigned short cdc_host_r(int sub)
3f23709e 826{
dd7c8c05 827 int dir = Pico_mcd->s68k_regs[0x04+0] & 0x07;
828
829 /* sync sub cpu if DSR bit not there (yet?) on main cpu */
830 if (!(Pico_mcd->s68k_regs[0x04+0] & 0x40))
831 if (!sub) pcd_sync_s68k(SekCyclesDone()+8, 0); /* HACK, mcd-verificator */
832
3f23709e 833 /* check if data is available */
834 if (!(cdc.ifstat & BIT_DTEN))
835 {
836 /* read data word from CDC RAM buffer */
f47d0a28 837 uint8 *datap = cdc.ram + (cdc.dac & 0x3ffe);
3f23709e 838 uint16 data = (datap[0] << 8) | datap[1];
839
840#ifdef LOG_CDC
f47d0a28 841 error("CDC host read 0x%04x -> 0x%04x (dbc=0x%x) (%X)\n", cdc.dac, data, cdc.dbc, s68k.pc);
3f23709e 842#endif
dd7c8c05 843
844 /* only the configured cpu access advances the DMA */
845 if ((sub && dir != 3) || (!sub && dir != 2))
846 return data;
847
3f23709e 848 /* increment data address counter */
f47d0a28 849 cdc.dac += 2;
3f23709e 850
851 /* decrement data byte counter */
f47d0a28 852 cdc.dbc -= 2;
3f23709e 853
854 /* end of transfer ? */
f47d0a28 855 if ((int16)cdc.dbc <= 0)
3f23709e 856 {
857 /* reset data byte counter (DBCH bits 4-7 should be set to 1) */
691abdfa 858 cdc.dbc = 0xffff;
3f23709e 859
860 /* clear !DTEN and !DTBSY */
861 cdc.ifstat |= (BIT_DTBSY | BIT_DTEN);
862
178a9b68 863 /* clear DSR bit & set EDT bit (SCD register $04) */
864 Pico_mcd->s68k_regs[0x04+0] = (Pico_mcd->s68k_regs[0x04+0] & 0x07) | 0x80;
02ff0254 865
866 } else if ((int16)cdc.dbc <= 2)
867 {
178a9b68 868 if (cdc.ifstat & BIT_DTEI) {
869 /* pending Data Transfer End interrupt */
870 cdc.ifstat &= ~BIT_DTEI;
3f23709e 871
178a9b68 872 /* Data Transfer End interrupt enabled ? */
dd7c8c05 873 if (!check_decoder_irq_pending() && (cdc.ifctrl & BIT_DTEIEN))
3f23709e 874 {
178a9b68 875 /* level 5 interrupt enabled ? */
876 if (Pico_mcd->s68k_regs[0x32+1] & PCDS_IEN5)
877 {
878 /* update IRQ level */
879 elprintf(EL_INTS, "cdc DTE irq 5");
880 pcd_irq_s68k(5, 1);
881 }
3f23709e 882 }
883 }
178a9b68 884 /* set DSR and EDT bit (SCD register $04) */
885 Pico_mcd->s68k_regs[0x04+0] = (Pico_mcd->s68k_regs[0x04+0] & 0x07) | 0xc0;
3f23709e 886 }
887
888 return data;
889 }
890
891#ifdef LOG_CDC
892 error("error reading CDC host (data transfer disabled)\n");
893#endif
894 return 0xffff;
895}
896
897// vim:shiftwidth=2:ts=2:expandtab