inline void M68K_Exec(s32 cycles) { #ifdef CPU68K_USE_MUSASHI m68k_execute(cycles); #endif #ifdef CPU68K_USE_C68K C68k_Exec(&C68K, cycles); #endif }
void SekStepM68k(void) { SekCycleAim=SekCycleCnt+1; #if defined(EMU_CORE_DEBUG) SekCycleCnt+=CM_compareRun(1, 0); #elif defined(EMU_C68K) PicoCpuCM68k.cycles=1; CycloneRun(&PicoCpuCM68k); SekCycleCnt+=1-PicoCpuCM68k.cycles; #elif defined(EMU_M68K) SekCycleCnt+=m68k_execute(1); #elif defined(EMU_F68K) SekCycleCnt+=fm68k_emulate(1, 0); #endif }
/*------------------------------------------------------------------------- Run our virtual Neo Geo according to the run mode. ---------------------------------------------------------------------------*/ Uint32 neogeo_run ( void ) { Uint32 TimeSlice; Uint32 Elapsed; Uint32 Z80_Elapsed; Uint32 ReturnCode; ReturnCode = 0; switch ( neogeo_run_mode ) { case NEOGEO_RUN_QUIT: ReturnCode = 1; break; case NEOGEO_RUN_TRACE: Elapsed = m68k_execute ( 0 ); if ( !neogeo_z80_disable ) { neogeo_z80_time_to_execute += M68K_TO_REF ( Elapsed ); if ( neogeo_z80_time_to_execute > 0 ) { Z80_Elapsed = z80_execute ( REF_TO_Z80 ( neogeo_z80_time_to_execute ) ); neogeo_z80_time_to_execute -= Z80_TO_REF ( Z80_Elapsed ); neogeo_z80_time_this_vbl += Z80_TO_REF ( Z80_Elapsed ); } } neogeo_screen_position += M68K_TO_REF ( Elapsed ); timer_advance ( M68K_TO_REF ( Elapsed ) ); timer_call_events(); ReturnCode = 3; break; case NEOGEO_RUN_NORMAL: case NEOGEO_RUN_FULL_THROTTLE: while ( 1 ) { TimeSlice = REF_TO_M68K ( timer_request_timeslice() ); if ( neogeo_show_debugger ) { neogeo_show_debugger = 0; ReturnCode = 3; break; } Elapsed = m68k_execute ( TimeSlice ); if ( !neogeo_z80_disable ) { neogeo_z80_time_to_execute += M68K_TO_REF ( Elapsed ); if ( neogeo_z80_time_to_execute > 0 ) { Z80_Elapsed = z80_execute ( REF_TO_Z80 ( neogeo_z80_time_to_execute ) ); neogeo_z80_time_to_execute -= Z80_TO_REF ( Z80_Elapsed ); neogeo_z80_time_this_vbl += Z80_TO_REF ( Z80_Elapsed ); } } neogeo_screen_position += M68K_TO_REF ( Elapsed ); timer_advance ( M68K_TO_REF ( Elapsed ) ); if ( neogeo_show_debugger ) { neogeo_show_debugger = 0; ReturnCode = 3; } if ( neogeo_run_mode == NEOGEO_RUN_TRACE ) { timer_call_events(); ReturnCode = 2; } if ( neogeo_run_mode == NEOGEO_RUN_QUIT ) ReturnCode = 1; if ( ReturnCode ) break; } break; } return ReturnCode; }
/**************************************************************************** * neogeo_runframe * * This function will run a complete video frame for NeoCD. * CPU initialization etc is performed in neocd.c as usual. ****************************************************************************/ void neogeo_runframe (void) { int cycles; if (!inited) { memset (&CPU_Z80, 0, sizeof (CPU)); memset (&CPU_M68K, 0, sizeof (CPU)); CPU_Z80.total_cycles = 0.0; CPU_M68K.total_cycles = 0.0; inited = 1; } /*** Set CPU cycles for this frame ***/ CPU_Z80.cycles_frame = Z80FRAME + CPU_Z80.boost; CPU_M68K.cycles_frame = M68FRAME + CPU_M68K.boost; /*** Set CPU cycles for scanline ***/ CPU_Z80.cycles_scanline = ((CPU_Z80.cycles_frame) / TIMESLICE); CPU_M68K.cycles_scanline = (CPU_M68K.cycles_frame) / TIMESLICE; /*** Clear done cycles ***/ CPU_Z80.cycles_done = CPU_M68K.cycles_done = 0; for (scanline = TIMESLICE - 1; scanline >= 0; scanline--) { /*** Run M68K ***/ if (CPU_M68K.cycles_done < CPU_M68K.cycles_frame) { if (scanline) cycles = m68k_execute (CPU_M68K.cycles_scanline); else cycles = m68k_execute (CPU_M68K.cycles_frame - CPU_M68K.cycles_done); CPU_M68K.cycles_done += cycles; CPU_M68K.total_cycles += cycles; } /*** Run Z80 ***/ if ((CPU_Z80.cycles_done < CPU_Z80.cycles_frame) && ( cpu_enabled)) { if (scanline) cycles = mz80exec (CPU_Z80.cycles_scanline); else cycles = mz80exec (CPU_Z80.cycles_frame - CPU_Z80.cycles_done); CPU_Z80.cycles_done += cycles; CPU_Z80.total_cycles += cycles; my_timer (); } switch (raster_interrupt_enabled) { case 0: neogeo_interrupt (); break; case 1: neogeo_raster_interrupt (); break; case 2: neogeo_raster_interrupt_busy (); break; } } /*** Adjust processors ***/ CPU_Z80.total_time_us = (CPU_Z80.total_cycles * Z80_USEC); CPU_M68K.total_time_us = (CPU_M68K.total_cycles * M68K_USEC); CPU_Z80.boost = CPU_M68K.boost = 0; if (CPU_Z80.total_time_us > CPU_M68K.total_time_us) CPU_M68K.boost = (int) ((double) M68SEC * (CPU_Z80.total_time_us - CPU_M68K.total_time_us)); else CPU_Z80.boost = (int) ((double) Z80SEC * (CPU_M68K.total_time_us - CPU_Z80.total_time_us)); }
int m68000_execute(int cycles) { return m68k_execute(cycles); }
int main(int argc, char **argv) { int binary_file; void *binary_data; struct stat sb; struct tos_environment te; int argb = 1; verbose = 0; /* Program usage */ if (argc < 2) { printf("Usage: tosemu [-v] <binary> [<args>]\n\n\t<binary> name of binary to execute\n"); return -1; } /* Check if we want to be verbose */ if (argc >= 3 && strcmp("-v", argv[1]) == 0) { verbose = -1; argb++; } /* Open the provided file */ binary_file = open(argv[argb], O_RDONLY); if (binary_file == -1) { printf("Error: failed to open '%s'\n", argv[argc-1]); return -1; } /* Determine the file size */ fstat(binary_file, &sb); /* Mmap the file into memory */ binary_data = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, binary_file, 0); if (!binary_data) { printf("Error: failed to mmap '%s'\n", argv[argc-1]); close(binary_file); return -1; } /* Check that the binary starts with the magix 0x601a sequence */ if( ((char*)binary_data)[0] != 0x60 || ((char*)binary_data)[1] != 0x1a) { printf("Error: invalid magic in '%s'\n", argv[argc-1]); close(binary_file); return -1; } argb++; argv += argb; argc -= argb; /* Setup a TOS environment for the binary */ if (init_tos_environment(&te, binary_data, sb.st_size, argc, argv)) { printf("Error: failed to initialize TOS environment\n"); close(binary_file); return -1; } /* Close the binary file */ close(binary_file); /* Start execution */ /* TODO init cpu */ m68k_init(); m68k_set_cpu_type(M68K_CPU_TYPE_68000); m68k_pulse_reset(); /* TODO is this really correct, or should it be the MSP? If so, why does that not work? */ m68k_set_reg(M68K_REG_ISP, 0x600); /* supervisor stack pointer */ m68k_set_reg(M68K_REG_USP, te.size-4); /* user stack pointer */ m68k_write_memory_32(te.size, 0x800); /* big endian 0x800 */ m68k_set_reg(M68K_REG_PC, 0x900); /* Set PC to the binary entry point */ disable_supervisor_mode(); /* TODO exec */ while (keepongoing) { m68k_execute(1); } /* Clean up */ free_tos_environment(&te); return 0; }