comparison segacd.c @ 2116:cd057d6fe030

Initial stab at subcode emulation
author Michael Pavone <pavone@retrodev.com>
date Sun, 06 Mar 2022 22:03:52 -0800
parents 4be496489eda
children 5ec2f97365a2
comparison
equal deleted inserted replaced
2115:e93ced356a21 2116:cd057d6fe030
53 GA_FONT_BITS, 53 GA_FONT_BITS,
54 GA_FONT_DATA0, 54 GA_FONT_DATA0,
55 GA_FONT_DATA1, 55 GA_FONT_DATA1,
56 GA_FONT_DATA2, 56 GA_FONT_DATA2,
57 GA_FONT_DATA3, 57 GA_FONT_DATA3,
58 GA_SUBCODE_START = 0x80,
59 GA_SUBCODE_MIRROR = 0xC0,
58 60
59 GA_HINT_VECTOR = GA_CDC_REG_DATA 61 GA_HINT_VECTOR = GA_CDC_REG_DATA
60 }; 62 };
61 //GA_SUB_CPU_CTRL 63 //GA_SUB_CPU_CTRL
62 #define BIT_IEN2 0x8000 64 #define BIT_IEN2 0x8000
385 { 387 {
386 segacd_context *cd = context->system; 388 segacd_context *cd = context->system;
387 context->int_cycle = CYCLE_NEVER; 389 context->int_cycle = CYCLE_NEVER;
388 uint8_t mask = context->status & 0x7; 390 uint8_t mask = context->status & 0x7;
389 uint32_t cdc_cycle = CYCLE_NEVER; 391 uint32_t cdc_cycle = CYCLE_NEVER;
390 if (mask < 5) { 392 if (mask < 6) {
391 if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN5) { 393 if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN6) {
392 cdc_cycle = lc8951_next_interrupt(&cd->cdc); 394 uint32_t subcode_cycle = cd->cdd.subcode_int_pending ? context->current_cycle : cd->cdd.next_subcode_int_cycle;
393 //CDC interrupts only generated on falling edge of !INT signal 395 if (subcode_cycle != CYCLE_NEVER) {
394 if (cd->cdc_int_ack) { 396 context->int_cycle = subcode_cycle;
395 if (cdc_cycle > cd->cdc.cycle) { 397 context->int_num = 6;
396 cd->cdc_int_ack = 0; 398 }
397 } else { 399 }
398 cdc_cycle = CYCLE_NEVER; 400 if (mask < 5) {
399 } 401 if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN5) {
400 } 402 cdc_cycle = lc8951_next_interrupt(&cd->cdc);
401 if (cdc_cycle < context->int_cycle) { 403 //CDC interrupts only generated on falling edge of !INT signal
402 context->int_cycle = cdc_cycle; 404 if (cd->cdc_int_ack) {
403 context->int_num = 5; 405 if (cdc_cycle > cd->cdc.cycle) {
404 } 406 cd->cdc_int_ack = 0;
405 } 407 } else {
406 if (mask < 4) { 408 cdc_cycle = CYCLE_NEVER;
407 if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN4) {
408 uint32_t cdd_cycle = cd->cdd.int_pending ? context->current_cycle : cd->cdd.next_int_cycle;
409 if (cdd_cycle < context->int_cycle) {
410 context->int_cycle = cdd_cycle;
411 context->int_num = 4;
412 }
413 }
414 if (mask < 3) {
415 uint32_t next_timer;
416 if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN3) {
417 uint32_t next_timer_cycle = next_timer_int(cd);
418 if (next_timer_cycle < context->int_cycle) {
419 context->int_cycle = next_timer_cycle;
420 context->int_num = 3;
421 } 409 }
422 } 410 }
423 if (mask < 2) { 411 if (cdc_cycle < context->int_cycle) {
424 if (cd->int2_cycle < context->int_cycle && (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN2)) { 412 context->int_cycle = cdc_cycle;
425 context->int_cycle = cd->int2_cycle; 413 context->int_num = 5;
426 context->int_num = 2; 414 }
415 }
416 if (mask < 4) {
417 if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN4) {
418 uint32_t cdd_cycle = cd->cdd.int_pending ? context->current_cycle : cd->cdd.next_int_cycle;
419 if (cdd_cycle < context->int_cycle) {
420 context->int_cycle = cdd_cycle;
421 context->int_num = 4;
427 } 422 }
428 if (mask < 1) { 423 }
429 if (cd->graphics_int_cycle < context->int_cycle && (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN1)) { 424 if (mask < 3) {
430 context->int_cycle = cd->graphics_int_cycle; 425 uint32_t next_timer;
431 context->int_num = 1; 426 if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN3) {
427 uint32_t next_timer_cycle = next_timer_int(cd);
428 if (next_timer_cycle < context->int_cycle) {
429 context->int_cycle = next_timer_cycle;
430 context->int_num = 3;
431 }
432 }
433 if (mask < 2) {
434 if (cd->int2_cycle < context->int_cycle && (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN2)) {
435 context->int_cycle = cd->int2_cycle;
436 context->int_num = 2;
437 }
438 if (mask < 1) {
439 if (cd->graphics_int_cycle < context->int_cycle && (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN1)) {
440 context->int_cycle = cd->graphics_int_cycle;
441 context->int_num = 1;
442 }
432 } 443 }
433 } 444 }
434 } 445 }
435 } 446 }
436 } 447 }
519 pixel = bg; 530 pixel = bg;
520 } 531 }
521 value |= pixel << (i * 4); 532 value |= pixel << (i * 4);
522 } 533 }
523 return value; 534 return value;
535 }
524 case GA_STAMP_SIZE: 536 case GA_STAMP_SIZE:
525 case GA_IMAGE_BUFFER_LINES: 537 case GA_IMAGE_BUFFER_LINES:
526 //these two have bits that change based on graphics operations 538 //these two have bits that change based on graphics operations
527 cd_graphics_run(cd, m68k->current_cycle); 539 cd_graphics_run(cd, m68k->current_cycle);
528 return cd->gate_array[reg]; 540 return cd->gate_array[reg];
529 case GA_TRACE_VECTOR_BASE: 541 case GA_TRACE_VECTOR_BASE:
530 //write only 542 //write only
531 return 0xFFFF; 543 return 0xFFFF;
532 }
533 default: 544 default:
545 if (reg >= GA_SUBCODE_MIRROR) {
546 return cd->gate_array[GA_SUBCODE_START + (reg & 0x3F)];
547 }
534 return cd->gate_array[reg]; 548 return cd->gate_array[reg];
535 } 549 }
536 } 550 }
537 551
538 static uint8_t sub_gate_read8(uint32_t address, void *vcontext) 552 static uint8_t sub_gate_read8(uint32_t address, void *vcontext)
653 timers_run(cd, m68k->current_cycle); 667 timers_run(cd, m68k->current_cycle);
654 cd->gate_array[reg] = value & 0xFF; 668 cd->gate_array[reg] = value & 0xFF;
655 calculate_target_cycle(m68k); 669 calculate_target_cycle(m68k);
656 break; 670 break;
657 case GA_INT_MASK: 671 case GA_INT_MASK:
672 if (!(cd->gate_array[reg] & BIT_MASK_IEN6)) {
673 //subcode interrupts can't be made pending when they are disabled in this reg
674 cd->cdd.subcode_int_pending = 0;
675 }
658 cd->gate_array[reg] = value & (BIT_MASK_IEN6|BIT_MASK_IEN5|BIT_MASK_IEN4|BIT_MASK_IEN3|BIT_MASK_IEN2|BIT_MASK_IEN1); 676 cd->gate_array[reg] = value & (BIT_MASK_IEN6|BIT_MASK_IEN5|BIT_MASK_IEN4|BIT_MASK_IEN3|BIT_MASK_IEN2|BIT_MASK_IEN1);
659 calculate_target_cycle(m68k); 677 calculate_target_cycle(m68k);
660 break; 678 break;
661 case GA_CDD_FADER: 679 case GA_CDD_FADER:
662 cdd_run(cd, m68k->current_cycle); 680 cdd_run(cd, m68k->current_cycle);
900 case 4: 918 case 4:
901 cd->cdd.int_pending = 0; 919 cd->cdd.int_pending = 0;
902 break; 920 break;
903 case 5: 921 case 5:
904 cd->cdc_int_ack = 1; 922 cd->cdc_int_ack = 1;
923 break;
924 case 6:
925 cd->cdd.subcode_int_pending = 0;
905 break; 926 break;
906 } 927 }
907 context->int_ack = 0; 928 context->int_ack = 0;
908 calculate_target_cycle(context); 929 calculate_target_cycle(context);
909 return context; 930 return context;