comparison segacd.c @ 2094:ca6fc8c8dc60

Pass some more mcd-verificator tests
author Michael Pavone <pavone@retrodev.com>
date Mon, 07 Feb 2022 21:25:56 -0800
parents 3e0801280bef
children b92c998c6742
comparison
equal deleted inserted replaced
2093:46ee354f29bd 2094:ca6fc8c8dc60
373 static void calculate_target_cycle(m68k_context * context) 373 static void calculate_target_cycle(m68k_context * context)
374 { 374 {
375 segacd_context *cd = context->system; 375 segacd_context *cd = context->system;
376 context->int_cycle = CYCLE_NEVER; 376 context->int_cycle = CYCLE_NEVER;
377 uint8_t mask = context->status & 0x7; 377 uint8_t mask = context->status & 0x7;
378 uint32_t cdc_cycle = CYCLE_NEVER;
378 if (mask < 5) { 379 if (mask < 5) {
379 if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN5) { 380 if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN5) {
380 uint32_t cdc_cycle = lc8951_next_interrupt(&cd->cdc); 381 cdc_cycle = lc8951_next_interrupt(&cd->cdc);
381 //CDC interrupts only generated on falling edge of !INT signal 382 //CDC interrupts only generated on falling edge of !INT signal
382 if (cd->cdc_int_ack) { 383 if (cd->cdc_int_ack) {
383 if (cdc_cycle > cd->cdc.cycle) { 384 if (cdc_cycle > cd->cdc.cycle) {
384 cd->cdc_int_ack = 0; 385 cd->cdc_int_ack = 0;
385 } else { 386 } else {
434 if (context->status & M68K_STATUS_TRACE || context->trace_pending) { 435 if (context->status & M68K_STATUS_TRACE || context->trace_pending) {
435 context->target_cycle = context->current_cycle; 436 context->target_cycle = context->current_cycle;
436 return; 437 return;
437 } 438 }
438 context->target_cycle = context->sync_cycle < context->int_cycle ? context->sync_cycle : context->int_cycle; 439 context->target_cycle = context->sync_cycle < context->int_cycle ? context->sync_cycle : context->int_cycle;
440 if (context->target_cycle == cdc_cycle && context->int_num == 5) {
441 uint32_t before = context->target_cycle - 2 * cd->cdc.clock_step;
442 if (before > context->current_cycle) {
443 context->target_cycle = context->sync_cycle = before;
444 }
445 }
439 } 446 }
440 447
441 static uint16_t sub_gate_read16(uint32_t address, void *vcontext) 448 static uint16_t sub_gate_read16(uint32_t address, void *vcontext)
442 { 449 {
443 m68k_context *m68k = vcontext; 450 m68k_context *m68k = vcontext;
801 cd->gate_array[GA_CDC_CTRL] |= BIT_DSR; 808 cd->gate_array[GA_CDC_CTRL] |= BIT_DSR;
802 printf("DSR set at %u, (transfer_end %u, dbcl %X, dbch %X)\n", cd->cdc.cycle, cd->cdc.transfer_end, cd->cdc.regs[2], cd->cdc.regs[3]); 809 printf("DSR set at %u, (transfer_end %u, dbcl %X, dbch %X)\n", cd->cdc.cycle, cd->cdc.transfer_end, cd->cdc.regs[2], cd->cdc.regs[3]);
803 break; 810 break;
804 case DST_PCM_RAM: 811 case DST_PCM_RAM:
805 dma_addr &= (1 << 13) - 1; 812 dma_addr &= (1 << 13) - 1;
813 rf5c164_run(&cd->pcm, cd->cdc.cycle);
806 rf5c164_write(&cd->pcm, 0x1000 | (dma_addr >> 1), value); 814 rf5c164_write(&cd->pcm, 0x1000 | (dma_addr >> 1), value);
807 dma_addr += 2; 815 dma_addr += 2;
808 cd->cdc_dst_low = dma_addr & 7; 816 cd->cdc_dst_low = dma_addr & 7;
809 cd->gate_array[GA_CDC_DMA_ADDR] = dma_addr >> 3; 817 cd->gate_array[GA_CDC_DMA_ADDR] = dma_addr >> 3;
810 break; 818 break;
822 cd->m68k->mem_pointers[1][dma_addr >> 1] = cd->gate_array[GA_CDC_HOST_DATA]; 830 cd->m68k->mem_pointers[1][dma_addr >> 1] = cd->gate_array[GA_CDC_HOST_DATA];
823 m68k_invalidate_code_range(cd->m68k, 0x0C0000 + dma_addr - 1, 0x0C0000 + dma_addr + 1); 831 m68k_invalidate_code_range(cd->m68k, 0x0C0000 + dma_addr - 1, 0x0C0000 + dma_addr + 1);
824 } else { 832 } else {
825 //2M mode, check if Sub CPU has access 833 //2M mode, check if Sub CPU has access
826 if (!(cd->gate_array[GA_MEM_MODE] & BIT_RET)) { 834 if (!(cd->gate_array[GA_MEM_MODE] & BIT_RET)) {
835 cd_graphics_run(cd, cd->cdc.cycle);
827 dma_addr &= (1 << 18) - 1; 836 dma_addr &= (1 << 18) - 1;
828 cd->word_ram[dma_addr >> 1] = cd->gate_array[GA_CDC_HOST_DATA]; 837 cd->word_ram[dma_addr >> 1] = cd->gate_array[GA_CDC_HOST_DATA];
829 m68k_invalidate_code_range(cd->m68k, 0x080000 + dma_addr, 0x080000 + dma_addr + 1); 838 m68k_invalidate_code_range(cd->m68k, 0x080000 + dma_addr, 0x080000 + dma_addr + 1);
830 } 839 }
831 } 840 }
884 } 893 }
885 894
886 void scd_run(segacd_context *cd, uint32_t cycle) 895 void scd_run(segacd_context *cd, uint32_t cycle)
887 { 896 {
888 uint8_t m68k_run = !can_main_access_prog(cd); 897 uint8_t m68k_run = !can_main_access_prog(cd);
889 if (cycle > cd->m68k->current_cycle) { 898 while (cycle > cd->m68k->current_cycle) {
890 if (m68k_run) { 899 if (m68k_run) {
891 uint32_t start = cd->m68k->current_cycle; 900 uint32_t start = cd->m68k->current_cycle;
892 cd->m68k->sync_cycle = cycle; 901 cd->m68k->sync_cycle = cycle;
893 if (cd->need_reset) { 902 if (cd->need_reset) {
894 cd->need_reset = 0; 903 cd->need_reset = 0;
898 resume_68k(cd->m68k); 907 resume_68k(cd->m68k);
899 } 908 }
900 } else { 909 } else {
901 cd->m68k->current_cycle = cycle; 910 cd->m68k->current_cycle = cycle;
902 } 911 }
903 } 912 scd_peripherals_run(cd, cd->m68k->current_cycle);
904 scd_peripherals_run(cd, cycle); 913 }
914
905 } 915 }
906 916
907 uint32_t gen_cycle_to_scd(uint32_t cycle, genesis_context *gen) 917 uint32_t gen_cycle_to_scd(uint32_t cycle, genesis_context *gen)
908 { 918 {
909 return ((uint64_t)cycle) * ((uint64_t)SCD_MCLKS) / ((uint64_t)gen->normal_clock); 919 return ((uint64_t)cycle) * ((uint64_t)SCD_MCLKS) / ((uint64_t)gen->normal_clock);