comparison segacd.c @ 2069:8e51c0c3f2e3 segacd

Initial attempt at implementing the Sega CD graphics hardware
author Michael Pavone <pavone@retrodev.com>
date Sun, 30 Jan 2022 19:55:33 -0800
parents f573f2c31bc9
children c69e42444f96
comparison
equal deleted inserted replaced
2068:f573f2c31bc9 2069:8e51c0c3f2e3
1 #include <stdlib.h> 1 #include <stdlib.h>
2 #include <string.h> 2 #include <string.h>
3 #include "segacd.h" 3 #include "cd_graphics.h"
4 #include "genesis.h" 4 #include "genesis.h"
5 #include "util.h" 5 #include "util.h"
6 6
7 #define SCD_MCLKS 50000000 7 #define SCD_MCLKS 50000000
8 #define SCD_PERIPH_RESET_CLKS (SCD_MCLKS / 10) 8 #define SCD_PERIPH_RESET_CLKS (SCD_MCLKS / 10)
365 if (mask < 2) { 365 if (mask < 2) {
366 if (cd->int2_cycle < context->int_cycle && (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN2)) { 366 if (cd->int2_cycle < context->int_cycle && (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN2)) {
367 context->int_cycle = cd->int2_cycle; 367 context->int_cycle = cd->int2_cycle;
368 context->int_num = 2; 368 context->int_num = 2;
369 } 369 }
370 if (mask < 1) {
371 if (cd->graphics_int_cycle < context->int_cycle && (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN1)) {
372 context->int_cycle = cd->graphics_int_cycle;
373 context->int_num = 1;
374 }
375 }
370 } 376 }
371 } 377 }
372 } 378 }
373 } 379 }
374 if (context->int_cycle > context->current_cycle && context->int_pending == INT_PENDING_SR_CHANGE) { 380 if (context->int_cycle > context->current_cycle && context->int_pending == INT_PENDING_SR_CHANGE) {
449 pixel = bg; 455 pixel = bg;
450 } 456 }
451 value |= pixel << (i * 4); 457 value |= pixel << (i * 4);
452 } 458 }
453 return value; 459 return value;
460 case GA_STAMP_SIZE:
461 case GA_IMAGE_BUFFER_LINES:
462 //these two have bits that change based on graphics operations
463 cd_graphics_run(cd, m68k->current_cycle);
464 return cd->gate_array[reg];
465 case GA_TRACE_VECTOR_BASE:
466 //write only
467 return 0xFFFF;
454 } 468 }
455 default: 469 default:
456 return cd->gate_array[reg]; 470 return cd->gate_array[reg];
457 } 471 }
458 } 472 }
611 cd->gate_array[reg] = value & 0xFF; 625 cd->gate_array[reg] = value & 0xFF;
612 break; 626 break;
613 case GA_FONT_BITS: 627 case GA_FONT_BITS:
614 cd->gate_array[reg] = value; 628 cd->gate_array[reg] = value;
615 break; 629 break;
630 case GA_STAMP_SIZE:
631 cd_graphics_run(cd, m68k->current_cycle);
632 cd->gate_array[reg] &= BIT_GRON;
633 cd->gate_array[reg] |= value & (BIT_SMS|BIT_STS|BIT_RPT);
634 break;
635 case GA_STAMP_MAP_BASE:
636 cd_graphics_run(cd, m68k->current_cycle);
637 cd->gate_array[reg] = value & 0xFFE0;
638 break;
639 case GA_IMAGE_BUFFER_VCELLS:
640 cd_graphics_run(cd, m68k->current_cycle);
641 cd->gate_array[reg] = value & 0x1F;
642 break;
643 case GA_IMAGE_BUFFER_START:
644 cd_graphics_run(cd, m68k->current_cycle);
645 cd->gate_array[reg] = value & 0xFFF8;
646 break;
647 case GA_IMAGE_BUFFER_OFFSET:
648 cd_graphics_run(cd, m68k->current_cycle);
649 cd->gate_array[reg] = value & 0x3F;
650 break;
651 case GA_IMAGE_BUFFER_HDOTS:
652 cd_graphics_run(cd, m68k->current_cycle);
653 cd->gate_array[reg] = value & 0x1FF;
654 break;
655 case GA_IMAGE_BUFFER_LINES:
656 cd_graphics_run(cd, m68k->current_cycle);
657 cd->gate_array[reg] = value & 0xFF;
658 break;
659 case GA_TRACE_VECTOR_BASE:
660 cd_graphics_run(cd, m68k->current_cycle);
661 cd->gate_array[reg] = value & 0xFFFE;
662 cd_graphics_start(cd);
663 break;
616 default: 664 default:
617 printf("Unhandled gate array write %X:%X\n", address, value); 665 printf("Unhandled gate array write %X:%X\n", address, value);
618 } 666 }
619 return vcontext; 667 return vcontext;
620 } 668 }
745 793
746 static void scd_peripherals_run(segacd_context *cd, uint32_t cycle) 794 static void scd_peripherals_run(segacd_context *cd, uint32_t cycle)
747 { 795 {
748 timers_run(cd, cycle); 796 timers_run(cd, cycle);
749 cdd_run(cd, cycle); 797 cdd_run(cd, cycle);
798 cd_graphics_run(cd, cycle);
750 } 799 }
751 800
752 static m68k_context *sync_components(m68k_context * context, uint32_t address) 801 static m68k_context *sync_components(m68k_context * context, uint32_t address)
753 { 802 {
754 segacd_context *cd = context->system; 803 segacd_context *cd = context->system;
755 scd_peripherals_run(cd, context->current_cycle); 804 scd_peripherals_run(cd, context->current_cycle);
756 switch (context->int_ack) 805 switch (context->int_ack)
757 { 806 {
807 case 1:
808 cd->graphics_int_cycle = CYCLE_NEVER;
809 break;
758 case 2: 810 case 2:
759 cd->int2_cycle = CYCLE_NEVER; 811 cd->int2_cycle = CYCLE_NEVER;
760 break; 812 break;
761 case 3: 813 case 3:
762 cd->timer_pending = 0; 814 cd->timer_pending = 0;
814 } else if (cd->periph_reset_cycle != CYCLE_NEVER) { 866 } else if (cd->periph_reset_cycle != CYCLE_NEVER) {
815 cd->periph_reset_cycle -= deduction; 867 cd->periph_reset_cycle -= deduction;
816 } 868 }
817 cdd_mcu_adjust_cycle(&cd->cdd, deduction); 869 cdd_mcu_adjust_cycle(&cd->cdd, deduction);
818 lc8951_adjust_cycles(&cd->cdc, deduction); 870 lc8951_adjust_cycles(&cd->cdc, deduction);
871 cd->graphics_cycle -= deduction;
872 if (cd->graphics_int_cycle != CYCLE_NEVER) {
873 if (cd->graphics_int_cycle > deduction) {
874 cd->graphics_int_cycle -= deduction;
875 } else {
876 cd->graphics_int_cycle = 0;
877 }
878 }
819 } 879 }
820 880
821 static uint16_t main_gate_read16(uint32_t address, void *vcontext) 881 static uint16_t main_gate_read16(uint32_t address, void *vcontext)
822 { 882 {
823 m68k_context *m68k = vcontext; 883 m68k_context *m68k = vcontext;
1104 lc8951_init(&cd->cdc, handle_cdc_byte, cd); 1164 lc8951_init(&cd->cdc, handle_cdc_byte, cd);
1105 if (media->chain && media->type != MEDIA_CDROM) { 1165 if (media->chain && media->type != MEDIA_CDROM) {
1106 media = media->chain; 1166 media = media->chain;
1107 } 1167 }
1108 cdd_mcu_init(&cd->cdd, media); 1168 cdd_mcu_init(&cd->cdd, media);
1169 cd_graphics_init(cd);
1109 1170
1110 return cd; 1171 return cd;
1111 } 1172 }
1112 1173
1113 memmap_chunk *segacd_main_cpu_map(segacd_context *cd, uint8_t cart_boot, uint32_t *num_chunks) 1174 memmap_chunk *segacd_main_cpu_map(segacd_context *cd, uint8_t cart_boot, uint32_t *num_chunks)