From 7562b83c44f4686ce0e4ada180d08950385f1f96 Mon Sep 17 00:00:00 2001 From: Gwenhael Le Moine Date: Sun, 14 Apr 2024 14:08:56 +0200 Subject: [PATCH] state files' location is now ~/.config/hpemu --- Makefile | 1 + src/config.c | 24 +++++ src/config.h | 16 +++ src/emulator.c | 19 ++-- src/emulator.h | 4 +- src/files.c | 279 ++++++++++++++++++++++++++++++++++++------------- src/files.h | 6 +- src/main.c | 24 +---- src/ports.h | 3 - 9 files changed, 267 insertions(+), 109 deletions(-) create mode 100644 src/config.c create mode 100644 src/config.h diff --git a/Makefile b/Makefile index 291af04..01d1c2e 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,7 @@ dist/hpemu: src/bus.o \ src/files.o \ src/ports.o \ src/rpl.o \ + src/config.o \ src/timers.o $(CC) $(CFLAGS) $(LIBS) -o $@ $+ diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..e33224d --- /dev/null +++ b/src/config.c @@ -0,0 +1,24 @@ +#include "config.h" + +Config config = { + .progname = "hpemu", + .real_speed = true, + .verbose = true, +}; + +void parse_args( int argc, char* argv[] ) +{ + while ( --argc ) { + argv++; + if ( argv[ 0 ][ 0 ] == '-' ) { + switch ( argv[ 0 ][ 1 ] ) { + case 't': + config.real_speed = true; + break; + case 'r': + config.real_speed = false; + break; + } + } + } +} diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..f879360 --- /dev/null +++ b/src/config.h @@ -0,0 +1,16 @@ +#ifndef __CONFIG_H +#define __CONFIG_H + +#include + +typedef struct { + char* progname; + bool real_speed; + bool verbose; +} Config; + +extern Config config; + +void parse_args( int argc, char* argv[] ); + +#endif diff --git a/src/emulator.c b/src/emulator.c index f37f954..099f24b 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -9,10 +9,10 @@ #include "bus.h" #include "timers.h" #include "display.h" -#include "gui.h" #include "emulator.h" #include "files.h" #include "ports.h" +#include "config.h" #define MAX_DELTA 4000 @@ -44,24 +44,25 @@ static int emulator_state = EMULATOR_RUN; void emulator_set_state( int state ) { emulator_state = state; } -void emulator_init( void ) +void emulator_init( char* fn_rom, char* fn_ram, char* fn_port1, char* fn_port2 ) { static bool locked = false; - rom_init( "./rom" ); - ram_init( "./ram" ); - ports_init( "./port1", "./port2" ); + get_absolute_working_dir_path( "hpemu" ); + rom_init( fn_rom ); + ram_init( fn_ram ); + ports_init( fn_port1, fn_port2 ); bus_init(); if ( !locked ) locked = true; } -void emulator_exit( void ) +void emulator_exit( char* fn_rom, char* fn_ram, char* fn_port1, char* fn_port2 ) { rom_exit(); - ram_exit( "./ram" ); - ports_exit( "./port1", "./port2" ); + ram_exit( fn_ram ); + ports_exit( fn_port1, fn_port2 ); bus_exit(); } @@ -120,7 +121,7 @@ bool emulator_run( void ) if ( !cpu.shutdown ) { execute_instruction(); - throttle( true ); + throttle( config.real_speed || cpu.keyintp ); if ( emulator_state == EMULATOR_STEP ) { emulator_set_state( EMULATOR_STOP ); diff --git a/src/emulator.h b/src/emulator.h index 9aa6035..2b182d3 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -8,8 +8,8 @@ enum EmulatorStates { EMULATOR_STOP, EMULATOR_STEP, EMULATOR_RUN }; extern volatile bool please_exit; extern dword emulator_speed; -extern void emulator_init( void ); -extern void emulator_exit( void ); +extern void emulator_init( char* fn_rom, char* fn_ram, char* fn_port1, char* fn_port2 ); +extern void emulator_exit( char* fn_rom, char* fn_ram, char* fn_port1, char* fn_port2 ); extern bool emulator_run( void ); extern void emulator_set_state( int state ); diff --git a/src/files.c b/src/files.c index 8547df1..83756fe 100644 --- a/src/files.c +++ b/src/files.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -5,50 +6,133 @@ #include // readlink #include // PATH_MAX #include +#include #include "gui.h" #include "rpl.h" #include "files.h" #include "bus.h" #include "ports.h" +#include "config.h" extern byte current_bank; extern byte* port2; extern address port2mask; -char WorkingPath[ 512 ]; +/* char WorkingPath[ MAX_LENGTH_FILENAME ]; */ +char absolute_working_dir_path[ MAX_LENGTH_FILENAME ]; static address ram_size = 256 * 1024; // in nibbles, not bytes! -void getExePath() -{ - char programPath[ 1024 ]; - char temp[ 1024 ]; - memset( programPath, 0, sizeof( programPath ) ); - memset( temp, 0, sizeof( temp ) ); +static address port1_size = ( 256 * 1024 ); /* 128Kio in nibbles */ +static address port2_size = ( 8192 * 1024 ); /* 4Mio in nibbles */ - char result[ PATH_MAX ]; - ssize_t count = readlink( "/proc/self/exe", result, PATH_MAX ); - const char* path; - if ( count != -1 ) { - path = dirname( result ); - strcpy( programPath, path ); +void get_absolute_working_dir_path() +{ + if ( absolute_working_dir_path[ 0 ] == '/' ) + return; + if ( config.verbose ) + fprintf( stderr, "Finding and creating absolute_working_dir_path\n" ); + + memset( absolute_working_dir_path, 0, sizeof( absolute_working_dir_path ) ); + char* xdg_config_home = getenv( "XDG_CONFIG_HOME" ); + + if ( xdg_config_home ) { + if ( config.verbose ) + fprintf( stderr, "XDG_CONFIG_HOME is %s\n", xdg_config_home ); + + strcpy( absolute_working_dir_path, xdg_config_home ); + strcat( absolute_working_dir_path, "/" ); + } else { + char* home = getenv( "HOME" ); + + if ( home ) { + if ( config.verbose ) + fprintf( stderr, "HOME is %s\n", home ); + + strcpy( absolute_working_dir_path, home ); + strcat( absolute_working_dir_path, "/.config/" ); + } else { + struct passwd* pwd = getpwuid( getuid() ); + + if ( pwd ) { + if ( config.verbose ) + fprintf( stderr, "pwd->pw_dir is %s\n", pwd->pw_dir ); + + strcpy( absolute_working_dir_path, pwd->pw_dir ); + strcat( absolute_working_dir_path, "/" ); + } else { + if ( config.verbose ) + fprintf( stderr, "can\'t figure out your home directory, " + "trying /tmp\n" ); + + strcpy( absolute_working_dir_path, "/tmp" ); + } + } } - memset( WorkingPath, 0, sizeof( WorkingPath ) ); - strcpy( WorkingPath, programPath ); + strcat( absolute_working_dir_path, config.progname ); + + if ( absolute_working_dir_path[ strlen( absolute_working_dir_path ) ] != '/' ) + strcat( absolute_working_dir_path, "/" ); + + if ( config.verbose ) + fprintf( stderr, "SET absolute_working_dir_path = %s\n", absolute_working_dir_path ); + + struct stat st; + bool make_dir = false; + if ( stat( absolute_working_dir_path, &st ) == -1 ) { + if ( errno == ENOENT ) { + make_dir = true; + } else { + if ( config.verbose ) + fprintf( stderr, "can\'t stat %s, saving to /tmp\n", absolute_working_dir_path ); + strcpy( absolute_working_dir_path, "/tmp" ); + } + } else { + if ( !S_ISDIR( st.st_mode ) ) { + if ( config.verbose ) + fprintf( stderr, "%s is no directory, saving to /tmp\n", absolute_working_dir_path ); + strcpy( absolute_working_dir_path, "/tmp" ); + } + } + + if ( make_dir ) { + if ( mkdir( absolute_working_dir_path, 0777 ) == -1 ) { + if ( config.verbose ) + fprintf( stderr, "can\'t mkdir %s, saving to /tmp\n", absolute_working_dir_path ); + strcpy( absolute_working_dir_path, "/tmp" ); + } + } } +/* void getExePath() */ +/* { */ +/* char programPath[ MAX_LENGTH_FILENAME ]; */ +/* char temp[ MAX_LENGTH_FILENAME ]; */ +/* memset( programPath, 0, sizeof( programPath ) ); */ +/* memset( temp, 0, sizeof( temp ) ); */ + +/* char result[ PATH_MAX ]; */ +/* ssize_t count = readlink( "/proc/self/exe", result, PATH_MAX ); */ +/* const char* path; */ +/* if ( count != -1 ) { */ +/* path = dirname( result ); */ +/* strcpy( programPath, path ); */ +/* } */ + +/* memset( WorkingPath, 0, sizeof( WorkingPath ) ); */ +/* strcpy( WorkingPath, programPath ); */ +/* } */ + int file_size( char* filename ) { - memset( WorkingPath, 0, sizeof( WorkingPath ) ); - getExePath(); + /* memset( WorkingPath, 0, sizeof( WorkingPath ) ); */ + /* getExePath(); */ + get_absolute_working_dir_path(); FILE* f; - char fullpath[ 1024 ]; - sprintf( fullpath, "%s/%s", WorkingPath, filename ); - printf( "%s\n", fullpath ); - f = fopen( fullpath, "r" ); + f = fopen( filename, "r" ); if ( !f ) return 0; @@ -60,7 +144,7 @@ int file_size( char* filename ) return size; } -int read_mem_file( char* filename, nibble* mem, int size ) +int read_mem_file( char* absolute_filename, nibble* mem, int size ) { struct stat st; FILE* fp; @@ -68,15 +152,15 @@ int read_mem_file( char* filename, nibble* mem, int size ) byte rbyte; int i, j; - if ( NULL == ( fp = fopen( filename, "r" ) ) ) { - /* if ( verbose ) */ - /* fprintf( stderr, "ct open %s\n", filename ); */ + if ( NULL == ( fp = fopen( absolute_filename, "r" ) ) ) { + if ( config.verbose ) + fprintf( stderr, "ct open %s\n", absolute_filename ); return 0; } - if ( stat( filename, &st ) < 0 ) { - /* if ( verbose ) */ - /* fprintf( stderr, "can\'t stat %s\n", filename ); */ + if ( stat( absolute_filename, &st ) < 0 ) { + if ( config.verbose ) + fprintf( stderr, "can\'t stat %s\n", absolute_filename ); return 0; } @@ -85,8 +169,8 @@ int read_mem_file( char* filename, nibble* mem, int size ) * size is same as memory size, old version file */ if ( fread( mem, 1, ( size_t )size, fp ) != ( unsigned long )size ) { - /* if ( verbose ) */ - /* fprintf( stderr, "can\'t read %s\n", filename ); */ + if ( config.verbose ) + fprintf( stderr, "can\'t read %s\n", absolute_filename ); fclose( fp ); return 0; } @@ -96,8 +180,8 @@ int read_mem_file( char* filename, nibble* mem, int size ) */ if ( st.st_size != size / 2 ) { - /* if ( verbose ) */ - /* fprintf( stderr, "strange size %s, expected %d, found %ld\n", filename, size / 2, st.st_size ); */ + if ( config.verbose ) + fprintf( stderr, "strange size %s, expected %d, found %ld\n", absolute_filename, size / 2, st.st_size ); fclose( fp ); return 0; } @@ -105,8 +189,8 @@ int read_mem_file( char* filename, nibble* mem, int size ) if ( NULL == ( tmp_mem = ( byte* )malloc( ( size_t )st.st_size ) ) ) { for ( i = 0, j = 0; i < size / 2; i++ ) { if ( 1 != fread( &rbyte, 1, 1, fp ) ) { - /* if ( verbose ) */ - /* fprintf( stderr, "can\'t read %s\n", filename ); */ + if ( config.verbose ) + fprintf( stderr, "can\'t read %s\n", absolute_filename ); fclose( fp ); return 0; } @@ -115,8 +199,8 @@ int read_mem_file( char* filename, nibble* mem, int size ) } } else { if ( fread( tmp_mem, 1, ( size_t )size / 2, fp ) != ( unsigned long )( size / 2 ) ) { - /* if ( verbose ) */ - /* fprintf( stderr, "can\'t read %s\n", filename ); */ + if ( config.verbose ) + fprintf( stderr, "can\'t read %s\n", absolute_filename ); fclose( fp ); free( tmp_mem ); return 0; @@ -133,22 +217,22 @@ int read_mem_file( char* filename, nibble* mem, int size ) fclose( fp ); - /* if ( verbose ) */ - /* printf( "read %s\n", filename ); */ + if ( config.verbose ) + printf( "read %s\n", absolute_filename ); return 1; } -int write_mem_file( char* filename, nibble* mem, int size ) +int write_mem_file( char* absolute_filename, nibble* mem, int size ) { FILE* fp; byte* tmp_mem; byte rbyte; int i, j; - if ( NULL == ( fp = fopen( filename, "w" ) ) ) { - /* if ( verbose ) */ - /* fprintf( stderr, "can\'t open %s\n", filename ); */ + if ( NULL == ( fp = fopen( absolute_filename, "w" ) ) ) { + if ( config.verbose ) + fprintf( stderr, "can\'t open %s\n", absolute_filename ); return 0; } @@ -157,8 +241,8 @@ int write_mem_file( char* filename, nibble* mem, int size ) rbyte = ( mem[ j++ ] & 0x0f ); rbyte |= ( mem[ j++ ] << 4 ) & 0xf0; if ( 1 != fwrite( &rbyte, 1, 1, fp ) ) { - /* if ( verbose ) */ - /* fprintf( stderr, "can\'t write %s\n", filename ); */ + if ( config.verbose ) + fprintf( stderr, "can\'t write %s\n", absolute_filename ); fclose( fp ); return 0; } @@ -170,8 +254,8 @@ int write_mem_file( char* filename, nibble* mem, int size ) } if ( fwrite( tmp_mem, 1, ( size_t )size / 2, fp ) != ( unsigned long )size / 2 ) { - /* if ( verbose ) */ - /* fprintf( stderr, "can\'t write %s\n", filename ); */ + if ( config.verbose ) + fprintf( stderr, "can\'t write %s\n", absolute_filename ); fclose( fp ); free( tmp_mem ); return 0; @@ -182,8 +266,8 @@ int write_mem_file( char* filename, nibble* mem, int size ) fclose( fp ); - /* if ( verbose ) */ - /* printf( "wrote %s\n", filename ); */ + if ( config.verbose ) + printf( "wrote %s\n", absolute_filename ); return 1; } @@ -197,7 +281,11 @@ void load_file_on_stack( char* filename ) int fsize; address size; - fsize = file_size( filename ); + char fullpath[ MAX_LENGTH_FILENAME ]; + get_absolute_working_dir_path(); + sprintf( fullpath, "%s%s", absolute_working_dir_path, filename ); + + fsize = file_size( fullpath ); if ( fsize < 11 ) // "PHPH48-X" + prologue (8 + 2.5) return; @@ -205,7 +293,7 @@ void load_file_on_stack( char* filename ) if ( !buf ) return; - f = fopen( filename, "r" ); + f = fopen( fullpath, "r" ); if ( !f ) { free( buf ); return; @@ -250,7 +338,13 @@ void rom_init( char* filename ) byte *buf, *ptr1, *ptr2; FILE* f; - size = file_size( filename ); + char fullpath[ MAX_LENGTH_FILENAME ]; + get_absolute_working_dir_path(); + sprintf( fullpath, "%s%s", absolute_working_dir_path, filename ); + if ( config.verbose ) + fprintf( stderr, "fullpath = %s\n", fullpath ); + + size = file_size( fullpath ); if ( !size ) { printf( "ERROR: Can't read ROM file size\n" ); exit( 0x10 ); @@ -265,9 +359,6 @@ void rom_init( char* filename ) exit( 0x12 ); } - char fullpath[ 1024 ]; - sprintf( fullpath, "%s/%s", WorkingPath, filename ); - f = fopen( fullpath, "r" ); if ( !f ) { printf( "ERROR: can't open ROM file\n" ); @@ -313,11 +404,23 @@ void ram_init( char* filename ) { bus_info.ram_data = malloc( ram_size ); - int filesize = file_size( filename ); - fprintf( stderr, "filesize(%i) == ram_size(%i)\n", filesize, ram_size ); - if ( filesize * 2 == ram_size ) - read_mem_file( filename, bus_info.ram_data, ram_size ); - else { + char fullpath[ MAX_LENGTH_FILENAME ]; + get_absolute_working_dir_path(); + sprintf( fullpath, "%s%s", absolute_working_dir_path, filename ); + if ( config.verbose ) + fprintf( stderr, "fullpath = %s\n", fullpath ); + + int filesize = file_size( fullpath ) * 2; + if ( config.verbose ) + fprintf( stderr, "filesize(%i) == ram_size(%i)\n", filesize, ram_size ); + if ( filesize == ram_size ) { + if ( config.verbose ) + fprintf( stderr, "loading %s as RAM\n", fullpath ); + read_mem_file( fullpath, bus_info.ram_data, ram_size ); + } else { + if ( config.verbose ) + fprintf( stderr, "Creating RAM\n" ); + byte* buf = malloc( ram_size ); if ( !buf ) exit( 0x20 ); @@ -331,7 +434,15 @@ void ram_init( char* filename ) void ram_exit( char* filename ) { - write_mem_file( filename, bus_info.ram_data, ram_size ); + fprintf( stderr, "\n\nfilename = %s\n", filename ); + char fullpath[ MAX_LENGTH_FILENAME ]; + get_absolute_working_dir_path(); + sprintf( fullpath, "%s%s", absolute_working_dir_path, filename ); + if ( config.verbose ) { + fprintf( stderr, "fullpath = %s\n", fullpath ); + fprintf( stderr, "Saving RAM to %s\n", fullpath ); + } + write_mem_file( fullpath, bus_info.ram_data, ram_size ); free( bus_info.ram_data ); bus_info.ram_data = NULL; @@ -347,22 +458,34 @@ void ports_init( char* filename1, char* filename2 ) bus_info.ce1_bs = true; // ce2 = port1 (plugged) - bus_info.ce2_data = malloc( PORT1_SIZE ); + bus_info.ce2_data = malloc( port1_size ); - int filesize = file_size( filename1 ); - if ( filesize * 2 == PORT1_SIZE ) - read_mem_file( filename1, bus_info.ce2_data, ram_size ); + char fullpath1[ MAX_LENGTH_FILENAME ]; + get_absolute_working_dir_path(); + sprintf( fullpath1, "%s%s", absolute_working_dir_path, filename1 ); + if ( config.verbose ) + fprintf( stderr, "fullpath = %s\n", fullpath1 ); - bus_info.ce2_mask = PORT1_SIZE - 1; + int filesize = file_size( fullpath1 ) * 2; + if ( filesize == port1_size ) + read_mem_file( fullpath1, bus_info.ce2_data, ram_size ); + + bus_info.ce2_mask = port1_size - 1; bus_info.ce2_r_o = false; // nce3 = port2 (plugged) - port2 = malloc( PORT2_SIZE ); + port2 = malloc( port2_size ); - filesize = file_size( filename2 ); - if ( filesize * 2 == PORT2_SIZE ) - read_mem_file( filename2, port2, PORT2_SIZE ); - port2mask = PORT2_SIZE - 1; + char fullpath2[ MAX_LENGTH_FILENAME ]; + get_absolute_working_dir_path(); + sprintf( fullpath2, "%s%s", absolute_working_dir_path, filename2 ); + if ( config.verbose ) + fprintf( stderr, "fullpath = %s\n", fullpath1 ); + + filesize = file_size( fullpath2 ) * 2; + if ( filesize == port2_size ) + read_mem_file( fullpath2, port2, port2_size ); + port2mask = port2_size - 1; bus_info.nce3_data = port2; bus_info.nce3_mask = port2mask & 0x3FFFF; bus_info.nce3_r_o = false; @@ -373,6 +496,18 @@ void ports_init( char* filename1, char* filename2 ) void ports_exit( char* filename1, char* filename2 ) { - write_mem_file( filename1, bus_info.ce2_data, PORT1_SIZE ); - write_mem_file( filename2, port2, PORT2_SIZE ); + char fullpath1[ MAX_LENGTH_FILENAME ]; + get_absolute_working_dir_path(); + sprintf( fullpath1, "%s%s", absolute_working_dir_path, filename1 ); + if ( config.verbose ) + fprintf( stderr, "fullpath = %s\n", fullpath1 ); + + char fullpath2[ MAX_LENGTH_FILENAME ]; + get_absolute_working_dir_path(); + sprintf( fullpath2, "%s%s", absolute_working_dir_path, filename2 ); + if ( config.verbose ) + fprintf( stderr, "fullpath = %s\n", fullpath1 ); + + write_mem_file( fullpath1, bus_info.ce2_data, port1_size ); + write_mem_file( fullpath2, port2, port2_size ); } diff --git a/src/files.h b/src/files.h index 53caf95..ae059cd 100644 --- a/src/files.h +++ b/src/files.h @@ -3,13 +3,15 @@ #include "types.h" -extern char WorkingPath[ 512 ]; +#define MAX_LENGTH_FILENAME 2048 + +extern void get_absolute_working_dir_path(); extern int file_size( char* filename ); extern void load_file_on_stack( char* filename ); extern void rom_init( char* filename ); -extern void rom_exit( void ); +extern void rom_exit(); extern void ram_init( char* filename ); extern void ram_exit( char* filename ); diff --git a/src/main.c b/src/main.c index e0214f5..a509e5d 100644 --- a/src/main.c +++ b/src/main.c @@ -3,6 +3,7 @@ #include +#include "config.h" #include "emulator.h" #include "gui.h" #include "display.h" @@ -18,25 +19,6 @@ unsigned int delay_timer1 = 16384; unsigned int lastTime_timer5 = 0; unsigned int delay_timer5 = 64; // fps -static int fullscreen = false; - -static void parse_args( int argc, char* argv[] ) -{ - while ( --argc ) { - argv++; - if ( argv[ 0 ][ 0 ] == '-' ) { - switch ( argv[ 0 ][ 1 ] ) { - case 'f': - fullscreen = true; - break; - case 'w': - fullscreen = false; - break; - } - } - } -} - static inline void mainloop() { if ( please_exit || !SDL_ready ) @@ -65,12 +47,12 @@ int main( int argc, char* argv[] ) parse_args( argc, argv ); gui_init(); - emulator_init(); + emulator_init( "rom", "ram", "port1", "port2" ); while ( !please_exit ) mainloop(); - emulator_exit(); + emulator_exit( "rom", "ram", "port1", "port2" ); gui_exit(); return 0; diff --git a/src/ports.h b/src/ports.h index 188731f..47c359c 100644 --- a/src/ports.h +++ b/src/ports.h @@ -3,9 +3,6 @@ #include "types.h" -#define PORT1_SIZE ( 256 * 1024 ) /* 128Kio in nibbles */ -#define PORT2_SIZE ( 256 * 1024 ) /* 128Kio in nibbles */ - extern byte current_bank; extern byte* port2; extern address port2mask;