state files' location is now ~/.config/hpemu

This commit is contained in:
Gwenhael Le Moine 2024-04-14 14:08:56 +02:00
parent f25ed5776e
commit 7562b83c44
No known key found for this signature in database
GPG key ID: FDFE3669426707A7
9 changed files with 267 additions and 109 deletions

View file

@ -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 $@ $+

24
src/config.c Normal file
View file

@ -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;
}
}
}
}

16
src/config.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef __CONFIG_H
#define __CONFIG_H
#include <stdbool.h>
typedef struct {
char* progname;
bool real_speed;
bool verbose;
} Config;
extern Config config;
void parse_args( int argc, char* argv[] );
#endif

View file

@ -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 );

View file

@ -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 );

View file

@ -1,3 +1,4 @@
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@ -5,50 +6,133 @@
#include <unistd.h> // readlink
#include <linux/limits.h> // PATH_MAX
#include <sys/stat.h>
#include <pwd.h>
#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 );
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 * 2 == ram_size )
read_mem_file( filename, bus_info.ram_data, ram_size );
else {
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 );
}

View file

@ -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 );

View file

@ -3,6 +3,7 @@
#include <SDL2/SDL.h>
#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;

View file

@ -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;