comparison genesis.c @ 1116:fe8c79f82c22

More cleanup in preparation for SMS/Mark III support
author Michael Pavone <pavone@retrodev.com>
date Thu, 22 Dec 2016 10:51:33 -0800
parents 45db303fc705
children 928a65750345
comparison
equal deleted inserted replaced
1115:c1e78a101912 1116:fe8c79f82c22
43 { 43 {
44 genesis_context *genesis = (genesis_context *)current_system; 44 genesis_context *genesis = (genesis_context *)current_system;
45 return read_dma_value(genesis->m68k->last_prefetch_address/2); 45 return read_dma_value(genesis->m68k->last_prefetch_address/2);
46 } 46 }
47 47
48 void adjust_int_cycle(m68k_context * context, vdp_context * v_context) 48 static void adjust_int_cycle(m68k_context * context, vdp_context * v_context)
49 { 49 {
50 //static int old_int_cycle = CYCLE_NEVER; 50 //static int old_int_cycle = CYCLE_NEVER;
51 genesis_context *gen = context->system; 51 genesis_context *gen = context->system;
52 if (context->sync_cycle - context->current_cycle > gen->max_cycles) { 52 if (context->sync_cycle - context->current_cycle > gen->max_cycles) {
53 context->sync_cycle = context->current_cycle + gen->max_cycles; 53 context->sync_cycle = context->current_cycle + gen->max_cycles;
107 z_context->int_pulse_start = vdp_next_vint_z80(gen->vdp); 107 z_context->int_pulse_start = vdp_next_vint_z80(gen->vdp);
108 //Notes in the Genesis Plus GX code suggest this is asserted for one line 108 //Notes in the Genesis Plus GX code suggest this is asserted for one line
109 z_context->int_pulse_end = z_context->int_pulse_start + MCLKS_LINE; 109 z_context->int_pulse_end = z_context->int_pulse_start + MCLKS_LINE;
110 } 110 }
111 111
112 void sync_z80(z80_context * z_context, uint32_t mclks) 112 static void sync_z80(z80_context * z_context, uint32_t mclks)
113 { 113 {
114 #ifndef NO_Z80 114 #ifndef NO_Z80
115 if (z80_enabled) { 115 if (z80_enabled) {
116 z80_run(z_context, mclks); 116 z80_run(z_context, mclks);
117 } else 117 } else
119 { 119 {
120 z_context->current_cycle = mclks; 120 z_context->current_cycle = mclks;
121 } 121 }
122 } 122 }
123 123
124 void sync_sound(genesis_context * gen, uint32_t target) 124 static void sync_sound(genesis_context * gen, uint32_t target)
125 { 125 {
126 //printf("YM | Cycle: %d, bpos: %d, PSG | Cycle: %d, bpos: %d\n", gen->ym->current_cycle, gen->ym->buffer_pos, gen->psg->cycles, gen->psg->buffer_pos * 2); 126 //printf("YM | Cycle: %d, bpos: %d, PSG | Cycle: %d, bpos: %d\n", gen->ym->current_cycle, gen->ym->buffer_pos, gen->psg->cycles, gen->psg->buffer_pos * 2);
127 while (target > gen->psg->cycles && target - gen->psg->cycles > MAX_SOUND_CYCLES) { 127 while (target > gen->psg->cycles && target - gen->psg->cycles > MAX_SOUND_CYCLES) {
128 uint32_t cur_target = gen->psg->cycles + MAX_SOUND_CYCLES; 128 uint32_t cur_target = gen->psg->cycles + MAX_SOUND_CYCLES;
129 //printf("Running PSG to cycle %d\n", cur_target); 129 //printf("Running PSG to cycle %d\n", cur_target);
135 ym_run(gen->ym, target); 135 ym_run(gen->ym, target);
136 136
137 //printf("Target: %d, YM bufferpos: %d, PSG bufferpos: %d\n", target, gen->ym->buffer_pos, gen->psg->buffer_pos * 2); 137 //printf("Target: %d, YM bufferpos: %d, PSG bufferpos: %d\n", target, gen->ym->buffer_pos, gen->psg->buffer_pos * 2);
138 } 138 }
139 139
140 uint32_t last_frame_num; 140 //TODO: move this inside the system context
141 static uint32_t last_frame_num;
141 142
142 //My refresh emulation isn't currently good enough and causes more problems than it solves 143 //My refresh emulation isn't currently good enough and causes more problems than it solves
143 #ifdef REFRESH_EMULATION 144 #ifdef REFRESH_EMULATION
144 #define REFRESH_INTERVAL 128 145 #define REFRESH_INTERVAL 128
145 #define REFRESH_DELAY 2 146 #define REFRESH_DELAY 2
235 last_sync_cycle = context->current_cycle; 236 last_sync_cycle = context->current_cycle;
236 #endif 237 #endif
237 return context; 238 return context;
238 } 239 }
239 240
240 m68k_context * vdp_port_write(uint32_t vdp_port, m68k_context * context, uint16_t value) 241 static m68k_context * vdp_port_write(uint32_t vdp_port, m68k_context * context, uint16_t value)
241 { 242 {
242 if (vdp_port & 0x2700E0) { 243 if (vdp_port & 0x2700E0) {
243 fatal_error("machine freeze due to write to address %X\n", 0xC00000 | vdp_port); 244 fatal_error("machine freeze due to write to address %X\n", 0xC00000 | vdp_port);
244 } 245 }
245 vdp_port &= 0x1F; 246 vdp_port &= 0x1F;
330 //TODO: Implement undocumented test register(s) 331 //TODO: Implement undocumented test register(s)
331 } 332 }
332 return context; 333 return context;
333 } 334 }
334 335
335 m68k_context * vdp_port_write_b(uint32_t vdp_port, m68k_context * context, uint8_t value) 336 static m68k_context * vdp_port_write_b(uint32_t vdp_port, m68k_context * context, uint8_t value)
336 { 337 {
337 return vdp_port_write(vdp_port, context, vdp_port < 0x10 ? value | value << 8 : ((vdp_port & 1) ? value : 0)); 338 return vdp_port_write(vdp_port, context, vdp_port < 0x10 ? value | value << 8 : ((vdp_port & 1) ? value : 0));
338 } 339 }
339 340
340 void * z80_vdp_port_write(uint32_t vdp_port, void * vcontext, uint8_t value) 341 static void * z80_vdp_port_write(uint32_t vdp_port, void * vcontext, uint8_t value)
341 { 342 {
342 z80_context * context = vcontext; 343 z80_context * context = vcontext;
343 genesis_context * gen = context->system; 344 genesis_context * gen = context->system;
344 vdp_port &= 0xFF; 345 vdp_port &= 0xFF;
345 if (vdp_port & 0xE0) { 346 if (vdp_port & 0xE0) {
362 vdp_test_port_write(gen->vdp, value); 363 vdp_test_port_write(gen->vdp, value);
363 } 364 }
364 return context; 365 return context;
365 } 366 }
366 367
367 uint16_t vdp_port_read(uint32_t vdp_port, m68k_context * context) 368 static uint16_t vdp_port_read(uint32_t vdp_port, m68k_context * context)
368 { 369 {
369 if (vdp_port & 0x2700E0) { 370 if (vdp_port & 0x2700E0) {
370 fatal_error("machine freeze due to read from address %X\n", 0xC00000 | vdp_port); 371 fatal_error("machine freeze due to read from address %X\n", 0xC00000 | vdp_port);
371 } 372 }
372 vdp_port &= 0x1F; 373 vdp_port &= 0x1F;
402 gen->bus_busy = 0; 403 gen->bus_busy = 0;
403 } 404 }
404 return value; 405 return value;
405 } 406 }
406 407
407 uint8_t vdp_port_read_b(uint32_t vdp_port, m68k_context * context) 408 static uint8_t vdp_port_read_b(uint32_t vdp_port, m68k_context * context)
408 { 409 {
409 uint16_t value = vdp_port_read(vdp_port, context); 410 uint16_t value = vdp_port_read(vdp_port, context);
410 if (vdp_port & 1) { 411 if (vdp_port & 1) {
411 return value; 412 return value;
412 } else { 413 } else {
413 return value >> 8; 414 return value >> 8;
414 } 415 }
415 } 416 }
416 417
417 uint8_t z80_vdp_port_read(uint32_t vdp_port, void * vcontext) 418 static uint8_t z80_vdp_port_read(uint32_t vdp_port, void * vcontext)
418 { 419 {
419 z80_context * context = vcontext; 420 z80_context * context = vcontext;
420 if (vdp_port & 0xE0) { 421 if (vdp_port & 0xE0) {
421 fatal_error("machine freeze due to read from Z80 address %X\n", 0x7F00 | vdp_port); 422 fatal_error("machine freeze due to read from Z80 address %X\n", 0x7F00 | vdp_port);
422 } 423 }
447 ret = 0xFFFF; 448 ret = 0xFFFF;
448 } 449 }
449 return vdp_port & 1 ? ret : ret >> 8; 450 return vdp_port & 1 ? ret : ret >> 8;
450 } 451 }
451 452
452 uint32_t zram_counter = 0; 453 //TODO: Move this inside the system context
453 454 static uint32_t zram_counter = 0;
454 m68k_context * io_write(uint32_t location, m68k_context * context, uint8_t value) 455
456 static m68k_context * io_write(uint32_t location, m68k_context * context, uint8_t value)
455 { 457 {
456 genesis_context * gen = context->system; 458 genesis_context * gen = context->system;
457 if (location < 0x10000) { 459 if (location < 0x10000) {
458 //Access to Z80 memory incurs a one 68K cycle wait state 460 //Access to Z80 memory incurs a one 68K cycle wait state
459 context->current_cycle += MCLKS_PER_68K; 461 context->current_cycle += MCLKS_PER_68K;
553 } 555 }
554 } 556 }
555 return context; 557 return context;
556 } 558 }
557 559
558 m68k_context * io_write_w(uint32_t location, m68k_context * context, uint16_t value) 560 static m68k_context * io_write_w(uint32_t location, m68k_context * context, uint16_t value)
559 { 561 {
560 if (location < 0x10000 || (location & 0x1FFF) >= 0x100) { 562 if (location < 0x10000 || (location & 0x1FFF) >= 0x100) {
561 return io_write(location, context, value >> 8); 563 return io_write(location, context, value >> 8);
562 } else { 564 } else {
563 return io_write(location, context, value); 565 return io_write(location, context, value);
569 #define USA FOREIGN 571 #define USA FOREIGN
570 #define JAP 0x00 572 #define JAP 0x00
571 #define EUR (HZ50|FOREIGN) 573 #define EUR (HZ50|FOREIGN)
572 #define NO_DISK 0x20 574 #define NO_DISK 0x20
573 575
574 uint8_t io_read(uint32_t location, m68k_context * context) 576 static uint8_t io_read(uint32_t location, m68k_context * context)
575 { 577 {
576 uint8_t value; 578 uint8_t value;
577 genesis_context *gen = context->system; 579 genesis_context *gen = context->system;
578 if (location < 0x10000) { 580 if (location < 0x10000) {
579 //Access to Z80 memory incurs a one 68K cycle wait state 581 //Access to Z80 memory incurs a one 68K cycle wait state
635 } 637 }
636 } 638 }
637 return value; 639 return value;
638 } 640 }
639 641
640 uint16_t io_read_w(uint32_t location, m68k_context * context) 642 static uint16_t io_read_w(uint32_t location, m68k_context * context)
641 { 643 {
642 uint16_t value = io_read(location, context); 644 uint16_t value = io_read(location, context);
643 if (location < 0x10000 || (location & 0x1FFF) < 0x100) { 645 if (location < 0x10000 || (location & 0x1FFF) < 0x100) {
644 value = value | (value << 8); 646 value = value | (value << 8);
645 } else { 647 } else {
647 value |= get_open_bus_value() & 0xFF; 649 value |= get_open_bus_value() & 0xFF;
648 } 650 }
649 return value; 651 return value;
650 } 652 }
651 653
652 void * z80_write_ym(uint32_t location, void * vcontext, uint8_t value) 654 static void * z80_write_ym(uint32_t location, void * vcontext, uint8_t value)
653 { 655 {
654 z80_context * context = vcontext; 656 z80_context * context = vcontext;
655 genesis_context * gen = context->system; 657 genesis_context * gen = context->system;
656 sync_sound(gen, context->current_cycle); 658 sync_sound(gen, context->current_cycle);
657 if (location & 1) { 659 if (location & 1) {
662 ym_address_write_part1(gen->ym, value); 664 ym_address_write_part1(gen->ym, value);
663 } 665 }
664 return context; 666 return context;
665 } 667 }
666 668
667 uint8_t z80_read_ym(uint32_t location, void * vcontext) 669 static uint8_t z80_read_ym(uint32_t location, void * vcontext)
668 { 670 {
669 z80_context * context = vcontext; 671 z80_context * context = vcontext;
670 genesis_context * gen = context->system; 672 genesis_context * gen = context->system;
671 sync_sound(gen, context->current_cycle); 673 sync_sound(gen, context->current_cycle);
672 return ym_read_status(gen->ym); 674 return ym_read_status(gen->ym);
673 } 675 }
674 676
675 uint8_t z80_read_bank(uint32_t location, void * vcontext) 677 static uint8_t z80_read_bank(uint32_t location, void * vcontext)
676 { 678 {
677 z80_context * context = vcontext; 679 z80_context * context = vcontext;
678 genesis_context *gen = context->system; 680 genesis_context *gen = context->system;
679 if (gen->bus_busy) { 681 if (gen->bus_busy) {
680 context->current_cycle = context->sync_cycle; 682 context->current_cycle = context->sync_cycle;
697 fprintf(stderr, "Unhandled read by Z80 from address %X through banked memory area (%X)\n", address, context->bank_reg << 15); 699 fprintf(stderr, "Unhandled read by Z80 from address %X through banked memory area (%X)\n", address, context->bank_reg << 15);
698 } 700 }
699 return 0; 701 return 0;
700 } 702 }
701 703
702 void *z80_write_bank(uint32_t location, void * vcontext, uint8_t value) 704 static void *z80_write_bank(uint32_t location, void * vcontext, uint8_t value)
703 { 705 {
704 z80_context * context = vcontext; 706 z80_context * context = vcontext;
705 genesis_context *gen = context->system; 707 genesis_context *gen = context->system;
706 if (gen->bus_busy) { 708 if (gen->bus_busy) {
707 context->current_cycle = context->sync_cycle; 709 context->current_cycle = context->sync_cycle;
724 fprintf(stderr, "Unhandled write by Z80 to address %X through banked memory area\n", address); 726 fprintf(stderr, "Unhandled write by Z80 to address %X through banked memory area\n", address);
725 } 727 }
726 return context; 728 return context;
727 } 729 }
728 730
729 void *z80_write_bank_reg(uint32_t location, void * vcontext, uint8_t value) 731 static void *z80_write_bank_reg(uint32_t location, void * vcontext, uint8_t value)
730 { 732 {
731 z80_context * context = vcontext; 733 z80_context * context = vcontext;
732 734
733 context->bank_reg = (context->bank_reg >> 1 | value << 8) & 0x1FF; 735 context->bank_reg = (context->bank_reg >> 1 | value << 8) & 0x1FF;
734 if (context->bank_reg < 0x100) { 736 if (context->bank_reg < 0x100) {
746 genesis_context *context = (genesis_context *)system; 748 genesis_context *context = (genesis_context *)system;
747 uint32_t old_clock = context->master_clock; 749 uint32_t old_clock = context->master_clock;
748 context->master_clock = ((uint64_t)context->normal_clock * (uint64_t)percent) / 100; 750 context->master_clock = ((uint64_t)context->normal_clock * (uint64_t)percent) / 100;
749 while (context->ym->current_cycle != context->psg->cycles) { 751 while (context->ym->current_cycle != context->psg->cycles) {
750 sync_sound(context, context->psg->cycles + MCLKS_PER_PSG); 752 sync_sound(context, context->psg->cycles + MCLKS_PER_PSG);
751 } 753 }
752 ym_adjust_master_clock(context->ym, context->master_clock); 754 ym_adjust_master_clock(context->ym, context->master_clock);
753 psg_adjust_master_clock(context->psg, context->master_clock); 755 psg_adjust_master_clock(context->psg, context->master_clock);
754 } 756 }
755 757
756 void set_region(genesis_context *gen, rom_info *info, uint8_t region) 758 void set_region(genesis_context *gen, rom_info *info, uint8_t region)
868 static void free_genesis(system_header *system) 870 static void free_genesis(system_header *system)
869 { 871 {
870 genesis_context *gen = (genesis_context *)system; 872 genesis_context *gen = (genesis_context *)system;
871 vdp_free(gen->vdp); 873 vdp_free(gen->vdp);
872 m68k_options_free(gen->m68k->options); 874 m68k_options_free(gen->m68k->options);
875 free(gen->cart);
873 free(gen->m68k); 876 free(gen->m68k);
874 free(gen->work_ram); 877 free(gen->work_ram);
875 z80_options_free(gen->z80->options); 878 z80_options_free(gen->z80->options);
876 free(gen->z80); 879 free(gen->z80);
877 free(gen->zram); 880 free(gen->zram);
878 ym_free(gen->ym); 881 ym_free(gen->ym);
879 psg_free(gen->psg); 882 psg_free(gen->psg);
880 free(gen->save_storage); 883 free(gen->save_storage);
881 free(gen->header.save_dir); 884 free(gen->header.save_dir);
882 free(gen->lock_on); 885 free(gen->lock_on);
886 free(gen);
883 } 887 }
884 888
885 genesis_context *alloc_init_genesis(rom_info *rom, void *main_rom, void *lock_on, uint32_t system_opts, uint8_t force_region) 889 genesis_context *alloc_init_genesis(rom_info *rom, void *main_rom, void *lock_on, uint32_t system_opts, uint8_t force_region)
886 { 890 {
887 static memmap_chunk z80_map[] = { 891 static memmap_chunk z80_map[] = {
921 gen->z80 = calloc(1, sizeof(z80_context)); 925 gen->z80 = calloc(1, sizeof(z80_context));
922 gen->zram = calloc(1, Z80_RAM_BYTES); 926 gen->zram = calloc(1, Z80_RAM_BYTES);
923 z80_map[0].buffer = gen->zram = calloc(1, Z80_RAM_BYTES); 927 z80_map[0].buffer = gen->zram = calloc(1, Z80_RAM_BYTES);
924 #ifndef NO_Z80 928 #ifndef NO_Z80
925 z80_options *z_opts = malloc(sizeof(z80_options)); 929 z80_options *z_opts = malloc(sizeof(z80_options));
926 init_z80_opts(z_opts, z80_map, 5, NULL, 0, MCLKS_PER_Z80); 930 init_z80_opts(z_opts, z80_map, 5, NULL, 0, MCLKS_PER_Z80, 0xFFFF);
927 init_z80_context(gen->z80, z_opts); 931 init_z80_context(gen->z80, z_opts);
928 z80_assert_reset(gen->z80, 0); 932 z80_assert_reset(gen->z80, 0);
929 #endif 933 #endif
930 934
931 gen->z80->system = gen; 935 gen->z80->system = gen;
933 gen->z80->mem_pointers[1] = gen->z80->mem_pointers[2] = (uint8_t *)main_rom; 937 gen->z80->mem_pointers[1] = gen->z80->mem_pointers[2] = (uint8_t *)main_rom;
934 938
935 gen->cart = main_rom; 939 gen->cart = main_rom;
936 gen->lock_on = lock_on; 940 gen->lock_on = lock_on;
937 gen->work_ram = calloc(2, RAM_WORDS); 941 gen->work_ram = calloc(2, RAM_WORDS);
938 setup_io_devices(config, rom, gen); 942 setup_io_devices(config, rom, &gen->io);
939 943
940 gen->save_type = rom->save_type; 944 gen->save_type = rom->save_type;
941 gen->save_type = rom->save_type; 945 gen->save_type = rom->save_type;
942 if (gen->save_type != SAVE_NONE) { 946 if (gen->save_type != SAVE_NONE) {
943 gen->save_ram_mask = rom->save_mask; 947 gen->save_ram_mask = rom->save_mask;