2022-03-24 13:41:22 +01:00
|
|
|
#include <errno.h>
|
|
|
|
#include <pwd.h>
|
2015-07-26 11:16:05 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2023-04-27 16:56:13 +02:00
|
|
|
#include <unistd.h>
|
2022-03-24 13:41:22 +01:00
|
|
|
#include <sys/stat.h>
|
2023-04-27 16:56:13 +02:00
|
|
|
#include <string.h>
|
2015-07-26 11:16:05 +02:00
|
|
|
#include <sys/types.h>
|
|
|
|
|
2022-03-24 13:41:22 +01:00
|
|
|
#include "device.h"
|
2015-07-26 11:16:05 +02:00
|
|
|
#include "hp48.h"
|
|
|
|
#include "hp48_emu.h"
|
|
|
|
#include "resources.h"
|
|
|
|
#include "romio.h"
|
|
|
|
|
|
|
|
#define X48_MAGIC 0x48503438
|
|
|
|
#define NR_CONFIG 8
|
|
|
|
|
|
|
|
short rom_is_new = 1;
|
2022-03-24 13:41:22 +01:00
|
|
|
long ram_size;
|
|
|
|
long port1_size;
|
|
|
|
long port1_mask;
|
2015-07-26 11:16:05 +02:00
|
|
|
short port1_is_ram;
|
2022-03-24 13:41:22 +01:00
|
|
|
long port2_size;
|
|
|
|
long port2_mask;
|
2015-07-26 11:16:05 +02:00
|
|
|
short port2_is_ram;
|
|
|
|
|
|
|
|
typedef struct old_keystate_t {
|
2023-04-27 12:15:59 +02:00
|
|
|
int rows[ 9 ];
|
2015-07-26 11:16:05 +02:00
|
|
|
} old_keystate_t;
|
|
|
|
|
|
|
|
typedef struct old_saturn_t {
|
2023-04-27 12:15:59 +02:00
|
|
|
unsigned char A[ 16 ], B[ 16 ], C[ 16 ], D[ 16 ];
|
|
|
|
long d[ 2 ];
|
|
|
|
int P;
|
|
|
|
long PC;
|
|
|
|
unsigned char R0[ 16 ], R1[ 16 ], R2[ 16 ], R3[ 16 ], R4[ 16 ];
|
|
|
|
unsigned char IN[ 4 ];
|
|
|
|
unsigned char OUT[ 3 ];
|
|
|
|
int CARRY;
|
|
|
|
unsigned char PSTAT[ NR_PSTAT ];
|
|
|
|
unsigned char XM, SB, SR, MP;
|
|
|
|
unsigned char hexmode;
|
|
|
|
long rstk[ NR_RSTK ];
|
|
|
|
short rstkp;
|
|
|
|
old_keystate_t keybuf;
|
|
|
|
unsigned char intenable;
|
|
|
|
unsigned char int_pending;
|
|
|
|
unsigned char kbd_ien;
|
|
|
|
long configs[ NR_CONFIG ];
|
|
|
|
short daisy_state;
|
|
|
|
long ram32k;
|
|
|
|
long devices;
|
|
|
|
unsigned char disp_io;
|
|
|
|
unsigned char contrast_ctrl;
|
|
|
|
unsigned char disp_test;
|
|
|
|
unsigned int crc;
|
|
|
|
unsigned char power_status;
|
|
|
|
unsigned char power_ctrl;
|
|
|
|
unsigned char mode;
|
|
|
|
unsigned char annunc;
|
|
|
|
unsigned char baud;
|
|
|
|
unsigned char card_ctrl;
|
|
|
|
unsigned char card_status;
|
|
|
|
unsigned char io_ctrl;
|
|
|
|
unsigned char rcs;
|
|
|
|
unsigned char tcs;
|
|
|
|
unsigned char rbr;
|
|
|
|
unsigned char tbr;
|
|
|
|
unsigned char sreq;
|
|
|
|
unsigned char ir_ctrl;
|
|
|
|
unsigned char base_off;
|
|
|
|
unsigned char lcr;
|
|
|
|
unsigned char lbr;
|
|
|
|
unsigned char scratch;
|
|
|
|
unsigned char base_nibble;
|
|
|
|
long disp_addr;
|
|
|
|
long line_offset;
|
|
|
|
long line_count;
|
|
|
|
long unknown;
|
|
|
|
unsigned char t1_ctrl;
|
|
|
|
unsigned char t2_ctrl;
|
|
|
|
long menu_addr;
|
|
|
|
long unknown2;
|
|
|
|
int timer1;
|
|
|
|
long timer2;
|
|
|
|
long t1_instr;
|
|
|
|
long t2_instr;
|
|
|
|
unsigned char* rom;
|
|
|
|
unsigned char* ram;
|
|
|
|
unsigned char* port1;
|
|
|
|
unsigned char* port2;
|
2015-07-26 11:16:05 +02:00
|
|
|
} old_saturn_t;
|
|
|
|
|
|
|
|
old_saturn_t old_saturn;
|
|
|
|
|
|
|
|
typedef struct saturn_0_3_0_t {
|
2023-04-27 12:15:59 +02:00
|
|
|
unsigned long magic;
|
|
|
|
char version[ 4 ];
|
|
|
|
unsigned char A[ 16 ], B[ 16 ], C[ 16 ], D[ 16 ];
|
|
|
|
word_20 d[ 2 ];
|
|
|
|
word_4 P;
|
|
|
|
word_20 PC;
|
|
|
|
unsigned char R0[ 16 ], R1[ 16 ], R2[ 16 ], R3[ 16 ], R4[ 16 ];
|
|
|
|
unsigned char IN[ 4 ];
|
|
|
|
unsigned char OUT[ 3 ];
|
|
|
|
word_1 CARRY;
|
|
|
|
unsigned char PSTAT[ NR_PSTAT ];
|
|
|
|
unsigned char XM, SB, SR, MP;
|
|
|
|
word_4 hexmode;
|
|
|
|
word_20 rstk[ NR_RSTK ];
|
|
|
|
short rstkp;
|
|
|
|
keystate_t keybuf;
|
|
|
|
unsigned char intenable;
|
|
|
|
unsigned char int_pending;
|
|
|
|
unsigned char kbd_ien;
|
|
|
|
word_20 configs[ NR_CONFIG ];
|
|
|
|
word_16 daisy_state;
|
|
|
|
word_20 ram32k;
|
|
|
|
word_20 devices;
|
|
|
|
word_4 disp_io;
|
|
|
|
word_4 contrast_ctrl;
|
|
|
|
word_8 disp_test;
|
|
|
|
word_16 crc;
|
|
|
|
word_4 power_status;
|
|
|
|
word_4 power_ctrl;
|
|
|
|
word_4 mode;
|
|
|
|
word_8 annunc;
|
|
|
|
word_4 baud;
|
|
|
|
word_4 card_ctrl;
|
|
|
|
word_4 card_status;
|
|
|
|
word_4 io_ctrl;
|
|
|
|
word_4 rcs;
|
|
|
|
word_4 tcs;
|
|
|
|
word_8 rbr;
|
|
|
|
word_8 tbr;
|
|
|
|
word_8 sreq;
|
|
|
|
word_4 ir_ctrl;
|
|
|
|
word_4 base_off;
|
|
|
|
word_4 lcr;
|
|
|
|
word_4 lbr;
|
|
|
|
word_4 scratch;
|
|
|
|
word_4 base_nibble;
|
|
|
|
word_20 disp_addr;
|
|
|
|
word_12 line_offset;
|
|
|
|
word_8 line_count;
|
|
|
|
word_16 unknown;
|
|
|
|
word_4 t1_ctrl;
|
|
|
|
word_4 t2_ctrl;
|
|
|
|
word_20 menu_addr;
|
|
|
|
word_8 unknown2;
|
|
|
|
char timer1;
|
|
|
|
word_32 timer2;
|
|
|
|
long t1_instr;
|
|
|
|
long t2_instr;
|
|
|
|
short t1_tick;
|
|
|
|
short t2_tick;
|
|
|
|
long i_per_s;
|
|
|
|
unsigned char* rom;
|
|
|
|
unsigned char* ram;
|
|
|
|
unsigned char* port1;
|
|
|
|
unsigned char* port2;
|
2015-07-26 11:16:05 +02:00
|
|
|
} saturn_0_3_0_t;
|
|
|
|
|
|
|
|
saturn_0_3_0_t saturn_0_3_0;
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
void saturn_config_init( void ) {
|
|
|
|
saturn.version[ 0 ] = VERSION_MAJOR;
|
|
|
|
saturn.version[ 1 ] = VERSION_MINOR;
|
|
|
|
saturn.version[ 2 ] = PATCHLEVEL;
|
2023-04-28 14:06:51 +02:00
|
|
|
// saturn.version[ 3 ] = COMPILE_VERSION;
|
2023-04-27 12:15:59 +02:00
|
|
|
memset( &device, 0, sizeof( device ) );
|
|
|
|
device.display_touched = 1;
|
|
|
|
device.contrast_touched = 1;
|
|
|
|
device.baud_touched = 1;
|
|
|
|
device.ann_touched = 1;
|
|
|
|
saturn.rcs = 0x0;
|
|
|
|
saturn.tcs = 0x0;
|
|
|
|
saturn.lbr = 0x0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
void init_saturn( void ) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
memset( &saturn, 0, sizeof( saturn ) - 4 * sizeof( unsigned char* ) );
|
|
|
|
saturn.PC = 0x00000;
|
|
|
|
saturn.magic = X48_MAGIC;
|
|
|
|
saturn.t1_tick = 8192;
|
|
|
|
saturn.t2_tick = 16;
|
|
|
|
saturn.i_per_s = 0;
|
|
|
|
saturn.version[ 0 ] = VERSION_MAJOR;
|
|
|
|
saturn.version[ 1 ] = VERSION_MINOR;
|
|
|
|
saturn.version[ 2 ] = PATCHLEVEL;
|
2023-04-28 14:06:51 +02:00
|
|
|
// saturn.version[ 3 ] = COMPILE_VERSION;
|
2023-04-27 12:15:59 +02:00
|
|
|
saturn.hexmode = HEX;
|
|
|
|
saturn.rstkp = -1;
|
|
|
|
saturn.intenable = 1;
|
|
|
|
saturn.int_pending = 0;
|
|
|
|
saturn.kbd_ien = 1;
|
|
|
|
saturn.timer1 = 0;
|
|
|
|
saturn.timer2 = 0x2000;
|
|
|
|
saturn.bank_switch = 0;
|
|
|
|
for ( i = 0; i < NR_MCTL; i++ ) {
|
|
|
|
if ( i == 0 )
|
|
|
|
saturn.mem_cntl[ i ].unconfigured = 1;
|
|
|
|
else if ( i == 5 )
|
|
|
|
saturn.mem_cntl[ i ].unconfigured = 0;
|
|
|
|
else
|
|
|
|
saturn.mem_cntl[ i ].unconfigured = 2;
|
|
|
|
saturn.mem_cntl[ i ].config[ 0 ] = 0;
|
|
|
|
saturn.mem_cntl[ i ].config[ 1 ] = 0;
|
|
|
|
}
|
|
|
|
dev_memory_init();
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 16:56:13 +02:00
|
|
|
void copy_old_saturn( old_saturn_t* old, saturn_t* newt ) {
|
2023-04-27 12:15:59 +02:00
|
|
|
int i;
|
|
|
|
|
2023-04-27 16:56:13 +02:00
|
|
|
memcpy( &( newt->A[ 0 ] ), &( old->A[ 0 ] ), 16 );
|
|
|
|
memcpy( &( newt->B[ 0 ] ), &( old->B[ 0 ] ), 16 );
|
|
|
|
memcpy( &( newt->C[ 0 ] ), &( old->C[ 0 ] ), 16 );
|
|
|
|
memcpy( &( newt->D[ 0 ] ), &( old->D[ 0 ] ), 16 );
|
|
|
|
newt->d[ 0 ] = old->d[ 0 ];
|
|
|
|
newt->d[ 1 ] = old->d[ 1 ];
|
|
|
|
newt->P = old->P;
|
|
|
|
newt->PC = old->PC;
|
|
|
|
memcpy( &( newt->R0[ 0 ] ), &( old->R0[ 0 ] ), 16 );
|
|
|
|
memcpy( &( newt->R1[ 0 ] ), &( old->R1[ 0 ] ), 16 );
|
|
|
|
memcpy( &( newt->R2[ 0 ] ), &( old->R2[ 0 ] ), 16 );
|
|
|
|
memcpy( &( newt->R3[ 0 ] ), &( old->R3[ 0 ] ), 16 );
|
|
|
|
memcpy( &( newt->R4[ 0 ] ), &( old->R4[ 0 ] ), 16 );
|
|
|
|
memcpy( &( newt->IN[ 0 ] ), &( old->IN[ 0 ] ), 4 );
|
|
|
|
memcpy( &( newt->OUT[ 0 ] ), &( old->OUT[ 0 ] ), 3 );
|
|
|
|
newt->CARRY = old->CARRY;
|
|
|
|
memcpy( &( newt->PSTAT[ 0 ] ), &( old->PSTAT[ 0 ] ), NR_PSTAT );
|
|
|
|
newt->XM = old->XM;
|
|
|
|
newt->SB = old->SB;
|
|
|
|
newt->SR = old->SR;
|
|
|
|
newt->MP = old->MP;
|
|
|
|
newt->hexmode = old->hexmode;
|
|
|
|
memcpy( &( newt->rstk[ 0 ] ), &( old->rstk[ 0 ] ),
|
2023-04-27 12:15:59 +02:00
|
|
|
NR_RSTK * sizeof( word_20 ) );
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->rstkp = old->rstkp;
|
2023-04-27 12:15:59 +02:00
|
|
|
for ( i = 0; i < 9; i++ ) {
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->keybuf.rows[ i ] = old->keybuf.rows[ i ];
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->intenable = old->intenable;
|
|
|
|
newt->int_pending = old->int_pending;
|
|
|
|
newt->kbd_ien = old->kbd_ien;
|
|
|
|
newt->disp_io = old->disp_io;
|
|
|
|
newt->contrast_ctrl = old->contrast_ctrl;
|
|
|
|
newt->disp_test = old->disp_test;
|
|
|
|
newt->crc = old->crc;
|
|
|
|
newt->power_status = old->power_status;
|
|
|
|
newt->power_ctrl = old->power_ctrl;
|
|
|
|
newt->mode = old->mode;
|
|
|
|
newt->annunc = old->annunc;
|
|
|
|
newt->baud = old->baud;
|
|
|
|
newt->card_ctrl = old->card_ctrl;
|
|
|
|
newt->card_status = old->card_status;
|
|
|
|
newt->io_ctrl = old->io_ctrl;
|
|
|
|
newt->rcs = old->rcs;
|
|
|
|
newt->tcs = old->tcs;
|
|
|
|
newt->rbr = old->rbr;
|
|
|
|
newt->tbr = old->tbr;
|
|
|
|
newt->sreq = old->sreq;
|
|
|
|
newt->ir_ctrl = old->ir_ctrl;
|
|
|
|
newt->base_off = old->base_off;
|
|
|
|
newt->lcr = old->lcr;
|
|
|
|
newt->lbr = old->lbr;
|
|
|
|
newt->scratch = old->scratch;
|
|
|
|
newt->base_nibble = old->base_nibble;
|
|
|
|
newt->disp_addr = old->disp_addr;
|
|
|
|
newt->line_offset = old->line_offset;
|
|
|
|
newt->line_count = old->line_count;
|
|
|
|
newt->unknown = old->unknown;
|
|
|
|
newt->t1_ctrl = old->t1_ctrl;
|
|
|
|
newt->t2_ctrl = old->t2_ctrl;
|
|
|
|
newt->menu_addr = old->menu_addr;
|
|
|
|
newt->unknown2 = old->unknown2;
|
|
|
|
newt->timer1 = old->timer1;
|
|
|
|
newt->timer2 = old->timer2;
|
|
|
|
newt->t1_instr = old->t1_instr;
|
|
|
|
newt->t2_instr = old->t2_instr;
|
|
|
|
newt->bank_switch = 0;
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( opt_gx ) {
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->mem_cntl[ 0 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 0 ].config[ 0 ] = 0x00100;
|
|
|
|
newt->mem_cntl[ 1 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 0 ] = 0x80000;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 1 ] = 0xc0000;
|
|
|
|
newt->mem_cntl[ 2 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 2 ].config[ 0 ] = 0x7f000;
|
|
|
|
newt->mem_cntl[ 2 ].config[ 1 ] = 0xff000;
|
|
|
|
newt->mem_cntl[ 3 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 3 ].config[ 0 ] = 0xc0000;
|
|
|
|
newt->mem_cntl[ 3 ].config[ 1 ] = 0xc0000;
|
|
|
|
newt->mem_cntl[ 4 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 4 ].config[ 0 ] = 0xc0000;
|
|
|
|
newt->mem_cntl[ 4 ].config[ 1 ] = 0xc0000;
|
|
|
|
newt->mem_cntl[ 5 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 5 ].config[ 0 ] = 0x00000;
|
|
|
|
newt->mem_cntl[ 5 ].config[ 1 ] = 0x00000;
|
2022-03-24 13:41:22 +01:00
|
|
|
} else {
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( old->devices == 0x100 ) {
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->mem_cntl[ 0 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 0 ].config[ 0 ] = old->devices;
|
2023-04-27 12:15:59 +02:00
|
|
|
} else {
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->mem_cntl[ 0 ].unconfigured = 1;
|
|
|
|
newt->mem_cntl[ 0 ].config[ 0 ] = 0x00000;
|
2023-04-27 12:15:59 +02:00
|
|
|
}
|
|
|
|
if ( old->ram32k == 0x70000 ) {
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->mem_cntl[ 1 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 0 ] = 0x70000;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 1 ] = 0xf0000;
|
2023-04-27 12:15:59 +02:00
|
|
|
} else if ( old->ram32k == 0xf0000 ) {
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->mem_cntl[ 1 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 0 ] = 0xf0000;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 1 ] = 0xf0000;
|
2023-04-27 12:15:59 +02:00
|
|
|
} else if ( old->ram32k == 0xfc000 ) {
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->mem_cntl[ 1 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 0 ] = 0x70000;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 1 ] = 0xfc000;
|
2023-04-27 12:15:59 +02:00
|
|
|
} else if ( old->ram32k == 0xfe000 ) {
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->mem_cntl[ 1 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 0 ] = 0x70000;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 1 ] = 0xfe000;
|
2023-04-27 12:15:59 +02:00
|
|
|
} else {
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->mem_cntl[ 1 ].unconfigured = 2;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 0 ] = 0x00000;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 1 ] = 0x00000;
|
2023-04-27 12:15:59 +02:00
|
|
|
}
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->mem_cntl[ 2 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 2 ].config[ 0 ] = 0x80000;
|
|
|
|
newt->mem_cntl[ 2 ].config[ 1 ] = 0xc0000;
|
|
|
|
newt->mem_cntl[ 3 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 3 ].config[ 0 ] = 0xc0000;
|
|
|
|
newt->mem_cntl[ 3 ].config[ 1 ] = 0xc0000;
|
|
|
|
newt->mem_cntl[ 4 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 4 ].config[ 0 ] = 0xd0000;
|
|
|
|
newt->mem_cntl[ 4 ].config[ 1 ] = 0xff000;
|
|
|
|
newt->mem_cntl[ 5 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 5 ].config[ 0 ] = 0x00000;
|
|
|
|
newt->mem_cntl[ 5 ].config[ 1 ] = 0x80000;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-27 16:56:13 +02:00
|
|
|
void copy_0_3_0_saturn( saturn_0_3_0_t* old, saturn_t* newt ) {
|
2023-04-27 12:15:59 +02:00
|
|
|
int i;
|
|
|
|
|
2023-04-27 16:56:13 +02:00
|
|
|
memcpy( &( newt->A[ 0 ] ), &( old->A[ 0 ] ), 16 );
|
|
|
|
memcpy( &( newt->B[ 0 ] ), &( old->B[ 0 ] ), 16 );
|
|
|
|
memcpy( &( newt->C[ 0 ] ), &( old->C[ 0 ] ), 16 );
|
|
|
|
memcpy( &( newt->D[ 0 ] ), &( old->D[ 0 ] ), 16 );
|
|
|
|
newt->d[ 0 ] = old->d[ 0 ];
|
|
|
|
newt->d[ 1 ] = old->d[ 1 ];
|
|
|
|
newt->P = old->P;
|
|
|
|
newt->PC = old->PC;
|
|
|
|
memcpy( &( newt->R0[ 0 ] ), &( old->R0[ 0 ] ), 16 );
|
|
|
|
memcpy( &( newt->R1[ 0 ] ), &( old->R1[ 0 ] ), 16 );
|
|
|
|
memcpy( &( newt->R2[ 0 ] ), &( old->R2[ 0 ] ), 16 );
|
|
|
|
memcpy( &( newt->R3[ 0 ] ), &( old->R3[ 0 ] ), 16 );
|
|
|
|
memcpy( &( newt->R4[ 0 ] ), &( old->R4[ 0 ] ), 16 );
|
|
|
|
memcpy( &( newt->IN[ 0 ] ), &( old->IN[ 0 ] ), 4 );
|
|
|
|
memcpy( &( newt->OUT[ 0 ] ), &( old->OUT[ 0 ] ), 3 );
|
|
|
|
newt->CARRY = old->CARRY;
|
|
|
|
memcpy( &( newt->PSTAT[ 0 ] ), &( old->PSTAT[ 0 ] ), NR_PSTAT );
|
|
|
|
newt->XM = old->XM;
|
|
|
|
newt->SB = old->SB;
|
|
|
|
newt->SR = old->SR;
|
|
|
|
newt->MP = old->MP;
|
|
|
|
newt->hexmode = old->hexmode;
|
|
|
|
memcpy( &( newt->rstk[ 0 ] ), &( old->rstk[ 0 ] ),
|
2023-04-27 12:15:59 +02:00
|
|
|
NR_RSTK * sizeof( word_20 ) );
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->rstkp = old->rstkp;
|
2023-04-27 12:15:59 +02:00
|
|
|
for ( i = 0; i < 9; i++ ) {
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->keybuf.rows[ i ] = old->keybuf.rows[ i ];
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->intenable = old->intenable;
|
|
|
|
newt->int_pending = old->int_pending;
|
|
|
|
newt->kbd_ien = old->kbd_ien;
|
|
|
|
newt->disp_io = old->disp_io;
|
|
|
|
newt->contrast_ctrl = old->contrast_ctrl;
|
|
|
|
newt->disp_test = old->disp_test;
|
|
|
|
newt->crc = old->crc;
|
|
|
|
newt->power_status = old->power_status;
|
|
|
|
newt->power_ctrl = old->power_ctrl;
|
|
|
|
newt->mode = old->mode;
|
|
|
|
newt->annunc = old->annunc;
|
|
|
|
newt->baud = old->baud;
|
|
|
|
newt->card_ctrl = old->card_ctrl;
|
|
|
|
newt->card_status = old->card_status;
|
|
|
|
newt->io_ctrl = old->io_ctrl;
|
|
|
|
newt->rcs = old->rcs;
|
|
|
|
newt->tcs = old->tcs;
|
|
|
|
newt->rbr = old->rbr;
|
|
|
|
newt->tbr = old->tbr;
|
|
|
|
newt->sreq = old->sreq;
|
|
|
|
newt->ir_ctrl = old->ir_ctrl;
|
|
|
|
newt->base_off = old->base_off;
|
|
|
|
newt->lcr = old->lcr;
|
|
|
|
newt->lbr = old->lbr;
|
|
|
|
newt->scratch = old->scratch;
|
|
|
|
newt->base_nibble = old->base_nibble;
|
|
|
|
newt->disp_addr = old->disp_addr;
|
|
|
|
newt->line_offset = old->line_offset;
|
|
|
|
newt->line_count = old->line_count;
|
|
|
|
newt->unknown = old->unknown;
|
|
|
|
newt->t1_ctrl = old->t1_ctrl;
|
|
|
|
newt->t2_ctrl = old->t2_ctrl;
|
|
|
|
newt->menu_addr = old->menu_addr;
|
|
|
|
newt->unknown2 = old->unknown2;
|
|
|
|
newt->timer1 = old->timer1;
|
|
|
|
newt->timer2 = old->timer2;
|
|
|
|
newt->t1_instr = old->t1_instr;
|
|
|
|
newt->t2_instr = old->t2_instr;
|
|
|
|
newt->t1_tick = old->t1_tick;
|
|
|
|
newt->t2_tick = old->t2_tick;
|
|
|
|
newt->i_per_s = old->i_per_s;
|
|
|
|
newt->bank_switch = 0;
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( opt_gx ) {
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->mem_cntl[ 0 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 0 ].config[ 0 ] = 0x00100;
|
|
|
|
newt->mem_cntl[ 1 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 0 ] = 0x80000;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 1 ] = 0xc0000;
|
|
|
|
newt->mem_cntl[ 2 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 2 ].config[ 0 ] = 0x7f000;
|
|
|
|
newt->mem_cntl[ 2 ].config[ 1 ] = 0xff000;
|
|
|
|
newt->mem_cntl[ 3 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 3 ].config[ 0 ] = 0xc0000;
|
|
|
|
newt->mem_cntl[ 3 ].config[ 1 ] = 0xc0000;
|
|
|
|
newt->mem_cntl[ 4 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 4 ].config[ 0 ] = 0xc0000;
|
|
|
|
newt->mem_cntl[ 4 ].config[ 1 ] = 0xc0000;
|
|
|
|
newt->mem_cntl[ 5 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 5 ].config[ 0 ] = 0x00000;
|
|
|
|
newt->mem_cntl[ 5 ].config[ 1 ] = 0x00000;
|
2022-03-24 13:41:22 +01:00
|
|
|
} else {
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( old->devices == 0x100 ) {
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->mem_cntl[ 0 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 0 ].config[ 0 ] = old->devices;
|
2023-04-27 12:15:59 +02:00
|
|
|
} else {
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->mem_cntl[ 0 ].unconfigured = 1;
|
|
|
|
newt->mem_cntl[ 0 ].config[ 0 ] = 0x00000;
|
2023-04-27 12:15:59 +02:00
|
|
|
}
|
|
|
|
if ( old->ram32k == 0x70000 ) {
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->mem_cntl[ 1 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 0 ] = 0x70000;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 1 ] = 0xf0000;
|
2023-04-27 12:15:59 +02:00
|
|
|
} else if ( old->ram32k == 0xf0000 ) {
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->mem_cntl[ 1 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 0 ] = 0xf0000;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 1 ] = 0xf0000;
|
2023-04-27 12:15:59 +02:00
|
|
|
} else if ( old->ram32k == 0xfc000 ) {
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->mem_cntl[ 1 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 0 ] = 0x70000;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 1 ] = 0xfc000;
|
2023-04-27 12:15:59 +02:00
|
|
|
} else if ( old->ram32k == 0xfe000 ) {
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->mem_cntl[ 1 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 0 ] = 0x70000;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 1 ] = 0xfe000;
|
2023-04-27 12:15:59 +02:00
|
|
|
} else {
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->mem_cntl[ 1 ].unconfigured = 2;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 0 ] = 0x00000;
|
|
|
|
newt->mem_cntl[ 1 ].config[ 1 ] = 0x00000;
|
2023-04-27 12:15:59 +02:00
|
|
|
}
|
2023-04-27 16:56:13 +02:00
|
|
|
newt->mem_cntl[ 2 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 2 ].config[ 0 ] = 0x80000;
|
|
|
|
newt->mem_cntl[ 2 ].config[ 1 ] = 0xc0000;
|
|
|
|
newt->mem_cntl[ 3 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 3 ].config[ 0 ] = 0xc0000;
|
|
|
|
newt->mem_cntl[ 3 ].config[ 1 ] = 0xc0000;
|
|
|
|
newt->mem_cntl[ 4 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 4 ].config[ 0 ] = 0xd0000;
|
|
|
|
newt->mem_cntl[ 4 ].config[ 1 ] = 0xff000;
|
|
|
|
newt->mem_cntl[ 5 ].unconfigured = 0;
|
|
|
|
newt->mem_cntl[ 5 ].config[ 0 ] = 0x00000;
|
|
|
|
newt->mem_cntl[ 5 ].config[ 1 ] = 0x80000;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int read_8( FILE* fp, word_8* var ) {
|
|
|
|
unsigned char tmp;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( fread( &tmp, 1, 1, fp ) != 1 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t read word_8\n", progname );
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
*var = tmp;
|
|
|
|
return 1;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int read_char( FILE* fp, char* var ) {
|
|
|
|
char tmp;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( fread( &tmp, 1, 1, fp ) != 1 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t read char\n", progname );
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
*var = tmp;
|
|
|
|
return 1;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int read_16( FILE* fp, word_16* var ) {
|
|
|
|
unsigned char tmp[ 2 ];
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( fread( &tmp[ 0 ], 1, 2, fp ) != 2 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t read word_16\n", progname );
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
*var = tmp[ 0 ] << 8;
|
|
|
|
*var |= tmp[ 1 ];
|
|
|
|
return 1;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int read_32( FILE* fp, word_32* var ) {
|
|
|
|
unsigned char tmp[ 4 ];
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( fread( &tmp[ 0 ], 1, 4, fp ) != 4 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t read word_32\n", progname );
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
*var = tmp[ 0 ] << 24;
|
|
|
|
*var |= tmp[ 1 ] << 16;
|
|
|
|
*var |= tmp[ 2 ] << 8;
|
|
|
|
*var |= tmp[ 3 ];
|
|
|
|
return 1;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int read_u_long( FILE* fp, unsigned long* var ) {
|
|
|
|
unsigned char tmp[ 4 ];
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( fread( &tmp[ 0 ], 1, 4, fp ) != 4 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t read unsigned long\n", progname );
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
*var = tmp[ 0 ] << 24;
|
|
|
|
*var |= tmp[ 1 ] << 16;
|
|
|
|
*var |= tmp[ 2 ] << 8;
|
|
|
|
*var |= tmp[ 3 ];
|
|
|
|
return 1;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int read_version_0_3_0_file( FILE* fp ) {
|
|
|
|
int i;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* version 0.3.x, read in the saturn_0_3_0_t struct
|
|
|
|
*/
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.A[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.B[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.C[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.D[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn_0_3_0.d[ 0 ] ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn_0_3_0.d[ 1 ] ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.P ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn_0_3_0.PC ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.R0[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.R1[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.R2[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.R3[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.R4[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 4; i++ )
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.IN[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 3; i++ )
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.OUT[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.CARRY ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < NR_PSTAT; i++ )
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.PSTAT[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.XM ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.SB ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.SR ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.MP ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.hexmode ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < NR_RSTK; i++ )
|
|
|
|
if ( !read_32( fp, &saturn_0_3_0.rstk[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_16( fp, ( word_16* )&saturn_0_3_0.rstkp ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 9; i++ )
|
|
|
|
if ( !read_16( fp, ( word_16* )&saturn_0_3_0.keybuf.rows[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.intenable ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.int_pending ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.kbd_ien ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < NR_CONFIG; i++ )
|
|
|
|
if ( !read_32( fp, &saturn_0_3_0.configs[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_16( fp, ( word_16* )&saturn_0_3_0.daisy_state ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn_0_3_0.ram32k ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn_0_3_0.devices ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.disp_io ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.contrast_ctrl ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.disp_test ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_16( fp, &saturn_0_3_0.crc ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.power_status ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.power_ctrl ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.mode ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.annunc ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.baud ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.card_ctrl ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.card_status ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.io_ctrl ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.rcs ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.tcs ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.rbr ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.tbr ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.sreq ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.ir_ctrl ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.base_off ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.lcr ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.lbr ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.scratch ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.base_nibble ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn_0_3_0.disp_addr ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_16( fp, &saturn_0_3_0.line_offset ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.line_count ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_16( fp, &saturn_0_3_0.unknown ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.t1_ctrl ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.t2_ctrl ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn_0_3_0.menu_addr ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn_0_3_0.unknown2 ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_char( fp, &saturn_0_3_0.timer1 ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn_0_3_0.timer2 ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn_0_3_0.t1_instr ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn_0_3_0.t2_instr ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_16( fp, ( word_16* )&saturn_0_3_0.t1_tick ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_16( fp, ( word_16* )&saturn_0_3_0.t2_tick ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn_0_3_0.i_per_s ) )
|
|
|
|
return 0;
|
|
|
|
return 1;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int read_version_0_4_0_file( FILE* fp ) {
|
|
|
|
int i;
|
2022-03-24 13:41:22 +01:00
|
|
|
|
|
|
|
/*
|
2023-04-27 12:15:59 +02:00
|
|
|
* version 0.4.x, read in the saturn_t struct
|
2022-03-24 13:41:22 +01:00
|
|
|
*/
|
2023-04-27 12:15:59 +02:00
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
if ( !read_8( fp, &saturn.A[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
if ( !read_8( fp, &saturn.B[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
if ( !read_8( fp, &saturn.C[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
if ( !read_8( fp, &saturn.D[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn.d[ 0 ] ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn.d[ 1 ] ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.P ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn.PC ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
if ( !read_8( fp, &saturn.R0[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
if ( !read_8( fp, &saturn.R1[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
if ( !read_8( fp, &saturn.R2[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
if ( !read_8( fp, &saturn.R3[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
if ( !read_8( fp, &saturn.R4[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 4; i++ )
|
|
|
|
if ( !read_8( fp, &saturn.IN[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 3; i++ )
|
|
|
|
if ( !read_8( fp, &saturn.OUT[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.CARRY ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < NR_PSTAT; i++ )
|
|
|
|
if ( !read_8( fp, &saturn.PSTAT[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.XM ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.SB ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.SR ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.MP ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.hexmode ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < NR_RSTK; i++ )
|
|
|
|
if ( !read_32( fp, &saturn.rstk[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_16( fp, ( word_16* )&saturn.rstkp ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < 9; i++ )
|
|
|
|
if ( !read_16( fp, ( word_16* )&saturn.keybuf.rows[ i ] ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.intenable ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.int_pending ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.kbd_ien ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.disp_io ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.contrast_ctrl ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.disp_test ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_16( fp, &saturn.crc ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.power_status ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.power_ctrl ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.mode ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.annunc ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.baud ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.card_ctrl ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.card_status ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.io_ctrl ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.rcs ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.tcs ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.rbr ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.tbr ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.sreq ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.ir_ctrl ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.base_off ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.lcr ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.lbr ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.scratch ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.base_nibble ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn.disp_addr ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_16( fp, &saturn.line_offset ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.line_count ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_16( fp, &saturn.unknown ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.t1_ctrl ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.t2_ctrl ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn.menu_addr ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_8( fp, &saturn.unknown2 ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_char( fp, &saturn.timer1 ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn.timer2 ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn.t1_instr ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn.t2_instr ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_16( fp, ( word_16* )&saturn.t1_tick ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_16( fp, ( word_16* )&saturn.t2_tick ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn.i_per_s ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_16( fp, ( word_16* )&saturn.bank_switch ) )
|
|
|
|
return 0;
|
|
|
|
for ( i = 0; i < NR_MCTL; i++ ) {
|
|
|
|
if ( !read_16( fp, &saturn.mem_cntl[ i ].unconfigured ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn.mem_cntl[ i ].config[ 0 ] ) )
|
|
|
|
return 0;
|
|
|
|
if ( !read_32( fp, &saturn.mem_cntl[ i ].config[ 1 ] ) )
|
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
return 1;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int read_mem_file( char* name, word_4* mem, int size ) {
|
|
|
|
struct stat st;
|
|
|
|
FILE* fp;
|
|
|
|
word_8* tmp_mem;
|
|
|
|
word_8 byte;
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
if ( NULL == ( fp = fopen( name, "r" ) ) ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t open %s\n", progname, name );
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( stat( name, &st ) < 0 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t stat %s\n", progname, name );
|
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( st.st_size == size ) {
|
|
|
|
/*
|
|
|
|
* size is same as memory size, old version file
|
|
|
|
*/
|
|
|
|
if ( fread( mem, 1, ( size_t )size, fp ) != size ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t read %s\n", progname, name );
|
|
|
|
fclose( fp );
|
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2022-03-24 13:41:22 +01:00
|
|
|
} else {
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* size is different, check size and decompress memory
|
|
|
|
*/
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( st.st_size != size / 2 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr,
|
|
|
|
"%s: strange size %s, expected %d, found %ld\n",
|
|
|
|
progname, name, size / 2, st.st_size );
|
|
|
|
fclose( fp );
|
|
|
|
return 0;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( NULL == ( tmp_mem = ( word_8* )malloc( ( size_t )st.st_size ) ) ) {
|
|
|
|
for ( i = 0, j = 0; i < size / 2; i++ ) {
|
|
|
|
if ( 1 != fread( &byte, 1, 1, fp ) ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t read %s\n", progname,
|
|
|
|
name );
|
|
|
|
fclose( fp );
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
mem[ j++ ] = ( word_4 )( ( int )byte & 0xf );
|
|
|
|
mem[ j++ ] = ( word_4 )( ( ( int )byte >> 4 ) & 0xf );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( fread( tmp_mem, 1, ( size_t )size / 2, fp ) != size / 2 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t read %s\n", progname, name );
|
|
|
|
fclose( fp );
|
|
|
|
free( tmp_mem );
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( i = 0, j = 0; i < size / 2; i++ ) {
|
|
|
|
mem[ j++ ] = ( word_4 )( ( int )tmp_mem[ i ] & 0xf );
|
|
|
|
mem[ j++ ] = ( word_4 )( ( ( int )tmp_mem[ i ] >> 4 ) & 0xf );
|
|
|
|
}
|
|
|
|
|
|
|
|
free( tmp_mem );
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
fclose( fp );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( verbose )
|
|
|
|
printf( "%s: read %s\n", progname, name );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
return 1;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int read_rom( const char* fname ) {
|
|
|
|
int ram_size;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( !read_rom_file( romFileName, &saturn.rom, &rom_size ) )
|
|
|
|
return 0;
|
|
|
|
dev_memory_init();
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( opt_gx )
|
|
|
|
ram_size = RAM_SIZE_GX;
|
|
|
|
else
|
|
|
|
ram_size = RAM_SIZE_SX;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( NULL == ( saturn.ram = ( word_4* )malloc( ram_size ) ) ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t malloc RAM\n", progname );
|
|
|
|
return 0;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
memset( saturn.ram, 0, ram_size );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
port1_size = 0;
|
|
|
|
port1_mask = 0;
|
|
|
|
port1_is_ram = 0;
|
|
|
|
saturn.port1 = ( unsigned char* )0;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
port2_size = 0;
|
|
|
|
port2_mask = 0;
|
|
|
|
port2_is_ram = 0;
|
|
|
|
saturn.port2 = ( unsigned char* )0;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
saturn.card_status = 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
return 1;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
void get_home_directory( char* path ) {
|
|
|
|
char* p;
|
|
|
|
struct passwd* pwd;
|
|
|
|
|
|
|
|
if ( homeDirectory[ 0 ] == '/' ) {
|
|
|
|
strcpy( path, homeDirectory );
|
2022-03-24 13:41:22 +01:00
|
|
|
} else {
|
2023-04-27 12:15:59 +02:00
|
|
|
p = getenv( "HOME" );
|
|
|
|
if ( p ) {
|
|
|
|
strcpy( path, p );
|
|
|
|
strcat( path, "/" );
|
|
|
|
} else {
|
|
|
|
pwd = getpwuid( getuid() );
|
|
|
|
if ( pwd ) {
|
|
|
|
strcpy( path, pwd->pw_dir );
|
|
|
|
strcat( path, "/" );
|
|
|
|
} else {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr,
|
|
|
|
"%s: can\'t figure out your home directory, "
|
|
|
|
"trying /tmp\n",
|
|
|
|
progname );
|
|
|
|
strcpy( path, "/tmp" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
strcat( path, homeDirectory );
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int read_files( void ) {
|
|
|
|
char path[ 1024 ];
|
|
|
|
char fnam[ 1024 ];
|
|
|
|
unsigned long v1, v2;
|
|
|
|
int i, read_version;
|
|
|
|
int ram_size;
|
|
|
|
struct stat st;
|
|
|
|
FILE* fp;
|
|
|
|
|
|
|
|
get_home_directory( path );
|
|
|
|
strcat( path, "/" );
|
|
|
|
|
|
|
|
saturn.rom = ( word_4* )NULL;
|
|
|
|
strcpy( fnam, path );
|
|
|
|
strcat( fnam, "rom" );
|
|
|
|
if ( !read_rom_file( fnam, &saturn.rom, &rom_size ) )
|
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
rom_is_new = 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
strcpy( fnam, path );
|
|
|
|
strcat( fnam, "hp48" );
|
|
|
|
if ( NULL == ( fp = fopen( fnam, "r" ) ) ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t open %s\n", progname, fnam );
|
|
|
|
return 0;
|
2022-03-24 13:41:22 +01:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2022-03-24 13:41:22 +01:00
|
|
|
/*
|
2023-04-27 12:15:59 +02:00
|
|
|
* ok, file is open, try to read the MAGIC number
|
2022-03-24 13:41:22 +01:00
|
|
|
*/
|
2023-04-27 12:15:59 +02:00
|
|
|
read_u_long( fp, &saturn.magic );
|
2022-03-24 11:19:16 +01:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( X48_MAGIC != saturn.magic ) {
|
2022-03-24 13:41:22 +01:00
|
|
|
/*
|
2023-04-27 12:15:59 +02:00
|
|
|
* no MAGIC number, try to read old format file
|
2022-03-24 13:41:22 +01:00
|
|
|
*/
|
2023-04-27 12:15:59 +02:00
|
|
|
fseek( fp, 0, SEEK_SET );
|
|
|
|
if ( fread( ( char* )&old_saturn, 1, sizeof( old_saturn ), fp ) ==
|
|
|
|
sizeof( old_saturn ) ) {
|
|
|
|
/*
|
|
|
|
* seems to work
|
|
|
|
*/
|
|
|
|
copy_old_saturn( &old_saturn, &saturn );
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: %s seems to be an old version file\n",
|
|
|
|
progname, fnam );
|
|
|
|
saturn.magic = X48_MAGIC;
|
|
|
|
saturn.t1_tick = 8192;
|
|
|
|
saturn.t2_tick = 16;
|
|
|
|
saturn.i_per_s = 0;
|
|
|
|
saturn.version[ 0 ] = VERSION_MAJOR;
|
|
|
|
saturn.version[ 1 ] = VERSION_MINOR;
|
|
|
|
saturn.version[ 2 ] = PATCHLEVEL;
|
2023-04-28 14:06:51 +02:00
|
|
|
// saturn.version[ 3 ] = COMPILE_VERSION;
|
2022-03-24 13:41:22 +01:00
|
|
|
} else {
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* no, initialize
|
|
|
|
*/
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t handle %s\n", progname, fnam );
|
|
|
|
init_saturn();
|
2022-03-24 13:41:22 +01:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
} else {
|
2022-03-24 13:41:22 +01:00
|
|
|
/*
|
2023-04-27 12:15:59 +02:00
|
|
|
* MAGIC ok, read and compare the version
|
2022-03-24 13:41:22 +01:00
|
|
|
*/
|
2023-04-27 12:15:59 +02:00
|
|
|
read_version = 1;
|
|
|
|
for ( i = 0; i < 4; i++ ) {
|
|
|
|
if ( !read_char( fp, &saturn.version[ i ] ) ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t read version\n", progname );
|
|
|
|
read_version = 0;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
|
|
|
|
if ( read_version ) {
|
|
|
|
v1 = ( ( int )saturn.version[ 0 ] & 0xff ) << 24;
|
|
|
|
v1 |= ( ( int )saturn.version[ 1 ] & 0xff ) << 16;
|
|
|
|
v1 |= ( ( int )saturn.version[ 2 ] & 0xff ) << 8;
|
|
|
|
v1 |= ( ( int )saturn.version[ 3 ] & 0xff );
|
|
|
|
v2 = ( ( int )VERSION_MAJOR & 0xff ) << 24;
|
|
|
|
v2 |= ( ( int )VERSION_MINOR & 0xff ) << 16;
|
|
|
|
v2 |= ( ( int )PATCHLEVEL & 0xff ) << 8;
|
2023-04-28 14:06:51 +02:00
|
|
|
// v2 |= ( ( int )COMPILE_VERSION & 0xff );
|
2023-04-27 12:15:59 +02:00
|
|
|
|
|
|
|
if ( ( v1 & 0xffffff00 ) < ( v2 & 0xffffff00 ) ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr,
|
|
|
|
"%s: %s is a version %d.%d.%d file, converting\n",
|
|
|
|
progname, fnam, saturn.version[ 0 ],
|
|
|
|
saturn.version[ 1 ], saturn.version[ 2 ] );
|
|
|
|
} else if ( ( v2 & 0xffffff00 ) < ( v1 & 0xffffff00 ) ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr,
|
|
|
|
"%s: %s is a version %d.%d.%d file, trying ...\n",
|
|
|
|
progname, fnam, saturn.version[ 0 ],
|
|
|
|
saturn.version[ 1 ], saturn.version[ 2 ] );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( v1 < 0x00040000 ) {
|
|
|
|
/*
|
|
|
|
* read version < 0.4 file
|
|
|
|
*/
|
|
|
|
if ( !read_version_0_3_0_file( fp ) ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t handle %s\n", progname,
|
|
|
|
fnam );
|
|
|
|
init_saturn();
|
|
|
|
} else {
|
|
|
|
copy_0_3_0_saturn( &saturn_0_3_0, &saturn );
|
|
|
|
if ( verbose )
|
|
|
|
printf( "%s: read %s\n", progname, fnam );
|
|
|
|
}
|
|
|
|
} else if ( v1 <= v2 ) {
|
|
|
|
/*
|
|
|
|
* read latest version file
|
|
|
|
*/
|
|
|
|
if ( !read_version_0_4_0_file( fp ) ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t handle %s\n", progname,
|
|
|
|
fnam );
|
|
|
|
init_saturn();
|
|
|
|
} else if ( verbose ) {
|
|
|
|
printf( "%s: read %s\n", progname, fnam );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* try to read latest version file
|
|
|
|
*/
|
|
|
|
if ( !read_version_0_4_0_file( fp ) ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t handle %s\n", progname,
|
|
|
|
fnam );
|
|
|
|
init_saturn();
|
|
|
|
} else if ( verbose ) {
|
|
|
|
printf( "%s: read %s\n", progname, fnam );
|
|
|
|
}
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
fclose( fp );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
dev_memory_init();
|
|
|
|
|
|
|
|
saturn_config_init();
|
|
|
|
|
|
|
|
if ( opt_gx )
|
|
|
|
ram_size = RAM_SIZE_GX;
|
|
|
|
else
|
|
|
|
ram_size = RAM_SIZE_SX;
|
|
|
|
|
|
|
|
saturn.ram = ( word_4* )NULL;
|
|
|
|
if ( NULL == ( saturn.ram = ( word_4* )malloc( ram_size ) ) ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t malloc RAM[%d]\n", progname,
|
|
|
|
ram_size );
|
|
|
|
exit( 1 );
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
|
|
|
|
strcpy( fnam, path );
|
|
|
|
strcat( fnam, "ram" );
|
|
|
|
if ( ( fp = fopen( fnam, "r" ) ) == NULL ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t open %s\n", progname, fnam );
|
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( !read_mem_file( fnam, saturn.ram, ram_size ) )
|
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
saturn.card_status = 0;
|
|
|
|
|
|
|
|
port1_size = 0;
|
|
|
|
port1_mask = 0;
|
|
|
|
port1_is_ram = 0;
|
|
|
|
saturn.port1 = ( unsigned char* )0;
|
|
|
|
|
|
|
|
strcpy( fnam, path );
|
|
|
|
strcat( fnam, "port1" );
|
|
|
|
if ( stat( fnam, &st ) >= 0 ) {
|
|
|
|
port1_size = 2 * st.st_size;
|
|
|
|
if ( ( port1_size == 0x10000 ) || ( port1_size == 0x40000 ) ) {
|
|
|
|
if ( NULL == ( saturn.port1 = ( word_4* )malloc( port1_size ) ) ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t malloc PORT1[%ld]\n", progname,
|
|
|
|
port1_size );
|
|
|
|
} else if ( !read_mem_file( fnam, saturn.port1, port1_size ) ) {
|
|
|
|
port1_size = 0;
|
|
|
|
port1_is_ram = 0;
|
|
|
|
} else {
|
|
|
|
port1_is_ram = ( st.st_mode & S_IWUSR ) ? 1 : 0;
|
|
|
|
port1_mask = port1_size - 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( opt_gx ) {
|
|
|
|
saturn.card_status |= ( port1_size > 0 ) ? 2 : 0;
|
|
|
|
saturn.card_status |= port1_is_ram ? 8 : 0;
|
|
|
|
} else {
|
|
|
|
saturn.card_status |= ( port1_size > 0 ) ? 1 : 0;
|
|
|
|
saturn.card_status |= port1_is_ram ? 4 : 0;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
port2_size = 0;
|
|
|
|
port2_mask = 0;
|
|
|
|
port2_is_ram = 0;
|
|
|
|
saturn.port2 = ( unsigned char* )0;
|
|
|
|
|
|
|
|
strcpy( fnam, path );
|
|
|
|
strcat( fnam, "port2" );
|
|
|
|
if ( stat( fnam, &st ) >= 0 ) {
|
|
|
|
port2_size = 2 * st.st_size;
|
|
|
|
if ( ( opt_gx && ( ( port2_size % 0x40000 ) == 0 ) ) ||
|
|
|
|
( !opt_gx &&
|
|
|
|
( ( port2_size == 0x10000 ) || ( port2_size == 0x40000 ) ) ) ) {
|
|
|
|
if ( NULL == ( saturn.port2 = ( word_4* )malloc( port2_size ) ) ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t malloc PORT2[%ld]\n", progname,
|
|
|
|
port2_size );
|
|
|
|
} else if ( !read_mem_file( fnam, saturn.port2, port2_size ) ) {
|
|
|
|
port2_size = 0;
|
|
|
|
port2_is_ram = 0;
|
|
|
|
} else {
|
|
|
|
port2_is_ram = ( st.st_mode & S_IWUSR ) ? 1 : 0;
|
|
|
|
port2_mask = port2_size - 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( opt_gx ) {
|
|
|
|
saturn.card_status |= ( port2_size > 0 ) ? 1 : 0;
|
|
|
|
saturn.card_status |= port2_is_ram ? 4 : 0;
|
|
|
|
} else {
|
|
|
|
saturn.card_status |= ( port2_size > 0 ) ? 2 : 0;
|
|
|
|
saturn.card_status |= port2_is_ram ? 8 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int write_8( FILE* fp, word_8* var ) {
|
|
|
|
unsigned char tmp;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
tmp = *var;
|
|
|
|
if ( fwrite( &tmp, 1, 1, fp ) != 1 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t write word_8\n", progname );
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int write_char( FILE* fp, char* var ) {
|
|
|
|
char tmp;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
tmp = *var;
|
|
|
|
if ( fwrite( &tmp, 1, 1, fp ) != 1 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t write char\n", progname );
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int write_16( FILE* fp, word_16* var ) {
|
|
|
|
unsigned char tmp[ 2 ];
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
tmp[ 0 ] = ( *var >> 8 ) & 0xff;
|
|
|
|
tmp[ 1 ] = *var & 0xff;
|
|
|
|
if ( fwrite( &tmp[ 0 ], 1, 2, fp ) != 2 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t write word_16\n", progname );
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int write_32( FILE* fp, word_32* var ) {
|
|
|
|
unsigned char tmp[ 4 ];
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
tmp[ 0 ] = ( *var >> 24 ) & 0xff;
|
|
|
|
tmp[ 1 ] = ( *var >> 16 ) & 0xff;
|
|
|
|
tmp[ 2 ] = ( *var >> 8 ) & 0xff;
|
|
|
|
tmp[ 3 ] = *var & 0xff;
|
|
|
|
if ( fwrite( &tmp[ 0 ], 1, 4, fp ) != 4 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t write word_32\n", progname );
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int write_u_long( FILE* fp, unsigned long* var ) {
|
|
|
|
unsigned char tmp[ 4 ];
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
tmp[ 0 ] = ( *var >> 24 ) & 0xff;
|
|
|
|
tmp[ 1 ] = ( *var >> 16 ) & 0xff;
|
|
|
|
tmp[ 2 ] = ( *var >> 8 ) & 0xff;
|
|
|
|
tmp[ 3 ] = *var & 0xff;
|
|
|
|
if ( fwrite( &tmp[ 0 ], 1, 4, fp ) != 4 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t write unsigned long\n", progname );
|
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
return 1;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int write_mem_file( char* name, word_4* mem, int size ) {
|
|
|
|
FILE* fp;
|
|
|
|
word_8* tmp_mem;
|
|
|
|
word_8 byte;
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
if ( NULL == ( fp = fopen( name, "w" ) ) ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t open %s\n", progname, name );
|
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( NULL == ( tmp_mem = ( word_8* )malloc( ( size_t )size / 2 ) ) ) {
|
|
|
|
for ( i = 0, j = 0; i < size / 2; i++ ) {
|
|
|
|
byte = ( mem[ j++ ] & 0x0f );
|
|
|
|
byte |= ( mem[ j++ ] << 4 ) & 0xf0;
|
|
|
|
if ( 1 != fwrite( &byte, 1, 1, fp ) ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t write %s\n", progname, name );
|
|
|
|
fclose( fp );
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for ( i = 0, j = 0; i < size / 2; i++ ) {
|
|
|
|
tmp_mem[ i ] = ( mem[ j++ ] & 0x0f );
|
|
|
|
tmp_mem[ i ] |= ( mem[ j++ ] << 4 ) & 0xf0;
|
|
|
|
}
|
2022-03-24 13:41:22 +01:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( fwrite( tmp_mem, 1, ( size_t )size / 2, fp ) != size / 2 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t write %s\n", progname, name );
|
|
|
|
fclose( fp );
|
|
|
|
free( tmp_mem );
|
|
|
|
return 0;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
free( tmp_mem );
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose( fp );
|
|
|
|
|
|
|
|
if ( verbose )
|
|
|
|
printf( "%s: wrote %s\n", progname, name );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
return 1;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int write_files( void ) {
|
|
|
|
char path[ 1024 ];
|
|
|
|
char fnam[ 1024 ];
|
|
|
|
struct stat st;
|
|
|
|
int i, make_dir;
|
|
|
|
int ram_size;
|
|
|
|
FILE* fp;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
make_dir = 0;
|
|
|
|
get_home_directory( path );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( stat( path, &st ) == -1 ) {
|
|
|
|
if ( errno == ENOENT ) {
|
|
|
|
make_dir = 1;
|
|
|
|
} else {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t stat %s, saving to /tmp\n",
|
|
|
|
progname, path );
|
|
|
|
strcpy( path, "/tmp" );
|
|
|
|
}
|
2022-03-24 13:41:22 +01:00
|
|
|
} else {
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( !S_ISDIR( st.st_mode ) ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: %s is no directory, saving to /tmp\n",
|
|
|
|
progname, path );
|
|
|
|
strcpy( path, "/tmp" );
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
|
|
|
|
if ( make_dir ) {
|
|
|
|
if ( mkdir( path, 0777 ) == -1 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t mkdir %s, saving to /tmp\n",
|
|
|
|
progname, path );
|
|
|
|
strcpy( path, "/tmp" );
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
|
|
|
|
strcat( path, "/" );
|
|
|
|
|
|
|
|
strcpy( fnam, path );
|
|
|
|
strcat( fnam, "hp48" );
|
|
|
|
if ( ( fp = fopen( fnam, "w" ) ) == NULL ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t open %s, no saving done\n", progname,
|
|
|
|
fnam );
|
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* write the hp48 config file
|
|
|
|
*/
|
|
|
|
write_32( fp, ( word_32* )&saturn.magic );
|
|
|
|
for ( i = 0; i < 4; i++ )
|
|
|
|
write_char( fp, &saturn.version[ i ] );
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
write_8( fp, &saturn.A[ i ] );
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
write_8( fp, &saturn.B[ i ] );
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
write_8( fp, &saturn.C[ i ] );
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
write_8( fp, &saturn.D[ i ] );
|
|
|
|
write_32( fp, &saturn.d[ 0 ] );
|
|
|
|
write_32( fp, &saturn.d[ 1 ] );
|
|
|
|
write_8( fp, &saturn.P );
|
|
|
|
write_32( fp, &saturn.PC );
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
write_8( fp, &saturn.R0[ i ] );
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
write_8( fp, &saturn.R1[ i ] );
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
write_8( fp, &saturn.R2[ i ] );
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
write_8( fp, &saturn.R3[ i ] );
|
|
|
|
for ( i = 0; i < 16; i++ )
|
|
|
|
write_8( fp, &saturn.R4[ i ] );
|
|
|
|
for ( i = 0; i < 4; i++ )
|
|
|
|
write_8( fp, &saturn.IN[ i ] );
|
|
|
|
for ( i = 0; i < 3; i++ )
|
|
|
|
write_8( fp, &saturn.OUT[ i ] );
|
|
|
|
write_8( fp, &saturn.CARRY );
|
|
|
|
for ( i = 0; i < NR_PSTAT; i++ )
|
|
|
|
write_8( fp, &saturn.PSTAT[ i ] );
|
|
|
|
write_8( fp, &saturn.XM );
|
|
|
|
write_8( fp, &saturn.SB );
|
|
|
|
write_8( fp, &saturn.SR );
|
|
|
|
write_8( fp, &saturn.MP );
|
|
|
|
write_8( fp, &saturn.hexmode );
|
|
|
|
for ( i = 0; i < NR_RSTK; i++ )
|
|
|
|
write_32( fp, &saturn.rstk[ i ] );
|
|
|
|
write_16( fp, ( word_16* )&saturn.rstkp );
|
|
|
|
for ( i = 0; i < 9; i++ )
|
|
|
|
write_16( fp, ( word_16* )&saturn.keybuf.rows[ i ] );
|
|
|
|
write_8( fp, &saturn.intenable );
|
|
|
|
write_8( fp, &saturn.int_pending );
|
|
|
|
write_8( fp, &saturn.kbd_ien );
|
|
|
|
write_8( fp, &saturn.disp_io );
|
|
|
|
write_8( fp, &saturn.contrast_ctrl );
|
|
|
|
write_8( fp, &saturn.disp_test );
|
|
|
|
write_16( fp, &saturn.crc );
|
|
|
|
write_8( fp, &saturn.power_status );
|
|
|
|
write_8( fp, &saturn.power_ctrl );
|
|
|
|
write_8( fp, &saturn.mode );
|
|
|
|
write_8( fp, &saturn.annunc );
|
|
|
|
write_8( fp, &saturn.baud );
|
|
|
|
write_8( fp, &saturn.card_ctrl );
|
|
|
|
write_8( fp, &saturn.card_status );
|
|
|
|
write_8( fp, &saturn.io_ctrl );
|
|
|
|
write_8( fp, &saturn.rcs );
|
|
|
|
write_8( fp, &saturn.tcs );
|
|
|
|
write_8( fp, &saturn.rbr );
|
|
|
|
write_8( fp, &saturn.tbr );
|
|
|
|
write_8( fp, &saturn.sreq );
|
|
|
|
write_8( fp, &saturn.ir_ctrl );
|
|
|
|
write_8( fp, &saturn.base_off );
|
|
|
|
write_8( fp, &saturn.lcr );
|
|
|
|
write_8( fp, &saturn.lbr );
|
|
|
|
write_8( fp, &saturn.scratch );
|
|
|
|
write_8( fp, &saturn.base_nibble );
|
|
|
|
write_32( fp, &saturn.disp_addr );
|
|
|
|
write_16( fp, &saturn.line_offset );
|
|
|
|
write_8( fp, &saturn.line_count );
|
|
|
|
write_16( fp, &saturn.unknown );
|
|
|
|
write_8( fp, &saturn.t1_ctrl );
|
|
|
|
write_8( fp, &saturn.t2_ctrl );
|
|
|
|
write_32( fp, &saturn.menu_addr );
|
|
|
|
write_8( fp, &saturn.unknown2 );
|
|
|
|
write_char( fp, &saturn.timer1 );
|
|
|
|
write_32( fp, &saturn.timer2 );
|
|
|
|
write_32( fp, &saturn.t1_instr );
|
|
|
|
write_32( fp, &saturn.t2_instr );
|
|
|
|
write_16( fp, ( word_16* )&saturn.t1_tick );
|
|
|
|
write_16( fp, ( word_16* )&saturn.t2_tick );
|
|
|
|
write_32( fp, &saturn.i_per_s );
|
|
|
|
write_16( fp, &saturn.bank_switch );
|
|
|
|
for ( i = 0; i < NR_MCTL; i++ ) {
|
|
|
|
write_16( fp, &saturn.mem_cntl[ i ].unconfigured );
|
|
|
|
write_32( fp, &saturn.mem_cntl[ i ].config[ 0 ] );
|
|
|
|
write_32( fp, &saturn.mem_cntl[ i ].config[ 1 ] );
|
|
|
|
}
|
|
|
|
fclose( fp );
|
|
|
|
if ( verbose )
|
|
|
|
printf( "%s: wrote %s\n", progname, fnam );
|
|
|
|
|
|
|
|
if ( rom_is_new ) {
|
|
|
|
strcpy( fnam, path );
|
|
|
|
strcat( fnam, "rom" );
|
|
|
|
if ( !write_mem_file( fnam, saturn.rom, rom_size ) )
|
|
|
|
return 0;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( opt_gx )
|
|
|
|
ram_size = RAM_SIZE_GX;
|
|
|
|
else
|
|
|
|
ram_size = RAM_SIZE_SX;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
strcpy( fnam, path );
|
|
|
|
strcat( fnam, "ram" );
|
|
|
|
if ( !write_mem_file( fnam, saturn.ram, ram_size ) )
|
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( ( port1_size > 0 ) && port1_is_ram ) {
|
|
|
|
strcpy( fnam, path );
|
|
|
|
strcat( fnam, "port1" );
|
|
|
|
if ( !write_mem_file( fnam, saturn.port1, port1_size ) )
|
|
|
|
return 0;
|
2022-03-24 13:41:22 +01:00
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( ( port2_size > 0 ) && port2_is_ram ) {
|
|
|
|
strcpy( fnam, path );
|
|
|
|
strcat( fnam, "port2" );
|
|
|
|
if ( !write_mem_file( fnam, saturn.port2, port2_size ) )
|
|
|
|
return 0;
|
|
|
|
}
|
2022-03-24 11:19:16 +01:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int init_emulator( void ) {
|
|
|
|
if ( !initialize )
|
|
|
|
if ( read_files() ) {
|
|
|
|
if ( resetOnStartup )
|
|
|
|
saturn.PC = 0x00000;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
init_saturn();
|
|
|
|
if ( !read_rom( romFileName ) )
|
|
|
|
exit( 1 );
|
|
|
|
|
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
void init_active_stuff( void ) {
|
|
|
|
serial_init();
|
|
|
|
init_annunc();
|
|
|
|
init_display();
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int exit_emulator( void ) {
|
|
|
|
write_files();
|
|
|
|
return 1;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|