Search
lxdream.org :: lxdream :: r543:361ec0a70cf2
lxdream 0.9.1
released Jun 29
Download Now
changeset543:361ec0a70cf2
parent542:96c5494e02fd
child544:3c3a4bd77178
authornkeynes
dateThu Nov 22 11:10:15 2007 +0000 (16 years ago)
Re-add "Load Binary" menu item (misplaced in GUI rewrite)
Prevent running with no code loaded
src/dreamcast.c
src/dreamcast.h
src/gtkui/debug_win.c
src/gtkui/gtkcb.c
src/gtkui/gtkui.c
src/gtkui/gtkui.h
src/gtkui/main_win.c
src/gtkui/path_dlg.c
src/loader.c
src/main.c
src/mem.c
src/mem.h
1.1 --- a/src/dreamcast.c Wed Nov 21 11:52:13 2007 +0000
1.2 +++ b/src/dreamcast.c Thu Nov 22 11:10:15 2007 +0000
1.3 @@ -18,6 +18,7 @@
1.4 */
1.5
1.6 #include <errno.h>
1.7 +#include <glib.h>
1.8 #include "dream.h"
1.9 #include "config.h"
1.10 #include "mem.h"
1.11 @@ -30,13 +31,14 @@
1.12 /**
1.13 * Current state of the DC virtual machine
1.14 */
1.15 -#define STATE_UNINIT 0
1.16 -#define STATE_RUNNING 1
1.17 -#define STATE_STOPPING 2
1.18 -#define STATE_STOPPED 3
1.19 -static volatile int dreamcast_state = STATE_UNINIT;
1.20 +typedef enum { STATE_UNINIT=0, STATE_RUNNING,
1.21 + STATE_STOPPING, STATE_STOPPED } dreamcast_state_t;
1.22 +
1.23 +static volatile dreamcast_state_t dreamcast_state = STATE_UNINIT;
1.24 +static gboolean dreamcast_has_bios = FALSE;
1.25 +static gchar *dreamcast_program_name = NULL;
1.26 +static sh4addr_t dreamcast_entry_point = 0xA0000000;
1.27 static uint32_t timeslice_length = DEFAULT_TIMESLICE_LENGTH;
1.28 -const char *dreamcast_config = "DEFAULT";
1.29
1.30 #define MAX_MODULES 32
1.31 static int num_modules = 0;
1.32 @@ -67,8 +69,9 @@
1.33 mem_create_ram_region( 0x00800000, 2 MB, MEM_REGION_AUDIO );
1.34 mem_create_ram_region( 0x00703000, 8 KB, MEM_REGION_AUDIO_SCRATCH );
1.35 mem_create_ram_region( 0x05000000, 8 MB, MEM_REGION_VIDEO );
1.36 - mem_load_rom( lxdream_get_config_value(CONFIG_BIOS_PATH),
1.37 - 0x00000000, 0x00200000, 0x89f2b1a1, MEM_REGION_BIOS );
1.38 + dreamcast_has_bios = mem_load_rom( lxdream_get_config_value(CONFIG_BIOS_PATH),
1.39 + 0x00000000, 0x00200000, 0x89f2b1a1,
1.40 + MEM_REGION_BIOS );
1.41 mem_create_ram_region( 0x00200000, 0x00020000, MEM_REGION_FLASH );
1.42 mem_load_block( lxdream_get_config_value(CONFIG_FLASH_PATH),
1.43 0x00200000, 0x00020000 );
1.44 @@ -84,8 +87,9 @@
1.45
1.46 void dreamcast_config_changed(void)
1.47 {
1.48 - mem_load_rom( lxdream_get_config_value(CONFIG_BIOS_PATH),
1.49 - 0x00000000, 0x00200000, 0x89f2b1a1, MEM_REGION_BIOS );
1.50 + dreamcast_has_bios = mem_load_rom( lxdream_get_config_value(CONFIG_BIOS_PATH),
1.51 + 0x00000000, 0x00200000, 0x89f2b1a1,
1.52 + MEM_REGION_BIOS );
1.53 mem_load_block( lxdream_get_config_value(CONFIG_FLASH_PATH),
1.54 0x00200000, 0x00020000 );
1.55 }
1.56 @@ -207,11 +211,32 @@
1.57 dreamcast_save_flash();
1.58 }
1.59
1.60 +void dreamcast_program_loaded( const gchar *name, sh4addr_t entry_point )
1.61 +{
1.62 + if( dreamcast_program_name != NULL ) {
1.63 + g_free(dreamcast_program_name);
1.64 + }
1.65 + dreamcast_program_name = g_strdup(name);
1.66 + dreamcast_entry_point = entry_point;
1.67 + sh4_set_pc(entry_point);
1.68 + if( !dreamcast_has_bios ) {
1.69 + bios_install();
1.70 + }
1.71 + dcload_install();
1.72 + gui_update_state();
1.73 +}
1.74 +
1.75 gboolean dreamcast_is_running( void )
1.76 {
1.77 return dreamcast_state == STATE_RUNNING;
1.78 }
1.79
1.80 +gboolean dreamcast_can_run(void)
1.81 +{
1.82 + return dreamcast_state != STATE_UNINIT &&
1.83 + (dreamcast_has_bios || dreamcast_program_name != NULL);
1.84 +}
1.85 +
1.86 /********************************* Save States *****************************/
1.87
1.88 struct save_state_header {
2.1 --- a/src/dreamcast.h Wed Nov 21 11:52:13 2007 +0000
2.2 +++ b/src/dreamcast.h Thu Nov 22 11:10:15 2007 +0000
2.3 @@ -46,6 +46,13 @@
2.4 void dreamcast_config_changed(void);
2.5 gboolean dreamcast_is_running(void);
2.6
2.7 +/**
2.8 + * Return if it's possible to start the VM - currently this requires
2.9 + * a) A configured system
2.10 + * b) Some code to run (either a user program or a ROM)
2.11 + */
2.12 +gboolean dreamcast_can_run(void);
2.13 +
2.14 #define DREAMCAST_SAVE_MAGIC "%!-lxDream!Save\0"
2.15 #define DREAMCAST_SAVE_VERSION 0x00010002
2.16
3.1 --- a/src/gtkui/debug_win.c Wed Nov 21 11:52:13 2007 +0000
3.2 +++ b/src/gtkui/debug_win.c Thu Nov 22 11:10:15 2007 +0000
3.3 @@ -396,7 +396,7 @@
3.4 {
3.5 if( data != NULL ) {
3.6 gtk_gui_enable_action( "SingleStep", !isRunning );
3.7 - gtk_gui_enable_action( "RunTo", !isRunning );
3.8 + gtk_gui_enable_action( "RunTo", !isRunning && dreamcast_can_run() );
3.9 }
3.10 }
3.11
3.12 @@ -437,7 +437,7 @@
3.13 GdkEvent *event, gpointer user_data)
3.14 {
3.15 gtk_gui_enable_action( "SetBreakpoint", TRUE );
3.16 - gtk_gui_enable_action( "RunTo", TRUE );
3.17 + gtk_gui_enable_action( "RunTo", dreamcast_can_run() );
3.18 }
3.19
3.20 void on_disasm_list_unselect_row (GtkCList *clist, gint row, gint column,
4.1 --- a/src/gtkui/gtkcb.c Wed Nov 21 11:52:13 2007 +0000
4.2 +++ b/src/gtkui/gtkcb.c Thu Nov 22 11:10:15 2007 +0000
4.3 @@ -22,7 +22,7 @@
4.4 #include "gdrom/gdrom.h"
4.5 #include "gtkui/gtkui.h"
4.6 #include "pvr2/pvr2.h"
4.7 -
4.8 +#include "loader.h"
4.9
4.10
4.11 static void add_file_pattern( GtkFileChooser *chooser, char *pattern, char *patname )
4.12 @@ -101,6 +101,12 @@
4.13 dreamcast_run();
4.14 }
4.15
4.16 +void load_binary_action_callback( GtkAction *action, gpointer user_data)
4.17 +{
4.18 + const gchar *dir = lxdream_get_config_value(CONFIG_DEFAULT_PATH);
4.19 + open_file_dialog( "Open Binary...", file_load_magic, NULL, NULL, dir );
4.20 +}
4.21 +
4.22 void load_state_preview_callback( GtkFileChooser *chooser, gpointer user_data )
4.23 {
4.24 GtkWidget *preview = GTK_WIDGET(user_data);
5.1 --- a/src/gtkui/gtkui.c Wed Nov 21 11:52:13 2007 +0000
5.2 +++ b/src/gtkui/gtkui.c Thu Nov 22 11:10:15 2007 +0000
5.3 @@ -67,6 +67,7 @@
5.4 { "FileMenu", NULL, N_("_File") },
5.5 { "SettingsMenu", NULL, N_("_Settings") },
5.6 { "HelpMenu", NULL, N_("_Help") },
5.7 + { "LoadBinary", NULL, N_("Load _Binary..."), NULL, N_("Load and run a program binary"), G_CALLBACK(load_binary_action_callback) },
5.8 { "Reset", GTK_STOCK_REFRESH, N_("_Reset"), "<control>R", N_("Reset dreamcast"), G_CALLBACK(reset_action_callback) },
5.9 { "Pause", GTK_STOCK_MEDIA_PAUSE, N_("_Pause"), NULL, N_("Pause dreamcast"), G_CALLBACK(pause_action_callback) },
5.10 { "Run", GTK_STOCK_MEDIA_PLAY, N_("Resume"), NULL, N_("Resume"), G_CALLBACK(resume_action_callback) },
5.11 @@ -100,6 +101,7 @@
5.12 "<ui>"
5.13 " <menubar name='MainMenu'>"
5.14 " <menu action='FileMenu'>"
5.15 + " <menuitem action='LoadBinary'/>"
5.16 " <menuitem action='GdromSettings'/>"
5.17 " <separator/>"
5.18 " <menuitem action='Reset'/>"
5.19 @@ -235,6 +237,7 @@
5.20
5.21 void gui_main_loop(void)
5.22 {
5.23 + gtk_gui_update();
5.24 gtk_main();
5.25 }
5.26
5.27 @@ -346,6 +349,8 @@
5.28
5.29 void gtk_gui_update( void )
5.30 {
5.31 + gtk_gui_enable_action("Run", dreamcast_can_run() && !dreamcast_is_running() );
5.32 + gtk_gui_enable_action("Pause", dreamcast_is_running() );
5.33 if( debug_win ) {
5.34 debug_window_set_running( debug_win, FALSE );
5.35 debug_window_update(debug_win);
6.1 --- a/src/gtkui/gtkui.h Wed Nov 21 11:52:13 2007 +0000
6.2 +++ b/src/gtkui/gtkui.h Thu Nov 22 11:10:15 2007 +0000
6.3 @@ -97,6 +97,7 @@
6.4
6.5 /******************* Callback declarations *******************/
6.6
6.7 +void load_binary_action_callback( GtkAction *action, gpointer user_data);
6.8 void mount_action_callback( GtkAction *action, gpointer user_data);
6.9 void reset_action_callback( GtkAction *action, gpointer user_data);
6.10 void pause_action_callback( GtkAction *action, gpointer user_data);
7.1 --- a/src/gtkui/main_win.c Wed Nov 21 11:52:13 2007 +0000
7.2 +++ b/src/gtkui/main_win.c Thu Nov 22 11:10:15 2007 +0000
7.3 @@ -117,7 +117,7 @@
7.4 void main_window_set_running( main_window_t win, gboolean running )
7.5 {
7.6 gtk_gui_enable_action( "Pause", running );
7.7 - gtk_gui_enable_action( "Run", !running );
7.8 + gtk_gui_enable_action( "Run", !running && dreamcast_can_run() );
7.9 gtk_statusbar_pop( GTK_STATUSBAR(win->statusbar), 1 );
7.10 gtk_statusbar_push( GTK_STATUSBAR(win->statusbar), 1, running ? "Running" : "Stopped" );
7.11 }
8.1 --- a/src/gtkui/path_dlg.c Wed Nov 21 11:52:13 2007 +0000
8.2 +++ b/src/gtkui/path_dlg.c Thu Nov 22 11:10:15 2007 +0000
8.3 @@ -119,6 +119,7 @@
8.4
8.5 lxdream_save_config();
8.6 dreamcast_config_changed();
8.7 + gtk_gui_update();
8.8 }
8.9 }
8.10
9.1 --- a/src/loader.c Wed Nov 21 11:52:13 2007 +0000
9.2 +++ b/src/loader.c Thu Nov 22 11:10:15 2007 +0000
9.3 @@ -25,13 +25,10 @@
9.4 #include <stdint.h>
9.5 #include <elf.h>
9.6 #include "mem.h"
9.7 -#include "sh4core.h"
9.8 #include "bootstrap.h"
9.9 #include "dreamcast.h"
9.10 #include "config.h"
9.11 #include "loader.h"
9.12 -#include "syscall.h"
9.13 -#include "gui.h"
9.14
9.15 char bootstrap_magic[32] = "SEGA SEGAKATANA SEGA ENTERPRISES";
9.16 char iso_magic[6] = "\001CD001";
9.17 @@ -48,7 +45,7 @@
9.18 #define CDI_V2 0x80000004
9.19 #define CDI_V3 0x80000005
9.20
9.21 -gboolean file_load_elf_fd( int fd );
9.22 +gboolean file_load_elf_fd( const gchar *filename, int fd );
9.23
9.24
9.25 gboolean file_load_magic( const gchar *filename )
9.26 @@ -77,8 +74,7 @@
9.27 lseek( fd, 0, SEEK_SET );
9.28 read( fd, load, BOOTSTRAP_SIZE );
9.29 bootstrap_dump( load, TRUE );
9.30 - sh4_set_pc( BOOTSTRAP_LOAD_ADDR + 0x300 );
9.31 - gui_update_state();
9.32 + dreamcast_program_loaded( filename, BOOTSTRAP_LOAD_ADDR + 0x300 );
9.33 } else {
9.34 /* look for a valid ISO9660 header */
9.35 lseek( fd, 32768, SEEK_SET );
9.36 @@ -100,7 +96,7 @@
9.37 buf[2] == 'L' && buf[3] == 'F' ) {
9.38 /* ELF binary */
9.39 lseek( fd, 0, SEEK_SET );
9.40 - result = file_load_elf_fd( fd );
9.41 + result = file_load_elf_fd( filename, fd );
9.42 } else {
9.43 result = FALSE;
9.44 }
9.45 @@ -108,25 +104,19 @@
9.46 return result;
9.47 }
9.48
9.49 -void file_load_postload( int pc )
9.50 +void file_load_postload( const gchar *filename, int pc )
9.51 {
9.52 const gchar *bootstrap_file = lxdream_get_config_value(CONFIG_BOOTSTRAP);
9.53 if( bootstrap_file != NULL ) {
9.54 /* Load in a bootstrap before the binary, to initialize everything
9.55 * correctly
9.56 */
9.57 - if( mem_load_block( bootstrap_file, BOOTSTRAP_LOAD_ADDR, BOOTSTRAP_SIZE ) != 0 ) {
9.58 - /* Try it without the bootstrap */
9.59 - sh4_set_pc( pc );
9.60 - } else {
9.61 - sh4_set_pc( BOOTSTRAP_LOAD_ADDR + 0x300 );
9.62 + if( mem_load_block( bootstrap_file, BOOTSTRAP_LOAD_ADDR, BOOTSTRAP_SIZE ) == 0 ) {
9.63 + dreamcast_program_loaded( filename, BOOTSTRAP_LOAD_ADDR+0x300 );
9.64 + return;
9.65 }
9.66 - } else {
9.67 - sh4_set_pc( pc );
9.68 }
9.69 - bios_install();
9.70 - dcload_install();
9.71 - gui_update_state();
9.72 + dreamcast_program_loaded( filename, pc );
9.73 }
9.74
9.75
9.76 @@ -134,14 +124,14 @@
9.77 {
9.78 /* Load the binary itself */
9.79 if( mem_load_block( filename, BINARY_LOAD_ADDR, -1 ) == 0 ) {
9.80 - file_load_postload( BINARY_LOAD_ADDR );
9.81 + file_load_postload( filename, BINARY_LOAD_ADDR );
9.82 return TRUE;
9.83 } else {
9.84 return FALSE;
9.85 }
9.86 }
9.87
9.88 -gboolean file_load_elf_fd( int fd )
9.89 +gboolean file_load_elf_fd( const gchar *filename, int fd )
9.90 {
9.91 Elf32_Ehdr head;
9.92 Elf32_Phdr phdr;
9.93 @@ -174,6 +164,6 @@
9.94 }
9.95 }
9.96
9.97 - file_load_postload( head.e_entry );
9.98 + file_load_postload( filename, head.e_entry );
9.99 return TRUE;
9.100 }
10.1 --- a/src/main.c Wed Nov 21 11:52:13 2007 +0000
10.2 +++ b/src/main.c Thu Nov 22 11:10:15 2007 +0000
10.3 @@ -57,6 +57,7 @@
10.4 gboolean display_ok;
10.5
10.6 install_crash_handler();
10.7 + gdrom_get_native_devices();
10.8 #ifdef ENABLE_NLS
10.9 bindtextdomain (PACKAGE, PACKAGE_LOCALE_DIR);
10.10 textdomain (PACKAGE);
10.11 @@ -185,11 +186,15 @@
10.12 sh4_set_use_xlat( use_xlat );
10.13
10.14 if( start_immediately ) {
10.15 - if( time_nanos != 0 || time_secs != 0 ) {
10.16 - dreamcast_run_for(time_secs, time_nanos);
10.17 - return 0;
10.18 + if( dreamcast_can_run() ) {
10.19 + if( time_nanos != 0 || time_secs != 0 ) {
10.20 + dreamcast_run_for(time_secs, time_nanos);
10.21 + return 0;
10.22 + } else {
10.23 + dreamcast_run();
10.24 + }
10.25 } else {
10.26 - dreamcast_run();
10.27 + ERROR( "Unable to start dreamcast: no program/bios loaded" );
10.28 }
10.29 }
10.30 if( !headless ) {
11.1 --- a/src/mem.c Wed Nov 21 11:52:13 2007 +0000
11.2 +++ b/src/mem.c Thu Nov 22 11:10:15 2007 +0000
11.3 @@ -198,7 +198,7 @@
11.4 FILE *f = fopen(file,"r");
11.5
11.6 if( f == NULL ) {
11.7 - ERROR( "Unable to load file '%s': %s", file, strerror(errno) );
11.8 + WARN( "Unable to load file '%s': %s", file, strerror(errno) );
11.9 return -1;
11.10 }
11.11 fstat( fileno(f), &st );
11.12 @@ -266,8 +266,8 @@
11.13 return mem;
11.14 }
11.15
11.16 -void *mem_load_rom( const gchar *file, uint32_t base, uint32_t size, uint32_t crc,
11.17 - const gchar *region_name )
11.18 +gboolean mem_load_rom( const gchar *file, uint32_t base, uint32_t size, uint32_t crc,
11.19 + const gchar *region_name )
11.20 {
11.21 sh4ptr_t mem;
11.22 uint32_t calc_crc;
11.23 @@ -278,7 +278,7 @@
11.24 mem = mmap( NULL, size, PROT_WRITE|PROT_READ, MAP_ANON|MAP_PRIVATE, -1, 0 );
11.25 if( mem == MAP_FAILED ) {
11.26 ERROR( "Unable to allocate ROM memory: %s (%s)", file, strerror(errno) );
11.27 - return NULL;
11.28 + return FALSE;
11.29 }
11.30 mem_map_region( mem, base, size, file, MEM_FLAG_ROM, size, base );
11.31 } else {
11.32 @@ -295,9 +295,10 @@
11.33 WARN( "Bios CRC Mismatch in %s: %08X (expected %08X)",
11.34 file, calc_crc, crc);
11.35 }
11.36 + return TRUE;
11.37 }
11.38
11.39 - return mem;
11.40 + return FALSE;
11.41 }
11.42
11.43 sh4ptr_t mem_get_region_by_name( const char *name )
12.1 --- a/src/mem.h Wed Nov 21 11:52:13 2007 +0000
12.2 +++ b/src/mem.h Thu Nov 22 11:10:15 2007 +0000
12.3 @@ -48,8 +48,14 @@
12.4 void *mem_create_ram_region( uint32_t base, uint32_t size, const char *name );
12.5 void *mem_create_repeating_ram_region( uint32_t base, uint32_t size, const char *name,
12.6 uint32_t repeat_offset, uint32_t last_repeat );
12.7 -void *mem_load_rom( const gchar *name, uint32_t base, uint32_t size, uint32_t crc,
12.8 - const gchar *region_name );
12.9 +/**
12.10 + * Load a ROM image from the specified filename. If the memory region has not
12.11 + * been allocated, it is created now, otherwise the existing region is reused.
12.12 + * If the CRC check fails, a warning will be printed.
12.13 + * @return TRUE if the image was loaded successfully (irrespective of CRC failure).
12.14 + */
12.15 +gboolean mem_load_rom( const gchar *filename, uint32_t base, uint32_t size,
12.16 + uint32_t crc, const gchar *region_name );
12.17 void *mem_alloc_pages( int n );
12.18 sh4ptr_t mem_get_region( uint32_t addr );
12.19 sh4ptr_t mem_get_region_by_name( const char *name );
.