/* * This file is part of x48, an emulator of the HP-48sx Calculator. * Copyright (C) 1994 Eddie C. Dost (ecd@dressler.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* $Log: init.c,v $ * Revision 1.13 1995/01/11 18:20:01 ecd * major update to support HP48 G/GX * * Revision 1.12 1994/12/07 20:20:50 ecd * minor fixes * * Revision 1.12 1994/12/07 20:20:50 ecd * minor fixes * * Revision 1.11 1994/11/28 02:00:51 ecd * deleted serial_init() from init_emulator * changed handling of version numbers * * Revision 1.10 1994/11/04 03:42:34 ecd * changed includes, doesn't depend on FILE_VERSION anymore * * Revision 1.9 1994/11/02 14:44:28 ecd * support for "compressed" files added. * * Revision 1.8 1994/10/09 20:32:02 ecd * deleted extern char lcd_buffer reference. * * Revision 1.7 1994/10/06 16:30:05 ecd * changed char to unsigned * * Revision 1.6 1994/10/05 08:36:44 ecd * changed saturn_config_init() * * Revision 1.5 1994/09/30 12:37:09 ecd * the file ~/.hp48/hp48 now contains a MAGIC and version info, so * backward compatibility can be achived * * Revision 1.4 1994/09/18 15:29:22 ecd * turned off unused rcsid message * * Revision 1.3 1994/09/13 16:57:00 ecd * changed to plain X11 * * Revision 1.2 1994/08/31 18:23:21 ecd * changed display initialization. * * Revision 1.1 1994/08/26 11:09:02 ecd * Initial revision * * $Id: init.c,v 1.13 1995/01/11 18:20:01 ecd Exp ecd $ */ #include #include #include #include #include #include #include #include #ifdef SUNOS #include #endif #include "hp48.h" #include "hp48_emu.h" #include "device.h" #include "resources.h" #include "romio.h" #define X48_MAGIC 0x48503438 #define NR_CONFIG 8 short rom_is_new = 1; long ram_size; long port1_size; long port1_mask; short port1_is_ram; long port2_size; long port2_mask; short port2_is_ram; typedef struct old_keystate_t { int rows[9]; } old_keystate_t; typedef struct old_saturn_t { 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; } old_saturn_t; old_saturn_t old_saturn; typedef struct saturn_0_3_0_t { 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; } saturn_0_3_0_t; saturn_0_3_0_t saturn_0_3_0; #include "config.h" void #ifdef __FunctionProto__ saturn_config_init(void) #else saturn_config_init() #endif { saturn.version[0] = VERSION_MAJOR; saturn.version[1] = VERSION_MINOR; saturn.version[2] = PATCHLEVEL; saturn.version[3] = COMPILE_VERSION; 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; } void #ifdef __FunctionProto__ init_saturn(void) #else init_saturn() #endif { 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; saturn.version[3] = COMPILE_VERSION; 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(); } void #ifdef __FunctionProto__ copy_old_saturn(old_saturn_t *old, saturn_t *new) #else copy_old_saturn(old, new) old_saturn_t *old; saturn_t *new; #endif { int i; memcpy(&(new->A[0]), &(old->A[0]), 16); memcpy(&(new->B[0]), &(old->B[0]), 16); memcpy(&(new->C[0]), &(old->C[0]), 16); memcpy(&(new->D[0]), &(old->D[0]), 16); new->d[0] = old->d[0]; new->d[1] = old->d[1]; new->P = old->P; new->PC = old->PC; memcpy(&(new->R0[0]), &(old->R0[0]), 16); memcpy(&(new->R1[0]), &(old->R1[0]), 16); memcpy(&(new->R2[0]), &(old->R2[0]), 16); memcpy(&(new->R3[0]), &(old->R3[0]), 16); memcpy(&(new->R4[0]), &(old->R4[0]), 16); memcpy(&(new->IN[0]), &(old->IN[0]), 4); memcpy(&(new->OUT[0]), &(old->OUT[0]), 3); new->CARRY = old->CARRY; memcpy(&(new->PSTAT[0]), &(old->PSTAT[0]), NR_PSTAT); new->XM = old->XM; new->SB = old->SB; new->SR = old->SR; new->MP = old->MP; new->hexmode = old->hexmode; memcpy(&(new->rstk[0]), &(old->rstk[0]), NR_RSTK * sizeof(word_20)); new->rstkp = old->rstkp; for (i = 0; i < 9; i++) { new->keybuf.rows[i] = old->keybuf.rows[i]; } new->intenable = old->intenable; new->int_pending = old->int_pending; new->kbd_ien = old->kbd_ien; new->disp_io = old->disp_io; new->contrast_ctrl = old->contrast_ctrl; new->disp_test = old->disp_test; new->crc = old->crc; new->power_status = old->power_status; new->power_ctrl = old->power_ctrl; new->mode = old->mode; new->annunc = old->annunc; new->baud = old->baud; new->card_ctrl = old->card_ctrl; new->card_status = old->card_status; new->io_ctrl = old->io_ctrl; new->rcs = old->rcs; new->tcs = old->tcs; new->rbr = old->rbr; new->tbr = old->tbr; new->sreq = old->sreq; new->ir_ctrl = old->ir_ctrl; new->base_off = old->base_off; new->lcr = old->lcr; new->lbr = old->lbr; new->scratch = old->scratch; new->base_nibble = old->base_nibble; new->disp_addr = old->disp_addr; new->line_offset = old->line_offset; new->line_count = old->line_count; new->unknown = old->unknown; new->t1_ctrl = old->t1_ctrl; new->t2_ctrl = old->t2_ctrl; new->menu_addr = old->menu_addr; new->unknown2 = old->unknown2; new->timer1 = old->timer1; new->timer2 = old->timer2; new->t1_instr = old->t1_instr; new->t2_instr = old->t2_instr; new->bank_switch = 0; if (opt_gx) { new->mem_cntl[0].unconfigured = 0; new->mem_cntl[0].config[0] = 0x00100; new->mem_cntl[1].unconfigured = 0; new->mem_cntl[1].config[0] = 0x80000; new->mem_cntl[1].config[1] = 0xc0000; new->mem_cntl[2].unconfigured = 0; new->mem_cntl[2].config[0] = 0x7f000; new->mem_cntl[2].config[1] = 0xff000; new->mem_cntl[3].unconfigured = 0; new->mem_cntl[3].config[0] = 0xc0000; new->mem_cntl[3].config[1] = 0xc0000; new->mem_cntl[4].unconfigured = 0; new->mem_cntl[4].config[0] = 0xc0000; new->mem_cntl[4].config[1] = 0xc0000; new->mem_cntl[5].unconfigured = 0; new->mem_cntl[5].config[0] = 0x00000; new->mem_cntl[5].config[1] = 0x00000; } else { if (old->devices == 0x100) { new->mem_cntl[0].unconfigured = 0; new->mem_cntl[0].config[0] = old->devices; } else { new->mem_cntl[0].unconfigured = 1; new->mem_cntl[0].config[0] = 0x00000; } if (old->ram32k == 0x70000) { new->mem_cntl[1].unconfigured = 0; new->mem_cntl[1].config[0] = 0x70000; new->mem_cntl[1].config[1] = 0xf0000; } else if (old->ram32k == 0xf0000) { new->mem_cntl[1].unconfigured = 0; new->mem_cntl[1].config[0] = 0xf0000; new->mem_cntl[1].config[1] = 0xf0000; } else if (old->ram32k == 0xfc000) { new->mem_cntl[1].unconfigured = 0; new->mem_cntl[1].config[0] = 0x70000; new->mem_cntl[1].config[1] = 0xfc000; } else if (old->ram32k == 0xfe000) { new->mem_cntl[1].unconfigured = 0; new->mem_cntl[1].config[0] = 0x70000; new->mem_cntl[1].config[1] = 0xfe000; } else { new->mem_cntl[1].unconfigured = 2; new->mem_cntl[1].config[0] = 0x00000; new->mem_cntl[1].config[1] = 0x00000; } new->mem_cntl[2].unconfigured = 0; new->mem_cntl[2].config[0] = 0x80000; new->mem_cntl[2].config[1] = 0xc0000; new->mem_cntl[3].unconfigured = 0; new->mem_cntl[3].config[0] = 0xc0000; new->mem_cntl[3].config[1] = 0xc0000; new->mem_cntl[4].unconfigured = 0; new->mem_cntl[4].config[0] = 0xd0000; new->mem_cntl[4].config[1] = 0xff000; new->mem_cntl[5].unconfigured = 0; new->mem_cntl[5].config[0] = 0x00000; new->mem_cntl[5].config[1] = 0x80000; } } void #ifdef __FunctionProto__ copy_0_3_0_saturn(saturn_0_3_0_t *old, saturn_t *new) #else copy_0_3_0_saturn(old, new) saturn_0_3_0_t *old; saturn_t *new; #endif { int i; memcpy(&(new->A[0]), &(old->A[0]), 16); memcpy(&(new->B[0]), &(old->B[0]), 16); memcpy(&(new->C[0]), &(old->C[0]), 16); memcpy(&(new->D[0]), &(old->D[0]), 16); new->d[0] = old->d[0]; new->d[1] = old->d[1]; new->P = old->P; new->PC = old->PC; memcpy(&(new->R0[0]), &(old->R0[0]), 16); memcpy(&(new->R1[0]), &(old->R1[0]), 16); memcpy(&(new->R2[0]), &(old->R2[0]), 16); memcpy(&(new->R3[0]), &(old->R3[0]), 16); memcpy(&(new->R4[0]), &(old->R4[0]), 16); memcpy(&(new->IN[0]), &(old->IN[0]), 4); memcpy(&(new->OUT[0]), &(old->OUT[0]), 3); new->CARRY = old->CARRY; memcpy(&(new->PSTAT[0]), &(old->PSTAT[0]), NR_PSTAT); new->XM = old->XM; new->SB = old->SB; new->SR = old->SR; new->MP = old->MP; new->hexmode = old->hexmode; memcpy(&(new->rstk[0]), &(old->rstk[0]), NR_RSTK * sizeof(word_20)); new->rstkp = old->rstkp; for (i = 0; i < 9; i++) { new->keybuf.rows[i] = old->keybuf.rows[i]; } new->intenable = old->intenable; new->int_pending = old->int_pending; new->kbd_ien = old->kbd_ien; new->disp_io = old->disp_io; new->contrast_ctrl = old->contrast_ctrl; new->disp_test = old->disp_test; new->crc = old->crc; new->power_status = old->power_status; new->power_ctrl = old->power_ctrl; new->mode = old->mode; new->annunc = old->annunc; new->baud = old->baud; new->card_ctrl = old->card_ctrl; new->card_status = old->card_status; new->io_ctrl = old->io_ctrl; new->rcs = old->rcs; new->tcs = old->tcs; new->rbr = old->rbr; new->tbr = old->tbr; new->sreq = old->sreq; new->ir_ctrl = old->ir_ctrl; new->base_off = old->base_off; new->lcr = old->lcr; new->lbr = old->lbr; new->scratch = old->scratch; new->base_nibble = old->base_nibble; new->disp_addr = old->disp_addr; new->line_offset = old->line_offset; new->line_count = old->line_count; new->unknown = old->unknown; new->t1_ctrl = old->t1_ctrl; new->t2_ctrl = old->t2_ctrl; new->menu_addr = old->menu_addr; new->unknown2 = old->unknown2; new->timer1 = old->timer1; new->timer2 = old->timer2; new->t1_instr = old->t1_instr; new->t2_instr = old->t2_instr; new->t1_tick = old->t1_tick; new->t2_tick = old->t2_tick; new->i_per_s = old->i_per_s; new->bank_switch = 0; if (opt_gx) { new->mem_cntl[0].unconfigured = 0; new->mem_cntl[0].config[0] = 0x00100; new->mem_cntl[1].unconfigured = 0; new->mem_cntl[1].config[0] = 0x80000; new->mem_cntl[1].config[1] = 0xc0000; new->mem_cntl[2].unconfigured = 0; new->mem_cntl[2].config[0] = 0x7f000; new->mem_cntl[2].config[1] = 0xff000; new->mem_cntl[3].unconfigured = 0; new->mem_cntl[3].config[0] = 0xc0000; new->mem_cntl[3].config[1] = 0xc0000; new->mem_cntl[4].unconfigured = 0; new->mem_cntl[4].config[0] = 0xc0000; new->mem_cntl[4].config[1] = 0xc0000; new->mem_cntl[5].unconfigured = 0; new->mem_cntl[5].config[0] = 0x00000; new->mem_cntl[5].config[1] = 0x00000; } else { if (old->devices == 0x100) { new->mem_cntl[0].unconfigured = 0; new->mem_cntl[0].config[0] = old->devices; } else { new->mem_cntl[0].unconfigured = 1; new->mem_cntl[0].config[0] = 0x00000; } if (old->ram32k == 0x70000) { new->mem_cntl[1].unconfigured = 0; new->mem_cntl[1].config[0] = 0x70000; new->mem_cntl[1].config[1] = 0xf0000; } else if (old->ram32k == 0xf0000) { new->mem_cntl[1].unconfigured = 0; new->mem_cntl[1].config[0] = 0xf0000; new->mem_cntl[1].config[1] = 0xf0000; } else if (old->ram32k == 0xfc000) { new->mem_cntl[1].unconfigured = 0; new->mem_cntl[1].config[0] = 0x70000; new->mem_cntl[1].config[1] = 0xfc000; } else if (old->ram32k == 0xfe000) { new->mem_cntl[1].unconfigured = 0; new->mem_cntl[1].config[0] = 0x70000; new->mem_cntl[1].config[1] = 0xfe000; } else { new->mem_cntl[1].unconfigured = 2; new->mem_cntl[1].config[0] = 0x00000; new->mem_cntl[1].config[1] = 0x00000; } new->mem_cntl[2].unconfigured = 0; new->mem_cntl[2].config[0] = 0x80000; new->mem_cntl[2].config[1] = 0xc0000; new->mem_cntl[3].unconfigured = 0; new->mem_cntl[3].config[0] = 0xc0000; new->mem_cntl[3].config[1] = 0xc0000; new->mem_cntl[4].unconfigured = 0; new->mem_cntl[4].config[0] = 0xd0000; new->mem_cntl[4].config[1] = 0xff000; new->mem_cntl[5].unconfigured = 0; new->mem_cntl[5].config[0] = 0x00000; new->mem_cntl[5].config[1] = 0x80000; } } int #ifdef __FunctionProto__ read_8(FILE *fp, word_8 *var) #else read_8(fp, var) FILE *fp; word_8 *var; #endif { unsigned char tmp; if (fread(&tmp, 1, 1, fp) != 1) { if (!quiet) LOGE( "%s: can\'t read word_8\n", progname); return 0; } *var = tmp; return 1; } int #ifdef __FunctionProto__ read_char(FILE *fp, char *var) #else read_char(fp, var) FILE *fp; char *var; #endif { char tmp; if (fread(&tmp, 1, 1, fp) != 1) { if (!quiet) LOGE( "%s: can\'t read char\n", progname); return 0; } *var = tmp; return 1; } int #ifdef __FunctionProto__ read_16(FILE *fp, word_16 *var) #else read_16(fp, var) FILE *fp; word_16 *var; #endif { unsigned char tmp[2]; if (fread(&tmp[0], 1, 2, fp) != 2) { if (!quiet) LOGE( "%s: can\'t read word_16\n", progname); return 0; } *var = tmp[0] << 8; *var |= tmp[1]; return 1; } int #ifdef __FunctionProto__ read_32(FILE *fp, word_32 *var) #else read_32(fp, var) FILE *fp; word_32 *var; #endif { unsigned char tmp[4]; if (fread(&tmp[0], 1, 4, fp) != 4) { if (!quiet) LOGE( "%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; } int #ifdef __FunctionProto__ read_u_long(FILE *fp, unsigned long *var) #else read_u_long(fp, var) FILE *fp; unsigned long*var; #endif { unsigned char tmp[4]; if (fread(&tmp[0], 1, 4, fp) != 4) { if (!quiet) LOGE( "%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; } int #ifdef __FunctionProto__ read_version_0_3_0_file(FILE *fp) #else read_version_0_3_0_file(fp) FILE *fp; #endif { int i; /* * 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; } int #ifdef __FunctionProto__ read_version_0_4_0_file(FILE *fp) #else read_version_0_4_0_file(fp) FILE *fp; #endif { int i; /* * version 0.4.x, read in the saturn_t struct */ 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; } return 1; } int #ifdef __FunctionProto__ read_mem_file(char *name, word_4 *mem, int size) #else read_mem_file(name, mem, size) char *name; word_4 *mem; int size; #endif { struct stat st; FILE *fp; word_8 *tmp_mem; word_8 byte; int i, j; if (NULL == (fp = fopen(name, "r"))) { if (!quiet) LOGE( "%s: can\'t open %s\n", progname, name); return 0; } if (stat(name, &st) < 0) { if (!quiet) LOGE( "%s: can\'t stat %s\n", progname, name); return 0; } 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) LOGE( "%s: can\'t read %s\n", progname, name); fclose(fp); return 0; } } else { /* * size is different, check size and decompress memory */ if (st.st_size != size / 2) { if (!quiet) LOGE( "%s: strange size %s, expected %d, found %ld\n", progname, name, size / 2, st.st_size); fclose(fp); return 0; } 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) LOGE( "%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) LOGE( "%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); } } fclose(fp); if (verbose) printf("%s: read %s\n", progname, name); return 1; } int #ifdef __FunctionProto__ read_rom(const char *fname) #else read_rom(fname) const char *fname; #endif { int ram_size; if (!read_rom_file(fname, &saturn.rom, &rom_size)) return 0; dev_memory_init(); if (opt_gx) ram_size = RAM_SIZE_GX; else ram_size = RAM_SIZE_SX; if (NULL == (saturn.ram = (word_4 *)malloc(ram_size))) { if (!quiet) LOGE( "%s: can\'t malloc RAM\n", progname); return 0; } memset(saturn.ram, 0, ram_size); port1_size = 0; port1_mask = 0; port1_is_ram = 0; saturn.port1 = (unsigned char *)0; port2_size = 0; port2_mask = 0; port2_is_ram = 0; saturn.port2 = (unsigned char *)0; saturn.card_status = 0; return 1; } void #ifdef __FunctionProto__ get_home_directory(char *path) #else get_home_directory(path) char *path; #endif { char *p; struct passwd *pwd; if (homeDirectory[0] == '/') { strcpy(path, homeDirectory); } else { 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) LOGE( "%s: can\'t figure out your home directory, trying /tmp\n", progname); strcpy(path, "/tmp"); } } strcat(path, homeDirectory); } } int #ifdef __FunctionProto__ read_files(void) #else read_files() #endif { char path[1024]; char fnam[1024]; unsigned long v1, v2; int i, read_version; int ram_size; struct stat st; FILE *fp; strcpy(path, files_path); //get_home_directory(path); LOGI("path: %s", path); saturn.rom = (word_4 *)NULL; strcpy(fnam, path); strcat(fnam, rom_filename); if (!read_rom_file(fnam, &saturn.rom, &rom_size)) return 0; rom_is_new = 0; strcpy(fnam, path); strcat(fnam, conf_filename); if (NULL == (fp = fopen(fnam, "r"))) { if (!quiet) LOGE("%s: can\'t open %s\n", progname, fnam); return 0; } /* * ok, file is open, try to read the MAGIC number */ read_u_long(fp, &saturn.magic); if (X48_MAGIC != saturn.magic) { /* * no MAGIC number, try to read old format file */ 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) LOGE("%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; saturn.version[3] = COMPILE_VERSION; } else { /* * no, initialize */ if (!quiet) LOGE( "%s: can\'t handle %s\n", progname, fnam); init_saturn(); } } else { /* * MAGIC ok, read and compare the version */ read_version = 1; for (i = 0; i < 4; i++) { if (!read_char(fp, &saturn.version[i])) { if (!quiet) LOGE( "%s: can\'t read version\n", progname); read_version = 0; } } 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; v2 |= ((int)COMPILE_VERSION & 0xff); if ((v1 & 0xffffff00) < (v2 & 0xffffff00)) { if (!quiet) LOGE( "%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) LOGE( "%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) LOGE( "%s: can\'t handle %s\n", progname, fnam); init_saturn(); } else { copy_0_3_0_saturn(&saturn_0_3_0, &saturn); if (verbose) LOGI("%s: read %s\n", progname, fnam); } } else if (v1 <= v2) { /* * read latest version file */ if (!read_version_0_4_0_file(fp)) { if (!quiet) LOGE( "%s: can\'t handle %s\n", progname, fnam); init_saturn(); } else if (verbose) { LOGI("%s: read %s\n", progname, fnam); } } else { /* * try to read latest version file */ if (!read_version_0_4_0_file(fp)) { if (!quiet) LOGE( "%s: can\'t handle %s\n", progname, fnam); init_saturn(); } else if (verbose) { LOGI("%s: read %s\n", progname, fnam); } } } } fclose(fp); 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) LOGE( "%s: can\'t malloc RAM[%d]\n", progname, ram_size); exit (1); } strcpy(fnam, path); strcat(fnam, ram_filename); if ((fp = fopen(fnam, "r")) == NULL) { if (!quiet) LOGE( "%s: can\'t open %s\n", progname, fnam); return 0; } if (!read_mem_file(fnam, saturn.ram, ram_size)) return 0; 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_filename); 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) LOGE( "%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_IWGRP) ? 1 : 0; port1_mask = port1_size - 1; } } } 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; } port2_size = 0; port2_mask = 0; port2_is_ram = 0; saturn.port2 = (unsigned char *)0; strcpy(fnam, path); strcat(fnam, port2_filename); 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) LOGE( "%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_IWGRP) ? 1 : 0; port2_mask = port2_size - 1; } } } 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; } int #ifdef __FunctionProto__ write_8(FILE *fp, word_8 *var) #else write_8(fp, var) FILE *fp; word_8 *var; #endif { unsigned char tmp; tmp = *var; if (fwrite(&tmp, 1, 1, fp) != 1) { if (!quiet) LOGE( "%s: can\'t write word_8\n", progname); return 0; } return 1; } int #ifdef __FunctionProto__ write_char(FILE *fp, char *var) #else write_char(fp, var) FILE *fp; char *var; #endif { char tmp; tmp = *var; if (fwrite(&tmp, 1, 1, fp) != 1) { if (!quiet) LOGE( "%s: can\'t write char\n", progname); return 0; } return 1; } int #ifdef __FunctionProto__ write_16(FILE *fp, word_16 *var) #else write_16(fp, var) FILE *fp; word_16 *var; #endif { unsigned char tmp[2]; tmp[0] = (*var >> 8) & 0xff; tmp[1] = *var & 0xff; if (fwrite(&tmp[0], 1, 2, fp) != 2) { if (!quiet) LOGE( "%s: can\'t write word_16\n", progname); return 0; } return 1; } int #ifdef __FunctionProto__ write_32(FILE *fp, word_32 *var) #else write_32(fp, var) FILE *fp; word_32 *var; #endif { unsigned char tmp[4]; 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) LOGE( "%s: can\'t write word_32\n", progname); return 0; } return 1; } int #ifdef __FunctionProto__ write_u_long(FILE *fp, unsigned long *var) #else write_u_long(fp, var) FILE *fp; unsigned long*var; #endif { unsigned char tmp[4]; 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) LOGE( "%s: can\'t write unsigned long\n", progname); return 0; } return 1; } int #ifdef __FunctionProto__ write_mem_file(char *name, word_4 *mem, int size) #else write_mem_file(name, mem, size) char *name; word_4 *mem; int size; #endif { FILE *fp; word_8 *tmp_mem; word_8 byte; int i, j; if (NULL == (fp = fopen(name, "w"))) { if (!quiet) LOGE( "%s: can\'t open %s\n", progname, name); return 0; } 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) LOGE( "%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; } if (fwrite(tmp_mem, 1, (size_t)size / 2, fp) != size / 2) { if (!quiet) LOGE( "%s: can\'t write %s\n", progname, name); fclose(fp); free(tmp_mem); return 0; } free(tmp_mem); } fclose(fp); if (verbose) printf("%s: wrote %s\n", progname, name); return 1; } int #ifdef __FunctionProto__ write_files(void) #else write_files() #endif { char path[1024]; char fnam[1024]; struct stat st; int i, make_dir; int ram_size; FILE *fp; make_dir = 0; strcpy(path, files_path); if (stat(path, &st) == -1) { if (errno == ENOENT) { make_dir = 1; } else { if (!quiet) LOGE( "%s: can\'t stat %s, saving to /tmp\n", progname, path); strcpy(path, "/tmp"); } } else { if (!S_ISDIR(st.st_mode)) { if (!quiet) LOGE( "%s: %s is no directory, saving to /tmp\n", progname, path); strcpy(path, "/tmp"); } } if (make_dir) { if (mkdir(path, 0777) == -1) { if (!quiet) LOGE( "%s: can\'t mkdir %s, saving to /tmp\n", progname, path); strcpy(path, "/tmp"); } } //strcat(path, "/"); strcpy(fnam, path); strcat(fnam, conf_filename); LOGI("trying to save: %s", fnam); if ((fp = fopen(fnam, "w")) == NULL) { if (!quiet) LOGE( "%s: can\'t open %s, no saving done\n", progname, fnam); return 0; } /* * 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_filename); if (!write_mem_file(fnam, saturn.rom, rom_size)) return 0; } if (opt_gx) ram_size = RAM_SIZE_GX; else ram_size = RAM_SIZE_SX; strcpy(fnam, path); strcat(fnam, ram_filename); if (!write_mem_file(fnam, saturn.ram, ram_size)) return 0; if ((port1_size > 0) && port1_is_ram) { strcpy(fnam, path); strcat(fnam, port1_filename); if (!write_mem_file(fnam, saturn.port1, port1_size)) return 0; } if ((port2_size > 0) && port2_is_ram) { strcpy(fnam, path); strcat(fnam, port2_filename); if (!write_mem_file(fnam, saturn.port2, port2_size)) return 0; } return 1; } int #ifdef __FunctionProto__ init_emulator(void) #else init_emulator() #endif { if (!initialize) if (read_files()) { if (resetOnStartup) saturn.PC = 0x00000; return 0; } init_saturn(); char path[1024]; strcpy(path, files_path); strcat(path, rom_filename); if (!read_rom(path)) exit(1); return 0; } void #ifdef __FunctionProto__ init_active_stuff(void) #else init_active_stuff() #endif { serial_init(); init_annunc(); init_display(); } int #ifdef __FunctionProto__ exit_emulator(void) #else exit_emulator() #endif { write_files(); return 1; }