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: romio.c,v $
21 * Revision 1.1 1995/01/11 18:11:25 ecd
22 * Initial revision
23 *
24 *
25 * $Id: romio.c,v 1.1 1995/01/11 18:11:25 ecd Exp ecd $
26 */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <sys/stat.h>
32
33 #include "global.h"
34 #include "resources.h"
35 #include "romio.h"
36
37 unsigned int opt_gx = 0;
38 unsigned int rom_size = 0;
39
40 int
41 #ifdef __FunctionProto__
read_rom_file(char * name,unsigned char ** mem,int * size)42 read_rom_file(char *name, unsigned char **mem, int *size)
43 #else
44 read_rom_file(name, mem, size)
45 char *name;
46 unsigned char **mem;
47 int *size;
48 #endif
49 {
50 struct stat st;
51 FILE *fp;
52 unsigned char *tmp_mem;
53 unsigned char byte;
54 unsigned char four[4];
55 int i, j;
56
57 *mem = NULL;
58 *size = 0;
59 if (NULL == (fp = fopen(name, "r")))
60 {
61 fprintf(stderr, "can\'t open %s\n", name);
62 return 0;
63 }
64
65 if (stat(name, &st) < 0)
66 {
67 fprintf(stderr, "can\'t stat %s\n", name);
68 fclose(fp);
69 return 0;
70 }
71
72 if (fread(four, 1, 4, fp) != 4)
73 {
74 fprintf(stderr, "can\'t read first 4 bytes of %s\n", name);
75 fclose(fp);
76 return 0;
77 }
78
79 if (four[0] == 0x02 && four[1] == 0x03 &&
80 four[2] == 0x06 && four[3] == 0x09)
81 {
82 *size = st.st_size;
83 }
84 else if (four[0] == 0x32 && four[1] == 0x96 &&
85 four[2] == 0x1b && four[3] == 0x80)
86 {
87 *size = 2 * st.st_size;
88 }
89 else if (four[1] = 0x49)
90 {
91 fprintf(stderr, "%s is an HP49 ROM\n", name);
92 *size = 2 * st.st_size;
93 }
94 else if (four[0])
95 {
96 printf("%d\n", st.st_size);
97 *size = st.st_size;
98 }
99 else
100 {
101 fprintf(stderr, "%s is not a HP48 ROM\n", name);
102 fclose(fp);
103 return 0;
104 }
105
106 if (fseek(fp, 0, 0) < 0)
107 {
108 fprintf(stderr, "can\'t fseek to position 0 in %s\n", name);
109 *size = 0;
110 fclose(fp);
111 return 0;
112 }
113
114 *mem = (unsigned char *)malloc(*size);
115
116 if (st.st_size == *size)
117 {
118 /*
119 * size is same as memory size, old version file
120 */
121 if (fread(*mem, 1, (size_t)*size, fp) != *size)
122 {
123 fprintf(stderr, "can\'t read %s\n", name);
124 free(*mem);
125 *mem = NULL;
126 *size = 0;
127 fclose(fp);
128 return 0;
129 }
130 }
131 else
132 {
133 /*
134 * size is different, check size and decompress memory
135 */
136
137 if (st.st_size != *size / 2)
138 {
139 fprintf(stderr, "strange size %s, expected %d, found %ld\n",
140 name, *size / 2, st.st_size);
141 free(*mem);
142 *mem = NULL;
143 *size = 0;
144 fclose(fp);
145 return 0;
146 }
147
148 if (NULL == (tmp_mem = (unsigned char *)malloc((size_t)st.st_size)))
149 {
150 for (i = 0, j = 0; i < *size / 2; i++)
151 {
152 if (1 != fread(&byte, 1, 1, fp))
153 {
154 fprintf(stderr, "can\'t read %s\n", name);
155 free(*mem);
156 *mem = NULL;
157 *size = 0;
158 fclose(fp);
159 return 0;
160 }
161 (*mem)[j++] = byte & 0xf;
162 (*mem)[j++] = (byte >> 4) & 0xf;
163 }
164 }
165 else
166 {
167 if (fread(tmp_mem, 1, (size_t)*size / 2, fp) != *size / 2)
168 {
169 fprintf(stderr, "can\'t read %s\n", name);
170 free(*mem);
171 *mem = NULL;
172 *size = 0;
173 fclose(fp);
174 free(tmp_mem);
175 return 0;
176 }
177
178 for (i = 0, j = 0; i < *size / 2; i++)
179 {
180 (*mem)[j++] = tmp_mem[i] & 0xf;
181 (*mem)[j++] = (tmp_mem[i] >> 4) & 0xf;
182 }
183
184 free(tmp_mem);
185 }
186 }
187
188 fclose(fp);
189
190 if ((*mem)[0x29] == 0x00)
191 {
192 if (*size == ROM_SIZE_GX)
193 {
194 opt_gx = 1;
195 }
196 else
197 if (*size == 4 * ROM_SIZE_GX)
198 {
199 fprintf(stderr, "%s seems to be HP49 ROM, but size is 0x%x\n",
200 name, *size);
201 opt_gx = 2;
202 }
203 else
204 if (*size == 8 * ROM_SIZE_GX)
205 {
206 fprintf(stderr, "%s seems to be HP49 ROM, but size is 0x%x\n",
207 name, *size);
208 opt_gx = 2;
209 }
210 else
211 {
212 fprintf(stderr, "%s seems to be G/GX ROM, but size is 0x%x\n",
213 name, *size);
214 free(*mem);
215 *mem = NULL;
216 *size = 0;
217 return 0;
218 }
219 }
220 else
221 {
222 if (*size == ROM_SIZE_SX)
223 {
224 opt_gx = 0;
225 }
226 else
227 {
228 fprintf(stderr, "%s seems to be S/SX ROM, but size is 0x%x\n",
229 name, *size);
230 free(*mem);
231 *mem = NULL;
232 *size = 0;
233 return 0;
234 }
235 }
236
237 if (verbose)
238 printf("%s: read %s\n", progname, name);
239
240 return 1;
241 }
242
243