/* profile.c: Z80 profiler Copyright (c) 2005 Philip Kendall $Id: profile.c,v 1.6 2007/02/02 16:21:51 pak21 Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Author contact information: E-mail: Philip Kendall */ #include #include #include #include "event.h" #include "fuse.h" #include "ui/ui.h" #include "z80/z80.h" int profile_active = 0; static int total_tstates[ 0x10000 ]; static libspectrum_word profile_last_pc; static libspectrum_dword profile_last_tstates; void profile_start( void ) { memset( total_tstates, 0, sizeof( total_tstates ) ); profile_active = 1; profile_last_pc = z80.pc.w; profile_last_tstates = tstates; /* Schedule an event to ensure that the main z80 emulation loop recognises profiling is turned on; otherwise problems occur if we we started while the debugger was active (bug #1530345) */ event_add( tstates, EVENT_TYPE_NULL ); ui_menu_activate( UI_MENU_ITEM_MACHINE_PROFILER, 1 ); } void profile_map( libspectrum_word pc ) { if( tstates - profile_last_tstates > 256 ) fuse_abort(); total_tstates[ profile_last_pc ] += tstates - profile_last_tstates; profile_last_pc = z80.pc.w; profile_last_tstates = tstates; } void profile_frame( libspectrum_dword frame_length ) { profile_last_tstates -= frame_length; } void profile_finish( const char *filename ) { FILE *f; size_t i; f = fopen( filename, "wb" ); if( !f ) { ui_error( UI_ERROR_ERROR, "unable to open profile map '%s' for writing", filename ); return; } for( i = 0; i < 0x10000; i++ ) { if( !total_tstates[ i ] ) continue; fprintf( f, "0x%04x,%d\n", i, total_tstates[ i ] ); } profile_active = 0; /* Again, schedule an event to ensure this change is picked up by the main loop */ event_add( tstates, EVENT_TYPE_NULL ); ui_menu_activate( UI_MENU_ITEM_MACHINE_PROFILER, 0 ); }