comparison blastem.c @ 668:5439ae7946ca

Made the Z80 core more contained by refactoring some code in blastem.c into z80_to_x86.c
author Michael Pavone <pavone@retrodev.com>
date Sat, 03 Jan 2015 18:23:04 -0800
parents 30ccf56842d6
children 7a9a7c96cb22
comparison
equal deleted inserted replaced
667:30ccf56842d6 668:5439ae7946ca
153 } 153 }
154 154
155 int break_on_sync = 0; 155 int break_on_sync = 0;
156 int save_state = 0; 156 int save_state = 0;
157 157
158 uint8_t reset = 1;
159 uint8_t need_reset = 0;
160 uint8_t busreq = 0;
161 uint8_t busack = 0;
162 uint32_t busack_cycle = CYCLE_NEVER;
163 uint8_t new_busack = 0;
164 //#define DO_DEBUG_PRINT 158 //#define DO_DEBUG_PRINT
165 #ifdef DO_DEBUG_PRINT 159 #ifdef DO_DEBUG_PRINT
166 #define dprintf printf 160 #define dprintf printf
167 #define dputs puts 161 #define dputs puts
168 #else 162 #else
170 #define dputs 164 #define dputs
171 #endif 165 #endif
172 166
173 #define Z80_VINT_DURATION 128 167 #define Z80_VINT_DURATION 128
174 168
169 void z80_next_int_pulse(z80_context * z_context)
170 {
171 genesis_context * gen = z_context->system;
172 z_context->int_pulse_start = vdp_next_vint_z80(gen->vdp);
173 z_context->int_pulse_end = z_context->int_pulse_start + Z80_VINT_DURATION;
174 }
175
175 void sync_z80(z80_context * z_context, uint32_t mclks) 176 void sync_z80(z80_context * z_context, uint32_t mclks)
176 { 177 {
177 #ifndef NO_Z80 178 #ifndef NO_Z80
178 if (z80_enabled && !reset && !busreq) { 179 if (z80_enabled) {
179 genesis_context * gen = z_context->system; 180 z80_run(z_context, mclks);
180 z_context->sync_cycle = mclks;
181 if (z_context->current_cycle < z_context->sync_cycle) {
182 if (need_reset) {
183 z80_reset(z_context);
184 need_reset = 0;
185 }
186
187 while (z_context->current_cycle < z_context->sync_cycle) {
188 if (z_context->int_pulse_end < z_context->current_cycle || z_context->int_pulse_end == CYCLE_NEVER) {
189 z_context->int_pulse_start = vdp_next_vint_z80(gen->vdp);
190 z_context->int_pulse_end = z_context->int_pulse_start + Z80_VINT_DURATION;
191 }
192 if (z_context->iff1) {
193 z_context->int_cycle = z_context->int_pulse_start < z_context->int_enable_cycle ? z_context->int_enable_cycle : z_context->int_pulse_start;
194 } else {
195 z_context->int_cycle = CYCLE_NEVER;
196 }
197 z_context->target_cycle = z_context->sync_cycle < z_context->int_cycle ? z_context->sync_cycle : z_context->int_cycle;
198 dprintf("Running Z80 from cycle %d to cycle %d. Int cycle: %d\n", z_context->current_cycle, z_context->sync_cycle, z_context->int_cycle);
199 z_context->run(z_context);
200 dprintf("Z80 ran to cycle %d\n", z_context->current_cycle);
201 }
202 }
203 } else 181 } else
204 #endif 182 #endif
205 { 183 {
206 z_context->current_cycle = mclks; 184 z_context->current_cycle = mclks;
207 } 185 }
254 mclks -= mclk_target; 232 mclks -= mclk_target;
255 vdp_adjust_cycles(v_context, mclk_target); 233 vdp_adjust_cycles(v_context, mclk_target);
256 io_adjust_cycles(gen->ports, context->current_cycle, mclk_target); 234 io_adjust_cycles(gen->ports, context->current_cycle, mclk_target);
257 io_adjust_cycles(gen->ports+1, context->current_cycle, mclk_target); 235 io_adjust_cycles(gen->ports+1, context->current_cycle, mclk_target);
258 io_adjust_cycles(gen->ports+2, context->current_cycle, mclk_target); 236 io_adjust_cycles(gen->ports+2, context->current_cycle, mclk_target);
259 if (busack_cycle != CYCLE_NEVER) {
260 if (busack_cycle > mclk_target) {
261 busack_cycle -= mclk_target;
262 } else {
263 busack_cycle = CYCLE_NEVER;
264 busack = new_busack;
265 }
266 }
267 context->current_cycle -= mclk_target; 237 context->current_cycle -= mclk_target;
268 if (z_context->current_cycle >= mclk_target) { 238 z80_adjust_cycles(z_context, mclk_target);
269 z_context->current_cycle -= mclk_target;
270 } else {
271 z_context->current_cycle = 0;
272 }
273 if (z_context->int_cycle != CYCLE_NEVER) {
274 if (z_context->int_cycle >= mclk_target) {
275 z_context->int_cycle -= mclk_target;
276 } else {
277 z_context->int_cycle = 0;
278 }
279 }
280 if (z_context->int_pulse_start != CYCLE_NEVER) {
281 if (z_context->int_pulse_end >= mclk_target) {
282 z_context->int_pulse_end -= mclk_target;
283 if (z_context->int_pulse_start >= mclk_target) {
284 z_context->int_pulse_start -= mclk_target;
285 } else {
286 z_context->int_pulse_start = 0;
287 }
288 }
289 } else {
290 z_context->int_pulse_start = CYCLE_NEVER;
291 z_context->int_pulse_end = CYCLE_NEVER;
292 }
293 if (z_context->int_enable_cycle >= mclk_target) {
294 z_context->int_enable_cycle -= mclk_target;
295 } else {
296 z_context->int_enable_cycle = 0;
297 }
298 if (mclks) { 239 if (mclks) {
299 vdp_run_context(v_context, mclks); 240 vdp_run_context(v_context, mclks);
300 } 241 }
301 mclk_target = vdp_cycles_to_frame_end(v_context); 242 mclk_target = vdp_cycles_to_frame_end(v_context);
302 context->sync_cycle = mclk_target; 243 context->sync_cycle = mclk_target;
456 value = vdp_control_port_read(v_context); 397 value = vdp_control_port_read(v_context);
457 } else { 398 } else {
458 value = vdp_hv_counter_read(v_context); 399 value = vdp_hv_counter_read(v_context);
459 //printf("HV Counter: %X at cycle %d\n", value, v_context->cycles); 400 //printf("HV Counter: %X at cycle %d\n", value, v_context->cycles);
460 } 401 }
461 } else if (vdp_port < 0x18){ 402 } else if (vdp_port < 0x18) {
462 printf("Illegal read from PSG port %X\n", vdp_port); 403 printf("Illegal read from PSG port %X\n", vdp_port);
463 exit(1); 404 exit(1);
464 } else { 405 } else {
465 value = vdp_test_port_read(v_context); 406 value = vdp_test_port_read(v_context);
466 } 407 }
518 459
519 m68k_context * io_write(uint32_t location, m68k_context * context, uint8_t value) 460 m68k_context * io_write(uint32_t location, m68k_context * context, uint8_t value)
520 { 461 {
521 genesis_context * gen = context->system; 462 genesis_context * gen = context->system;
522 if (location < 0x10000) { 463 if (location < 0x10000) {
523 if (busack_cycle <= context->current_cycle) { 464 if (!z80_enabled || z80_get_busack(gen->z80, context->current_cycle)) {
524 busack = new_busack;
525 busack_cycle = CYCLE_NEVER;
526 }
527 if (!(busack || reset)) {
528 location &= 0x7FFF; 465 location &= 0x7FFF;
529 if (location < 0x4000) { 466 if (location < 0x4000) {
530 z80_ram[location & 0x1FFF] = value; 467 z80_ram[location & 0x1FFF] = value;
531 #ifndef NO_Z80 468 #ifndef NO_Z80
532 z80_handle_code_write(location & 0x1FFF, gen->z80); 469 z80_handle_code_write(location & 0x1FFF, gen->z80);
576 gen->ports[2].control = value; 513 gen->ports[2].control = value;
577 break; 514 break;
578 } 515 }
579 } else { 516 } else {
580 if (location == 0x1100) { 517 if (location == 0x1100) {
581 if (busack_cycle <= context->current_cycle) {
582 busack = new_busack;
583 busack_cycle = CYCLE_NEVER;
584 }
585 if (value & 1) { 518 if (value & 1) {
586 dputs("bus requesting Z80"); 519 dputs("bus requesting Z80");
587 520 if (z80_enabled) {
588 if(!reset && !busreq) { 521 z80_assert_busreq(gen->z80, context->current_cycle);
589 sync_z80(gen->z80, context->current_cycle + Z80_ACK_DELAY*MCLKS_PER_Z80);
590 busack_cycle = gen->z80->current_cycle;//context->current_cycle + Z80_ACK_DELAY;
591 new_busack = Z80_REQ_ACK;
592 } 522 }
593 busreq = 1;
594 } else { 523 } else {
595 sync_z80(gen->z80, context->current_cycle); 524 if (gen->z80->busreq) {
596 if (busreq) {
597 dputs("releasing z80 bus"); 525 dputs("releasing z80 bus");
598 #ifdef DO_DEBUG_PRINT 526 #ifdef DO_DEBUG_PRINT
599 char fname[20]; 527 char fname[20];
600 sprintf(fname, "zram-%d", zram_counter++); 528 sprintf(fname, "zram-%d", zram_counter++);
601 FILE * f = fopen(fname, "wb"); 529 FILE * f = fopen(fname, "wb");
602 fwrite(z80_ram, 1, sizeof(z80_ram), f); 530 fwrite(z80_ram, 1, sizeof(z80_ram), f);
603 fclose(f); 531 fclose(f);
604 #endif 532 #endif
605 busack_cycle = gen->z80->current_cycle + Z80_BUSY_DELAY;
606 new_busack = Z80_REQ_BUSY;
607 busreq = 0;
608 } 533 }
609 //busack_cycle = CYCLE_NEVER; 534 if (z80_enabled) {
610 //busack = Z80_REQ_BUSY; 535 z80_clear_busreq(gen->z80, context->current_cycle);
611 536 }
612 } 537 }
613 } else if (location == 0x1200) { 538 } else if (location == 0x1200) {
614 sync_z80(gen->z80, context->current_cycle); 539 sync_z80(gen->z80, context->current_cycle);
615 if (value & 1) { 540 if (value & 1) {
616 if (reset && busreq) { 541 if (z80_enabled) {
617 new_busack = 0; 542 z80_clear_reset(gen->z80, context->current_cycle);
618 busack_cycle = gen->z80->current_cycle + Z80_ACK_DELAY;//context->current_cycle + Z80_ACK_DELAY; 543 } else {
544 gen->z80->reset = 0;
619 } 545 }
620 //TODO: Deal with the scenario in which reset is not asserted long enough 546 } else {
621 if (reset) { 547 if (z80_enabled) {
622 need_reset = 1; 548 z80_assert_reset(gen->z80, context->current_cycle);
623 //TODO: Add necessary delay between release of reset and start of execution 549 } else {
624 gen->z80->current_cycle = context->current_cycle + 16 * MCLKS_PER_Z80; 550 gen->z80->reset = 1;
625 } 551 }
626 reset = 0;
627 } else {
628 reset = 1;
629 } 552 }
630 } 553 }
631 } 554 }
632 } 555 }
633 return context; 556 return context;
651 uint8_t io_read(uint32_t location, m68k_context * context) 574 uint8_t io_read(uint32_t location, m68k_context * context)
652 { 575 {
653 uint8_t value; 576 uint8_t value;
654 genesis_context *gen = context->system; 577 genesis_context *gen = context->system;
655 if (location < 0x10000) { 578 if (location < 0x10000) {
656 if (busack_cycle <= context->current_cycle) { 579 if (!z80_enabled || z80_get_busack(gen->z80, context->current_cycle)) {
657 busack = new_busack;
658 busack_cycle = CYCLE_NEVER;
659 }
660 if (!(busack==Z80_REQ_BUSY || reset)) {
661 location &= 0x7FFF; 580 location &= 0x7FFF;
662 if (location < 0x4000) { 581 if (location < 0x4000) {
663 value = z80_ram[location & 0x1FFF]; 582 value = z80_ram[location & 0x1FFF];
664 } else if (location < 0x6000) { 583 } else if (location < 0x6000) {
665 sync_sound(gen, context->current_cycle); 584 sync_sound(gen, context->current_cycle);
700 default: 619 default:
701 value = 0xFF; 620 value = 0xFF;
702 } 621 }
703 } else { 622 } else {
704 if (location == 0x1100) { 623 if (location == 0x1100) {
705 if (busack_cycle <= context->current_cycle) { 624 value = z80_enabled ? !z80_get_busack(gen->z80, context->current_cycle) : 0;
706 busack = new_busack; 625 dprintf("Byte read of BUSREQ returned %d @ %d (reset: %d)\n", value, context->current_cycle, gen->z80->reset);
707 busack_cycle = CYCLE_NEVER;
708 }
709 value = Z80_RES_BUSACK || busack;
710 dprintf("Byte read of BUSREQ returned %d @ %d (reset: %d, busack: %d, busack_cycle %d)\n", value, context->current_cycle, reset, busack, busack_cycle);
711 } else if (location == 0x1200) { 626 } else if (location == 0x1200) {
712 value = !reset; 627 value = !gen->z80->reset;
713 } else { 628 } else {
714 value = 0xFF; 629 value = 0xFF;
715 printf("Byte read of unknown IO location: %X\n", location); 630 printf("Byte read of unknown IO location: %X\n", location);
716 } 631 }
717 } 632 }
1103 printf("Loaded %s\n", statefile); 1018 printf("Loaded %s\n", statefile);
1104 if (debugger) { 1019 if (debugger) {
1105 insert_breakpoint(&context, pc, debugger); 1020 insert_breakpoint(&context, pc, debugger);
1106 } 1021 }
1107 adjust_int_cycle(gen->m68k, gen->vdp); 1022 adjust_int_cycle(gen->m68k, gen->vdp);
1108 #ifndef NO_Z80
1109 gen->z80->native_pc = z80_get_native_address_trans(gen->z80, gen->z80->pc);
1110 #endif
1111 start_68k_context(&context, pc); 1023 start_68k_context(&context, pc);
1112 } else { 1024 } else {
1113 if (debugger) { 1025 if (debugger) {
1114 insert_breakpoint(&context, address, debugger); 1026 insert_breakpoint(&context, address, debugger);
1115 } 1027 }
1362 z80_context z_context; 1274 z80_context z_context;
1363 #ifndef NO_Z80 1275 #ifndef NO_Z80
1364 z80_options z_opts; 1276 z80_options z_opts;
1365 init_z80_opts(&z_opts, z80_map, 5, MCLKS_PER_Z80); 1277 init_z80_opts(&z_opts, z80_map, 5, MCLKS_PER_Z80);
1366 init_z80_context(&z_context, &z_opts); 1278 init_z80_context(&z_context, &z_opts);
1279 z80_assert_reset(&z_context, 0);
1367 #endif 1280 #endif
1368 1281
1369 z_context.system = &gen; 1282 z_context.system = &gen;
1370 z_context.mem_pointers[0] = z80_ram; 1283 z_context.mem_pointers[0] = z80_ram;
1371 z_context.sync_cycle = z_context.target_cycle = mclk_target; 1284 z_context.sync_cycle = z_context.target_cycle = mclk_target;