comparison segacd.c @ 2061:7c1760b5b3e5 segacd

Implemented basic TOC functionality of CDD MCU
author Michael Pavone <pavone@retrodev.com>
date Thu, 27 Jan 2022 00:33:41 -0800
parents 70260f6051dd
children 07ed42bd7b4c
comparison
equal deleted inserted replaced
2060:f1c2415f4d1d 2061:7c1760b5b3e5
79 #define BIT_MASK_IEN3 0x0008 79 #define BIT_MASK_IEN3 0x0008
80 #define BIT_MASK_IEN4 0x0010 80 #define BIT_MASK_IEN4 0x0010
81 #define BIT_MASK_IEN5 0x0020 81 #define BIT_MASK_IEN5 0x0020
82 #define BIT_MASK_IEN6 0x0040 82 #define BIT_MASK_IEN6 0x0040
83 83
84 //GA_CDD_CTRL
85 #define BIT_HOCK 0x0004
86
84 static void *prog_ram_wp_write16(uint32_t address, void *vcontext, uint16_t value) 87 static void *prog_ram_wp_write16(uint32_t address, void *vcontext, uint16_t value)
85 { 88 {
86 m68k_context *m68k = vcontext; 89 m68k_context *m68k = vcontext;
87 segacd_context *cd = m68k->system; 90 segacd_context *cd = m68k->system;
88 //if (!(cd->gate_array[GA_MEM_MODE] & (1 << ((address >> 9) + 8)))) { 91 //if (!(cd->gate_array[GA_MEM_MODE] & (1 << ((address >> 9) + 8)))) {
306 static void calculate_target_cycle(m68k_context * context) 309 static void calculate_target_cycle(m68k_context * context)
307 { 310 {
308 segacd_context *cd = context->system; 311 segacd_context *cd = context->system;
309 context->int_cycle = CYCLE_NEVER; 312 context->int_cycle = CYCLE_NEVER;
310 uint8_t mask = context->status & 0x7; 313 uint8_t mask = context->status & 0x7;
311 if (mask < 3) { 314 if (mask < 4) {
312 uint32_t next_timer; 315 if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN4) {
313 if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN3) { 316 uint32_t cdd_cycle = cd->cdd.int_pending ? context->current_cycle : cd->cdd.next_int_cycle;
314 uint32_t next_timer_cycle = next_timer_int(cd); 317 if (cdd_cycle < context->int_cycle) {
315 if (next_timer_cycle < context->int_cycle) { 318 context->int_cycle = cdd_cycle;
316 context->int_cycle = next_timer_cycle; 319 context->int_num = 4;
317 context->int_num = 3; 320 }
318 } 321 }
319 } 322 if (mask < 3) {
320 if (mask < 2) { 323 uint32_t next_timer;
321 if (cd->int2_cycle < context->int_cycle && (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN2)) { 324 if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN3) {
322 context->int_cycle = cd->int2_cycle; 325 uint32_t next_timer_cycle = next_timer_int(cd);
323 context->int_num = 2; 326 if (next_timer_cycle < context->int_cycle) {
327 context->int_cycle = next_timer_cycle;
328 context->int_num = 3;
329 }
330 }
331 if (mask < 2) {
332 if (cd->int2_cycle < context->int_cycle && (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN2)) {
333 context->int_cycle = cd->int2_cycle;
334 context->int_num = 2;
335 }
324 } 336 }
325 } 337 }
326 } 338 }
327 if (context->int_cycle > context->current_cycle && context->int_pending == INT_PENDING_SR_CHANGE) { 339 if (context->int_cycle > context->current_cycle && context->int_pending == INT_PENDING_SR_CHANGE) {
328 context->int_pending = INT_PENDING_NONE; 340 context->int_pending = INT_PENDING_NONE;
361 return lc8951_reg_read(&cd->cdc); 373 return lc8951_reg_read(&cd->cdc);
362 case GA_STOP_WATCH: 374 case GA_STOP_WATCH:
363 case GA_TIMER: 375 case GA_TIMER:
364 timers_run(cd, m68k->current_cycle); 376 timers_run(cd, m68k->current_cycle);
365 return cd->gate_array[reg]; 377 return cd->gate_array[reg];
378 case GA_CDD_STATUS0:
379 case GA_CDD_STATUS1:
380 case GA_CDD_STATUS2:
381 case GA_CDD_STATUS3:
382 case GA_CDD_STATUS4:
383 cdd_mcu_run(&cd->cdd, m68k->current_cycle, cd->gate_array + GA_CDD_CTRL);
384 return cd->gate_array[reg];
385 break;
366 case GA_FONT_DATA0: 386 case GA_FONT_DATA0:
367 case GA_FONT_DATA1: 387 case GA_FONT_DATA1:
368 case GA_FONT_DATA2: 388 case GA_FONT_DATA2:
369 case GA_FONT_DATA3: { 389 case GA_FONT_DATA3: {
370 uint16_t shift = 4 * (3 - (reg - GA_FONT_DATA0)); 390 uint16_t shift = 4 * (3 - (reg - GA_FONT_DATA0));
497 break; 517 break;
498 case GA_INT_MASK: 518 case GA_INT_MASK:
499 cd->gate_array[reg] = value & (BIT_MASK_IEN6|BIT_MASK_IEN5|BIT_MASK_IEN4|BIT_MASK_IEN3|BIT_MASK_IEN2|BIT_MASK_IEN1); 519 cd->gate_array[reg] = value & (BIT_MASK_IEN6|BIT_MASK_IEN5|BIT_MASK_IEN4|BIT_MASK_IEN3|BIT_MASK_IEN2|BIT_MASK_IEN1);
500 calculate_target_cycle(m68k); 520 calculate_target_cycle(m68k);
501 break; 521 break;
522 case GA_CDD_CTRL: {
523 cdd_mcu_run(&cd->cdd, m68k->current_cycle, cd->gate_array + GA_CDD_CTRL);
524 uint16_t changed = cd->gate_array[reg] ^ value;
525 cd->gate_array[reg] &= ~BIT_HOCK;
526 cd->gate_array[reg] |= value & BIT_HOCK;
527 if (changed & BIT_HOCK) {
528 if (value & BIT_HOCK) {
529 cdd_hock_enabled(&cd->cdd);
530 } else {
531 cdd_hock_disabled(&cd->cdd);
532 }
533 calculate_target_cycle(m68k);
534 }
535 break;
536 }
537 case GA_CDD_CMD0:
538 case GA_CDD_CMD1:
539 case GA_CDD_CMD2:
540 case GA_CDD_CMD3:
541 cdd_mcu_run(&cd->cdd, m68k->current_cycle, cd->gate_array + GA_CDD_CTRL);
542 cd->gate_array[reg] = value & 0x0F0F;
543 break;
544 case GA_CDD_CMD4:
545 cdd_mcu_run(&cd->cdd, m68k->current_cycle, cd->gate_array + GA_CDD_CTRL);
546 cd->gate_array[reg] = value & 0x0F0F;
547 cdd_mcu_start_cmd_recv(&cd->cdd, cd->gate_array + GA_CDD_CTRL);
548 break;
502 case GA_FONT_COLOR: 549 case GA_FONT_COLOR:
503 cd->gate_array[reg] = value & 0xFF; 550 cd->gate_array[reg] = value & 0xFF;
504 break; 551 break;
505 case GA_FONT_BITS: 552 case GA_FONT_BITS:
506 cd->gate_array[reg] = value; 553 cd->gate_array[reg] = value;
534 lc8951_ar_write(&cd->cdc, value); 581 lc8951_ar_write(&cd->cdc, value);
535 } else { 582 } else {
536 cd->gate_array[reg] = value << 8; 583 cd->gate_array[reg] = value << 8;
537 } 584 }
538 return vcontext; 585 return vcontext;
586 case GA_CDD_CMD4:
587 if (!address) {
588 //byte write to $FF804A should not trigger transfer
589 cdd_mcu_run(&cd->cdd, m68k->current_cycle, cd->gate_array + GA_CDD_CTRL);
590 cd->gate_array[reg] &= 0x0F;
591 cd->gate_array[reg] |= (value << 8 & 0x0F00);
592 return vcontext;
593 }
594 //intentional fallthrough for $FF804B
539 default: 595 default:
540 if (address & 1) { 596 if (address & 1) {
541 value16 = cd->gate_array[reg] & 0xFF00 | value; 597 value16 = cd->gate_array[reg] & 0xFF00 | value;
542 } else { 598 } else {
543 value16 = cd->gate_array[reg] & 0xFF | (value << 8); 599 value16 = cd->gate_array[reg] & 0xFF | (value << 8);
553 } 609 }
554 610
555 static void scd_peripherals_run(segacd_context *cd, uint32_t cycle) 611 static void scd_peripherals_run(segacd_context *cd, uint32_t cycle)
556 { 612 {
557 timers_run(cd, cycle); 613 timers_run(cd, cycle);
614 cdd_mcu_run(&cd->cdd, cycle, cd->gate_array + GA_CDD_CTRL);
558 } 615 }
559 616
560 static m68k_context *sync_components(m68k_context * context, uint32_t address) 617 static m68k_context *sync_components(m68k_context * context, uint32_t address)
561 { 618 {
562 segacd_context *cd = context->system; 619 segacd_context *cd = context->system;
567 cd->int2_cycle = CYCLE_NEVER; 624 cd->int2_cycle = CYCLE_NEVER;
568 break; 625 break;
569 case 3: 626 case 3:
570 cd->timer_pending = 0; 627 cd->timer_pending = 0;
571 break; 628 break;
629 case 4:
630 cd->cdd.int_pending = 0;
572 } 631 }
573 context->int_ack = 0; 632 context->int_ack = 0;
574 calculate_target_cycle(context); 633 calculate_target_cycle(context);
575 return context; 634 return context;
576 } 635 }
611 if (deduction >= cd->periph_reset_cycle) { 670 if (deduction >= cd->periph_reset_cycle) {
612 cd->periph_reset_cycle = CYCLE_NEVER; 671 cd->periph_reset_cycle = CYCLE_NEVER;
613 } else if (cd->periph_reset_cycle != CYCLE_NEVER) { 672 } else if (cd->periph_reset_cycle != CYCLE_NEVER) {
614 cd->periph_reset_cycle -= deduction; 673 cd->periph_reset_cycle -= deduction;
615 } 674 }
675 cdd_mcu_adjust_cycle(&cd->cdd, deduction);
616 } 676 }
617 677
618 static uint16_t main_gate_read16(uint32_t address, void *vcontext) 678 static uint16_t main_gate_read16(uint32_t address, void *vcontext)
619 { 679 {
620 m68k_context *m68k = vcontext; 680 m68k_context *m68k = vcontext;
847 cd->reset = 1; //active low, so reset is not active on start 907 cd->reset = 1; //active low, so reset is not active on start
848 cd->memptr_start_index = 0; 908 cd->memptr_start_index = 0;
849 cd->gate_array[1] = 1; 909 cd->gate_array[1] = 1;
850 cd->gate_array[0x1B] = 0x100; 910 cd->gate_array[0x1B] = 0x100;
851 lc8951_init(&cd->cdc); 911 lc8951_init(&cd->cdc);
912 if (media->chain && media->type != MEDIA_CDROM) {
913 media = media->chain;
914 }
915 cdd_mcu_init(&cd->cdd, media);
852 916
853 return cd; 917 return cd;
854 } 918 }
855 919
856 memmap_chunk *segacd_main_cpu_map(segacd_context *cd, uint8_t cart_boot, uint32_t *num_chunks) 920 memmap_chunk *segacd_main_cpu_map(segacd_context *cd, uint8_t cart_boot, uint32_t *num_chunks)