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