Mercurial > repos > blastem
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) |