comparison genesis.c @ 2460:a4f8fa24764b

Initial work on emulating the YMZ263B in the Copera
author Michael Pavone <pavone@retrodev.com>
date Fri, 23 Feb 2024 01:16:38 -0800
parents cb62730d5c99
children b5640ac9aea9
comparison
equal deleted inserted replaced
2459:cb62730d5c99 2460:a4f8fa24764b
686 while (target > gen->psg->cycles && target - gen->psg->cycles > MAX_SOUND_CYCLES) 686 while (target > gen->psg->cycles && target - gen->psg->cycles > MAX_SOUND_CYCLES)
687 { 687 {
688 uint32_t cur_target = gen->psg->cycles + MAX_SOUND_CYCLES; 688 uint32_t cur_target = gen->psg->cycles + MAX_SOUND_CYCLES;
689 psg_run(gen->psg, cur_target); 689 psg_run(gen->psg, cur_target);
690 pico_pcm_run(gen->adpcm, cur_target); 690 pico_pcm_run(gen->adpcm, cur_target);
691 if (gen->ymz) {
692 ymz263b_run(gen->ymz, cur_target);
693 }
691 } 694 }
692 psg_run(gen->psg, target); 695 psg_run(gen->psg, target);
693 pico_pcm_run(gen->adpcm, target); 696 pico_pcm_run(gen->adpcm, target);
697 if (gen->ymz) {
698 ymz263b_run(gen->ymz, target);
699 }
694 } 700 }
695 701
696 static void adjust_int_cycle_pico(m68k_context *context, vdp_context *v_context) 702 static void adjust_int_cycle_pico(m68k_context *context, vdp_context *v_context)
697 { 703 {
698 genesis_context *gen = context->system; 704 genesis_context *gen = context->system;
715 context->int_cycle = next_hint; 721 context->int_cycle = next_hint;
716 context->int_num = 5; 722 context->int_num = 5;
717 723
718 } 724 }
719 } 725 }
720 if (mask < 3) { 726 if (mask < 4) {
721 uint32_t next_pcm_int = pico_pcm_next_int(gen->adpcm); 727 if (v_context->regs[REG_MODE_3] & BIT_EINT_EN) {
722 if (next_pcm_int != CYCLE_NEVER && next_pcm_int < context->int_cycle) {
723 context->int_cycle = next_pcm_int;
724 context->int_num = 3;
725 }
726 if (mask < 2 && (v_context->regs[REG_MODE_3] & BIT_EINT_EN) && gen->header.type == SYSTEM_GENESIS) {
727 uint32_t next_eint_port0 = io_next_interrupt(gen->io.ports, context->current_cycle); 728 uint32_t next_eint_port0 = io_next_interrupt(gen->io.ports, context->current_cycle);
728 uint32_t next_eint_port1 = io_next_interrupt(gen->io.ports + 1, context->current_cycle); 729 uint32_t next_eint_port1 = io_next_interrupt(gen->io.ports + 1, context->current_cycle);
729 uint32_t next_eint_port2 = io_next_interrupt(gen->io.ports + 2, context->current_cycle); 730 uint32_t next_eint_port2 = io_next_interrupt(gen->io.ports + 2, context->current_cycle);
730 uint32_t next_eint = next_eint_port0 < next_eint_port1 731 uint32_t next_eint = next_eint_port0 < next_eint_port1
731 ? (next_eint_port0 < next_eint_port2 ? next_eint_port0 : next_eint_port2) 732 ? (next_eint_port0 < next_eint_port2 ? next_eint_port0 : next_eint_port2)
736 context->int_cycle = next_eint; 737 context->int_cycle = next_eint;
737 context->int_num = 2; 738 context->int_num = 2;
738 } 739 }
739 } 740 }
740 } 741 }
742 if (mask < 3) {
743 uint32_t next_pcm_int = pico_pcm_next_int(gen->adpcm);
744 if (next_pcm_int != CYCLE_NEVER && next_pcm_int < context->int_cycle) {
745 context->int_cycle = next_pcm_int;
746 context->int_num = 3;
747 }
748
749 if (mask < 2 && gen->ymz) {
750 uint32_t ymz_int = ymz263b_next_int(gen->ymz);
751 if (ymz_int < context->int_cycle) {
752 context->int_cycle = ymz_int;
753 context->int_num = 2;
754 }
755 }
756 }
741 } 757 }
742 } 758 }
743 } 759 }
744 if (context->int_cycle > context->current_cycle && context->int_pending == INT_PENDING_SR_CHANGE) { 760 if (context->int_cycle > context->current_cycle && context->int_pending == INT_PENDING_SR_CHANGE) {
745 context->int_pending = INT_PENDING_NONE; 761 context->int_pending = INT_PENDING_NONE;
832 if (gen->psg->vgm) { 848 if (gen->psg->vgm) {
833 vgm_adjust_cycles(gen->psg->vgm, deduction); 849 vgm_adjust_cycles(gen->psg->vgm, deduction);
834 } 850 }
835 gen->psg->cycles -= deduction; 851 gen->psg->cycles -= deduction;
836 gen->adpcm->cycle -= deduction; 852 gen->adpcm->cycle -= deduction;
853 if (gen->ymz) {
854 gen->ymz->cycle -= deduction;
855 }
837 if (gen->reset_cycle != CYCLE_NEVER) { 856 if (gen->reset_cycle != CYCLE_NEVER) {
838 gen->reset_cycle -= deduction; 857 gen->reset_cycle -= deduction;
839 } 858 }
840 event_cycle_adjust(mclks, deduction); 859 event_cycle_adjust(mclks, deduction);
841 if (gen->expansion) { 860 if (gen->expansion) {
904 } 923 }
905 924
906 static m68k_context *int_ack(m68k_context *context) 925 static m68k_context *int_ack(m68k_context *context)
907 { 926 {
908 genesis_context * gen = context->system; 927 genesis_context * gen = context->system;
909 if ((gen->header.type != SYSTEM_PICO && gen->header.type != SYSTEM_COPERA) || context->int_num > 4 || context->int_num < 3) { 928 if ((gen->header.type != SYSTEM_PICO && gen->header.type != SYSTEM_COPERA) || context->int_num > 3) {
910 vdp_context * v_context = gen->vdp; 929 vdp_context * v_context = gen->vdp;
911 //printf("acknowledging %d @ %d:%d, vcounter: %d, hslot: %d\n", context->int_ack, context->current_cycle, v_context->cycles, v_context->vcounter, v_context->hslot); 930 //printf("acknowledging %d @ %d:%d, vcounter: %d, hslot: %d\n", context->int_ack, context->current_cycle, v_context->cycles, v_context->vcounter, v_context->hslot);
912 vdp_run_context(v_context, context->current_cycle); 931 vdp_run_context(v_context, context->current_cycle);
913 vdp_int_ack(v_context); 932 vdp_int_ack(v_context);
914 } 933 }
1559 return 0xFFFF; 1578 return 0xFFFF;
1560 } 1579 }
1561 1580
1562 static uint8_t copera_io_read(uint32_t location, void *vcontext) 1581 static uint8_t copera_io_read(uint32_t location, void *vcontext)
1563 { 1582 {
1564 printf("Unhandled Copera 8-bit read %X\n", location); 1583 uint8_t ret;
1565 return 0xFF; 1584 m68k_context *m68k = vcontext;
1566 } 1585 genesis_context *gen = m68k->system;
1567
1568 static void* copera_io_write_w(uint32_t location, void *vcontext, uint16_t value)
1569 {
1570 printf("Unhandled Copera 16-bit write %X: %X\n", location, value);
1571 return vcontext;
1572 }
1573
1574 static void* copera_io_write(uint32_t location, void *vcontext, uint8_t value)
1575 {
1576 switch (location & 0xFF) 1586 switch (location & 0xFF)
1577 { 1587 {
1578 case 1: 1588 case 1:
1579 case 5: 1589 case 5:
1590 ymz263b_run(gen->ymz, m68k->current_cycle);
1591 ret = ymz263b_status_read(gen->ymz);
1592 printf("Copera YMZ263 Status read - %X: %X\n", location, ret);
1593 adjust_int_cycle_pico(gen->m68k, gen->vdp);
1594 return ret;
1595 case 3:
1596 case 7:
1597 ymz263b_run(gen->ymz, m68k->current_cycle);
1598 ret = ymz263b_data_read(gen->ymz, location & 4);
1599 printf("Copera YMZ263 Data read - %X: %X\n", location, ret);
1600 return ret;
1601 default:
1602 printf("Unhandled Copera 8-bit read %X\n", location);
1603 return 0xFF;
1604 }
1605 }
1606
1607 static void* copera_io_write_w(uint32_t location, void *vcontext, uint16_t value)
1608 {
1609 printf("Unhandled Copera 16-bit write %X: %X\n", location, value);
1610 return vcontext;
1611 }
1612
1613 static void* copera_io_write(uint32_t location, void *vcontext, uint8_t value)
1614 {
1615 m68k_context *m68k = vcontext;
1616 genesis_context *gen = m68k->system;
1617 switch (location & 0xFF)
1618 {
1619 case 1:
1620 case 5:
1621 ymz263b_run(gen->ymz, m68k->current_cycle);
1580 printf("Copera YMZ263 Address write - %X: %X\n", location, value); 1622 printf("Copera YMZ263 Address write - %X: %X\n", location, value);
1623 ymz263b_address_write(gen->ymz, value);
1581 break; 1624 break;
1582 case 3: 1625 case 3:
1583 case 7: 1626 case 7:
1627 ymz263b_run(gen->ymz, m68k->current_cycle);
1584 printf("Copera YMZ263 Channel #%d Data write - %X: %X\n", ((location & 4) >> 2) + 1, location, value); 1628 printf("Copera YMZ263 Channel #%d Data write - %X: %X\n", ((location & 4) >> 2) + 1, location, value);
1629 ymz263b_data_write(gen->ymz, location & 4, value);
1630 adjust_int_cycle_pico(gen->m68k, gen->vdp);
1585 break; 1631 break;
1586 case 0x24: 1632 case 0x24:
1587 case 0x34: 1633 case 0x34:
1588 printf("Copera YMF263 Address Part #%d write - %X: %X\n", ((location >> 4) & 1) + 1, location, value); 1634 printf("Copera YMF262 Address Part #%d write - %X: %X\n", ((location >> 4) & 1) + 1, location, value);
1589 break; 1635 break;
1590 case 0x28: 1636 case 0x28:
1591 printf("Copera YMF263 Data write - %X: %X\n", location, value); 1637 printf("Copera YMF262 Data write - %X: %X\n", location, value);
1592 break; 1638 break;
1593 case 0x40: 1639 case 0x40:
1594 //Bit 4 = SCI 1640 //Bit 4 = SCI
1595 //Bit 5 = DIN 1641 //Bit 5 = DIN
1596 //Bit 6 = A0 1642 //Bit 6 = A0
2157 free(gen->zram); 2203 free(gen->zram);
2158 } 2204 }
2159 if (gen->header.type == SYSTEM_PICO || gen->header.type == SYSTEM_COPERA) { 2205 if (gen->header.type == SYSTEM_PICO || gen->header.type == SYSTEM_COPERA) {
2160 pico_pcm_free(gen->adpcm); 2206 pico_pcm_free(gen->adpcm);
2161 free(gen->adpcm); 2207 free(gen->adpcm);
2208 if (gen->ymz) {
2209 //TODO: call cleanup function once it exists
2210 free(gen->ymz);
2211 }
2162 } else { 2212 } else {
2163 ym_free(gen->ym); 2213 ym_free(gen->ym);
2164 } 2214 }
2165 psg_free(gen->psg); 2215 psg_free(gen->psg);
2166 free(gen->header.save_dir); 2216 free(gen->header.save_dir);
3123 psg_init(gen->psg, gen->master_clock, MCLKS_PER_PSG); 3173 psg_init(gen->psg, gen->master_clock, MCLKS_PER_PSG);
3124 3174
3125 gen->adpcm = calloc(1, sizeof(pico_pcm)); 3175 gen->adpcm = calloc(1, sizeof(pico_pcm));
3126 pico_pcm_init(gen->adpcm, gen->master_clock, 42); 3176 pico_pcm_init(gen->adpcm, gen->master_clock, 42);
3127 3177
3178 if (stype == SYSTEM_COPERA) {
3179 gen->ymz = calloc(1, sizeof(*gen->ymz));
3180 //This divider is just a guess, PCB diagram in MAME shows no other crystal
3181 //Datasheet says the typical clock is 16.9344 MHz
3182 //Master clock / 3 is 17.897725 MHz which is reasonably close
3183 ymz263b_init(gen->ymz, 3);
3184 }
3185
3128 gen->work_ram = calloc(2, RAM_WORDS); 3186 gen->work_ram = calloc(2, RAM_WORDS);
3129 if (!strcmp("random", tern_find_path_default(config, "system\0ram_init\0", (tern_val){.ptrval = "zero"}, TVAL_PTR).ptrval)) 3187 if (!strcmp("random", tern_find_path_default(config, "system\0ram_init\0", (tern_val){.ptrval = "zero"}, TVAL_PTR).ptrval))
3130 { 3188 {
3131 srand(time(NULL)); 3189 srand(time(NULL));
3132 for (int i = 0; i < RAM_WORDS; i++) 3190 for (int i = 0; i < RAM_WORDS; i++)