comparison blastem.c @ 263:2989ed7b8608

Add a second context pointer to m68k_context so that try_fifo_write can still have easy access to the VDP. Handle writes to Z80 code addresses from the 68K.
author Mike Pavone <pavone@retrodev.com>
date Tue, 30 Apr 2013 20:36:15 -0700
parents 625f8e4d5fd2
children 8fd6652e56f8
comparison
equal deleted inserted replaced
262:d97c9eca49f4 263:2989ed7b8608
134 uint8_t new_busack = 0; 134 uint8_t new_busack = 0;
135 135
136 m68k_context * sync_components(m68k_context * context, uint32_t address) 136 m68k_context * sync_components(m68k_context * context, uint32_t address)
137 { 137 {
138 //TODO: Handle sync targets smaller than a single frame 138 //TODO: Handle sync targets smaller than a single frame
139 z80_context * z_context = context->next_context; 139 z80_context * z_context = context->next_cpu;
140 vdp_context * v_context = z_context->next_context; 140 vdp_context * v_context = context->video_context;
141 uint32_t mclks = context->current_cycle * MCLKS_PER_68K; 141 uint32_t mclks = context->current_cycle * MCLKS_PER_68K;
142 if (!reset && !busreq) { 142 if (!reset && !busreq) {
143 if (need_reset) { 143 if (need_reset) {
144 z80_reset(z_context); 144 z80_reset(z_context);
145 need_reset = 0; 145 need_reset = 0;
148 while (z_context->current_cycle < z_context->sync_cycle) { 148 while (z_context->current_cycle < z_context->sync_cycle) {
149 if (z_context->iff1 && z_context->current_cycle < ZVINT_CYCLE) { 149 if (z_context->iff1 && z_context->current_cycle < ZVINT_CYCLE) {
150 z_context->int_cycle = ZVINT_CYCLE; 150 z_context->int_cycle = ZVINT_CYCLE;
151 } 151 }
152 z_context->target_cycle = z_context->sync_cycle < z_context->int_cycle ? z_context->sync_cycle : z_context->int_cycle; 152 z_context->target_cycle = z_context->sync_cycle < z_context->int_cycle ? z_context->sync_cycle : z_context->int_cycle;
153 printf("Running Z80 from cycle %d to cycle %d\n", z_context->current_cycle, z_context->sync_cycle);
154 printf("HL: %X, Native PC: %p\n", (z_context->regs[Z80_H] << 8) | z_context->regs[Z80_L], z_context->native_pc);
153 z80_run(z_context); 155 z80_run(z_context);
156 printf("Z80 returned at cycle %d\n", z_context->current_cycle);
154 } 157 }
155 } 158 }
156 if (mclks >= MCLKS_PER_FRAME) { 159 if (mclks >= MCLKS_PER_FRAME) {
157 //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks); 160 //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks);
158 vdp_run_context(v_context, MCLKS_PER_FRAME); 161 vdp_run_context(v_context, MCLKS_PER_FRAME);
186 189
187 m68k_context * vdp_port_write(uint32_t vdp_port, m68k_context * context, uint16_t value) 190 m68k_context * vdp_port_write(uint32_t vdp_port, m68k_context * context, uint16_t value)
188 { 191 {
189 //printf("vdp_port write: %X, value: %X, cycle: %d\n", vdp_port, value, context->current_cycle); 192 //printf("vdp_port write: %X, value: %X, cycle: %d\n", vdp_port, value, context->current_cycle);
190 sync_components(context, 0); 193 sync_components(context, 0);
191 z80_context * z_context = context->next_context; 194 vdp_context * v_context = context->video_context;
192 vdp_context * v_context = z_context->next_context;
193 if (vdp_port < 0x10) { 195 if (vdp_port < 0x10) {
194 int blocked; 196 int blocked;
195 if (vdp_port < 4) { 197 if (vdp_port < 4) {
196 while (vdp_data_port_write(v_context, value) < 0) { 198 while (vdp_data_port_write(v_context, value) < 0) {
197 while(v_context->flags & FLAG_DMA_RUN) { 199 while(v_context->flags & FLAG_DMA_RUN) {
246 } 248 }
247 249
248 m68k_context * vdp_port_read(uint32_t vdp_port, m68k_context * context) 250 m68k_context * vdp_port_read(uint32_t vdp_port, m68k_context * context)
249 { 251 {
250 sync_components(context, 0); 252 sync_components(context, 0);
251 z80_context * z_context = context->next_context; 253 vdp_context * v_context = context->video_context;
252 vdp_context * v_context = z_context->next_context;
253 if (vdp_port < 0x10) { 254 if (vdp_port < 0x10) {
254 if (vdp_port < 4) { 255 if (vdp_port < 4) {
255 context->value = vdp_data_port_read(v_context); 256 context->value = vdp_data_port_read(v_context);
256 } else if(vdp_port < 8) { 257 } else if(vdp_port < 8) {
257 context->value = vdp_control_port_read(v_context); 258 context->value = vdp_control_port_read(v_context);
345 } 346 }
346 if (!(busack || reset)) { 347 if (!(busack || reset)) {
347 location &= 0x7FFF; 348 location &= 0x7FFF;
348 if (location < 0x4000) { 349 if (location < 0x4000) {
349 z80_ram[location & 0x1FFF] = value; 350 z80_ram[location & 0x1FFF] = value;
351 z80_handle_code_write(location & 0x1FFF, context->next_cpu);
350 } 352 }
351 } 353 }
352 } else { 354 } else {
353 location &= 0x1FFF; 355 location &= 0x1FFF;
354 if (location < 0x100) { 356 if (location < 0x100) {
381 busack_cycle = context->current_cycle + Z80_ACK_DELAY; 383 busack_cycle = context->current_cycle + Z80_ACK_DELAY;
382 new_busack = 0; 384 new_busack = 0;
383 } 385 }
384 } else { 386 } else {
385 if (busreq) { 387 if (busreq) {
386 z80_context * z_context = context->next_context; 388 z80_context * z_context = context->next_cpu;
387 //TODO: Add necessary delay between release of busreq and resumption of execution 389 //TODO: Add necessary delay between release of busreq and resumption of execution
388 z_context->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80; 390 z_context->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80;
389 } 391 }
390 busreq = 0; 392 busreq = 0;
391 busack_cycle = CYCLE_NEVER; 393 busack_cycle = CYCLE_NEVER;
397 new_busack = 0; 399 new_busack = 0;
398 busack_cycle = context->current_cycle + Z80_ACK_DELAY; 400 busack_cycle = context->current_cycle + Z80_ACK_DELAY;
399 } 401 }
400 //TODO: Deal with the scenario in which reset is not asserted long enough 402 //TODO: Deal with the scenario in which reset is not asserted long enough
401 if (reset) { 403 if (reset) {
402 z80_context * z_context = context->next_context; 404 z80_context * z_context = context->next_cpu;
403 need_reset = 1; 405 need_reset = 1;
404 //TODO: Add necessary delay between release of reset and start of execution 406 //TODO: Add necessary delay between release of reset and start of execution
405 z_context->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80; 407 z_context->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80;
406 } 408 }
407 reset = 0; 409 reset = 0;
423 } 425 }
424 if (!(busack || reset)) { 426 if (!(busack || reset)) {
425 location &= 0x7FFF; 427 location &= 0x7FFF;
426 if (location < 0x4000) { 428 if (location < 0x4000) {
427 z80_ram[location & 0x1FFE] = value >> 8; 429 z80_ram[location & 0x1FFE] = value >> 8;
430 z80_handle_code_write(location & 0x1FFE, context->next_cpu);
428 } 431 }
429 } 432 }
430 } else { 433 } else {
431 location &= 0x1FFF; 434 location &= 0x1FFF;
432 if (location < 0x100) { 435 if (location < 0x100) {
460 busack_cycle = context->current_cycle + Z80_ACK_DELAY; 463 busack_cycle = context->current_cycle + Z80_ACK_DELAY;
461 new_busack = 0; 464 new_busack = 0;
462 } 465 }
463 } else { 466 } else {
464 if (busreq) { 467 if (busreq) {
465 z80_context * z_context = context->next_context; 468 z80_context * z_context = context->next_cpu;
466 //TODO: Add necessary delay between release of busreq and resumption of execution 469 //TODO: Add necessary delay between release of busreq and resumption of execution
467 z_context->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80; 470 z_context->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80;
468 } 471 }
469 busreq = 0; 472 busreq = 0;
470 busack_cycle = CYCLE_NEVER; 473 busack_cycle = CYCLE_NEVER;
476 new_busack = 0; 479 new_busack = 0;
477 busack_cycle = context->current_cycle + Z80_ACK_DELAY; 480 busack_cycle = context->current_cycle + Z80_ACK_DELAY;
478 } 481 }
479 //TODO: Deal with the scenario in which reset is not asserted long enough 482 //TODO: Deal with the scenario in which reset is not asserted long enough
480 if (reset) { 483 if (reset) {
481 z80_context * z_context = context->next_context; 484 z80_context * z_context = context->next_cpu;
482 need_reset = 1; 485 need_reset = 1;
483 //TODO: Add necessary delay between release of reset and start of execution 486 //TODO: Add necessary delay between release of reset and start of execution
484 z_context->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80; 487 z_context->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80;
485 } 488 }
486 reset = 0; 489 reset = 0;
852 } 855 }
853 } 856 }
854 return context; 857 return context;
855 } 858 }
856 859
857 void init_run_cpu(z80_context * zcontext, int debug, FILE * address_log) 860 void init_run_cpu(vdp_context * vcontext, z80_context * zcontext, int debug, FILE * address_log)
858 { 861 {
859 m68k_context context; 862 m68k_context context;
860 x86_68k_options opts; 863 x86_68k_options opts;
861 init_x86_68k_opts(&opts); 864 init_x86_68k_opts(&opts);
862 opts.address_log = address_log; 865 opts.address_log = address_log;
863 init_68k_context(&context, opts.native_code_map, &opts); 866 init_68k_context(&context, opts.native_code_map, &opts);
864 867
865 context.next_context = zcontext; 868 context.video_context = vcontext;
869 context.next_cpu = zcontext;
866 //cartridge ROM 870 //cartridge ROM
867 context.mem_pointers[0] = cart; 871 context.mem_pointers[0] = cart;
868 context.target_cycle = context.sync_cycle = MCLKS_PER_FRAME/MCLKS_PER_68K; 872 context.target_cycle = context.sync_cycle = MCLKS_PER_FRAME/MCLKS_PER_68K;
869 //work RAM 873 //work RAM
870 context.mem_pointers[1] = ram; 874 context.mem_pointers[1] = ram;
936 z_context.mem_pointers[0] = z80_ram; 940 z_context.mem_pointers[0] = z80_ram;
937 z_context.sync_cycle = z_context.target_cycle = MCLKS_PER_FRAME/MCLKS_PER_Z80; 941 z_context.sync_cycle = z_context.target_cycle = MCLKS_PER_FRAME/MCLKS_PER_Z80;
938 z_context.int_cycle = CYCLE_NEVER; 942 z_context.int_cycle = CYCLE_NEVER;
939 z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart; 943 z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart;
940 944
941 init_run_cpu(&z_context, debug, address_log); 945 init_run_cpu(&v_context, &z_context, debug, address_log);
942 return 0; 946 return 0;
943 } 947 }