Search
lxdream.org :: lxdream :: r1100:50e702af9373
lxdream 0.9.1
released Jun 29
Download Now
changeset1100:50e702af9373
parent1099:566cdeb157ec
child1101:78e762cec843
authornkeynes
dateMon Feb 15 17:27:14 2010 +1000 (14 years ago)
Hook up the fake bios boot
Use fakebios if invoked with -b, or if there's no boot rom loaded
src/asic.c
src/asic.h
src/bios.c
src/bootstrap.h
src/dreamcast.c
src/dreamcast.h
src/loader.c
src/main.c
src/syscall.h
1.1 --- a/src/asic.c Wed Feb 10 18:16:19 2010 +1000
1.2 +++ b/src/asic.c Mon Feb 15 17:27:14 2010 +1000
1.3 @@ -416,6 +416,13 @@
1.4 MMIO_WRITE( ASIC, SORTDMACTL, 0 );
1.5 }
1.6
1.7 +gboolean asic_enable_ide_interface( gboolean enable )
1.8 +{
1.9 + gboolean oldval = idereg.interface_enabled;
1.10 + idereg.interface_enabled = enable;
1.11 + return oldval;
1.12 +}
1.13 +
1.14 MMIO_REGION_READ_FN( ASIC, reg )
1.15 {
1.16 int32_t val;
2.1 --- a/src/asic.h Wed Feb 10 18:16:19 2010 +1000
2.2 +++ b/src/asic.h Mon Feb 15 17:27:14 2010 +1000
2.3 @@ -218,3 +218,5 @@
2.4 void asic_clear_event( int event );
2.5
2.6 void asic_g2_write_word( );
2.7 +
2.8 +gboolean asic_enable_ide_interface( gboolean enable );
3.1 --- a/src/bios.c Wed Feb 10 18:16:19 2010 +1000
3.2 +++ b/src/bios.c Mon Feb 15 17:27:14 2010 +1000
3.3 @@ -3,7 +3,7 @@
3.4 *
3.5 * "Fake" BIOS functions, for operation without the actual BIOS.
3.6 *
3.7 - * Copyright (c) 2005 Nathan Keynes.
3.8 + * Copyright (c) 2005-2010 Nathan Keynes.
3.9 *
3.10 * This program is free software; you can redistribute it and/or modify
3.11 * it under the terms of the GNU General Public License as published by
3.12 @@ -19,6 +19,7 @@
3.13 #include "dream.h"
3.14 #include "mem.h"
3.15 #include "syscall.h"
3.16 +#include "asic.h"
3.17 #include "dreamcast.h"
3.18 #include "bootstrap.h"
3.19 #include "sh4/sh4.h"
3.20 @@ -26,51 +27,73 @@
3.21 #include "drivers/cdrom/isoread.h"
3.22 #include "gdrom/gdrom.h"
3.23
3.24 +/* Definitions from KOS */
3.25 #define COMMAND_QUEUE_LENGTH 16
3.26
3.27 -/* TODO: Check if these are the real ATAPI command codes or not */
3.28 -#define GD_CMD_PIOREAD 16
3.29 -#define GD_CMD_DMAREAD 17
3.30 +#define GD_CMD_PIOREAD 16 /* readcd */
3.31 +#define GD_CMD_DMAREAD 17 /* readcd */
3.32 #define GD_CMD_GETTOC 18
3.33 -#define GD_CMD_GETTOC2 19
3.34 -#define GD_CMD_PLAY 20
3.35 -#define GD_CMD_PLAY2 21
3.36 -#define GD_CMD_PAUSE 22
3.37 -#define GD_CMD_RELEASE 23
3.38 -#define GD_CMD_INIT 24
3.39 +#define GD_CMD_GETTOC2 19 /* toc2 */
3.40 +#define GD_CMD_PLAY 20 /* playcd */
3.41 +#define GD_CMD_PLAY2 21 /* playcd */
3.42 +#define GD_CMD_PAUSE 22 /* No params */
3.43 +#define GD_CMD_RELEASE 23 /* No params */
3.44 +#define GD_CMD_INIT 24 /* No params */
3.45 #define GD_CMD_SEEK 27
3.46 #define GD_CMD_READ 28
3.47 -#define GD_CMD_STOP 33
3.48 +#define GD_CMD_STOP 33 /* No params */
3.49 #define GD_CMD_GETSCD 34
3.50 #define GD_CMD_GETSES 35
3.51
3.52 -#define GD_CMD_STATUS_NONE 0
3.53 +#define GD_CMD_STATUS_NONE 0
3.54 #define GD_CMD_STATUS_ACTIVE 1
3.55 -#define GD_CMD_STATUS_DONE 2
3.56 -#define GD_CMD_STATUS_ABORT 3
3.57 -#define GD_CMD_STATUS_ERROR 4
3.58 +#define GD_CMD_STATUS_DONE 2
3.59 +#define GD_CMD_STATUS_ABORT 3
3.60 +#define GD_CMD_STATUS_ERROR 4
3.61
3.62 #define GD_ERROR_OK 0
3.63 #define GD_ERROR_NO_DISC 2
3.64 #define GD_ERROR_DISC_CHANGE 6
3.65 #define GD_ERROR_SYSTEM 1
3.66
3.67 +typedef union gdrom_cmd_params {
3.68 + struct gdrom_toc2_params {
3.69 + uint32_t session;
3.70 + sh4addr_t buffer;
3.71 + } toc2;
3.72
3.73 -typedef struct gdrom_command {
3.74 + struct gdrom_readcd_params {
3.75 + cdrom_lba_t sector;
3.76 + cdrom_count_t count;
3.77 + sh4addr_t buffer;
3.78 + uint32_t unknown;
3.79 + } readcd;
3.80 +
3.81 + struct gdrom_playcd_params {
3.82 + cdrom_lba_t start;
3.83 + cdrom_lba_t end;
3.84 + uint32_t repeat;
3.85 + } playcd;
3.86 +} *gdrom_cmd_params_t;
3.87 +
3.88 +
3.89 +
3.90 +
3.91 +typedef struct gdrom_queue_entry {
3.92 int status;
3.93 uint32_t cmd_code;
3.94 sh4ptr_t data;
3.95 uint32_t result[4];
3.96 -} *gdrom_command_t;
3.97 +} *gdrom_queue_entry_t;
3.98
3.99 -static struct gdrom_command gdrom_cmd_queue[COMMAND_QUEUE_LENGTH];
3.100 +static struct gdrom_queue_entry gdrom_cmd_queue[COMMAND_QUEUE_LENGTH];
3.101
3.102 static struct bios_gdrom_status {
3.103 uint32_t status;
3.104 uint32_t disk_type;
3.105 } bios_gdrom_status;
3.106
3.107 -void bios_gdrom_run_command( gdrom_command_t cmd )
3.108 +void bios_gdrom_run_command( gdrom_queue_entry_t cmd )
3.109 {
3.110 DEBUG( "BIOS GD command %d", cmd->cmd_code );
3.111 switch( cmd->cmd_code ) {
3.112 @@ -114,7 +137,7 @@
3.113 }
3.114 }
3.115
3.116 -gdrom_command_t bios_gdrom_get_command( uint32_t id )
3.117 +gdrom_queue_entry_t bios_gdrom_get_command( uint32_t id )
3.118 {
3.119 if( id >= COMMAND_QUEUE_LENGTH ||
3.120 gdrom_cmd_queue[id].status == GD_CMD_STATUS_NONE )
3.121 @@ -128,7 +151,7 @@
3.122
3.123 void bios_syscall( uint32_t syscallid )
3.124 {
3.125 - gdrom_command_t cmd;
3.126 + gdrom_queue_entry_t cmd;
3.127
3.128 switch( syscallid ) {
3.129 case 0xB0: /* sysinfo */
3.130 @@ -211,7 +234,11 @@
3.131 {
3.132 /* Initialize hardware */
3.133 /* Boot disc if present */
3.134 - bios_boot_gdrom_disc();
3.135 + if( bios_boot_gdrom_disc() ) {
3.136 + sh4r.pr = sh4r.pc; /* Set the syscall return address to the bootstrap entry */
3.137 + } else {
3.138 + dreamcast_stop();
3.139 + }
3.140 }
3.141
3.142 void bios_install( void )
3.143 @@ -302,6 +329,7 @@
3.144 isofs_reader_destroy(iso);
3.145 return FALSE;
3.146 }
3.147 + asic_enable_ide_interface(TRUE);
3.148 } else {
3.149 /* Load the binary into a temp buffer */
3.150 unsigned char tmp[program_sectors*2048];
3.151 @@ -312,7 +340,9 @@
3.152 return FALSE;
3.153 }
3.154 bootprogram_unscramble(program, tmp, ent->size);
3.155 + asic_enable_ide_interface(FALSE);
3.156 }
3.157 isofs_reader_destroy(iso);
3.158 - dreamcast_program_loaded( "", BOOTSTRAP_LOAD_ADDR );
3.159 + dreamcast_program_loaded( "", BOOTSTRAP_ENTRY_ADDR );
3.160 + return TRUE;
3.161 }
4.1 --- a/src/bootstrap.h Wed Feb 10 18:16:19 2010 +1000
4.2 +++ b/src/bootstrap.h Mon Feb 15 17:27:14 2010 +1000
4.3 @@ -29,6 +29,7 @@
4.4 #endif
4.5
4.6 #define BOOTSTRAP_LOAD_ADDR 0x8C008000
4.7 +#define BOOTSTRAP_ENTRY_ADDR 0x8c008300
4.8 #define BOOTSTRAP_SIZE 32768
4.9 #define BOOTSTRAP_MAGIC "SEGA SEGAKATANA SEGA ENTERPRISES"
4.10 #define BOOTSTRAP_MAGIC_SIZE 32
5.1 --- a/src/dreamcast.c Wed Feb 10 18:16:19 2010 +1000
5.2 +++ b/src/dreamcast.c Mon Feb 15 17:27:14 2010 +1000
5.3 @@ -43,6 +43,7 @@
5.4 STATE_STOPPING, STATE_STOPPED } dreamcast_state_t;
5.5
5.6 static volatile dreamcast_state_t dreamcast_state = STATE_UNINIT;
5.7 +static gboolean dreamcast_use_bios = TRUE;
5.8 static gboolean dreamcast_has_bios = FALSE;
5.9 static gboolean dreamcast_has_flash = FALSE;
5.10 static gboolean dreamcast_exit_on_stop = FALSE;
5.11 @@ -86,7 +87,7 @@
5.12 * Note currently the locations of the various MMIO pages are hard coded in
5.13 * the MMIO definitions - they should probably be moved here.
5.14 */
5.15 -void dreamcast_configure( )
5.16 +void dreamcast_configure( gboolean use_bootrom )
5.17 {
5.18 char *bios_path = lxdream_get_global_config_path_value(CONFIG_BIOS_PATH);
5.19 char *flash_path = lxdream_get_global_config_path_value(CONFIG_FLASH_PATH);
5.20 @@ -108,7 +109,12 @@
5.21 mem_map_region( NULL, 0x11000000, 16 MB, MEM_REGION_PVR2VDMA1, &mem_region_pvr2vdma1, 0, 16 MB, 0 );
5.22 mem_map_region( NULL, 0x13000000, 16 MB, MEM_REGION_PVR2VDMA2, &mem_region_pvr2vdma2, 0, 16 MB, 0 );
5.23
5.24 - dreamcast_has_bios = mem_load_rom( dc_boot_rom, bios_path, 2 MB, 0x89f2b1a1 );
5.25 + dreamcast_use_bios = use_bootrom;
5.26 + dreamcast_has_bios = dreamcast_load_bios( bios_path );
5.27 + if( !dreamcast_has_bios ) {
5.28 + dreamcast_load_fakebios();
5.29 + }
5.30 +
5.31 if( flash_path != NULL && flash_path[0] != '\0' ) {
5.32 mem_load_block( flash_path, 0x00200000, 0x00020000 );
5.33 }
5.34 @@ -128,10 +134,28 @@
5.35
5.36 gboolean dreamcast_load_bios( const gchar *filename )
5.37 {
5.38 - dreamcast_has_bios = mem_load_rom( dc_boot_rom, filename, 2 MB, 0x89f2b1a1 );
5.39 + if( dreamcast_use_bios ) {
5.40 + dreamcast_has_bios = mem_load_rom( dc_boot_rom, filename, 2 MB, 0x89f2b1a1 );
5.41 + } else {
5.42 + dreamcast_has_bios = FALSE;
5.43 + }
5.44 return dreamcast_has_bios;
5.45 }
5.46
5.47 +static const char fakebios[] = {
5.48 + 0x00, 0xd1, /* movl $+4, r1 */
5.49 + 0x2b, 0x41, /* jmp @r1 */
5.50 + 0xa0, 0xff, /* .long 0xffffffa0 */
5.51 + 0xff, 0xff };
5.52 +gboolean dreamcast_load_fakebios( )
5.53 +{
5.54 + memset( dc_boot_rom, 0, 2 MB );
5.55 + memcpy( dc_boot_rom, fakebios, sizeof(fakebios) );
5.56 + syscall_add_hook( 0xA0, bios_boot );
5.57 + dreamcast_has_bios = TRUE;
5.58 + return TRUE;
5.59 +}
5.60 +
5.61 gboolean dreamcast_load_flash( const gchar *filename )
5.62 {
5.63 if( filename != NULL && filename[0] != '\0' ) {
5.64 @@ -201,9 +225,9 @@
5.65 dreamcast_exit_on_stop = flag;
5.66 }
5.67
5.68 -void dreamcast_init( void )
5.69 +void dreamcast_init( gboolean use_bootrom )
5.70 {
5.71 - dreamcast_configure();
5.72 + dreamcast_configure( use_bootrom );
5.73 dreamcast_state = STATE_STOPPED;
5.74 }
5.75
5.76 @@ -326,8 +350,7 @@
5.77
5.78 gboolean dreamcast_can_run(void)
5.79 {
5.80 - return dreamcast_state != STATE_UNINIT &&
5.81 - (dreamcast_has_bios || dreamcast_program_name != NULL);
5.82 + return dreamcast_state != STATE_UNINIT;
5.83 }
5.84
5.85 /********************************* Save States *****************************/
6.1 --- a/src/dreamcast.h Wed Feb 10 18:16:19 2010 +1000
6.2 +++ b/src/dreamcast.h Mon Feb 15 17:27:14 2010 +1000
6.3 @@ -37,9 +37,9 @@
6.4
6.5 struct lxdream_config_group; // Forward declaration
6.6
6.7 -void dreamcast_configure(void);
6.8 +void dreamcast_configure(gboolean use_bootrom);
6.9 void dreamcast_configure_aica_only(void);
6.10 -void dreamcast_init(void);
6.11 +void dreamcast_init(gboolean use_bootrom);
6.12 void dreamcast_reset(void);
6.13 void dreamcast_run(void);
6.14 void dreamcast_set_run_time( unsigned int seconds, unsigned int nanosecs );
6.15 @@ -86,6 +86,7 @@
6.16 * allocation and does not need to be freed separately)
6.17 */
6.18 frame_buffer_t dreamcast_load_preview( const gchar *filename );
6.19 +gboolean dreamcast_load_fakebios();
6.20
6.21 #define SCENE_SAVE_MAGIC "%!-lxDream!Scene"
6.22 #define SCENE_SAVE_VERSION 0x00010000
7.1 --- a/src/loader.c Wed Feb 10 18:16:19 2010 +1000
7.2 +++ b/src/loader.c Mon Feb 15 17:27:14 2010 +1000
7.3 @@ -107,7 +107,7 @@
7.4 * correctly
7.5 */
7.6 if( mem_load_block( bootstrap_file, BOOTSTRAP_LOAD_ADDR, BOOTSTRAP_SIZE ) == 0 ) {
7.7 - dreamcast_program_loaded( filename, BOOTSTRAP_LOAD_ADDR+0x300 );
7.8 + dreamcast_program_loaded( filename, BOOTSTRAP_ENTRY_ADDR );
7.9 g_free(bootstrap_file);
7.10 return;
7.11 }
8.1 --- a/src/main.c Wed Feb 10 18:16:19 2010 +1000
8.2 +++ b/src/main.c Mon Feb 15 17:27:14 2010 +1000
8.3 @@ -41,10 +41,11 @@
8.4 #include "hotkeys.h"
8.5 #include "plugin.h"
8.6
8.7 -char *option_list = "a:A:c:dfg:G:hHl:m:npt:T:uvV:x?";
8.8 +char *option_list = "a:A:bc:dfg:G:hHl:m:npt:T:uvV:x?";
8.9 struct option longopts[] = {
8.10 { "aica", required_argument, NULL, 'a' },
8.11 { "audio", required_argument, NULL, 'A' },
8.12 + { "biosless", no_argument, NULL, 'b' },
8.13 { "config", required_argument, NULL, 'c' },
8.14 { "debugger", no_argument, NULL, 'D' },
8.15 { "fullscreen", no_argument, NULL, 'f' },
8.16 @@ -72,6 +73,7 @@
8.17 gboolean use_xlat = TRUE;
8.18 gboolean show_debugger = FALSE;
8.19 gboolean show_fullscreen = FALSE;
8.20 +gboolean use_bootrom = TRUE;
8.21 extern uint32_t sh4_cpu_multiplier;
8.22
8.23 static void print_version()
8.24 @@ -87,6 +89,7 @@
8.25 printf( "Options:\n" );
8.26 printf( " -a, --aica=PROGFILE %s\n", _("Run the AICA SPU only, with the supplied program") );
8.27 printf( " -A, --audio=DRIVER %s\n", _("Use the specified audio driver (? to list)") );
8.28 + printf( " -b, --biosless %s\n", _("Run without the BIOS boot rom even if available") );
8.29 printf( " -c, --config=CONFFILE %s\n", _("Load configuration from CONFFILE") );
8.30 printf( " -d, --debugger %s\n", _("Start in debugger mode") );
8.31 printf( " -f, --fullscreen %s\n", _("Start in fullscreen mode") );
8.32 @@ -133,6 +136,8 @@
8.33 case 'A': /* Audio driver */
8.34 audio_driver_name = optarg;
8.35 break;
8.36 + case 'b': /* No Boot rom */
8.37 + use_bootrom = FALSE;
8.38 case 'c': /* Config file */
8.39 lxdream_set_config_filename(optarg);
8.40 break;
8.41 @@ -223,7 +228,7 @@
8.42 vmulist_init();
8.43
8.44 if( aica_program == NULL ) {
8.45 - dreamcast_init();
8.46 + dreamcast_init(use_bootrom);
8.47 } else {
8.48 dreamcast_configure_aica_only();
8.49 mem_load_block( aica_program, 0x00800000, 2048*1024 );
9.1 --- a/src/syscall.h Wed Feb 10 18:16:19 2010 +1000
9.2 +++ b/src/syscall.h Mon Feb 15 17:27:14 2010 +1000
9.3 @@ -60,6 +60,8 @@
9.4 */
9.5 void bios_install( void );
9.6
9.7 +void bios_boot( uint32_t syscallid );
9.8 +
9.9 /**
9.10 * Install the DCLoad syscall hack
9.11 */
.