Added GDB debugger stub.

This commit is contained in:
masscat 2007-06-07 10:00:52 +00:00
parent 35168b3e01
commit 9fb807fe7e
13 changed files with 648 additions and 78 deletions

View File

@ -160,6 +160,7 @@ AC_CONFIG_FILES([Makefile
src/gtk-glade/Makefile
src/gtk-glade/desmume-glade.desktop
src/windows/Makefile
src/gdbstub/Makefile
autopackage/default.apspec
debian/rules
debian/changelog

View File

@ -1,6 +1,6 @@
EXTRA_DIST = build.bat instruction_tabdef.inc thumb_tabdef.inc fs-linux.c fs-windows.c
DIST_SUBDIRS = . cli gtk gtk-glade windows
SUBDIRS = . $(UI_DIR)
DIST_SUBDIRS = . gdbstub cli gtk gtk-glade windows
SUBDIRS = . gdbstub $(UI_DIR)
noinst_LIBRARIES = libdesmume.a
libdesmume_a_SOURCES = \
armcpu.c armcpu.h ARM9.h \
@ -19,6 +19,7 @@ libdesmume_a_SOURCES = \
render3D.c render3D.h \
saves.c saves.h \
SPU.c SPU.h \
gdbstub.h \
matrix.c matrix.h \
opengl_collector_3Demu.c opengl_collector_3Demu.h \
thumb_instructions.c thumb_instructions.h types.h

View File

@ -1,4 +1,4 @@
bin_PROGRAMS = desmume-cli
desmume_cli_SOURCES = main.c ../sndsdl.c ../ctrlssdl.h ../ctrlssdl.c
desmume_cli_LDADD = ../libdesmume.a $(SDL_LIBS)
desmume_cli_LDADD = ../libdesmume.a ../gdbstub/libgdbstub.a $(SDL_LIBS)
desmume_cli_CFLAGS = $(SDL_CFLAGS)

View File

@ -19,6 +19,7 @@
* Boston, MA 02111-1307, USA.
*/
#include "SDL.h"
#include "SDL_thread.h"
#include <stdlib.h>
#include <string.h>
#include <libgen.h>
@ -46,6 +47,7 @@
#include "../sndsdl.h"
#include "../ctrlssdl.h"
#include "../render3D.h"
#include "../gdbstub.h"
volatile BOOL execute = FALSE;
@ -95,27 +97,35 @@ const u16 cli_kb_cfg[NB_KEYS] =
SDLK_o // BOOST
};
struct my_config {
u16 arm9_gdb_port;
u16 arm7_gdb_port;
int disable_sound;
#ifdef INCLUDE_OPENGL_2D
int opengl_2d;
int soft_colour_convert;
#endif
int disable_limiter;
const char *nds_file;
const char *cflash_disk_image_file;
};
static void
init_config( struct my_config *config) {
config->arm9_gdb_port = 0;
config->arm7_gdb_port = 0;
config->disable_sound = 0;
config->disable_limiter = 0;
config->nds_file = NULL;
config->cflash_disk_image_file = NULL;
#ifdef INCLUDE_OPENGL_2D
config->opengl_2d = 0;
config->soft_colour_convert = 0;
@ -135,12 +145,20 @@ fill_config( struct my_config *config,
printf( "USAGE: %s <nds-file>\n", argv[0]);
printf( "OPTIONS:\n");
printf( " --disable-sound Disables the sound emulation\n");
printf( " --disable-limiter Disables the 60 fps limiter\n");
#ifdef INCLUDE_OPENGL_2D
printf( " --opengl-2d Enables using OpenGL for screen rendering\n");
printf( " --soft-convert Use software colour conversion during OpenGL\n");
printf( " screen rendering. May produce better or worse\n");
printf( " frame rates depending on hardware.\n");
#endif
printf( "\n");
printf( " --arm9gdb=PORT_NUM Enable the ARM9 GDB stub on the given port\n");
printf( " --arm7gdb=PORT_NUM Enable the ARM7 GDB stub on the given port\n");
//printf( " --sticky Enable sticky keys and stylus\n");
printf( "\n");
printf( " --cflash=PATH_TO_DISK_IMAGE\n");
printf( " Enable disk image GBAMP compact flash emulation\n");
printf( "\n");
printf( " --help Display this message\n");
good_args = 0;
@ -156,6 +174,43 @@ fill_config( struct my_config *config,
config->soft_colour_convert = 1;
}
#endif
else if ( strcmp( argv[i], "--disable-limiter") == 0) {
config->disable_limiter = 1;
}
else if ( strncmp( argv[i], "--arm9gdb=", 10) == 0) {
char *end_char;
unsigned long port_num = strtoul( &argv[i][10], &end_char, 10);
if ( port_num > 0 && port_num < 65536) {
config->arm9_gdb_port = port_num;
}
else {
fprintf( stderr, "ARM9 GDB stub port must be in the range 1 to 65535\n");
good_args = 0;
}
}
else if ( strncmp( argv[i], "--arm7gdb=", 10) == 0) {
char *end_char;
unsigned long port_num = strtoul( &argv[i][10], &end_char, 10);
if ( port_num > 0 && port_num < 65536) {
config->arm7_gdb_port = port_num;
}
else {
fprintf( stderr, "ARM7 GDB stub port must be in the range 1 to 65535\n");
good_args = 0;
}
}
else if ( strncmp( argv[i], "--cflash=", 9) == 0) {
if ( config->cflash_disk_image_file == NULL) {
config->cflash_disk_image_file = &argv[i][9];
}
else {
fprintf( stderr, "CFlash disk image file (\"%s\") already set\n",
config->cflash_disk_image_file);
good_args = 0;
}
}
else {
if ( config->nds_file == NULL) {
config->nds_file = argv[i];
@ -182,6 +237,26 @@ fill_config( struct my_config *config,
}
/*
* The thread handling functions needed by the GDB stub code.
*/
void *
createThread_gdb( void (*thread_function)( void *data),
void *thread_data) {
SDL_Thread *new_thread = SDL_CreateThread( (int (*)(void *data))thread_function,
thread_data);
return new_thread;
}
void
joinThread_gdb( void *thread_handle) {
int ignore;
SDL_WaitThread( thread_handle, &ignore);
}
/**
* A SDL timer callback function. Signals the supplied SDL semaphore
* if its value is small.
@ -420,16 +495,25 @@ Draw( void) {
if(rawImage == NULL) return;
SDL_BlitSurface(rawImage, 0, surface, 0);
SDL_UpdateRect(surface, 0, 0, 0, 0);
SDL_FreeSurface(rawImage);
return;
}
int main(int argc, char ** argv) {
static unsigned short keypad = 0;
struct my_config my_config;
u32 last_cycle = 0;
gdbstub_handle_t arm9_gdb_stub;
gdbstub_handle_t arm7_gdb_stub;
struct armcpu_memory_iface *arm9_memio = &arm9_base_memory_iface;
struct armcpu_memory_iface *arm7_memio = &arm7_base_memory_iface;
struct armcpu_ctrl_iface *arm9_ctrl_iface;
struct armcpu_ctrl_iface *arm7_ctrl_iface;
int limiter_frame_counter = 0;
SDL_sem *fps_limiter_semaphore;
SDL_TimerID limiter_timer;
@ -454,20 +538,55 @@ int main(int argc, char ** argv) {
exit(1);
}
if ( my_config.arm9_gdb_port != 0) {
arm9_gdb_stub = createStub_gdb( my_config.arm9_gdb_port,
&arm9_memio,
&arm9_direct_memory_iface);
if ( arm9_gdb_stub == NULL) {
fprintf( stderr, "Failed to create ARM9 gdbstub on port %d\n",
my_config.arm9_gdb_port);
exit( 1);
}
}
if ( my_config.arm7_gdb_port != 0) {
arm7_gdb_stub = createStub_gdb( my_config.arm7_gdb_port,
&arm7_memio,
&arm7_base_memory_iface);
if ( arm7_gdb_stub == NULL) {
fprintf( stderr, "Failed to create ARM7 gdbstub on port %d\n",
my_config.arm7_gdb_port);
exit( 1);
}
}
#ifdef DEBUG
LogStart();
#endif
NDS_Init();
NDS_Init( arm9_memio, &arm9_ctrl_iface,
arm7_memio, &arm7_ctrl_iface);
if ( !my_config.disable_sound) {
SPU_ChangeSoundCore(SNDCORE_SDL, 735 * 4);
}
if ( NDS_LoadROM( my_config.nds_file, MC_TYPE_AUTODETECT, 1) < 0) {
if (NDS_LoadROM( my_config.nds_file, MC_TYPE_AUTODETECT, 1, my_config.cflash_disk_image_file) < 0) {
fprintf(stderr, "error while loading %s\n", my_config.nds_file);
exit(-1);
}
/*
* Activate the GDB stubs
* This has to come after the NDS_Init where the cpus are set up.
*/
if ( my_config.arm9_gdb_port != 0) {
activateStub_gdb( arm9_gdb_stub, arm9_ctrl_iface);
}
if ( my_config.arm7_gdb_port != 0) {
activateStub_gdb( arm7_gdb_stub, arm7_ctrl_iface);
}
/* // This has to get fixed yet
strcpy(szRomPath, dirname(argv[1]));
cflash_close();
@ -555,16 +674,18 @@ int main(int argc, char ** argv) {
/* Load our own keyboard configuration */
set_kb_keys(cli_kb_cfg);
/* create the semaphore used for fps limiting */
fps_limiter_semaphore = SDL_CreateSemaphore( 1);
if ( !my_config.disable_limiter) {
/* create the semaphore used for fps limiting */
fps_limiter_semaphore = SDL_CreateSemaphore( 1);
/* start a SDL timer for every FPS_LIMITER_FRAME_PERIOD frames to keep us at 60 fps */
limiter_timer = SDL_AddTimer( 16 * FPS_LIMITER_FRAME_PERIOD,
fps_limiter_fn, fps_limiter_semaphore);
if ( limiter_timer == NULL) {
fprintf( stderr, "Error trying to start FPS limiter timer: %s\n",
SDL_GetError());
return 1;
/* start a SDL timer for every FPS_LIMITER_FRAME_PERIOD frames to keep us at 60 fps */
limiter_timer = SDL_AddTimer( 16 * FPS_LIMITER_FRAME_PERIOD,
fps_limiter_fn, fps_limiter_semaphore);
if ( limiter_timer == NULL) {
fprintf( stderr, "Error trying to start FPS limiter timer: %s\n",
SDL_GetError());
return 1;
}
}
@ -596,12 +717,14 @@ int main(int argc, char ** argv) {
#endif
Draw();
limiter_frame_counter += 1;
if ( limiter_frame_counter >= FPS_LIMITER_FRAME_PERIOD) {
limiter_frame_counter = 0;
if ( !my_config.disable_limiter) {
limiter_frame_counter += 1;
if ( limiter_frame_counter >= FPS_LIMITER_FRAME_PERIOD) {
limiter_frame_counter = 0;
/* wait for the timer to expire */
SDL_SemWait( fps_limiter_semaphore);
/* wait for the timer to expire */
SDL_SemWait( fps_limiter_semaphore);
}
}
#ifdef DISPLAY_FPS
@ -620,22 +743,34 @@ int main(int argc, char ** argv) {
fps_frame_counter = 0;
fps_timing = 0;
sprintf( win_title, "%f Desmume", fps);
sprintf( win_title, "Desmume %f", fps);
SDL_WM_SetCaption( win_title, NULL);
}
#endif
}
/* Unload joystick */
uninit_joy();
/* tidy up the FPS limiter timer and semaphore */
SDL_RemoveTimer( limiter_timer);
SDL_DestroySemaphore( fps_limiter_semaphore);
if ( !my_config.disable_limiter) {
/* tidy up the FPS limiter timer and semaphore */
SDL_RemoveTimer( limiter_timer);
SDL_DestroySemaphore( fps_limiter_semaphore);
}
SDL_Quit();
NDS_DeInit();
if ( my_config.arm9_gdb_port != 0) {
destroyStub_gdb( arm9_gdb_stub);
}
if ( my_config.arm7_gdb_port != 0) {
destroyStub_gdb( arm7_gdb_stub);
}
#ifdef DEBUG
LogStop();
#endif

View File

@ -17,7 +17,7 @@ desmume_glade_SOURCES = \
gladedir = $(datadir)/desmume/glade
glade_DATA = glade/DeSmuMe_Dtools.glade glade/DeSmuMe.glade glade/DeSmuME.xpm
desmume_glade_LDADD = ../libdesmume.a $(SDL_LIBS) $(GTKGLEXT_LIBS) $(LIBGLADE_LIBS) $(GTHREAD_LIBS)
desmume_glade_LDADD = ../libdesmume.a ../gdbstub/libgdbstub.a $(SDL_LIBS) $(GTKGLEXT_LIBS) $(LIBGLADE_LIBS) $(GTHREAD_LIBS)
desmume_glade_CFLAGS = $(SDL_CFLAGS) $(GTKGLEXT_CFLAGS) $(LIBGLADE_CFLAGS) $(GTHREAD_CFLAGS) -DDATADIR=\"$(gladedir)/\"
desmume_glade_LDFLAGS = -rdynamic

View File

@ -39,9 +39,13 @@ void desmume_mem_init();
u8 *desmume_rom_data = NULL;
u32 desmume_last_cycle;
void desmume_init()
void desmume_init( struct armcpu_memory_iface *arm9_mem_if,
struct armcpu_ctrl_iface **arm9_ctrl_iface,
struct armcpu_memory_iface *arm7_mem_if,
struct armcpu_ctrl_iface **arm7_ctrl_iface)
{
NDS_Init();
NDS_Init( arm9_mem_if, arm9_ctrl_iface,
arm7_mem_if, arm7_ctrl_iface);
SPU_ChangeSoundCore(SNDCORE_SDL, 735 * 4);
execute = FALSE;
}
@ -57,7 +61,7 @@ int desmume_open(const char *filename)
int i;
noticed_3D=attempted_3D_op=FALSE;
clear_savestates();
i = NDS_LoadROM(filename, savetype, savesize);
i = NDS_LoadROM(filename, savetype, savesize, NULL);
return i;
}

View File

@ -22,22 +22,24 @@
#include "globals.h"
#define FPS_LIMITER_FRAME_PERIOD 5
extern SDL_sem *glade_fps_limiter_semaphore;
extern int glade_fps_limiter_disabled;
extern void desmume_init();
extern void desmume_free();
extern void desmume_init( struct armcpu_memory_iface *arm9_mem_if,
struct armcpu_ctrl_iface **arm9_ctrl_iface,
struct armcpu_memory_iface *arm7_mem_if,
struct armcpu_ctrl_iface **arm7_ctrl_iface);
extern void desmume_free( void);
extern int desmume_open(const char *filename);
extern void desmume_savetype(int type);
extern void desmume_pause();
extern void desmume_resume();
extern void desmume_reset();
extern void desmume_toggle();
extern BOOL desmume_running();
extern void desmume_pause( void);
extern void desmume_resume( void);
extern void desmume_reset( void);
extern void desmume_toggle( void);
extern BOOL desmume_running( void);
extern void desmume_cycle();
extern void desmume_cycle( void);
#endif /*__DESMUME_H__*/

View File

@ -24,6 +24,7 @@
#include "callbacks_IO.h"
#include "dTools/callbacks_dtools.h"
#include "globals.h"
#include "../gdbstub.h"
#ifdef GTKGLEXT_AVAILABLE
#include <gtk/gtkgl.h>
@ -67,11 +68,18 @@ struct configured_features {
int software_colour_convert;
int disable_3d;
int disable_limiter;
u16 arm9_gdb_port;
u16 arm7_gdb_port;
const char *nds_file;
};
static void
init_configured_features( struct configured_features *config) {
config->arm9_gdb_port = 0;
config->arm7_gdb_port = 0;
config->software_colour_convert = 0;
config->disable_3d = 0;
@ -102,6 +110,10 @@ fill_configured_features( struct configured_features *config,
#endif
g_print( " --disable-limiter Disables the 60 fps limiter\n");
g_print( "\n");
g_print( " --arm9gdb=PORT_NUM Enable the ARM9 GDB stub on the given port\n");
g_print( " --arm7gdb=PORT_NUM Enable the ARM7 GDB stub on the given port\n");
//g_print( " --sticky Enable sticky keys and stylus\n");
g_print( "\n");
g_print( " --help Display this message\n");
good_args = 0;
}
@ -113,6 +125,30 @@ fill_configured_features( struct configured_features *config,
config->disable_3d = 1;
}
#endif
else if ( strncmp( argv[i], "--arm9gdb=", 10) == 0) {
char *end_char;
unsigned long port_num = strtoul( &argv[i][10], &end_char, 10);
if ( port_num > 0 && port_num < 65536) {
config->arm9_gdb_port = port_num;
}
else {
g_print( "ARM9 GDB stub port must be in the range 1 to 65535\n");
good_args = 0;
}
}
else if ( strncmp( argv[i], "--arm7gdb=", 10) == 0) {
char *end_char;
unsigned long port_num = strtoul( &argv[i][10], &end_char, 10);
if ( port_num > 0 && port_num < 65536) {
config->arm7_gdb_port = port_num;
}
else {
g_print( "ARM7 GDB stub port must be in the range 1 to 65535\n");
good_args = 0;
}
}
else if ( strcmp( argv[i], "--disable-limiter") == 0) {
config->disable_limiter = 1;
}
@ -314,6 +350,27 @@ void update_savestate(u8 num)
}
/*
* The thread handling functions needed by the GDB stub code.
*/
void *
createThread_gdb( void (*thread_function)( void *data),
void *thread_data) {
GThread *new_thread = g_thread_create( (GThreadFunc)thread_function,
thread_data,
TRUE,
NULL);
return new_thread;
}
void
joinThread_gdb( void *thread_handle) {
g_thread_join( thread_handle);
}
/**
* A SDL timer callback function. Signals the supplied SDL semaphore
* if its value is small.
@ -340,7 +397,12 @@ glade_fps_limiter_fn( Uint32 interval, void *param) {
static int
common_gtk_glade_main( struct configured_features *my_config) {
SDL_TimerID limiter_timer;
gdbstub_handle_t arm9_gdb_stub;
gdbstub_handle_t arm7_gdb_stub;
struct armcpu_memory_iface *arm9_memio = &arm9_base_memory_iface;
struct armcpu_memory_iface *arm7_memio = &arm7_base_memory_iface;
struct armcpu_ctrl_iface *arm9_ctrl_iface;
struct armcpu_ctrl_iface *arm7_ctrl_iface;
#ifdef GTKGLEXT_AVAILABLE
// check if you have GTHREAD when running configure script
@ -353,6 +415,30 @@ common_gtk_glade_main( struct configured_features *my_config) {
#endif
init_keyvals();
if ( my_config->arm9_gdb_port != 0) {
arm9_gdb_stub = createStub_gdb( my_config->arm9_gdb_port,
&arm9_memio,
&arm9_base_memory_iface);
if ( arm9_gdb_stub == NULL) {
g_print( "Failed to create ARM9 gdbstub on port %d\n",
my_config->arm9_gdb_port);
return -1;
}
}
if ( my_config->arm7_gdb_port != 0) {
arm7_gdb_stub = createStub_gdb( my_config->arm7_gdb_port,
&arm7_memio,
&arm7_base_memory_iface);
if ( arm7_gdb_stub == NULL) {
g_print( "Failed to create ARM7 gdbstub on port %d\n",
my_config->arm7_gdb_port);
return -1;
}
}
if(SDL_Init( SDL_INIT_TIMER | SDL_INIT_VIDEO) == -1)
{
fprintf(stderr, "Error trying to initialize SDL: %s\n",
@ -360,8 +446,21 @@ common_gtk_glade_main( struct configured_features *my_config) {
return 1;
}
desmume_init( arm9_memio, &arm9_ctrl_iface,
arm7_memio, &arm7_ctrl_iface);
/*
* Activate the GDB stubs
* This has to come after the NDS_Init (called in desmume_init)
* where the cpus are set up.
*/
if ( my_config->arm9_gdb_port != 0) {
activateStub_gdb( arm9_gdb_stub, arm9_ctrl_iface);
}
if ( my_config->arm7_gdb_port != 0) {
activateStub_gdb( arm7_gdb_stub, arm7_ctrl_iface);
}
desmume_init();
/* Initialize joysticks */
if(!init_joy()) return 1;
@ -475,7 +574,10 @@ int main(int argc, char *argv[]) {
struct configured_features my_config;
init_configured_features( &my_config);
if (!g_thread_supported())
g_thread_init( NULL);
gtk_init(&argc, &argv);
#ifdef GTKGLEXT_AVAILABLE

View File

@ -16,6 +16,7 @@ desmume_SOURCES = \
../ctrlssdl.h ../ctrlssdl.c \
gdk_3Demu.c gdk_3Demu.h \
main.c
desmume_LDADD = ../libdesmume.a $(SDL_LIBS) $(GTK_LIBS) $(GTKGLEXT_LIBS)
desmume_CFLAGS = $(SDL_CFLAGS) $(GTK_CFLAGS) $(GTKGLEXT_CFLAGS)
desmume_LDADD = ../libdesmume.a ../gdbstub/libgdbstub.a \
$(SDL_LIBS) $(GTK_LIBS) $(GTKGLEXT_LIBS) $(GTHREAD_LIBS)
desmume_CFLAGS = $(SDL_CFLAGS) $(GTK_CFLAGS) $(GTKGLEXT_CFLAGS) $(GTHREAD_CFLAGS)
#desmume_LDFLAGS = -rdynamic

View File

@ -29,9 +29,14 @@ unsigned long glock = 0;
u8 *desmume_rom_data = NULL;
u32 desmume_last_cycle;
void desmume_init( int disable_sound)
void desmume_init( struct armcpu_memory_iface *arm9_mem_if,
struct armcpu_ctrl_iface **arm9_ctrl_iface,
struct armcpu_memory_iface *arm7_mem_if,
struct armcpu_ctrl_iface **arm7_ctrl_iface,
int disable_sound)
{
NDS_Init();
NDS_Init( arm9_mem_if, arm9_ctrl_iface,
arm7_mem_if, arm7_ctrl_iface);
if ( !disable_sound) {
SPU_ChangeSoundCore(SNDCORE_SDL, 735 * 4);
}

View File

@ -24,7 +24,11 @@
#include "globals.h"
extern void desmume_init( int disable_sound);
extern void desmume_init( struct armcpu_memory_iface *arm9_mem_if,
struct armcpu_ctrl_iface **arm9_ctrl_iface,
struct armcpu_memory_iface *arm7_mem_if,
struct armcpu_ctrl_iface **arm7_ctrl_iface,
int disable_sound);
extern void desmume_free( void);
extern void desmume_pause( void);

View File

@ -27,6 +27,8 @@
#include "globals.h"
#include "../debug.h"
#include "../gdbstub.h"
#ifdef GTKGLEXT_AVAILABLE
#include "../opengl_collector_3Demu.h"
#include "gdk_3Demu.h"
@ -36,8 +38,23 @@
#define EMULOOP_PRIO (G_PRIORITY_HIGH_IDLE + 20)
#define ENABLE_MEMORY_PROFILING 1
#ifdef ENABLE_MEMORY_PROFILING
#include <gdk/gdkkeysyms.h>
void
print_memory_profiling( void);
#endif
static const char *bad_glob_cflash_disk_image_file;
#define FPS_LIMITER_FRAME_PERIOD 8
static SDL_sem *fps_limiter_semaphore;
static int gtk_fps_limiter_disabled = 0;
/************************ CONFIG FILE *****************************/
@ -87,13 +104,23 @@ struct screen_render_config {
struct configured_features {
struct screen_render_config screen;
int disable_sound;
int disable_3d;
int disable_limiter;
u16 arm9_gdb_port;
u16 arm7_gdb_port;
const char *nds_file;
const char *cflash_disk_image_file;
};
static void
init_configured_features( struct configured_features *config) {
config->arm9_gdb_port = 0;
config->arm7_gdb_port = 0;
config->disable_sound = 0;
config->screen.opengl = 0;
@ -101,7 +128,11 @@ init_configured_features( struct configured_features *config) {
config->disable_3d = 0;
config->disable_limiter = 0;
config->nds_file = NULL;
config->cflash_disk_image_file = NULL;
}
static int
@ -125,6 +156,14 @@ fill_configured_features( struct configured_features *config,
printf( "\n");
#endif
printf( " --disable-sound Disables the sound emulation\n");
printf( " --disable-limiter Disables the 60 fps limiter\n");
printf( "\n");
printf( " --arm9gdb=PORT_NUM Enable the ARM9 GDB stub on the given port\n");
printf( " --arm7gdb=PORT_NUM Enable the ARM7 GDB stub on the given port\n");
//printf( " --sticky Enable sticky keys and stylus\n");
printf( "\n");
printf( " --cflash=PATH_TO_DISK_IMAGE\n");
printf( " Enable disk image GBAMP compact flash emulation\n");
printf( "\n");
printf( " --help Display this message\n");
good_args = 0;
@ -143,6 +182,43 @@ fill_configured_features( struct configured_features *config,
config->disable_3d = 1;
}
#endif
else if ( strcmp( argv[i], "--disable-limiter") == 0) {
config->disable_limiter = 1;
}
else if ( strncmp( argv[i], "--arm9gdb=", 10) == 0) {
char *end_char;
unsigned long port_num = strtoul( &argv[i][10], &end_char, 10);
if ( port_num > 0 && port_num < 65536) {
config->arm9_gdb_port = port_num;
}
else {
fprintf( stderr, "ARM9 GDB stub port must be in the range 1 to 65535\n");
good_args = 0;
}
}
else if ( strncmp( argv[i], "--arm7gdb=", 10) == 0) {
char *end_char;
unsigned long port_num = strtoul( &argv[i][10], &end_char, 10);
if ( port_num > 0 && port_num < 65536) {
config->arm7_gdb_port = port_num;
}
else {
fprintf( stderr, "ARM7 GDB stub port must be in the range 1 to 65535\n");
good_args = 0;
}
}
else if ( strncmp( argv[i], "--cflash=", 9) == 0) {
if ( config->cflash_disk_image_file == NULL) {
config->cflash_disk_image_file = &argv[i][9];
}
else {
fprintf( stderr, "CFlash disk image file (\"%s\") already set\n",
config->cflash_disk_image_file);
good_args = 0;
}
}
else {
if ( config->nds_file == NULL) {
config->nds_file = argv[i];
@ -168,6 +244,29 @@ fill_configured_features( struct configured_features *config,
return good_args;
}
/*
* The thread handling functions needed by the GDB stub code.
*/
void *
createThread_gdb( void (*thread_function)( void *data),
void *thread_data) {
GThread *new_thread = g_thread_create( (GThreadFunc)thread_function,
thread_data,
TRUE,
NULL);
return new_thread;
}
void
joinThread_gdb( void *thread_handle) {
g_thread_join( thread_handle);
}
u16 Keypad_Temp[NB_KEYS];
int Write_ConfigFile()
@ -286,9 +385,10 @@ void About(GtkWidget* widget, gpointer data)
g_object_unref(pixbuf);
}
static int Open(const char *filename)
static int Open(const char *filename, const char *cflash_disk_image)
{
int i = NDS_LoadROM(filename, MC_TYPE_AUTODETECT, 1);
int i = NDS_LoadROM( filename, MC_TYPE_AUTODETECT, 1,
cflash_disk_image);
return i;
}
@ -366,7 +466,7 @@ static void *Open_Select(GtkWidget* widget, gpointer data)
case GTK_RESPONSE_OK:
/* Recuperation du chemin */
sChemin = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(pFileSelection));
if(Open((const char*)sChemin) < 0)
if(Open((const char*)sChemin, bad_glob_cflash_disk_image_file) < 0)
{
GtkWidget *pDialog = gtk_message_dialog_new(GTK_WINDOW(pFileSelection),
GTK_DIALOG_MODAL,
@ -865,6 +965,12 @@ static gint Key_Press(GtkWidget *w, GdkEventKey *e)
u16 Key = lookup_key(e->keyval);
ADD_KEY( Cur_Keypad, Key );
if(desmume_running()) update_keypad(Cur_Keypad);
#ifdef ENABLE_MEMORY_PROFILING
if ( e->keyval == GDK_Tab) {
print_memory_profiling();
}
#endif
return 1;
}
@ -1381,12 +1487,14 @@ gboolean EmuLoop(gpointer data)
_updateDTools();
gtk_widget_queue_draw( nds_screen_widget);
limiter_frame_counter += 1;
if ( limiter_frame_counter >= FPS_LIMITER_FRAME_PERIOD) {
limiter_frame_counter = 0;
if ( !gtk_fps_limiter_disabled) {
limiter_frame_counter += 1;
if ( limiter_frame_counter >= FPS_LIMITER_FRAME_PERIOD) {
limiter_frame_counter = 0;
/* wait for the timer to expire */
SDL_SemWait( fps_limiter_semaphore);
/* wait for the timer to expire */
SDL_SemWait( fps_limiter_semaphore);
}
}
@ -1438,11 +1546,43 @@ common_gtk_main( struct configured_features *my_config) {
GdkGLConfig *glconfig;
GdkGLContext *glcontext;
#endif
gdbstub_handle_t arm9_gdb_stub;
gdbstub_handle_t arm7_gdb_stub;
struct armcpu_memory_iface *arm9_memio = &arm9_base_memory_iface;
struct armcpu_memory_iface *arm7_memio = &arm7_base_memory_iface;
struct armcpu_ctrl_iface *arm9_ctrl_iface;
struct armcpu_ctrl_iface *arm7_ctrl_iface;
bad_glob_cflash_disk_image_file = my_config->cflash_disk_image_file;
#ifdef DEBUG
LogStart();
#endif
if ( my_config->arm9_gdb_port != 0) {
arm9_gdb_stub = createStub_gdb( my_config->arm9_gdb_port,
&arm9_memio,
&arm9_base_memory_iface);
if ( arm9_gdb_stub == NULL) {
fprintf( stderr, "Failed to create ARM9 gdbstub on port %d\n",
my_config->arm9_gdb_port);
exit( -1);
}
}
if ( my_config->arm7_gdb_port != 0) {
arm7_gdb_stub = createStub_gdb( my_config->arm7_gdb_port,
&arm7_memio,
&arm7_base_memory_iface);
if ( arm7_gdb_stub == NULL) {
fprintf( stderr, "Failed to create ARM7 gdbstub on port %d\n",
my_config->arm7_gdb_port);
exit( -1);
}
}
#ifdef GTKGLEXT_AVAILABLE
/* Try double-buffered visual */
glconfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB |
@ -1470,8 +1610,23 @@ common_gtk_main( struct configured_features *my_config) {
SDL_GetError());
return 1;
}
desmume_init( arm9_memio, &arm9_ctrl_iface,
arm7_memio, &arm7_ctrl_iface,
my_config->disable_sound);
/*
* Activate the GDB stubs
* This has to come after the NDS_Init (called in desmume_init)
* where the cpus are set up.
*/
if ( my_config->arm9_gdb_port != 0) {
activateStub_gdb( arm9_gdb_stub, arm9_ctrl_iface);
}
if ( my_config->arm7_gdb_port != 0) {
activateStub_gdb( arm7_gdb_stub, arm7_ctrl_iface);
}
desmume_init( my_config->disable_sound);
/* Initialize joysticks */
if(!init_joy()) return 1;
@ -1789,15 +1944,18 @@ common_gtk_main( struct configured_features *my_config) {
//LoadFirmware("fw.bin");
/* create the semaphore used for fps limiting */
fps_limiter_semaphore = SDL_CreateSemaphore( 1);
gtk_fps_limiter_disabled = my_config->disable_limiter;
if ( !gtk_fps_limiter_disabled) {
/* create the semaphore used for fps limiting */
fps_limiter_semaphore = SDL_CreateSemaphore( 1);
/* start a SDL timer for every FPS_LIMITER_FRAME_PERIOD frames to keep us at 60 fps */
limiter_timer = SDL_AddTimer( 16 * FPS_LIMITER_FRAME_PERIOD, fps_limiter_fn, fps_limiter_semaphore);
if ( limiter_timer == NULL) {
fprintf( stderr, "Error trying to start FPS limiter timer: %s\n",
SDL_GetError());
return 1;
/* start a SDL timer for every FPS_LIMITER_FRAME_PERIOD frames to keep us at 60 fps */
limiter_timer = SDL_AddTimer( 16 * FPS_LIMITER_FRAME_PERIOD, fps_limiter_fn, fps_limiter_semaphore);
if ( limiter_timer == NULL) {
fprintf( stderr, "Error trying to start FPS limiter timer: %s\n",
SDL_GetError());
return 1;
}
}
/*
@ -1836,7 +1994,7 @@ common_gtk_main( struct configured_features *my_config) {
/* Vérifie la ligne de commandes */
if( my_config->nds_file != NULL)
{
if(Open( my_config->nds_file) >= 0)
if(Open( my_config->nds_file, bad_glob_cflash_disk_image_file) >= 0)
{
Launch();
}
@ -1861,9 +2019,11 @@ common_gtk_main( struct configured_features *my_config) {
desmume_free();
/* tidy up the FPS limiter timer and semaphore */
SDL_RemoveTimer( limiter_timer);
SDL_DestroySemaphore( fps_limiter_semaphore);
if ( !gtk_fps_limiter_disabled) {
/* tidy up the FPS limiter timer and semaphore */
SDL_RemoveTimer( limiter_timer);
SDL_DestroySemaphore( fps_limiter_semaphore);
}
#ifdef DEBUG
LogStop();
@ -1872,8 +2032,15 @@ common_gtk_main( struct configured_features *my_config) {
uninit_joy();
SDL_Quit();
Write_ConfigFile();
if ( my_config->arm9_gdb_port != 0) {
destroyStub_gdb( arm9_gdb_stub);
}
if ( my_config->arm7_gdb_port != 0) {
destroyStub_gdb( arm7_gdb_stub);
}
return EXIT_SUCCESS;
}
@ -1884,7 +2051,10 @@ main (int argc, char *argv[]) {
struct configured_features my_config;
init_configured_features( &my_config);
if (!g_thread_supported())
g_thread_init( NULL);
gtk_init(&argc, &argv);
#ifdef GTKGLEXT_AVAILABLE

View File

@ -50,9 +50,14 @@
#include "FirmConfig.h"
#include "OGLRender.h"
#include "../render3D.h"
#include "../gdbstub.h"
#include "snddx.h"
/* The compact flash disk image file */
static const char *bad_glob_cflash_disk_image_file;
static char cflash_filename_buffer[512];
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
@ -112,7 +117,79 @@ static u32 backupmemorysize=1;
LRESULT CALLBACK SoundSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
LPARAM lParam);
struct configured_features {
u16 arm9_gdb_port;
u16 arm7_gdb_port;
const char *cflash_disk_image_file;
};
static void
init_configured_features( struct configured_features *config) {
config->arm9_gdb_port = 0;
config->arm7_gdb_port = 0;
config->cflash_disk_image_file = NULL;
}
static int
fill_configured_features( struct configured_features *config, LPSTR lpszArgument) {
int good_args = 0;
LPTSTR cmd_line;
LPWSTR *argv;
int argc;
argv = CommandLineToArgvW( GetCommandLineW(), &argc);
if ( argv != NULL) {
int i;
good_args = 1;
for ( i = 1; i < argc && good_args; i++) {
if ( wcsncmp( argv[i], L"--arm9gdb=", 10) == 0) {
wchar_t *end_char;
unsigned long port_num = wcstoul( &argv[i][10], &end_char, 10);
if ( port_num > 0 && port_num < 65536) {
config->arm9_gdb_port = port_num;
}
else {
MessageBox(NULL,"ARM9 GDB stub port must be in the range 1 to 65535","Error",MB_OK);
good_args = 0;
}
}
else if ( wcsncmp( argv[i], L"--arm7gdb=", 10) == 0) {
wchar_t *end_char;
unsigned long port_num = wcstoul( &argv[i][10], &end_char, 10);
if ( port_num > 0 && port_num < 65536) {
config->arm7_gdb_port = port_num;
}
else {
MessageBox(NULL,"ARM9 GDB stub port must be in the range 1 to 65535","Error",MB_OK);
good_args = 0;
}
}
else if ( wcsncmp( argv[i], L"--cflash=", 9) == 0) {
if ( config->cflash_disk_image_file == NULL) {
size_t convert_count = wcstombs( &cflash_filename_buffer[0], &argv[i][9], 512);
if ( convert_count > 0) {
config->cflash_disk_image_file = cflash_filename_buffer;
}
}
else {
MessageBox(NULL,"CFlash disk image file already set","Error",MB_OK);
good_args = 0;
}
}
}
LocalFree( argv);
}
return good_args;
}
// Rotation definitions
u8 GPU_screenrotated[4*256*192];
short GPU_rotation = 0;
@ -423,16 +500,34 @@ void StateLoadSlot(int num)
NDS_UnPause();
}
BOOL LoadROM(char * filename)
BOOL LoadROM(char * filename, const char *cflash_disk_image)
{
NDS_Pause();
if (NDS_LoadROM(filename, backupmemorytype, backupmemorysize) > 0)
if (NDS_LoadROM(filename, backupmemorytype, backupmemorysize, cflash_disk_image) > 0)
return TRUE;
return FALSE;
}
/*
* The thread handling functions needed by the GDB stub code.
*/
void *
createThread_gdb( void (*thread_function)( void *data),
void *thread_data) {
void *new_thread = CreateThread( NULL, 0,
(LPTHREAD_START_ROUTINE)thread_function, thread_data,
0, NULL);
return new_thread;
}
void
joinThread_gdb( void *thread_handle) {
}
void SetLanguage(int langid)
{
switch(langid)
@ -491,7 +586,15 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
int nFunsterStil)
{
MSG messages; /* Here messages to the application are saved */
gdbstub_handle_t arm9_gdb_stub;
gdbstub_handle_t arm7_gdb_stub;
struct armcpu_memory_iface *arm9_memio = &arm9_base_memory_iface;
struct armcpu_memory_iface *arm7_memio = &arm7_base_memory_iface;
struct armcpu_ctrl_iface *arm9_ctrl_iface;
struct armcpu_ctrl_iface *arm7_ctrl_iface;
struct configured_features my_config;
MSG messages; /* Here messages to the application are saved */
char text[80];
cwindow_struct MainWindow;
HACCEL hAccel;
@ -505,6 +608,13 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
sprintf(text, "DeSmuME v%s", VERSION);
init_configured_features( &my_config);
if ( !fill_configured_features( &my_config, lpszArgument)) {
MessageBox(NULL,"Unable to parse command line arguments","Error",MB_OK);
return 0;
}
bad_glob_cflash_disk_image_file = my_config.cflash_disk_image_file;
hAccel = LoadAccelerators(hAppInst, MAKEINTRESOURCE(IDR_MAIN_ACCEL));
if (CWindow_Init(&MainWindow, hThisInstance, szClassName, text,
@ -535,6 +645,41 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
NDS_Init();
if ( my_config.arm9_gdb_port != 0) {
arm9_gdb_stub = createStub_gdb( my_config.arm9_gdb_port,
&arm9_memio, &arm9_direct_memory_iface);
if ( arm9_gdb_stub == NULL) {
MessageBox(hwnd,"Failed to create ARM9 gdbstub","Error",MB_OK);
return -1;
}
}
if ( my_config.arm7_gdb_port != 0) {
arm7_gdb_stub = createStub_gdb( my_config.arm7_gdb_port,
&arm7_memio,
&arm7_base_memory_iface);
if ( arm7_gdb_stub == NULL) {
MessageBox(hwnd,"Failed to create ARM7 gdbstub","Error",MB_OK);
return -1;
}
}
NDS_Init( arm9_memio, &arm9_ctrl_iface,
arm7_memio, &arm7_ctrl_iface);
/*
* Activate the GDB stubs
* This has to come after the NDS_Init where the cpus are set up.
*/
if ( my_config.arm9_gdb_port != 0) {
activateStub_gdb( arm9_gdb_stub, arm9_ctrl_iface);
}
if ( my_config.arm7_gdb_port != 0) {
activateStub_gdb( arm7_gdb_stub, arm7_ctrl_iface);
}
GetPrivateProfileString("General", "Language", "0", text, 80, IniName);
CheckLanguage(IDC_LANGENGLISH+atoi(text));
@ -581,7 +726,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
if (lpszArgument[0] == '\"')
sscanf(lpszArgument, "\"%[^\"]\"", lpszArgument);
if(LoadROM(lpszArgument))
if(LoadROM(lpszArgument, bad_glob_cflash_disk_image_file))
{
EnableMenuItem(menu, IDM_EXEC, MF_GRAYED);
EnableMenuItem(menu, IDM_PAUSE, MF_ENABLED);
@ -690,7 +835,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
char filename[MAX_PATH] = "";
DragQueryFile((HDROP)wParam,0,filename,MAX_PATH);
DragFinish((HDROP)wParam);
if(LoadROM(filename))
if(LoadROM(filename, bad_glob_cflash_disk_image_file))
{
EnableMenuItem(menu, IDM_EXEC, MF_GRAYED);
EnableMenuItem(menu, IDM_PAUSE, MF_ENABLED);
@ -948,7 +1093,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
LOG("%s\r\n", filename);
if(LoadROM(filename))
if(LoadROM(filename, bad_glob_cflash_disk_image_file))
{
EnableMenuItem(menu, IDM_EXEC, MF_GRAYED);
EnableMenuItem(menu, IDM_PAUSE, MF_ENABLED);