1 /*
2 * This file is part of x48, an emulator of the HP-48sx Calculator.
3 * Copyright (C) 1994 Eddie C. Dost (ecd@dressler.de)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 /* $Log: init.c,v $
21 * Revision 1.13 1995/01/11 18:20:01 ecd
22 * major update to support HP48 G/GX
23 *
24 * Revision 1.12 1994/12/07 20:20:50 ecd
25 * minor fixes
26 *
27 * Revision 1.12 1994/12/07 20:20:50 ecd
28 * minor fixes
29 *
30 * Revision 1.11 1994/11/28 02:00:51 ecd
31 * deleted serial_init() from init_emulator
32 * changed handling of version numbers
33 *
34 * Revision 1.10 1994/11/04 03:42:34 ecd
35 * changed includes, doesn't depend on FILE_VERSION anymore
36 *
37 * Revision 1.9 1994/11/02 14:44:28 ecd
38 * support for "compressed" files added.
39 *
40 * Revision 1.8 1994/10/09 20:32:02 ecd
41 * deleted extern char lcd_buffer reference.
42 *
43 * Revision 1.7 1994/10/06 16:30:05 ecd
44 * changed char to unsigned
45 *
46 * Revision 1.6 1994/10/05 08:36:44 ecd
47 * changed saturn_config_init()
48 *
49 * Revision 1.5 1994/09/30 12:37:09 ecd
50 * the file ~/.hp48/hp48 now contains a MAGIC and version info, so
51 * backward compatibility can be achived
52 *
53 * Revision 1.4 1994/09/18 15:29:22 ecd
54 * turned off unused rcsid message
55 *
56 * Revision 1.3 1994/09/13 16:57:00 ecd
57 * changed to plain X11
58 *
59 * Revision 1.2 1994/08/31 18:23:21 ecd
60 * changed display initialization.
61 *
62 * Revision 1.1 1994/08/26 11:09:02 ecd
63 * Initial revision
64 *
65 * $Id: init.c,v 1.13 1995/01/11 18:20:01 ecd Exp ecd $
66 */
67
68 #include <stdio.h>
69 #include <stdlib.h>
70 #include <errno.h>
71 #include <unistd.h>
72 #include <sys/stat.h>
73 #include <string.h>
74 #include <pwd.h>
75 #include <sys/types.h>
76 #ifdef SUNOS
77 #include <memory.h>
78 #endif
79
80 #include "hp48.h"
81 #include "hp48_emu.h"
82 #include "device.h"
83 #include "resources.h"
84 #include "romio.h"
85
86 #define X48_MAGIC 0x48503438
87 #define NR_CONFIG 8
88
89 short rom_is_new = 1;
90 long ram_size;
91 long port1_size;
92 long port1_mask;
93 short port1_is_ram;
94 long port2_size;
95 long port2_mask;
96 short port2_is_ram;
97
98 typedef struct old_keystate_t {
99 int rows[9];
100 } old_keystate_t;
101
102 typedef struct old_saturn_t {
103 unsigned char A[16], B[16], C[16], D[16];
104 long d[2];
105 int P;
106 long PC;
107 unsigned char R0[16], R1[16], R2[16], R3[16], R4[16];
108 unsigned char IN[4];
109 unsigned char OUT[3];
110 int CARRY;
111 unsigned char PSTAT[NR_PSTAT];
112 unsigned char XM, SB, SR, MP;
113 unsigned char hexmode;
114 long rstk[NR_RSTK];
115 short rstkp;
116 old_keystate_t keybuf;
117 unsigned char intenable;
118 unsigned char int_pending;
119 unsigned char kbd_ien;
120 long configs[NR_CONFIG];
121 short daisy_state;
122 long ram32k;
123 long devices;
124 unsigned char disp_io;
125 unsigned char contrast_ctrl;
126 unsigned char disp_test;
127 unsigned int crc;
128 unsigned char power_status;
129 unsigned char power_ctrl;
130 unsigned char mode;
131 unsigned char annunc;
132 unsigned char baud;
133 unsigned char card_ctrl;
134 unsigned char card_status;
135 unsigned char io_ctrl;
136 unsigned char rcs;
137 unsigned char tcs;
138 unsigned char rbr;
139 unsigned char tbr;
140 unsigned char sreq;
141 unsigned char ir_ctrl;
142 unsigned char base_off;
143 unsigned char lcr;
144 unsigned char lbr;
145 unsigned char scratch;
146 unsigned char base_nibble;
147 long disp_addr;
148 long line_offset;
149 long line_count;
150 long unknown;
151 unsigned char t1_ctrl;
152 unsigned char t2_ctrl;
153 long menu_addr;
154 long unknown2;
155 int timer1;
156 long timer2;
157 long t1_instr;
158 long t2_instr;
159 unsigned char *rom;
160 unsigned char *ram;
161 unsigned char *port1;
162 unsigned char *port2;
163 } old_saturn_t;
164
165 old_saturn_t old_saturn;
166
167 typedef struct saturn_0_3_0_t {
168 unsigned long magic;
169 char version[4];
170 unsigned char A[16], B[16], C[16], D[16];
171 word_20 d[2];
172 word_4 P;
173 word_20 PC;
174 unsigned char R0[16], R1[16], R2[16], R3[16], R4[16];
175 unsigned char IN[4];
176 unsigned char OUT[3];
177 word_1 CARRY;
178 unsigned char PSTAT[NR_PSTAT];
179 unsigned char XM, SB, SR, MP;
180 word_4 hexmode;
181 word_20 rstk[NR_RSTK];
182 short rstkp;
183 keystate_t keybuf;
184 unsigned char intenable;
185 unsigned char int_pending;
186 unsigned char kbd_ien;
187 word_20 configs[NR_CONFIG];
188 word_16 daisy_state;
189 word_20 ram32k;
190 word_20 devices;
191 word_4 disp_io;
192 word_4 contrast_ctrl;
193 word_8 disp_test;
194 word_16 crc;
195 word_4 power_status;
196 word_4 power_ctrl;
197 word_4 mode;
198 word_8 annunc;
199 word_4 baud;
200 word_4 card_ctrl;
201 word_4 card_status;
202 word_4 io_ctrl;
203 word_4 rcs;
204 word_4 tcs;
205 word_8 rbr;
206 word_8 tbr;
207 word_8 sreq;
208 word_4 ir_ctrl;
209 word_4 base_off;
210 word_4 lcr;
211 word_4 lbr;
212 word_4 scratch;
213 word_4 base_nibble;
214 word_20 disp_addr;
215 word_12 line_offset;
216 word_8 line_count;
217 word_16 unknown;
218 word_4 t1_ctrl;
219 word_4 t2_ctrl;
220 word_20 menu_addr;
221 word_8 unknown2;
222 char timer1;
223 word_32 timer2;
224 long t1_instr;
225 long t2_instr;
226 short t1_tick;
227 short t2_tick;
228 long i_per_s;
229 unsigned char *rom;
230 unsigned char *ram;
231 unsigned char *port1;
232 unsigned char *port2;
233 } saturn_0_3_0_t;
234
235 saturn_0_3_0_t saturn_0_3_0;
236
237 #include "config.h"
238
239 void
240 #ifdef __FunctionProto__
saturn_config_init(void)241 saturn_config_init(void)
242 #else
243 saturn_config_init()
244 #endif
245 {
246 saturn.version[0] = VERSION_MAJOR;
247 saturn.version[1] = VERSION_MINOR;
248 saturn.version[2] = PATCHLEVEL;
249 saturn.version[3] = COMPILE_VERSION;
250 memset(&device, 0, sizeof(device));
251 device.display_touched = 1;
252 device.contrast_touched = 1;
253 device.baud_touched = 1;
254 device.ann_touched = 1;
255 saturn.rcs = 0x0;
256 saturn.tcs = 0x0;
257 saturn.lbr = 0x0;
258 }
259
260 void
261 #ifdef __FunctionProto__
init_saturn(void)262 init_saturn(void)
263 #else
264 init_saturn()
265 #endif
266 {
267 int i;
268
269 memset(&saturn, 0, sizeof(saturn) - 4 * sizeof(unsigned char *));
270 saturn.PC = 0x00000;
271 saturn.magic = X48_MAGIC;
272 saturn.t1_tick = 8192;
273 saturn.t2_tick = 16;
274 saturn.i_per_s = 0;
275 saturn.version[0] = VERSION_MAJOR;
276 saturn.version[1] = VERSION_MINOR;
277 saturn.version[2] = PATCHLEVEL;
278 saturn.version[3] = COMPILE_VERSION;
279 saturn.hexmode = HEX;
280 saturn.rstkp = -1;
281 saturn.intenable = 1;
282 saturn.int_pending = 0;
283 saturn.kbd_ien = 1;
284 saturn.timer1 = 0;
285 saturn.timer2 = 0x2000;
286 saturn.bank_switch = 0;
287 for (i = 0; i < NR_MCTL; i++)
288 {
289 if (i == 0)
290 saturn.mem_cntl[i].unconfigured = 1;
291 else if (i == 5)
292 saturn.mem_cntl[i].unconfigured = 0;
293 else
294 saturn.mem_cntl[i].unconfigured = 2;
295 saturn.mem_cntl[i].config[0] = 0;
296 saturn.mem_cntl[i].config[1] = 0;
297 }
298 dev_memory_init();
299 }
300
301 void
302 #ifdef __FunctionProto__
copy_old_saturn(old_saturn_t * old,saturn_t * new)303 copy_old_saturn(old_saturn_t *old, saturn_t *new)
304 #else
305 copy_old_saturn(old, new)
306 old_saturn_t *old;
307 saturn_t *new;
308 #endif
309 {
310 int i;
311
312 memcpy(&(new->A[0]), &(old->A[0]), 16);
313 memcpy(&(new->B[0]), &(old->B[0]), 16);
314 memcpy(&(new->C[0]), &(old->C[0]), 16);
315 memcpy(&(new->D[0]), &(old->D[0]), 16);
316 new->d[0] = old->d[0];
317 new->d[1] = old->d[1];
318 new->P = old->P;
319 new->PC = old->PC;
320 memcpy(&(new->R0[0]), &(old->R0[0]), 16);
321 memcpy(&(new->R1[0]), &(old->R1[0]), 16);
322 memcpy(&(new->R2[0]), &(old->R2[0]), 16);
323 memcpy(&(new->R3[0]), &(old->R3[0]), 16);
324 memcpy(&(new->R4[0]), &(old->R4[0]), 16);
325 memcpy(&(new->IN[0]), &(old->IN[0]), 4);
326 memcpy(&(new->OUT[0]), &(old->OUT[0]), 3);
327 new->CARRY = old->CARRY;
328 memcpy(&(new->PSTAT[0]), &(old->PSTAT[0]), NR_PSTAT);
329 new->XM = old->XM;
330 new->SB = old->SB;
331 new->SR = old->SR;
332 new->MP = old->MP;
333 new->hexmode = old->hexmode;
334 memcpy(&(new->rstk[0]), &(old->rstk[0]), NR_RSTK * sizeof(word_20));
335 new->rstkp = old->rstkp;
336 for (i = 0; i < 9; i++) {
337 new->keybuf.rows[i] = old->keybuf.rows[i];
338 }
339 new->intenable = old->intenable;
340 new->int_pending = old->int_pending;
341 new->kbd_ien = old->kbd_ien;
342 new->disp_io = old->disp_io;
343 new->contrast_ctrl = old->contrast_ctrl;
344 new->disp_test = old->disp_test;
345 new->crc = old->crc;
346 new->power_status = old->power_status;
347 new->power_ctrl = old->power_ctrl;
348 new->mode = old->mode;
349 new->annunc = old->annunc;
350 new->baud = old->baud;
351 new->card_ctrl = old->card_ctrl;
352 new->card_status = old->card_status;
353 new->io_ctrl = old->io_ctrl;
354 new->rcs = old->rcs;
355 new->tcs = old->tcs;
356 new->rbr = old->rbr;
357 new->tbr = old->tbr;
358 new->sreq = old->sreq;
359 new->ir_ctrl = old->ir_ctrl;
360 new->base_off = old->base_off;
361 new->lcr = old->lcr;
362 new->lbr = old->lbr;
363 new->scratch = old->scratch;
364 new->base_nibble = old->base_nibble;
365 new->disp_addr = old->disp_addr;
366 new->line_offset = old->line_offset;
367 new->line_count = old->line_count;
368 new->unknown = old->unknown;
369 new->t1_ctrl = old->t1_ctrl;
370 new->t2_ctrl = old->t2_ctrl;
371 new->menu_addr = old->menu_addr;
372 new->unknown2 = old->unknown2;
373 new->timer1 = old->timer1;
374 new->timer2 = old->timer2;
375 new->t1_instr = old->t1_instr;
376 new->t2_instr = old->t2_instr;
377 new->bank_switch = 0;
378 if (opt_gx)
379 {
380 new->mem_cntl[0].unconfigured = 0;
381 new->mem_cntl[0].config[0] = 0x00100;
382 new->mem_cntl[1].unconfigured = 0;
383 new->mem_cntl[1].config[0] = 0x80000;
384 new->mem_cntl[1].config[1] = 0xc0000;
385 new->mem_cntl[2].unconfigured = 0;
386 new->mem_cntl[2].config[0] = 0x7f000;
387 new->mem_cntl[2].config[1] = 0xff000;
388 new->mem_cntl[3].unconfigured = 0;
389 new->mem_cntl[3].config[0] = 0xc0000;
390 new->mem_cntl[3].config[1] = 0xc0000;
391 new->mem_cntl[4].unconfigured = 0;
392 new->mem_cntl[4].config[0] = 0xc0000;
393 new->mem_cntl[4].config[1] = 0xc0000;
394 new->mem_cntl[5].unconfigured = 0;
395 new->mem_cntl[5].config[0] = 0x00000;
396 new->mem_cntl[5].config[1] = 0x00000;
397 }
398 else
399 {
400 if (old->devices == 0x100)
401 {
402 new->mem_cntl[0].unconfigured = 0;
403 new->mem_cntl[0].config[0] = old->devices;
404 }
405 else
406 {
407 new->mem_cntl[0].unconfigured = 1;
408 new->mem_cntl[0].config[0] = 0x00000;
409 }
410 if (old->ram32k == 0x70000)
411 {
412 new->mem_cntl[1].unconfigured = 0;
413 new->mem_cntl[1].config[0] = 0x70000;
414 new->mem_cntl[1].config[1] = 0xf0000;
415 }
416 else if (old->ram32k == 0xf0000)
417 {
418 new->mem_cntl[1].unconfigured = 0;
419 new->mem_cntl[1].config[0] = 0xf0000;
420 new->mem_cntl[1].config[1] = 0xf0000;
421 }
422 else if (old->ram32k == 0xfc000)
423 {
424 new->mem_cntl[1].unconfigured = 0;
425 new->mem_cntl[1].config[0] = 0x70000;
426 new->mem_cntl[1].config[1] = 0xfc000;
427 }
428 else if (old->ram32k == 0xfe000)
429 {
430 new->mem_cntl[1].unconfigured = 0;
431 new->mem_cntl[1].config[0] = 0x70000;
432 new->mem_cntl[1].config[1] = 0xfe000;
433 }
434 else
435 {
436 new->mem_cntl[1].unconfigured = 2;
437 new->mem_cntl[1].config[0] = 0x00000;
438 new->mem_cntl[1].config[1] = 0x00000;
439 }
440 new->mem_cntl[2].unconfigured = 0;
441 new->mem_cntl[2].config[0] = 0x80000;
442 new->mem_cntl[2].config[1] = 0xc0000;
443 new->mem_cntl[3].unconfigured = 0;
444 new->mem_cntl[3].config[0] = 0xc0000;
445 new->mem_cntl[3].config[1] = 0xc0000;
446 new->mem_cntl[4].unconfigured = 0;
447 new->mem_cntl[4].config[0] = 0xd0000;
448 new->mem_cntl[4].config[1] = 0xff000;
449 new->mem_cntl[5].unconfigured = 0;
450 new->mem_cntl[5].config[0] = 0x00000;
451 new->mem_cntl[5].config[1] = 0x80000;
452 }
453 }
454
455 void
456 #ifdef __FunctionProto__
copy_0_3_0_saturn(saturn_0_3_0_t * old,saturn_t * new)457 copy_0_3_0_saturn(saturn_0_3_0_t *old, saturn_t *new)
458 #else
459 copy_0_3_0_saturn(old, new)
460 saturn_0_3_0_t *old;
461 saturn_t *new;
462 #endif
463 {
464 int i;
465
466 memcpy(&(new->A[0]), &(old->A[0]), 16);
467 memcpy(&(new->B[0]), &(old->B[0]), 16);
468 memcpy(&(new->C[0]), &(old->C[0]), 16);
469 memcpy(&(new->D[0]), &(old->D[0]), 16);
470 new->d[0] = old->d[0];
471 new->d[1] = old->d[1];
472 new->P = old->P;
473 new->PC = old->PC;
474 memcpy(&(new->R0[0]), &(old->R0[0]), 16);
475 memcpy(&(new->R1[0]), &(old->R1[0]), 16);
476 memcpy(&(new->R2[0]), &(old->R2[0]), 16);
477 memcpy(&(new->R3[0]), &(old->R3[0]), 16);
478 memcpy(&(new->R4[0]), &(old->R4[0]), 16);
479 memcpy(&(new->IN[0]), &(old->IN[0]), 4);
480 memcpy(&(new->OUT[0]), &(old->OUT[0]), 3);
481 new->CARRY = old->CARRY;
482 memcpy(&(new->PSTAT[0]), &(old->PSTAT[0]), NR_PSTAT);
483 new->XM = old->XM;
484 new->SB = old->SB;
485 new->SR = old->SR;
486 new->MP = old->MP;
487 new->hexmode = old->hexmode;
488 memcpy(&(new->rstk[0]), &(old->rstk[0]), NR_RSTK * sizeof(word_20));
489 new->rstkp = old->rstkp;
490 for (i = 0; i < 9; i++) {
491 new->keybuf.rows[i] = old->keybuf.rows[i];
492 }
493 new->intenable = old->intenable;
494 new->int_pending = old->int_pending;
495 new->kbd_ien = old->kbd_ien;
496 new->disp_io = old->disp_io;
497 new->contrast_ctrl = old->contrast_ctrl;
498 new->disp_test = old->disp_test;
499 new->crc = old->crc;
500 new->power_status = old->power_status;
501 new->power_ctrl = old->power_ctrl;
502 new->mode = old->mode;
503 new->annunc = old->annunc;
504 new->baud = old->baud;
505 new->card_ctrl = old->card_ctrl;
506 new->card_status = old->card_status;
507 new->io_ctrl = old->io_ctrl;
508 new->rcs = old->rcs;
509 new->tcs = old->tcs;
510 new->rbr = old->rbr;
511 new->tbr = old->tbr;
512 new->sreq = old->sreq;
513 new->ir_ctrl = old->ir_ctrl;
514 new->base_off = old->base_off;
515 new->lcr = old->lcr;
516 new->lbr = old->lbr;
517 new->scratch = old->scratch;
518 new->base_nibble = old->base_nibble;
519 new->disp_addr = old->disp_addr;
520 new->line_offset = old->line_offset;
521 new->line_count = old->line_count;
522 new->unknown = old->unknown;
523 new->t1_ctrl = old->t1_ctrl;
524 new->t2_ctrl = old->t2_ctrl;
525 new->menu_addr = old->menu_addr;
526 new->unknown2 = old->unknown2;
527 new->timer1 = old->timer1;
528 new->timer2 = old->timer2;
529 new->t1_instr = old->t1_instr;
530 new->t2_instr = old->t2_instr;
531 new->t1_tick = old->t1_tick;
532 new->t2_tick = old->t2_tick;
533 new->i_per_s = old->i_per_s;
534 new->bank_switch = 0;
535 if (opt_gx)
536 {
537 new->mem_cntl[0].unconfigured = 0;
538 new->mem_cntl[0].config[0] = 0x00100;
539 new->mem_cntl[1].unconfigured = 0;
540 new->mem_cntl[1].config[0] = 0x80000;
541 new->mem_cntl[1].config[1] = 0xc0000;
542 new->mem_cntl[2].unconfigured = 0;
543 new->mem_cntl[2].config[0] = 0x7f000;
544 new->mem_cntl[2].config[1] = 0xff000;
545 new->mem_cntl[3].unconfigured = 0;
546 new->mem_cntl[3].config[0] = 0xc0000;
547 new->mem_cntl[3].config[1] = 0xc0000;
548 new->mem_cntl[4].unconfigured = 0;
549 new->mem_cntl[4].config[0] = 0xc0000;
550 new->mem_cntl[4].config[1] = 0xc0000;
551 new->mem_cntl[5].unconfigured = 0;
552 new->mem_cntl[5].config[0] = 0x00000;
553 new->mem_cntl[5].config[1] = 0x00000;
554 }
555 else
556 {
557 if (old->devices == 0x100)
558 {
559 new->mem_cntl[0].unconfigured = 0;
560 new->mem_cntl[0].config[0] = old->devices;
561 }
562 else
563 {
564 new->mem_cntl[0].unconfigured = 1;
565 new->mem_cntl[0].config[0] = 0x00000;
566 }
567 if (old->ram32k == 0x70000)
568 {
569 new->mem_cntl[1].unconfigured = 0;
570 new->mem_cntl[1].config[0] = 0x70000;
571 new->mem_cntl[1].config[1] = 0xf0000;
572 }
573 else if (old->ram32k == 0xf0000)
574 {
575 new->mem_cntl[1].unconfigured = 0;
576 new->mem_cntl[1].config[0] = 0xf0000;
577 new->mem_cntl[1].config[1] = 0xf0000;
578 }
579 else if (old->ram32k == 0xfc000)
580 {
581 new->mem_cntl[1].unconfigured = 0;
582 new->mem_cntl[1].config[0] = 0x70000;
583 new->mem_cntl[1].config[1] = 0xfc000;
584 }
585 else if (old->ram32k == 0xfe000)
586 {
587 new->mem_cntl[1].unconfigured = 0;
588 new->mem_cntl[1].config[0] = 0x70000;
589 new->mem_cntl[1].config[1] = 0xfe000;
590 }
591 else
592 {
593 new->mem_cntl[1].unconfigured = 2;
594 new->mem_cntl[1].config[0] = 0x00000;
595 new->mem_cntl[1].config[1] = 0x00000;
596 }
597 new->mem_cntl[2].unconfigured = 0;
598 new->mem_cntl[2].config[0] = 0x80000;
599 new->mem_cntl[2].config[1] = 0xc0000;
600 new->mem_cntl[3].unconfigured = 0;
601 new->mem_cntl[3].config[0] = 0xc0000;
602 new->mem_cntl[3].config[1] = 0xc0000;
603 new->mem_cntl[4].unconfigured = 0;
604 new->mem_cntl[4].config[0] = 0xd0000;
605 new->mem_cntl[4].config[1] = 0xff000;
606 new->mem_cntl[5].unconfigured = 0;
607 new->mem_cntl[5].config[0] = 0x00000;
608 new->mem_cntl[5].config[1] = 0x80000;
609 }
610 }
611
612 int
613 #ifdef __FunctionProto__
read_8(FILE * fp,word_8 * var)614 read_8(FILE *fp, word_8 *var)
615 #else
616 read_8(fp, var)
617 FILE *fp;
618 word_8 *var;
619 #endif
620 {
621 unsigned char tmp;
622
623 if (fread(&tmp, 1, 1, fp) != 1) {
624 if (!quiet)
625 fprintf(stderr, "%s: can\'t read word_8\n", progname);
626 return 0;
627 }
628 *var = tmp;
629 return 1;
630 }
631
632 int
633 #ifdef __FunctionProto__
read_char(FILE * fp,char * var)634 read_char(FILE *fp, char *var)
635 #else
636 read_char(fp, var)
637 FILE *fp;
638 char *var;
639 #endif
640 {
641 char tmp;
642
643 if (fread(&tmp, 1, 1, fp) != 1) {
644 if (!quiet)
645 fprintf(stderr, "%s: can\'t read char\n", progname);
646 return 0;
647 }
648 *var = tmp;
649 return 1;
650 }
651
652 int
653 #ifdef __FunctionProto__
read_16(FILE * fp,word_16 * var)654 read_16(FILE *fp, word_16 *var)
655 #else
656 read_16(fp, var)
657 FILE *fp;
658 word_16 *var;
659 #endif
660 {
661 unsigned char tmp[2];
662
663 if (fread(&tmp[0], 1, 2, fp) != 2) {
664 if (!quiet)
665 fprintf(stderr, "%s: can\'t read word_16\n", progname);
666 return 0;
667 }
668 *var = tmp[0] << 8;
669 *var |= tmp[1];
670 return 1;
671 }
672
673 int
674 #ifdef __FunctionProto__
read_32(FILE * fp,word_32 * var)675 read_32(FILE *fp, word_32 *var)
676 #else
677 read_32(fp, var)
678 FILE *fp;
679 word_32 *var;
680 #endif
681 {
682 unsigned char tmp[4];
683
684 if (fread(&tmp[0], 1, 4, fp) != 4) {
685 if (!quiet)
686 fprintf(stderr, "%s: can\'t read word_32\n", progname);
687 return 0;
688 }
689 *var = tmp[0] << 24;
690 *var |= tmp[1] << 16;
691 *var |= tmp[2] << 8;
692 *var |= tmp[3];
693 return 1;
694 }
695
696 int
697 #ifdef __FunctionProto__
read_u_long(FILE * fp,unsigned long * var)698 read_u_long(FILE *fp, unsigned long *var)
699 #else
700 read_u_long(fp, var)
701 FILE *fp;
702 unsigned long*var;
703 #endif
704 {
705 unsigned char tmp[4];
706
707 if (fread(&tmp[0], 1, 4, fp) != 4) {
708 if (!quiet)
709 fprintf(stderr, "%s: can\'t read unsigned long\n", progname);
710 return 0;
711 }
712 *var = tmp[0] << 24;
713 *var |= tmp[1] << 16;
714 *var |= tmp[2] << 8;
715 *var |= tmp[3];
716 return 1;
717 }
718
719 int
720 #ifdef __FunctionProto__
read_version_0_3_0_file(FILE * fp)721 read_version_0_3_0_file(FILE *fp)
722 #else
723 read_version_0_3_0_file(fp)
724 FILE *fp;
725 #endif
726 {
727 int i;
728
729 /*
730 * version 0.3.x, read in the saturn_0_3_0_t struct
731 */
732 for (i = 0; i < 16; i++)
733 if(!read_8(fp, &saturn_0_3_0.A[i]))
734 return 0;
735 for (i = 0; i < 16; i++)
736 if (!read_8(fp, &saturn_0_3_0.B[i]))
737 return 0;
738 for (i = 0; i < 16; i++)
739 if (!read_8(fp, &saturn_0_3_0.C[i]))
740 return 0;
741 for (i = 0; i < 16; i++)
742 if (!read_8(fp, &saturn_0_3_0.D[i]))
743 return 0;
744 if (!read_32(fp, &saturn_0_3_0.d[0])) return 0;
745 if (!read_32(fp, &saturn_0_3_0.d[1])) return 0;
746 if (!read_8(fp, &saturn_0_3_0.P)) return 0;
747 if (!read_32(fp, &saturn_0_3_0.PC)) return 0;
748 for (i = 0; i < 16; i++)
749 if (!read_8(fp, &saturn_0_3_0.R0[i]))
750 return 0;
751 for (i = 0; i < 16; i++)
752 if (!read_8(fp, &saturn_0_3_0.R1[i]))
753 return 0;
754 for (i = 0; i < 16; i++)
755 if (!read_8(fp, &saturn_0_3_0.R2[i]))
756 return 0;
757 for (i = 0; i < 16; i++)
758 if (!read_8(fp, &saturn_0_3_0.R3[i]))
759 return 0;
760 for (i = 0; i < 16; i++)
761 if (!read_8(fp, &saturn_0_3_0.R4[i]))
762 return 0;
763 for (i = 0; i < 4; i++)
764 if (!read_8(fp, &saturn_0_3_0.IN[i]))
765 return 0;
766 for (i = 0; i < 3; i++)
767 if (!read_8(fp, &saturn_0_3_0.OUT[i]))
768 return 0;
769 if (!read_8(fp, &saturn_0_3_0.CARRY))
770 return 0;
771 for (i = 0; i < NR_PSTAT; i++)
772 if (!read_8(fp, &saturn_0_3_0.PSTAT[i]))
773 return 0;
774 if (!read_8(fp, &saturn_0_3_0.XM)) return 0;
775 if (!read_8(fp, &saturn_0_3_0.SB)) return 0;
776 if (!read_8(fp, &saturn_0_3_0.SR)) return 0;
777 if (!read_8(fp, &saturn_0_3_0.MP)) return 0;
778 if (!read_8(fp, &saturn_0_3_0.hexmode)) return 0;
779 for (i = 0; i < NR_RSTK; i++)
780 if (!read_32(fp, &saturn_0_3_0.rstk[i]))
781 return 0;
782 if (!read_16(fp, (word_16 *)&saturn_0_3_0.rstkp)) return 0;
783 for (i = 0; i < 9; i++)
784 if (!read_16(fp, (word_16 *)&saturn_0_3_0.keybuf.rows[i]))
785 return 0;
786 if (!read_8(fp, &saturn_0_3_0.intenable)) return 0;
787 if (!read_8(fp, &saturn_0_3_0.int_pending)) return 0;
788 if (!read_8(fp, &saturn_0_3_0.kbd_ien)) return 0;
789 for (i = 0; i < NR_CONFIG; i++)
790 if (!read_32(fp, &saturn_0_3_0.configs[i]))
791 return 0;
792 if (!read_16(fp, (word_16 *)&saturn_0_3_0.daisy_state)) return 0;
793 if (!read_32(fp, &saturn_0_3_0.ram32k)) return 0;
794 if (!read_32(fp, &saturn_0_3_0.devices)) return 0;
795 if (!read_8(fp, &saturn_0_3_0.disp_io)) return 0;
796 if (!read_8(fp, &saturn_0_3_0.contrast_ctrl)) return 0;
797 if (!read_8(fp, &saturn_0_3_0.disp_test)) return 0;
798 if (!read_16(fp, &saturn_0_3_0.crc)) return 0;
799 if (!read_8(fp, &saturn_0_3_0.power_status)) return 0;
800 if (!read_8(fp, &saturn_0_3_0.power_ctrl)) return 0;
801 if (!read_8(fp, &saturn_0_3_0.mode)) return 0;
802 if (!read_8(fp, &saturn_0_3_0.annunc)) return 0;
803 if (!read_8(fp, &saturn_0_3_0.baud)) return 0;
804 if (!read_8(fp, &saturn_0_3_0.card_ctrl)) return 0;
805 if (!read_8(fp, &saturn_0_3_0.card_status)) return 0;
806 if (!read_8(fp, &saturn_0_3_0.io_ctrl)) return 0;
807 if (!read_8(fp, &saturn_0_3_0.rcs)) return 0;
808 if (!read_8(fp, &saturn_0_3_0.tcs)) return 0;
809 if (!read_8(fp, &saturn_0_3_0.rbr)) return 0;
810 if (!read_8(fp, &saturn_0_3_0.tbr)) return 0;
811 if (!read_8(fp, &saturn_0_3_0.sreq)) return 0;
812 if (!read_8(fp, &saturn_0_3_0.ir_ctrl)) return 0;
813 if (!read_8(fp, &saturn_0_3_0.base_off)) return 0;
814 if (!read_8(fp, &saturn_0_3_0.lcr)) return 0;
815 if (!read_8(fp, &saturn_0_3_0.lbr)) return 0;
816 if (!read_8(fp, &saturn_0_3_0.scratch)) return 0;
817 if (!read_8(fp, &saturn_0_3_0.base_nibble)) return 0;
818 if (!read_32(fp, &saturn_0_3_0.disp_addr)) return 0;
819 if (!read_16(fp, &saturn_0_3_0.line_offset)) return 0;
820 if (!read_8(fp, &saturn_0_3_0.line_count)) return 0;
821 if (!read_16(fp, &saturn_0_3_0.unknown)) return 0;
822 if (!read_8(fp, &saturn_0_3_0.t1_ctrl)) return 0;
823 if (!read_8(fp, &saturn_0_3_0.t2_ctrl)) return 0;
824 if (!read_32(fp, &saturn_0_3_0.menu_addr)) return 0;
825 if (!read_8(fp, &saturn_0_3_0.unknown2)) return 0;
826 if (!read_char(fp, &saturn_0_3_0.timer1)) return 0;
827 if (!read_32(fp, &saturn_0_3_0.timer2)) return 0;
828 if (!read_32(fp, &saturn_0_3_0.t1_instr)) return 0;
829 if (!read_32(fp, &saturn_0_3_0.t2_instr)) return 0;
830 if (!read_16(fp, (word_16 *)&saturn_0_3_0.t1_tick)) return 0;
831 if (!read_16(fp, (word_16 *)&saturn_0_3_0.t2_tick)) return 0;
832 if (!read_32(fp, &saturn_0_3_0.i_per_s)) return 0;
833 return 1;
834 }
835
836 int
837 #ifdef __FunctionProto__
read_version_0_4_0_file(FILE * fp)838 read_version_0_4_0_file(FILE *fp)
839 #else
840 read_version_0_4_0_file(fp)
841 FILE *fp;
842 #endif
843 {
844 int i;
845
846 /*
847 * version 0.4.x, read in the saturn_t struct
848 */
849 for (i = 0; i < 16; i++)
850 if(!read_8(fp, &saturn.A[i]))
851 return 0;
852 for (i = 0; i < 16; i++)
853 if (!read_8(fp, &saturn.B[i]))
854 return 0;
855 for (i = 0; i < 16; i++)
856 if (!read_8(fp, &saturn.C[i]))
857 return 0;
858 for (i = 0; i < 16; i++)
859 if (!read_8(fp, &saturn.D[i]))
860 return 0;
861 if (!read_32(fp, &saturn.d[0])) return 0;
862 if (!read_32(fp, &saturn.d[1])) return 0;
863 if (!read_8(fp, &saturn.P)) return 0;
864 if (!read_32(fp, &saturn.PC)) return 0;
865 for (i = 0; i < 16; i++)
866 if (!read_8(fp, &saturn.R0[i]))
867 return 0;
868 for (i = 0; i < 16; i++)
869 if (!read_8(fp, &saturn.R1[i]))
870 return 0;
871 for (i = 0; i < 16; i++)
872 if (!read_8(fp, &saturn.R2[i]))
873 return 0;
874 for (i = 0; i < 16; i++)
875 if (!read_8(fp, &saturn.R3[i]))
876 return 0;
877 for (i = 0; i < 16; i++)
878 if (!read_8(fp, &saturn.R4[i]))
879 return 0;
880 for (i = 0; i < 4; i++)
881 if (!read_8(fp, &saturn.IN[i]))
882 return 0;
883 for (i = 0; i < 3; i++)
884 if (!read_8(fp, &saturn.OUT[i]))
885 return 0;
886 if (!read_8(fp, &saturn.CARRY))
887 return 0;
888 for (i = 0; i < NR_PSTAT; i++)
889 if (!read_8(fp, &saturn.PSTAT[i]))
890 return 0;
891 if (!read_8(fp, &saturn.XM)) return 0;
892 if (!read_8(fp, &saturn.SB)) return 0;
893 if (!read_8(fp, &saturn.SR)) return 0;
894 if (!read_8(fp, &saturn.MP)) return 0;
895 if (!read_8(fp, &saturn.hexmode)) return 0;
896 for (i = 0; i < NR_RSTK; i++)
897 if (!read_32(fp, &saturn.rstk[i]))
898 return 0;
899 if (!read_16(fp, (word_16 *)&saturn.rstkp)) return 0;
900 for (i = 0; i < 9; i++)
901 if (!read_16(fp, (word_16 *)&saturn.keybuf.rows[i]))
902 return 0;
903 if (!read_8(fp, &saturn.intenable)) return 0;
904 if (!read_8(fp, &saturn.int_pending)) return 0;
905 if (!read_8(fp, &saturn.kbd_ien)) return 0;
906 if (!read_8(fp, &saturn.disp_io)) return 0;
907 if (!read_8(fp, &saturn.contrast_ctrl)) return 0;
908 if (!read_8(fp, &saturn.disp_test)) return 0;
909 if (!read_16(fp, &saturn.crc)) return 0;
910 if (!read_8(fp, &saturn.power_status)) return 0;
911 if (!read_8(fp, &saturn.power_ctrl)) return 0;
912 if (!read_8(fp, &saturn.mode)) return 0;
913 if (!read_8(fp, &saturn.annunc)) return 0;
914 if (!read_8(fp, &saturn.baud)) return 0;
915 if (!read_8(fp, &saturn.card_ctrl)) return 0;
916 if (!read_8(fp, &saturn.card_status)) return 0;
917 if (!read_8(fp, &saturn.io_ctrl)) return 0;
918 if (!read_8(fp, &saturn.rcs)) return 0;
919 if (!read_8(fp, &saturn.tcs)) return 0;
920 if (!read_8(fp, &saturn.rbr)) return 0;
921 if (!read_8(fp, &saturn.tbr)) return 0;
922 if (!read_8(fp, &saturn.sreq)) return 0;
923 if (!read_8(fp, &saturn.ir_ctrl)) return 0;
924 if (!read_8(fp, &saturn.base_off)) return 0;
925 if (!read_8(fp, &saturn.lcr)) return 0;
926 if (!read_8(fp, &saturn.lbr)) return 0;
927 if (!read_8(fp, &saturn.scratch)) return 0;
928 if (!read_8(fp, &saturn.base_nibble)) return 0;
929 if (!read_32(fp, &saturn.disp_addr)) return 0;
930 if (!read_16(fp, &saturn.line_offset)) return 0;
931 if (!read_8(fp, &saturn.line_count)) return 0;
932 if (!read_16(fp, &saturn.unknown)) return 0;
933 if (!read_8(fp, &saturn.t1_ctrl)) return 0;
934 if (!read_8(fp, &saturn.t2_ctrl)) return 0;
935 if (!read_32(fp, &saturn.menu_addr)) return 0;
936 if (!read_8(fp, &saturn.unknown2)) return 0;
937 if (!read_char(fp, &saturn.timer1)) return 0;
938 if (!read_32(fp, &saturn.timer2)) return 0;
939 if (!read_32(fp, &saturn.t1_instr)) return 0;
940 if (!read_32(fp, &saturn.t2_instr)) return 0;
941 if (!read_16(fp, (word_16 *)&saturn.t1_tick)) return 0;
942 if (!read_16(fp, (word_16 *)&saturn.t2_tick)) return 0;
943 if (!read_32(fp, &saturn.i_per_s)) return 0;
944 if (!read_16(fp, (word_16 *)&saturn.bank_switch)) return 0;
945 for (i = 0; i < NR_MCTL; i++)
946 {
947 if (!read_16(fp, &saturn.mem_cntl[i].unconfigured)) return 0;
948 if (!read_32(fp, &saturn.mem_cntl[i].config[0])) return 0;
949 if (!read_32(fp, &saturn.mem_cntl[i].config[1])) return 0;
950 }
951 return 1;
952 }
953
954 int
955 #ifdef __FunctionProto__
read_mem_file(char * name,word_4 * mem,int size)956 read_mem_file(char *name, word_4 *mem, int size)
957 #else
958 read_mem_file(name, mem, size)
959 char *name;
960 word_4 *mem;
961 int size;
962 #endif
963 {
964 struct stat st;
965 FILE *fp;
966 word_8 *tmp_mem;
967 word_8 byte;
968 int i, j;
969
970 if (NULL == (fp = fopen(name, "r")))
971 {
972 if (!quiet)
973 fprintf(stderr, "%s: can\'t open %s\n", progname, name);
974 return 0;
975 }
976
977 if (stat(name, &st) < 0)
978 {
979 if (!quiet)
980 fprintf(stderr, "%s: can\'t stat %s\n", progname, name);
981 return 0;
982 }
983
984 if (st.st_size == size)
985 {
986 /*
987 * size is same as memory size, old version file
988 */
989 if (fread(mem, 1, (size_t)size, fp) != size)
990 {
991 if (!quiet)
992 fprintf(stderr, "%s: can\'t read %s\n", progname, name);
993 fclose(fp);
994 return 0;
995 }
996 }
997 else
998 {
999 /*
1000 * size is different, check size and decompress memory
1001 */
1002
1003 if (st.st_size != size / 2)
1004 {
1005 if (!quiet)
1006 fprintf(stderr, "%s: strange size %s, expected %d, found %ld\n",
1007 progname, name, size / 2, st.st_size);
1008 fclose(fp);
1009 return 0;
1010 }
1011
1012 if (NULL == (tmp_mem = (word_8 *)malloc((size_t)st.st_size)))
1013 {
1014 for (i = 0, j = 0; i < size / 2; i++)
1015 {
1016 if (1 != fread(&byte, 1, 1, fp))
1017 {
1018 if (!quiet)
1019 fprintf(stderr, "%s: can\'t read %s\n", progname, name);
1020 fclose(fp);
1021 return 0;
1022 }
1023 mem[j++] = (word_4)((int)byte & 0xf);
1024 mem[j++] = (word_4)(((int)byte >> 4) & 0xf);
1025 }
1026 }
1027 else
1028 {
1029 if (fread(tmp_mem, 1, (size_t)size / 2, fp) != size / 2)
1030 {
1031 if (!quiet)
1032 fprintf(stderr, "%s: can\'t read %s\n", progname, name);
1033 fclose(fp);
1034 free(tmp_mem);
1035 return 0;
1036 }
1037
1038 for (i = 0, j = 0; i < size / 2; i++)
1039 {
1040 mem[j++] = (word_4)((int)tmp_mem[i] & 0xf);
1041 mem[j++] = (word_4)(((int)tmp_mem[i] >> 4) & 0xf);
1042 }
1043
1044 free(tmp_mem);
1045 }
1046 }
1047
1048 fclose(fp);
1049
1050 if (verbose)
1051 printf("%s: read %s\n", progname, name);
1052
1053 return 1;
1054 }
1055
1056 int
1057 #ifdef __FunctionProto__
read_rom(const char * fname)1058 read_rom(const char *fname)
1059 #else
1060 read_rom(fname)
1061 const char *fname;
1062 #endif
1063 {
1064 int ram_size;
1065
1066 if (!read_rom_file(romFileName, &saturn.rom, &rom_size))
1067 return 0;
1068 dev_memory_init();
1069
1070 if (opt_gx)
1071 ram_size = RAM_SIZE_GX;
1072 else
1073 ram_size = RAM_SIZE_SX;
1074
1075 if (NULL == (saturn.ram = (word_4 *)malloc(ram_size)))
1076 {
1077 if (!quiet)
1078 fprintf(stderr, "%s: can\'t malloc RAM\n", progname);
1079 return 0;
1080 }
1081
1082 memset(saturn.ram, 0, ram_size);
1083
1084 port1_size = 0;
1085 port1_mask = 0;
1086 port1_is_ram = 0;
1087 saturn.port1 = (unsigned char *)0;
1088
1089 port2_size = 0;
1090 port2_mask = 0;
1091 port2_is_ram = 0;
1092 saturn.port2 = (unsigned char *)0;
1093
1094 saturn.card_status = 0;
1095
1096 return 1;
1097 }
1098
1099 void
1100 #ifdef __FunctionProto__
get_home_directory(char * path)1101 get_home_directory(char *path)
1102 #else
1103 get_home_directory(path)
1104 char *path;
1105 #endif
1106 {
1107 char *p;
1108 struct passwd *pwd;
1109
1110 if (homeDirectory[0] == '/')
1111 {
1112 strcpy(path, homeDirectory);
1113 }
1114 else
1115 {
1116 p = getenv("HOME");
1117 if (p)
1118 {
1119 strcpy(path, p);
1120 strcat(path, "/");
1121 }
1122 else
1123 {
1124 pwd = getpwuid(getuid());
1125 if (pwd)
1126 {
1127 strcpy(path, pwd->pw_dir);
1128 strcat(path, "/");
1129 }
1130 else
1131 {
1132 if (!quiet)
1133 fprintf(stderr,
1134 "%s: can\'t figure out your home directory, trying /tmp\n",
1135 progname);
1136 strcpy(path, "/tmp");
1137 }
1138 }
1139 strcat(path, homeDirectory);
1140 }
1141 }
1142
1143 int
1144 #ifdef __FunctionProto__
read_files(void)1145 read_files(void)
1146 #else
1147 read_files()
1148 #endif
1149 {
1150 char path[1024];
1151 char fnam[1024];
1152 unsigned long v1, v2;
1153 int i, read_version;
1154 int ram_size;
1155 struct stat st;
1156 FILE *fp;
1157
1158 get_home_directory(path);
1159 strcat(path, "/");
1160
1161 saturn.rom = (word_4 *)NULL;
1162 strcpy(fnam, path);
1163 strcat(fnam, "rom");
1164 if (!read_rom_file(fnam, &saturn.rom, &rom_size))
1165 return 0;
1166
1167 rom_is_new = 0;
1168
1169 strcpy(fnam, path);
1170 strcat(fnam, "hp48");
1171 if (NULL == (fp = fopen(fnam, "r")))
1172 {
1173 if (!quiet)
1174 fprintf(stderr, "%s: can\'t open %s\n", progname, fnam);
1175 return 0;
1176 }
1177
1178 /*
1179 * ok, file is open, try to read the MAGIC number
1180 */
1181 read_u_long(fp, &saturn.magic);
1182
1183 if (X48_MAGIC != saturn.magic)
1184 {
1185 /*
1186 * no MAGIC number, try to read old format file
1187 */
1188 fseek(fp, 0, SEEK_SET);
1189 if (fread((char *)&old_saturn, 1, sizeof(old_saturn), fp)
1190 == sizeof(old_saturn)) {
1191 /*
1192 * seems to work
1193 */
1194 copy_old_saturn(&old_saturn, &saturn);
1195 if (!quiet)
1196 fprintf(stderr, "%s: %s seems to be an old version file\n",
1197 progname, fnam);
1198 saturn.magic = X48_MAGIC;
1199 saturn.t1_tick = 8192;
1200 saturn.t2_tick = 16;
1201 saturn.i_per_s = 0;
1202 saturn.version[0] = VERSION_MAJOR;
1203 saturn.version[1] = VERSION_MINOR;
1204 saturn.version[2] = PATCHLEVEL;
1205 saturn.version[3] = COMPILE_VERSION;
1206 } else {
1207 /*
1208 * no, initialize
1209 */
1210 if (!quiet)
1211 fprintf(stderr, "%s: can\'t handle %s\n", progname, fnam);
1212 init_saturn();
1213 }
1214 } else {
1215 /*
1216 * MAGIC ok, read and compare the version
1217 */
1218 read_version = 1;
1219 for (i = 0; i < 4; i++) {
1220 if (!read_char(fp, &saturn.version[i])) {
1221 if (!quiet)
1222 fprintf(stderr, "%s: can\'t read version\n", progname);
1223 read_version = 0;
1224 }
1225 }
1226
1227 if (read_version) {
1228 v1 = ((int)saturn.version[0] & 0xff) << 24;
1229 v1 |= ((int)saturn.version[1] & 0xff) << 16;
1230 v1 |= ((int)saturn.version[2] & 0xff) << 8;
1231 v1 |= ((int)saturn.version[3] & 0xff);
1232 v2 = ((int)VERSION_MAJOR & 0xff) << 24;
1233 v2 |= ((int)VERSION_MINOR & 0xff) << 16;
1234 v2 |= ((int)PATCHLEVEL & 0xff) << 8;
1235 v2 |= ((int)COMPILE_VERSION & 0xff);
1236
1237 if ((v1 & 0xffffff00) < (v2 & 0xffffff00)) {
1238 if (!quiet)
1239 fprintf(stderr, "%s: %s is a version %d.%d.%d file, converting\n",
1240 progname, fnam,
1241 saturn.version[0], saturn.version[1], saturn.version[2]);
1242 } else if ((v2 & 0xffffff00) < (v1 & 0xffffff00)) {
1243 if (!quiet)
1244 fprintf(stderr, "%s: %s is a version %d.%d.%d file, trying ...\n",
1245 progname, fnam,
1246 saturn.version[0], saturn.version[1], saturn.version[2]);
1247 }
1248
1249 if (v1 < 0x00040000)
1250 {
1251 /*
1252 * read version < 0.4 file
1253 */
1254 if (!read_version_0_3_0_file(fp))
1255 {
1256 if (!quiet)
1257 fprintf(stderr, "%s: can\'t handle %s\n", progname, fnam);
1258 init_saturn();
1259 }
1260 else
1261 {
1262 copy_0_3_0_saturn(&saturn_0_3_0, &saturn);
1263 if (verbose)
1264 printf("%s: read %s\n", progname, fnam);
1265 }
1266 }
1267 else if (v1 <= v2) {
1268 /*
1269 * read latest version file
1270 */
1271 if (!read_version_0_4_0_file(fp))
1272 {
1273 if (!quiet)
1274 fprintf(stderr, "%s: can\'t handle %s\n", progname, fnam);
1275 init_saturn();
1276 }
1277 else if (verbose)
1278 {
1279 printf("%s: read %s\n", progname, fnam);
1280 }
1281 } else {
1282 /*
1283 * try to read latest version file
1284 */
1285 if (!read_version_0_4_0_file(fp))
1286 {
1287 if (!quiet)
1288 fprintf(stderr, "%s: can\'t handle %s\n", progname, fnam);
1289 init_saturn();
1290 }
1291 else if (verbose)
1292 {
1293 printf("%s: read %s\n", progname, fnam);
1294 }
1295 }
1296 }
1297 }
1298 fclose(fp);
1299
1300 dev_memory_init();
1301
1302 saturn_config_init();
1303
1304 if (opt_gx)
1305 ram_size = RAM_SIZE_GX;
1306 else
1307 ram_size = RAM_SIZE_SX;
1308
1309 saturn.ram = (word_4 *)NULL;
1310 if (NULL == (saturn.ram = (word_4 *)malloc(ram_size)))
1311 {
1312 if (!quiet)
1313 fprintf(stderr, "%s: can\'t malloc RAM[%d]\n",
1314 progname, ram_size);
1315 exit (1);
1316 }
1317
1318 strcpy(fnam, path);
1319 strcat(fnam, "ram");
1320 if ((fp = fopen(fnam, "r")) == NULL) {
1321 if (!quiet)
1322 fprintf(stderr, "%s: can\'t open %s\n", progname, fnam);
1323 return 0;
1324 }
1325 if (!read_mem_file(fnam, saturn.ram, ram_size))
1326 return 0;
1327
1328 saturn.card_status = 0;
1329
1330 port1_size = 0;
1331 port1_mask = 0;
1332 port1_is_ram = 0;
1333 saturn.port1 = (unsigned char *)0;
1334
1335 strcpy(fnam, path);
1336 strcat(fnam, "port1");
1337 if (stat(fnam, &st) >= 0)
1338 {
1339 port1_size = 2 * st.st_size;
1340 if ((port1_size == 0x10000) || (port1_size == 0x40000))
1341 {
1342 if (NULL == (saturn.port1 = (word_4 *)malloc(port1_size)))
1343 {
1344 if (!quiet)
1345 fprintf(stderr, "%s: can\'t malloc PORT1[%ld]\n",
1346 progname, port1_size);
1347 }
1348 else if (!read_mem_file(fnam, saturn.port1, port1_size))
1349 {
1350 port1_size = 0;
1351 port1_is_ram = 0;
1352 }
1353 else
1354 {
1355 port1_is_ram = (st.st_mode & S_IWUSR) ? 1 : 0;
1356 port1_mask = port1_size - 1;
1357 }
1358 }
1359 }
1360
1361 if (opt_gx)
1362 {
1363 saturn.card_status |= (port1_size > 0) ? 2 : 0;
1364 saturn.card_status |= port1_is_ram ? 8 : 0;
1365 }
1366 else
1367 {
1368 saturn.card_status |= (port1_size > 0) ? 1 : 0;
1369 saturn.card_status |= port1_is_ram ? 4 : 0;
1370 }
1371
1372 port2_size = 0;
1373 port2_mask = 0;
1374 port2_is_ram = 0;
1375 saturn.port2 = (unsigned char *)0;
1376
1377 strcpy(fnam, path);
1378 strcat(fnam, "port2");
1379 if (stat(fnam, &st) >= 0)
1380 {
1381 port2_size = 2 * st.st_size;
1382 if ((opt_gx && ((port2_size % 0x40000) == 0)) ||
1383 (!opt_gx && ((port2_size == 0x10000) || (port2_size == 0x40000))))
1384 {
1385 if (NULL == (saturn.port2 = (word_4 *)malloc(port2_size)))
1386 {
1387 if (!quiet)
1388 fprintf(stderr, "%s: can\'t malloc PORT2[%ld]\n",
1389 progname, port2_size);
1390 }
1391 else if (!read_mem_file(fnam, saturn.port2, port2_size))
1392 {
1393 port2_size = 0;
1394 port2_is_ram = 0;
1395 }
1396 else
1397 {
1398 port2_is_ram = (st.st_mode & S_IWUSR) ? 1 : 0;
1399 port2_mask = port2_size - 1;
1400 }
1401 }
1402 }
1403
1404 if (opt_gx)
1405 {
1406 saturn.card_status |= (port2_size > 0) ? 1 : 0;
1407 saturn.card_status |= port2_is_ram ? 4 : 0;
1408 }
1409 else
1410 {
1411 saturn.card_status |= (port2_size > 0) ? 2 : 0;
1412 saturn.card_status |= port2_is_ram ? 8 : 0;
1413 }
1414
1415 return 1;
1416 }
1417
1418 int
1419 #ifdef __FunctionProto__
write_8(FILE * fp,word_8 * var)1420 write_8(FILE *fp, word_8 *var)
1421 #else
1422 write_8(fp, var)
1423 FILE *fp;
1424 word_8 *var;
1425 #endif
1426 {
1427 unsigned char tmp;
1428
1429 tmp = *var;
1430 if (fwrite(&tmp, 1, 1, fp) != 1) {
1431 if (!quiet)
1432 fprintf(stderr, "%s: can\'t write word_8\n", progname);
1433 return 0;
1434 }
1435 return 1;
1436 }
1437
1438 int
1439 #ifdef __FunctionProto__
write_char(FILE * fp,char * var)1440 write_char(FILE *fp, char *var)
1441 #else
1442 write_char(fp, var)
1443 FILE *fp;
1444 char *var;
1445 #endif
1446 {
1447 char tmp;
1448
1449 tmp = *var;
1450 if (fwrite(&tmp, 1, 1, fp) != 1) {
1451 if (!quiet)
1452 fprintf(stderr, "%s: can\'t write char\n", progname);
1453 return 0;
1454 }
1455 return 1;
1456 }
1457
1458 int
1459 #ifdef __FunctionProto__
write_16(FILE * fp,word_16 * var)1460 write_16(FILE *fp, word_16 *var)
1461 #else
1462 write_16(fp, var)
1463 FILE *fp;
1464 word_16 *var;
1465 #endif
1466 {
1467 unsigned char tmp[2];
1468
1469 tmp[0] = (*var >> 8) & 0xff;
1470 tmp[1] = *var & 0xff;
1471 if (fwrite(&tmp[0], 1, 2, fp) != 2) {
1472 if (!quiet)
1473 fprintf(stderr, "%s: can\'t write word_16\n", progname);
1474 return 0;
1475 }
1476 return 1;
1477 }
1478
1479 int
1480 #ifdef __FunctionProto__
write_32(FILE * fp,word_32 * var)1481 write_32(FILE *fp, word_32 *var)
1482 #else
1483 write_32(fp, var)
1484 FILE *fp;
1485 word_32 *var;
1486 #endif
1487 {
1488 unsigned char tmp[4];
1489
1490 tmp[0] = (*var >> 24) & 0xff;
1491 tmp[1] = (*var >> 16) & 0xff;
1492 tmp[2] = (*var >> 8) & 0xff;
1493 tmp[3] = *var & 0xff;
1494 if (fwrite(&tmp[0], 1, 4, fp) != 4) {
1495 if (!quiet)
1496 fprintf(stderr, "%s: can\'t write word_32\n", progname);
1497 return 0;
1498 }
1499 return 1;
1500 }
1501
1502 int
1503 #ifdef __FunctionProto__
write_u_long(FILE * fp,unsigned long * var)1504 write_u_long(FILE *fp, unsigned long *var)
1505 #else
1506 write_u_long(fp, var)
1507 FILE *fp;
1508 unsigned long*var;
1509 #endif
1510 {
1511 unsigned char tmp[4];
1512
1513 tmp[0] = (*var >> 24) & 0xff;
1514 tmp[1] = (*var >> 16) & 0xff;
1515 tmp[2] = (*var >> 8) & 0xff;
1516 tmp[3] = *var & 0xff;
1517 if (fwrite(&tmp[0], 1, 4, fp) != 4) {
1518 if (!quiet)
1519 fprintf(stderr, "%s: can\'t write unsigned long\n", progname);
1520 return 0;
1521 }
1522 return 1;
1523 }
1524
1525 int
1526 #ifdef __FunctionProto__
write_mem_file(char * name,word_4 * mem,int size)1527 write_mem_file(char *name, word_4 *mem, int size)
1528 #else
1529 write_mem_file(name, mem, size)
1530 char *name;
1531 word_4 *mem;
1532 int size;
1533 #endif
1534 {
1535 FILE *fp;
1536 word_8 *tmp_mem;
1537 word_8 byte;
1538 int i, j;
1539
1540 if (NULL == (fp = fopen(name, "w")))
1541 {
1542 if (!quiet)
1543 fprintf(stderr, "%s: can\'t open %s\n", progname, name);
1544 return 0;
1545 }
1546
1547 if (NULL == (tmp_mem = (word_8 *)malloc((size_t)size / 2)))
1548 {
1549 for (i = 0, j = 0; i < size / 2; i++)
1550 {
1551 byte = (mem[j++] & 0x0f);
1552 byte |= (mem[j++] << 4) & 0xf0;
1553 if (1 != fwrite(&byte, 1, 1, fp))
1554 {
1555 if (!quiet)
1556 fprintf(stderr, "%s: can\'t write %s\n", progname, name);
1557 fclose(fp);
1558 return 0;
1559 }
1560 }
1561 }
1562 else
1563 {
1564 for (i = 0, j = 0; i < size / 2; i++)
1565 {
1566 tmp_mem[i] = (mem[j++] & 0x0f);
1567 tmp_mem[i] |= (mem[j++] << 4) & 0xf0;
1568 }
1569
1570 if (fwrite(tmp_mem, 1, (size_t)size / 2, fp) != size / 2)
1571 {
1572 if (!quiet)
1573 fprintf(stderr, "%s: can\'t write %s\n", progname, name);
1574 fclose(fp);
1575 free(tmp_mem);
1576 return 0;
1577 }
1578
1579 free(tmp_mem);
1580 }
1581
1582 fclose(fp);
1583
1584 if (verbose)
1585 printf("%s: wrote %s\n", progname, name);
1586
1587 return 1;
1588 }
1589
1590
1591 int
1592 #ifdef __FunctionProto__
write_files(void)1593 write_files(void)
1594 #else
1595 write_files()
1596 #endif
1597 {
1598 char path[1024];
1599 char fnam[1024];
1600 struct stat st;
1601 int i, make_dir;
1602 int ram_size;
1603 FILE *fp;
1604
1605 make_dir = 0;
1606 get_home_directory(path);
1607
1608 if (stat(path, &st) == -1)
1609 {
1610 if (errno == ENOENT)
1611 {
1612 make_dir = 1;
1613 }
1614 else
1615 {
1616 if (!quiet)
1617 fprintf(stderr, "%s: can\'t stat %s, saving to /tmp\n",
1618 progname, path);
1619 strcpy(path, "/tmp");
1620 }
1621 }
1622 else
1623 {
1624 if (!S_ISDIR(st.st_mode))
1625 {
1626 if (!quiet)
1627 fprintf(stderr, "%s: %s is no directory, saving to /tmp\n",
1628 progname, path);
1629 strcpy(path, "/tmp");
1630 }
1631 }
1632
1633 if (make_dir)
1634 {
1635 if (mkdir(path, 0777) == -1)
1636 {
1637 if (!quiet)
1638 fprintf(stderr, "%s: can\'t mkdir %s, saving to /tmp\n",
1639 progname, path);
1640 strcpy(path, "/tmp");
1641 }
1642 }
1643
1644 strcat(path, "/");
1645
1646 strcpy(fnam, path);
1647 strcat(fnam, "hp48");
1648 if ((fp = fopen(fnam, "w")) == NULL) {
1649 if (!quiet)
1650 fprintf(stderr, "%s: can\'t open %s, no saving done\n",
1651 progname, fnam);
1652 return 0;
1653 }
1654
1655 /*
1656 * write the hp48 config file
1657 */
1658 write_32(fp, (word_32 *)&saturn.magic);
1659 for (i = 0; i < 4; i++) write_char(fp, &saturn.version[i]);
1660 for (i = 0; i < 16; i++) write_8(fp, &saturn.A[i]);
1661 for (i = 0; i < 16; i++) write_8(fp, &saturn.B[i]);
1662 for (i = 0; i < 16; i++) write_8(fp, &saturn.C[i]);
1663 for (i = 0; i < 16; i++) write_8(fp, &saturn.D[i]);
1664 write_32(fp, &saturn.d[0]);
1665 write_32(fp, &saturn.d[1]);
1666 write_8(fp, &saturn.P);
1667 write_32(fp, &saturn.PC);
1668 for (i = 0; i < 16; i++) write_8(fp, &saturn.R0[i]);
1669 for (i = 0; i < 16; i++) write_8(fp, &saturn.R1[i]);
1670 for (i = 0; i < 16; i++) write_8(fp, &saturn.R2[i]);
1671 for (i = 0; i < 16; i++) write_8(fp, &saturn.R3[i]);
1672 for (i = 0; i < 16; i++) write_8(fp, &saturn.R4[i]);
1673 for (i = 0; i < 4; i++) write_8(fp, &saturn.IN[i]);
1674 for (i = 0; i < 3; i++) write_8(fp, &saturn.OUT[i]);
1675 write_8(fp, &saturn.CARRY);
1676 for (i = 0; i < NR_PSTAT; i++) write_8(fp, &saturn.PSTAT[i]);
1677 write_8(fp, &saturn.XM);
1678 write_8(fp, &saturn.SB);
1679 write_8(fp, &saturn.SR);
1680 write_8(fp, &saturn.MP);
1681 write_8(fp, &saturn.hexmode);
1682 for (i = 0; i < NR_RSTK; i++) write_32(fp, &saturn.rstk[i]);
1683 write_16(fp, (word_16 *)&saturn.rstkp);
1684 for (i = 0; i < 9; i++) write_16(fp, (word_16 *)&saturn.keybuf.rows[i]);
1685 write_8(fp, &saturn.intenable);
1686 write_8(fp, &saturn.int_pending);
1687 write_8(fp, &saturn.kbd_ien);
1688 write_8(fp, &saturn.disp_io);
1689 write_8(fp, &saturn.contrast_ctrl);
1690 write_8(fp, &saturn.disp_test);
1691 write_16(fp, &saturn.crc);
1692 write_8(fp, &saturn.power_status);
1693 write_8(fp, &saturn.power_ctrl);
1694 write_8(fp, &saturn.mode);
1695 write_8(fp, &saturn.annunc);
1696 write_8(fp, &saturn.baud);
1697 write_8(fp, &saturn.card_ctrl);
1698 write_8(fp, &saturn.card_status);
1699 write_8(fp, &saturn.io_ctrl);
1700 write_8(fp, &saturn.rcs);
1701 write_8(fp, &saturn.tcs);
1702 write_8(fp, &saturn.rbr);
1703 write_8(fp, &saturn.tbr);
1704 write_8(fp, &saturn.sreq);
1705 write_8(fp, &saturn.ir_ctrl);
1706 write_8(fp, &saturn.base_off);
1707 write_8(fp, &saturn.lcr);
1708 write_8(fp, &saturn.lbr);
1709 write_8(fp, &saturn.scratch);
1710 write_8(fp, &saturn.base_nibble);
1711 write_32(fp, &saturn.disp_addr);
1712 write_16(fp, &saturn.line_offset);
1713 write_8(fp, &saturn.line_count);
1714 write_16(fp, &saturn.unknown);
1715 write_8(fp, &saturn.t1_ctrl);
1716 write_8(fp, &saturn.t2_ctrl);
1717 write_32(fp, &saturn.menu_addr);
1718 write_8(fp, &saturn.unknown2);
1719 write_char(fp, &saturn.timer1);
1720 write_32(fp, &saturn.timer2);
1721 write_32(fp, &saturn.t1_instr);
1722 write_32(fp, &saturn.t2_instr);
1723 write_16(fp, (word_16 *)&saturn.t1_tick);
1724 write_16(fp, (word_16 *)&saturn.t2_tick);
1725 write_32(fp, &saturn.i_per_s);
1726 write_16(fp, &saturn.bank_switch);
1727 for (i = 0; i < NR_MCTL; i++)
1728 {
1729 write_16(fp, &saturn.mem_cntl[i].unconfigured);
1730 write_32(fp, &saturn.mem_cntl[i].config[0]);
1731 write_32(fp, &saturn.mem_cntl[i].config[1]);
1732 }
1733 fclose(fp);
1734 if (verbose)
1735 printf("%s: wrote %s\n", progname, fnam);
1736
1737 if (rom_is_new)
1738 {
1739 strcpy(fnam, path);
1740 strcat(fnam, "rom");
1741 if (!write_mem_file(fnam, saturn.rom, rom_size))
1742 return 0;
1743 }
1744
1745 if (opt_gx)
1746 ram_size = RAM_SIZE_GX;
1747 else
1748 ram_size = RAM_SIZE_SX;
1749
1750 strcpy(fnam, path);
1751 strcat(fnam, "ram");
1752 if (!write_mem_file(fnam, saturn.ram, ram_size))
1753 return 0;
1754
1755 if ((port1_size > 0) && port1_is_ram)
1756 {
1757 strcpy(fnam, path);
1758 strcat(fnam, "port1");
1759 if (!write_mem_file(fnam, saturn.port1, port1_size))
1760 return 0;
1761 }
1762
1763 if ((port2_size > 0) && port2_is_ram)
1764 {
1765 strcpy(fnam, path);
1766 strcat(fnam, "port2");
1767 if (!write_mem_file(fnam, saturn.port2, port2_size))
1768 return 0;
1769 }
1770
1771 return 1;
1772 }
1773
1774 int
1775 #ifdef __FunctionProto__
init_emulator(void)1776 init_emulator(void)
1777 #else
1778 init_emulator()
1779 #endif
1780 {
1781 if (!initialize)
1782 if (read_files())
1783 {
1784 if (resetOnStartup)
1785 saturn.PC = 0x00000;
1786 return 0;
1787 }
1788
1789 init_saturn();
1790 if (!read_rom(romFileName))
1791 exit(1);
1792
1793 return 0;
1794 }
1795
1796 void
1797 #ifdef __FunctionProto__
init_active_stuff(void)1798 init_active_stuff(void)
1799 #else
1800 init_active_stuff()
1801 #endif
1802 {
1803 serial_init();
1804 init_annunc();
1805 init_display();
1806 }
1807
1808 int
1809 #ifdef __FunctionProto__
exit_emulator(void)1810 exit_emulator(void)
1811 #else
1812 exit_emulator()
1813 #endif
1814 {
1815 write_files();
1816 return 1;
1817 }
1818
1819