fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/lib/load.c *
7 * Created: 2004-08-02 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2004-2022 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#include <config.h>
24
25#include <stdlib.h>
26#include <stdio.h>
27#include <string.h>
28
29#include <libini/libini.h>
30
31#include <lib/log.h>
32#include <lib/ihex.h>
33#include <lib/mhex.h>
34#include <lib/srec.h>
35#include <lib/thex.h>
36#include <lib/load.h>
37#include <lib/path.h>
38
39
40int pce_load_blk_bin (mem_blk_t *blk, const char *fname)
41{
42 FILE *fp;
43
44 if ((fp = fopen (fname, "rb")) == NULL) {
45 return (1);
46 }
47
48 (void) fread (blk->data, 1, blk->size, fp);
49
50 fclose (fp);
51
52 return (0);
53}
54
55int pce_load_mem_ihex (memory_t *mem, const char *fname)
56{
57 int r;
58 FILE *fp;
59
60 if ((fp = fopen (fname, "r")) == NULL) {
61 return (1);
62 }
63
64 r = ihex_load_fp (fp, mem, (ihex_set_f) mem_set_uint8_rw);
65
66 fclose (fp);
67
68 return (r);
69}
70
71int pce_load_mem_mhex (memory_t *mem, const char *fname)
72{
73 int r;
74 FILE *fp;
75
76 if ((fp = fopen (fname, "r")) == NULL) {
77 return (1);
78 }
79
80 r = mhex_load_fp (fp, mem, (mhex_set_f) mem_set_uint8_rw);
81
82 fclose (fp);
83
84 return (r);
85}
86
87int pce_load_mem_srec (memory_t *mem, const char *fname)
88{
89 int r;
90 FILE *fp;
91
92 if ((fp = fopen (fname, "r")) == NULL) {
93 return (1);
94 }
95
96 r = srec_load_fp (fp, mem, (ihex_set_f) mem_set_uint8_rw);
97
98 fclose (fp);
99
100 return (r);
101}
102
103int pce_load_mem_thex (memory_t *mem, const char *fname)
104{
105 int r;
106 FILE *fp;
107
108 if ((fp = fopen (fname, "r")) == NULL) {
109 return (1);
110 }
111
112 r = thex_load_fp (fp, mem, (thex_set_f) mem_set_uint8_rw);
113
114 fclose (fp);
115
116 return (r);
117}
118
119int pce_load_mem_bin (memory_t *mem, const char *fname, unsigned long addr)
120{
121 int c;
122 FILE *fp;
123
124 if ((fp = fopen (fname, "rb")) == NULL) {
125 return (1);
126 }
127
128 while ((c = fgetc (fp)) != EOF) {
129 mem_set_uint8_rw (mem, addr, c & 0xff);
130 addr += 1;
131 }
132
133 fclose (fp);
134
135 return (0);
136}
137
138int pce_load_mem (memory_t *mem, const char *fname, const char *fmt, unsigned long addr)
139{
140 unsigned i;
141 const char *ext;
142
143 if (fname == NULL) {
144 return (1);
145 }
146
147 if ((fmt == NULL) || (strcmp (fmt, "auto") == 0)) {
148 i = 0;
149 ext = NULL;
150
151 while (fname[i] != 0) {
152 if (fname[i] == '.') {
153 ext = fname + i + 1;
154 }
155 else if (fname[i] == PCE_DIR_SEP) {
156 ext = NULL;
157 }
158
159 i += 1;
160 }
161
162 if (ext == NULL) {
163 return (1);
164 }
165
166 if ((strcasecmp (ext, "ihex") == 0) || (strcasecmp (ext, "ihx") == 0)) {
167 fmt = "ihex";
168 }
169 else if (strcasecmp (ext, "mhex") == 0) {
170 fmt = "mhex";
171 }
172 else if (strcasecmp (ext, "srec") == 0) {
173 fmt = "srec";
174 }
175 else if (strcasecmp (ext, "thex") == 0) {
176 fmt = "thex";
177 }
178 else if (strcasecmp (ext, "bin") == 0) {
179 fmt = "binary";
180 }
181 else if (strcasecmp (ext, "rom") == 0) {
182 fmt = "binary";
183 }
184 else {
185 return (1);
186 }
187 }
188
189 if (strcmp (fmt, "binary") == 0) {
190 return (pce_load_mem_bin (mem, fname, addr));
191 }
192 else if (strcmp (fmt, "ihex") == 0) {
193 return (pce_load_mem_ihex (mem, fname));
194 }
195 else if (strcmp (fmt, "mhex") == 0) {
196 return (pce_load_mem_mhex (mem, fname));
197 }
198 else if (strcmp (fmt, "srec") == 0) {
199 return (pce_load_mem_srec (mem, fname));
200 }
201 else if (strcmp (fmt, "thex") == 0) {
202 return (pce_load_mem_thex (mem, fname));
203 }
204
205 return (1);
206}
207
208int pce_load_mem_ini (memory_t *mem, ini_sct_t *ini)
209{
210 int r;
211 const char *fmt;
212 const char *fname;
213 char *path;
214 unsigned long addr;
215 ini_sct_t *sct;
216
217 r = 0;
218
219 sct = NULL;
220
221 while ((sct = ini_next_sct (ini, sct, "load")) != NULL) {
222 ini_get_string (sct, "format", &fmt, "auto");
223 ini_get_string (sct, "file", &fname, NULL);
224
225 if (ini_get_uint32 (sct, "address", &addr, 0)) {
226 ini_get_uint32 (sct, "base", &addr, 0);
227 }
228
229 if (fname != NULL) {
230 path = pce_path_get (fname);
231
232 pce_log_tag (MSG_INF, "Load:", "file=%s format=%s\n",
233 fname, fmt
234 );
235
236 if (pce_load_mem (mem, path, fmt, addr)) {
237 r = 1;
238 pce_log (MSG_ERR, "*** loading failed (%s)\n",
239 path
240 );
241 }
242
243 free (path);
244 }
245 }
246
247 return (r);
248}