1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * Config file handling
5 * This still needs some thought before it's complete...
6 *
7 * Copyright 1998 Brian King, Bernd Schmidt
8 */
9
10 #include "sysconfig.h"
11 #include "sysdeps.h"
12
13 #include <ctype.h>
14
15 #ifdef FSUAE // NL
16 #ifdef _WIN32
17 #include <winsock2.h>
18 #else
19 #include <arpa/inet.h>
20 #endif
21 #endif
22
23 #include "options.h"
24 #include "uae.h"
25 #include "audio.h"
26 #include "events.h"
27 #include "custom.h"
28 #include "inputdevice.h"
29 #include "gfxfilter.h"
30 #include "savestate.h"
31 #include "uae/memory.h"
32 #include "autoconf.h"
33 #include "rommgr.h"
34 #include "gui.h"
35 #include "newcpu.h"
36 #include "zfile.h"
37 #include "filesys.h"
38 #include "fsdb.h"
39 #include "disk.h"
40 #include "blkdev.h"
41 #include "statusline.h"
42 #include "debug.h"
43 #include "calc.h"
44 #include "gfxboard.h"
45 #include "cpuboard.h"
46 #include "luascript.h"
47
48 #ifdef FSUAE
49 #include <uae/fs.h>
50 #define cfgfile_warning error_log
51 #define cfgfile_warning_obsolete error_log
52 #else
53 #define cfgfile_warning write_log
54 #define cfgfile_warning_obsolete write_log
55 #endif
56
57 #if SIZEOF_TCHAR != 1
58 /* FIXME: replace strcasecmp with _tcsicmp in source code instead */
59 #undef strcasecmp
60 #define strcasecmp _tcsicmp
61 #endif
62
63 static int config_newfilesystem;
64 static struct strlist *temp_lines;
65 static struct strlist *error_lines;
66 static struct zfile *default_file, *configstore;
67 static int uaeconfig;
68 static int unicode_config = 0;
69
70 /* @@@ need to get rid of this... just cut part of the manual and print that
71 * as a help text. */
72 struct cfg_lines
73 {
74 const TCHAR *config_label, *config_help;
75 };
76
77 static const struct cfg_lines opttable[] =
78 {
79 {_T("help"), _T("Prints this help") },
80 {_T("config_description"), _T("") },
81 {_T("config_info"), _T("") },
82 {_T("use_gui"), _T("Enable the GUI? If no, then goes straight to emulator") },
83 {_T("use_debugger"), _T("Enable the debugger?") },
84 {_T("cpu_speed"), _T("can be max, real, or a number between 1 and 20") },
85 {_T("cpu_model"), _T("Can be 68000, 68010, 68020, 68030, 68040, 68060") },
86 {_T("fpu_model"), _T("Can be 68881, 68882, 68040, 68060") },
87 {_T("cpu_compatible"), _T("yes enables compatibility-mode") },
88 {_T("cpu_24bit_addressing"), _T("must be set to 'no' in order for Z3mem or P96mem to work") },
89 {_T("autoconfig"), _T("yes = add filesystems and extra ram") },
90 {_T("log_illegal_mem"), _T("print illegal memory access by Amiga software?") },
91 {_T("fastmem_size"), _T("Size in megabytes of fast-memory") },
92 {_T("chipmem_size"), _T("Size in megabytes of chip-memory") },
93 {_T("bogomem_size"), _T("Size in megabytes of bogo-memory at 0xC00000") },
94 {_T("a3000mem_size"), _T("Size in megabytes of A3000 memory") },
95 {_T("gfxcard_size"), _T("Size in megabytes of Picasso96 graphics-card memory") },
96 {_T("z3mem_size"), _T("Size in megabytes of Zorro-III expansion memory") },
97 {_T("gfx_test_speed"), _T("Test graphics speed?") },
98 {_T("gfx_framerate"), _T("Print every nth frame") },
99 {_T("gfx_width"), _T("Screen width") },
100 {_T("gfx_height"), _T("Screen height") },
101 {_T("gfx_refreshrate"), _T("Fullscreen refresh rate") },
102 {_T("gfx_vsync"), _T("Sync screen refresh to refresh rate") },
103 {_T("gfx_lores"), _T("Treat display as lo-res?") },
104 {_T("gfx_linemode"), _T("Can be none, double, or scanlines") },
105 {_T("gfx_fullscreen_amiga"), _T("Amiga screens are fullscreen?") },
106 {_T("gfx_fullscreen_picasso"), _T("Picasso screens are fullscreen?") },
107 {_T("gfx_center_horizontal"), _T("Center display horizontally?") },
108 {_T("gfx_center_vertical"), _T("Center display vertically?") },
109 {_T("gfx_colour_mode"), _T("") },
110 {_T("32bit_blits"), _T("Enable 32 bit blitter emulation") },
111 {_T("immediate_blits"), _T("Perform blits immediately") },
112 {_T("show_leds"), _T("LED display") },
113 {_T("keyboard_leds"), _T("Keyboard LEDs") },
114 {_T("gfxlib_replacement"), _T("Use graphics.library replacement?") },
115 {_T("sound_output"), _T("") },
116 {_T("sound_frequency"), _T("") },
117 {_T("sound_bits"), _T("") },
118 {_T("sound_channels"), _T("") },
119 {_T("sound_max_buff"), _T("") },
120 {_T("comp_trustbyte"), _T("How to access bytes in compiler (direct/indirect/indirectKS/afterPic") },
121 {_T("comp_trustword"), _T("How to access words in compiler (direct/indirect/indirectKS/afterPic") },
122 {_T("comp_trustlong"), _T("How to access longs in compiler (direct/indirect/indirectKS/afterPic") },
123 {_T("comp_nf"), _T("Whether to optimize away flag generation where possible") },
124 {_T("comp_fpu"), _T("Whether to provide JIT FPU emulation") },
125 {_T("cachesize"), _T("How many MB to use to buffer translated instructions")},
126 {_T("override_dga_address"),_T("Address from which to map the frame buffer (upper 16 bits) (DANGEROUS!)")},
127 {_T("avoid_dga"), _T("Set to yes if the use of DGA extension creates problems") },
128 {_T("avoid_vid"), _T("Set to yes if the use of the Vidmode extension creates problems") },
129 {_T("parallel_on_demand"), _T("") },
130 {_T("serial_on_demand"), _T("") },
131 {_T("scsi"), _T("scsi.device emulation") },
132 {_T("joyport0"), _T("") },
133 {_T("joyport1"), _T("") },
134 {_T("pci_devices"), _T("List of PCI devices to make visible to the emulated Amiga") },
135 {_T("kickstart_rom_file"), _T("Kickstart ROM image, (C) Copyright Amiga, Inc.") },
136 {_T("kickstart_ext_rom_file"), _T("Extended Kickstart ROM image, (C) Copyright Amiga, Inc.") },
137 {_T("kickstart_key_file"), _T("Key-file for encrypted ROM images (from Cloanto's Amiga Forever)") },
138 {_T("flash_ram_file"), _T("Flash/battery backed RAM image file.") },
139 {_T("cart_file"), _T("Freezer cartridge ROM image file.") },
140 {_T("floppy0"), _T("Diskfile for drive 0") },
141 {_T("floppy1"), _T("Diskfile for drive 1") },
142 {_T("floppy2"), _T("Diskfile for drive 2") },
143 {_T("floppy3"), _T("Diskfile for drive 3") },
144 {_T("hardfile"), _T("access,sectors, surfaces, reserved, blocksize, path format") },
145 {_T("filesystem"), _T("access,'Amiga volume-name':'host directory path' - where 'access' can be 'read-only' or 'read-write'") },
146 {_T("catweasel"), _T("Catweasel board io base address") }
147 };
148
149 static const TCHAR *guimode1[] = { _T("no"), _T("yes"), _T("nowait"), 0 };
150 static const TCHAR *guimode2[] = { _T("false"), _T("true"), _T("nowait"), 0 };
151 static const TCHAR *guimode3[] = { _T("0"), _T("1"), _T("nowait"), 0 };
152 static const TCHAR *csmode[] = { _T("ocs"), _T("ecs_agnus"), _T("ecs_denise"), _T("ecs"), _T("aga"), 0 };
153 static const TCHAR *linemode[] = {
154 _T("none"),
155 _T("double"), _T("scanlines"), _T("scanlines2p"), _T("scanlines3p"),
156 _T("double2"), _T("scanlines2"), _T("scanlines2p2"), _T("scanlines2p3"),
157 _T("double3"), _T("scanlines3"), _T("scanlines3p2"), _T("scanlines3p3"),
158 0 };
159 static const TCHAR *speedmode[] = { _T("max"), _T("real"), 0 };
160 static const TCHAR *colormode1[] = { _T("8bit"), _T("15bit"), _T("16bit"), _T("8bit_dither"), _T("4bit_dither"), _T("32bit"), 0 };
161 static const TCHAR *colormode2[] = { _T("8"), _T("15"), _T("16"), _T("8d"), _T("4d"), _T("32"), 0 };
162 static const TCHAR *soundmode1[] = { _T("none"), _T("interrupts"), _T("normal"), _T("exact"), 0 };
163 static const TCHAR *soundmode2[] = { _T("none"), _T("interrupts"), _T("good"), _T("best"), 0 };
164 static const TCHAR *centermode1[] = { _T("none"), _T("simple"), _T("smart"), 0 };
165 static const TCHAR *centermode2[] = { _T("false"), _T("true"), _T("smart"), 0 };
166 static const TCHAR *stereomode[] = { _T("mono"), _T("stereo"), _T("clonedstereo"), _T("4ch"), _T("clonedstereo6ch"), _T("6ch"), _T("mixed"), 0 };
167 static const TCHAR *interpolmode[] = { _T("none"), _T("anti"), _T("sinc"), _T("rh"), _T("crux"), 0 };
168 static const TCHAR *collmode[] = { _T("none"), _T("sprites"), _T("playfields"), _T("full"), 0 };
169 static const TCHAR *compmode[] = { _T("direct"), _T("indirect"), _T("indirectKS"), _T("afterPic"), 0 };
170 static const TCHAR *flushmode[] = { _T("soft"), _T("hard"), 0 };
171 static const TCHAR *kbleds[] = { _T("none"), _T("POWER"), _T("DF0"), _T("DF1"), _T("DF2"), _T("DF3"), _T("HD"), _T("CD"), _T("DFx"), 0 };
172 static const TCHAR *onscreenleds[] = { _T("false"), _T("true"), _T("rtg"), _T("both"), 0 };
173 static const TCHAR *soundfiltermode1[] = { _T("off"), _T("emulated"), _T("on"), 0 };
174 static const TCHAR *soundfiltermode2[] = { _T("standard"), _T("enhanced"), 0 };
175 static const TCHAR *lorestype1[] = { _T("lores"), _T("hires"), _T("superhires"), 0 };
176 static const TCHAR *lorestype2[] = { _T("true"), _T("false"), 0 };
177 static const TCHAR *loresmode[] = { _T("normal"), _T("filtered"), 0 };
178 static const TCHAR *horizmode[] = { _T("vertical"), _T("lores"), _T("hires"), _T("superhires"), 0 };
179 static const TCHAR *vertmode[] = { _T("horizontal"), _T("single"), _T("double"), _T("quadruple"), 0 };
180 #ifdef GFXFILTER
181 static const TCHAR *filtermode2[] = { _T("1x"), _T("2x"), _T("3x"), _T("4x"), 0 };
182 #endif
183 static const TCHAR *cartsmode[] = { _T("none"), _T("hrtmon"), 0 };
184 static const TCHAR *idemode[] = { _T("none"), _T("a600/a1200"), _T("a4000"), 0 };
185 static const TCHAR *rtctype[] = { _T("none"), _T("MSM6242B"), _T("RP5C01A"), _T("MSM6242B_A2000"), 0 };
186 static const TCHAR *ciaatodmode[] = { _T("vblank"), _T("50hz"), _T("60hz"), 0 };
187 static const TCHAR *ksmirrortype[] = { _T("none"), _T("e0"), _T("a8+e0"), 0 };
188 static const TCHAR *cscompa[] = {
189 _T("-"), _T("Generic"), _T("CDTV"), _T("CDTV-CR"), _T("CD32"), _T("A500"), _T("A500+"), _T("A600"),
190 _T("A1000"), _T("A1200"), _T("A2000"), _T("A3000"), _T("A3000T"), _T("A4000"), _T("A4000T"),
191 _T("Velvet"),
192 NULL
193 };
194 static const TCHAR *qsmodes[] = {
195 _T("A500"), _T("A500+"), _T("A600"), _T("A1000"), _T("A1200"), _T("A3000"), _T("A4000"), _T(""), _T("CD32"), _T("CDTV"), _T("CDTV-CR"), _T("ARCADIA"), NULL };
196 /* 3-state boolean! */
197 static const TCHAR *fullmodes[] = { _T("false"), _T("true"), /* "FILE_NOT_FOUND", */ _T("fullwindow"), 0 };
198 /* bleh for compatibility */
199 static const TCHAR *scsimode[] = { _T("false"), _T("true"), _T("scsi"), 0 };
200 static const TCHAR *maxhoriz[] = { _T("lores"), _T("hires"), _T("superhires"), 0 };
201 static const TCHAR *maxvert[] = { _T("nointerlace"), _T("interlace"), 0 };
202 static const TCHAR *abspointers[] = { _T("none"), _T("mousehack"), _T("tablet"), 0 };
203 static const TCHAR *magiccursors[] = { _T("both"), _T("native"), _T("host"), 0 };
204 static const TCHAR *autoscale[] = { _T("none"), _T("auto"), _T("standard"), _T("max"), _T("scale"), _T("resize"), _T("center"), _T("manual"),
205 _T("integer"), _T("integer_auto"), _T("separator"), _T("overscan_blanking"), 0 };
206 static const TCHAR *autoscale_rtg[] = { _T("resize"), _T("scale"), _T("center"), _T("integer"), 0 };
207 static const TCHAR *autoscalelimit[] = { _T("1/1"), _T("1/2"), _T("1/4"), _T("1/8"), 0 };
208 static const TCHAR *joyportmodes[] = { _T(""), _T("mouse"), _T("mousenowheel"), _T("djoy"), _T("gamepad"), _T("ajoy"), _T("cdtvjoy"), _T("cd32joy"), _T("lightpen"), 0 };
209 static const TCHAR *joyaf[] = { _T("none"), _T("normal"), _T("toggle"), _T("always"), 0 };
210 static const TCHAR *epsonprinter[] = { _T("none"), _T("ascii"), _T("epson_matrix_9pin"), _T("epson_matrix_24pin"), _T("epson_matrix_48pin"), 0 };
211 static const TCHAR *aspects[] = { _T("none"), _T("vga"), _T("tv"), 0 };
212 static const TCHAR *vsyncmodes[] = { _T("false"), _T("true"), _T("autoswitch"), 0 };
213 static const TCHAR *vsyncmodes2[] = { _T("normal"), _T("busywait"), 0 };
214 static const TCHAR *filterapi[] = { _T("directdraw"), _T("direct3d"), 0 };
215 static const TCHAR *dongles[] =
216 {
217 _T("none"),
218 _T("robocop 3"), _T("leaderboard"), _T("b.a.t. ii"), _T("italy'90 soccer"), _T("dames grand maitre"),
219 _T("rugby coach"), _T("cricket captain"), _T("leviathan"),
220 NULL
221 };
222 static const TCHAR *cdmodes[] = { _T("disabled"), _T(""), _T("image"), _T("ioctl"), _T("spti"), _T("aspi"), 0 };
223 static const TCHAR *cdconmodes[] = { _T(""), _T("uae"), _T("ide"), _T("scsi"), _T("cdtv"), _T("cd32"), 0 };
224 static const TCHAR *specialmonitors[] = { _T("none"), _T("autodetect"), _T("a2024"), _T("graffiti"),
225 _T("ham_e"), _T("ham_e_plus"), _T("videodac18"), _T("avideo12"), _T("avideo24"), _T("firecracker24"), _T("dctv"), 0 };
226 static const TCHAR *genlockmodes[] = { _T("none"), _T("noise"), _T("testcard"), NULL };
227 static const TCHAR *ppc_implementations[] = {
228 _T("auto"),
229 _T("dummy"),
230 _T("pearpc"),
231 _T("qemu"),
232 NULL
233 };
234 #ifdef FSUAE
235 static const TCHAR *slirp_implementations[] = {
236 _T("auto"),
237 _T("none"),
238 _T("builtin"),
239 _T("qemu"),
240 NULL
241 };
242 #endif
243 static const TCHAR *ppc_cpu_idle[] = {
244 _T("disabled"),
245 _T("1"),
246 _T("2"),
247 _T("3"),
248 _T("4"),
249 _T("5"),
250 _T("6"),
251 _T("7"),
252 _T("8"),
253 _T("9"),
254 _T("max"),
255 NULL
256 };
257 static const TCHAR *waitblits[] = { _T("disabled"), _T("automatic"), _T("noidleonly"), _T("always"), 0 };
258 static const TCHAR *autoext2[] = { _T("disabled"), _T("copy"), _T("replace"), 0 };
259 static const TCHAR *leds[] = { _T("power"), _T("df0"), _T("df1"), _T("df2"), _T("df3"), _T("hd"), _T("cd"), _T("fps"), _T("cpu"), _T("snd"), _T("md"), 0 };
260 static const int leds_order[] = { 3, 6, 7, 8, 9, 4, 5, 2, 1, 0, 9 };
261 static const TCHAR *lacer[] = { _T("off"), _T("i"), _T("p"), 0 };
262 /* another boolean to choice update.. */
263 static const TCHAR *cycleexact[] = { _T("false"), _T("memory"), _T("true"), 0 };
264
265 static const TCHAR *hdcontrollers[] = {
266 _T("uae"),
267
268 _T("ide%d"),
269 _T("ide%d_mainboard"),
270
271 _T("scsi%d"),
272 _T("scsi%d_a3000"),
273 _T("scsi%d_a4000t"),
274 _T("scsi%d_cdtv"),
275
276 _T("scsram"),
277 _T("scide"),
278 NULL
279 };
280 static const TCHAR *z3mapping[] = {
281 _T("auto"),
282 _T("uae"),
283 _T("real"),
284 NULL
285 };
286 static const TCHAR *uaescsidevmodes[] = {
287 _T("original"),
288 _T("rename_scsi"),
289 NULL
290 };
291 static const TCHAR *uaebootrom[] = {
292 _T("automatic"),
293 _T("disabled"),
294 _T("min"),
295 _T("full"),
296 NULL
297 };
298 static const TCHAR *serialcrlf[] = {
299 _T("disabled"),
300 _T("crlf_cr"),
301 NULL
302 };
303 static const TCHAR *obsolete[] = {
304 _T("accuracy"), _T("gfx_opengl"), _T("gfx_32bit_blits"), _T("32bit_blits"),
305 _T("gfx_immediate_blits"), _T("gfx_ntsc"), _T("win32"), _T("gfx_filter_bits"),
306 _T("sound_pri_cutoff"), _T("sound_pri_time"), _T("sound_min_buff"), _T("sound_bits"),
307 _T("gfx_test_speed"), _T("gfxlib_replacement"), _T("enforcer"), _T("catweasel_io"),
308 _T("kickstart_key_file"), _T("fast_copper"), _T("sound_adjust"), _T("sound_latency"),
309 _T("serial_hardware_dtrdsr"), _T("gfx_filter_upscale"),
310 _T("gfx_correct_aspect"), _T("gfx_autoscale"), _T("parallel_sampler"), _T("parallel_ascii_emulation"),
311 _T("avoid_vid"), _T("avoid_dga"), _T("z3chipmem_size"), _T("state_replay_buffer"), _T("state_replay"),
312 _T("z3realmapping"), _T("force_0x10000000_z3"),
313
314 _T("gfx_filter_vert_zoom"),_T("gfx_filter_horiz_zoom"),
315 _T("gfx_filter_vert_zoom_mult"), _T("gfx_filter_horiz_zoom_mult"),
316 _T("gfx_filter_vert_offset"), _T("gfx_filter_horiz_offset"),
317
318 // created by some buggy beta
319 _T("uaehf0%s,%s"),
320 _T("uaehf1%s,%s"),
321 _T("uaehf2%s,%s"),
322 _T("uaehf3%s,%s"),
323 _T("uaehf4%s,%s"),
324 _T("uaehf5%s,%s"),
325 _T("uaehf6%s,%s"),
326 _T("uaehf7%s,%s"),
327
328 _T("pcibridge_rom_file"),
329 _T("pcibridge_rom_options"),
330
331 _T("cpuboard_ext_rom_file"),
332
333 _T("comp_oldsegv"),
334 _T("comp_midopt"),
335 _T("comp_lowopt"),
336 _T("avoid_cmov"),
337 _T("compforcesettings"),
338
339 NULL
340 };
341
342 #define UNEXPANDED _T("$(FILE_PATH)")
343
cfgfile_option_find_it(const TCHAR * s,const TCHAR * option,bool checkequals)344 static TCHAR *cfgfile_option_find_it(const TCHAR *s, const TCHAR *option, bool checkequals)
345 {
346 TCHAR buf[MAX_DPATH];
347 if (!s)
348 return NULL;
349 _tcscpy(buf, s);
350 _tcscat(buf, _T(","));
351 TCHAR *p = buf;
352 for (;;) {
353 TCHAR *tmpp = _tcschr(p, ',');
354 TCHAR *tmpp2 = NULL;
355 if (tmpp == NULL)
356 return NULL;
357 *tmpp++ = 0;
358 if (checkequals) {
359 tmpp2 = _tcschr(p, '=');
360 if (tmpp2)
361 *tmpp2++ = 0;
362 }
363 if (!strcasecmp(p, option)) {
364 if (checkequals && tmpp2)
365 return tmpp2;
366 return p;
367 }
368 p = tmpp;
369 }
370 }
371
cfgfile_option_find(const TCHAR * s,const TCHAR * option)372 static bool cfgfile_option_find(const TCHAR *s, const TCHAR *option)
373 {
374 return cfgfile_option_find_it(s, option, false) != NULL;
375 }
376
cfgfile_option_get(const TCHAR * s,const TCHAR * option)377 static TCHAR *cfgfile_option_get(const TCHAR *s, const TCHAR *option)
378 {
379 return cfgfile_option_find_it(s, option, true);
380 }
381
trimwsa(char * s)382 static void trimwsa (char *s)
383 {
384 /* Delete trailing whitespace. */
385 int len = strlen (s);
386 while (len > 0 && strcspn (s + len - 1, "\t \r\n") == 0)
387 s[--len] = '\0';
388 }
389
match_string(const TCHAR * table[],const TCHAR * str)390 static int match_string (const TCHAR *table[], const TCHAR *str)
391 {
392 int i;
393 for (i = 0; table[i] != 0; i++)
394 if (strcasecmp (table[i], str) == 0)
395 return i;
396 return -1;
397 }
398
399 // escape config file separators and control characters
cfgfile_escape(const TCHAR * s,const TCHAR * escstr,bool quote)400 static TCHAR *cfgfile_escape (const TCHAR *s, const TCHAR *escstr, bool quote)
401 {
402 bool doquote = false;
403 int cnt = 0;
404 for (int i = 0; s[i]; i++) {
405 TCHAR c = s[i];
406 if (c == 0)
407 break;
408 if (c < 32 || c == '\\' || c == '\"' || c == '\'') {
409 cnt++;
410 }
411 for (int j = 0; escstr && escstr[j]; j++) {
412 if (c == escstr[j]) {
413 cnt++;
414 if (quote) {
415 doquote = true;
416 cnt++;
417 }
418 }
419 }
420 }
421 TCHAR *s2 = xmalloc (TCHAR, _tcslen (s) + cnt * 4 + 1);
422 TCHAR *p = s2;
423 if (doquote)
424 *p++ = '\"';
425 for (int i = 0; s[i]; i++) {
426 TCHAR c = s[i];
427 if (c == 0)
428 break;
429 if (c == '\\' || c == '\"' || c == '\'') {
430 *p++ = '\\';
431 *p++ = c;
432 } else if (c >= 32 && !quote) {
433 bool escaped = false;
434 for (int j = 0; escstr && escstr[j]; j++) {
435 if (c == escstr[j]) {
436 *p++ = '\\';
437 *p++ = c;
438 escaped = true;
439 break;
440 }
441 }
442 if (!escaped)
443 *p++ = c;
444 } else if (c < 32) {
445 *p++ = '\\';
446 switch (c)
447 {
448 case '\t':
449 *p++ = 't';
450 break;
451 case '\n':
452 *p++ = 'n';
453 break;
454 case '\r':
455 *p++ = 'r';
456 break;
457 default:
458 *p++ = 'x';
459 *p++ = (c >> 4) >= 10 ? (c >> 4) + 'a' : (c >> 4) + '0';
460 *p++ = (c & 15) >= 10 ? (c & 15) + 'a' : (c & 15) + '0';
461 break;
462 }
463 } else {
464 *p++ = c;
465 }
466 }
467 if (doquote)
468 *p++ = '\"';
469 *p = 0;
470 return s2;
471 }
cfgfile_unescape(const TCHAR * s,const TCHAR ** endpos,TCHAR separator)472 static TCHAR *cfgfile_unescape (const TCHAR *s, const TCHAR **endpos, TCHAR separator)
473 {
474 bool quoted = false;
475 TCHAR *s2 = xmalloc (TCHAR, _tcslen (s) + 1);
476 TCHAR *p = s2;
477 if (s[0] == '\"') {
478 s++;
479 quoted = true;
480 }
481 int i;
482 for (i = 0; s[i]; i++) {
483 TCHAR c = s[i];
484 if (quoted && c == '\"') {
485 i++;
486 break;
487 }
488 if (c == separator) {
489 i++;
490 break;
491 }
492 if (c == '\\') {
493 char v = 0;
494 TCHAR c2;
495 c = s[i + 1];
496 switch (c)
497 {
498 case 'X':
499 case 'x':
500 c2 = _totupper (s[i + 2]);
501 v = ((c2 >= 'A') ? c2 - 'A' : c2 - '0') << 4;
502 c2 = _totupper (s[i + 3]);
503 v |= (c2 >= 'A') ? c2 - 'A' : c2 - '0';
504 *p++ = c2;
505 i += 2;
506 break;
507 case 'r':
508 *p++ = '\r';
509 break;
510 case '\n':
511 *p++ = '\n';
512 break;
513 default:
514 *p++ = c;
515 break;
516 }
517 i++;
518 } else {
519 *p++ = c;
520 }
521 }
522 *p = 0;
523 if (endpos)
524 *endpos = &s[i];
525 return s2;
526 }
cfgfile_unescape(const TCHAR * s,const TCHAR ** endpos)527 static TCHAR *cfgfile_unescape (const TCHAR *s, const TCHAR **endpos)
528 {
529 return cfgfile_unescape (s, endpos, 0);
530 }
531
getnextentry(const TCHAR ** valuep,const TCHAR separator)532 static TCHAR *getnextentry (const TCHAR **valuep, const TCHAR separator)
533 {
534 TCHAR *s;
535 const TCHAR *value = *valuep;
536 if (value[0] == '\"') {
537 s = cfgfile_unescape (value, valuep);
538 value = *valuep;
539 if (*value != 0 && *value != separator) {
540 xfree (s);
541 return NULL;
542 }
543 value++;
544 *valuep = value;
545 } else {
546 s = cfgfile_unescape (value, valuep, separator);
547 }
548 return s;
549 }
550
cfgfile_subst_path2(const TCHAR * path,const TCHAR * subst,const TCHAR * file)551 static TCHAR *cfgfile_subst_path2 (const TCHAR *path, const TCHAR *subst, const TCHAR *file)
552 {
553 /* @@@ use strcasecmp for some targets. */
554 if (_tcslen (path) > 0 && _tcsncmp (file, path, _tcslen (path)) == 0) {
555 int l;
556 TCHAR *p2, *p = xmalloc (TCHAR, _tcslen (file) + _tcslen (subst) + 2);
557 _tcscpy (p, subst);
558 l = _tcslen (p);
559 while (l > 0 && p[l - 1] == '/')
560 p[--l] = '\0';
561 l = _tcslen (path);
562 while (file[l] == '/')
563 l++;
564 _tcscat (p, _T("/"));
565 _tcscat (p, file + l);
566 p2 = target_expand_environment (p);
567 xfree (p);
568 return p2;
569 }
570 return NULL;
571 }
572
cfgfile_subst_path(const TCHAR * path,const TCHAR * subst,const TCHAR * file)573 TCHAR *cfgfile_subst_path (const TCHAR *path, const TCHAR *subst, const TCHAR *file)
574 {
575 TCHAR *s = cfgfile_subst_path2 (path, subst, file);
576 if (s)
577 return s;
578 s = target_expand_environment (file);
579 if (s) {
580 TCHAR tmp[MAX_DPATH];
581 _tcscpy (tmp, s);
582 xfree (s);
583 fullpath (tmp, sizeof tmp / sizeof (TCHAR));
584 s = my_strdup (tmp);
585 }
586 return s;
587 }
588
cfgfile_get_multipath2(struct multipath * mp,const TCHAR * path,const TCHAR * file,bool dir)589 static TCHAR *cfgfile_get_multipath2 (struct multipath *mp, const TCHAR *path, const TCHAR *file, bool dir)
590 {
591 for (int i = 0; i < MAX_PATHS; i++) {
592 if (mp->path[i][0] && _tcscmp (mp->path[i], _T(".\\")) != 0 && _tcscmp (mp->path[i], _T("./")) != 0 && (file[0] != '/' && file[0] != '\\' && !_tcschr(file, ':'))) {
593 TCHAR *s = NULL;
594 if (path)
595 s = cfgfile_subst_path2 (path, mp->path[i], file);
596 if (!s) {
597 TCHAR np[MAX_DPATH];
598 _tcscpy (np, mp->path[i]);
599 fixtrailing (np);
600 _tcscat (np, file);
601 fullpath (np, sizeof np / sizeof (TCHAR));
602 s = my_strdup (np);
603 }
604 if (dir) {
605 if (my_existsdir (s))
606 return s;
607 } else {
608 if (zfile_exists (s))
609 return s;
610 }
611 xfree (s);
612 }
613 }
614 return NULL;
615 }
616
cfgfile_get_multipath(struct multipath * mp,const TCHAR * path,const TCHAR * file,bool dir)617 static TCHAR *cfgfile_get_multipath (struct multipath *mp, const TCHAR *path, const TCHAR *file, bool dir)
618 {
619 TCHAR *s = cfgfile_get_multipath2 (mp, path, file, dir);
620 if (s)
621 return s;
622 return my_strdup (file);
623 }
624
cfgfile_put_multipath(struct multipath * mp,const TCHAR * s)625 static TCHAR *cfgfile_put_multipath (struct multipath *mp, const TCHAR *s)
626 {
627 for (int i = 0; i < MAX_PATHS; i++) {
628 if (mp->path[i][0] && _tcscmp (mp->path[i], _T(".\\")) != 0 && _tcscmp (mp->path[i], _T("./")) != 0) {
629 if (_tcsnicmp (mp->path[i], s, _tcslen (mp->path[i])) == 0) {
630 return my_strdup (s + _tcslen (mp->path[i]));
631 }
632 }
633 }
634 return my_strdup (s);
635 }
636
cfgfile_subst_path_load(const TCHAR * path,struct multipath * mp,const TCHAR * file,bool dir)637 static TCHAR *cfgfile_subst_path_load (const TCHAR *path, struct multipath *mp, const TCHAR *file, bool dir)
638 {
639 TCHAR *s = cfgfile_get_multipath2 (mp, path, file, dir);
640 if (s)
641 return s;
642 return cfgfile_subst_path (path, mp->path[0], file);
643 }
644
isdefault(const TCHAR * s)645 static bool isdefault (const TCHAR *s)
646 {
647 TCHAR tmp[MAX_DPATH];
648 if (!default_file || uaeconfig)
649 return false;
650 zfile_fseek (default_file, 0, SEEK_SET);
651 while (zfile_fgets (tmp, sizeof tmp / sizeof (TCHAR), default_file)) {
652 if (tmp[0] && tmp[_tcslen (tmp) - 1] == '\n')
653 tmp[_tcslen (tmp) - 1] = 0;
654 if (!_tcscmp (tmp, s))
655 return true;
656 }
657 return false;
658 }
659
cfg_write(const void * b,struct zfile * z)660 static size_t cfg_write (const void *b, struct zfile *z)
661 {
662 size_t v;
663 if (unicode_config) {
664 TCHAR lf = 10;
665 v = zfile_fwrite (b, _tcslen ((TCHAR*)b), sizeof (TCHAR), z);
666 zfile_fwrite (&lf, 1, 1, z);
667 } else {
668 char lf = 10;
669 char *s = ua ((TCHAR*)b);
670 v = zfile_fwrite (s, strlen (s), 1, z);
671 zfile_fwrite (&lf, 1, 1, z);
672 xfree (s);
673 }
674 return v;
675 }
676
677 #define UTF8NAME _T(".utf8")
678
cfg_dowrite(struct zfile * f,const TCHAR * option,const TCHAR * optionext,const TCHAR * value,int d,int target)679 static void cfg_dowrite (struct zfile *f, const TCHAR *option, const TCHAR *optionext, const TCHAR *value, int d, int target)
680 {
681 char lf = 10;
682 TCHAR tmp[CONFIG_BLEN], tmpext[CONFIG_BLEN];
683 const TCHAR *optionp;
684 char tmpa[CONFIG_BLEN];
685 char *tmp1, *tmp2;
686 int utf8;
687
688 if (value == NULL)
689 return;
690 if (optionext) {
691 _tcscpy (tmpext, option);
692 _tcscat (tmpext, optionext);
693 optionp = tmpext;
694 } else {
695 optionp = option;
696 }
697 utf8 = 0;
698 tmp1 = ua (value);
699 tmp2 = uutf8 (value);
700 if (strcmp (tmp1, tmp2) && tmp2[0] != 0)
701 utf8 = 1;
702
703 if (target)
704 _stprintf (tmp, _T("%s.%s=%s"), TARGET_NAME, optionp, value);
705 else
706 _stprintf (tmp, _T("%s=%s"), optionp, value);
707 if (d && isdefault (tmp))
708 goto end;
709 cfg_write (tmp, f);
710 if (utf8 && !unicode_config) {
711 char *opt = ua (optionp);
712 if (target) {
713 char *tna = ua (TARGET_NAME);
714 sprintf (tmpa, "%s.%s.utf8=%s", tna, opt, tmp2);
715 xfree (tna);
716 } else {
717 sprintf (tmpa, "%s.utf8=%s", opt, tmp2);
718 }
719 xfree (opt);
720 zfile_fwrite (tmpa, strlen (tmpa), 1, f);
721 zfile_fwrite (&lf, 1, 1, f);
722 }
723 end:
724 xfree (tmp2);
725 xfree (tmp1);
726 }
cfg_dowrite(struct zfile * f,const TCHAR * option,const TCHAR * value,int d,int target)727 static void cfg_dowrite (struct zfile *f, const TCHAR *option, const TCHAR *value, int d, int target)
728 {
729 cfg_dowrite (f, option, NULL, value, d, target);
730 }
cfgfile_write_bool(struct zfile * f,const TCHAR * option,bool b)731 void cfgfile_write_bool (struct zfile *f, const TCHAR *option, bool b)
732 {
733 cfg_dowrite (f, option, b ? _T("true") : _T("false"), 0, 0);
734 }
cfgfile_dwrite_bool(struct zfile * f,const TCHAR * option,bool b)735 void cfgfile_dwrite_bool (struct zfile *f, const TCHAR *option, bool b)
736 {
737 cfg_dowrite (f, option, b ? _T("true") : _T("false"), 1, 0);
738 }
cfgfile_dwrite_bool(struct zfile * f,const TCHAR * option,const TCHAR * optionext,bool b)739 static void cfgfile_dwrite_bool (struct zfile *f, const TCHAR *option, const TCHAR *optionext, bool b)
740 {
741 cfg_dowrite (f, option, optionext, b ? _T("true") : _T("false"), 1, 0);
742 }
cfgfile_dwrite_bool(struct zfile * f,const TCHAR * option,int b)743 static void cfgfile_dwrite_bool (struct zfile *f, const TCHAR *option, int b)
744 {
745 cfgfile_dwrite_bool (f, option, b != 0);
746 }
cfgfile_write_str(struct zfile * f,const TCHAR * option,const TCHAR * value)747 void cfgfile_write_str (struct zfile *f, const TCHAR *option, const TCHAR *value)
748 {
749 cfg_dowrite (f, option, value, 0, 0);
750 }
cfgfile_write_str(struct zfile * f,const TCHAR * option,const TCHAR * optionext,const TCHAR * value)751 static void cfgfile_write_str (struct zfile *f, const TCHAR *option, const TCHAR *optionext, const TCHAR *value)
752 {
753 cfg_dowrite (f, option, optionext, value, 0, 0);
754 }
cfgfile_dwrite_str(struct zfile * f,const TCHAR * option,const TCHAR * value)755 void cfgfile_dwrite_str (struct zfile *f, const TCHAR *option, const TCHAR *value)
756 {
757 cfg_dowrite (f, option, value, 1, 0);
758 }
cfgfile_dwrite_str(struct zfile * f,const TCHAR * option,const TCHAR * optionext,const TCHAR * value)759 static void cfgfile_dwrite_str (struct zfile *f, const TCHAR *option, const TCHAR *optionext, const TCHAR *value)
760 {
761 cfg_dowrite (f, option, optionext, value, 1, 0);
762 }
763
cfgfile_target_write_bool(struct zfile * f,const TCHAR * option,bool b)764 void cfgfile_target_write_bool (struct zfile *f, const TCHAR *option, bool b)
765 {
766 cfg_dowrite (f, option, b ? _T("true") : _T("false"), 0, 1);
767 }
cfgfile_target_dwrite_bool(struct zfile * f,const TCHAR * option,bool b)768 void cfgfile_target_dwrite_bool (struct zfile *f, const TCHAR *option, bool b)
769 {
770 cfg_dowrite (f, option, b ? _T("true") : _T("false"), 1, 1);
771 }
cfgfile_target_write_str(struct zfile * f,const TCHAR * option,const TCHAR * value)772 void cfgfile_target_write_str (struct zfile *f, const TCHAR *option, const TCHAR *value)
773 {
774 cfg_dowrite (f, option, value, 0, 1);
775 }
cfgfile_target_dwrite_str(struct zfile * f,const TCHAR * option,const TCHAR * value)776 void cfgfile_target_dwrite_str (struct zfile *f, const TCHAR *option, const TCHAR *value)
777 {
778 cfg_dowrite (f, option, value, 1, 1);
779 }
780
cfgfile_write_ext(struct zfile * f,const TCHAR * option,const TCHAR * optionext,const TCHAR * format,...)781 static void cfgfile_write_ext (struct zfile *f, const TCHAR *option, const TCHAR *optionext, const TCHAR *format,...)
782 {
783 va_list parms;
784 TCHAR tmp[CONFIG_BLEN], tmp2[CONFIG_BLEN];
785
786 if (optionext) {
787 _tcscpy (tmp2, option);
788 _tcscat (tmp2, optionext);
789 }
790 va_start (parms, format);
791 _vsntprintf (tmp, CONFIG_BLEN, format, parms);
792 cfg_dowrite (f, optionext ? tmp2 : option, tmp, 0, 0);
793 va_end (parms);
794 }
cfgfile_write(struct zfile * f,const TCHAR * option,const TCHAR * format,...)795 void cfgfile_write (struct zfile *f, const TCHAR *option, const TCHAR *format,...)
796 {
797 va_list parms;
798 TCHAR tmp[CONFIG_BLEN];
799
800 va_start (parms, format);
801 _vsntprintf (tmp, CONFIG_BLEN, format, parms);
802 cfg_dowrite (f, option, tmp, 0, 0);
803 va_end (parms);
804 }
805
cfgfile_dwrite_ext(struct zfile * f,const TCHAR * option,const TCHAR * optionext,const TCHAR * format,...)806 static void cfgfile_dwrite_ext (struct zfile *f, const TCHAR *option, const TCHAR *optionext, const TCHAR *format,...)
807 {
808 va_list parms;
809 TCHAR tmp[CONFIG_BLEN], tmp2[CONFIG_BLEN];
810
811 if (optionext) {
812 _tcscpy (tmp2, option);
813 _tcscat (tmp2, optionext);
814 }
815 va_start (parms, format);
816 _vsntprintf (tmp, CONFIG_BLEN, format, parms);
817 cfg_dowrite (f, optionext ? tmp2 : option, tmp, 1, 0);
818 va_end (parms);
819 }
cfgfile_dwrite(struct zfile * f,const TCHAR * option,const TCHAR * format,...)820 void cfgfile_dwrite (struct zfile *f, const TCHAR *option, const TCHAR *format,...)
821 {
822 va_list parms;
823 TCHAR tmp[CONFIG_BLEN];
824
825 va_start (parms, format);
826 _vsntprintf (tmp, CONFIG_BLEN, format, parms);
827 cfg_dowrite (f, option, tmp, 1, 0);
828 va_end (parms);
829 }
cfgfile_target_write(struct zfile * f,const TCHAR * option,const TCHAR * format,...)830 void cfgfile_target_write (struct zfile *f, const TCHAR *option, const TCHAR *format,...)
831 {
832 va_list parms;
833 TCHAR tmp[CONFIG_BLEN];
834
835 va_start (parms, format);
836 _vsntprintf (tmp, CONFIG_BLEN, format, parms);
837 cfg_dowrite (f, option, tmp, 0, 1);
838 va_end (parms);
839 }
cfgfile_target_dwrite(struct zfile * f,const TCHAR * option,const TCHAR * format,...)840 void cfgfile_target_dwrite (struct zfile *f, const TCHAR *option, const TCHAR *format,...)
841 {
842 va_list parms;
843 TCHAR tmp[CONFIG_BLEN];
844
845 va_start (parms, format);
846 _vsntprintf (tmp, CONFIG_BLEN, format, parms);
847 cfg_dowrite (f, option, tmp, 1, 1);
848 va_end (parms);
849 }
850
cfgfile_write_rom(struct zfile * f,struct multipath * mp,const TCHAR * romfile,const TCHAR * name)851 static void cfgfile_write_rom (struct zfile *f, struct multipath *mp, const TCHAR *romfile, const TCHAR *name)
852 {
853 TCHAR *str = cfgfile_subst_path (mp->path[0], UNEXPANDED, romfile);
854 str = cfgfile_put_multipath (mp, str);
855 cfgfile_write_str (f, name, str);
856 struct zfile *zf = zfile_fopen (str, _T("rb"), ZFD_ALL);
857 if (zf) {
858 struct romdata *rd = getromdatabyzfile (zf);
859 if (rd) {
860 TCHAR name2[MAX_DPATH], str2[MAX_DPATH];
861 _tcscpy (name2, name);
862 _tcscat (name2, _T("_id"));
863 _stprintf (str2, _T("%08X,%s"), rd->crc32, rd->name);
864 cfgfile_write_str (f, name2, str2);
865 }
866 zfile_fclose (zf);
867 }
868 xfree (str);
869
870 }
871
cfgfile_write_path(struct zfile * f,struct multipath * mp,const TCHAR * option,const TCHAR * value)872 static void cfgfile_write_path (struct zfile *f, struct multipath *mp, const TCHAR *option, const TCHAR *value)
873 {
874 TCHAR *s = cfgfile_put_multipath (mp, value);
875 cfgfile_write_str (f, option, s);
876 xfree (s);
877 }
cfgfile_dwrite_path(struct zfile * f,struct multipath * mp,const TCHAR * option,const TCHAR * value)878 static void cfgfile_dwrite_path (struct zfile *f, struct multipath *mp, const TCHAR *option, const TCHAR *value)
879 {
880 TCHAR *s = cfgfile_put_multipath (mp, value);
881 cfgfile_dwrite_str (f, option, s);
882 xfree (s);
883 }
884
write_filesys_config(struct uae_prefs * p,struct zfile * f)885 static void write_filesys_config (struct uae_prefs *p, struct zfile *f)
886 {
887 int i;
888 TCHAR tmp[MAX_DPATH], tmp2[MAX_DPATH], tmp3[MAX_DPATH], hdcs[MAX_DPATH];
889
890 for (i = 0; i < p->mountitems; i++) {
891 struct uaedev_config_data *uci = &p->mountconfig[i];
892 struct uaedev_config_info *ci = &uci->ci;
893 TCHAR *str1, *str1b, *str2b;
894 const TCHAR *str2;
895 int bp = ci->bootpri;
896
897 str2 = _T("");
898 if (ci->rootdir[0] == ':') {
899 TCHAR *ptr;
900 // separate harddrive names
901 str1 = my_strdup (ci->rootdir);
902 ptr = _tcschr (str1 + 1, ':');
903 if (ptr) {
904 *ptr++ = 0;
905 str2 = ptr;
906 ptr = (TCHAR *) _tcschr (str2, ',');
907 if (ptr)
908 *ptr = 0;
909 }
910 } else {
911 str1 = cfgfile_put_multipath (&p->path_hardfile, ci->rootdir);
912 }
913 int ct = ci->controller_type;
914 if (ct >= HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST && ct <= HD_CONTROLLER_TYPE_SCSI_LAST) {
915 _stprintf(hdcs, _T("scsi%d_%s"), ci->controller_unit, expansionroms[ct - HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST].name);
916 } else if (ct >= HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST && ct <= HD_CONTROLLER_TYPE_IDE_LAST) {
917 _stprintf(hdcs, _T("ide%d_%s"), ci->controller_unit, expansionroms[ct - HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST].name);
918 } else if (ct >= HD_CONTROLLER_TYPE_SCSI_FIRST && ct < HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST) {
919 _stprintf(hdcs, hdcontrollers[ct - HD_CONTROLLER_EXPANSION_MAX], ci->controller_unit);
920 } else if (ct >= HD_CONTROLLER_TYPE_PCMCIA_SRAM && ct <= HD_CONTROLLER_TYPE_PCMCIA_IDE) {
921 _stprintf(hdcs, hdcontrollers[ct - 2 * HD_CONTROLLER_EXPANSION_MAX], ci->controller_unit);
922 } else {
923 _stprintf(hdcs, hdcontrollers[ct], ci->controller_unit);
924 }
925 if (ci->controller_type_unit > 0)
926 _stprintf(hdcs + _tcslen(hdcs), _T("-%d"), ci->controller_type_unit + 1);
927
928 str1b = cfgfile_escape (str1, _T(":,"), true);
929 str2b = cfgfile_escape (str2, _T(":,"), true);
930 if (ci->type == UAEDEV_DIR) {
931 _stprintf (tmp, _T("%s,%s:%s:%s,%d"), ci->readonly ? _T("ro") : _T("rw"),
932 ci->devname ? ci->devname : _T(""), ci->volname, str1, bp);
933 cfgfile_write_str (f, _T("filesystem2"), tmp);
934 _tcscpy (tmp3, tmp);
935 #if 0
936 _stprintf (tmp2, _T("filesystem=%s,%s:%s"), uci->readonly ? _T("ro") : _T("rw"),
937 uci->volname, str);
938 zfile_fputs (f, tmp2);
939 #endif
940 } else if (ci->type == UAEDEV_HDF || ci->type == UAEDEV_CD || ci->type == UAEDEV_TAPE) {
941 _stprintf (tmp, _T("%s,%s:%s,%d,%d,%d,%d,%d,%s,%s"),
942 ci->readonly ? _T("ro") : _T("rw"),
943 ci->devname ? ci->devname : _T(""), str1,
944 ci->sectors, ci->surfaces, ci->reserved, ci->blocksize,
945 bp, ci->filesys ? ci->filesys : _T(""), hdcs);
946 _stprintf (tmp3, _T("%s,%s:%s%s%s,%d,%d,%d,%d,%d,%s,%s"),
947 ci->readonly ? _T("ro") : _T("rw"),
948 ci->devname ? ci->devname : _T(""), str1b, str2b[0] ? _T(":") : _T(""), str2b,
949 ci->sectors, ci->surfaces, ci->reserved, ci->blocksize,
950 bp, ci->filesys ? ci->filesys : _T(""), hdcs);
951 if (ci->highcyl || ci->physical_geometry) {
952 TCHAR *s = tmp + _tcslen (tmp);
953 TCHAR *s2 = s;
954 _stprintf (s2, _T(",%d"), ci->highcyl);
955 if (ci->physical_geometry && ci->pheads && ci->psecs) {
956 TCHAR *s = tmp + _tcslen (tmp);
957 _stprintf (s, _T(",%d/%d/%d"), ci->pcyls, ci->pheads, ci->psecs);
958 }
959 _tcscat (tmp3, s2);
960 }
961 if (ci->controller_media_type) {
962 _tcscat(tmp, _T(",CF"));
963 _tcscat(tmp3, _T(",CF"));
964 }
965 const TCHAR *extras = NULL;
966 if (ct >= HD_CONTROLLER_TYPE_SCSI_FIRST && ct <= HD_CONTROLLER_TYPE_SCSI_LAST) {
967 if (ci->unit_feature_level == HD_LEVEL_SCSI_1){
968 extras = _T("SCSI1");
969 } else if (ci->unit_feature_level == HD_LEVEL_SASI) {
970 extras = _T("SASI");
971 } else if (ci->unit_feature_level == HD_LEVEL_SASI_ENHANCED) {
972 extras = _T("SASIE");
973 } else if (ci->unit_feature_level == HD_LEVEL_SASI_CHS) {
974 extras = _T("SASI_CHS");
975 }
976 } else if (ct >= HD_CONTROLLER_TYPE_IDE_FIRST && ct <= HD_CONTROLLER_TYPE_IDE_LAST) {
977 if (ci->unit_feature_level == HD_LEVEL_ATA_1) {
978 extras = _T("ATA1");
979 } else if (ci->unit_feature_level == HD_LEVEL_ATA_2S) {
980 extras = _T("ATA2+S");
981 }
982 }
983 if (extras) {
984 _tcscat(tmp, _T(","));
985 _tcscat(tmp3, _T(","));
986 _tcscat(tmp, extras);
987 _tcscat(tmp3, extras);
988 }
989 if (ci->unit_special_flags) {
990 TCHAR tmpx[32];
991 _stprintf(tmpx, _T(",flags=0x%x"), ci->unit_special_flags);
992 _tcscat(tmp, tmpx);
993 _tcscat(tmp3, tmpx);
994 }
995 if (ci->type == UAEDEV_HDF)
996 cfgfile_write_str (f, _T("hardfile2"), tmp);
997 #if 0
998 _stprintf (tmp2, _T("hardfile=%s,%d,%d,%d,%d,%s"),
999 uci->readonly ? "ro" : "rw", uci->sectors,
1000 uci->surfaces, uci->reserved, uci->blocksize, str);
1001 zfile_fputs (f, tmp2);
1002 #endif
1003 }
1004 _stprintf (tmp2, _T("uaehf%d"), i);
1005 if (ci->type == UAEDEV_CD) {
1006 cfgfile_write (f, tmp2, _T("cd%d,%s"), ci->device_emu_unit, tmp);
1007 } else if (ci->type == UAEDEV_TAPE) {
1008 cfgfile_write (f, tmp2, _T("tape%d,%s"), ci->device_emu_unit, tmp);
1009 } else {
1010 cfgfile_write (f, tmp2, _T("%s,%s"), ci->type == UAEDEV_HDF ? _T("hdf") : _T("dir"), tmp3);
1011 }
1012 if (ci->type == UAEDEV_DIR) {
1013 bool add_extra = false;
1014 if (ci->inject_icons) {
1015 add_extra = true;
1016 }
1017 if (add_extra) {
1018 _stprintf(tmp2, _T("%s,inject_icons=%s"), ci->devname, ci->inject_icons ? _T("true") : _T("false"));
1019 cfgfile_write(f, _T("filesystem_extra"), tmp2);
1020 }
1021 }
1022 xfree (str1b);
1023 xfree (str2b);
1024 xfree (str1);
1025
1026 }
1027 }
1028
write_compatibility_cpu(struct zfile * f,struct uae_prefs * p)1029 static void write_compatibility_cpu (struct zfile *f, struct uae_prefs *p)
1030 {
1031 TCHAR tmp[100];
1032 int model;
1033
1034 model = p->cpu_model;
1035 if (model == 68030)
1036 model = 68020;
1037 if (model == 68060)
1038 model = 68040;
1039 if (p->address_space_24 && model == 68020)
1040 _tcscpy (tmp, _T("68ec020"));
1041 else
1042 _stprintf (tmp, _T("%d"), model);
1043 if (model == 68020 && (p->fpu_model == 68881 || p->fpu_model == 68882))
1044 _tcscat (tmp, _T("/68881"));
1045 cfgfile_write (f, _T("cpu_type"), tmp);
1046 }
1047
write_leds(struct zfile * f,const TCHAR * name,int mask)1048 static void write_leds (struct zfile *f, const TCHAR *name, int mask)
1049 {
1050 TCHAR tmp[MAX_DPATH];
1051 tmp[0] = 0;
1052 for (int i = 0; leds[i]; i++) {
1053 bool got = false;
1054 for (int j = 0; leds[j]; j++) {
1055 if (leds_order[j] == i) {
1056 if (mask & (1 << j)) {
1057 if (got)
1058 _tcscat (tmp, _T(":"));
1059 _tcscat (tmp, leds[j]);
1060 got = true;
1061 }
1062 }
1063 }
1064 if (leds[i + 1] && got)
1065 _tcscat (tmp, _T(","));
1066 }
1067 while (tmp[0] && tmp[_tcslen (tmp) - 1] == ',')
1068 tmp[_tcslen (tmp) - 1] = 0;
1069 cfgfile_dwrite_str (f, name, tmp);
1070 }
1071
write_resolution(struct zfile * f,const TCHAR * ws,const TCHAR * hs,struct wh * wh)1072 static void write_resolution (struct zfile *f, const TCHAR *ws, const TCHAR *hs, struct wh *wh)
1073 {
1074 if (wh->width <= 0 || wh->height <= 0 || wh->special == WH_NATIVE) {
1075 cfgfile_write_str (f, ws, _T("native"));
1076 cfgfile_write_str (f, hs, _T("native"));
1077 } else {
1078 cfgfile_write (f, ws, _T("%d"), wh->width);
1079 cfgfile_write (f, hs, _T("%d"), wh->height);
1080 }
1081 }
1082
cfgfile_read_rom_settings(const struct expansionboardsettings * ebs,const TCHAR * buf)1083 static int cfgfile_read_rom_settings(const struct expansionboardsettings *ebs, const TCHAR *buf)
1084 {
1085 int settings = 0;
1086 int bitcnt = 0;
1087 for (int i = 0; ebs[i].name; i++) {
1088 const struct expansionboardsettings *eb = &ebs[i];
1089 bitcnt += eb->bitshift;
1090 if (eb->multiselect) {
1091 int itemcnt = -1;
1092 int itemfound = 0;
1093 const TCHAR *p = eb->configname;
1094 while (p[0]) {
1095 if (itemcnt >= 0) {
1096 if (cfgfile_option_find(buf, p)) {
1097 itemfound = itemcnt;
1098 }
1099 }
1100 itemcnt++;
1101 p += _tcslen(p) + 1;
1102 }
1103 int cnt = 1;
1104 int bits = 1;
1105 for (int i = 0; i < 8; i++) {
1106 if ((1 << i) >= itemcnt) {
1107 cnt = 1 << i;
1108 bits = i;
1109 break;
1110 }
1111 }
1112 int multimask = cnt - 1;
1113 if (eb->invert)
1114 itemfound ^= 0x7fffffff;
1115 itemfound &= multimask;
1116 settings |= itemfound << bitcnt;
1117 bitcnt += bits;
1118 } else {
1119 int mask = 1 << bitcnt;
1120 if (cfgfile_option_find(buf, eb->configname)) {
1121 settings |= mask;
1122 }
1123 if (eb->invert)
1124 settings ^= mask;
1125 bitcnt++;
1126 }
1127 }
1128 return settings;
1129 }
1130
cfgfile_write_rom_settings(const struct expansionboardsettings * ebs,TCHAR * buf,int settings)1131 static void cfgfile_write_rom_settings(const struct expansionboardsettings *ebs, TCHAR *buf, int settings)
1132 {
1133 int bitcnt = 0;
1134 for (int j = 0; ebs[j].name; j++) {
1135 const struct expansionboardsettings *eb = &ebs[j];
1136 bitcnt += eb->bitshift;
1137 if (eb->multiselect) {
1138 int itemcnt = -1;
1139 const TCHAR *p = eb->configname;
1140 while (p[0]) {
1141 itemcnt++;
1142 p += _tcslen(p) + 1;
1143 }
1144 int cnt = 1;
1145 int bits = 1;
1146 for (int i = 0; i < 8; i++) {
1147 if ((1 << i) >= itemcnt) {
1148 cnt = 1 << i;
1149 bits = i;
1150 break;
1151 }
1152 }
1153 int multimask = cnt - 1;
1154 int multivalue = settings;
1155 if (eb->invert)
1156 multivalue ^= 0x7fffffff;
1157 multivalue = (multivalue >> bitcnt) & multimask;
1158 p = eb->configname;
1159 while (multivalue >= 0) {
1160 multivalue--;
1161 p += _tcslen(p) + 1;
1162 }
1163 if (buf[0])
1164 _tcscat(buf, _T(","));
1165 _tcscat(buf, p);
1166 bitcnt += bits;
1167 } else {
1168 int value = settings;
1169 if (eb->invert)
1170 value ^= 0x7fffffff;
1171 if (value & (1 << bitcnt)) {
1172 if (buf[0])
1173 _tcscat(buf, _T(","));
1174 _tcscat(buf, eb->configname);
1175 }
1176 bitcnt++;
1177 }
1178 }
1179 }
1180
cfgfile_write_board_rom(struct zfile * f,struct multipath * mp,struct boardromconfig * br)1181 static void cfgfile_write_board_rom(struct zfile *f, struct multipath *mp, struct boardromconfig *br)
1182 {
1183 TCHAR buf[256];
1184 TCHAR name[256];
1185 const struct expansionromtype *ert;
1186
1187 if (br->device_type == 0)
1188 return;
1189 ert = get_device_expansion_rom(br->device_type);
1190 if (!ert)
1191 return;
1192 for (int i = 0; i < MAX_BOARD_ROMS; i++) {
1193 if (br->device_num == 0)
1194 _tcscpy(name, ert->name);
1195 else
1196 _stprintf(name, _T("%s-%d"), ert->name, br->device_num + 1);
1197 if (i == 0 || _tcslen(br->roms[i].romfile)) {
1198 _stprintf(buf, _T("%s%s_rom_file"), name, i ? _T("_ext") : _T(""));
1199 cfgfile_write_rom (f, mp, br->roms[i].romfile, buf);
1200 if (br->roms[i].romident[0]) {
1201 _stprintf(buf, _T("%s%s_rom"), name, i ? _T("_ext") : _T(""));
1202 cfgfile_dwrite_str (f, buf, br->roms[i].romident);
1203 }
1204 if (br->roms[i].autoboot_disabled || ert->subtypes || ert->settings || ert->id_jumper) {
1205 TCHAR buf2[256], *p;
1206 buf2[0] = 0;
1207 p = buf2;
1208 _stprintf(buf, _T("%s%s_rom_options"), name, i ? _T("_ext") : _T(""));
1209 if (ert->subtypes) {
1210 const struct expansionsubromtype *srt = ert->subtypes;
1211 int k = br->roms[i].subtype;
1212 while (k && srt[1].name) {
1213 srt++;
1214 k--;
1215 }
1216 _stprintf(p, _T("subtype=%s"), srt->configname);
1217 }
1218 if (br->roms[i].autoboot_disabled) {
1219 if (buf2[0])
1220 _tcscat(buf2, _T(","));
1221 _tcscat(buf2, _T("autoboot_disabled=true"));
1222 }
1223 if (ert->id_jumper) {
1224 TCHAR tmp[256];
1225 _stprintf(tmp, _T("id=%d"), br->roms[i].device_id);
1226 if (buf2[0])
1227 _tcscat(buf2, _T(","));
1228 _tcscat(buf2, tmp);
1229 }
1230 if (br->roms[i].device_settings && ert->settings) {
1231 cfgfile_write_rom_settings(ert->settings, buf2, br->roms[i].device_settings);
1232 }
1233 if (buf2[0])
1234 cfgfile_dwrite_str (f, buf, buf2);
1235 }
1236
1237 if (br->roms[i].board_ram_size) {
1238 _stprintf(buf, _T("%s%s_mem_size"), name, i ? _T("_ext") : _T(""));
1239 cfgfile_write(f, buf, _T("%d"), br->roms[i].board_ram_size / 0x40000);
1240 }
1241 }
1242 }
1243 }
1244
cfgfile_save_options(struct zfile * f,struct uae_prefs * p,int type)1245 void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
1246 {
1247 struct strlist *sl;
1248 TCHAR tmp[MAX_DPATH];
1249 int i;
1250
1251 cfgfile_write_str (f, _T("config_description"), p->description);
1252 cfgfile_write_bool (f, _T("config_hardware"), type & CONFIG_TYPE_HARDWARE);
1253 cfgfile_write_bool (f, _T("config_host"), !!(type & CONFIG_TYPE_HOST));
1254 if (p->info[0])
1255 cfgfile_write (f, _T("config_info"), p->info);
1256 cfgfile_write (f, _T("config_version"), _T("%d.%d.%d"), UAEMAJOR, UAEMINOR, UAESUBREV);
1257 cfgfile_write_str (f, _T("config_hardware_path"), p->config_hardware_path);
1258 cfgfile_write_str (f, _T("config_host_path"), p->config_host_path);
1259 cfgfile_write_str (f, _T("config_all_path"), p->config_all_path);
1260 if (p->config_window_title[0])
1261 cfgfile_write_str (f, _T("config_window_title"), p->config_window_title);
1262
1263 for (sl = p->all_lines; sl; sl = sl->next) {
1264 if (sl->unknown) {
1265 if (sl->option)
1266 cfgfile_write_str (f, sl->option, sl->value);
1267 }
1268 }
1269
1270 for (i = 0; i < MAX_PATHS; i++) {
1271 if (p->path_rom.path[i][0]) {
1272 _stprintf (tmp, _T("%s.rom_path"), TARGET_NAME);
1273 cfgfile_write_str (f, tmp, p->path_rom.path[i]);
1274 }
1275 }
1276 for (i = 0; i < MAX_PATHS; i++) {
1277 if (p->path_floppy.path[i][0]) {
1278 _stprintf (tmp, _T("%s.floppy_path"), TARGET_NAME);
1279 cfgfile_write_str (f, tmp, p->path_floppy.path[i]);
1280 }
1281 }
1282 for (i = 0; i < MAX_PATHS; i++) {
1283 if (p->path_hardfile.path[i][0]) {
1284 _stprintf (tmp, _T("%s.hardfile_path"), TARGET_NAME);
1285 cfgfile_write_str (f, tmp, p->path_hardfile.path[i]);
1286 }
1287 }
1288 for (i = 0; i < MAX_PATHS; i++) {
1289 if (p->path_cd.path[i][0]) {
1290 _stprintf (tmp, _T("%s.cd_path"), TARGET_NAME);
1291 cfgfile_write_str (f, tmp, p->path_cd.path[i]);
1292 }
1293 }
1294
1295 cfg_write (_T("; host-specific"), f);
1296
1297 target_save_options (f, p);
1298
1299 cfg_write (_T("; common"), f);
1300
1301 cfgfile_write_str (f, _T("use_gui"), guimode1[p->start_gui]);
1302 cfgfile_write_bool (f, _T("use_debugger"), p->start_debugger);
1303
1304 cfgfile_write_rom (f, &p->path_rom, p->romfile, _T("kickstart_rom_file"));
1305 cfgfile_write_rom (f, &p->path_rom, p->romextfile, _T("kickstart_ext_rom_file"));
1306 if (p->romextfile2addr) {
1307 cfgfile_write (f, _T("kickstart_ext_rom_file2_address"), _T("%x"), p->romextfile2addr);
1308 cfgfile_write_rom (f, &p->path_rom, p->romextfile2, _T("kickstart_ext_rom_file2"));
1309 }
1310 if (p->romident[0])
1311 cfgfile_dwrite_str (f, _T("kickstart_rom"), p->romident);
1312 if (p->romextident[0])
1313 cfgfile_write_str (f, _T("kickstart_ext_rom="), p->romextident);
1314
1315 for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) {
1316 cfgfile_write_board_rom(f, &p->path_rom, &p->expansionboard[i]);
1317 }
1318
1319 cfgfile_write_path (f, &p->path_rom, _T("flash_file"), p->flashfile);
1320 cfgfile_write_path (f, &p->path_rom, _T("cart_file"), p->cartfile);
1321 cfgfile_write_path (f, &p->path_rom, _T("rtc_file"), p->rtcfile);
1322 if (p->cartident[0])
1323 cfgfile_write_str (f, _T("cart"), p->cartident);
1324 cfgfile_dwrite_path (f, &p->path_rom, _T("picassoiv_rom_file"), p->picassoivromfile);
1325
1326 cfgfile_write_bool (f, _T("kickshifter"), p->kickshifter);
1327 cfgfile_write_bool (f, _T("ks_write_enabled"), p->rom_readwrite);
1328
1329 cfgfile_write (f, _T("floppy_volume"), _T("%d"), p->dfxclickvolume_disk[0]);
1330 p->nr_floppies = 4;
1331 for (i = 0; i < 4; i++) {
1332 _stprintf (tmp, _T("floppy%d"), i);
1333 cfgfile_write_path (f, &p->path_floppy, tmp, p->floppyslots[i].df);
1334 _stprintf (tmp, _T("floppy%dwp"), i);
1335 cfgfile_dwrite_bool (f, tmp, p->floppyslots[i].forcedwriteprotect);
1336 _stprintf (tmp, _T("floppy%dtype"), i);
1337 cfgfile_dwrite (f, tmp, _T("%d"), p->floppyslots[i].dfxtype);
1338 _stprintf (tmp, _T("floppy%dsound"), i);
1339 cfgfile_dwrite (f, tmp, _T("%d"), p->floppyslots[i].dfxclick);
1340 if (p->floppyslots[i].dfxclick < 0 && p->floppyslots[i].dfxclickexternal[0]) {
1341 _stprintf (tmp, _T("floppy%dsoundext"), i);
1342 cfgfile_dwrite (f, tmp, p->floppyslots[i].dfxclickexternal);
1343 }
1344 if (p->floppyslots[i].dfxclick) {
1345 _stprintf (tmp, _T("floppy%dsoundvolume_disk"), i);
1346 cfgfile_write (f, tmp, _T("%d"), p->dfxclickvolume_disk[i]);
1347 _stprintf (tmp, _T("floppy%dsoundvolume_empty"), i);
1348 cfgfile_write (f, tmp, _T("%d"), p->dfxclickvolume_empty[i]);
1349 }
1350 if (p->floppyslots[i].dfxtype < 0 && p->nr_floppies > i)
1351 p->nr_floppies = i;
1352 }
1353 for (i = 0; i < MAX_SPARE_DRIVES; i++) {
1354 if (p->dfxlist[i][0]) {
1355 _stprintf (tmp, _T("diskimage%d"), i);
1356 cfgfile_dwrite_path (f, &p->path_floppy, tmp, p->dfxlist[i]);
1357 }
1358 }
1359
1360 for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
1361 if (p->cdslots[i].name[0] || p->cdslots[i].inuse) {
1362 TCHAR tmp2[MAX_DPATH];
1363 _stprintf (tmp, _T("cdimage%d"), i);
1364 TCHAR *s = cfgfile_put_multipath (&p->path_cd, p->cdslots[i].name);
1365 _tcscpy (tmp2, s);
1366 xfree (s);
1367 if (p->cdslots[i].type != SCSI_UNIT_DEFAULT || _tcschr (p->cdslots[i].name, ',') || p->cdslots[i].delayed) {
1368 _tcscat (tmp2, _T(","));
1369 if (p->cdslots[i].delayed) {
1370 _tcscat (tmp2, _T("delay"));
1371 _tcscat (tmp2, _T(":"));
1372 }
1373 if (p->cdslots[i].type != SCSI_UNIT_DEFAULT) {
1374 _tcscat (tmp2, cdmodes[p->cdslots[i].type + 1]);
1375 }
1376 }
1377 cfgfile_write_str (f, tmp, tmp2);
1378 }
1379 }
1380
1381 for (i = 0; i < MAX_LUA_STATES; i++) {
1382 if (p->luafiles[i][0]) {
1383 cfgfile_write_str (f, _T("lua"), p->luafiles[i]);
1384 }
1385 }
1386
1387 if (p->statefile[0])
1388 cfgfile_write_str (f, _T("statefile"), p->statefile);
1389 if (p->quitstatefile[0])
1390 cfgfile_write_str (f, _T("statefile_quit"), p->quitstatefile);
1391
1392 cfgfile_write (f, _T("nr_floppies"), _T("%d"), p->nr_floppies);
1393 cfgfile_dwrite_bool (f, _T("floppy_write_protect"), p->floppy_read_only);
1394 cfgfile_write (f, _T("floppy_speed"), _T("%d"), p->floppy_speed);
1395 cfgfile_dwrite (f, _T("floppy_channel_mask"), _T("0x%x"), p->dfxclickchannelmask);
1396 cfgfile_write (f, _T("cd_speed"), _T("%d"), p->cd_speed);
1397 cfgfile_write_bool (f, _T("parallel_on_demand"), p->parallel_demand);
1398 cfgfile_write_bool (f, _T("serial_on_demand"), p->serial_demand);
1399 cfgfile_write_bool (f, _T("serial_hardware_ctsrts"), p->serial_hwctsrts);
1400 cfgfile_write_bool (f, _T("serial_direct"), p->serial_direct);
1401 cfgfile_dwrite (f, _T("serial_stopbits"), _T("%d"), p->serial_stopbits);
1402 cfgfile_dwrite_str(f, _T("serial_translate"), serialcrlf[p->serial_crlf]);
1403 cfgfile_write_str (f, _T("scsi"), scsimode[p->scsi]);
1404 cfgfile_write_bool (f, _T("uaeserial"), p->uaeserial);
1405 cfgfile_write_bool (f, _T("sana2"), p->sana2);
1406
1407 cfgfile_write_str (f, _T("sound_output"), soundmode1[p->produce_sound]);
1408 cfgfile_write_str (f, _T("sound_channels"), stereomode[p->sound_stereo]);
1409 cfgfile_write (f, _T("sound_stereo_separation"), _T("%d"), p->sound_stereo_separation);
1410 cfgfile_write (f, _T("sound_stereo_mixing_delay"), _T("%d"), p->sound_mixed_stereo_delay >= 0 ? p->sound_mixed_stereo_delay : 0);
1411 cfgfile_write (f, _T("sound_max_buff"), _T("%d"), p->sound_maxbsiz);
1412 cfgfile_write (f, _T("sound_frequency"), _T("%d"), p->sound_freq);
1413 cfgfile_write_str (f, _T("sound_interpol"), interpolmode[p->sound_interpol]);
1414 cfgfile_write_str (f, _T("sound_filter"), soundfiltermode1[p->sound_filter]);
1415 cfgfile_write_str (f, _T("sound_filter_type"), soundfiltermode2[p->sound_filter_type]);
1416 cfgfile_write (f, _T("sound_volume"), _T("%d"), p->sound_volume_master);
1417 cfgfile_write (f, _T("sound_volume_paula"), _T("%d"), p->sound_volume_paula);
1418 if (p->sound_volume_cd >= 0)
1419 cfgfile_write (f, _T("sound_volume_cd"), _T("%d"), p->sound_volume_cd);
1420 if (p->sound_volume_board >= 0)
1421 cfgfile_write (f, _T("sound_volume_ahi"), _T("%d"), p->sound_volume_board);
1422 cfgfile_write_bool (f, _T("sound_auto"), p->sound_auto);
1423 cfgfile_write_bool (f, _T("sound_cdaudio"), p->sound_cdaudio);
1424 cfgfile_write_bool (f, _T("sound_stereo_swap_paula"), p->sound_stereo_swap_paula);
1425 cfgfile_write_bool (f, _T("sound_stereo_swap_ahi"), p->sound_stereo_swap_ahi);
1426 cfgfile_dwrite (f, _T("sampler_frequency"), _T("%d"), p->sampler_freq);
1427 cfgfile_dwrite (f, _T("sampler_buffer"), _T("%d"), p->sampler_buffer);
1428 cfgfile_dwrite_bool (f, _T("sampler_stereo"), p->sampler_stereo);
1429
1430 cfgfile_write_str (f, _T("comp_trustbyte"), compmode[p->comptrustbyte]);
1431 cfgfile_write_str (f, _T("comp_trustword"), compmode[p->comptrustword]);
1432 cfgfile_write_str (f, _T("comp_trustlong"), compmode[p->comptrustlong]);
1433 cfgfile_write_str (f, _T("comp_trustnaddr"), compmode[p->comptrustnaddr]);
1434 cfgfile_write_bool (f, _T("comp_nf"), p->compnf);
1435 cfgfile_write_bool (f, _T("comp_constjump"), p->comp_constjump);
1436 cfgfile_write_str (f, _T("comp_flushmode"), flushmode[p->comp_hardflush]);
1437 #ifdef USE_JIT_FPU
1438 cfgfile_write_bool (f, _T("compfpu"), p->compfpu);
1439 #endif
1440 cfgfile_write (f, _T("cachesize"), _T("%d"), p->cachesize);
1441
1442 for (i = 0; i < MAX_JPORTS; i++) {
1443 struct jport *jp = &p->jports[i];
1444 int v = jp->id;
1445 TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH];
1446 if (v == JPORT_NONE) {
1447 _tcscpy (tmp2, _T("none"));
1448 } else if (v < JSEM_CUSTOM) {
1449 _stprintf(tmp2, _T("kbd%d"), v + 1);
1450 } else if (v < JSEM_JOYS) {
1451 _stprintf(tmp2, _T("custom%d"), v - JSEM_CUSTOM);
1452 } else if (v < JSEM_MICE) {
1453 _stprintf (tmp2, _T("joy%d"), v - JSEM_JOYS);
1454 } else {
1455 _tcscpy (tmp2, _T("mouse"));
1456 if (v - JSEM_MICE > 0)
1457 _stprintf (tmp2, _T("mouse%d"), v - JSEM_MICE);
1458 }
1459 if (i < 2 || jp->id >= 0) {
1460 _stprintf (tmp1, _T("joyport%d"), i);
1461 cfgfile_write (f, tmp1, tmp2);
1462 _stprintf (tmp1, _T("joyport%dautofire"), i);
1463 cfgfile_write (f, tmp1, joyaf[jp->autofire]);
1464 if (i < 2 && jp->mode > 0) {
1465 _stprintf (tmp1, _T("joyport%dmode"), i);
1466 cfgfile_write (f, tmp1, joyportmodes[jp->mode]);
1467 }
1468 if (jp->name[0]) {
1469 _stprintf (tmp1, _T("joyportfriendlyname%d"), i);
1470 cfgfile_write (f, tmp1, jp->name);
1471 }
1472 if (jp->configname[0]) {
1473 _stprintf (tmp1, _T("joyportname%d"), i);
1474 cfgfile_write (f, tmp1, jp->configname);
1475 }
1476 if (jp->nokeyboardoverride) {
1477 _stprintf (tmp1, _T("joyport%dkeyboardoverride"), i);
1478 cfgfile_write_bool (f, tmp1, !jp->nokeyboardoverride);
1479 }
1480 }
1481 }
1482 for (i = 0; i < MAX_JPORTS_CUSTOM; i++) {
1483 struct jport_custom *jp = &p->jports_custom[i];
1484 if (jp->custom[0]) {
1485 TCHAR tmp1[MAX_DPATH];
1486 _stprintf(tmp1, _T("joyportcustom%d"), i);
1487 cfgfile_write(f, tmp1, jp->custom);
1488 }
1489 }
1490
1491 if (p->dongle) {
1492 if (p->dongle + 1 >= sizeof (dongles) / sizeof (TCHAR*))
1493 cfgfile_write (f, _T("dongle"), _T("%d"), p->dongle);
1494 else
1495 cfgfile_write_str (f, _T("dongle"), dongles[p->dongle]);
1496 }
1497
1498 cfgfile_write_bool (f, _T("bsdsocket_emu"), p->socket_emu);
1499 if (p->a2065name[0])
1500 cfgfile_write_str (f, _T("a2065"), p->a2065name);
1501 if (p->ne2000pciname[0])
1502 cfgfile_write_str(f, _T("ne2000_pci"), p->ne2000pciname);
1503
1504 #ifdef WITH_SLIRP
1505 #ifdef FSUAE
1506 cfgfile_dwrite_str(f, _T("slirp_implementation"), slirp_implementations[p->slirp_implementation]);
1507 #endif
1508 tmp[0] = 0;
1509 for (i = 0; i < MAX_SLIRP_REDIRS; i++) {
1510 struct slirp_redir *sr = &p->slirp_redirs[i];
1511 if (sr->proto && !sr->srcport) {
1512 TCHAR *p = tmp + _tcslen (tmp);
1513 if (p > tmp)
1514 *p++ = ',';
1515 _stprintf (p, _T("%d"), sr->dstport);
1516 }
1517 }
1518 if (tmp[0])
1519 cfgfile_write_str (f, _T("slirp_ports"), tmp);
1520 for (i = 0; i < MAX_SLIRP_REDIRS; i++) {
1521 struct slirp_redir *sr = &p->slirp_redirs[i];
1522 if (sr->proto && sr->srcport) {
1523 uae_u32 v = htonl (sr->addr);
1524 if (v) {
1525 _stprintf (tmp, _T("%s:%d:%d:%d.%d.%d.%d"),
1526 sr->proto == 1 ? _T("tcp") : _T("udp"),
1527 sr->dstport, sr->srcport,
1528 (v >> 24) & 0xff, (v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff);
1529 } else {
1530 _stprintf (tmp, _T("%s:%d:%d"),
1531 sr->proto == 1 ? _T("tcp") : _T("udp"),
1532 sr->dstport, sr->srcport);
1533 }
1534 cfgfile_write_str (f, _T("slirp_redir"), tmp);
1535 }
1536 }
1537 #endif /* WITH_SLIRP */
1538
1539 cfgfile_write_bool (f, _T("synchronize_clock"), p->tod_hack);
1540 cfgfile_write (f, _T("maprom"), _T("0x%x"), p->maprom);
1541 cfgfile_dwrite_str (f, _T("boot_rom_uae"), uaebootrom[p->boot_rom]);
1542 cfgfile_dwrite_str (f, _T("parallel_matrix_emulation"), epsonprinter[p->parallel_matrix_emulation]);
1543 cfgfile_write_bool (f, _T("parallel_postscript_emulation"), p->parallel_postscript_emulation);
1544 cfgfile_write_bool (f, _T("parallel_postscript_detection"), p->parallel_postscript_detection);
1545 cfgfile_write_str (f, _T("ghostscript_parameters"), p->ghostscript_parameters);
1546 cfgfile_write (f, _T("parallel_autoflush"), _T("%d"), p->parallel_autoflush_time);
1547 cfgfile_dwrite (f, _T("uae_hide"), _T("%d"), p->uae_hide);
1548 cfgfile_dwrite_bool (f, _T("uae_hide_autoconfig"), p->uae_hide_autoconfig);
1549 cfgfile_dwrite_bool (f, _T("magic_mouse"), p->input_magic_mouse);
1550 cfgfile_dwrite_str (f, _T("magic_mousecursor"), magiccursors[p->input_magic_mouse_cursor]);
1551 cfgfile_dwrite_str (f, _T("absolute_mouse"), abspointers[p->input_tablet]);
1552 cfgfile_dwrite_bool (f, _T("tablet_library"), p->tablet_library);
1553 cfgfile_dwrite_bool (f, _T("clipboard_sharing"), p->clipboard_sharing);
1554 cfgfile_dwrite_bool(f, _T("native_code"), p->native_code);
1555
1556 cfgfile_write (f, _T("gfx_display"), _T("%d"), p->gfx_apmode[APMODE_NATIVE].gfx_display);
1557 cfgfile_write_str (f, _T("gfx_display_friendlyname"), target_get_display_name (p->gfx_apmode[APMODE_NATIVE].gfx_display, true));
1558 cfgfile_write_str (f, _T("gfx_display_name"), target_get_display_name (p->gfx_apmode[APMODE_NATIVE].gfx_display, false));
1559 cfgfile_write (f, _T("gfx_display_rtg"), _T("%d"), p->gfx_apmode[APMODE_RTG].gfx_display);
1560 cfgfile_write_str (f, _T("gfx_display_friendlyname_rtg"), target_get_display_name (p->gfx_apmode[APMODE_RTG].gfx_display, true));
1561 cfgfile_write_str (f, _T("gfx_display_name_rtg"), target_get_display_name (p->gfx_apmode[APMODE_RTG].gfx_display, false));
1562
1563 cfgfile_write (f, _T("gfx_framerate"), _T("%d"), p->gfx_framerate);
1564 write_resolution (f, _T("gfx_width"), _T("gfx_height"), &p->gfx_size_win); /* compatibility with old versions */
1565 cfgfile_write (f, _T("gfx_top_windowed"), _T("%d"), p->gfx_size_win.x);
1566 cfgfile_write (f, _T("gfx_left_windowed"), _T("%d"), p->gfx_size_win.y);
1567 write_resolution (f, _T("gfx_width_windowed"), _T("gfx_height_windowed"), &p->gfx_size_win);
1568 write_resolution (f, _T("gfx_width_fullscreen"), _T("gfx_height_fullscreen"), &p->gfx_size_fs);
1569 cfgfile_write (f, _T("gfx_refreshrate"), _T("%d"), p->gfx_apmode[0].gfx_refreshrate);
1570 cfgfile_dwrite (f, _T("gfx_refreshrate_rtg"), _T("%d"), p->gfx_apmode[1].gfx_refreshrate);
1571 cfgfile_write (f, _T("gfx_autoresolution"), _T("%d"), p->gfx_autoresolution);
1572 cfgfile_dwrite (f, _T("gfx_autoresolution_delay"), _T("%d"), p->gfx_autoresolution_delay);
1573 cfgfile_dwrite (f, _T("gfx_autoresolution_min_vertical"), vertmode[p->gfx_autoresolution_minv + 1]);
1574 cfgfile_dwrite (f, _T("gfx_autoresolution_min_horizontal"), horizmode[p->gfx_autoresolution_minh + 1]);
1575 cfgfile_write_bool (f, _T("gfx_autoresolution_vga"), p->gfx_autoresolution_vga);
1576
1577 cfgfile_write (f, _T("gfx_backbuffers"), _T("%d"), p->gfx_apmode[0].gfx_backbuffers);
1578 cfgfile_write (f, _T("gfx_backbuffers_rtg"), _T("%d"), p->gfx_apmode[1].gfx_backbuffers);
1579 if (p->gfx_apmode[APMODE_NATIVE].gfx_interlaced)
1580 cfgfile_write_bool (f, _T("gfx_interlace"), p->gfx_apmode[APMODE_NATIVE].gfx_interlaced);
1581 cfgfile_write_str (f, _T("gfx_vsync"), vsyncmodes[p->gfx_apmode[0].gfx_vsync]);
1582 cfgfile_write_str (f, _T("gfx_vsyncmode"), vsyncmodes2[p->gfx_apmode[0].gfx_vsyncmode]);
1583 cfgfile_write_str (f, _T("gfx_vsync_picasso"), vsyncmodes[p->gfx_apmode[1].gfx_vsync]);
1584 cfgfile_write_str (f, _T("gfx_vsyncmode_picasso"), vsyncmodes2[p->gfx_apmode[1].gfx_vsyncmode]);
1585 cfgfile_write_bool (f, _T("gfx_lores"), p->gfx_resolution == 0);
1586 cfgfile_write_str (f, _T("gfx_resolution"), lorestype1[p->gfx_resolution]);
1587 cfgfile_write_str (f, _T("gfx_lores_mode"), loresmode[p->gfx_lores_mode]);
1588 cfgfile_write_bool (f, _T("gfx_flickerfixer"), p->gfx_scandoubler);
1589 cfgfile_write_str (f, _T("gfx_linemode"), p->gfx_vresolution > 0 ? linemode[p->gfx_iscanlines * 4 + p->gfx_pscanlines + 1] : linemode[0]);
1590 cfgfile_write_str (f, _T("gfx_fullscreen_amiga"), fullmodes[p->gfx_apmode[0].gfx_fullscreen]);
1591 cfgfile_write_str (f, _T("gfx_fullscreen_picasso"), fullmodes[p->gfx_apmode[1].gfx_fullscreen]);
1592 cfgfile_write_str (f, _T("gfx_center_horizontal"), centermode1[p->gfx_xcenter]);
1593 cfgfile_write_str (f, _T("gfx_center_vertical"), centermode1[p->gfx_ycenter]);
1594 cfgfile_write_str (f, _T("gfx_colour_mode"), colormode1[p->color_mode]);
1595 cfgfile_write_bool (f, _T("gfx_blacker_than_black"), p->gfx_blackerthanblack);
1596 cfgfile_dwrite_bool (f, _T("gfx_black_frame_insertion"), p->lightboost_strobo);
1597 cfgfile_write_str (f, _T("gfx_api"), filterapi[p->gfx_api]);
1598 cfgfile_dwrite (f, _T("gfx_horizontal_tweak"), _T("%d"), p->gfx_extrawidth);
1599
1600 #ifdef GFXFILTER
1601 for (int j = 0; j < 2; j++) {
1602 struct gfx_filterdata *gf = &p->gf[j];
1603 const TCHAR *ext = j == 0 ? NULL : _T("_rtg");
1604 for (int i = 0; i <MAX_FILTERSHADERS; i++) {
1605 if (gf->gfx_filtershader[i][0])
1606 cfgfile_write_ext (f, _T("gfx_filter_pre"), ext, _T("D3D:%s"), gf->gfx_filtershader[i]);
1607 if (gf->gfx_filtermask[i][0])
1608 cfgfile_write_str (f, _T("gfx_filtermask_pre"), ext, gf->gfx_filtermask[i]);
1609 }
1610 for (int i = 0; i < MAX_FILTERSHADERS; i++) {
1611 if (gf->gfx_filtershader[i + MAX_FILTERSHADERS][0])
1612 cfgfile_write_ext (f, _T("gfx_filter_post"), ext, _T("D3D:%s"), gf->gfx_filtershader[i + MAX_FILTERSHADERS]);
1613 if (gf->gfx_filtermask[i + MAX_FILTERSHADERS][0])
1614 cfgfile_write_str (f, _T("gfx_filtermask_post"), ext, gf->gfx_filtermask[i + MAX_FILTERSHADERS]);
1615 }
1616 cfgfile_dwrite_str (f, _T("gfx_filter_mask"), ext, gf->gfx_filtermask[2 * MAX_FILTERSHADERS]);
1617 {
1618 bool d3dfound = false;
1619 if (gf->gfx_filtershader[2 * MAX_FILTERSHADERS][0] && p->gfx_api) {
1620 cfgfile_dwrite_ext (f, _T("gfx_filter"), ext, _T("D3D:%s"), gf->gfx_filtershader[2 * MAX_FILTERSHADERS]);
1621 d3dfound = true;
1622 }
1623 if (!d3dfound) {
1624 if (gf->gfx_filter > 0) {
1625 int i = 0;
1626 struct uae_filter *uf;
1627 while (uaefilters[i].name) {
1628 uf = &uaefilters[i];
1629 if (uf->type == gf->gfx_filter) {
1630 cfgfile_dwrite_str (f, _T("gfx_filter"), ext, uf->cfgname);
1631 }
1632 i++;
1633 }
1634 } else {
1635 cfgfile_dwrite_ext (f, _T("gfx_filter"), ext, _T("no"));
1636 }
1637 }
1638 }
1639 cfgfile_dwrite_str (f, _T("gfx_filter_mode"), ext, filtermode2[gf->gfx_filter_filtermode]);
1640 cfgfile_dwrite_ext (f, _T("gfx_filter_vert_zoomf"), ext, _T("%f"), gf->gfx_filter_vert_zoom);
1641 cfgfile_dwrite_ext (f, _T("gfx_filter_horiz_zoomf"), ext, _T("%f"), gf->gfx_filter_horiz_zoom);
1642 cfgfile_dwrite_ext (f, _T("gfx_filter_vert_zoom_multf"), ext, _T("%f"), gf->gfx_filter_vert_zoom_mult);
1643 cfgfile_dwrite_ext (f, _T("gfx_filter_horiz_zoom_multf"), ext, _T("%f"), gf->gfx_filter_horiz_zoom_mult);
1644 cfgfile_dwrite_ext (f, _T("gfx_filter_vert_offsetf"), ext, _T("%f"), gf->gfx_filter_vert_offset);
1645 cfgfile_dwrite_ext (f, _T("gfx_filter_horiz_offsetf"), ext, _T("%f"), gf->gfx_filter_horiz_offset);
1646
1647 cfgfile_dwrite_ext (f, _T("gfx_filter_left_border"), ext, _T("%d"), gf->gfx_filter_left_border);
1648 cfgfile_dwrite_ext (f, _T("gfx_filter_right_border"), ext, _T("%d"), gf->gfx_filter_right_border);
1649 cfgfile_dwrite_ext (f, _T("gfx_filter_top_border"), ext, _T("%d"), gf->gfx_filter_top_border);
1650 cfgfile_dwrite_ext (f, _T("gfx_filter_bottom_border"), ext, _T("%d"), gf->gfx_filter_bottom_border);
1651
1652 cfgfile_dwrite_ext (f, _T("gfx_filter_scanlines"), ext, _T("%d"), gf->gfx_filter_scanlines);
1653 cfgfile_dwrite_ext (f, _T("gfx_filter_scanlinelevel"), ext, _T("%d"), gf->gfx_filter_scanlinelevel);
1654 cfgfile_dwrite_ext (f, _T("gfx_filter_scanlineratio"), ext, _T("%d"), gf->gfx_filter_scanlineratio);
1655
1656 cfgfile_dwrite_ext (f, _T("gfx_filter_luminance"), ext, _T("%d"), gf->gfx_filter_luminance);
1657 cfgfile_dwrite_ext (f, _T("gfx_filter_contrast"), ext, _T("%d"), gf->gfx_filter_contrast);
1658 cfgfile_dwrite_ext (f, _T("gfx_filter_saturation"), ext, _T("%d"), gf->gfx_filter_saturation);
1659 cfgfile_dwrite_ext (f, _T("gfx_filter_gamma"), ext, _T("%d"), gf->gfx_filter_gamma);
1660 cfgfile_dwrite_ext (f, _T("gfx_filter_gamma_r"), ext, _T("%d"), gf->gfx_filter_gamma_ch[0]);
1661 cfgfile_dwrite_ext (f, _T("gfx_filter_gamma_g"), ext, _T("%d"), gf->gfx_filter_gamma_ch[1]);
1662 cfgfile_dwrite_ext (f, _T("gfx_filter_gamma_b"), ext, _T("%d"), gf->gfx_filter_gamma_ch[2]);
1663
1664 cfgfile_dwrite_ext (f, _T("gfx_filter_blur"), ext, _T("%d"), gf->gfx_filter_blur);
1665 cfgfile_dwrite_ext (f, _T("gfx_filter_noise"), ext, _T("%d"), gf->gfx_filter_noise);
1666 cfgfile_dwrite_bool (f, _T("gfx_filter_bilinear"), ext, gf->gfx_filter_bilinear != 0);
1667
1668 cfgfile_dwrite_ext (f, _T("gfx_filter_keep_autoscale_aspect"), ext, _T("%d"), gf->gfx_filter_keep_autoscale_aspect);
1669 cfgfile_dwrite_str (f, _T("gfx_filter_keep_aspect"), ext, aspects[gf->gfx_filter_keep_aspect]);
1670 cfgfile_dwrite_str(f, _T("gfx_filter_autoscale"), ext, ext == NULL ? autoscale[gf->gfx_filter_autoscale] : autoscale_rtg[gf->gfx_filter_autoscale]);
1671 cfgfile_dwrite_str (f, _T("gfx_filter_autoscale_limit"), ext, autoscalelimit[gf->gfx_filter_integerscalelimit]);
1672 cfgfile_dwrite_ext (f, _T("gfx_filter_aspect_ratio"), ext, _T("%d:%d"),
1673 gf->gfx_filter_aspect >= 0 ? (gf->gfx_filter_aspect / ASPECTMULT) : -1,
1674 gf->gfx_filter_aspect >= 0 ? (gf->gfx_filter_aspect & (ASPECTMULT - 1)) : -1);
1675 if (gf->gfx_filteroverlay[0]) {
1676 cfgfile_dwrite_ext(f, _T("gfx_filter_overlay"), ext, _T("%s%s"),
1677 gf->gfx_filteroverlay, _tcschr (gf->gfx_filteroverlay, ',') ? _T(",") : _T(""));
1678 }
1679 }
1680 cfgfile_dwrite (f, _T("gfx_luminance"), _T("%d"), p->gfx_luminance);
1681 cfgfile_dwrite (f, _T("gfx_contrast"), _T("%d"), p->gfx_contrast);
1682 cfgfile_dwrite (f, _T("gfx_gamma"), _T("%d"), p->gfx_gamma);
1683 cfgfile_dwrite (f, _T("gfx_gamma_r"), _T("%d"), p->gfx_gamma_ch[0]);
1684 cfgfile_dwrite (f, _T("gfx_gamma_g"), _T("%d"), p->gfx_gamma_ch[1]);
1685 cfgfile_dwrite (f, _T("gfx_gamma_b"), _T("%d"), p->gfx_gamma_ch[2]);
1686
1687 cfgfile_dwrite (f, _T("gfx_center_horizontal_position"), _T("%d"), p->gfx_xcenter_pos);
1688 cfgfile_dwrite (f, _T("gfx_center_vertical_position"), _T("%d"), p->gfx_ycenter_pos);
1689 cfgfile_dwrite (f, _T("gfx_center_horizontal_size"), _T("%d"), p->gfx_xcenter_size);
1690 cfgfile_dwrite (f, _T("gfx_center_vertical_size"), _T("%d"), p->gfx_ycenter_size);
1691
1692 cfgfile_dwrite (f, _T("rtg_vert_zoom_multf"), _T("%.f"), p->rtg_vert_zoom_mult);
1693 cfgfile_dwrite (f, _T("rtg_horiz_zoom_multf"), _T("%.f"), p->rtg_horiz_zoom_mult);
1694
1695 #endif
1696
1697 cfgfile_write_bool (f, _T("immediate_blits"), p->immediate_blits);
1698 cfgfile_dwrite_str (f, _T("waiting_blits"), waitblits[p->waiting_blits]);
1699 cfgfile_write_bool (f, _T("ntsc"), p->ntscmode);
1700 cfgfile_write_bool (f, _T("genlock"), p->genlock);
1701 cfgfile_dwrite_str(f, _T("genlockmode"), genlockmodes[p->genlock_image]);
1702 cfgfile_dwrite_str(f, _T("genlock_image"), p->genlock_image_file);
1703 cfgfile_dwrite(f, _T("genlock_mix"), _T("%d"), p->genlock_mix);
1704 cfgfile_dwrite_str(f, _T("monitoremu"), specialmonitors[p->monitoremu]);
1705
1706 cfgfile_dwrite_bool (f, _T("show_leds"), !!(p->leds_on_screen & STATUSLINE_CHIPSET));
1707 cfgfile_dwrite_bool (f, _T("show_leds_rtg"), !!(p->leds_on_screen & STATUSLINE_RTG));
1708 write_leds(f, _T("show_leds_enabled"), p->leds_on_screen_mask[0]);
1709 write_leds(f, _T("show_leds_enabled_rtg"), p->leds_on_screen_mask[1]);
1710 cfgfile_dwrite_bool(f, _T("show_refresh_indicator"), p->refresh_indicator);
1711
1712 if (p->osd_pos.y || p->osd_pos.x) {
1713 cfgfile_dwrite (f, _T("osd_position"), _T("%.1f%s:%.1f%s"),
1714 p->osd_pos.x >= 20000 ? (p->osd_pos.x - 30000) / 10.0 : (float)p->osd_pos.x, p->osd_pos.x >= 20000 ? _T("%") : _T(""),
1715 p->osd_pos.y >= 20000 ? (p->osd_pos.y - 30000) / 10.0 : (float)p->osd_pos.y, p->osd_pos.y >= 20000 ? _T("%") : _T(""));
1716 }
1717 cfgfile_dwrite (f, _T("keyboard_leds"), _T("numlock:%s,capslock:%s,scrolllock:%s"),
1718 kbleds[p->keyboard_leds[0]], kbleds[p->keyboard_leds[1]], kbleds[p->keyboard_leds[2]]);
1719 if (p->chipset_mask & CSMASK_AGA)
1720 cfgfile_write (f, _T("chipset"),_T("aga"));
1721 else if ((p->chipset_mask & CSMASK_ECS_AGNUS) && (p->chipset_mask & CSMASK_ECS_DENISE))
1722 cfgfile_write (f, _T("chipset"),_T("ecs"));
1723 else if (p->chipset_mask & CSMASK_ECS_AGNUS)
1724 cfgfile_write (f, _T("chipset"),_T("ecs_agnus"));
1725 else if (p->chipset_mask & CSMASK_ECS_DENISE)
1726 cfgfile_write (f, _T("chipset"),_T("ecs_denise"));
1727 else
1728 cfgfile_write (f, _T("chipset"), _T("ocs"));
1729 if (p->chipset_refreshrate > 0)
1730 cfgfile_write (f, _T("chipset_refreshrate"), _T("%f"), p->chipset_refreshrate);
1731
1732 for (int i = 0; i < MAX_CHIPSET_REFRESH_TOTAL; i++) {
1733 if (p->cr[i].rate <= 0)
1734 continue;
1735 struct chipset_refresh *cr = &p->cr[i];
1736 cr->index = i;
1737 _stprintf (tmp, _T("%f"), cr->rate);
1738 TCHAR *s = tmp + _tcslen (tmp);
1739 if (cr->label[0] > 0 && i < MAX_CHIPSET_REFRESH)
1740 s += _stprintf (s, _T(",t=%s"), cr->label);
1741 if (cr->horiz > 0)
1742 s += _stprintf (s, _T(",h=%d"), cr->horiz);
1743 if (cr->vert > 0)
1744 s += _stprintf (s, _T(",v=%d"), cr->vert);
1745 if (cr->locked)
1746 _tcscat (s, _T(",locked"));
1747 if (cr->ntsc > 0)
1748 _tcscat (s, _T(",ntsc"));
1749 else if (cr->ntsc == 0)
1750 _tcscat (s, _T(",pal"));
1751 if (cr->lace > 0)
1752 _tcscat (s, _T(",lace"));
1753 else if (cr->lace == 0)
1754 _tcscat (s, _T(",nlace"));
1755 if (cr->framelength > 0)
1756 _tcscat (s, _T(",lof"));
1757 else if (cr->framelength == 0)
1758 _tcscat (s, _T(",shf"));
1759 if (cr->vsync > 0)
1760 _tcscat (s, _T(",vsync"));
1761 else if (cr->vsync == 0)
1762 _tcscat (s, _T(",nvsync"));
1763 if (cr->rtg)
1764 _tcscat (s, _T(",rtg"));
1765 if (cr->commands[0]) {
1766 _tcscat (s, _T(","));
1767 _tcscat (s, cr->commands);
1768 for (int j = 0; j < _tcslen (s); j++) {
1769 if (s[j] == '\n')
1770 s[j] = ',';
1771 }
1772 s[_tcslen (s) - 1] = 0;
1773 }
1774 if (i == CHIPSET_REFRESH_PAL)
1775 cfgfile_dwrite (f, _T("displaydata_pal"), tmp);
1776 else if (i == CHIPSET_REFRESH_NTSC)
1777 cfgfile_dwrite (f, _T("displaydata_ntsc"), tmp);
1778 else
1779 cfgfile_dwrite (f, _T("displaydata"), tmp);
1780 }
1781
1782 cfgfile_write_str (f, _T("collision_level"), collmode[p->collision_level]);
1783
1784 cfgfile_write_str(f, _T("chipset_compatible"), cscompa[p->cs_compatible]);
1785 cfgfile_dwrite_str (f, _T("ciaatod"), ciaatodmode[p->cs_ciaatod]);
1786 cfgfile_dwrite_str (f, _T("rtc"), rtctype[p->cs_rtc]);
1787 //cfgfile_dwrite (f, _T("chipset_rtc_adjust"), _T("%d"), p->cs_rtc_adjust);
1788 cfgfile_dwrite_bool (f, _T("ksmirror_e0"), p->cs_ksmirror_e0);
1789 cfgfile_dwrite_bool (f, _T("ksmirror_a8"), p->cs_ksmirror_a8);
1790 cfgfile_dwrite_bool (f, _T("cd32cd"), p->cs_cd32cd);
1791 cfgfile_dwrite_bool (f, _T("cd32c2p"), p->cs_cd32c2p);
1792 cfgfile_dwrite_bool(f, _T("cd32nvram"), p->cs_cd32nvram);
1793 cfgfile_dwrite (f, _T("cd32nvram_size"), _T("%d"), p->cs_cd32nvram_size / 1024);
1794 cfgfile_dwrite_bool(f, _T("cd32fmv"), p->cs_cd32fmv);
1795 cfgfile_dwrite_bool(f, _T("cdtvcd"), p->cs_cdtvcd);
1796 cfgfile_dwrite_bool(f, _T("cdtv-cr"), p->cs_cdtvcr);
1797 cfgfile_dwrite_bool (f, _T("cdtvram"), p->cs_cdtvram);
1798 cfgfile_dwrite (f, _T("cdtvramcard"), _T("%d"), p->cs_cdtvcard);
1799 cfgfile_dwrite_str (f, _T("ide"), p->cs_ide == IDE_A600A1200 ? _T("a600/a1200") : (p->cs_ide == IDE_A4000 ? _T("a4000") : _T("none")));
1800 cfgfile_dwrite_bool (f, _T("a1000ram"), p->cs_a1000ram);
1801 cfgfile_dwrite (f, _T("fatgary"), _T("%d"), p->cs_fatgaryrev);
1802 cfgfile_dwrite (f, _T("ramsey"), _T("%d"), p->cs_ramseyrev);
1803 cfgfile_dwrite_bool (f, _T("pcmcia"), p->cs_pcmcia);
1804 cfgfile_dwrite_bool (f, _T("scsi_cdtv"), p->cs_cdtvscsi);
1805 cfgfile_dwrite_bool (f, _T("scsi_a3000"), p->cs_mbdmac == 1);
1806 cfgfile_dwrite_bool (f, _T("scsi_a4000t"), p->cs_mbdmac == 2);
1807 cfgfile_dwrite_bool (f, _T("bogomem_fast"), p->cs_slowmemisfast);
1808 cfgfile_dwrite_bool (f, _T("resetwarning"), p->cs_resetwarning);
1809 cfgfile_dwrite_bool (f, _T("denise_noehb"), p->cs_denisenoehb);
1810 cfgfile_dwrite_bool (f, _T("agnus_bltbusybug"), p->cs_agnusbltbusybug);
1811 cfgfile_dwrite_bool (f, _T("ics_agnus"), p->cs_dipagnus);
1812 cfgfile_dwrite_bool (f, _T("cia_todbug"), p->cs_ciatodbug);
1813 cfgfile_dwrite_bool (f, _T("z3_autoconfig"), p->cs_z3autoconfig);
1814 cfgfile_dwrite_bool (f, _T("1mchipjumper"), p->cs_1mchipjumper);
1815 cfgfile_dwrite (f, _T("chipset_hacks"), _T("0x%x"), p->cs_hacks);
1816
1817 cfgfile_dwrite_str (f, _T("z3mapping"), z3mapping[p->z3_mapping_mode]);
1818 cfgfile_dwrite_bool (f, _T("fastmem_autoconfig"), p->fastmem_autoconfig);
1819 if (p->fastmem_size < 0x100000 && p->fastmem_size)
1820 cfgfile_write (f, _T("fastmem_size_k"), _T("%d"), p->fastmem_size / 1024);
1821 else
1822 cfgfile_write (f, _T("fastmem_size"), _T("%d"), p->fastmem_size / 0x100000);
1823 if (p->fastmem2_size < 0x100000 && p->fastmem2_size)
1824 cfgfile_dwrite (f, _T("fastmem2_size_k"), _T("%d"), p->fastmem2_size / 1024);
1825 else
1826 cfgfile_dwrite (f, _T("fastmem2_size"), _T("%d"), p->fastmem2_size / 0x100000);
1827 cfgfile_write (f, _T("mem25bit_size"), _T("%d"), p->mem25bit_size / 0x100000);
1828 cfgfile_write (f, _T("a3000mem_size"), _T("%d"), p->mbresmem_low_size / 0x100000);
1829 cfgfile_write (f, _T("mbresmem_size"), _T("%d"), p->mbresmem_high_size / 0x100000);
1830 cfgfile_write (f, _T("z3mem_size"), _T("%d"), p->z3fastmem_size / 0x100000);
1831 cfgfile_dwrite (f, _T("z3mem2_size"), _T("%d"), p->z3fastmem2_size / 0x100000);
1832 cfgfile_write (f, _T("z3mem_start"), _T("0x%x"), p->z3autoconfig_start);
1833 cfgfile_write(f, _T("bogomem_size"), _T("%d"), p->bogomem_size / 0x40000);
1834 if (p->cpuboard_type) {
1835 const struct cpuboardtype *cbt = &cpuboards[p->cpuboard_type];
1836 const struct cpuboardsubtype *cbst = &cbt->subtypes[p->cpuboard_subtype];
1837 const struct expansionboardsettings *cbs = cbst->settings;
1838 cfgfile_dwrite_str(f, _T("cpuboard_type"), cbst->configname);
1839 if (cbs && p->cpuboard_settings) {
1840 tmp[0] = 0;
1841 cfgfile_write_rom_settings(cbs, tmp, p->cpuboard_settings);
1842 cfgfile_dwrite_str(f, _T("cpuboard_settings"), tmp);
1843 }
1844 } else {
1845 cfgfile_dwrite_str(f, _T("cpuboard_type"), _T("none"));
1846 }
1847 cfgfile_dwrite(f, _T("cpuboardmem1_size"), _T("%d"), p->cpuboardmem1_size / 0x100000);
1848 cfgfile_dwrite(f, _T("cpuboardmem2_size"), _T("%d"), p->cpuboardmem2_size / 0x100000);
1849 cfgfile_write(f, _T("gfxcard_size"), _T("%d"), p->rtgmem_size / 0x100000);
1850 cfgfile_write_str(f, _T("gfxcard_type"), gfxboard_get_configname(p->rtgmem_type));
1851 cfgfile_write_bool(f, _T("gfxcard_hardware_vblank"), p->rtg_hardwareinterrupt);
1852 cfgfile_write_bool (f, _T("gfxcard_hardware_sprite"), p->rtg_hardwaresprite);
1853 cfgfile_write (f, _T("chipmem_size"), _T("%d"), p->chipmem_size == 0x20000 ? -1 : (p->chipmem_size == 0x40000 ? 0 : p->chipmem_size / 0x80000));
1854 cfgfile_dwrite (f, _T("megachipmem_size"), _T("%d"), p->z3chipmem_size / 0x100000);
1855 // do not save aros rom special space
1856 if (!(p->custom_memory_sizes[0] == 512 * 1024 && p->custom_memory_sizes[1] == 512 * 1024 && p->custom_memory_addrs[0] == 0xa80000 && p->custom_memory_addrs[1] == 0xb00000)) {
1857 if (p->custom_memory_sizes[0])
1858 cfgfile_write (f, _T("addmem1"), _T("0x%x,0x%x"), p->custom_memory_addrs[0], p->custom_memory_sizes[0]);
1859 if (p->custom_memory_sizes[1])
1860 cfgfile_write (f, _T("addmem2"), _T("0x%x,0x%x"), p->custom_memory_addrs[1], p->custom_memory_sizes[1]);
1861 }
1862
1863 if (p->m68k_speed > 0) {
1864 cfgfile_write (f, _T("finegrain_cpu_speed"), _T("%d"), p->m68k_speed);
1865 } else {
1866 cfgfile_write_str (f, _T("cpu_speed"), p->m68k_speed < 0 ? _T("max") : _T("real"));
1867 }
1868 cfgfile_write (f, _T("cpu_throttle"), _T("%.1f"), p->m68k_speed_throttle);
1869 cfgfile_dwrite(f, _T("cpu_x86_throttle"), _T("%.1f"), p->x86_speed_throttle);
1870
1871 /* do not reorder start */
1872 write_compatibility_cpu(f, p);
1873 cfgfile_write (f, _T("cpu_model"), _T("%d"), p->cpu_model);
1874 if (p->fpu_model)
1875 cfgfile_write (f, _T("fpu_model"), _T("%d"), p->fpu_model);
1876 if (p->mmu_model)
1877 cfgfile_write (f, _T("mmu_model"), _T("%d"), p->mmu_model);
1878 if (p->ppc_mode) {
1879 cfgfile_write_str(f, _T("ppc_model"), p->ppc_model[0] ? p->ppc_model : (p->ppc_mode == 1 ? _T("automatic") : _T("manual")));
1880 cfgfile_write_str(f, _T("ppc_cpu_idle"), ppc_cpu_idle[p->ppc_cpu_idle]);
1881 }
1882 cfgfile_write_bool (f, _T("cpu_compatible"), p->cpu_compatible);
1883 cfgfile_write_bool (f, _T("cpu_24bit_addressing"), p->address_space_24);
1884 /* do not reorder end */
1885 cfgfile_dwrite_bool(f, _T("cpu_reset_pause"), p->reset_delay);
1886 cfgfile_dwrite_bool(f, _T("cpu_threaded"), p->cpu_thread);
1887 if (p->ppc_mode)
1888 cfgfile_write_str(f, _T("ppc_implementation"), ppc_implementations[p->ppc_implementation]);
1889
1890 if (p->cpu_cycle_exact) {
1891 if (p->cpu_frequency)
1892 cfgfile_write (f, _T("cpu_frequency"), _T("%d"), p->cpu_frequency);
1893 if (p->cpu_clock_multiplier) {
1894 if (p->cpu_clock_multiplier >= 256)
1895 cfgfile_write (f, _T("cpu_multiplier"), _T("%d"), p->cpu_clock_multiplier >> 8);
1896 }
1897 }
1898
1899 cfgfile_write_bool (f, _T("cpu_cycle_exact"), p->cpu_cycle_exact);
1900 // must be after cpu_cycle_exact
1901 cfgfile_write_bool (f, _T("cpu_memory_cycle_exact"), p->cpu_memory_cycle_exact);
1902 cfgfile_write_bool (f, _T("blitter_cycle_exact"), p->blitter_cycle_exact);
1903 // must be after cpu_cycle_exact, cpu_memory_cycle_exact and blitter_cycle_exact
1904 if (p->cpu_cycle_exact && p->blitter_cycle_exact)
1905 cfgfile_write_str (f, _T("cycle_exact"), cycleexact[2]);
1906 else if (p->cpu_memory_cycle_exact && p->blitter_cycle_exact)
1907 cfgfile_write_str (f, _T("cycle_exact"), cycleexact[1]);
1908 else
1909 cfgfile_write_str (f, _T("cycle_exact"), cycleexact[0]);
1910
1911 cfgfile_dwrite_bool (f, _T("fpu_no_unimplemented"), p->fpu_no_unimplemented);
1912 cfgfile_dwrite_bool (f, _T("cpu_no_unimplemented"), p->int_no_unimplemented);
1913 cfgfile_write_bool (f, _T("fpu_strict"), p->fpu_strict);
1914 cfgfile_dwrite_bool (f, _T("fpu_softfloat"), p->fpu_softfloat);
1915
1916 cfgfile_write_bool (f, _T("rtg_nocustom"), p->picasso96_nocustom);
1917 cfgfile_write (f, _T("rtg_modes"), _T("0x%x"), p->picasso96_modeflags);
1918
1919 cfgfile_write_bool (f, _T("log_illegal_mem"), p->illegal_mem);
1920 if (p->catweasel >= 100)
1921 cfgfile_dwrite (f, _T("catweasel"), _T("0x%x"), p->catweasel);
1922 else
1923 cfgfile_dwrite (f, _T("catweasel"), _T("%d"), p->catweasel);
1924 cfgfile_write_bool(f, _T("toccata"), p->sound_toccata);
1925 if (p->sound_toccata_mixer)
1926 cfgfile_write_bool(f, _T("toccata_mixer"), p->sound_toccata_mixer);
1927 cfgfile_write_bool(f, _T("es1370_pci"), p->sound_es1370);
1928 cfgfile_write_bool(f, _T("fm801_pci"), p->sound_fm801);
1929
1930 cfgfile_write_str (f, _T("kbd_lang"), (p->keyboard_lang == KBD_LANG_DE ? _T("de")
1931 : p->keyboard_lang == KBD_LANG_DK ? _T("dk")
1932 : p->keyboard_lang == KBD_LANG_ES ? _T("es")
1933 : p->keyboard_lang == KBD_LANG_US ? _T("us")
1934 : p->keyboard_lang == KBD_LANG_SE ? _T("se")
1935 : p->keyboard_lang == KBD_LANG_FR ? _T("fr")
1936 : p->keyboard_lang == KBD_LANG_IT ? _T("it")
1937 : _T("FOO")));
1938
1939 cfgfile_dwrite (f, _T("state_replay_rate"), _T("%d"), p->statecapturerate);
1940 cfgfile_dwrite (f, _T("state_replay_buffers"), _T("%d"), p->statecapturebuffersize);
1941 cfgfile_dwrite_bool (f, _T("state_replay_autoplay"), p->inprec_autoplay);
1942 cfgfile_dwrite_bool (f, _T("warp"), p->turbo_emulation);
1943 cfgfile_dwrite (f, _T("warp_limit"), _T("%d"), p->turbo_emulation_limit);
1944
1945 #ifdef FILESYS
1946 write_filesys_config (p, f);
1947 if (p->filesys_no_uaefsdb)
1948 cfgfile_write_bool (f, _T("filesys_no_fsdb"), p->filesys_no_uaefsdb);
1949 cfgfile_dwrite (f, _T("filesys_max_size"), _T("%d"), p->filesys_limit);
1950 cfgfile_dwrite (f, _T("filesys_max_name_length"), _T("%d"), p->filesys_max_name);
1951 cfgfile_dwrite (f, _T("filesys_max_file_size"), _T("%d"), p->filesys_max_file_size);
1952 cfgfile_dwrite_bool (f, _T("filesys_inject_icons"), p->filesys_inject_icons);
1953 cfgfile_dwrite_str (f, _T("filesys_inject_icons_drawer"), p->filesys_inject_icons_drawer);
1954 cfgfile_dwrite_str (f, _T("filesys_inject_icons_project"), p->filesys_inject_icons_project);
1955 cfgfile_dwrite_str (f, _T("filesys_inject_icons_tool"), p->filesys_inject_icons_tool);
1956 cfgfile_dwrite_str (f, _T("scsidev_mode"), uaescsidevmodes[p->uaescsidevmode]);
1957 #endif
1958
1959 cfgfile_dwrite(f, _T("uaeboard_mode"), _T("%d"), p->uaeboard);
1960
1961 write_inputdevice_config (p, f);
1962 }
1963
cfgfile_yesno(const TCHAR * option,const TCHAR * value,const TCHAR * name,int * location,bool numbercheck)1964 static int cfgfile_yesno (const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location, bool numbercheck)
1965 {
1966 if (name != NULL && _tcscmp (option, name) != 0)
1967 return 0;
1968 if (strcasecmp (value, _T("yes")) == 0 || strcasecmp (value, _T("y")) == 0
1969 || strcasecmp (value, _T("true")) == 0 || strcasecmp (value, _T("t")) == 0
1970 || (numbercheck && strcasecmp (value, _T("1")) == 0))
1971 *location = 1;
1972 else if (strcasecmp (value, _T("no")) == 0 || strcasecmp (value, _T("n")) == 0
1973 || strcasecmp (value, _T("false")) == 0 || strcasecmp (value, _T("f")) == 0
1974 || (numbercheck && strcasecmp (value, _T("0")) == 0))
1975 *location = 0;
1976 else {
1977 cfgfile_warning(_T("Option '%s' requires a value of either 'true' or 'false' (was '%s').\n"), option, value);
1978 return -1;
1979 }
1980 return 1;
1981 }
1982
cfgfile_yesno(const TCHAR * option,const TCHAR * value,const TCHAR * name,int * location)1983 static int cfgfile_yesno (const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location)
1984 {
1985 return cfgfile_yesno (option, value, name, location, true);
1986 }
1987
cfgfile_yesno(const TCHAR * option,const TCHAR * value,const TCHAR * name,bool * location,bool numbercheck)1988 static int cfgfile_yesno (const TCHAR *option, const TCHAR *value, const TCHAR *name, bool *location, bool numbercheck)
1989 {
1990 int val;
1991 int ret = cfgfile_yesno (option, value, name, &val, numbercheck);
1992 if (ret == 0)
1993 return 0;
1994 if (ret < 0)
1995 *location = false;
1996 else
1997 *location = val != 0;
1998 return 1;
1999 }
2000
cfgfile_yesno(const TCHAR * option,const TCHAR * value,const TCHAR * name,bool * location)2001 int cfgfile_yesno (const TCHAR *option, const TCHAR *value, const TCHAR *name, bool *location)
2002 {
2003 return cfgfile_yesno (option, value, name, location, true);
2004 }
2005
cfgfile_doubleval(const TCHAR * option,const TCHAR * value,const TCHAR * name,double * location)2006 static int cfgfile_doubleval (const TCHAR *option, const TCHAR *value, const TCHAR *name, double *location)
2007 {
2008 TCHAR *endptr;
2009 if (name != NULL && _tcscmp (option, name) != 0)
2010 return 0;
2011 *location = _tcstod (value, &endptr);
2012 return 1;
2013 }
2014
cfgfile_floatval(const TCHAR * option,const TCHAR * value,const TCHAR * name,const TCHAR * nameext,float * location)2015 static int cfgfile_floatval (const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, float *location)
2016 {
2017 TCHAR *endptr;
2018 if (name == NULL)
2019 return 0;
2020 if (nameext) {
2021 TCHAR tmp[MAX_DPATH];
2022 _tcscpy (tmp, name);
2023 _tcscat (tmp, nameext);
2024 if (_tcscmp (tmp, option) != 0)
2025 return 0;
2026 } else {
2027 if (_tcscmp (option, name) != 0)
2028 return 0;
2029 }
2030 *location = (float)_tcstod (value, &endptr);
2031 return 1;
2032 }
2033
cfgfile_floatval(const TCHAR * option,const TCHAR * value,const TCHAR * name,float * location)2034 static int cfgfile_floatval (const TCHAR *option, const TCHAR *value, const TCHAR *name, float *location)
2035 {
2036 return cfgfile_floatval (option, value, name, NULL, location);
2037 }
2038
cfgfile_intval(const TCHAR * option,const TCHAR * value,const TCHAR * name,const TCHAR * nameext,unsigned int * location,int scale)2039 static int cfgfile_intval (const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, unsigned int *location, int scale)
2040 {
2041 int base = 10;
2042 TCHAR *endptr;
2043 TCHAR tmp[MAX_DPATH];
2044
2045 if (name == NULL)
2046 return 0;
2047 if (nameext) {
2048 _tcscpy (tmp, name);
2049 _tcscat (tmp, nameext);
2050 if (_tcscmp (tmp, option) != 0)
2051 return 0;
2052 } else {
2053 if (_tcscmp (option, name) != 0)
2054 return 0;
2055 }
2056 /* I guess octal isn't popular enough to worry about here... */
2057 if (value[0] == '0' && _totupper (value[1]) == 'X')
2058 value += 2, base = 16;
2059 *location = _tcstol (value, &endptr, base) * scale;
2060
2061 if (*endptr != '\0' || *value == '\0') {
2062 if (strcasecmp (value, _T("false")) == 0 || strcasecmp (value, _T("no")) == 0) {
2063 *location = 0;
2064 return 1;
2065 }
2066 if (strcasecmp (value, _T("true")) == 0 || strcasecmp (value, _T("yes")) == 0) {
2067 *location = 1;
2068 return 1;
2069 }
2070 cfgfile_warning(_T("Option '%s' requires a numeric argument but got '%s'\n"), nameext ? tmp : option, value);
2071 return -1;
2072 }
2073 return 1;
2074 }
cfgfile_intval(const TCHAR * option,const TCHAR * value,const TCHAR * name,unsigned int * location,int scale)2075 static int cfgfile_intval (const TCHAR *option, const TCHAR *value, const TCHAR *name, unsigned int *location, int scale)
2076 {
2077 return cfgfile_intval (option, value, name, NULL, location, scale);
2078 }
cfgfile_intval(const TCHAR * option,const TCHAR * value,const TCHAR * name,int * location,int scale)2079 int cfgfile_intval (const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location, int scale)
2080 {
2081 unsigned int v = 0;
2082 int r = cfgfile_intval (option, value, name, NULL, &v, scale);
2083 if (!r)
2084 return 0;
2085 *location = (int)v;
2086 return r;
2087 }
cfgfile_intval(const TCHAR * option,const TCHAR * value,const TCHAR * name,const TCHAR * nameext,int * location,int scale)2088 static int cfgfile_intval (const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, int *location, int scale)
2089 {
2090 unsigned int v = 0;
2091 int r = cfgfile_intval (option, value, name, nameext, &v, scale);
2092 if (!r)
2093 return 0;
2094 *location = (int)v;
2095 return r;
2096 }
2097
cfgfile_strval(const TCHAR * option,const TCHAR * value,const TCHAR * name,const TCHAR * nameext,int * location,const TCHAR * table[],int more)2098 static int cfgfile_strval (const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, int *location, const TCHAR *table[], int more)
2099 {
2100 int val;
2101 TCHAR tmp[MAX_DPATH];
2102 if (name == NULL)
2103 return 0;
2104 if (nameext) {
2105 _tcscpy (tmp, name);
2106 _tcscat (tmp, nameext);
2107 if (_tcscmp (tmp, option) != 0)
2108 return 0;
2109 } else {
2110 if (_tcscmp (option, name) != 0)
2111 return 0;
2112 }
2113 val = match_string (table, value);
2114 if (val == -1) {
2115 if (more)
2116 return 0;
2117 if (!strcasecmp (value, _T("yes")) || !strcasecmp (value, _T("true"))) {
2118 val = 1;
2119 } else if (!strcasecmp (value, _T("no")) || !strcasecmp (value, _T("false"))) {
2120 val = 0;
2121 } else {
2122 cfgfile_warning(_T("Unknown value ('%s') for option '%s'.\n"), value, nameext ? tmp : option);
2123 return -1;
2124 }
2125 }
2126 *location = val;
2127 return 1;
2128 }
cfgfile_strval(const TCHAR * option,const TCHAR * value,const TCHAR * name,int * location,const TCHAR * table[],int more)2129 int cfgfile_strval (const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location, const TCHAR *table[], int more)
2130 {
2131 return cfgfile_strval (option, value, name, NULL, location, table, more);
2132 }
2133
cfgfile_strboolval(const TCHAR * option,const TCHAR * value,const TCHAR * name,bool * location,const TCHAR * table[],int more)2134 static int cfgfile_strboolval (const TCHAR *option, const TCHAR *value, const TCHAR *name, bool *location, const TCHAR *table[], int more)
2135 {
2136 int locationint;
2137 if (!cfgfile_strval (option, value, name, &locationint, table, more))
2138 return 0;
2139 *location = locationint != 0;
2140 return 1;
2141 }
2142
cfgfile_string(const TCHAR * option,const TCHAR * value,const TCHAR * name,TCHAR * location,int maxsz)2143 int cfgfile_string (const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz)
2144 {
2145 if (_tcscmp (option, name) != 0)
2146 return 0;
2147 _tcsncpy (location, value, maxsz - 1);
2148 location[maxsz - 1] = '\0';
2149 return 1;
2150 }
2151
cfgfile_string(const TCHAR * option,const TCHAR * value,const TCHAR * name,const TCHAR * nameext,TCHAR * location,int maxsz)2152 static int cfgfile_string (const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, TCHAR *location, int maxsz)
2153 {
2154 if (nameext) {
2155 TCHAR tmp[MAX_DPATH];
2156 _tcscpy (tmp, name);
2157 _tcscat (tmp, nameext);
2158 if (_tcscmp (tmp, option) != 0)
2159 return 0;
2160 } else {
2161 if (_tcscmp (option, name) != 0)
2162 return 0;
2163 }
2164 _tcsncpy (location, value, maxsz - 1);
2165 location[maxsz - 1] = '\0';
2166 return 1;
2167 }
2168
2169
cfgfile_path(const TCHAR * option,const TCHAR * value,const TCHAR * name,TCHAR * location,int maxsz,struct multipath * mp)2170 static int cfgfile_path (const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz, struct multipath *mp)
2171 {
2172 if (!cfgfile_string (option, value, name, location, maxsz))
2173 return 0;
2174 TCHAR *s = target_expand_environment (location);
2175 _tcsncpy (location, s, maxsz - 1);
2176 location[maxsz - 1] = 0;
2177 if (mp) {
2178 for (int i = 0; i < MAX_PATHS; i++) {
2179 if (mp->path[i][0] && _tcscmp (mp->path[i], _T(".\\")) != 0 && _tcscmp (mp->path[i], _T("./")) != 0 && (location[0] != '/' && location[0] != '\\' && !_tcschr(location, ':'))) {
2180 TCHAR np[MAX_DPATH];
2181 _tcscpy (np, mp->path[i]);
2182 fixtrailing (np);
2183 _tcscat (np, s);
2184 fullpath (np, sizeof np / sizeof (TCHAR));
2185 if (zfile_exists (np)) {
2186 _tcsncpy (location, np, maxsz - 1);
2187 location[maxsz - 1] = 0;
2188 break;
2189 }
2190 }
2191 }
2192 }
2193 xfree (s);
2194 return 1;
2195 }
2196
cfgfile_path(const TCHAR * option,const TCHAR * value,const TCHAR * name,TCHAR * location,int maxsz)2197 static int cfgfile_path (const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz)
2198 {
2199 return cfgfile_path (option, value, name, location, maxsz, NULL);
2200 }
2201
cfgfile_multipath(const TCHAR * option,const TCHAR * value,const TCHAR * name,struct multipath * mp)2202 static int cfgfile_multipath (const TCHAR *option, const TCHAR *value, const TCHAR *name, struct multipath *mp)
2203 {
2204 TCHAR tmploc[MAX_DPATH];
2205 if (!cfgfile_string (option, value, name, tmploc, 256))
2206 return 0;
2207 for (int i = 0; i < MAX_PATHS; i++) {
2208 if (mp->path[i][0] == 0 || (i == 0 && (!_tcscmp (mp->path[i], _T(".\\")) || !_tcscmp (mp->path[i], _T("./"))))) {
2209 TCHAR *s = target_expand_environment (tmploc);
2210 _tcsncpy (mp->path[i], s, 256 - 1);
2211 mp->path[i][256 - 1] = 0;
2212 fixtrailing (mp->path[i]);
2213 xfree (s);
2214 return 1;
2215 }
2216 }
2217 return 1;
2218 }
2219
cfgfile_rom(const TCHAR * option,const TCHAR * value,const TCHAR * name,TCHAR * location,int maxsz)2220 static int cfgfile_rom (const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz)
2221 {
2222 TCHAR id[MAX_DPATH];
2223 if (!cfgfile_string (option, value, name, id, sizeof id / sizeof (TCHAR)))
2224 return 0;
2225 TCHAR *p = _tcschr (id, ',');
2226 if (p) {
2227 TCHAR *endptr, tmp;
2228 *p = 0;
2229 tmp = id[4];
2230 id[4] = 0;
2231 uae_u32 crc32 = _tcstol (id, &endptr, 16) << 16;
2232 id[4] = tmp;
2233 crc32 |= _tcstol (id + 4, &endptr, 16);
2234 struct romdata *rd = getromdatabycrc (crc32, true);
2235 if (rd) {
2236 struct romdata *rd2 = getromdatabyid (rd->id);
2237 if (rd->group == 0 && rd2 == rd) {
2238 if (zfile_exists (location))
2239 return 1;
2240 }
2241 if (rd->group && rd2)
2242 rd = rd2;
2243 struct romlist *rl = getromlistbyromdata (rd);
2244 if (rl) {
2245 write_log (_T("%s: %s -> %s\n"), name, location, rl->path);
2246 _tcsncpy (location, rl->path, maxsz);
2247 }
2248 }
2249 }
2250 return 1;
2251 }
2252
getintval(TCHAR ** p,int * result,int delim)2253 static int getintval (TCHAR **p, int *result, int delim)
2254 {
2255 TCHAR *value = *p;
2256 int base = 10;
2257 TCHAR *endptr;
2258 TCHAR *p2 = _tcschr (*p, delim);
2259
2260 if (p2 == 0)
2261 return 0;
2262
2263 *p2++ = '\0';
2264
2265 if (value[0] == '0' && _totupper (value[1]) == 'X')
2266 value += 2, base = 16;
2267 *result = _tcstol (value, &endptr, base);
2268 *p = p2;
2269
2270 if (*endptr != '\0' || *value == '\0')
2271 return 0;
2272
2273 return 1;
2274 }
2275
getintval2(TCHAR ** p,int * result,int delim,bool last)2276 static int getintval2 (TCHAR **p, int *result, int delim, bool last)
2277 {
2278 TCHAR *value = *p;
2279 int base = 10;
2280 TCHAR *endptr;
2281 TCHAR *p2;
2282
2283 p2 = _tcschr (*p, delim);
2284 if (p2 == 0) {
2285 if (last) {
2286 if (delim != '.')
2287 p2 = _tcschr (*p, ',');
2288 if (p2 == 0) {
2289 p2 = *p;
2290 while(*p2)
2291 p2++;
2292 if (p2 == *p)
2293 return 0;
2294 }
2295 } else {
2296 return 0;
2297 }
2298 }
2299 if (!_istdigit(**p) && **p != '-' && **p != '+')
2300 return 0;
2301
2302 if (*p2 != 0)
2303 *p2++ = '\0';
2304
2305 if (value[0] == '0' && _totupper (value[1]) == 'X')
2306 value += 2, base = 16;
2307 *result = _tcstol (value, &endptr, base);
2308 *p = p2;
2309
2310 if (*endptr != '\0' || *value == '\0') {
2311 *p = 0;
2312 return 0;
2313 }
2314
2315 return 1;
2316 }
2317
cfgfile_option_select(TCHAR * s,const TCHAR * option,const TCHAR * select)2318 static int cfgfile_option_select(TCHAR *s, const TCHAR *option, const TCHAR *select)
2319 {
2320 TCHAR buf[MAX_DPATH];
2321 if (!s)
2322 return -1;
2323 _tcscpy(buf, s);
2324 _tcscat(buf, _T(","));
2325 TCHAR *p = buf;
2326 for (;;) {
2327 TCHAR *tmpp = _tcschr (p, ',');
2328 if (tmpp == NULL)
2329 return -1;
2330 *tmpp++ = 0;
2331 TCHAR *tmpp2 = _tcschr(p, '=');
2332 if (!tmpp2)
2333 return -1;
2334 *tmpp2++ = 0;
2335 if (!strcasecmp(p, option)) {
2336 int idx = 0;
2337 while (select[0]) {
2338 if (!strcasecmp(select, tmpp2))
2339 return idx;
2340 idx++;
2341 select += _tcslen(select) + 1;
2342 }
2343 }
2344 p = tmpp;
2345 }
2346 }
2347
cfgfile_option_bool(TCHAR * s,const TCHAR * option)2348 static int cfgfile_option_bool(TCHAR *s, const TCHAR *option)
2349 {
2350 TCHAR buf[MAX_DPATH];
2351 if (!s)
2352 return -1;
2353 _tcscpy(buf, s);
2354 _tcscat(buf, _T(","));
2355 TCHAR *p = buf;
2356 for (;;) {
2357 TCHAR *tmpp = _tcschr (p, ',');
2358 if (tmpp == NULL)
2359 return -1;
2360 *tmpp++ = 0;
2361 TCHAR *tmpp2 = _tcschr(p, '=');
2362 if (tmpp2)
2363 *tmpp2++ = 0;
2364 if (!strcasecmp(p, option)) {
2365 if (!tmpp2)
2366 return 0;
2367 TCHAR *tmpp3 = _tcschr (tmpp2, ',');
2368 if (tmpp3)
2369 *tmpp3 = 0;
2370 if (tmpp2 && !strcasecmp(tmpp2, _T("true")))
2371 return 1;
2372 if (tmpp2 && !strcasecmp(tmpp2, _T("false")))
2373 return 0;
2374 return 1;
2375 }
2376 p = tmpp;
2377 }
2378 }
set_chipset_mask(struct uae_prefs * p,int val)2379 static void set_chipset_mask (struct uae_prefs *p, int val)
2380 {
2381 p->chipset_mask = (val == 0 ? 0
2382 : val == 1 ? CSMASK_ECS_AGNUS
2383 : val == 2 ? CSMASK_ECS_DENISE
2384 : val == 3 ? CSMASK_ECS_DENISE | CSMASK_ECS_AGNUS
2385 : CSMASK_AGA | CSMASK_ECS_DENISE | CSMASK_ECS_AGNUS);
2386 }
2387
cfgfile_parse_host(struct uae_prefs * p,TCHAR * option,TCHAR * value)2388 static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
2389 {
2390 int i, v;
2391 bool vb;
2392 TCHAR *section = 0;
2393 TCHAR *tmpp;
2394 TCHAR tmpbuf[CONFIG_BLEN];
2395
2396 if (_tcsncmp (option, _T("input."), 6) == 0) {
2397 read_inputdevice_config (p, option, value);
2398 return 1;
2399 }
2400
2401 for (tmpp = option; *tmpp != '\0'; tmpp++)
2402 if (_istupper (*tmpp))
2403 *tmpp = _totlower (*tmpp);
2404 tmpp = _tcschr (option, '.');
2405 if (tmpp) {
2406 section = option;
2407 option = tmpp + 1;
2408 *tmpp = '\0';
2409 if (_tcscmp (section, TARGET_NAME) == 0) {
2410 /* We special case the various path options here. */
2411 if (cfgfile_multipath (option, value, _T("rom_path"), &p->path_rom)
2412 || cfgfile_multipath (option, value, _T("floppy_path"), &p->path_floppy)
2413 || cfgfile_multipath (option, value, _T("cd_path"), &p->path_cd)
2414 || cfgfile_multipath (option, value, _T("hardfile_path"), &p->path_hardfile))
2415 return 1;
2416 return target_parse_option (p, option, value);
2417 }
2418 return 0;
2419 }
2420
2421 for (i = 0; i < MAX_SPARE_DRIVES; i++) {
2422 _stprintf (tmpbuf, _T("diskimage%d"), i);
2423 if (cfgfile_path (option, value, tmpbuf, p->dfxlist[i], sizeof p->dfxlist[i] / sizeof (TCHAR), &p->path_floppy)) {
2424 #if 0
2425 if (i < 4 && !p->df[i][0])
2426 _tcscpy (p->df[i], p->dfxlist[i]);
2427 #endif
2428 return 1;
2429 }
2430 }
2431
2432 for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
2433 TCHAR tmp[20];
2434 _stprintf (tmp, _T("cdimage%d"), i);
2435 if (!_tcsicmp (option, tmp)) {
2436 if (!_tcsicmp (value, _T("autodetect"))) {
2437 p->cdslots[i].type = SCSI_UNIT_DEFAULT;
2438 p->cdslots[i].inuse = true;
2439 p->cdslots[i].name[0] = 0;
2440 } else {
2441 p->cdslots[i].delayed = false;
2442 TCHAR *next = _tcsrchr (value, ',');
2443 int type = SCSI_UNIT_DEFAULT;
2444 int mode = 0;
2445 int unitnum = 0;
2446 for (;;) {
2447 if (!next)
2448 break;
2449 *next++ = 0;
2450 TCHAR *next2 = _tcschr (next, ':');
2451 if (next2)
2452 *next2++ = 0;
2453 if (!_tcsicmp (next, _T("delay"))) {
2454 p->cdslots[i].delayed = true;
2455 next = next2;
2456 if (!next)
2457 break;
2458 next2 = _tcschr (next, ':');
2459 if (next2)
2460 *next2++ = 0;
2461 }
2462 type = match_string (cdmodes, next);
2463 if (type < 0)
2464 type = SCSI_UNIT_DEFAULT;
2465 else
2466 type--;
2467 next = next2;
2468 if (!next)
2469 break;
2470 next2 = _tcschr (next, ':');
2471 if (next2)
2472 *next2++ = 0;
2473 mode = match_string (cdconmodes, next);
2474 if (mode < 0)
2475 mode = 0;
2476 next = next2;
2477 if (!next)
2478 break;
2479 next2 = _tcschr (next, ':');
2480 if (next2)
2481 *next2++ = 0;
2482 cfgfile_intval (option, next, tmp, &unitnum, 1);
2483 }
2484 if (_tcslen (value) > 0) {
2485 TCHAR *s = cfgfile_get_multipath (&p->path_cd, NULL, value, false);
2486 _tcsncpy (p->cdslots[i].name, s, sizeof p->cdslots[i].name / sizeof (TCHAR));
2487 xfree (s);
2488 }
2489 p->cdslots[i].name[sizeof p->cdslots[i].name - 1] = 0;
2490 p->cdslots[i].inuse = true;
2491 p->cdslots[i].type = type;
2492 }
2493 // disable all following units
2494 i++;
2495 while (i < MAX_TOTAL_SCSI_DEVICES) {
2496 p->cdslots[i].type = SCSI_UNIT_DISABLED;
2497 i++;
2498 }
2499 return 1;
2500 }
2501 }
2502
2503 if (!_tcsicmp (option, _T("lua"))) {
2504 for (i = 0; i < MAX_LUA_STATES; i++) {
2505 if (!p->luafiles[i][0]) {
2506 _tcscpy (p->luafiles[i], value);
2507 break;
2508 }
2509 }
2510 return 1;
2511 }
2512
2513 if (cfgfile_strval (option, value, _T("gfx_autoresolution_min_vertical"), &p->gfx_autoresolution_minv, vertmode, 0)) {
2514 p->gfx_autoresolution_minv--;
2515 return 1;
2516 }
2517 if (cfgfile_strval (option, value, _T("gfx_autoresolution_min_horizontal"), &p->gfx_autoresolution_minh, horizmode, 0)) {
2518 p->gfx_autoresolution_minh--;
2519 return 1;
2520 }
2521 if (!_tcsicmp (option, _T("gfx_autoresolution"))) {
2522 p->gfx_autoresolution = 0;
2523 cfgfile_intval (option, value, _T("gfx_autoresolution"), &p->gfx_autoresolution, 1);
2524 if (!p->gfx_autoresolution) {
2525 v = cfgfile_yesno (option, value, _T("gfx_autoresolution"), &vb);
2526 if (v > 0)
2527 p->gfx_autoresolution = vb ? 10 : 0;
2528 }
2529 return 1;
2530 }
2531
2532 if (cfgfile_intval (option, value, _T("sound_frequency"), &p->sound_freq, 1)
2533 || cfgfile_intval (option, value, _T("sound_max_buff"), &p->sound_maxbsiz, 1)
2534 || cfgfile_intval (option, value, _T("state_replay_rate"), &p->statecapturerate, 1)
2535 || cfgfile_intval (option, value, _T("state_replay_buffers"), &p->statecapturebuffersize, 1)
2536 || cfgfile_yesno (option, value, _T("state_replay_autoplay"), &p->inprec_autoplay)
2537 || cfgfile_intval (option, value, _T("sound_frequency"), &p->sound_freq, 1)
2538 || cfgfile_intval (option, value, _T("sound_volume"), &p->sound_volume_master, 1)
2539 || cfgfile_intval (option, value, _T("sound_volume_paula"), &p->sound_volume_paula, 1)
2540 || cfgfile_intval (option, value, _T("sound_volume_cd"), &p->sound_volume_cd, 1)
2541 || cfgfile_intval (option, value, _T("sound_volume_ahi"), &p->sound_volume_board, 1)
2542 || cfgfile_intval (option, value, _T("sound_stereo_separation"), &p->sound_stereo_separation, 1)
2543 || cfgfile_intval (option, value, _T("sound_stereo_mixing_delay"), &p->sound_mixed_stereo_delay, 1)
2544 || cfgfile_intval (option, value, _T("sampler_frequency"), &p->sampler_freq, 1)
2545 || cfgfile_intval (option, value, _T("sampler_buffer"), &p->sampler_buffer, 1)
2546 || cfgfile_intval (option, value, _T("warp_limit"), &p->turbo_emulation_limit, 1)
2547
2548 || cfgfile_intval (option, value, _T("gfx_framerate"), &p->gfx_framerate, 1)
2549 || cfgfile_intval (option, value, _T("gfx_top_windowed"), &p->gfx_size_win.x, 1)
2550 || cfgfile_intval (option, value, _T("gfx_left_windowed"), &p->gfx_size_win.y, 1)
2551 || cfgfile_intval (option, value, _T("gfx_refreshrate"), &p->gfx_apmode[APMODE_NATIVE].gfx_refreshrate, 1)
2552 || cfgfile_intval (option, value, _T("gfx_refreshrate_rtg"), &p->gfx_apmode[APMODE_RTG].gfx_refreshrate, 1)
2553 || cfgfile_intval (option, value, _T("gfx_autoresolution_delay"), &p->gfx_autoresolution_delay, 1)
2554 || cfgfile_intval (option, value, _T("gfx_backbuffers"), &p->gfx_apmode[APMODE_NATIVE].gfx_backbuffers, 1)
2555 || cfgfile_intval (option, value, _T("gfx_backbuffers_rtg"), &p->gfx_apmode[APMODE_RTG].gfx_backbuffers, 1)
2556 || cfgfile_yesno (option, value, _T("gfx_interlace"), &p->gfx_apmode[APMODE_NATIVE].gfx_interlaced)
2557 || cfgfile_yesno (option, value, _T("gfx_interlace_rtg"), &p->gfx_apmode[APMODE_RTG].gfx_interlaced)
2558
2559 || cfgfile_intval (option, value, _T("gfx_center_horizontal_position"), &p->gfx_xcenter_pos, 1)
2560 || cfgfile_intval (option, value, _T("gfx_center_vertical_position"), &p->gfx_ycenter_pos, 1)
2561 || cfgfile_intval (option, value, _T("gfx_center_horizontal_size"), &p->gfx_xcenter_size, 1)
2562 || cfgfile_intval (option, value, _T("gfx_center_vertical_size"), &p->gfx_ycenter_size, 1)
2563
2564 || cfgfile_intval (option, value, _T("filesys_max_size"), &p->filesys_limit, 1)
2565 || cfgfile_intval (option, value, _T("filesys_max_name_length"), &p->filesys_max_name, 1)
2566 || cfgfile_intval (option, value, _T("filesys_max_file_size"), &p->filesys_max_file_size, 1)
2567 || cfgfile_yesno (option, value, _T("filesys_inject_icons"), &p->filesys_inject_icons)
2568 || cfgfile_string (option, value, _T("filesys_inject_icons_drawer"), p->filesys_inject_icons_drawer, sizeof p->filesys_inject_icons_drawer / sizeof (TCHAR))
2569 || cfgfile_string (option, value, _T("filesys_inject_icons_project"), p->filesys_inject_icons_project, sizeof p->filesys_inject_icons_project / sizeof (TCHAR))
2570 || cfgfile_string (option, value, _T("filesys_inject_icons_tool"), p->filesys_inject_icons_tool, sizeof p->filesys_inject_icons_tool / sizeof (TCHAR))
2571
2572 || cfgfile_intval (option, value, _T("gfx_luminance"), &p->gfx_luminance, 1)
2573 || cfgfile_intval (option, value, _T("gfx_contrast"), &p->gfx_contrast, 1)
2574 || cfgfile_intval (option, value, _T("gfx_gamma"), &p->gfx_gamma, 1)
2575 || cfgfile_intval (option, value, _T("gfx_gamma_r"), &p->gfx_gamma_ch[0], 1)
2576 || cfgfile_intval (option, value, _T("gfx_gamma_g"), &p->gfx_gamma_ch[1], 1)
2577 || cfgfile_intval (option, value, _T("gfx_gamma_b"), &p->gfx_gamma_ch[2], 1)
2578 || cfgfile_floatval (option, value, _T("rtg_vert_zoom_multf"), &p->rtg_vert_zoom_mult)
2579 || cfgfile_floatval (option, value, _T("rtg_horiz_zoom_multf"), &p->rtg_horiz_zoom_mult)
2580 || cfgfile_intval (option, value, _T("gfx_horizontal_tweak"), &p->gfx_extrawidth, 1)
2581
2582 || cfgfile_intval (option, value, _T("floppy0sound"), &p->floppyslots[0].dfxclick, 1)
2583 || cfgfile_intval (option, value, _T("floppy1sound"), &p->floppyslots[1].dfxclick, 1)
2584 || cfgfile_intval (option, value, _T("floppy2sound"), &p->floppyslots[2].dfxclick, 1)
2585 || cfgfile_intval (option, value, _T("floppy3sound"), &p->floppyslots[3].dfxclick, 1)
2586 || cfgfile_intval (option, value, _T("floppy0soundvolume_disk"), &p->dfxclickvolume_disk[0], 1)
2587 || cfgfile_intval (option, value, _T("floppy1soundvolume_disk"), &p->dfxclickvolume_disk[1], 1)
2588 || cfgfile_intval (option, value, _T("floppy2soundvolume_disk"), &p->dfxclickvolume_disk[2], 1)
2589 || cfgfile_intval (option, value, _T("floppy3soundvolume_disk"), &p->dfxclickvolume_disk[3], 1)
2590 || cfgfile_intval (option, value, _T("floppy0soundvolume_empty"), &p->dfxclickvolume_empty[0], 1)
2591 || cfgfile_intval (option, value, _T("floppy1soundvolume_empty"), &p->dfxclickvolume_empty[1], 1)
2592 || cfgfile_intval (option, value, _T("floppy2soundvolume_empty"), &p->dfxclickvolume_empty[2], 1)
2593 || cfgfile_intval (option, value, _T("floppy3soundvolume_empty"), &p->dfxclickvolume_empty[3], 1)
2594 || cfgfile_intval (option, value, _T("floppy_channel_mask"), &p->dfxclickchannelmask, 1))
2595 return 1;
2596
2597 if (cfgfile_path (option, value, _T("floppy0soundext"), p->floppyslots[0].dfxclickexternal, sizeof p->floppyslots[0].dfxclickexternal / sizeof (TCHAR))
2598 || cfgfile_path (option, value, _T("floppy1soundext"), p->floppyslots[1].dfxclickexternal, sizeof p->floppyslots[1].dfxclickexternal / sizeof (TCHAR))
2599 || cfgfile_path (option, value, _T("floppy2soundext"), p->floppyslots[2].dfxclickexternal, sizeof p->floppyslots[2].dfxclickexternal / sizeof (TCHAR))
2600 || cfgfile_path (option, value, _T("floppy3soundext"), p->floppyslots[3].dfxclickexternal, sizeof p->floppyslots[3].dfxclickexternal / sizeof (TCHAR))
2601 || cfgfile_string (option, value, _T("config_window_title"), p->config_window_title, sizeof p->config_window_title / sizeof (TCHAR))
2602 || cfgfile_string (option, value, _T("config_info"), p->info, sizeof p->info / sizeof (TCHAR))
2603 || cfgfile_string (option, value, _T("config_description"), p->description, sizeof p->description / sizeof (TCHAR)))
2604 return 1;
2605
2606 if (cfgfile_yesno(option, value, _T("use_debugger"), &p->start_debugger)
2607 || cfgfile_yesno(option, value, _T("floppy0wp"), &p->floppyslots[0].forcedwriteprotect)
2608 || cfgfile_yesno(option, value, _T("floppy1wp"), &p->floppyslots[1].forcedwriteprotect)
2609 || cfgfile_yesno(option, value, _T("floppy2wp"), &p->floppyslots[2].forcedwriteprotect)
2610 || cfgfile_yesno(option, value, _T("floppy3wp"), &p->floppyslots[3].forcedwriteprotect)
2611 || cfgfile_yesno(option, value, _T("sampler_stereo"), &p->sampler_stereo)
2612 || cfgfile_yesno(option, value, _T("sound_auto"), &p->sound_auto)
2613 || cfgfile_yesno(option, value, _T("sound_cdaudio"), &p->sound_cdaudio)
2614 || cfgfile_yesno(option, value, _T("sound_stereo_swap_paula"), &p->sound_stereo_swap_paula)
2615 || cfgfile_yesno(option, value, _T("sound_stereo_swap_ahi"), &p->sound_stereo_swap_ahi)
2616 || cfgfile_yesno(option, value, _T("log_illegal_mem"), &p->illegal_mem)
2617 || cfgfile_yesno(option, value, _T("filesys_no_fsdb"), &p->filesys_no_uaefsdb)
2618 || cfgfile_yesno(option, value, _T("gfx_blacker_than_black"), &p->gfx_blackerthanblack)
2619 || cfgfile_yesno(option, value, _T("gfx_black_frame_insertion"), &p->lightboost_strobo)
2620 || cfgfile_yesno(option, value, _T("gfx_flickerfixer"), &p->gfx_scandoubler)
2621 || cfgfile_yesno(option, value, _T("gfx_autoresolution_vga"), &p->gfx_autoresolution_vga)
2622 || cfgfile_yesno(option, value, _T("show_refresh_indicator"), &p->refresh_indicator)
2623 || cfgfile_yesno(option, value, _T("magic_mouse"), &p->input_magic_mouse)
2624 || cfgfile_yesno(option, value, _T("warp"), &p->turbo_emulation)
2625 || cfgfile_yesno(option, value, _T("headless"), &p->headless)
2626 || cfgfile_yesno(option, value, _T("clipboard_sharing"), &p->clipboard_sharing)
2627 || cfgfile_yesno(option, value, _T("native_code"), &p->native_code)
2628 || cfgfile_yesno(option, value, _T("tablet_library"), &p->tablet_library)
2629 || cfgfile_yesno(option, value, _T("bsdsocket_emu"), &p->socket_emu))
2630 return 1;
2631
2632 if (cfgfile_strval (option, value, _T("sound_output"), &p->produce_sound, soundmode1, 1)
2633 || cfgfile_strval (option, value, _T("sound_output"), &p->produce_sound, soundmode2, 0)
2634 || cfgfile_strval (option, value, _T("sound_interpol"), &p->sound_interpol, interpolmode, 0)
2635 || cfgfile_strval (option, value, _T("sound_filter"), &p->sound_filter, soundfiltermode1, 0)
2636 || cfgfile_strval (option, value, _T("sound_filter_type"), &p->sound_filter_type, soundfiltermode2, 0)
2637 || cfgfile_strboolval (option, value, _T("use_gui"), &p->start_gui, guimode1, 1)
2638 || cfgfile_strboolval (option, value, _T("use_gui"), &p->start_gui, guimode2, 1)
2639 || cfgfile_strboolval (option, value, _T("use_gui"), &p->start_gui, guimode3, 0)
2640 || cfgfile_strval (option, value, _T("gfx_resolution"), &p->gfx_resolution, lorestype1, 0)
2641 || cfgfile_strval (option, value, _T("gfx_lores"), &p->gfx_resolution, lorestype2, 0)
2642 || cfgfile_strval (option, value, _T("gfx_lores_mode"), &p->gfx_lores_mode, loresmode, 0)
2643 || cfgfile_strval (option, value, _T("gfx_fullscreen_amiga"), &p->gfx_apmode[APMODE_NATIVE].gfx_fullscreen, fullmodes, 0)
2644 || cfgfile_strval (option, value, _T("gfx_fullscreen_picasso"), &p->gfx_apmode[APMODE_RTG].gfx_fullscreen, fullmodes, 0)
2645 || cfgfile_strval (option, value, _T("gfx_center_horizontal"), &p->gfx_xcenter, centermode1, 1)
2646 || cfgfile_strval (option, value, _T("gfx_center_vertical"), &p->gfx_ycenter, centermode1, 1)
2647 || cfgfile_strval (option, value, _T("gfx_center_horizontal"), &p->gfx_xcenter, centermode2, 0)
2648 || cfgfile_strval (option, value, _T("gfx_center_vertical"), &p->gfx_ycenter, centermode2, 0)
2649 || cfgfile_strval (option, value, _T("gfx_colour_mode"), &p->color_mode, colormode1, 1)
2650 || cfgfile_strval (option, value, _T("gfx_colour_mode"), &p->color_mode, colormode2, 0)
2651 || cfgfile_strval (option, value, _T("gfx_color_mode"), &p->color_mode, colormode1, 1)
2652 || cfgfile_strval (option, value, _T("gfx_color_mode"), &p->color_mode, colormode2, 0)
2653 || cfgfile_strval (option, value, _T("gfx_max_horizontal"), &p->gfx_max_horizontal, maxhoriz, 0)
2654 || cfgfile_strval (option, value, _T("gfx_max_vertical"), &p->gfx_max_vertical, maxvert, 0)
2655 || cfgfile_strval (option, value, _T("gfx_api"), &p->gfx_api, filterapi, 0)
2656 || cfgfile_strval (option, value, _T("magic_mousecursor"), &p->input_magic_mouse_cursor, magiccursors, 0)
2657 || cfgfile_strval (option, value, _T("absolute_mouse"), &p->input_tablet, abspointers, 0))
2658 return 1;
2659
2660 #ifdef GFXFILTER
2661 for (int j = 0; j < 2; j++) {
2662 struct gfx_filterdata *gf = &p->gf[j];
2663 const TCHAR *ext = j == 0 ? NULL : _T("_rtg");
2664 if (cfgfile_strval (option, value, _T("gfx_filter_autoscale"), ext, &gf->gfx_filter_autoscale, j == 0 ? autoscale : autoscale_rtg, 0)
2665 || cfgfile_strval (option, value, _T("gfx_filter_keep_aspect"), ext, &gf->gfx_filter_keep_aspect, aspects, 0)
2666 || cfgfile_strval (option, value, _T("gfx_filter_autoscale_limit"), ext, &gf->gfx_filter_integerscalelimit, autoscalelimit, 0))
2667 return 1;
2668
2669 if (cfgfile_floatval (option, value, _T("gfx_filter_vert_zoomf"), ext, &gf->gfx_filter_vert_zoom)
2670 || cfgfile_floatval (option, value, _T("gfx_filter_horiz_zoomf"), ext, &gf->gfx_filter_horiz_zoom)
2671 || cfgfile_floatval (option, value, _T("gfx_filter_vert_zoom_multf"), ext, &gf->gfx_filter_vert_zoom_mult)
2672 || cfgfile_floatval (option, value, _T("gfx_filter_horiz_zoom_multf"), ext, &gf->gfx_filter_horiz_zoom_mult)
2673 || cfgfile_floatval (option, value, _T("gfx_filter_vert_offsetf"), ext, &gf->gfx_filter_vert_offset)
2674 || cfgfile_floatval (option, value, _T("gfx_filter_horiz_offsetf"), ext, &gf->gfx_filter_horiz_offset)
2675 || cfgfile_intval (option, value, _T("gfx_filter_left_border"), ext, &gf->gfx_filter_left_border, 1)
2676 || cfgfile_intval (option, value, _T("gfx_filter_right_border"), ext, &gf->gfx_filter_right_border, 1)
2677 || cfgfile_intval (option, value, _T("gfx_filter_top_border"), ext, &gf->gfx_filter_top_border, 1)
2678 || cfgfile_intval (option, value, _T("gfx_filter_bottom_border"), ext, &gf->gfx_filter_bottom_border, 1)
2679 || cfgfile_intval (option, value, _T("gfx_filter_scanlines"), ext, &gf->gfx_filter_scanlines, 1)
2680 || cfgfile_intval (option, value, _T("gfx_filter_scanlinelevel"), ext, &gf->gfx_filter_scanlinelevel, 1)
2681 || cfgfile_intval (option, value, _T("gfx_filter_scanlineratio"), ext, &gf->gfx_filter_scanlineratio, 1)
2682 || cfgfile_intval (option, value, _T("gfx_filter_luminance"), ext, &gf->gfx_filter_luminance, 1)
2683 || cfgfile_intval (option, value, _T("gfx_filter_contrast"), ext, &gf->gfx_filter_contrast, 1)
2684 || cfgfile_intval (option, value, _T("gfx_filter_saturation"), ext, &gf->gfx_filter_saturation, 1)
2685 || cfgfile_intval (option, value, _T("gfx_filter_gamma"), ext, &gf->gfx_filter_gamma, 1)
2686 || cfgfile_intval (option, value, _T("gfx_filter_gamma_r"), ext, &gf->gfx_filter_gamma_ch[0], 1)
2687 || cfgfile_intval (option, value, _T("gfx_filter_gamma_g"), ext, &gf->gfx_filter_gamma_ch[1], 1)
2688 || cfgfile_intval (option, value, _T("gfx_filter_gamma_b"), ext, &gf->gfx_filter_gamma_ch[2], 1)
2689 || cfgfile_intval (option, value, _T("gfx_filter_blur"), ext, &gf->gfx_filter_blur, 1)
2690 || cfgfile_intval (option, value, _T("gfx_filter_noise"), ext, &gf->gfx_filter_noise, 1)
2691 || cfgfile_intval (option, value, _T("gfx_filter_bilinear"), ext, &gf->gfx_filter_bilinear, 1)
2692 || cfgfile_intval (option, value, _T("gfx_filter_keep_autoscale_aspect"), ext, &gf->gfx_filter_keep_autoscale_aspect, 1)
2693 || cfgfile_string (option, value, _T("gfx_filter_mask"), ext, gf->gfx_filtermask[2 * MAX_FILTERSHADERS], sizeof gf->gfx_filtermask[2 * MAX_FILTERSHADERS] / sizeof (TCHAR)))
2694 return 1;
2695 }
2696 #endif
2697
2698 if (cfgfile_intval (option, value, _T("floppy_volume"), &v, 1)) {
2699 for (int i = 0; i < 4; i++) {
2700 p->dfxclickvolume_disk[i] = v;
2701 p->dfxclickvolume_empty[i] = v;
2702 }
2703 return 1;
2704 }
2705
2706 if (_tcscmp (option, _T("gfx_width_windowed")) == 0) {
2707 if (!_tcscmp (value, _T("native"))) {
2708 p->gfx_size_win.width = 0;
2709 p->gfx_size_win.height = 0;
2710 } else {
2711 cfgfile_intval (option, value, _T("gfx_width_windowed"), &p->gfx_size_win.width, 1);
2712 }
2713 return 1;
2714 }
2715 if (_tcscmp (option, _T("gfx_height_windowed")) == 0) {
2716 if (!_tcscmp (value, _T("native"))) {
2717 p->gfx_size_win.width = 0;
2718 p->gfx_size_win.height = 0;
2719 } else {
2720 cfgfile_intval (option, value, _T("gfx_height_windowed"), &p->gfx_size_win.height, 1);
2721 }
2722 return 1;
2723 }
2724 if (_tcscmp (option, _T("gfx_width_fullscreen")) == 0) {
2725 if (!_tcscmp (value, _T("native"))) {
2726 p->gfx_size_fs.width = 0;
2727 p->gfx_size_fs.height = 0;
2728 p->gfx_size_fs.special = WH_NATIVE;
2729 } else {
2730 cfgfile_intval (option, value, _T("gfx_width_fullscreen"), &p->gfx_size_fs.width, 1);
2731 p->gfx_size_fs.special = 0;
2732 }
2733 return 1;
2734 }
2735 if (_tcscmp (option, _T("gfx_height_fullscreen")) == 0) {
2736 if (!_tcscmp (value, _T("native"))) {
2737 p->gfx_size_fs.width = 0;
2738 p->gfx_size_fs.height = 0;
2739 p->gfx_size_fs.special = WH_NATIVE;
2740 } else {
2741 cfgfile_intval (option, value, _T("gfx_height_fullscreen"), &p->gfx_size_fs.height, 1);
2742 p->gfx_size_fs.special = 0;
2743 }
2744 return 1;
2745 }
2746
2747 if (cfgfile_intval (option, value, _T("gfx_display"), &p->gfx_apmode[APMODE_NATIVE].gfx_display, 1)) {
2748 p->gfx_apmode[APMODE_RTG].gfx_display = p->gfx_apmode[APMODE_NATIVE].gfx_display;
2749 return 1;
2750 }
2751 if (cfgfile_intval (option, value, _T("gfx_display_rtg"), &p->gfx_apmode[APMODE_RTG].gfx_display, 1)) {
2752 return 1;
2753 }
2754 if (_tcscmp (option, _T("gfx_display_friendlyname")) == 0 || _tcscmp (option, _T("gfx_display_name")) == 0) {
2755 TCHAR tmp[MAX_DPATH];
2756 if (cfgfile_string (option, value, _T("gfx_display_friendlyname"), tmp, sizeof tmp / sizeof (TCHAR))) {
2757 int num = target_get_display (tmp);
2758 if (num >= 0)
2759 p->gfx_apmode[APMODE_RTG].gfx_display = p->gfx_apmode[APMODE_NATIVE].gfx_display = num;
2760 }
2761 if (cfgfile_string (option, value, _T("gfx_display_name"), tmp, sizeof tmp / sizeof (TCHAR))) {
2762 int num = target_get_display (tmp);
2763 if (num >= 0)
2764 p->gfx_apmode[APMODE_RTG].gfx_display = p->gfx_apmode[APMODE_NATIVE].gfx_display = num;
2765 }
2766 return 1;
2767 }
2768 if (_tcscmp (option, _T("gfx_display_friendlyname_rtg")) == 0 || _tcscmp (option, _T("gfx_display_name_rtg")) == 0) {
2769 TCHAR tmp[MAX_DPATH];
2770 if (cfgfile_string (option, value, _T("gfx_display_friendlyname_rtg"), tmp, sizeof tmp / sizeof (TCHAR))) {
2771 int num = target_get_display (tmp);
2772 if (num >= 0)
2773 p->gfx_apmode[APMODE_RTG].gfx_display = num;
2774 }
2775 if (cfgfile_string (option, value, _T("gfx_display_name_rtg"), tmp, sizeof tmp / sizeof (TCHAR))) {
2776 int num = target_get_display (tmp);
2777 if (num >= 0)
2778 p->gfx_apmode[APMODE_RTG].gfx_display = num;
2779 }
2780 return 1;
2781 }
2782
2783 if (_tcscmp (option, _T("gfx_linemode")) == 0) {
2784 int v;
2785 p->gfx_vresolution = VRES_DOUBLE;
2786 p->gfx_pscanlines = 0;
2787 p->gfx_iscanlines = 0;
2788 if (cfgfile_strval(option, value, _T("gfx_linemode"), &v, linemode, 0)) {
2789 p->gfx_vresolution = VRES_NONDOUBLE;
2790 if (v > 0) {
2791 p->gfx_iscanlines = (v - 1) / 4;
2792 p->gfx_pscanlines = (v - 1) % 4;
2793 p->gfx_vresolution = VRES_DOUBLE;
2794 }
2795 }
2796 return 1;
2797 }
2798 if (_tcscmp (option, _T("gfx_vsync")) == 0) {
2799 if (cfgfile_strval (option, value, _T("gfx_vsync"), &p->gfx_apmode[APMODE_NATIVE].gfx_vsync, vsyncmodes, 0) >= 0)
2800 return 1;
2801 return cfgfile_yesno (option, value, _T("gfx_vsync"), &p->gfx_apmode[APMODE_NATIVE].gfx_vsync);
2802 }
2803 if (_tcscmp (option, _T("gfx_vsync_picasso")) == 0) {
2804 if (cfgfile_strval (option, value, _T("gfx_vsync_picasso"), &p->gfx_apmode[APMODE_RTG].gfx_vsync, vsyncmodes, 0) >= 0)
2805 return 1;
2806 return cfgfile_yesno (option, value, _T("gfx_vsync_picasso"), &p->gfx_apmode[APMODE_RTG].gfx_vsync);
2807 }
2808 if (cfgfile_strval (option, value, _T("gfx_vsyncmode"), &p->gfx_apmode[APMODE_NATIVE].gfx_vsyncmode, vsyncmodes2, 0))
2809 return 1;
2810 if (cfgfile_strval (option, value, _T("gfx_vsyncmode_picasso"), &p->gfx_apmode[APMODE_RTG].gfx_vsyncmode, vsyncmodes2, 0))
2811 return 1;
2812
2813 if (cfgfile_yesno (option, value, _T("show_leds"), &vb)) {
2814 if (vb)
2815 p->leds_on_screen |= STATUSLINE_CHIPSET;
2816 else
2817 p->leds_on_screen &= ~STATUSLINE_CHIPSET;
2818 return 1;
2819 }
2820 if (cfgfile_yesno (option, value, _T("show_leds_rtg"), &vb)) {
2821 if (vb)
2822 p->leds_on_screen |= STATUSLINE_RTG;
2823 else
2824 p->leds_on_screen &= ~STATUSLINE_RTG;
2825 return 1;
2826 }
2827 if (_tcscmp (option, _T("show_leds_enabled")) == 0 || _tcscmp (option, _T("show_leds_enabled_rtg")) == 0) {
2828 TCHAR tmp[MAX_DPATH];
2829 int idx = _tcscmp (option, _T("show_leds_enabled")) == 0 ? 0 : 1;
2830 p->leds_on_screen_mask[idx] = 0;
2831 _tcscpy (tmp, value);
2832 _tcscat (tmp, _T(","));
2833 TCHAR *s = tmp;
2834 for (;;) {
2835 TCHAR *s2 = s;
2836 TCHAR *s3 = _tcschr (s, ':');
2837 s = _tcschr (s, ',');
2838 if (!s)
2839 break;
2840 if (s3 && s3 < s)
2841 s = s3;
2842 *s = 0;
2843 for (int i = 0; leds[i]; i++) {
2844 if (!_tcsicmp (s2, leds[i])) {
2845 p->leds_on_screen_mask[idx] |= 1 << i;
2846 }
2847 }
2848 s++;
2849 }
2850 return 1;
2851 }
2852
2853 if (!_tcscmp (option, _T("osd_position"))) {
2854 TCHAR *s = value;
2855 p->osd_pos.x = 0;
2856 p->osd_pos.y = 0;
2857 while (s) {
2858 if (!_tcschr (s, ':'))
2859 break;
2860 p->osd_pos.x = (int)(_tstof (s) * 10.0);
2861 s = _tcschr (s, ':');
2862 if (!s)
2863 break;
2864 if (s[-1] == '%')
2865 p->osd_pos.x += 30000;
2866 s++;
2867 p->osd_pos.y = (int)(_tstof (s) * 10.0);
2868 s += _tcslen (s);
2869 if (s[-1] == '%')
2870 p->osd_pos.y += 30000;
2871 break;
2872 }
2873 return 1;
2874 }
2875
2876 #ifdef GFXFILTER
2877 for (int j = 0; j < 2; j++) {
2878 struct gfx_filterdata *gf = &p->gf[j];
2879 if ((j == 0 && _tcscmp (option, _T("gfx_filter_overlay")) == 0) || (j == 1 && _tcscmp (option, _T("gfx_filter_overlay_rtg")) == 0)) {
2880 TCHAR *s = _tcschr (value, ',');
2881 gf->gfx_filteroverlay_overscan = 0;
2882 gf->gfx_filteroverlay_pos.x = 0;
2883 gf->gfx_filteroverlay_pos.y = 0;
2884 gf->gfx_filteroverlay_pos.width = 0;
2885 gf->gfx_filteroverlay_pos.height = 0;
2886 if (s)
2887 *s = 0;
2888 while (s) {
2889 *s++ = 0;
2890 gf->gfx_filteroverlay_overscan = _tstol (s);
2891 s = _tcschr (s, ':');
2892 if (!s)
2893 break;
2894 break;
2895 }
2896 _tcsncpy (gf->gfx_filteroverlay, value, sizeof gf->gfx_filteroverlay / sizeof (TCHAR) - 1);
2897 gf->gfx_filteroverlay[sizeof gf->gfx_filteroverlay / sizeof (TCHAR) - 1] = 0;
2898 return 1;
2899 }
2900
2901 if ((j == 0 && (_tcscmp (option, _T("gfx_filtermask_pre")) == 0 || _tcscmp (option, _T("gfx_filtermask_post")) == 0)) ||
2902 (j == 1 && (_tcscmp (option, _T("gfx_filtermask_pre_rtg")) == 0 || _tcscmp (option, _T("gfx_filtermask_post_rtg")) == 0))) {
2903 if (_tcscmp (option, _T("gfx_filtermask_pre")) == 0 || _tcscmp (option, _T("gfx_filtermask_pre_rtg")) == 0) {
2904 for (int i = 0; i < MAX_FILTERSHADERS; i++) {
2905 if (gf->gfx_filtermask[i][0] == 0) {
2906 _tcscpy (gf->gfx_filtermask[i], value);
2907 break;
2908 }
2909 }
2910 } else {
2911 for (int i = 0; i < MAX_FILTERSHADERS; i++) {
2912 if (gf->gfx_filtermask[i + MAX_FILTERSHADERS][0] == 0) {
2913 _tcscpy (gf->gfx_filtermask[i + MAX_FILTERSHADERS], value);
2914 break;
2915 }
2916 }
2917 }
2918 return 1;
2919 }
2920
2921 if ((j == 0 && (_tcscmp (option, _T("gfx_filter_pre")) == 0 || _tcscmp (option, _T("gfx_filter_post")) == 0)) ||
2922 (j == 1 && (_tcscmp (option, _T("gfx_filter_pre_rtg")) == 0 || _tcscmp (option, _T("gfx_filter_post_rtg")) == 0))) {
2923 TCHAR *s = _tcschr (value, ':');
2924 if (s) {
2925 *s++ = 0;
2926 if (!_tcscmp (value, _T("D3D"))) {
2927 p->gfx_api = 1;
2928 if (_tcscmp (option, _T("gfx_filter_pre")) == 0 || _tcscmp (option, _T("gfx_filter_pre_rtg")) == 0) {
2929 for (int i = 0; i < MAX_FILTERSHADERS; i++) {
2930 if (gf->gfx_filtershader[i][0] == 0) {
2931 _tcscpy (gf->gfx_filtershader[i], s);
2932 break;
2933 }
2934 }
2935 } else {
2936 for (int i = 0; i < MAX_FILTERSHADERS; i++) {
2937 if (gf->gfx_filtershader[i + MAX_FILTERSHADERS][0] == 0) {
2938 _tcscpy (gf->gfx_filtershader[i + MAX_FILTERSHADERS], s);
2939 break;
2940 }
2941 }
2942 }
2943 }
2944 }
2945 return 1;
2946 }
2947
2948 if ((j == 0 && _tcscmp (option, _T("gfx_filter")) == 0) || (j == 1 && _tcscmp (option, _T("gfx_filter_rtg")) == 0)) {
2949 TCHAR *s = _tcschr (value, ':');
2950 gf->gfx_filter = 0;
2951 if (s) {
2952 *s++ = 0;
2953 if (!_tcscmp (value, _T("D3D"))) {
2954 p->gfx_api = 1;
2955 _tcscpy (gf->gfx_filtershader[2 * MAX_FILTERSHADERS], s);
2956 for (int i = 0; i < 2 * MAX_FILTERSHADERS; i++) {
2957 if (!_tcsicmp (gf->gfx_filtershader[i], s)) {
2958 gf->gfx_filtershader[i][0] = 0;
2959 gf->gfx_filtermask[i][0] = 0;
2960 }
2961 }
2962 }
2963 }
2964 if (!_tcscmp (value, _T("direct3d"))) {
2965 p->gfx_api = 1; // forwards compatibiity
2966 } else {
2967 int i = 0;
2968 while(uaefilters[i].name) {
2969 if (!_tcscmp (uaefilters[i].cfgname, value)) {
2970 gf->gfx_filter = uaefilters[i].type;
2971 break;
2972 }
2973 i++;
2974 }
2975 }
2976 return 1;
2977 }
2978 if (j == 0 && _tcscmp (option, _T("gfx_filter_mode")) == 0) {
2979 cfgfile_strval (option, value, _T("gfx_filter_mode"), &gf->gfx_filter_filtermode, filtermode2, 0);
2980 return 1;
2981 }
2982 if (j == 1 && _tcscmp (option, _T("gfx_filter_mode_rtg")) == 0) {
2983 cfgfile_strval (option, value, _T("gfx_filter_mode_rtg"), &gf->gfx_filter_filtermode, filtermode2, 0);
2984 return 1;
2985 }
2986
2987 if ((j == 0 && cfgfile_string (option, value, _T("gfx_filter_aspect_ratio"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) ||
2988 (j == 1 && cfgfile_string (option, value, _T("gfx_filter_aspect_ratio_rtg"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR)))) {
2989 int v1, v2;
2990 TCHAR *s;
2991
2992 gf->gfx_filter_aspect = -1;
2993 v1 = _tstol (tmpbuf);
2994 s = _tcschr (tmpbuf, ':');
2995 if (s) {
2996 v2 = _tstol (s + 1);
2997 if (v1 < 0 || v2 < 0)
2998 gf->gfx_filter_aspect = -1;
2999 else if (v1 == 0 || v2 == 0)
3000 gf->gfx_filter_aspect = 0;
3001 else
3002 gf->gfx_filter_aspect = v1 * ASPECTMULT + v2;
3003 }
3004 return 1;
3005 }
3006 }
3007 #endif
3008
3009 if (_tcscmp (option, _T("gfx_width")) == 0 || _tcscmp (option, _T("gfx_height")) == 0) {
3010 cfgfile_intval (option, value, _T("gfx_width"), &p->gfx_size_win.width, 1);
3011 cfgfile_intval (option, value, _T("gfx_height"), &p->gfx_size_win.height, 1);
3012 p->gfx_size_fs.width = p->gfx_size_win.width;
3013 p->gfx_size_fs.height = p->gfx_size_win.height;
3014 return 1;
3015 }
3016
3017 if (_tcscmp (option, _T("gfx_fullscreen_multi")) == 0 || _tcscmp (option, _T("gfx_windowed_multi")) == 0) {
3018 TCHAR tmp[256], *tmpp, *tmpp2;
3019 struct wh *wh = p->gfx_size_win_xtra;
3020 if (_tcscmp (option, _T("gfx_fullscreen_multi")) == 0)
3021 wh = p->gfx_size_fs_xtra;
3022 _stprintf (tmp, _T(",%s,"), value);
3023 tmpp2 = tmp;
3024 for (i = 0; i < 4; i++) {
3025 tmpp = _tcschr (tmpp2, ',');
3026 tmpp++;
3027 wh[i].width = _tstol (tmpp);
3028 while (*tmpp != ',' && *tmpp != 'x' && *tmpp != '*')
3029 tmpp++;
3030 wh[i].height = _tstol (tmpp + 1);
3031 tmpp2 = tmpp;
3032 }
3033 return 1;
3034 }
3035
3036 if (cfgfile_string(option, value, _T("joyportcustom0"), p->jports_custom[0].custom, sizeof p->jports_custom[0].custom / sizeof(TCHAR)))
3037 return 1;
3038 if (cfgfile_string(option, value, _T("joyportcustom1"), p->jports_custom[1].custom, sizeof p->jports_custom[1].custom / sizeof(TCHAR)))
3039 return 1;
3040 if (cfgfile_string(option, value, _T("joyportcustom2"), p->jports_custom[2].custom, sizeof p->jports_custom[2].custom / sizeof(TCHAR)))
3041 return 1;
3042 if (cfgfile_string(option, value, _T("joyportcustom3"), p->jports_custom[3].custom, sizeof p->jports_custom[3].custom / sizeof(TCHAR)))
3043 return 1;
3044 if (cfgfile_string(option, value, _T("joyportcustom4"), p->jports_custom[4].custom, sizeof p->jports_custom[4].custom / sizeof(TCHAR)))
3045 return 1;
3046 if (cfgfile_string(option, value, _T("joyportcustom5"), p->jports_custom[5].custom, sizeof p->jports_custom[5].custom / sizeof(TCHAR)))
3047 return 1;
3048
3049 if (_tcscmp (option, _T("joyportfriendlyname0")) == 0 || _tcscmp (option, _T("joyportfriendlyname1")) == 0) {
3050 inputdevice_joyport_config_store(p, value, _tcscmp (option, _T("joyportfriendlyname0")) == 0 ? 0 : 1, -1, 2);
3051 return 1;
3052 }
3053 if (_tcscmp (option, _T("joyportfriendlyname2")) == 0 || _tcscmp (option, _T("joyportfriendlyname3")) == 0) {
3054 inputdevice_joyport_config_store(p, value, _tcscmp (option, _T("joyportfriendlyname2")) == 0 ? 2 : 3, -1, 2);
3055 return 1;
3056 }
3057 if (_tcscmp (option, _T("joyportname0")) == 0 || _tcscmp (option, _T("joyportname1")) == 0) {
3058 inputdevice_joyport_config_store(p, value, _tcscmp (option, _T("joyportname0")) == 0 ? 0 : 1, -1, 1);
3059 return 1;
3060 }
3061 if (_tcscmp (option, _T("joyportname2")) == 0 || _tcscmp (option, _T("joyportname3")) == 0) {
3062 inputdevice_joyport_config_store(p, value, _tcscmp (option, _T("joyportname2")) == 0 ? 2 : 3, -1, 1);
3063 return 1;
3064 }
3065 if (_tcscmp (option, _T("joyport0")) == 0 || _tcscmp (option, _T("joyport1")) == 0) {
3066 inputdevice_joyport_config_store(p, value, _tcscmp (option, _T("joyport0")) == 0 ? 0 : 1, -1, 0);
3067 return 1;
3068 }
3069 if (_tcscmp (option, _T("joyport2")) == 0 || _tcscmp (option, _T("joyport3")) == 0) {
3070 inputdevice_joyport_config_store(p, value, _tcscmp (option, _T("joyport2")) == 0 ? 2 : 3, -1, 0);
3071 return 1;
3072 }
3073 if (cfgfile_strval (option, value, _T("joyport0mode"), &p->jports[0].mode, joyportmodes, 0))
3074 return 1;
3075 if (cfgfile_strval (option, value, _T("joyport1mode"), &p->jports[1].mode, joyportmodes, 0))
3076 return 1;
3077 if (cfgfile_strval (option, value, _T("joyport2mode"), &p->jports[2].mode, joyportmodes, 0))
3078 return 1;
3079 if (cfgfile_strval (option, value, _T("joyport3mode"), &p->jports[3].mode, joyportmodes, 0))
3080 return 1;
3081 if (cfgfile_strval (option, value, _T("joyport0autofire"), &p->jports[0].autofire, joyaf, 0))
3082 return 1;
3083 if (cfgfile_strval (option, value, _T("joyport1autofire"), &p->jports[1].autofire, joyaf, 0))
3084 return 1;
3085 if (cfgfile_strval (option, value, _T("joyport2autofire"), &p->jports[2].autofire, joyaf, 0))
3086 return 1;
3087 if (cfgfile_strval (option, value, _T("joyport3autofire"), &p->jports[3].autofire, joyaf, 0))
3088 return 1;
3089
3090 if (cfgfile_yesno (option, value, _T("joyport0keyboardoverride"), &vb)) {
3091 p->jports[0].nokeyboardoverride = !vb;
3092 return 1;
3093 }
3094 if (cfgfile_yesno (option, value, _T("joyport1keyboardoverride"), &vb)) {
3095 p->jports[1].nokeyboardoverride = !vb;
3096 return 1;
3097 }
3098 if (cfgfile_yesno (option, value, _T("joyport2keyboardoverride"), &vb)) {
3099 p->jports[2].nokeyboardoverride = !vb;
3100 return 1;
3101 }
3102 if (cfgfile_yesno (option, value, _T("joyport3keyboardoverride"), &vb)) {
3103 p->jports[3].nokeyboardoverride = !vb;
3104 return 1;
3105 }
3106
3107 #ifdef SAVESTATE
3108
3109 if (cfgfile_path (option, value, _T("statefile_quit"), p->quitstatefile, sizeof p->quitstatefile / sizeof (TCHAR)))
3110 return 1;
3111
3112 if (cfgfile_string (option, value, _T("statefile_name"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
3113 fetch_statefilepath (savestate_fname, sizeof savestate_fname / sizeof (TCHAR));
3114 _tcscat (savestate_fname, tmpbuf);
3115 if (_tcslen (savestate_fname) >= 4 && _tcsicmp (savestate_fname + _tcslen (savestate_fname) - 4, _T(".uss")))
3116 _tcscat (savestate_fname, _T(".uss"));
3117 return 1;
3118 }
3119
3120 if (cfgfile_path (option, value, _T("statefile"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
3121 _tcscpy (p->statefile, tmpbuf);
3122 _tcscpy (savestate_fname, tmpbuf);
3123 if (zfile_exists (savestate_fname)) {
3124 savestate_state = STATE_DORESTORE;
3125 } else {
3126 int ok = 0;
3127 #ifdef FSUAE
3128 // code above seems broken, checks dir but removes file
3129 // simple fix: force ok (but leave WIN32 version as it
3130 // is, in case it is supposed to work like this
3131 ok = 1;
3132 #else
3133 if (savestate_fname[0]) {
3134 for (;;) {
3135 TCHAR *p;
3136 if (my_existsdir (savestate_fname)) {
3137 ok = 1;
3138 break;
3139 }
3140 p = _tcsrchr (savestate_fname, '\\');
3141 if (!p)
3142 p = _tcsrchr (savestate_fname, '/');
3143 if (!p)
3144 break;
3145 *p = 0;
3146 }
3147 }
3148 #endif
3149 if (!ok) {
3150 TCHAR tmp[MAX_DPATH];
3151 fetch_statefilepath (tmp, sizeof tmp / sizeof (TCHAR));
3152 _tcscat (tmp, savestate_fname);
3153 if (zfile_exists (tmp)) {
3154 _tcscpy (savestate_fname, tmp);
3155 savestate_state = STATE_DORESTORE;
3156 } else {
3157 savestate_fname[0] = 0;
3158 }
3159 }
3160 }
3161 return 1;
3162 }
3163
3164 #endif /* SAVESTATE */
3165
3166 if (cfgfile_strval (option, value, _T("sound_channels"), &p->sound_stereo, stereomode, 1)) {
3167 if (p->sound_stereo == SND_NONE) { /* "mixed stereo" compatibility hack */
3168 p->sound_stereo = SND_STEREO;
3169 p->sound_mixed_stereo_delay = 5;
3170 p->sound_stereo_separation = 7;
3171 }
3172 return 1;
3173 }
3174
3175 if (_tcscmp (option, _T("kbd_lang")) == 0) {
3176 KbdLang l;
3177 if ((l = KBD_LANG_DE, strcasecmp (value, _T("de")) == 0)
3178 || (l = KBD_LANG_DK, strcasecmp (value, _T("dk")) == 0)
3179 || (l = KBD_LANG_SE, strcasecmp (value, _T("se")) == 0)
3180 || (l = KBD_LANG_US, strcasecmp (value, _T("us")) == 0)
3181 || (l = KBD_LANG_FR, strcasecmp (value, _T("fr")) == 0)
3182 || (l = KBD_LANG_IT, strcasecmp (value, _T("it")) == 0)
3183 || (l = KBD_LANG_ES, strcasecmp (value, _T("es")) == 0))
3184 p->keyboard_lang = l;
3185 else
3186 cfgfile_warning(_T("Unknown keyboard language\n"));
3187 return 1;
3188 }
3189
3190 if (cfgfile_string (option, value, _T("config_version"), tmpbuf, sizeof (tmpbuf) / sizeof (TCHAR))) {
3191 TCHAR *tmpp2;
3192 tmpp = _tcschr (value, '.');
3193 if (tmpp) {
3194 *tmpp++ = 0;
3195 tmpp2 = tmpp;
3196 p->config_version = _tstol (tmpbuf) << 16;
3197 tmpp = _tcschr (tmpp, '.');
3198 if (tmpp) {
3199 *tmpp++ = 0;
3200 p->config_version |= _tstol (tmpp2) << 8;
3201 p->config_version |= _tstol (tmpp);
3202 }
3203 }
3204 return 1;
3205 }
3206
3207 if (cfgfile_string (option, value, _T("keyboard_leds"), tmpbuf, sizeof (tmpbuf) / sizeof (TCHAR))) {
3208 TCHAR *tmpp2 = tmpbuf;
3209 int i, num;
3210 p->keyboard_leds[0] = p->keyboard_leds[1] = p->keyboard_leds[2] = 0;
3211 p->keyboard_leds_in_use = 0;
3212 _tcscat (tmpbuf, _T(","));
3213 for (i = 0; i < 3; i++) {
3214 tmpp = _tcschr (tmpp2, ':');
3215 if (!tmpp)
3216 break;
3217 *tmpp++= 0;
3218 num = -1;
3219 if (!strcasecmp (tmpp2, _T("numlock")))
3220 num = 0;
3221 if (!strcasecmp (tmpp2, _T("capslock")))
3222 num = 1;
3223 if (!strcasecmp (tmpp2, _T("scrolllock")))
3224 num = 2;
3225 tmpp2 = tmpp;
3226 tmpp = _tcschr (tmpp2, ',');
3227 if (!tmpp)
3228 break;
3229 *tmpp++= 0;
3230 if (num >= 0) {
3231 p->keyboard_leds[num] = match_string (kbleds, tmpp2);
3232 if (p->keyboard_leds[num])
3233 p->keyboard_leds_in_use = 1;
3234 }
3235 tmpp2 = tmpp;
3236 }
3237 return 1;
3238 }
3239
3240 if (_tcscmp (option, _T("displaydata")) == 0 || _tcscmp (option, _T("displaydata_pal")) == 0 || _tcscmp (option, _T("displaydata_ntsc")) == 0) {
3241 _tcsncpy (tmpbuf, value, sizeof tmpbuf / sizeof (TCHAR) - 1);
3242 tmpbuf[sizeof tmpbuf / sizeof (TCHAR) - 1] = '\0';
3243
3244 int vert = -1, horiz = -1, lace = -1, ntsc = -1, framelength = -1, vsync = -1;
3245 bool locked = false;
3246 bool rtg = false;
3247 double rate = -1;
3248 TCHAR cmd[MAX_DPATH], label[16] = { 0 };
3249 TCHAR *tmpp = tmpbuf;
3250 TCHAR *end = tmpbuf + _tcslen (tmpbuf);
3251 cmd[0] = 0;
3252 for (;;) {
3253 TCHAR *next = _tcschr (tmpp, ',');
3254 TCHAR *equals = _tcschr (tmpp, '=');
3255
3256 if (!next)
3257 next = end;
3258 if (equals == NULL || equals > next)
3259 equals = NULL;
3260 else
3261 equals++;
3262 *next = 0;
3263
3264 if (rate < 0)
3265 rate = _tstof (tmpp);
3266 else if (!_tcsnicmp (tmpp, _T("v="), 2))
3267 vert = _tstol (equals);
3268 else if (!_tcsnicmp (tmpp, _T("h="), 2))
3269 horiz = _tstol (equals);
3270 else if (!_tcsnicmp (tmpp, _T("t="), 2))
3271 _tcsncpy (label, equals, sizeof label / sizeof (TCHAR) - 1);
3272 else if (equals) {
3273 if (_tcslen (cmd) + _tcslen (tmpp) + 2 < sizeof (cmd) / sizeof (TCHAR)) {
3274 _tcscat (cmd, tmpp);
3275 _tcscat (cmd, _T("\n"));
3276 }
3277 }
3278 if (!_tcsnicmp (tmpp, _T("locked"), 4))
3279 locked = true;
3280 if (!_tcsnicmp (tmpp, _T("nlace"), 5))
3281 lace = 0;
3282 if (!_tcsnicmp (tmpp, _T("lace"), 4))
3283 lace = 1;
3284 if (!_tcsnicmp (tmpp, _T("nvsync"), 5))
3285 vsync = 0;
3286 if (!_tcsnicmp (tmpp, _T("vsync"), 4))
3287 vsync = 1;
3288 if (!_tcsnicmp (tmpp, _T("ntsc"), 4))
3289 ntsc = 1;
3290 if (!_tcsnicmp (tmpp, _T("pal"), 3))
3291 ntsc = 0;
3292 if (!_tcsnicmp (tmpp, _T("lof"), 3))
3293 framelength = 1;
3294 if (!_tcsnicmp (tmpp, _T("shf"), 3))
3295 framelength = 0;
3296 if (!_tcsnicmp (tmpp, _T("rtg"), 3))
3297 rtg = true;
3298 tmpp = next;
3299 if (tmpp >= end)
3300 break;
3301 tmpp++;
3302 }
3303 if (rate > 0) {
3304 for (int i = 0; i < MAX_CHIPSET_REFRESH; i++) {
3305 if (_tcscmp (option, _T("displaydata_pal")) == 0) {
3306 i = CHIPSET_REFRESH_PAL;
3307 p->cr[i].rate = -1;
3308 _tcscpy (label, _T("PAL"));
3309 } else if (_tcscmp (option, _T("displaydata_ntsc")) == 0) {
3310 i = CHIPSET_REFRESH_NTSC;
3311 p->cr[i].rate = -1;
3312 _tcscpy (label, _T("NTSC"));
3313 }
3314 if (p->cr[i].rate <= 0) {
3315 p->cr[i].horiz = horiz;
3316 p->cr[i].vert = vert;
3317 p->cr[i].lace = lace;
3318 p->cr[i].ntsc = ntsc;
3319 p->cr[i].vsync = vsync;
3320 p->cr[i].locked = locked;
3321 p->cr[i].rtg = rtg;
3322 p->cr[i].framelength = framelength;
3323 p->cr[i].rate = rate;
3324 _tcscpy (p->cr[i].commands, cmd);
3325 _tcscpy (p->cr[i].label, label);
3326 break;
3327 }
3328 }
3329 }
3330 return 1;
3331 }
3332
3333 #ifdef WITH_SLIRP
3334 #ifdef FSUAE
3335 if (cfgfile_strval(option, value, _T("slirp_implementation"), &p->slirp_implementation, slirp_implementations, 0))
3336 return 1;
3337 #endif
3338 if (cfgfile_string (option, value, _T("slirp_ports"), tmpbuf, sizeof (tmpbuf) / sizeof (TCHAR))) {
3339 TCHAR *tmpp2 = tmpbuf;
3340 _tcscat (tmpbuf, _T(","));
3341 for (;;) {
3342 tmpp = _tcschr (tmpp2, ',');
3343 if (!tmpp)
3344 break;
3345 *tmpp++= 0;
3346 for (i = 0; i < MAX_SLIRP_REDIRS; i++) {
3347 struct slirp_redir *sr = &p->slirp_redirs[i];
3348 if (sr->proto == 0) {
3349 sr->dstport = _tstol (tmpp2);
3350 sr->proto = 1;
3351 break;
3352 }
3353 }
3354 tmpp2 = tmpp;
3355 }
3356 return 1;
3357 }
3358 if (cfgfile_string (option, value, _T("slirp_redir"), tmpbuf, sizeof (tmpbuf) / sizeof(TCHAR))) {
3359 TCHAR *tmpp2 = tmpbuf;
3360 _tcscat (tmpbuf, _T(":"));
3361 for (i = 0; i < MAX_SLIRP_REDIRS; i++) {
3362 struct slirp_redir *sr = &p->slirp_redirs[i];
3363 if (sr->proto == 0) {
3364 char *s;
3365 tmpp = _tcschr (tmpp2, ':');
3366 if (!tmpp)
3367 break;
3368 *tmpp++= 0;
3369 if (!_tcsicmp (tmpp2, _T("tcp")))
3370 sr->proto = 1;
3371 else if (!_tcsicmp (tmpp2, _T("udp")))
3372 sr->proto = 2;
3373 else
3374 break;
3375 tmpp2 = tmpp;
3376 tmpp = _tcschr (tmpp2, ':');
3377 if (!tmpp) {
3378 sr->proto = 0;
3379 break;
3380 }
3381 *tmpp++= 0;
3382 sr->dstport = _tstol (tmpp2);
3383 tmpp2 = tmpp;
3384 tmpp = _tcschr (tmpp2, ':');
3385 if (!tmpp) {
3386 sr->proto = 0;
3387 break;
3388 }
3389 *tmpp++= 0;
3390 sr->srcport = _tstol (tmpp2);
3391 tmpp2 = tmpp;
3392 tmpp = _tcschr (tmpp2, ':');
3393 if (!tmpp)
3394 break;
3395 *tmpp++= 0;
3396 s = ua (tmpp2);
3397 sr->addr = inet_addr (s);
3398 xfree (s);
3399 }
3400 }
3401 return 1;
3402 }
3403 #endif
3404
3405 return 0;
3406 }
3407
decode_rom_ident(TCHAR * romfile,int maxlen,const TCHAR * ident,int romflags)3408 static void decode_rom_ident (TCHAR *romfile, int maxlen, const TCHAR *ident, int romflags)
3409 {
3410 const TCHAR *p;
3411 int ver, rev, subver, subrev, round, i;
3412 TCHAR model[64], *modelp;
3413 struct romlist **rl;
3414 TCHAR *romtxt;
3415
3416 if (!ident[0])
3417 return;
3418 romtxt = xmalloc (TCHAR, 10000);
3419 romtxt[0] = 0;
3420 for (round = 0; round < 2; round++) {
3421 ver = rev = subver = subrev = -1;
3422 modelp = NULL;
3423 memset (model, 0, sizeof model);
3424 p = ident;
3425 while (*p) {
3426 TCHAR c = *p++;
3427 int *pp1 = NULL, *pp2 = NULL;
3428 if (_totupper (c) == 'V' && _istdigit (*p)) {
3429 pp1 = &ver;
3430 pp2 = &rev;
3431 } else if (_totupper (c) == 'R' && _istdigit (*p)) {
3432 pp1 = &subver;
3433 pp2 = &subrev;
3434 } else if (!_istdigit (c) && c != ' ') {
3435 _tcsncpy (model, p - 1, (sizeof model) / sizeof (TCHAR) - 1);
3436 p += _tcslen (model);
3437 modelp = model;
3438 }
3439 if (pp1) {
3440 *pp1 = _tstol (p);
3441 while (*p != 0 && *p != '.' && *p != ' ')
3442 p++;
3443 if (*p == '.') {
3444 p++;
3445 if (pp2)
3446 *pp2 = _tstol (p);
3447 }
3448 }
3449 if (*p == 0 || *p == ';') {
3450 rl = getromlistbyident (ver, rev, subver, subrev, modelp, romflags, round > 0);
3451 if (rl) {
3452 for (i = 0; rl[i]; i++) {
3453 if (round) {
3454 TCHAR romname[MAX_DPATH];
3455 getromname(rl[i]->rd, romname);
3456 _tcscat (romtxt, romname);
3457 _tcscat (romtxt, _T("\n"));
3458 } else {
3459 _tcsncpy (romfile, rl[i]->path, maxlen);
3460 goto end;
3461 }
3462 }
3463 xfree (rl);
3464 }
3465 }
3466 }
3467 }
3468 end:
3469 if (round && romtxt[0]) {
3470 notify_user_parms (NUMSG_ROMNEED, romtxt, romtxt);
3471 }
3472 xfree (romtxt);
3473 }
3474
getuci(struct uae_prefs * p)3475 static struct uaedev_config_data *getuci (struct uae_prefs *p)
3476 {
3477 if (p->mountitems < MOUNT_CONFIG_SIZE)
3478 return &p->mountconfig[p->mountitems++];
3479 return NULL;
3480 }
3481
add_filesys_config(struct uae_prefs * p,int index,struct uaedev_config_info * ci)3482 struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, struct uaedev_config_info *ci)
3483 {
3484 struct uaedev_config_data *uci;
3485 int i;
3486
3487 if (index < 0 && (ci->type == UAEDEV_DIR || ci->type == UAEDEV_HDF) && ci->devname && _tcslen (ci->devname) > 0) {
3488 for (i = 0; i < p->mountitems; i++) {
3489 if (p->mountconfig[i].ci.devname && !_tcscmp (p->mountconfig[i].ci.devname, ci->devname))
3490 return NULL;
3491 }
3492 }
3493 for (;;) {
3494 if (ci->type == UAEDEV_CD) {
3495 if (ci->controller_type >= HD_CONTROLLER_TYPE_IDE_FIRST && ci->controller_type <= HD_CONTROLLER_TYPE_IDE_LAST)
3496 break;
3497 if (ci->controller_type >= HD_CONTROLLER_TYPE_SCSI_FIRST && ci->controller_type <= HD_CONTROLLER_TYPE_SCSI_LAST)
3498 break;
3499 } else if (ci->type == UAEDEV_TAPE) {
3500 if (ci->controller_type == HD_CONTROLLER_TYPE_UAE)
3501 break;
3502 if (ci->controller_type >= HD_CONTROLLER_TYPE_SCSI_FIRST && ci->controller_type <= HD_CONTROLLER_TYPE_SCSI_LAST)
3503 break;
3504 } else {
3505 break;
3506 }
3507 return NULL;
3508 }
3509
3510 if (index < 0) {
3511 if (ci->controller_type != HD_CONTROLLER_TYPE_UAE) {
3512 int ctrl = ci->controller_type;
3513 int ctrlunit = ci->controller_type_unit;
3514 int cunit = ci->controller_unit;
3515 for (;;) {
3516 for (i = 0; i < p->mountitems; i++) {
3517 if (p->mountconfig[i].ci.controller_type == ctrl && p->mountconfig[i].ci.controller_type_unit == ctrlunit && p->mountconfig[i].ci.controller_unit == cunit) {
3518 cunit++;
3519 if (ctrl >= HD_CONTROLLER_TYPE_IDE_FIRST && ctrl <= HD_CONTROLLER_TYPE_IDE_LAST && cunit == 4)
3520 return NULL;
3521 if (ctrl >= HD_CONTROLLER_TYPE_SCSI_FIRST && ctrl <= HD_CONTROLLER_TYPE_SCSI_LAST && cunit >= 7)
3522 return NULL;
3523 }
3524 }
3525 if (i == p->mountitems) {
3526 ci->controller_unit = cunit;
3527 break;
3528 }
3529 }
3530 }
3531 if (ci->type == UAEDEV_CD) {
3532 for (i = 0; i < p->mountitems; i++) {
3533 if (p->mountconfig[i].ci.type == ci->type)
3534 return NULL;
3535 }
3536 }
3537 uci = getuci (p);
3538 uci->configoffset = -1;
3539 uci->unitnum = -1;
3540 } else {
3541 uci = &p->mountconfig[index];
3542 }
3543 if (!uci)
3544 return NULL;
3545
3546 memcpy (&uci->ci, ci, sizeof (struct uaedev_config_info));
3547 validatedevicename (uci->ci.devname, NULL);
3548 validatevolumename (uci->ci.volname, NULL);
3549 if (!uci->ci.devname[0] && ci->type != UAEDEV_CD && ci->type != UAEDEV_TAPE) {
3550 TCHAR base[32];
3551 TCHAR base2[32];
3552 int num = 0;
3553 if (uci->ci.rootdir[0] == 0 && ci->type == UAEDEV_DIR)
3554 _tcscpy (base, _T("RDH"));
3555 else
3556 _tcscpy (base, _T("DH"));
3557 _tcscpy (base2, base);
3558 for (i = 0; i < p->mountitems; i++) {
3559 _stprintf (base2, _T("%s%d"), base, num);
3560 if (!_tcsicmp(base2, p->mountconfig[i].ci.devname)) {
3561 num++;
3562 i = -1;
3563 continue;
3564 }
3565 }
3566 _tcscpy (uci->ci.devname, base2);
3567 validatedevicename (uci->ci.devname, NULL);
3568 }
3569 if (ci->type == UAEDEV_DIR) {
3570 TCHAR *s = filesys_createvolname (uci->ci.volname, uci->ci.rootdir, NULL, _T("Harddrive"));
3571 _tcscpy (uci->ci.volname, s);
3572 xfree (s);
3573 }
3574 return uci;
3575 }
3576
parse_addmem(struct uae_prefs * p,TCHAR * buf,int num)3577 static void parse_addmem (struct uae_prefs *p, TCHAR *buf, int num)
3578 {
3579 int size = 0, addr = 0;
3580
3581 if (!getintval2 (&buf, &addr, ',', false))
3582 return;
3583 if (!getintval2 (&buf, &size, 0, true))
3584 return;
3585 if (addr & 0xffff)
3586 return;
3587 if ((size & 0xffff) || (size & 0xffff0000) == 0)
3588 return;
3589 p->custom_memory_addrs[num] = addr;
3590 p->custom_memory_sizes[num] = size;
3591 }
3592
get_filesys_controller(const TCHAR * hdc,int * type,int * typenum,int * num)3593 static void get_filesys_controller (const TCHAR *hdc, int *type, int *typenum, int *num)
3594 {
3595 #ifdef FSUAE
3596 write_log("get_filesys_controller %s\n", hdc);
3597 #endif
3598 int hdcv = HD_CONTROLLER_TYPE_UAE;
3599 int hdunit = 0;
3600 int idx = 0;
3601 if(_tcslen (hdc) >= 4 && !_tcsncmp (hdc, _T("ide"), 3)) {
3602 hdcv = HD_CONTROLLER_TYPE_IDE_AUTO;
3603 hdunit = hdc[3] - '0';
3604 if (hdunit < 0 || hdunit >= 4)
3605 hdunit = 0;
3606 } else if(_tcslen (hdc) >= 5 && !_tcsncmp (hdc, _T("scsi"), 4)) {
3607 hdcv = HD_CONTROLLER_TYPE_SCSI_AUTO;
3608 #ifdef FSUAE
3609 write_log(" - HD_CONTROLLER_TYPE_SCSI_AUTO\n");
3610 #endif
3611 hdunit = hdc[4] - '0';
3612 if (hdunit < 0 || hdunit >= 8 + 2)
3613 hdunit = 0;
3614 }
3615 if (hdcv > HD_CONTROLLER_TYPE_UAE) {
3616 bool found = false;
3617 const TCHAR *ext = _tcsrchr (hdc, '_');
3618 if (ext) {
3619 ext++;
3620 int len = _tcslen(ext);
3621 if (len > 2 && ext[len - 2] == '-' && ext[len - 1] >= '2' && ext[len - 1] <= '9') {
3622 idx = ext[len - 1] - '1';
3623 len -= 2;
3624 }
3625 for (int i = 0; hdcontrollers[i]; i++) {
3626 const TCHAR *ext2 = _tcsrchr(hdcontrollers[i], '_');
3627 if (ext2) {
3628 ext2++;
3629 if (_tcslen(ext2) == len && !_tcsnicmp(ext, ext2, len) && hdc[0] == hdcontrollers[i][0]) {
3630 if (hdcv == HD_CONTROLLER_TYPE_IDE_AUTO) {
3631 hdcv = i;
3632 } else {
3633 hdcv = i + HD_CONTROLLER_EXPANSION_MAX;
3634 }
3635 #ifdef FSUAE
3636 write_log(" - found\n");
3637 #endif
3638 found = true;
3639 break;
3640 }
3641 }
3642 }
3643 if (!found) {
3644 for (int i = 0; expansionroms[i].name; i++) {
3645 const struct expansionromtype *ert = &expansionroms[i];
3646 if (_tcslen(ert->name) == len && !_tcsnicmp(ext, ert->name, len)) {
3647 if (hdcv == HD_CONTROLLER_TYPE_IDE_AUTO) {
3648 hdcv = HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST + i;
3649 } else {
3650 hdcv = HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST + i;
3651 }
3652 #ifdef FSUAE
3653 write_log(" - ert->name=%s ext=%s len=%d\n", ert->name, ext, len);
3654 #endif
3655 break;
3656 }
3657 }
3658
3659 }
3660 }
3661 } else if (_tcslen (hdc) >= 6 && !_tcsncmp (hdc, _T("scsram"), 6)) {
3662 hdcv = HD_CONTROLLER_TYPE_PCMCIA_SRAM;
3663 hdunit = 0;
3664 } else if (_tcslen (hdc) >= 5 && !_tcsncmp (hdc, _T("scide"), 6)) {
3665 hdcv = HD_CONTROLLER_TYPE_PCMCIA_IDE;
3666 hdunit = 0;
3667 }
3668 if (idx >= MAX_DUPLICATE_EXPANSION_BOARDS)
3669 idx = MAX_DUPLICATE_EXPANSION_BOARDS - 1;
3670 *type = hdcv;
3671 *typenum = idx;
3672 *num = hdunit;
3673 }
3674
parse_geo(const TCHAR * tname,struct uaedev_config_info * uci,struct hardfiledata * hfd,bool empty)3675 static bool parse_geo (const TCHAR *tname, struct uaedev_config_info *uci, struct hardfiledata *hfd, bool empty)
3676 {
3677 struct zfile *f;
3678 int found;
3679 TCHAR buf[200];
3680
3681 f = zfile_fopen (tname, _T("r"));
3682 if (!f)
3683 return false;
3684 found = hfd == NULL && !empty ? 2 : 0;
3685 if (found)
3686 write_log (_T("Geometry file '%s' detected\n"), tname);
3687 while (zfile_fgets (buf, sizeof buf / sizeof (TCHAR), f)) {
3688 int v;
3689 TCHAR *sep;
3690
3691 my_trim (buf);
3692 if (_tcslen (buf) == 0)
3693 continue;
3694 if (buf[0] == '[' && buf[_tcslen (buf) - 1] == ']') {
3695 if (found > 1) {
3696 zfile_fclose (f);
3697 return true;
3698 }
3699 found = 0;
3700 buf[_tcslen (buf) - 1] = 0;
3701 my_trim (buf + 1);
3702 if (!_tcsicmp (buf + 1, _T("empty"))) {
3703 if (empty)
3704 found = 1;
3705 } else if (!_tcsicmp (buf + 1, _T("default"))) {
3706 if (!empty)
3707 found = 1;
3708 } else if (hfd) {
3709 uae_u64 size = _tstoi64 (buf + 1);
3710 if (size == hfd->virtsize)
3711 found = 2;
3712 }
3713 if (found)
3714 write_log (_T("Geometry file '%s', entry '%s' detected\n"), tname, buf + 1);
3715 continue;
3716 }
3717 if (!found)
3718 continue;
3719
3720 sep = _tcschr (buf, '=');
3721 if (!sep)
3722 continue;
3723 sep[0] = 0;
3724
3725 TCHAR *key = my_strdup_trim (buf);
3726 TCHAR *val = my_strdup_trim (sep + 1);
3727 if (val[0] == '0' && _totupper (val[1]) == 'X') {
3728 TCHAR *endptr;
3729 v = _tcstol (val, &endptr, 16);
3730 } else {
3731 v = _tstol (val);
3732 }
3733 if (!_tcsicmp (key, _T("surfaces")))
3734 uci->surfaces = v;
3735 if (!_tcsicmp (key, _T("sectorspertrack")) || !_tcsicmp (key, _T("blockspertrack")))
3736 uci->sectors = v;
3737 if (!_tcsicmp (key, _T("sectorsperblock")))
3738 uci->sectorsperblock = v;
3739 if (!_tcsicmp (key, _T("reserved")))
3740 uci->reserved = v;
3741 if (!_tcsicmp (key, _T("lowcyl")))
3742 uci->lowcyl = v;
3743 if (!_tcsicmp (key, _T("highcyl")) || !_tcsicmp (key, _T("cyl")))
3744 uci->highcyl = v;
3745 if (!_tcsicmp (key, _T("blocksize")) || !_tcsicmp (key, _T("sectorsize")))
3746 uci->blocksize = v;
3747 if (!_tcsicmp (key, _T("buffers")))
3748 uci->buffers = v;
3749 if (!_tcsicmp (key, _T("maxtransfer")))
3750 uci->maxtransfer = v;
3751 if (!_tcsicmp (key, _T("interleave")))
3752 uci->interleave = v;
3753 if (!_tcsicmp (key, _T("dostype")))
3754 uci->dostype = v;
3755 if (!_tcsicmp (key, _T("bufmemtype")))
3756 uci->bufmemtype = v;
3757 if (!_tcsicmp (key, _T("stacksize")))
3758 uci->stacksize = v;
3759 if (!_tcsicmp (key, _T("mask")))
3760 uci->mask = v;
3761 if (!_tcsicmp (key, _T("unit")))
3762 uci->unit = v;
3763 if (!_tcsicmp (key, _T("controller")))
3764 get_filesys_controller (val, &uci->controller_type, &uci->controller_type_unit, &uci->controller_unit);
3765 if (!_tcsicmp (key, _T("flags")))
3766 uci->flags = v;
3767 if (!_tcsicmp (key, _T("priority")))
3768 uci->priority = v;
3769 if (!_tcsicmp (key, _T("forceload")))
3770 uci->forceload = v;
3771 if (!_tcsicmp (key, _T("bootpri"))) {
3772 if (v < -129)
3773 v = -129;
3774 if (v > 127)
3775 v = 127;
3776 uci->bootpri = v;
3777 }
3778 if (!_tcsicmp (key, _T("filesystem")))
3779 _tcscpy (uci->filesys, val);
3780 if (!_tcsicmp (key, _T("device")))
3781 _tcscpy (uci->devname, val);
3782 xfree (val);
3783 xfree (key);
3784 }
3785 zfile_fclose (f);
3786 return false;
3787 }
get_hd_geometry(struct uaedev_config_info * uci)3788 bool get_hd_geometry (struct uaedev_config_info *uci)
3789 {
3790 TCHAR tname[MAX_DPATH];
3791
3792 fetch_configurationpath (tname, sizeof tname / sizeof (TCHAR));
3793 _tcscat (tname, _T("default.geo"));
3794 if (zfile_exists (tname)) {
3795 struct hardfiledata hfd;
3796 memset (&hfd, 0, sizeof hfd);
3797 hfd.ci.readonly = true;
3798 hfd.ci.blocksize = 512;
3799 if (hdf_open (&hfd, uci->rootdir) > 0) {
3800 parse_geo (tname, uci, &hfd, false);
3801 hdf_close (&hfd);
3802 } else {
3803 parse_geo (tname, uci, NULL, true);
3804 }
3805 }
3806 if (uci->rootdir[0]) {
3807 _tcscpy (tname, uci->rootdir);
3808 _tcscat (tname, _T(".geo"));
3809 return parse_geo (tname, uci, NULL, false);
3810 }
3811 return false;
3812 }
3813
cfgfile_parse_partial_newfilesys(struct uae_prefs * p,int nr,int type,const TCHAR * value,int unit,bool uaehfentry)3814 static int cfgfile_parse_partial_newfilesys (struct uae_prefs *p, int nr, int type, const TCHAR *value, int unit, bool uaehfentry)
3815 {
3816 TCHAR *tmpp;
3817 TCHAR *name = NULL, *path = NULL;
3818
3819 // read only harddrive name
3820 if (!uaehfentry)
3821 return 0;
3822 if (type != 1)
3823 return 0;
3824 tmpp = getnextentry (&value, ',');
3825 if (!tmpp)
3826 return 0;
3827 xfree (tmpp);
3828 tmpp = getnextentry (&value, ':');
3829 if (!tmpp)
3830 return 0;
3831 xfree (tmpp);
3832 name = getnextentry (&value, ':');
3833 if (name && _tcslen (name) > 0) {
3834 path = getnextentry (&value, ',');
3835 if (path && _tcslen (path) > 0) {
3836 for (int i = 0; i < MAX_FILESYSTEM_UNITS; i++) {
3837 struct uaedev_config_info *uci = &p->mountconfig[i].ci;
3838 if (_tcsicmp (uci->rootdir, name) == 0) {
3839 _tcscat (uci->rootdir, _T(":"));
3840 _tcscat (uci->rootdir, path);
3841 }
3842 }
3843 }
3844 }
3845 xfree (path);
3846 xfree (name);
3847 return 1;
3848 }
3849
cfgfile_parse_newfilesys(struct uae_prefs * p,int nr,int type,TCHAR * value,int unit,bool uaehfentry)3850 static int cfgfile_parse_newfilesys (struct uae_prefs *p, int nr, int type, TCHAR *value, int unit, bool uaehfentry)
3851 {
3852 struct uaedev_config_info uci;
3853 TCHAR *tmpp = _tcschr (value, ','), *tmpp2;
3854 TCHAR *str = NULL;
3855 TCHAR devname[MAX_DPATH], volname[MAX_DPATH];
3856
3857 devname[0] = volname[0] = 0;
3858 uci_set_defaults (&uci, false);
3859
3860 config_newfilesystem = 1;
3861 if (tmpp == 0)
3862 goto invalid_fs;
3863
3864 *tmpp++ = '\0';
3865 if (strcasecmp (value, _T("ro")) == 0)
3866 uci.readonly = true;
3867 else if (strcasecmp (value, _T("rw")) == 0)
3868 uci.readonly = false;
3869 else
3870 goto invalid_fs;
3871
3872 value = tmpp;
3873 if (type == 0) {
3874 uci.type = UAEDEV_DIR;
3875 tmpp = _tcschr (value, ':');
3876 if (tmpp == 0)
3877 goto empty_fs;
3878 *tmpp++ = 0;
3879 _tcscpy (devname, value);
3880 tmpp2 = tmpp;
3881 tmpp = _tcschr (tmpp, ':');
3882 if (tmpp == 0)
3883 goto empty_fs;
3884 *tmpp++ = 0;
3885 _tcscpy (volname, tmpp2);
3886 tmpp2 = tmpp;
3887 tmpp = _tcschr (tmpp, ',');
3888 if (tmpp == 0)
3889 goto empty_fs;
3890 *tmpp++ = 0;
3891 _tcscpy (uci.rootdir, tmpp2);
3892 _tcscpy (uci.volname, volname);
3893 _tcscpy (uci.devname, devname);
3894 if (! getintval (&tmpp, &uci.bootpri, 0))
3895 goto empty_fs;
3896 } else if (type == 1 || ((type == 2 || type == 3) && uaehfentry)) {
3897 tmpp = _tcschr (value, ':');
3898 if (tmpp == 0)
3899 goto invalid_fs;
3900 *tmpp++ = '\0';
3901 _tcscpy (devname, value);
3902 tmpp2 = tmpp;
3903 tmpp = _tcschr (tmpp, ',');
3904 if (tmpp == 0)
3905 goto invalid_fs;
3906 *tmpp++ = 0;
3907 _tcscpy (uci.rootdir, tmpp2);
3908 if (uci.rootdir[0] != ':')
3909 get_hd_geometry (&uci);
3910 _tcscpy (uci.devname, devname);
3911 if (! getintval (&tmpp, &uci.sectors, ',')
3912 || ! getintval (&tmpp, &uci.surfaces, ',')
3913 || ! getintval (&tmpp, &uci.reserved, ',')
3914 || ! getintval (&tmpp, &uci.blocksize, ','))
3915 goto invalid_fs;
3916 if (getintval2 (&tmpp, &uci.bootpri, ',', false)) {
3917 tmpp2 = tmpp;
3918 tmpp = _tcschr (tmpp, ',');
3919 if (tmpp != 0) {
3920 *tmpp++ = 0;
3921 _tcscpy (uci.filesys, tmpp2);
3922 TCHAR *tmpp2 = _tcschr (tmpp, ',');
3923 if (tmpp2)
3924 *tmpp2++ = 0;
3925 get_filesys_controller (tmpp, &uci.controller_type, &uci.controller_type_unit, &uci.controller_unit);
3926 if (tmpp2) {
3927 if (getintval2 (&tmpp2, &uci.highcyl, ',', false)) {
3928 getintval (&tmpp2, &uci.pcyls, '/');
3929 getintval (&tmpp2, &uci.pheads, '/');
3930 getintval2 (&tmpp2, &uci.psecs, '/', true);
3931 if (uci.pheads && uci.psecs) {
3932 uci.physical_geometry = true;
3933 } else {
3934 uci.pheads = uci.psecs = uci.pcyls = 0;
3935 uci.physical_geometry = false;
3936 }
3937 }
3938 }
3939 uci.controller_media_type = 0;
3940 uci.unit_feature_level = 1;
3941
3942 if (cfgfile_option_find(tmpp2, _T("CF")))
3943 uci.controller_media_type = 1;
3944 else if (cfgfile_option_find(tmpp2, _T("HD")))
3945 uci.controller_media_type = 0;
3946
3947 TCHAR *pflags;
3948 if ((pflags = cfgfile_option_get(tmpp2, _T("flags")))) {
3949 getintval(&pflags, &uci.unit_special_flags, 0);
3950 }
3951
3952 if (cfgfile_option_find(tmpp2, _T("SCSI2")))
3953 uci.unit_feature_level = HD_LEVEL_SCSI_2;
3954 else if (cfgfile_option_find(tmpp2, _T("SCSI1")))
3955 uci.unit_feature_level = HD_LEVEL_SCSI_1;
3956 else if (cfgfile_option_find(tmpp2, _T("SASIE")))
3957 uci.unit_feature_level = HD_LEVEL_SASI_ENHANCED;
3958 else if (cfgfile_option_find(tmpp2, _T("SASI")))
3959 uci.unit_feature_level = HD_LEVEL_SASI;
3960 else if (cfgfile_option_find(tmpp2, _T("SASI_CHS")))
3961 uci.unit_feature_level = HD_LEVEL_SASI_CHS;
3962 else if (cfgfile_option_find(tmpp2, _T("ATA2+S")))
3963 uci.unit_feature_level = HD_LEVEL_ATA_2S;
3964 else if (cfgfile_option_find(tmpp2, _T("ATA2+")))
3965 uci.unit_feature_level = HD_LEVEL_ATA_2;
3966 else if (cfgfile_option_find(tmpp2, _T("ATA1")))
3967 uci.unit_feature_level = HD_LEVEL_ATA_1;
3968 }
3969 }
3970 if (type == 2) {
3971 uci.device_emu_unit = unit;
3972 uci.blocksize = 2048;
3973 uci.readonly = true;
3974 uci.type = UAEDEV_CD;
3975 } else if (type == 3) {
3976 uci.device_emu_unit = unit;
3977 uci.blocksize = 512;
3978 uci.type = UAEDEV_TAPE;
3979 } else {
3980 uci.type = UAEDEV_HDF;
3981 }
3982 } else {
3983 goto invalid_fs;
3984 }
3985 empty_fs:
3986 if (uci.rootdir[0]) {
3987 if (_tcslen (uci.rootdir) > 3 && uci.rootdir[0] == 'H' && uci.rootdir[1] == 'D' && uci.rootdir[2] == '_') {
3988 memmove (uci.rootdir, uci.rootdir + 2, (_tcslen (uci.rootdir + 2) + 1) * sizeof (TCHAR));
3989 uci.rootdir[0] = ':';
3990 }
3991 str = cfgfile_subst_path_load (UNEXPANDED, &p->path_hardfile, uci.rootdir, false);
3992 _tcscpy (uci.rootdir, str);
3993 }
3994 #ifdef FILESYS
3995 add_filesys_config (p, nr, &uci);
3996 #endif
3997 xfree (str);
3998 return 1;
3999
4000 invalid_fs:
4001 cfgfile_warning(_T("Invalid filesystem/hardfile/cd specification.\n"));
4002 return 1;
4003 }
4004
cfgfile_parse_filesys(struct uae_prefs * p,const TCHAR * option,TCHAR * value)4005 static int cfgfile_parse_filesys (struct uae_prefs *p, const TCHAR *option, TCHAR *value)
4006 {
4007 int i;
4008
4009 for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) {
4010 TCHAR tmp[100];
4011 _stprintf (tmp, _T("uaehf%d"), i);
4012 if (_tcscmp (option, tmp) == 0) {
4013 for (;;) {
4014 int type = -1;
4015 int unit = -1;
4016 TCHAR *tmpp = _tcschr (value, ',');
4017 if (tmpp == NULL)
4018 return 1;
4019 *tmpp++ = 0;
4020 if (_tcsicmp (value, _T("hdf")) == 0) {
4021 type = 1;
4022 cfgfile_parse_partial_newfilesys (p, -1, type, tmpp, unit, true);
4023 return 1;
4024 } else if (_tcsnicmp (value, _T("cd"), 2) == 0 && (value[2] == 0 || value[3] == 0)) {
4025 unit = 0;
4026 if (value[2] > 0)
4027 unit = value[2] - '0';
4028 if (unit >= 0 && unit <= MAX_TOTAL_SCSI_DEVICES) {
4029 type = 2;
4030 }
4031 } else if (_tcsnicmp (value, _T("tape"), 4) == 0 && (value[4] == 0 || value[5] == 0)) {
4032 unit = 0;
4033 if (value[4] > 0)
4034 unit = value[4] - '0';
4035 if (unit >= 0 && unit <= MAX_TOTAL_SCSI_DEVICES) {
4036 type = 3;
4037 }
4038 } else if (_tcsicmp (value, _T("dir")) != 0) {
4039 type = 0;
4040 return 1; /* ignore for now */
4041 }
4042 if (type >= 0)
4043 cfgfile_parse_newfilesys (p, -1, type, tmpp, unit, true);
4044 return 1;
4045 }
4046 return 1;
4047 } else if (!_tcsncmp (option, tmp, _tcslen (tmp)) && option[_tcslen (tmp)] == '_') {
4048 struct uaedev_config_info *uci = &currprefs.mountconfig[i].ci;
4049 if (uci->devname) {
4050 const TCHAR *s = &option[_tcslen (tmp) + 1];
4051 if (!_tcscmp (s, _T("bootpri"))) {
4052 getintval (&value, &uci->bootpri, 0);
4053 } else if (!_tcscmp (s, _T("read-only"))) {
4054 cfgfile_yesno (NULL, value, NULL, &uci->readonly);
4055 } else if (!_tcscmp (s, _T("volumename"))) {
4056 _tcscpy (uci->volname, value);
4057 } else if (!_tcscmp (s, _T("devicename"))) {
4058 _tcscpy (uci->devname, value);
4059 } else if (!_tcscmp (s, _T("root"))) {
4060 _tcscpy (uci->rootdir, value);
4061 } else if (!_tcscmp (s, _T("filesys"))) {
4062 _tcscpy (uci->filesys, value);
4063 } else if (!_tcscmp (s, _T("controller"))) {
4064 get_filesys_controller (value, &uci->controller_type, &uci->controller_type_unit, &uci->controller_unit);
4065 }
4066 }
4067 }
4068 }
4069
4070 if (_tcscmp (option, _T("filesystem")) == 0
4071 || _tcscmp (option, _T("hardfile")) == 0)
4072 {
4073 struct uaedev_config_info uci;
4074 TCHAR *tmpp = _tcschr (value, ',');
4075 TCHAR *str;
4076 bool hdf;
4077
4078 uci_set_defaults (&uci, false);
4079
4080 if (config_newfilesystem)
4081 return 1;
4082
4083 if (tmpp == 0)
4084 goto invalid_fs;
4085
4086 *tmpp++ = '\0';
4087 if (_tcscmp (value, _T("1")) == 0 || strcasecmp (value, _T("ro")) == 0
4088 || strcasecmp (value, _T("readonly")) == 0
4089 || strcasecmp (value, _T("read-only")) == 0)
4090 uci.readonly = true;
4091 else if (_tcscmp (value, _T("0")) == 0 || strcasecmp (value, _T("rw")) == 0
4092 || strcasecmp (value, _T("readwrite")) == 0
4093 || strcasecmp (value, _T("read-write")) == 0)
4094 uci.readonly = false;
4095 else
4096 goto invalid_fs;
4097
4098 value = tmpp;
4099 if (_tcscmp (option, _T("filesystem")) == 0) {
4100 hdf = false;
4101 tmpp = _tcschr (value, ':');
4102 if (tmpp == 0)
4103 goto invalid_fs;
4104 *tmpp++ = '\0';
4105 _tcscpy (uci.volname, value);
4106 _tcscpy (uci.rootdir, tmpp);
4107 } else {
4108 hdf = true;
4109 if (! getintval (&value, &uci.sectors, ',')
4110 || ! getintval (&value, &uci.surfaces, ',')
4111 || ! getintval (&value, &uci.reserved, ',')
4112 || ! getintval (&value, &uci.blocksize, ','))
4113 goto invalid_fs;
4114 _tcscpy (uci.rootdir, value);
4115 }
4116 str = cfgfile_subst_path_load (UNEXPANDED, &p->path_hardfile, uci.rootdir, true);
4117 #ifdef FILESYS
4118 uci.type = hdf ? UAEDEV_HDF : UAEDEV_DIR;
4119 add_filesys_config (p, -1, &uci);
4120 #endif
4121 xfree (str);
4122 return 1;
4123 invalid_fs:
4124 cfgfile_warning(_T("Invalid filesystem/hardfile specification.\n"));
4125 return 1;
4126
4127 }
4128
4129 if (_tcscmp (option, _T("filesystem2")) == 0)
4130 return cfgfile_parse_newfilesys (p, -1, 0, value, -1, false);
4131 if (_tcscmp (option, _T("hardfile2")) == 0)
4132 return cfgfile_parse_newfilesys (p, -1, 1, value, -1, false);
4133 if (_tcscmp (option, _T("filesystem_extra")) == 0) {
4134 int idx = 0;
4135 TCHAR *s = value;
4136 _tcscat(s, _T(","));
4137 struct uaedev_config_info *ci = NULL;
4138 for (;;) {
4139 TCHAR *tmpp = _tcschr (s, ',');
4140 if (tmpp == NULL)
4141 return 1;
4142 *tmpp++ = 0;
4143 if (idx == 0) {
4144 for (i = 0; i < p->mountitems; i++) {
4145 if (p->mountconfig[i].ci.devname && !_tcscmp (p->mountconfig[i].ci.devname, s)) {
4146 ci = &p->mountconfig[i].ci;
4147 break;
4148 }
4149 }
4150 if (!ci || ci->type != UAEDEV_DIR)
4151 return 1;
4152 } else {
4153 bool b = true;
4154 TCHAR *tmpp2 = _tcschr(s, '=');
4155 if (tmpp2) {
4156 *tmpp2++ = 0;
4157 if (!strcasecmp(tmpp2, _T("false")))
4158 b = false;
4159 }
4160 if (!strcasecmp(s, _T("inject_icons"))) {
4161 ci->inject_icons = b;
4162 }
4163 }
4164 idx++;
4165 s = tmpp;
4166 }
4167 }
4168
4169 return 0;
4170 }
4171
cfgfile_board_enabled(struct uae_prefs * p,int romtype,int devnum)4172 bool cfgfile_board_enabled(struct uae_prefs *p, int romtype, int devnum)
4173 {
4174 int idx;
4175 if (romtype == ROMTYPE_CPUBOARD && currprefs.cpuboard_type)
4176 return true;
4177 struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx);
4178 if (!brc)
4179 return false;
4180 return brc->roms[idx].romfile[0] != 0;
4181 }
4182
cfgfile_read_board_rom(struct uae_prefs * p,const TCHAR * option,const TCHAR * value,struct multipath * mp)4183 static bool cfgfile_read_board_rom(struct uae_prefs *p, const TCHAR *option, const TCHAR *value, struct multipath *mp)
4184 {
4185 TCHAR buf[256], buf2[MAX_DPATH], buf3[MAX_DPATH];
4186 bool dummy;
4187 int val;
4188 const struct expansionromtype *ert;
4189
4190 for (int i = 0; expansionroms[i].name; i++) {
4191 struct boardromconfig *brc;
4192 int idx;
4193 ert = &expansionroms[i];
4194
4195 for (int j = 0; j < MAX_DUPLICATE_EXPANSION_BOARDS; j++) {
4196 TCHAR name[256];
4197
4198 if (j == 0)
4199 _tcscpy(name, ert->name);
4200 else
4201 _stprintf(name, _T("%s-%d"), ert->name, j + 1);
4202
4203 _stprintf(buf, _T("scsi_%s"), name);
4204 if (cfgfile_yesno(option, value, buf, &dummy)) {
4205 return true;
4206 }
4207
4208 _stprintf(buf, _T("%s_rom_file"), name);
4209 if (cfgfile_path(option, value, buf, buf2, MAX_DPATH / sizeof (TCHAR), mp)) {
4210 if (buf2[0]) {
4211 brc = get_device_rom_new(p, ert->romtype, j, &idx);
4212 _tcscpy(brc->roms[idx].romfile, buf2);
4213 }
4214 return true;
4215 }
4216
4217 _stprintf(buf, _T("%s_rom_file_id"), name);
4218 buf2[0] = 0;
4219 if (cfgfile_rom (option, value, buf, buf2, MAX_DPATH / sizeof (TCHAR))) {
4220 if (buf2[0]) {
4221 brc = get_device_rom_new(p, ert->romtype, j, &idx);
4222 _tcscpy(brc->roms[idx].romfile, buf2);
4223 }
4224 return true;
4225 }
4226
4227 _stprintf(buf, _T("%s_rom"), name);
4228 if (cfgfile_string (option, value, buf, buf2, sizeof buf2 / sizeof (TCHAR))) {
4229 if (buf2[0]) {
4230 decode_rom_ident (buf3, sizeof(buf3) / sizeof (TCHAR), buf2, ert->romtype);
4231 if (buf3[0]) {
4232 brc = get_device_rom_new(p, ert->romtype, j, &idx);
4233 _tcscpy(brc->roms[idx].romident, buf3);
4234 }
4235 }
4236 return true;
4237 }
4238
4239 _stprintf(buf, _T("%s_rom_options"), name);
4240 if (cfgfile_string (option, value, buf, buf2, sizeof buf2 / sizeof (TCHAR))) {
4241 brc = get_device_rom(p, ert->romtype, j, &idx);
4242 if (brc) {
4243 if (cfgfile_option_bool(buf2, _T("autoboot_disabled")) == 1) {
4244 brc->roms[idx].autoboot_disabled = true;
4245 }
4246 if (ert->settings) {
4247 brc->roms[idx].device_settings = cfgfile_read_rom_settings(ert->settings, buf2);
4248 }
4249 if (ert->id_jumper) {
4250 TCHAR *p = cfgfile_option_get(buf2, _T("id"));
4251 if (p) {
4252 brc->roms[idx].device_id = _tstol(p);
4253 }
4254 }
4255 if (ert->subtypes) {
4256 const struct expansionsubromtype *srt = ert->subtypes;
4257 TCHAR tmp[MAX_DPATH], *p;
4258 p = tmp;
4259 *p = 0;
4260 while (srt->name) {
4261 _tcscpy(p, srt->configname);
4262 p += _tcslen(p) + 1;
4263 p[0] = 0;
4264 srt++;
4265 }
4266 int v = cfgfile_option_select(buf2, _T("subtype"), tmp);
4267 if (v >= 0)
4268 brc->roms[idx].subtype = v;
4269 }
4270 }
4271 return true;
4272 }
4273 }
4274
4275 _stprintf(buf, _T("%s_mem_size"), ert->name);
4276 if (cfgfile_intval (option, value, buf, &val, 0x40000)) {
4277 if (val) {
4278 brc = get_device_rom_new(p, ert->romtype, 0, &idx);
4279 brc->roms[idx].board_ram_size = val;
4280 }
4281 return true;
4282 }
4283 }
4284 return false;
4285 }
4286
cfgfile_parse_hardware(struct uae_prefs * p,const TCHAR * option,TCHAR * value)4287 static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCHAR *value)
4288 {
4289 int tmpval, dummyint, i;
4290 bool dummybool;
4291 TCHAR tmpbuf[CONFIG_BLEN];
4292
4293 if (cfgfile_yesno (option, value, _T("cpu_cycle_exact"), &p->cpu_cycle_exact)) {
4294 /* we don't want cycle-exact in 68020/40+JIT modes */
4295 if (p->cpu_model >= 68020 && p->cachesize > 0)
4296 p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = 0;
4297 p->cpu_memory_cycle_exact = p->cpu_cycle_exact;
4298 return 1;
4299 }
4300 if (cfgfile_yesno (option, value, _T("blitter_cycle_exact"), &p->blitter_cycle_exact)) {
4301 if (p->cpu_model >= 68020 && p->cachesize > 0)
4302 p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = 0;
4303 return 1;
4304 }
4305 if (cfgfile_yesno (option, value, _T("cpu_memory_cycle_exact"), &p->cpu_memory_cycle_exact)) {
4306 if (!p->cpu_memory_cycle_exact)
4307 p->blitter_cycle_exact = p->cpu_cycle_exact = false;
4308 return 1;
4309 }
4310 if (cfgfile_strval (option, value, _T("cycle_exact"), &tmpval, cycleexact, 0)) {
4311 if (tmpval > 0) {
4312 p->blitter_cycle_exact = true;
4313 p->cpu_cycle_exact = tmpval > 1;
4314 p->cpu_memory_cycle_exact = true;
4315 } else {
4316 p->blitter_cycle_exact = false;
4317 p->cpu_cycle_exact = false;
4318 p->cpu_memory_cycle_exact = false;
4319 }
4320 if (p->cpu_model >= 68020 && p->cachesize > 0)
4321 p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = false;
4322 // if old version and CE and fastest possible: set to approximate
4323 if (p->cpu_cycle_exact && p->config_version < ((2 << 16) | (8 << 8) | (2 << 0)) && p->m68k_speed < 0)
4324 p->m68k_speed = 0;
4325 return 1;
4326 }
4327
4328 if (cfgfile_string (option, value, _T("cpu_multiplier"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
4329 p->cpu_clock_multiplier = (int)(_tstof (tmpbuf) * 256.0);
4330 return 1;
4331 }
4332
4333
4334 if (cfgfile_yesno (option, value, _T("scsi_a3000"), &dummybool)) {
4335 if (dummybool)
4336 p->cs_mbdmac = 1;
4337 return 1;
4338 }
4339 if (cfgfile_yesno (option, value, _T("scsi_a4000t"), &dummybool)) {
4340 if (dummybool)
4341 p->cs_mbdmac = 2;
4342 return 1;
4343 }
4344
4345 if (cfgfile_string(option, value, _T("a2065"), p->a2065name, sizeof p->a2065name / sizeof(TCHAR)))
4346 return 1;
4347 if (cfgfile_string(option, value, _T("ne2000_pci"), p->ne2000pciname, sizeof p->ne2000pciname / sizeof(TCHAR)))
4348 return 1;
4349
4350 if (cfgfile_yesno (option, value, _T("immediate_blits"), &p->immediate_blits)
4351 || cfgfile_yesno (option, value, _T("fpu_no_unimplemented"), &p->fpu_no_unimplemented)
4352 || cfgfile_yesno (option, value, _T("cpu_no_unimplemented"), &p->int_no_unimplemented)
4353 || cfgfile_yesno (option, value, _T("cd32cd"), &p->cs_cd32cd)
4354 || cfgfile_yesno (option, value, _T("cd32c2p"), &p->cs_cd32c2p)
4355 || cfgfile_yesno(option, value, _T("cd32nvram"), &p->cs_cd32nvram)
4356 || cfgfile_yesno(option, value, _T("cd32fmv"), &p->cs_cd32fmv)
4357 || cfgfile_yesno(option, value, _T("cdtvcd"), &p->cs_cdtvcd)
4358 || cfgfile_yesno(option, value, _T("cdtv-cr"), &p->cs_cdtvcr)
4359 || cfgfile_yesno (option, value, _T("cdtvram"), &p->cs_cdtvram)
4360 || cfgfile_yesno (option, value, _T("a1000ram"), &p->cs_a1000ram)
4361 || cfgfile_yesno (option, value, _T("pcmcia"), &p->cs_pcmcia)
4362 || cfgfile_yesno (option, value, _T("scsi_cdtv"), &p->cs_cdtvscsi)
4363 || cfgfile_yesno (option, value, _T("cia_overlay"), &p->cs_ciaoverlay)
4364 || cfgfile_yesno (option, value, _T("bogomem_fast"), &p->cs_slowmemisfast)
4365 || cfgfile_yesno (option, value, _T("ksmirror_e0"), &p->cs_ksmirror_e0)
4366 || cfgfile_yesno (option, value, _T("ksmirror_a8"), &p->cs_ksmirror_a8)
4367 || cfgfile_yesno (option, value, _T("resetwarning"), &p->cs_resetwarning)
4368 || cfgfile_yesno (option, value, _T("cia_todbug"), &p->cs_ciatodbug)
4369 || cfgfile_yesno (option, value, _T("denise_noehb"), &p->cs_denisenoehb)
4370 || cfgfile_yesno (option, value, _T("ics_agnus"), &p->cs_dipagnus)
4371 || cfgfile_yesno (option, value, _T("z3_autoconfig"), &p->cs_z3autoconfig)
4372 || cfgfile_yesno (option, value, _T("1mchipjumper"), &p->cs_1mchipjumper)
4373 || cfgfile_yesno (option, value, _T("agnus_bltbusybug"), &p->cs_agnusbltbusybug)
4374 || cfgfile_yesno (option, value, _T("fastmem_autoconfig"), &p->fastmem_autoconfig)
4375 || cfgfile_yesno (option, value, _T("gfxcard_hardware_vblank"), &p->rtg_hardwareinterrupt)
4376 || cfgfile_yesno (option, value, _T("gfxcard_hardware_sprite"), &p->rtg_hardwaresprite)
4377 || cfgfile_yesno (option, value, _T("synchronize_clock"), &p->tod_hack)
4378
4379 || cfgfile_yesno (option, value, _T("kickshifter"), &p->kickshifter)
4380 || cfgfile_yesno (option, value, _T("ks_write_enabled"), &p->rom_readwrite)
4381 || cfgfile_yesno (option, value, _T("ntsc"), &p->ntscmode)
4382 || cfgfile_yesno (option, value, _T("sana2"), &p->sana2)
4383 || cfgfile_yesno (option, value, _T("genlock"), &p->genlock)
4384 || cfgfile_yesno(option, value, _T("cpu_compatible"), &p->cpu_compatible)
4385 || cfgfile_yesno(option, value, _T("cpu_threaded"), &p->cpu_thread)
4386 || cfgfile_yesno(option, value, _T("cpu_24bit_addressing"), &p->address_space_24)
4387 || cfgfile_yesno(option, value, _T("cpu_reset_pause"), &p->reset_delay)
4388 || cfgfile_yesno(option, value, _T("parallel_on_demand"), &p->parallel_demand)
4389 || cfgfile_yesno (option, value, _T("parallel_postscript_emulation"), &p->parallel_postscript_emulation)
4390 || cfgfile_yesno (option, value, _T("parallel_postscript_detection"), &p->parallel_postscript_detection)
4391 || cfgfile_yesno (option, value, _T("serial_on_demand"), &p->serial_demand)
4392 || cfgfile_yesno (option, value, _T("serial_hardware_ctsrts"), &p->serial_hwctsrts)
4393 || cfgfile_yesno (option, value, _T("serial_direct"), &p->serial_direct)
4394 || cfgfile_yesno (option, value, _T("fpu_strict"), &p->fpu_strict)
4395 || cfgfile_yesno (option, value, _T("fpu_softfloat"), &p->fpu_softfloat)
4396 || cfgfile_yesno (option, value, _T("comp_nf"), &p->compnf)
4397 || cfgfile_yesno (option, value, _T("comp_constjump"), &p->comp_constjump)
4398 #ifdef USE_JIT_FPU
4399 || cfgfile_yesno (option, value, _T("compfpu"), &p->compfpu)
4400 #endif
4401 || cfgfile_yesno (option, value, _T("rtg_nocustom"), &p->picasso96_nocustom)
4402 || cfgfile_yesno (option, value, _T("floppy_write_protect"), &p->floppy_read_only)
4403 || cfgfile_yesno (option, value, _T("uae_hide_autoconfig"), &p->uae_hide_autoconfig)
4404 || cfgfile_yesno(option, value, _T("toccata"), &p->sound_toccata)
4405 || cfgfile_yesno(option, value, _T("es1370_pci"), &p->sound_es1370)
4406 || cfgfile_yesno(option, value, _T("fm801_pci"), &p->sound_fm801)
4407 || cfgfile_yesno (option, value, _T("toccata_mixer"), &p->sound_toccata_mixer)
4408 || cfgfile_yesno (option, value, _T("uaeserial"), &p->uaeserial))
4409 return 1;
4410
4411 #ifdef FSUAE // NL
4412 if (!g_fs_uae_jit_compiler) {
4413 if (cfgfile_intval(option, value, _T("cachesize"), &p->cachesize, 1)) {
4414 /* If FS-UAE wasn't started with JIT support initially, we cannot
4415 * enable it at a later time, since 32-bit memory may not be
4416 * configured. */
4417 if (p->cachesize) {
4418 error_log(_T("uae_cachesize set without jit_compiler"));
4419 p->cachesize = 0;
4420 return 1;
4421 }
4422 }
4423 }
4424 #endif
4425
4426 if (cfgfile_intval (option, value, _T("cachesize"), &p->cachesize, 1)
4427 || cfgfile_intval (option, value, _T("cd32nvram_size"), &p->cs_cd32nvram_size, 1024)
4428 || cfgfile_intval (option, value, _T("chipset_hacks"), &p->cs_hacks, 1)
4429 || cfgfile_intval (option, value, _T("serial_stopbits"), &p->serial_stopbits, 1)
4430 || cfgfile_intval (option, value, _T("cpu060_revision"), &p->cpu060_revision, 1)
4431 || cfgfile_intval (option, value, _T("fpu_revision"), &p->fpu_revision, 1)
4432 || cfgfile_intval (option, value, _T("cdtvramcard"), &p->cs_cdtvcard, 1)
4433 || cfgfile_intval (option, value, _T("fatgary"), &p->cs_fatgaryrev, 1)
4434 || cfgfile_intval (option, value, _T("ramsey"), &p->cs_ramseyrev, 1)
4435 || cfgfile_doubleval (option, value, _T("chipset_refreshrate"), &p->chipset_refreshrate)
4436 || cfgfile_intval(option, value, _T("cpuboardmem1_size"), &p->cpuboardmem1_size, 0x100000)
4437 || cfgfile_intval(option, value, _T("cpuboardmem2_size"), &p->cpuboardmem2_size, 0x100000)
4438 || cfgfile_intval(option, value, _T("fastmem_size"), &p->fastmem_size, 0x100000)
4439 || cfgfile_intval(option, value, _T("fastmem_size_k"), &p->fastmem_size, 1024)
4440 || cfgfile_intval (option, value, _T("fastmem2_size"), &p->fastmem2_size, 0x100000)
4441 || cfgfile_intval (option, value, _T("fastmem2_size_k"), &p->fastmem2_size, 1024)
4442 || cfgfile_intval (option, value, _T("mem25bit_size"), &p->mem25bit_size, 0x100000)
4443 || cfgfile_intval (option, value, _T("a3000mem_size"), &p->mbresmem_low_size, 0x100000)
4444 || cfgfile_intval (option, value, _T("mbresmem_size"), &p->mbresmem_high_size, 0x100000)
4445 || cfgfile_intval (option, value, _T("z3mem_size"), &p->z3fastmem_size, 0x100000)
4446 || cfgfile_intval (option, value, _T("z3mem2_size"), &p->z3fastmem2_size, 0x100000)
4447 || cfgfile_intval (option, value, _T("megachipmem_size"), &p->z3chipmem_size, 0x100000)
4448 || cfgfile_intval (option, value, _T("z3mem_start"), &p->z3autoconfig_start, 1)
4449 || cfgfile_intval (option, value, _T("bogomem_size"), &p->bogomem_size, 0x40000)
4450 || cfgfile_intval (option, value, _T("gfxcard_size"), &p->rtgmem_size, 0x100000)
4451 || cfgfile_intval(option, value, _T("rtg_modes"), &p->picasso96_modeflags, 1)
4452 || cfgfile_intval (option, value, _T("floppy_speed"), &p->floppy_speed, 1)
4453 || cfgfile_intval (option, value, _T("cd_speed"), &p->cd_speed, 1)
4454 || cfgfile_intval (option, value, _T("floppy_write_length"), &p->floppy_write_length, 1)
4455 || cfgfile_intval (option, value, _T("floppy_random_bits_min"), &p->floppy_random_bits_min, 1)
4456 || cfgfile_intval (option, value, _T("floppy_random_bits_max"), &p->floppy_random_bits_max, 1)
4457 || cfgfile_intval (option, value, _T("nr_floppies"), &p->nr_floppies, 1)
4458 || cfgfile_intval (option, value, _T("floppy0type"), &p->floppyslots[0].dfxtype, 1)
4459 || cfgfile_intval (option, value, _T("floppy1type"), &p->floppyslots[1].dfxtype, 1)
4460 || cfgfile_intval (option, value, _T("floppy2type"), &p->floppyslots[2].dfxtype, 1)
4461 || cfgfile_intval (option, value, _T("floppy3type"), &p->floppyslots[3].dfxtype, 1)
4462 || cfgfile_intval (option, value, _T("maprom"), &p->maprom, 1)
4463 || cfgfile_intval (option, value, _T("parallel_autoflush"), &p->parallel_autoflush_time, 1)
4464 || cfgfile_intval (option, value, _T("uae_hide"), &p->uae_hide, 1)
4465 || cfgfile_intval (option, value, _T("cpu_frequency"), &p->cpu_frequency, 1)
4466 || cfgfile_intval(option, value, _T("kickstart_ext_rom_file2addr"), &p->romextfile2addr, 1)
4467 || cfgfile_intval(option, value, _T("genlock_mix"), &p->genlock_mix, 1)
4468 || cfgfile_intval(option, value, _T("uaeboard_mode"), &p->uaeboard, 1)
4469 || cfgfile_intval (option, value, _T("catweasel"), &p->catweasel, 1))
4470 return 1;
4471
4472 if (cfgfile_strval (option, value, _T("comp_trustbyte"), &p->comptrustbyte, compmode, 0)
4473 || cfgfile_strval (option, value, _T("rtc"), &p->cs_rtc, rtctype, 0)
4474 || cfgfile_strval (option, value, _T("ciaatod"), &p->cs_ciaatod, ciaatodmode, 0)
4475 || cfgfile_strval (option, value, _T("ide"), &p->cs_ide, idemode, 0)
4476 || cfgfile_strval (option, value, _T("scsi"), &p->scsi, scsimode, 0)
4477 || cfgfile_strval (option, value, _T("comp_trustword"), &p->comptrustword, compmode, 0)
4478 || cfgfile_strval (option, value, _T("comp_trustlong"), &p->comptrustlong, compmode, 0)
4479 || cfgfile_strval (option, value, _T("comp_trustnaddr"), &p->comptrustnaddr, compmode, 0)
4480 || cfgfile_strval (option, value, _T("collision_level"), &p->collision_level, collmode, 0)
4481 || cfgfile_strval (option, value, _T("parallel_matrix_emulation"), &p->parallel_matrix_emulation, epsonprinter, 0)
4482 || cfgfile_strval(option, value, _T("monitoremu"), &p->monitoremu, specialmonitors, 0)
4483 || cfgfile_strval(option, value, _T("genlockmode"), &p->genlock_image, genlockmodes, 0)
4484 || cfgfile_strval (option, value, _T("waiting_blits"), &p->waiting_blits, waitblits, 0)
4485 || cfgfile_strval (option, value, _T("floppy_auto_extended_adf"), &p->floppy_auto_ext2, autoext2, 0)
4486 || cfgfile_strval (option, value, _T("z3mapping"), &p->z3_mapping_mode, z3mapping, 0)
4487 || cfgfile_strval (option, value, _T("scsidev_mode"), &p->uaescsidevmode, uaescsidevmodes, 0)
4488 || cfgfile_strval (option, value, _T("boot_rom_uae"), &p->boot_rom, uaebootrom, 0)
4489 || cfgfile_strval (option, value, _T("serial_translate"), &p->serial_crlf, serialcrlf, 0)
4490 || cfgfile_strboolval (option, value, _T("comp_flushmode"), &p->comp_hardflush, flushmode, 0))
4491 return 1;
4492
4493 if (cfgfile_path (option, value, _T("kickstart_rom_file"), p->romfile, sizeof p->romfile / sizeof (TCHAR), &p->path_rom)
4494 || cfgfile_path (option, value, _T("kickstart_ext_rom_file"), p->romextfile, sizeof p->romextfile / sizeof (TCHAR), &p->path_rom)
4495 || cfgfile_path (option, value, _T("kickstart_ext_rom_file2"), p->romextfile2, sizeof p->romextfile2 / sizeof (TCHAR), &p->path_rom)
4496 || cfgfile_rom(option, value, _T("kickstart_rom_file_id"), p->romfile, sizeof p->romfile / sizeof(TCHAR))
4497 || cfgfile_rom (option, value, _T("kickstart_ext_rom_file_id"), p->romextfile, sizeof p->romextfile / sizeof (TCHAR))
4498 || cfgfile_path (option, value, _T("flash_file"), p->flashfile, sizeof p->flashfile / sizeof (TCHAR), &p->path_rom)
4499 || cfgfile_path (option, value, _T("cart_file"), p->cartfile, sizeof p->cartfile / sizeof (TCHAR), &p->path_rom)
4500 || cfgfile_path (option, value, _T("rtc_file"), p->rtcfile, sizeof p->rtcfile / sizeof (TCHAR), &p->path_rom)
4501 || cfgfile_path(option, value, _T("picassoiv_rom_file"), p->picassoivromfile, sizeof p->picassoivromfile / sizeof(TCHAR), &p->path_rom)
4502 || cfgfile_string(option, value, _T("genlock_image"), p->genlock_image_file, sizeof p->genlock_image_file / sizeof(TCHAR))
4503 || cfgfile_string(option, value, _T ("pci_devices"), p->pci_devices, sizeof p->pci_devices / sizeof(TCHAR))
4504 || cfgfile_string (option, value, _T("ghostscript_parameters"), p->ghostscript_parameters, sizeof p->ghostscript_parameters / sizeof (TCHAR)))
4505 return 1;
4506
4507 if (cfgfile_string(option, value, _T("gfxcard_type"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) {
4508 p->rtgmem_type = 0;
4509 i = 0;
4510 for (;;) {
4511 const TCHAR *t = gfxboard_get_configname(i);
4512 if (!t)
4513 break;
4514 if (!_tcsicmp(t, tmpbuf)) {
4515 p->rtgmem_type = i;
4516 break;
4517 }
4518 i++;
4519 }
4520 return 1;
4521 }
4522
4523
4524 if (cfgfile_string(option, value, _T("cpuboard_type"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) {
4525 p->cpuboard_type = 0;
4526 p->cpuboard_subtype = 0;
4527 for (i = 0; cpuboards[i].name && !p->cpuboard_type; i++) {
4528 const struct cpuboardtype *cbt = &cpuboards[i];
4529 if (cbt->subtypes) {
4530 for (int j = 0; cbt->subtypes[j].name; j++) {
4531 if (!_tcsicmp(cbt->subtypes[j].configname, tmpbuf)) {
4532 p->cpuboard_type = i;
4533 p->cpuboard_subtype = j;
4534 }
4535 }
4536 }
4537 }
4538 return 1;
4539 }
4540 if (cfgfile_string(option, value, _T("cpuboard_settings"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) {
4541 p->cpuboard_settings = 0;
4542 const struct cpuboardsubtype *cbst = &cpuboards[p->cpuboard_type].subtypes[p->cpuboard_subtype];
4543 if (cbst->settings) {
4544 const struct expansionboardsettings *cbs = cbst->settings;
4545 for(i = 0; cbs[i].name; i++) {
4546 if (cfgfile_option_find(tmpbuf, cbs[i].configname)) {
4547 p->cpuboard_settings |= 1 << (i + cbs[i].bitshift);
4548 break;
4549 }
4550 }
4551 }
4552 return 1;
4553 }
4554
4555 if (cfgfile_strval (option, value, _T("chipset_compatible"), &p->cs_compatible, cscompa, 0)) {
4556 built_in_chipset_prefs (p);
4557 return 1;
4558 }
4559
4560 if (cfgfile_strval (option, value, _T("cart_internal"), &p->cart_internal, cartsmode, 0)) {
4561 if (p->cart_internal) {
4562 struct romdata *rd = getromdatabyid (63);
4563 if (rd)
4564 _stprintf (p->cartfile, _T(":%s"), rd->configname);
4565 }
4566 return 1;
4567 }
4568 if (cfgfile_string (option, value, _T("kickstart_rom"), p->romident, sizeof p->romident / sizeof (TCHAR))) {
4569 decode_rom_ident (p->romfile, sizeof p->romfile / sizeof (TCHAR), p->romident, ROMTYPE_ALL_KICK);
4570 return 1;
4571 }
4572 if (cfgfile_string (option, value, _T("kickstart_ext_rom"), p->romextident, sizeof p->romextident / sizeof (TCHAR))) {
4573 decode_rom_ident (p->romextfile, sizeof p->romextfile / sizeof (TCHAR), p->romextident, ROMTYPE_ALL_EXT);
4574 return 1;
4575 }
4576
4577 if (cfgfile_string (option, value, _T("cart"), p->cartident, sizeof p->cartident / sizeof (TCHAR))) {
4578 decode_rom_ident (p->cartfile, sizeof p->cartfile / sizeof (TCHAR), p->cartident, ROMTYPE_ALL_CART);
4579 #ifdef FSUAE
4580 write_log("Cartridge file: %s\n", p->cartfile);
4581 #endif
4582 return 1;
4583 }
4584
4585 if (cfgfile_read_board_rom(p, option, value, &p->path_rom))
4586 return 1;
4587
4588 for (i = 0; i < 4; i++) {
4589 _stprintf (tmpbuf, _T("floppy%d"), i);
4590 if (cfgfile_path (option, value, tmpbuf, p->floppyslots[i].df, sizeof p->floppyslots[i].df / sizeof (TCHAR), &p->path_floppy))
4591 return 1;
4592 }
4593
4594 if (cfgfile_intval (option, value, _T("chipmem_size"), &dummyint, 1)) {
4595 if (dummyint < 0)
4596 p->chipmem_size = 0x20000; /* 128k, prototype support */
4597 else if (dummyint == 0)
4598 p->chipmem_size = 0x40000; /* 256k */
4599 else
4600 p->chipmem_size = dummyint * 0x80000;
4601 return 1;
4602 }
4603
4604 if (cfgfile_string (option, value, _T("addmem1"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
4605 parse_addmem (p, tmpbuf, 0);
4606 return 1;
4607 }
4608 if (cfgfile_string (option, value, _T("addmem2"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
4609 parse_addmem (p, tmpbuf, 1);
4610 return 1;
4611 }
4612
4613 if (cfgfile_strval (option, value, _T("chipset"), &tmpval, csmode, 0)) {
4614 set_chipset_mask (p, tmpval);
4615 return 1;
4616 }
4617
4618 if (cfgfile_string (option, value, _T("mmu_model"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
4619 p->mmu_model = _tstol (tmpbuf);
4620 return 1;
4621 }
4622
4623 if (cfgfile_string (option, value, _T("fpu_model"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
4624 p->fpu_model = _tstol (tmpbuf);
4625 return 1;
4626 }
4627
4628 if (cfgfile_string (option, value, _T("cpu_model"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
4629 p->cpu_model = _tstol (tmpbuf);
4630 p->fpu_model = 0;
4631 return 1;
4632 }
4633
4634 if (cfgfile_strval(option, value, _T("ppc_implementation"), &p->ppc_implementation, ppc_implementations, 0))
4635 return 1;
4636 if (cfgfile_string(option, value, _T("ppc_model"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) {
4637 p->ppc_mode = 0;
4638 p->ppc_model[0] = 0;
4639 if (!_tcsicmp(tmpbuf, _T("automatic"))) {
4640 p->ppc_mode = 1;
4641 } else if (!_tcsicmp(tmpbuf, _T("manual"))) {
4642 p->ppc_mode = 2;
4643 } else {
4644 if (tmpbuf[0] && _tcslen(tmpbuf) < sizeof(p->ppc_model) / sizeof(TCHAR)) {
4645 _tcscpy(p->ppc_model, tmpbuf);
4646 p->ppc_mode = 2;
4647 }
4648 }
4649 return 1;
4650 }
4651 if (cfgfile_strval(option, value, _T("ppc_cpu_idle"), &p->ppc_cpu_idle, ppc_cpu_idle, 0))
4652 return 1;
4653
4654 /* old-style CPU configuration */
4655 if (cfgfile_string (option, value, _T("cpu_type"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
4656 // 68000/010 32-bit addressing was not available until 2.8.2
4657 bool force24bit = p->config_version <= ((2 << 16) | (8 << 8) | (1 << 0));
4658 p->fpu_model = 0;
4659 p->address_space_24 = 0;
4660 p->cpu_model = 680000;
4661 if (!_tcscmp (tmpbuf, _T("68000"))) {
4662 p->cpu_model = 68000;
4663 if (force24bit)
4664 p->address_space_24 = 1;
4665 } else if (!_tcscmp (tmpbuf, _T("68010"))) {
4666 p->cpu_model = 68010;
4667 if (force24bit)
4668 p->address_space_24 = 1;
4669 } else if (!_tcscmp (tmpbuf, _T("68ec020"))) {
4670 p->cpu_model = 68020;
4671 } else if (!_tcscmp (tmpbuf, _T("68020"))) {
4672 p->cpu_model = 68020;
4673 } else if (!_tcscmp (tmpbuf, _T("68ec020/68881"))) {
4674 p->cpu_model = 68020;
4675 p->fpu_model = 68881;
4676 p->address_space_24 = 1;
4677 } else if (!_tcscmp (tmpbuf, _T("68020/68881"))) {
4678 p->cpu_model = 68020;
4679 p->fpu_model = 68881;
4680 } else if (!_tcscmp (tmpbuf, _T("68040"))) {
4681 p->cpu_model = 68040;
4682 p->fpu_model = 68040;
4683 } else if (!_tcscmp (tmpbuf, _T("68060"))) {
4684 p->cpu_model = 68060;
4685 p->fpu_model = 68060;
4686 }
4687 return 1;
4688 }
4689
4690 /* Broken earlier versions used to write this out as a string. */
4691 if (cfgfile_strval (option, value, _T("finegraincpu_speed"), &p->m68k_speed, speedmode, 1)) {
4692 p->m68k_speed--;
4693 return 1;
4694 }
4695
4696 if (cfgfile_strval (option, value, _T("cpu_speed"), &p->m68k_speed, speedmode, 1)) {
4697 p->m68k_speed--;
4698 return 1;
4699 }
4700 if (cfgfile_intval (option, value, _T("cpu_speed"), &p->m68k_speed, 1)) {
4701 p->m68k_speed *= CYCLE_UNIT;
4702 return 1;
4703 }
4704 if (cfgfile_doubleval(option, value, _T("cpu_throttle"), &p->m68k_speed_throttle)) {
4705 return 1;
4706 }
4707 if (cfgfile_doubleval(option, value, _T("cpu_x86_throttle"), &p->x86_speed_throttle)) {
4708 return 1;
4709 }
4710 if (cfgfile_intval (option, value, _T("finegrain_cpu_speed"), &p->m68k_speed, 1)) {
4711 if (OFFICIAL_CYCLE_UNIT > CYCLE_UNIT) {
4712 int factor = OFFICIAL_CYCLE_UNIT / CYCLE_UNIT;
4713 p->m68k_speed = (p->m68k_speed + factor - 1) / factor;
4714 }
4715 if (strcasecmp (value, _T("max")) == 0)
4716 p->m68k_speed = -1;
4717 return 1;
4718 }
4719
4720 if (cfgfile_intval (option, value, _T("dongle"), &p->dongle, 1)) {
4721 if (p->dongle == 0)
4722 cfgfile_strval (option, value, _T("dongle"), &p->dongle, dongles, 0);
4723 return 1;
4724 }
4725
4726 if (strcasecmp (option, _T("quickstart")) == 0) {
4727 int model = 0;
4728 TCHAR *tmpp = _tcschr (value, ',');
4729 if (tmpp) {
4730 *tmpp++ = 0;
4731 TCHAR *tmpp2 = _tcschr (value, ',');
4732 if (tmpp2)
4733 *tmpp2 = 0;
4734 cfgfile_strval (option, value, option, &model, qsmodes, 0);
4735 if (model >= 0) {
4736 int config = _tstol (tmpp);
4737 built_in_prefs (p, model, config, 0, 0);
4738 }
4739 }
4740 return 1;
4741 }
4742
4743 if (cfgfile_parse_filesys (p, option, value))
4744 return 1;
4745
4746 return 0;
4747 }
4748
4749
4750 static bool createconfigstore (struct uae_prefs*);
4751 static int getconfigstoreline (const TCHAR *option, TCHAR *value);
4752
calcformula(struct uae_prefs * prefs,TCHAR * in)4753 static void calcformula (struct uae_prefs *prefs, TCHAR *in)
4754 {
4755 TCHAR out[MAX_DPATH], configvalue[CONFIG_BLEN];
4756 TCHAR *p = out;
4757 double val;
4758 int cnt1, cnt2;
4759 static bool updatestore;
4760
4761 if (_tcslen (in) < 2 || in[0] != '[' || in[_tcslen (in) - 1] != ']')
4762 return;
4763 if (!configstore || updatestore)
4764 createconfigstore (prefs);
4765 updatestore = false;
4766 if (!configstore)
4767 return;
4768 cnt1 = cnt2 = 0;
4769 for (int i = 1; i < _tcslen (in) - 1; i++) {
4770 TCHAR c = _totupper (in[i]);
4771 if (c >= 'A' && c <='Z') {
4772 TCHAR *start = &in[i];
4773 while (_istalnum (c) || c == '_' || c == '.') {
4774 i++;
4775 c = in[i];
4776 }
4777 TCHAR store = in[i];
4778 in[i] = 0;
4779 //write_log (_T("'%s'\n"), start);
4780 if (!getconfigstoreline (start, configvalue))
4781 return;
4782 _tcscpy (p, configvalue);
4783 p += _tcslen (p);
4784 in[i] = store;
4785 i--;
4786 cnt1++;
4787 } else {
4788 cnt2++;
4789 *p ++= c;
4790 }
4791 }
4792 *p = 0;
4793 if (cnt1 == 0 && cnt2 == 0)
4794 return;
4795 /* single config entry only? */
4796 if (cnt1 == 1 && cnt2 == 0) {
4797 _tcscpy (in, out);
4798 updatestore = true;
4799 return;
4800 }
4801 if (calc (out, &val)) {
4802 if (val - (int)val != 0.0f)
4803 _stprintf (in, _T("%f"), val);
4804 else
4805 _stprintf (in, _T("%d"), (int)val);
4806 updatestore = true;
4807 return;
4808 }
4809 }
4810
cfgfile_parse_option(struct uae_prefs * p,const TCHAR * option,TCHAR * value,int type)4811 int cfgfile_parse_option (struct uae_prefs *p, const TCHAR *option, TCHAR *value, int type)
4812 {
4813 calcformula (p, value);
4814
4815 if (!_tcscmp (option, _T("debug"))) {
4816 write_log (_T("CONFIG DEBUG: '%s'\n"), value);
4817 return 1;
4818 }
4819 if (!_tcscmp (option, _T("config_hardware")))
4820 return 1;
4821 if (!_tcscmp (option, _T("config_host")))
4822 return 1;
4823 if (cfgfile_path (option, value, _T("config_all_path"), p->config_all_path, sizeof p->config_all_path / sizeof(TCHAR)))
4824 return 1;
4825 if (cfgfile_path (option, value, _T("config_hardware_path"), p->config_hardware_path, sizeof p->config_hardware_path / sizeof (TCHAR)))
4826 return 1;
4827 if (cfgfile_path (option, value, _T("config_host_path"), p->config_host_path, sizeof p->config_host_path / sizeof(TCHAR)))
4828 return 1;
4829 if (type == 0 || (type & CONFIG_TYPE_HARDWARE)) {
4830 if (cfgfile_parse_hardware (p, option, value))
4831 return 1;
4832 }
4833 if (type == 0 || (type & CONFIG_TYPE_HOST)) {
4834 // cfgfile_parse_host may modify the option (convert to lowercase).
4835 TCHAR* writable_option = my_strdup(option);
4836 if (cfgfile_parse_host (p, writable_option, value)) {
4837 free(writable_option);
4838 return 1;
4839 }
4840 free(writable_option);
4841 }
4842 if (type > 0 && (type & (CONFIG_TYPE_HARDWARE | CONFIG_TYPE_HOST)) != (CONFIG_TYPE_HARDWARE | CONFIG_TYPE_HOST))
4843 return 1;
4844 return 0;
4845 }
4846
isutf8ext(TCHAR * s)4847 static int isutf8ext (TCHAR *s)
4848 {
4849 if (_tcslen (s) > _tcslen (UTF8NAME) && !_tcscmp (s + _tcslen (s) - _tcslen (UTF8NAME), UTF8NAME)) {
4850 s[_tcslen (s) - _tcslen (UTF8NAME)] = 0;
4851 return 1;
4852 }
4853 return 0;
4854 }
4855
cfgfile_separate_linea(const TCHAR * filename,char * line,TCHAR * line1b,TCHAR * line2b)4856 static int cfgfile_separate_linea (const TCHAR *filename, char *line, TCHAR *line1b, TCHAR *line2b)
4857 {
4858 char *line1, *line2;
4859 int i;
4860
4861 line1 = line;
4862 line1 += strspn (line1, "\t \r\n");
4863 if (*line1 == ';')
4864 return 0;
4865 line2 = strchr (line, '=');
4866 if (! line2) {
4867 TCHAR *s = au (line1);
4868 cfgfile_warning(_T("CFGFILE: '%s', linea was incomplete with only %s\n"), filename, s);
4869 xfree (s);
4870 return 0;
4871 }
4872 *line2++ = '\0';
4873
4874 /* Get rid of whitespace. */
4875 i = strlen (line2);
4876 while (i > 0 && (line2[i - 1] == '\t' || line2[i - 1] == ' '
4877 || line2[i - 1] == '\r' || line2[i - 1] == '\n'))
4878 line2[--i] = '\0';
4879 line2 += strspn (line2, "\t \r\n");
4880
4881 i = strlen (line);
4882 while (i > 0 && (line[i - 1] == '\t' || line[i - 1] == ' '
4883 || line[i - 1] == '\r' || line[i - 1] == '\n'))
4884 line[--i] = '\0';
4885 line += strspn (line, "\t \r\n");
4886 au_copy (line1b, MAX_DPATH, line);
4887 if (isutf8ext (line1b)) {
4888 if (line2[0]) {
4889 TCHAR *s = utf8u (line2);
4890 _tcscpy (line2b, s);
4891 xfree (s);
4892 }
4893 } else {
4894 au_copy (line2b, MAX_DPATH, line2);
4895 }
4896 return 1;
4897 }
4898
cfgfile_separate_line(TCHAR * line,TCHAR * line1b,TCHAR * line2b)4899 static int cfgfile_separate_line (TCHAR *line, TCHAR *line1b, TCHAR *line2b)
4900 {
4901 TCHAR *line1, *line2;
4902 int i;
4903
4904 line1 = line;
4905 line1 += _tcsspn (line1, _T("\t \r\n"));
4906 if (*line1 == ';')
4907 return 0;
4908 line2 = _tcschr (line, '=');
4909 if (! line2) {
4910 cfgfile_warning(_T("CFGFILE: line was incomplete with only %s\n"), line1);
4911 return 0;
4912 }
4913 *line2++ = '\0';
4914
4915 /* Get rid of whitespace. */
4916 i = _tcslen (line2);
4917 while (i > 0 && (line2[i - 1] == '\t' || line2[i - 1] == ' '
4918 || line2[i - 1] == '\r' || line2[i - 1] == '\n'))
4919 line2[--i] = '\0';
4920 line2 += _tcsspn (line2, _T("\t \r\n"));
4921 _tcscpy (line2b, line2);
4922 i = _tcslen (line);
4923 while (i > 0 && (line[i - 1] == '\t' || line[i - 1] == ' '
4924 || line[i - 1] == '\r' || line[i - 1] == '\n'))
4925 line[--i] = '\0';
4926 line += _tcsspn (line, _T("\t \r\n"));
4927 _tcscpy (line1b, line);
4928
4929 if (line2b[0] == '"' || line2b[0] == '\"') {
4930 TCHAR c = line2b[0];
4931 int i = 0;
4932 memmove (line2b, line2b + 1, (_tcslen (line2b) + 1) * sizeof (TCHAR));
4933 while (line2b[i] != 0 && line2b[i] != c)
4934 i++;
4935 line2b[i] = 0;
4936 }
4937
4938 if (isutf8ext (line1b))
4939 return 0;
4940 return 1;
4941 }
4942
isobsolete(TCHAR * s)4943 static int isobsolete (TCHAR *s)
4944 {
4945 int i = 0;
4946 while (obsolete[i]) {
4947 if (!strcasecmp (s, obsolete[i])) {
4948 cfgfile_warning_obsolete(_T("obsolete config entry '%s'\n"), s);
4949 return 1;
4950 }
4951 i++;
4952 }
4953 if (_tcslen (s) > 2 && !_tcsncmp (s, _T("w."), 2))
4954 return 1;
4955 if (_tcslen (s) >= 10 && !_tcsncmp (s, _T("gfx_opengl"), 10)) {
4956 cfgfile_warning_obsolete(_T("obsolete config entry '%s\n"), s);
4957 return 1;
4958 }
4959 if (_tcslen (s) >= 6 && !_tcsncmp (s, _T("gfx_3d"), 6)) {
4960 cfgfile_warning_obsolete(_T("obsolete config entry '%s\n"), s);
4961 return 1;
4962 }
4963 return 0;
4964 }
4965
cfgfile_parse_separated_line(struct uae_prefs * p,TCHAR * line1b,TCHAR * line2b,int type)4966 static void cfgfile_parse_separated_line (struct uae_prefs *p, TCHAR *line1b, TCHAR *line2b, int type)
4967 {
4968 TCHAR line3b[CONFIG_BLEN], line4b[CONFIG_BLEN];
4969 struct strlist *sl;
4970 int ret;
4971
4972 _tcscpy (line3b, line1b);
4973 _tcscpy (line4b, line2b);
4974 ret = cfgfile_parse_option (p, line1b, line2b, type);
4975 if (!isobsolete (line3b)) {
4976 for (sl = p->all_lines; sl; sl = sl->next) {
4977 if (sl->option && !strcasecmp (line1b, sl->option)) break;
4978 }
4979 if (!sl) {
4980 struct strlist *u = xcalloc (struct strlist, 1);
4981 u->option = my_strdup (line3b);
4982 u->value = my_strdup (line4b);
4983 u->next = p->all_lines;
4984 p->all_lines = u;
4985 if (!ret) {
4986 u->unknown = 1;
4987 cfgfile_warning(_T("unknown config entry: '%s=%s'\n"), u->option, u->value);
4988 }
4989 }
4990 }
4991 }
4992
cfgfile_parse_lines(struct uae_prefs * p,const TCHAR * lines,int type)4993 void cfgfile_parse_lines (struct uae_prefs *p, const TCHAR *lines, int type)
4994 {
4995 TCHAR *buf = my_strdup (lines);
4996 TCHAR *t = buf;
4997 for (;;) {
4998 if (_tcslen (t) == 0)
4999 break;
5000 TCHAR *t2 = _tcschr (t, '\n');
5001 if (t2)
5002 *t2 = 0;
5003 cfgfile_parse_line (p, t, type);
5004 if (!t2)
5005 break;
5006 t = t2 + 1;
5007 }
5008 xfree (buf);
5009 }
5010
cfgfile_parse_line(struct uae_prefs * p,TCHAR * line,int type)5011 void cfgfile_parse_line (struct uae_prefs *p, TCHAR *line, int type)
5012 {
5013 TCHAR line1b[CONFIG_BLEN], line2b[CONFIG_BLEN];
5014
5015 if (!cfgfile_separate_line (line, line1b, line2b))
5016 return;
5017 cfgfile_parse_separated_line (p, line1b, line2b, type);
5018 }
5019
subst(TCHAR * p,TCHAR * f,int n)5020 static void subst (TCHAR *p, TCHAR *f, int n)
5021 {
5022 if (_tcslen(p) == 0 || _tcslen(f) == 0)
5023 return;
5024 TCHAR *str = cfgfile_subst_path (UNEXPANDED, p, f);
5025 _tcsncpy (f, str, n - 1);
5026 f[n - 1] = '\0';
5027 free (str);
5028 }
5029
getconfigstoreline(const TCHAR * option,TCHAR * value)5030 static int getconfigstoreline (const TCHAR *option, TCHAR *value)
5031 {
5032 TCHAR tmp[CONFIG_BLEN * 2], tmp2[CONFIG_BLEN * 2];
5033
5034 if (!configstore)
5035 return 0;
5036 zfile_fseek (configstore, 0, SEEK_SET);
5037 for (;;) {
5038 if (!zfile_fgets (tmp, sizeof tmp / sizeof (TCHAR), configstore))
5039 return 0;
5040 if (!cfgfile_separate_line (tmp, tmp2, value))
5041 continue;
5042 if (!_tcsicmp (option, tmp2))
5043 return 1;
5044 }
5045 }
5046
createconfigstore(struct uae_prefs * p)5047 static bool createconfigstore (struct uae_prefs *p)
5048 {
5049 uae_u8 zeros[4] = { 0 };
5050 zfile_fclose (configstore);
5051 configstore = zfile_fopen_empty (NULL, _T("configstore"), 50000);
5052 if (!configstore)
5053 return false;
5054 zfile_fseek (configstore, 0, SEEK_SET);
5055 uaeconfig++;
5056 cfgfile_save_options (configstore, p, 0);
5057 uaeconfig--;
5058 zfile_fwrite (zeros, 1, sizeof zeros, configstore);
5059 zfile_fseek (configstore, 0, SEEK_SET);
5060 return true;
5061 }
5062
cfg_fgets(char * line,int max,struct zfile * fh)5063 static char *cfg_fgets (char *line, int max, struct zfile *fh)
5064 {
5065 #ifdef SINGLEFILE
5066 extern TCHAR singlefile_config[];
5067 static TCHAR *sfile_ptr;
5068 TCHAR *p;
5069 #endif
5070
5071 if (fh)
5072 return zfile_fgetsa (line, max, fh);
5073 #ifdef SINGLEFILE
5074 if (sfile_ptr == 0) {
5075 sfile_ptr = singlefile_config;
5076 if (*sfile_ptr) {
5077 write_log (_T("singlefile config found\n"));
5078 while (*sfile_ptr++);
5079 }
5080 }
5081 if (*sfile_ptr == 0) {
5082 sfile_ptr = singlefile_config;
5083 return 0;
5084 }
5085 p = sfile_ptr;
5086 while (*p != 13 && *p != 10 && *p != 0) p++;
5087 memset (line, 0, max);
5088 memcpy (line, sfile_ptr, (p - sfile_ptr) * sizeof (TCHAR));
5089 sfile_ptr = p + 1;
5090 if (*sfile_ptr == 13)
5091 sfile_ptr++;
5092 if (*sfile_ptr == 10)
5093 sfile_ptr++;
5094 return line;
5095 #endif
5096 return 0;
5097 }
5098
cfgfile_load_2(struct uae_prefs * p,const TCHAR * filename,bool real,int * type)5099 static int cfgfile_load_2 (struct uae_prefs *p, const TCHAR *filename, bool real, int *type)
5100 {
5101 int i;
5102 struct zfile *fh;
5103 char linea[CONFIG_BLEN];
5104 TCHAR line[CONFIG_BLEN], line1b[CONFIG_BLEN], line2b[CONFIG_BLEN];
5105 struct strlist *sl;
5106 bool type1 = false, type2 = false;
5107 int askedtype = 0;
5108
5109 if (type) {
5110 askedtype = *type;
5111 *type = 0;
5112 }
5113 if (real) {
5114 p->config_version = 0;
5115 config_newfilesystem = 0;
5116 inputdevice_config_load_start(p);
5117 //reset_inputdevice_config (p);
5118 }
5119
5120 fh = zfile_fopen (filename, _T("r"), ZFD_NORMAL);
5121 #ifndef SINGLEFILE
5122 if (! fh)
5123 return 0;
5124 #endif
5125
5126 while (cfg_fgets (linea, sizeof (linea), fh) != 0) {
5127 trimwsa (linea);
5128 if (strlen (linea) > 0) {
5129 if (linea[0] == '#' || linea[0] == ';') {
5130 struct strlist *u = xcalloc (struct strlist, 1);
5131 u->option = NULL;
5132 TCHAR *com = au (linea);
5133 u->value = my_strdup (com);
5134 xfree (com);
5135 u->unknown = 1;
5136 u->next = p->all_lines;
5137 p->all_lines = u;
5138 continue;
5139 }
5140 if (!cfgfile_separate_linea (filename, linea, line1b, line2b))
5141 continue;
5142 type1 = type2 = 0;
5143 if (cfgfile_yesno (line1b, line2b, _T("config_hardware"), &type1) ||
5144 cfgfile_yesno (line1b, line2b, _T("config_host"), &type2)) {
5145 if (type1 && type)
5146 *type |= CONFIG_TYPE_HARDWARE;
5147 if (type2 && type)
5148 *type |= CONFIG_TYPE_HOST;
5149 continue;
5150 }
5151 if (real) {
5152 cfgfile_parse_separated_line (p, line1b, line2b, askedtype);
5153 } else {
5154 cfgfile_string (line1b, line2b, _T("config_description"), p->description, sizeof p->description / sizeof (TCHAR));
5155 cfgfile_path (line1b, line2b, _T("config_hardware_path"), p->config_hardware_path, sizeof p->config_hardware_path / sizeof (TCHAR));
5156 cfgfile_path (line1b, line2b, _T("config_host_path"), p->config_host_path, sizeof p->config_host_path / sizeof(TCHAR));
5157 cfgfile_path (line1b, line2b, _T("config_all_path"), p->config_all_path, sizeof p->config_all_path / sizeof(TCHAR));
5158 cfgfile_string (line1b, line2b, _T("config_window_title"), p->config_window_title, sizeof p->config_window_title / sizeof (TCHAR));
5159 }
5160 }
5161 }
5162
5163 if (type && *type == 0)
5164 *type = CONFIG_TYPE_HARDWARE | CONFIG_TYPE_HOST;
5165 zfile_fclose (fh);
5166
5167 if (!real)
5168 return 1;
5169
5170 for (sl = temp_lines; sl; sl = sl->next) {
5171 _stprintf (line, _T("%s=%s"), sl->option, sl->value);
5172 cfgfile_parse_line (p, line, 0);
5173 }
5174
5175 for (i = 0; i < 4; i++)
5176 subst (p->path_floppy.path[0], p->floppyslots[i].df, sizeof p->floppyslots[i].df / sizeof (TCHAR));
5177 subst (p->path_rom.path[0], p->romfile, sizeof p->romfile / sizeof (TCHAR));
5178 subst (p->path_rom.path[0], p->romextfile, sizeof p->romextfile / sizeof (TCHAR));
5179 subst (p->path_rom.path[0], p->romextfile2, sizeof p->romextfile2 / sizeof (TCHAR));
5180
5181 for (i = 0; i < MAX_EXPANSION_BOARDS; i++) {
5182 for (int j = 0; j < MAX_BOARD_ROMS; j++) {
5183 subst(p->path_rom.path[0], p->expansionboard[i].roms[j].romfile, MAX_DPATH / sizeof(TCHAR));
5184 }
5185 }
5186
5187 return 1;
5188 }
5189
cfgfile_load(struct uae_prefs * p,const TCHAR * filename,int * type,int ignorelink,int userconfig)5190 int cfgfile_load (struct uae_prefs *p, const TCHAR *filename, int *type, int ignorelink, int userconfig)
5191 {
5192 int v;
5193 TCHAR tmp[MAX_DPATH];
5194 int type2;
5195 static int recursive;
5196
5197 if (recursive > 1)
5198 return 0;
5199 recursive++;
5200 write_log (_T("load config '%s':%d\n"), filename, type ? *type : -1);
5201 v = cfgfile_load_2 (p, filename, 1, type);
5202 if (!v) {
5203 cfgfile_warning(_T("cfgfile_load_2 failed\n"));
5204 goto end;
5205 }
5206 if (userconfig)
5207 target_addtorecent (filename, 0);
5208 if (!ignorelink) {
5209 if (p->config_all_path[0]) {
5210 fetch_configurationpath(tmp, sizeof(tmp) / sizeof(TCHAR));
5211 _tcsncat(tmp, p->config_all_path, sizeof(tmp) / sizeof(TCHAR) - _tcslen(tmp) - 1);
5212 type2 = CONFIG_TYPE_HOST | CONFIG_TYPE_HARDWARE;
5213 cfgfile_load(p, tmp, &type2, 1, 0);
5214 }
5215 if (p->config_hardware_path[0]) {
5216 fetch_configurationpath (tmp, sizeof (tmp) / sizeof (TCHAR));
5217 _tcsncat (tmp, p->config_hardware_path, sizeof (tmp) / sizeof (TCHAR) - _tcslen(tmp) - 1);
5218 type2 = CONFIG_TYPE_HARDWARE;
5219 cfgfile_load (p, tmp, &type2, 1, 0);
5220 }
5221 if (p->config_host_path[0]) {
5222 fetch_configurationpath (tmp, sizeof (tmp) / sizeof (TCHAR));
5223 _tcsncat (tmp, p->config_host_path, sizeof (tmp) / sizeof (TCHAR) - _tcslen(tmp) - 1);
5224 type2 = CONFIG_TYPE_HOST;
5225 cfgfile_load (p, tmp, &type2, 1, 0);
5226 }
5227 }
5228 end:
5229 recursive--;
5230 fixup_prefs (p);
5231 return v;
5232 }
5233
cfgfile_backup(const TCHAR * path)5234 void cfgfile_backup (const TCHAR *path)
5235 {
5236 TCHAR dpath[MAX_DPATH];
5237
5238 fetch_configurationpath (dpath, sizeof (dpath) / sizeof (TCHAR));
5239 _tcscat (dpath, _T("configuration.backup"));
5240 bool hidden = my_isfilehidden (dpath);
5241 my_unlink (dpath);
5242 my_rename (path, dpath);
5243 if (hidden)
5244 my_setfilehidden (dpath, hidden);
5245 }
5246
cfgfile_save(struct uae_prefs * p,const TCHAR * filename,int type)5247 int cfgfile_save (struct uae_prefs *p, const TCHAR *filename, int type)
5248 {
5249 struct zfile *fh;
5250
5251 #ifdef FSUAE
5252 // don't back up config file
5253 #else
5254 cfgfile_backup (filename);
5255 #endif
5256 fh = zfile_fopen (filename, unicode_config ? _T("w, ccs=UTF-8") : _T("w"), ZFD_NORMAL);
5257 if (! fh)
5258 return 0;
5259
5260 if (!type)
5261 type = CONFIG_TYPE_HARDWARE | CONFIG_TYPE_HOST;
5262 cfgfile_save_options (fh, p, type);
5263 zfile_fclose (fh);
5264 return 1;
5265 }
5266
cfgfile_get_description(const TCHAR * filename,TCHAR * description,TCHAR * hostlink,TCHAR * hardwarelink,int * type)5267 int cfgfile_get_description (const TCHAR *filename, TCHAR *description, TCHAR *hostlink, TCHAR *hardwarelink, int *type)
5268 {
5269 int result = 0;
5270 struct uae_prefs *p = xmalloc (struct uae_prefs, 1);
5271
5272 p->description[0] = 0;
5273 p->config_host_path[0] = 0;
5274 p->config_hardware_path[0] = 0;
5275 if (cfgfile_load_2 (p, filename, 0, type)) {
5276 result = 1;
5277 if (description)
5278 _tcscpy (description, p->description);
5279 if (hostlink)
5280 _tcscpy (hostlink, p->config_host_path);
5281 if (hardwarelink)
5282 _tcscpy (hardwarelink, p->config_hardware_path);
5283 }
5284 xfree (p);
5285 return result;
5286 }
5287
cfgfile_configuration_change(int v)5288 int cfgfile_configuration_change (int v)
5289 {
5290 static int mode;
5291 if (v >= 0)
5292 mode = v;
5293 return mode;
5294 }
5295
cfgfile_show_usage(void)5296 void cfgfile_show_usage (void)
5297 {
5298 int i;
5299 write_log (_T("UAE Configuration Help:\n") \
5300 _T("=======================\n"));
5301 for (i = 0; i < sizeof opttable / sizeof *opttable; i++)
5302 write_log (_T("%s: %s\n"), opttable[i].config_label, opttable[i].config_help);
5303 }
5304
5305 /* This implements the old commandline option parsing. I've re-added this
5306 because the new way of doing things is painful for me (it requires me
5307 to type a couple hundred characters when invoking UAE). The following
5308 is far less annoying to use. */
parse_gfx_specs(struct uae_prefs * p,const TCHAR * spec)5309 static void parse_gfx_specs (struct uae_prefs *p, const TCHAR *spec)
5310 {
5311 TCHAR *x0 = my_strdup (spec);
5312 TCHAR *x1, *x2;
5313
5314 x1 = _tcschr (x0, ':');
5315 if (x1 == 0)
5316 goto argh;
5317 x2 = _tcschr (x1+1, ':');
5318 if (x2 == 0)
5319 goto argh;
5320 *x1++ = 0; *x2++ = 0;
5321
5322 p->gfx_size_win.width = p->gfx_size_fs.width = _tstoi (x0);
5323 p->gfx_size_win.height = p->gfx_size_fs.height = _tstoi (x1);
5324 p->gfx_resolution = _tcschr (x2, 'l') != 0 ? 1 : 0;
5325 p->gfx_xcenter = _tcschr (x2, 'x') != 0 ? 1 : _tcschr (x2, 'X') != 0 ? 2 : 0;
5326 p->gfx_ycenter = _tcschr (x2, 'y') != 0 ? 1 : _tcschr (x2, 'Y') != 0 ? 2 : 0;
5327 p->gfx_vresolution = _tcschr (x2, 'd') != 0 ? VRES_DOUBLE : VRES_NONDOUBLE;
5328 p->gfx_pscanlines = _tcschr (x2, 'D') != 0;
5329 if (p->gfx_pscanlines)
5330 p->gfx_vresolution = VRES_DOUBLE;
5331 p->gfx_apmode[0].gfx_fullscreen = _tcschr (x2, 'a') != 0;
5332 p->gfx_apmode[1].gfx_fullscreen = _tcschr (x2, 'p') != 0;
5333
5334 free (x0);
5335 return;
5336
5337 argh:
5338 write_log (_T("Bad display mode specification.\n"));
5339 write_log (_T("The format to use is: \"width:height:modifiers\"\n"));
5340 write_log (_T("Type \"uae -h\" for detailed help.\n"));
5341 free (x0);
5342 }
5343
parse_sound_spec(struct uae_prefs * p,const TCHAR * spec)5344 static void parse_sound_spec (struct uae_prefs *p, const TCHAR *spec)
5345 {
5346 TCHAR *x0 = my_strdup (spec);
5347 TCHAR *x1, *x2 = NULL, *x3 = NULL, *x4 = NULL, *x5 = NULL;
5348
5349 x1 = _tcschr (x0, ':');
5350 if (x1 != NULL) {
5351 *x1++ = '\0';
5352 x2 = _tcschr (x1 + 1, ':');
5353 if (x2 != NULL) {
5354 *x2++ = '\0';
5355 x3 = _tcschr (x2 + 1, ':');
5356 if (x3 != NULL) {
5357 *x3++ = '\0';
5358 x4 = _tcschr (x3 + 1, ':');
5359 if (x4 != NULL) {
5360 *x4++ = '\0';
5361 x5 = _tcschr (x4 + 1, ':');
5362 }
5363 }
5364 }
5365 }
5366 p->produce_sound = _tstoi (x0);
5367 if (x1) {
5368 p->sound_stereo_separation = 0;
5369 if (*x1 == 'S') {
5370 p->sound_stereo = SND_STEREO;
5371 p->sound_stereo_separation = 7;
5372 } else if (*x1 == 's')
5373 p->sound_stereo = SND_STEREO;
5374 else
5375 p->sound_stereo = SND_MONO;
5376 }
5377 if (x3)
5378 p->sound_freq = _tstoi (x3);
5379 if (x4)
5380 p->sound_maxbsiz = _tstoi (x4);
5381 free (x0);
5382 }
5383
5384
parse_joy_spec(struct uae_prefs * p,const TCHAR * spec)5385 static void parse_joy_spec (struct uae_prefs *p, const TCHAR *spec)
5386 {
5387 int v0 = 2, v1 = 0;
5388 if (_tcslen(spec) != 2)
5389 goto bad;
5390
5391 switch (spec[0]) {
5392 case '0': v0 = JSEM_JOYS; break;
5393 case '1': v0 = JSEM_JOYS + 1; break;
5394 case 'M': case 'm': v0 = JSEM_MICE; break;
5395 case 'A': case 'a': v0 = JSEM_KBDLAYOUT; break;
5396 case 'B': case 'b': v0 = JSEM_KBDLAYOUT + 1; break;
5397 case 'C': case 'c': v0 = JSEM_KBDLAYOUT + 2; break;
5398 default: goto bad;
5399 }
5400
5401 switch (spec[1]) {
5402 case '0': v1 = JSEM_JOYS; break;
5403 case '1': v1 = JSEM_JOYS + 1; break;
5404 case 'M': case 'm': v1 = JSEM_MICE; break;
5405 case 'A': case 'a': v1 = JSEM_KBDLAYOUT; break;
5406 case 'B': case 'b': v1 = JSEM_KBDLAYOUT + 1; break;
5407 case 'C': case 'c': v1 = JSEM_KBDLAYOUT + 2; break;
5408 default: goto bad;
5409 }
5410 if (v0 == v1)
5411 goto bad;
5412 /* Let's scare Pascal programmers */
5413 if (0)
5414 bad:
5415 write_log (_T("Bad joystick mode specification. Use -J xy, where x and y\n")
5416 _T("can be 0 for joystick 0, 1 for joystick 1, M for mouse, and\n")
5417 _T("a, b or c for different keyboard settings.\n"));
5418
5419 p->jports[0].id = v0;
5420 p->jports[1].id = v1;
5421 }
5422
parse_filesys_spec(struct uae_prefs * p,bool readonly,const TCHAR * spec)5423 static void parse_filesys_spec (struct uae_prefs *p, bool readonly, const TCHAR *spec)
5424 {
5425 struct uaedev_config_info uci;
5426 TCHAR buf[256];
5427 TCHAR *s2;
5428
5429 uci_set_defaults (&uci, false);
5430 _tcsncpy (buf, spec, 255); buf[255] = 0;
5431 s2 = _tcschr (buf, ':');
5432 if (s2) {
5433 *s2++ = '\0';
5434 #ifdef __DOS__
5435 {
5436 TCHAR *tmp;
5437
5438 while ((tmp = _tcschr (s2, '\\')))
5439 *tmp = '/';
5440 }
5441 #endif
5442 #ifdef FILESYS
5443 _tcscpy (uci.volname, buf);
5444 _tcscpy (uci.rootdir, s2);
5445 uci.readonly = readonly;
5446 uci.type = UAEDEV_DIR;
5447 add_filesys_config (p, -1, &uci);
5448 #endif
5449 } else {
5450 write_log (_T("Usage: [-m | -M] VOLNAME:mount_point\n"));
5451 }
5452 }
5453
parse_hardfile_spec(struct uae_prefs * p,const TCHAR * spec)5454 static void parse_hardfile_spec (struct uae_prefs *p, const TCHAR *spec)
5455 {
5456 struct uaedev_config_info uci;
5457 TCHAR *x0 = my_strdup (spec);
5458 TCHAR *x1, *x2, *x3, *x4;
5459
5460 uci_set_defaults (&uci, false);
5461 x1 = _tcschr (x0, ':');
5462 if (x1 == NULL)
5463 goto argh;
5464 *x1++ = '\0';
5465 x2 = _tcschr (x1 + 1, ':');
5466 if (x2 == NULL)
5467 goto argh;
5468 *x2++ = '\0';
5469 x3 = _tcschr (x2 + 1, ':');
5470 if (x3 == NULL)
5471 goto argh;
5472 *x3++ = '\0';
5473 x4 = _tcschr (x3 + 1, ':');
5474 if (x4 == NULL)
5475 goto argh;
5476 *x4++ = '\0';
5477 #ifdef FILESYS
5478 _tcscpy (uci.rootdir, x4);
5479 //add_filesys_config (p, -1, NULL, NULL, x4, 0, 0, _tstoi (x0), _tstoi (x1), _tstoi (x2), _tstoi (x3), 0, 0, 0, 0, 0, 0, 0);
5480 #endif
5481 free (x0);
5482 return;
5483
5484 argh:
5485 free (x0);
5486 cfgfile_warning(_T("Bad hardfile parameter specified\n"));
5487 return;
5488 }
5489
parse_cpu_specs(struct uae_prefs * p,const TCHAR * spec)5490 static void parse_cpu_specs (struct uae_prefs *p, const TCHAR *spec)
5491 {
5492 if (*spec < '0' || *spec > '4') {
5493 cfgfile_warning(_T("CPU parameter string must begin with '0', '1', '2', '3' or '4'.\n"));
5494 return;
5495 }
5496
5497 p->cpu_model = (*spec++) * 10 + 68000;
5498 p->address_space_24 = p->cpu_model < 68020;
5499 p->cpu_compatible = 0;
5500 while (*spec != '\0') {
5501 switch (*spec) {
5502 case 'a':
5503 if (p->cpu_model < 68020)
5504 cfgfile_warning(_T("In 68000/68010 emulation, the address space is always 24 bit.\n"));
5505 else if (p->cpu_model >= 68040)
5506 cfgfile_warning(_T("In 68040/060 emulation, the address space is always 32 bit.\n"));
5507 else
5508 p->address_space_24 = 1;
5509 break;
5510 case 'c':
5511 if (p->cpu_model != 68000)
5512 cfgfile_warning(_T("The more compatible CPU emulation is only available for 68000\n")
5513 _T("emulation, not for 68010 upwards.\n"));
5514 else
5515 p->cpu_compatible = 1;
5516 break;
5517 default:
5518 cfgfile_warning(_T("Bad CPU parameter specified.\n"));
5519 break;
5520 }
5521 spec++;
5522 }
5523 }
5524
cmdpath(TCHAR * dst,const TCHAR * src,int maxsz)5525 static void cmdpath (TCHAR *dst, const TCHAR *src, int maxsz)
5526 {
5527 TCHAR *s = target_expand_environment (src);
5528 _tcsncpy (dst, s, maxsz);
5529 dst[maxsz] = 0;
5530 xfree (s);
5531 }
5532
5533 /* Returns the number of args used up (0 or 1). */
parse_cmdline_option(struct uae_prefs * p,TCHAR c,const TCHAR * arg)5534 int parse_cmdline_option (struct uae_prefs *p, TCHAR c, const TCHAR *arg)
5535 {
5536 struct strlist *u = xcalloc (struct strlist, 1);
5537 const TCHAR arg_required[] = _T("0123rKpImWSAJwNCZUFcblOdHRv");
5538
5539 if (_tcschr (arg_required, c) && ! arg) {
5540 write_log (_T("Missing argument for option `-%c'!\n"), c);
5541 return 0;
5542 }
5543
5544 u->option = xmalloc (TCHAR, 2);
5545 u->option[0] = c;
5546 u->option[1] = 0;
5547 u->value = my_strdup (arg);
5548 u->next = p->all_lines;
5549 p->all_lines = u;
5550
5551 switch (c) {
5552 case 'h': usage (); exit (0);
5553
5554 case '0': cmdpath (p->floppyslots[0].df, arg, 255); break;
5555 case '1': cmdpath (p->floppyslots[1].df, arg, 255); break;
5556 case '2': cmdpath (p->floppyslots[2].df, arg, 255); break;
5557 case '3': cmdpath (p->floppyslots[3].df, arg, 255); break;
5558 case 'r': cmdpath (p->romfile, arg, 255); break;
5559 case 'K': cmdpath (p->romextfile, arg, 255); break;
5560 case 'p': _tcsncpy (p->prtname, arg, 255); p->prtname[255] = 0; break;
5561 /* case 'I': _tcsncpy (p->sername, arg, 255); p->sername[255] = 0; currprefs.use_serial = 1; break; */
5562 case 'm': case 'M': parse_filesys_spec (p, c == 'M', arg); break;
5563 case 'W': parse_hardfile_spec (p, arg); break;
5564 case 'S': parse_sound_spec (p, arg); break;
5565 case 'R': p->gfx_framerate = _tstoi (arg); break;
5566 case 'i': p->illegal_mem = 1; break;
5567 case 'J': parse_joy_spec (p, arg); break;
5568
5569 case 'w': p->m68k_speed = _tstoi (arg); break;
5570
5571 /* case 'g': p->use_gfxlib = 1; break; */
5572 case 'G': p->start_gui = 0; break;
5573 case 'D': p->start_debugger = 1; break;
5574
5575 case 'n':
5576 if (_tcschr (arg, 'i') != 0)
5577 p->immediate_blits = 1;
5578 break;
5579
5580 case 'v':
5581 set_chipset_mask (p, _tstoi (arg));
5582 break;
5583
5584 case 'C':
5585 parse_cpu_specs (p, arg);
5586 break;
5587
5588 case 'Z':
5589 p->z3fastmem_size = _tstoi (arg) * 0x100000;
5590 break;
5591
5592 case 'U':
5593 p->rtgmem_size = _tstoi (arg) * 0x100000;
5594 break;
5595
5596 case 'F':
5597 p->fastmem_size = _tstoi (arg) * 0x100000;
5598 break;
5599
5600 case 'b':
5601 p->bogomem_size = _tstoi (arg) * 0x40000;
5602 break;
5603
5604 case 'c':
5605 p->chipmem_size = _tstoi (arg) * 0x80000;
5606 break;
5607
5608 case 'l':
5609 if (0 == strcasecmp(arg, _T("de")))
5610 p->keyboard_lang = KBD_LANG_DE;
5611 else if (0 == strcasecmp(arg, _T("dk")))
5612 p->keyboard_lang = KBD_LANG_DK;
5613 else if (0 == strcasecmp(arg, _T("us")))
5614 p->keyboard_lang = KBD_LANG_US;
5615 else if (0 == strcasecmp(arg, _T("se")))
5616 p->keyboard_lang = KBD_LANG_SE;
5617 else if (0 == strcasecmp(arg, _T("fr")))
5618 p->keyboard_lang = KBD_LANG_FR;
5619 else if (0 == strcasecmp(arg, _T("it")))
5620 p->keyboard_lang = KBD_LANG_IT;
5621 else if (0 == strcasecmp(arg, _T("es")))
5622 p->keyboard_lang = KBD_LANG_ES;
5623 break;
5624
5625 case 'O': parse_gfx_specs (p, arg); break;
5626 case 'd':
5627 if (_tcschr (arg, 'S') != NULL || _tcschr (arg, 's')) {
5628 write_log (_T(" Serial on demand.\n"));
5629 p->serial_demand = 1;
5630 }
5631 if (_tcschr (arg, 'P') != NULL || _tcschr (arg, 'p')) {
5632 write_log (_T(" Parallel on demand.\n"));
5633 p->parallel_demand = 1;
5634 }
5635
5636 break;
5637
5638 case 'H':
5639 p->color_mode = _tstoi (arg);
5640 if (p->color_mode < 0) {
5641 write_log (_T("Bad color mode selected. Using default.\n"));
5642 p->color_mode = 0;
5643 }
5644 break;
5645 default:
5646 write_log (_T("Unknown option `-%c'!\n"), c);
5647 break;
5648 }
5649 return !! _tcschr (arg_required, c);
5650 }
5651
cfgfile_addcfgparam(TCHAR * line)5652 void cfgfile_addcfgparam (TCHAR *line)
5653 {
5654 struct strlist *u;
5655 TCHAR line1b[CONFIG_BLEN], line2b[CONFIG_BLEN];
5656
5657 if (!line) {
5658 struct strlist **ps = &temp_lines;
5659 while (*ps) {
5660 struct strlist *s = *ps;
5661 *ps = s->next;
5662 xfree (s->value);
5663 xfree (s->option);
5664 xfree (s);
5665 }
5666 temp_lines = 0;
5667 return;
5668 }
5669 if (!cfgfile_separate_line (line, line1b, line2b))
5670 return;
5671 u = xcalloc (struct strlist, 1);
5672 u->option = my_strdup (line1b);
5673 u->value = my_strdup (line2b);
5674 u->next = temp_lines;
5675 temp_lines = u;
5676 }
5677
5678 #if 0
5679 static int cfgfile_handle_custom_event (TCHAR *custom, int mode)
5680 {
5681 TCHAR option[CONFIG_BLEN], value[CONFIG_BLEN];
5682 TCHAR option2[CONFIG_BLEN], value2[CONFIG_BLEN];
5683 TCHAR *tmp, *p, *nextp;
5684 struct zfile *configstore = NULL;
5685 int cnt = 0, cnt_ok = 0;
5686
5687 if (!mode) {
5688 TCHAR zero = 0;
5689 configstore = zfile_fopen_empty ("configstore", 50000);
5690 cfgfile_save_options (configstore, &currprefs, 0);
5691 cfg_write (&zero, configstore);
5692 }
5693
5694 nextp = NULL;
5695 tmp = p = xcalloc (TCHAR, _tcslen (custom) + 2);
5696 _tcscpy (tmp, custom);
5697 while (p && *p) {
5698 if (*p == '\"') {
5699 TCHAR *p2;
5700 p++;
5701 p2 = p;
5702 while (*p2 != '\"' && *p2 != 0)
5703 p2++;
5704 if (*p2 == '\"') {
5705 *p2++ = 0;
5706 nextp = p2 + 1;
5707 if (*nextp == ' ')
5708 nextp++;
5709 }
5710 }
5711 if (cfgfile_separate_line (p, option, value)) {
5712 cnt++;
5713 if (mode) {
5714 cfgfile_parse_option (&changed_prefs, option, value, 0);
5715 } else {
5716 zfile_fseek (configstore, 0, SEEK_SET);
5717 for (;;) {
5718 if (!getconfigstoreline (configstore, option2, value2))
5719 break;
5720 if (!_tcscmpi (option, option2) && !_tcscmpi (value, value2)) {
5721 cnt_ok++;
5722 break;
5723 }
5724 }
5725 }
5726 }
5727 p = nextp;
5728 }
5729 xfree (tmp);
5730 zfile_fclose (configstore);
5731 if (cnt > 0 && cnt == cnt_ok)
5732 return 1;
5733 return 0;
5734 }
5735 #endif
5736
cmdlineparser(const TCHAR * s,TCHAR * outp[],int max)5737 int cmdlineparser (const TCHAR *s, TCHAR *outp[], int max)
5738 {
5739 int j, cnt = 0;
5740 int slash = 0;
5741 int quote = 0;
5742 TCHAR tmp1[MAX_DPATH];
5743 const TCHAR *prev;
5744 int doout;
5745
5746 doout = 0;
5747 prev = s;
5748 j = 0;
5749 outp[0] = 0;
5750 while (cnt < max) {
5751 TCHAR c = *s++;
5752 if (!c)
5753 break;
5754 if (c < 32)
5755 continue;
5756 if (c == '\\')
5757 slash = 1;
5758 if (!slash && c == '"') {
5759 if (quote) {
5760 quote = 0;
5761 doout = 1;
5762 } else {
5763 quote = 1;
5764 j = -1;
5765 }
5766 }
5767 if (!quote && c == ' ')
5768 doout = 1;
5769 if (!doout) {
5770 if (j >= 0) {
5771 tmp1[j] = c;
5772 tmp1[j + 1] = 0;
5773 }
5774 j++;
5775 }
5776 if (doout) {
5777 if (_tcslen (tmp1) > 0) {
5778 outp[cnt++] = my_strdup (tmp1);
5779 outp[cnt] = 0;
5780 }
5781 tmp1[0] = 0;
5782 doout = 0;
5783 j = 0;
5784 }
5785 slash = 0;
5786 }
5787 if (j > 0 && cnt < max) {
5788 outp[cnt++] = my_strdup (tmp1);
5789 outp[cnt] = 0;
5790 }
5791 return cnt;
5792 }
5793
5794 #define UAELIB_MAX_PARSE 100
5795
cfgfile_parse_uaelib_option(struct uae_prefs * p,TCHAR * option,TCHAR * value,int type)5796 static bool cfgfile_parse_uaelib_option (struct uae_prefs *p, TCHAR *option, TCHAR *value, int type)
5797 {
5798 return false;
5799 }
5800
cfgfile_searchconfig(const TCHAR * in,int index,TCHAR * out,int outsize)5801 int cfgfile_searchconfig(const TCHAR *in, int index, TCHAR *out, int outsize)
5802 {
5803 TCHAR tmp[CONFIG_BLEN];
5804 int j = 0;
5805 int inlen = _tcslen (in);
5806 int joker = 0;
5807 uae_u32 err = 0;
5808 bool configsearchfound = false;
5809
5810 if (in[inlen - 1] == '*') {
5811 joker = 1;
5812 inlen--;
5813 }
5814 *out = 0;
5815
5816 if (!configstore)
5817 createconfigstore(&currprefs);
5818 if (!configstore)
5819 return 20;
5820
5821 if (index < 0)
5822 zfile_fseek(configstore, 0, SEEK_SET);
5823
5824 for (;;) {
5825 uae_u8 b = 0;
5826
5827 if (zfile_fread (&b, 1, 1, configstore) != 1) {
5828 err = 10;
5829 if (configsearchfound)
5830 err = 0;
5831 goto end;
5832 }
5833 if (j >= sizeof (tmp) / sizeof (TCHAR) - 1)
5834 j = sizeof (tmp) / sizeof (TCHAR) - 1;
5835 if (b == 0) {
5836 err = 10;
5837 if (configsearchfound)
5838 err = 0;
5839 goto end;
5840 }
5841 if (b == '\n') {
5842 if (!_tcsncmp (tmp, in, inlen) && ((inlen > 0 && _tcslen (tmp) > inlen && tmp[inlen] == '=') || (joker))) {
5843 TCHAR *p;
5844 if (joker)
5845 p = tmp - 1;
5846 else
5847 p = _tcschr (tmp, '=');
5848 if (p) {
5849 for (int i = 0; out && i < outsize - 1; i++) {
5850 TCHAR b = *++p;
5851 out[i] = b;
5852 out[i + 1] = 0;
5853 if (!b)
5854 break;
5855 }
5856 }
5857 err = 0xffffffff;
5858 configsearchfound = true;
5859 goto end;
5860 }
5861 j = 0;
5862 } else {
5863 tmp[j++] = b;
5864 tmp[j] = 0;
5865 }
5866 }
5867 end:
5868 return err;
5869 }
5870
cfgfile_modify(uae_u32 index,const TCHAR * parms,uae_u32 size,TCHAR * out,uae_u32 outsize)5871 uae_u32 cfgfile_modify (uae_u32 index, const TCHAR *parms, uae_u32 size, TCHAR *out, uae_u32 outsize)
5872 {
5873 TCHAR *p;
5874 TCHAR *argc[UAELIB_MAX_PARSE];
5875 int argv, i;
5876 uae_u32 err;
5877 static TCHAR *configsearch;
5878
5879 #ifdef FSUAE // NL
5880 write_log("*** cfgfile_modify *** %s\n", parms);
5881 #endif
5882
5883 *out = 0;
5884 err = 0;
5885 argv = 0;
5886 p = 0;
5887 if (index != 0xffffffff) {
5888 if (!configstore) {
5889 err = 20;
5890 goto end;
5891 }
5892 if (configsearch) {
5893 err = cfgfile_searchconfig(configsearch, index, out, outsize);
5894 goto end;
5895 }
5896 err = 0xffffffff;
5897 for (i = 0; out && i < outsize - 1; i++) {
5898 uae_u8 b = 0;
5899 if (zfile_fread (&b, 1, 1, configstore) != 1)
5900 err = 0;
5901 if (b == 0)
5902 err = 0;
5903 if (b == '\n')
5904 b = 0;
5905 out[i] = b;
5906 out[i + 1] = 0;
5907 if (!b)
5908 break;
5909 }
5910 goto end;
5911 }
5912
5913 if (size > 10000)
5914 return 10;
5915 argv = cmdlineparser (parms, argc, UAELIB_MAX_PARSE);
5916
5917 if (argv <= 1 && index == 0xffffffff) {
5918 createconfigstore (&currprefs);
5919 xfree (configsearch);
5920 configsearch = NULL;
5921 if (!configstore) {
5922 err = 20;
5923 goto end;
5924 }
5925 if (argv > 0 && _tcslen (argc[0]) > 0)
5926 configsearch = my_strdup (argc[0]);
5927 err = 0xffffffff;
5928 goto end;
5929 }
5930
5931 for (i = 0; i < argv; i++) {
5932 if (i + 2 <= argv) {
5933 if (!_tcsicmp (argc[i], _T("dbg"))) {
5934 debug_parser (argc[i + 1], out, outsize);
5935 } else if (!inputdevice_uaelib (argc[i], argc[i + 1])) {
5936 if (!cfgfile_parse_uaelib_option (&changed_prefs, argc[i], argc[i + 1], 0)) {
5937 if (!cfgfile_parse_option (&changed_prefs, argc[i], argc[i + 1], 0)) {
5938 err = 5;
5939 break;
5940 }
5941 }
5942 }
5943 set_config_changed ();
5944 set_special(SPCFLAG_MODE_CHANGE);
5945 i++;
5946 }
5947 }
5948 end:
5949 for (i = 0; i < argv; i++)
5950 xfree (argc[i]);
5951 xfree (p);
5952 return err;
5953 }
5954
cfgfile_uaelib_modify(uae_u32 index,uae_u32 parms,uae_u32 size,uae_u32 out,uae_u32 outsize)5955 uae_u32 cfgfile_uaelib_modify (uae_u32 index, uae_u32 parms, uae_u32 size, uae_u32 out, uae_u32 outsize)
5956 {
5957 uae_char *p, *parms_p = NULL, *parms_out = NULL;
5958 int i, ret;
5959 TCHAR *out_p = NULL, *parms_in = NULL;
5960
5961 if (out)
5962 put_byte (out, 0);
5963 if (size == 0) {
5964 while (get_byte (parms + size) != 0)
5965 size++;
5966 }
5967 parms_p = xmalloc (uae_char, size + 1);
5968 if (!parms_p) {
5969 ret = 10;
5970 goto end;
5971 }
5972 if (out) {
5973 out_p = xmalloc (TCHAR, outsize + 1);
5974 if (!out_p) {
5975 ret = 10;
5976 goto end;
5977 }
5978 out_p[0] = 0;
5979 }
5980 p = parms_p;
5981 for (i = 0; i < size; i++) {
5982 p[i] = get_byte (parms + i);
5983 if (p[i] == 10 || p[i] == 13 || p[i] == 0)
5984 break;
5985 }
5986 p[i] = 0;
5987 parms_in = au (parms_p);
5988 ret = cfgfile_modify (index, parms_in, size, out_p, outsize);
5989 xfree (parms_in);
5990 if (out) {
5991 parms_out = ua (out_p);
5992 p = parms_out;
5993 for (i = 0; i < outsize - 1; i++) {
5994 uae_u8 b = *p++;
5995 put_byte (out + i, b);
5996 put_byte (out + i + 1, 0);
5997 if (!b)
5998 break;
5999 }
6000 }
6001 xfree (parms_out);
6002 end:
6003 xfree (out_p);
6004 xfree (parms_p);
6005 return ret;
6006 }
6007
cfgfile_read_config_value(const TCHAR * option)6008 static const TCHAR *cfgfile_read_config_value (const TCHAR *option)
6009 {
6010 struct strlist *sl;
6011 for (sl = currprefs.all_lines; sl; sl = sl->next) {
6012 if (sl->option && !strcasecmp (sl->option, option))
6013 return sl->value;
6014 }
6015 return NULL;
6016 }
6017
cfgfile_uaelib(int mode,uae_u32 name,uae_u32 dst,uae_u32 maxlen)6018 uae_u32 cfgfile_uaelib (int mode, uae_u32 name, uae_u32 dst, uae_u32 maxlen)
6019 {
6020 TCHAR tmp[CONFIG_BLEN];
6021 int i;
6022
6023 if (mode)
6024 return 0;
6025
6026 for (i = 0; i < sizeof (tmp) / sizeof (TCHAR); i++) {
6027 tmp[i] = get_byte (name + i);
6028 if (tmp[i] == 0)
6029 break;
6030 }
6031 tmp[sizeof(tmp) / sizeof (TCHAR) - 1] = 0;
6032 if (tmp[0] == 0)
6033 return 0;
6034 const TCHAR *value = cfgfile_read_config_value (tmp);
6035 if (value) {
6036 char *s = ua (value);
6037 for (i = 0; i < maxlen; i++) {
6038 put_byte (dst + i, s[i]);
6039 if (s[i] == 0)
6040 break;
6041 }
6042 xfree (s);
6043 return dst;
6044 }
6045 return 0;
6046 }
6047
restore_configuration(uae_u8 * src)6048 uae_u8 *restore_configuration (uae_u8 *src)
6049 {
6050 TCHAR *s = au ((char*)src);
6051 //write_log (s);
6052 xfree (s);
6053 src += strlen ((char*)src) + 1;
6054 return src;
6055 }
6056
save_configuration(int * len,bool fullconfig)6057 uae_u8 *save_configuration (int *len, bool fullconfig)
6058 {
6059 int tmpsize = 100000;
6060 uae_u8 *dstbak, *dst, *p;
6061 int index = -1;
6062
6063 dstbak = dst = xcalloc (uae_u8, tmpsize);
6064 p = dst;
6065 for (;;) {
6066 TCHAR tmpout[1000];
6067 int ret;
6068 tmpout[0] = 0;
6069 ret = cfgfile_modify (index, _T("*"), 1, tmpout, sizeof (tmpout) / sizeof (TCHAR));
6070 index++;
6071 if (_tcslen (tmpout) > 0) {
6072 char *out;
6073 if (!fullconfig && !_tcsncmp (tmpout, _T("input."), 6))
6074 continue;
6075 //write_log (_T("'%s'\n"), tmpout);
6076 out = uutf8 (tmpout);
6077 strcpy ((char*)p, out);
6078 xfree (out);
6079 strcat ((char*)p, "\n");
6080 p += strlen ((char*)p);
6081 if (p - dstbak >= tmpsize - sizeof (tmpout))
6082 break;
6083 }
6084 if (ret >= 0)
6085 break;
6086 }
6087 *len = p - dstbak + 1;
6088 return dstbak;
6089 }
6090
6091 #ifdef UAE_MINI
default_prefs_mini(struct uae_prefs * p,int type)6092 static void default_prefs_mini (struct uae_prefs *p, int type)
6093 {
6094 _tcscpy (p->description, _T("UAE default A500 configuration"));
6095
6096 p->nr_floppies = 1;
6097 p->floppyslots[0].dfxtype = DRV_35_DD;
6098 p->floppyslots[1].dfxtype = DRV_NONE;
6099 p->cpu_model = 68000;
6100 p->address_space_24 = 1;
6101 p->chipmem_size = 0x00080000;
6102 p->bogomem_size = 0x00080000;
6103 }
6104 #endif
6105
6106 #include "sounddep/sound.h"
6107
default_prefs(struct uae_prefs * p,int type)6108 void default_prefs (struct uae_prefs *p, int type)
6109 {
6110 int i;
6111 int roms[] = { 6, 7, 8, 9, 10, 14, 5, 4, 3, 2, 1, -1 };
6112 TCHAR zero = 0;
6113 struct zfile *f;
6114
6115 reset_inputdevice_config (p);
6116 memset (p, 0, sizeof (*p));
6117 _tcscpy (p->description, _T("UAE default configuration"));
6118 p->config_hardware_path[0] = 0;
6119 p->config_host_path[0] = 0;
6120
6121 p->gfx_scandoubler = false;
6122 p->start_gui = true;
6123 p->start_debugger = false;
6124
6125 p->all_lines = 0;
6126 /* Note to porters: please don't change any of these options! UAE is supposed
6127 * to behave identically on all platforms if possible.
6128 * (TW says: maybe it is time to update default config..) */
6129 p->illegal_mem = 0;
6130 p->use_serial = 0;
6131 p->serial_demand = 0;
6132 p->serial_hwctsrts = 1;
6133 p->serial_stopbits = 0;
6134 p->parallel_demand = 0;
6135 p->parallel_matrix_emulation = 0;
6136 p->parallel_postscript_emulation = 0;
6137 p->parallel_postscript_detection = 0;
6138 p->parallel_autoflush_time = 5;
6139 p->ghostscript_parameters[0] = 0;
6140 p->uae_hide = 0;
6141 p->uae_hide_autoconfig = false;
6142 p->z3_mapping_mode = Z3MAPPING_AUTO;
6143
6144 p->mountitems = 0;
6145 for (i = 0; i < MOUNT_CONFIG_SIZE; i++) {
6146 p->mountconfig[i].configoffset = -1;
6147 p->mountconfig[i].unitnum = -1;
6148 }
6149
6150 memset (&p->jports[0], 0, sizeof (struct jport));
6151 memset (&p->jports[1], 0, sizeof (struct jport));
6152 memset (&p->jports[2], 0, sizeof (struct jport));
6153 memset (&p->jports[3], 0, sizeof (struct jport));
6154 p->jports[0].id = JSEM_MICE;
6155 p->jports[1].id = JSEM_KBDLAYOUT;
6156 p->jports[2].id = -1;
6157 p->jports[3].id = -1;
6158 p->keyboard_lang = KBD_LANG_US;
6159
6160 p->produce_sound = 3;
6161 p->sound_stereo = SND_STEREO;
6162 p->sound_stereo_separation = 7;
6163 p->sound_mixed_stereo_delay = 0;
6164 p->sound_freq = DEFAULT_SOUND_FREQ;
6165 p->sound_maxbsiz = DEFAULT_SOUND_MAXB;
6166 p->sound_interpol = 1;
6167 p->sound_filter = FILTER_SOUND_EMUL;
6168 p->sound_filter_type = 0;
6169 p->sound_auto = 1;
6170 p->sound_cdaudio = false;
6171 p->sampler_stereo = false;
6172 p->sampler_buffer = 0;
6173 p->sampler_freq = 0;
6174
6175 p->comptrustbyte = 0;
6176 p->comptrustword = 0;
6177 p->comptrustlong = 0;
6178 p->comptrustnaddr= 0;
6179 p->compnf = 1;
6180 p->comp_hardflush = 0;
6181 p->comp_constjump = 1;
6182 #ifdef USE_JIT_FPU
6183 p->compfpu = 1;
6184 #else
6185 p->compfpu = 0;
6186 #endif
6187 p->cachesize = 0;
6188
6189 p->gfx_framerate = 1;
6190 p->gfx_autoframerate = 50;
6191 p->gfx_size_fs.width = 800;
6192 p->gfx_size_fs.height = 600;
6193 p->gfx_size_win.width = 720;
6194 p->gfx_size_win.height = 568;
6195 for (i = 0; i < 4; i++) {
6196 p->gfx_size_fs_xtra[i].width = 0;
6197 p->gfx_size_fs_xtra[i].height = 0;
6198 p->gfx_size_win_xtra[i].width = 0;
6199 p->gfx_size_win_xtra[i].height = 0;
6200 }
6201 p->gfx_resolution = RES_HIRES;
6202 p->gfx_vresolution = VRES_DOUBLE;
6203 p->gfx_iscanlines = 1;
6204 p->gfx_apmode[0].gfx_fullscreen = GFX_WINDOW;
6205 p->gfx_apmode[1].gfx_fullscreen = GFX_WINDOW;
6206 p->gfx_xcenter = 0; p->gfx_ycenter = 0;
6207 p->gfx_xcenter_pos = -1;
6208 p->gfx_ycenter_pos = -1;
6209 p->gfx_xcenter_size = -1;
6210 p->gfx_ycenter_size = -1;
6211 p->gfx_max_horizontal = RES_HIRES;
6212 p->gfx_max_vertical = VRES_DOUBLE;
6213 p->gfx_autoresolution_minv = 0;
6214 p->gfx_autoresolution_minh = 0;
6215 p->color_mode = 2;
6216 p->gfx_blackerthanblack = 0;
6217 p->gfx_autoresolution_vga = true;
6218 p->gfx_apmode[0].gfx_backbuffers = 2;
6219 p->gfx_apmode[1].gfx_backbuffers = 1;
6220
6221 p->immediate_blits = 0;
6222 p->waiting_blits = 0;
6223 p->collision_level = 2;
6224 p->leds_on_screen = 0;
6225 p->leds_on_screen_mask[0] = p->leds_on_screen_mask[1] = (1 << LED_MAX) - 1;
6226 p->keyboard_leds_in_use = 0;
6227 p->keyboard_leds[0] = p->keyboard_leds[1] = p->keyboard_leds[2] = 0;
6228 p->scsi = 0;
6229 p->uaeserial = 0;
6230 p->cpu_idle = 0;
6231 p->turbo_emulation = 0;
6232 p->turbo_emulation_limit = 0;
6233 p->headless = 0;
6234 p->catweasel = 0;
6235 p->tod_hack = 0;
6236 p->maprom = 0;
6237 p->boot_rom = 0;
6238 p->filesys_no_uaefsdb = 0;
6239 p->filesys_custom_uaefsdb = 1;
6240 p->picasso96_nocustom = 1;
6241 p->cart_internal = 1;
6242 p->sana2 = 0;
6243 p->clipboard_sharing = false;
6244 p->native_code = false;
6245
6246 p->cs_compatible = 1;
6247 p->cs_rtc = 2;
6248 p->cs_df0idhw = 1;
6249 p->cs_a1000ram = 0;
6250 p->cs_fatgaryrev = -1;
6251 p->cs_ramseyrev = -1;
6252 p->cs_agnusrev = -1;
6253 p->cs_deniserev = -1;
6254 p->cs_mbdmac = 0;
6255 p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = p->cs_cd32fmv = false;
6256 p->cs_cd32nvram_size = 1024;
6257 p->cs_cdtvcd = p->cs_cdtvram = false;
6258 p->cs_cdtvcard = 0;
6259 p->cs_pcmcia = 0;
6260 p->cs_ksmirror_e0 = 1;
6261 p->cs_ksmirror_a8 = 0;
6262 p->cs_ciaoverlay = 1;
6263 p->cs_ciaatod = 0;
6264 p->cs_df0idhw = 1;
6265 p->cs_slowmemisfast = 0;
6266 p->cs_resetwarning = 1;
6267 p->cs_ciatodbug = false;
6268
6269 for (int i = APMODE_NATIVE; i <= APMODE_RTG; i++) {
6270 struct gfx_filterdata *f = &p->gf[i];
6271 f->gfx_filter = 0;
6272 f->gfx_filter_scanlineratio = (1 << 4) | 1;
6273 for (int j = 0; j <= 2 * MAX_FILTERSHADERS; j++) {
6274 f->gfx_filtershader[i][0] = 0;
6275 f->gfx_filtermask[i][0] = 0;
6276 }
6277 f->gfx_filter_horiz_zoom_mult = 1.0;
6278 f->gfx_filter_vert_zoom_mult = 1.0;
6279 f->gfx_filter_bilinear = 0;
6280 f->gfx_filter_filtermode = 0;
6281 f->gfx_filter_keep_aspect = 0;
6282 f->gfx_filter_autoscale = AUTOSCALE_STATIC_AUTO;
6283 f->gfx_filter_keep_autoscale_aspect = false;
6284 f->gfx_filteroverlay_overscan = 0;
6285 }
6286
6287 p->rtg_horiz_zoom_mult = 1.0;
6288 p->rtg_vert_zoom_mult = 1.0;
6289
6290 _tcscpy (p->floppyslots[0].df, _T("df0.adf"));
6291 _tcscpy (p->floppyslots[1].df, _T("df1.adf"));
6292 _tcscpy (p->floppyslots[2].df, _T("df2.adf"));
6293 _tcscpy (p->floppyslots[3].df, _T("df3.adf"));
6294
6295 for (int i = 0; i < MAX_LUA_STATES; i++) {
6296 p->luafiles[i][0] = 0;
6297 }
6298
6299 configure_rom (p, roms, 0);
6300 _tcscpy (p->romextfile, _T(""));
6301 _tcscpy (p->romextfile2, _T(""));
6302 p->romextfile2addr = 0;
6303 _tcscpy (p->flashfile, _T(""));
6304 _tcscpy (p->cartfile, _T(""));
6305 _tcscpy (p->rtcfile, _T(""));
6306
6307 _tcscpy (p->path_rom.path[0], _T("./"));
6308 _tcscpy (p->path_floppy.path[0], _T("./"));
6309 _tcscpy (p->path_hardfile.path[0], _T("./"));
6310
6311 p->prtname[0] = 0;
6312 p->sername[0] = 0;
6313
6314 p->cpu_thread = false;
6315
6316 p->fpu_model = 0;
6317 p->cpu_model = 68000;
6318 p->m68k_speed_throttle = 0;
6319 p->cpu_clock_multiplier = 0;
6320 p->cpu_frequency = 0;
6321 p->mmu_model = 0;
6322 p->cpu060_revision = 6;
6323 p->fpu_revision = 0;
6324 p->fpu_no_unimplemented = false;
6325 p->int_no_unimplemented = false;
6326 p->fpu_strict = 0;
6327 p->fpu_softfloat = 0;
6328 p->m68k_speed = 0;
6329 p->cpu_compatible = 1;
6330 p->address_space_24 = 1;
6331 p->cpu_cycle_exact = 0;
6332 p->cpu_memory_cycle_exact = 0;
6333 p->blitter_cycle_exact = 0;
6334 p->chipset_mask = CSMASK_ECS_AGNUS;
6335 p->genlock = 0;
6336 p->genlock_image = 0;
6337 p->genlock_mix = 0;
6338 p->ntscmode = 0;
6339 p->filesys_limit = 0;
6340 p->filesys_max_name = 107;
6341 p->filesys_max_file_size = 0x7fffffff;
6342
6343 p->fastmem_size = 0x00000000;
6344 p->fastmem2_size = 0x00000000;
6345 p->mem25bit_size = 0x00000000;
6346 p->mbresmem_low_size = 0x00000000;
6347 p->mbresmem_high_size = 0x00000000;
6348 p->z3fastmem_size = 0x00000000;
6349 p->z3fastmem2_size = 0x00000000;
6350 p->z3autoconfig_start = 0x10000000;
6351 p->chipmem_size = 0x00080000;
6352 p->bogomem_size = 0x00080000;
6353 p->rtgmem_size = 0x00000000;
6354 p->rtgmem_type = GFXBOARD_UAE_Z3;
6355 p->custom_memory_addrs[0] = 0;
6356 p->custom_memory_sizes[0] = 0;
6357 p->custom_memory_addrs[1] = 0;
6358 p->custom_memory_sizes[1] = 0;
6359 p->fastmem_autoconfig = true;
6360
6361 p->nr_floppies = 2;
6362 p->floppy_read_only = false;
6363 p->floppyslots[0].dfxtype = DRV_35_DD;
6364 p->floppyslots[1].dfxtype = DRV_35_DD;
6365 p->floppyslots[2].dfxtype = DRV_NONE;
6366 p->floppyslots[3].dfxtype = DRV_NONE;
6367 p->floppy_speed = 100;
6368 p->floppy_write_length = 0;
6369 p->floppy_random_bits_min = 1;
6370 p->floppy_random_bits_max = 3;
6371 p->dfxclickvolume_disk[0] = 33;
6372 p->dfxclickvolume_disk[1] = 33;
6373 p->dfxclickvolume_empty[0] = 33;
6374 p->dfxclickvolume_empty[1] = 33;
6375 p->dfxclickchannelmask = 0xffff;
6376 p->cd_speed = 100;
6377
6378 p->statecapturebuffersize = 100;
6379 p->statecapturerate = 5 * 50;
6380 p->inprec_autoplay = true;
6381
6382 #ifdef UAE_MINI
6383 default_prefs_mini (p, 0);
6384 #endif
6385
6386 p->input_tablet = TABLET_OFF;
6387 p->tablet_library = false;
6388 p->input_magic_mouse = 0;
6389 p->input_magic_mouse_cursor = 0;
6390
6391 inputdevice_default_prefs (p);
6392
6393 blkdev_default_prefs (p);
6394
6395 p->cr_selected = -1;
6396 struct chipset_refresh *cr;
6397 for (int i = 0; i < MAX_CHIPSET_REFRESH_TOTAL; i++) {
6398 cr = &p->cr[i];
6399 cr->index = i;
6400 cr->rate = -1;
6401 }
6402 cr = &p->cr[CHIPSET_REFRESH_PAL];
6403 cr->index = CHIPSET_REFRESH_PAL;
6404 cr->horiz = -1;
6405 cr->vert = -1;
6406 cr->lace = -1;
6407 cr->vsync = - 1;
6408 cr->framelength = -1;
6409 cr->rate = 50.0;
6410 cr->ntsc = 0;
6411 cr->locked = false;
6412 _tcscpy (cr->label, _T("PAL"));
6413 cr = &p->cr[CHIPSET_REFRESH_NTSC];
6414 cr->index = CHIPSET_REFRESH_NTSC;
6415 cr->horiz = -1;
6416 cr->vert = -1;
6417 cr->lace = -1;
6418 cr->vsync = - 1;
6419 cr->framelength = -1;
6420 cr->rate = 60.0;
6421 cr->ntsc = 1;
6422 cr->locked = false;
6423 _tcscpy (cr->label, _T("NTSC"));
6424
6425 savestate_state = 0;
6426
6427 target_default_options (p, type);
6428
6429 zfile_fclose (default_file);
6430 default_file = NULL;
6431 f = zfile_fopen_empty (NULL, _T("configstore"));
6432 if (f) {
6433 uaeconfig++;
6434 cfgfile_save_options (f, p, 0);
6435 uaeconfig--;
6436 cfg_write (&zero, f);
6437 default_file = f;
6438 }
6439 }
6440
buildin_default_prefs_68020(struct uae_prefs * p)6441 static void buildin_default_prefs_68020 (struct uae_prefs *p)
6442 {
6443 p->cpu_model = 68020;
6444 p->address_space_24 = 1;
6445 p->cpu_compatible = 1;
6446 p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE | CSMASK_AGA;
6447 p->chipmem_size = 0x200000;
6448 p->bogomem_size = 0;
6449 p->m68k_speed = -1;
6450 }
6451
buildin_default_host_prefs(struct uae_prefs * p)6452 static void buildin_default_host_prefs (struct uae_prefs *p)
6453 {
6454 #if 0
6455 p->sound_filter = FILTER_SOUND_OFF;
6456 p->sound_stereo = SND_STEREO;
6457 p->sound_stereo_separation = 7;
6458 p->sound_mixed_stereo = 0;
6459 #endif
6460 }
6461
buildin_default_prefs(struct uae_prefs * p)6462 static void buildin_default_prefs (struct uae_prefs *p)
6463 {
6464 buildin_default_host_prefs (p);
6465
6466 p->floppyslots[0].dfxtype = DRV_35_DD;
6467 if (p->nr_floppies != 1 && p->nr_floppies != 2)
6468 p->nr_floppies = 2;
6469 p->floppyslots[1].dfxtype = p->nr_floppies >= 2 ? DRV_35_DD : DRV_NONE;
6470 p->floppyslots[2].dfxtype = DRV_NONE;
6471 p->floppyslots[3].dfxtype = DRV_NONE;
6472 p->floppy_speed = 100;
6473
6474 p->fpu_model = 0;
6475 p->cpu_model = 68000;
6476 p->cpu_clock_multiplier = 0;
6477 p->cpu_frequency = 0;
6478 p->cpu060_revision = 1;
6479 p->fpu_revision = -1;
6480 p->m68k_speed = 0;
6481 p->cpu_compatible = 1;
6482 p->address_space_24 = 1;
6483 p->cpu_cycle_exact = 0;
6484 p->cpu_memory_cycle_exact = 0;
6485 p->blitter_cycle_exact = 0;
6486 p->chipset_mask = CSMASK_ECS_AGNUS;
6487 p->immediate_blits = 0;
6488 p->waiting_blits = 0;
6489 p->collision_level = 2;
6490 if (p->produce_sound < 1)
6491 p->produce_sound = 1;
6492 p->scsi = 0;
6493 p->uaeserial = 0;
6494 p->cpu_idle = 0;
6495 p->turbo_emulation = 0;
6496 p->turbo_emulation_limit = 0;
6497 p->catweasel = 0;
6498 p->tod_hack = 0;
6499 p->maprom = 0;
6500 p->cachesize = 0;
6501 p->socket_emu = 0;
6502 p->sound_volume_master = 0;
6503 p->sound_volume_paula = 0;
6504 p->sound_volume_cd = 0;
6505 p->clipboard_sharing = false;
6506 p->ppc_mode = 0;
6507
6508 p->chipmem_size = 0x00080000;
6509 p->bogomem_size = 0x00080000;
6510 p->fastmem_size = 0x00000000;
6511 p->mem25bit_size = 0x00000000;
6512 p->mbresmem_low_size = 0x00000000;
6513 p->mbresmem_high_size = 0x00000000;
6514 p->z3fastmem_size = 0x00000000;
6515 p->z3fastmem2_size = 0x00000000;
6516 p->z3chipmem_size = 0x00000000;
6517 p->rtgmem_size = 0x00000000;
6518 p->rtgmem_type = GFXBOARD_UAE_Z3;
6519
6520 p->cs_rtc = 0;
6521 p->cs_a1000ram = false;
6522 p->cs_fatgaryrev = -1;
6523 p->cs_ramseyrev = -1;
6524 p->cs_agnusrev = -1;
6525 p->cs_deniserev = -1;
6526 p->cs_mbdmac = 0;
6527 p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = p->cs_cd32fmv = false;
6528 p->cs_cdtvcd = p->cs_cdtvram = p->cs_cdtvcard = false;
6529 p->cs_ide = 0;
6530 p->cs_pcmcia = 0;
6531 p->cs_ksmirror_e0 = 1;
6532 p->cs_ksmirror_a8 = 0;
6533 p->cs_ciaoverlay = 1;
6534 p->cs_ciaatod = 0;
6535 p->cs_df0idhw = 1;
6536 p->cs_resetwarning = 0;
6537 p->cs_ciatodbug = false;
6538 p->cs_1mchipjumper = false;
6539
6540 _tcscpy (p->romextfile, _T(""));
6541 _tcscpy (p->romextfile2, _T(""));
6542 set_device_rom(p, NULL, ROMTYPE_CPUBOARD, 0);
6543
6544 p->prtname[0] = 0;
6545 p->sername[0] = 0;
6546
6547 p->mountitems = 0;
6548
6549 target_default_options (p, 1);
6550 }
6551
set_68020_compa(struct uae_prefs * p,int compa,int cd32)6552 static void set_68020_compa (struct uae_prefs *p, int compa, int cd32)
6553 {
6554 switch (compa)
6555 {
6556 case 0:
6557 p->blitter_cycle_exact = 1;
6558 p->m68k_speed = 0;
6559 if (p->cpu_model == 68020 && p->cachesize == 0) {
6560 p->cpu_cycle_exact = 1;
6561 p->cpu_memory_cycle_exact = 1;
6562 p->cpu_clock_multiplier = 4 << 8;
6563 }
6564 break;
6565 case 1:
6566 p->cpu_compatible = true;
6567 p->m68k_speed = 0;
6568 break;
6569 case 2:
6570 p->cpu_compatible = 0;
6571 p->m68k_speed = -1;
6572 p->address_space_24 = 0;
6573 break;
6574 case 3:
6575 p->cpu_compatible = 0;
6576 p->address_space_24 = 0;
6577 p->cachesize = MAX_JIT_CACHE;
6578 break;
6579 }
6580 }
6581
6582 /* 0: cycle-exact
6583 * 1: more compatible
6584 * 2: no more compatible, no 100% sound
6585 * 3: no more compatible, waiting blits, no 100% sound
6586 */
6587
set_68000_compa(struct uae_prefs * p,int compa)6588 static void set_68000_compa (struct uae_prefs *p, int compa)
6589 {
6590 p->cpu_clock_multiplier = 2 << 8;
6591 switch (compa)
6592 {
6593 case 0:
6594 p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = 1;
6595 break;
6596 case 1:
6597 break;
6598 case 2:
6599 p->cpu_compatible = 0;
6600 break;
6601 case 3:
6602 p->produce_sound = 2;
6603 p->cpu_compatible = 0;
6604 break;
6605 }
6606 }
6607
bip_a3000(struct uae_prefs * p,int config,int compa,int romcheck)6608 static int bip_a3000 (struct uae_prefs *p, int config, int compa, int romcheck)
6609 {
6610 int roms[2];
6611
6612 if (config == 2)
6613 roms[0] = 61;
6614 else if (config == 1)
6615 roms[0] = 71;
6616 else
6617 roms[0] = 59;
6618 roms[1] = -1;
6619 p->bogomem_size = 0;
6620 p->chipmem_size = 0x200000;
6621 p->cpu_model = 68030;
6622 p->fpu_model = 68882;
6623 p->fpu_no_unimplemented = true;
6624 if (compa == 0)
6625 p->mmu_model = 68030;
6626 else
6627 p->cachesize = MAX_JIT_CACHE;
6628 p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
6629 p->cpu_compatible = p->address_space_24 = 0;
6630 p->m68k_speed = -1;
6631 p->immediate_blits = 0;
6632 p->produce_sound = 2;
6633 p->floppyslots[0].dfxtype = DRV_35_HD;
6634 p->floppy_speed = 0;
6635 p->cpu_idle = 150;
6636 p->cs_compatible = CP_A3000;
6637 p->mbresmem_low_size = 8 * 1024 * 1024;
6638 built_in_chipset_prefs (p);
6639 p->cs_ciaatod = p->ntscmode ? 2 : 1;
6640 return configure_rom (p, roms, romcheck);
6641 }
bip_a4000(struct uae_prefs * p,int config,int compa,int romcheck)6642 static int bip_a4000 (struct uae_prefs *p, int config, int compa, int romcheck)
6643 {
6644 int roms[8];
6645
6646 roms[0] = 16;
6647 roms[1] = 31;
6648 roms[2] = 13;
6649 roms[3] = 12;
6650 roms[4] = -1;
6651
6652 p->bogomem_size = 0;
6653 p->chipmem_size = 0x200000;
6654 p->mbresmem_low_size = 8 * 1024 * 1024;
6655 p->cpu_model = 68030;
6656 p->fpu_model = 68882;
6657 switch (config)
6658 {
6659 case 1:
6660 p->cpu_model = 68040;
6661 p->fpu_model = 68040;
6662 break;
6663 case 2:
6664 p->cpu_model = 68060;
6665 p->fpu_model = 68060;
6666 p->ppc_mode = 1;
6667 cpuboard_setboard(p, BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_PPC);
6668 p->cpuboardmem1_size = 128 * 1024 * 1024;
6669 int roms_ppc[] = { 98, -1 };
6670 configure_rom(p, roms_ppc, romcheck);
6671 break;
6672 }
6673 p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
6674 p->cpu_compatible = p->address_space_24 = 0;
6675 p->m68k_speed = -1;
6676 p->immediate_blits = 0;
6677 p->produce_sound = 2;
6678 p->cachesize = MAX_JIT_CACHE;
6679 p->floppyslots[0].dfxtype = DRV_35_HD;
6680 p->floppyslots[1].dfxtype = DRV_35_HD;
6681 p->floppy_speed = 0;
6682 p->cpu_idle = 150;
6683 p->cs_compatible = CP_A4000;
6684 built_in_chipset_prefs (p);
6685 p->cs_ciaatod = p->ntscmode ? 2 : 1;
6686 return configure_rom (p, roms, romcheck);
6687 }
bip_a4000t(struct uae_prefs * p,int config,int compa,int romcheck)6688 static int bip_a4000t (struct uae_prefs *p, int config, int compa, int romcheck)
6689 {
6690
6691 int roms[8];
6692
6693 roms[0] = 16;
6694 roms[1] = 31;
6695 roms[2] = 13;
6696 roms[3] = -1;
6697
6698 p->bogomem_size = 0;
6699 p->chipmem_size = 0x200000;
6700 p->mbresmem_low_size = 8 * 1024 * 1024;
6701 p->cpu_model = 68030;
6702 p->fpu_model = 68882;
6703 if (config > 0) {
6704 p->cpu_model = 68040;
6705 p->fpu_model = 68040;
6706 }
6707 p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
6708 p->cpu_compatible = p->address_space_24 = 0;
6709 p->m68k_speed = -1;
6710 p->immediate_blits = 0;
6711 p->produce_sound = 2;
6712 p->cachesize = MAX_JIT_CACHE;
6713 p->floppyslots[0].dfxtype = DRV_35_HD;
6714 p->floppyslots[1].dfxtype = DRV_35_HD;
6715 p->floppy_speed = 0;
6716 p->cpu_idle = 150;
6717 p->cs_compatible = CP_A4000T;
6718 built_in_chipset_prefs (p);
6719 p->cs_ciaatod = p->ntscmode ? 2 : 1;
6720 return configure_rom (p, roms, romcheck);
6721 }
6722
bip_velvet(struct uae_prefs * p,int config,int compa,int romcheck)6723 static void bip_velvet(struct uae_prefs *p, int config, int compa, int romcheck)
6724 {
6725 p->chipset_mask = 0;
6726 p->bogomem_size = 0;
6727 p->sound_filter = FILTER_SOUND_ON;
6728 set_68000_compa (p, compa);
6729 p->floppyslots[1].dfxtype = DRV_NONE;
6730 p->cs_compatible = CP_VELVET;
6731 p->cs_slowmemisfast = 1;
6732 p->cs_dipagnus = 1;
6733 p->cs_agnusbltbusybug = 1;
6734 built_in_chipset_prefs (p);
6735 p->cs_denisenoehb = 1;
6736 p->cs_cia6526 = 1;
6737 p->chipmem_size = 0x40000;
6738 }
6739
bip_a1000(struct uae_prefs * p,int config,int compa,int romcheck)6740 static int bip_a1000 (struct uae_prefs *p, int config, int compa, int romcheck)
6741 {
6742 int roms[2];
6743
6744 #ifdef FSUAE
6745 roms[0] = 5;
6746 #else
6747 roms[0] = 24;
6748 #endif
6749 roms[1] = -1;
6750 p->chipset_mask = 0;
6751 p->bogomem_size = 0;
6752 p->sound_filter = FILTER_SOUND_ON;
6753 set_68000_compa (p, compa);
6754 p->floppyslots[1].dfxtype = DRV_NONE;
6755 p->cs_compatible = CP_A1000;
6756 p->cs_slowmemisfast = 1;
6757 p->cs_dipagnus = 1;
6758 p->cs_agnusbltbusybug = 1;
6759 built_in_chipset_prefs (p);
6760 if (config > 0)
6761 p->cs_denisenoehb = 1;
6762 if (config > 1)
6763 p->chipmem_size = 0x40000;
6764 if (config > 2) {
6765 roms[0] = 125;
6766 roms[1] = -1;
6767 bip_velvet(p, config, compa, romcheck);
6768 }
6769 return configure_rom (p, roms, romcheck);
6770 }
6771
bip_cdtvcr(struct uae_prefs * p,int config,int compa,int romcheck)6772 static int bip_cdtvcr (struct uae_prefs *p, int config, int compa, int romcheck)
6773 {
6774 int roms[4];
6775
6776 p->bogomem_size = 0;
6777 p->chipmem_size = 0x100000;
6778 p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
6779 p->cs_cdtvcd = p->cs_cdtvram = true;
6780 p->cs_cdtvcr = true;
6781 p->cs_rtc = 1;
6782 p->nr_floppies = 0;
6783 p->floppyslots[0].dfxtype = DRV_NONE;
6784 if (config > 0)
6785 p->floppyslots[0].dfxtype = DRV_35_DD;
6786 p->floppyslots[1].dfxtype = DRV_NONE;
6787 set_68000_compa (p, compa);
6788 p->cs_compatible = CP_CDTVCR;
6789 built_in_chipset_prefs (p);
6790 fetch_datapath (p->flashfile, sizeof (p->flashfile) / sizeof (TCHAR));
6791 _tcscat (p->flashfile, _T("cdtv-cr.nvr"));
6792 roms[0] = 9;
6793 roms[1] = 10;
6794 roms[2] = -1;
6795 if (!configure_rom (p, roms, romcheck))
6796 return 0;
6797 roms[0] = 108;
6798 roms[1] = 107;
6799 roms[2] = -1;
6800 if (!configure_rom (p, roms, romcheck))
6801 return 0;
6802 return 1;
6803 }
6804
bip_cdtv(struct uae_prefs * p,int config,int compa,int romcheck)6805 static int bip_cdtv (struct uae_prefs *p, int config, int compa, int romcheck)
6806 {
6807 int roms[4];
6808
6809 if (config >= 2)
6810 return bip_cdtvcr(p, config - 2, compa, romcheck);
6811
6812 p->bogomem_size = 0;
6813 p->chipmem_size = 0x100000;
6814 p->chipset_mask = CSMASK_ECS_AGNUS;
6815 p->cs_cdtvcd = p->cs_cdtvram = 1;
6816 if (config > 0)
6817 p->cs_cdtvcard = 64;
6818 p->cs_rtc = 1;
6819 p->nr_floppies = 0;
6820 p->floppyslots[0].dfxtype = DRV_NONE;
6821 if (config > 0)
6822 p->floppyslots[0].dfxtype = DRV_35_DD;
6823 p->floppyslots[1].dfxtype = DRV_NONE;
6824 set_68000_compa (p, compa);
6825 p->cs_compatible = CP_CDTV;
6826 built_in_chipset_prefs (p);
6827 fetch_datapath (p->flashfile, sizeof (p->flashfile) / sizeof (TCHAR));
6828 _tcscat (p->flashfile, _T("cdtv.nvr"));
6829 roms[0] = 6;
6830 roms[1] = 32;
6831 roms[2] = -1;
6832 if (!configure_rom (p, roms, romcheck))
6833 return 0;
6834 roms[0] = 20;
6835 roms[1] = 21;
6836 roms[2] = 22;
6837 roms[3] = -1;
6838 if (!configure_rom (p, roms, romcheck))
6839 return 0;
6840 return 1;
6841 }
6842
bip_cd32(struct uae_prefs * p,int config,int compa,int romcheck)6843 static int bip_cd32 (struct uae_prefs *p, int config, int compa, int romcheck)
6844 {
6845 int roms[3];
6846
6847 buildin_default_prefs_68020 (p);
6848 p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = true;
6849 p->nr_floppies = 0;
6850 p->floppyslots[0].dfxtype = DRV_NONE;
6851 p->floppyslots[1].dfxtype = DRV_NONE;
6852 set_68020_compa (p, compa, 1);
6853 p->cs_compatible = CP_CD32;
6854 built_in_chipset_prefs (p);
6855 fetch_datapath (p->flashfile, sizeof (p->flashfile) / sizeof (TCHAR));
6856 _tcscat (p->flashfile, _T("cd32.nvr"));
6857 roms[0] = 64;
6858 roms[1] = -1;
6859 if (!configure_rom (p, roms, 0)) {
6860 roms[0] = 18;
6861 roms[1] = -1;
6862 if (!configure_rom (p, roms, romcheck))
6863 return 0;
6864 roms[0] = 19;
6865 if (!configure_rom (p, roms, romcheck))
6866 return 0;
6867 }
6868 if (config > 0) {
6869 p->cs_cd32fmv = true;
6870 roms[0] = 74;
6871 roms[1] = 23;
6872 roms[2] = -1;
6873 if (!configure_rom (p, roms, romcheck))
6874 return 0;
6875 }
6876 return 1;
6877 }
6878
bip_a1200(struct uae_prefs * p,int config,int compa,int romcheck)6879 static int bip_a1200 (struct uae_prefs *p, int config, int compa, int romcheck)
6880 {
6881 int roms[4];
6882 int roms_bliz[2];
6883
6884 buildin_default_prefs_68020 (p);
6885 roms[0] = 11;
6886 roms[1] = 15;
6887 roms[2] = 31;
6888 roms[3] = -1;
6889 #ifdef FSUAE
6890 roms[1] = -1;
6891 #endif
6892 roms_bliz[0] = -1;
6893 roms_bliz[1] = -1;
6894 p->cs_rtc = 0;
6895 p->cs_compatible = CP_A1200;
6896 built_in_chipset_prefs (p);
6897 switch (config)
6898 {
6899 case 1:
6900 p->fastmem_size = 0x400000;
6901 p->cs_rtc = 1;
6902 break;
6903 case 2:
6904 cpuboard_setboard(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1230IV);
6905 p->cpuboardmem1_size = 32 * 1024 * 1024;
6906 p->cpu_model = 68030;
6907 p->cs_rtc = 1;
6908 roms_bliz[0] = 89;
6909 configure_rom(p, roms_bliz, romcheck);
6910 break;
6911 case 3:
6912 cpuboard_setboard(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1260);
6913 p->cpuboardmem1_size = 32 * 1024 * 1024;
6914 p->cpu_model = 68040;
6915 p->fpu_model = 68040;
6916 p->cs_rtc = 1;
6917 roms_bliz[0] = 90;
6918 configure_rom(p, roms_bliz, romcheck);
6919 break;
6920 case 4:
6921 cpuboard_setboard(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1260);
6922 p->cpuboardmem1_size = 32 * 1024 * 1024;
6923 p->cpu_model = 68060;
6924 p->fpu_model = 68060;
6925 p->cs_rtc = 1;
6926 roms_bliz[0] = 90;
6927 configure_rom(p, roms_bliz, romcheck);
6928 break;
6929 case 5:
6930 cpuboard_setboard(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC);
6931 p->cpuboardmem1_size = 256 * 1024 * 1024;
6932 p->cpu_model = 68060;
6933 p->fpu_model = 68060;
6934 p->ppc_mode = 1;
6935 p->cs_rtc = 1;
6936 roms[0] = 15;
6937 roms[1] = 11;
6938 roms[2] = -1;
6939 roms_bliz[0] = 100;
6940 configure_rom(p, roms_bliz, romcheck);
6941 break;
6942 #ifdef FSUAE
6943 case 6:
6944 roms[0] = 15;
6945 roms[3] = -1;
6946 break;
6947 #endif
6948 }
6949 set_68020_compa (p, compa, 0);
6950 return configure_rom (p, roms, romcheck);
6951 }
6952
bip_a600(struct uae_prefs * p,int config,int compa,int romcheck)6953 static int bip_a600 (struct uae_prefs *p, int config, int compa, int romcheck)
6954 {
6955 int roms[4];
6956
6957 roms[0] = 10;
6958 roms[1] = 9;
6959 roms[2] = 8;
6960 roms[3] = -1;
6961 set_68000_compa (p, compa);
6962 p->cs_compatible = CP_A600;
6963 built_in_chipset_prefs (p);
6964 p->bogomem_size = 0;
6965 p->chipmem_size = 0x100000;
6966 if (config > 0)
6967 p->cs_rtc = 1;
6968 if (config == 1)
6969 p->chipmem_size = 0x200000;
6970 if (config == 2)
6971 p->fastmem_size = 0x400000;
6972 p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
6973 return configure_rom (p, roms, romcheck);
6974 }
6975
bip_a500p(struct uae_prefs * p,int config,int compa,int romcheck)6976 static int bip_a500p (struct uae_prefs *p, int config, int compa, int romcheck)
6977 {
6978 int roms[2];
6979
6980 roms[0] = 7;
6981 roms[1] = -1;
6982 set_68000_compa (p, compa);
6983 p->cs_compatible = CP_A500P;
6984 built_in_chipset_prefs (p);
6985 p->bogomem_size = 0;
6986 p->chipmem_size = 0x100000;
6987 if (config > 0)
6988 p->cs_rtc = 1;
6989 if (config == 1)
6990 p->chipmem_size = 0x200000;
6991 if (config == 2)
6992 p->fastmem_size = 0x400000;
6993 p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
6994 return configure_rom (p, roms, romcheck);
6995 }
bip_a500(struct uae_prefs * p,int config,int compa,int romcheck)6996 static int bip_a500 (struct uae_prefs *p, int config, int compa, int romcheck)
6997 {
6998 int roms[4];
6999
7000 roms[0] = roms[1] = roms[2] = roms[3] = -1;
7001 switch (config)
7002 {
7003 case 0: // KS 1.3, OCS Agnus, 0.5M Chip + 0.5M Slow
7004 roms[0] = 6;
7005 roms[1] = 32;
7006 p->chipset_mask = 0;
7007 break;
7008 case 1: // KS 1.3, ECS Agnus, 0.5M Chip + 0.5M Slow
7009 roms[0] = 6;
7010 roms[1] = 32;
7011 break;
7012 case 2: // KS 1.3, ECS Agnus, 1.0M Chip
7013 roms[0] = 6;
7014 roms[1] = 32;
7015 p->bogomem_size = 0;
7016 p->chipmem_size = 0x100000;
7017 break;
7018 case 3: // KS 1.3, OCS Agnus, 0.5M Chip
7019 roms[0] = 6;
7020 roms[1] = 32;
7021 p->bogomem_size = 0;
7022 p->chipset_mask = 0;
7023 p->cs_rtc = 0;
7024 p->floppyslots[1].dfxtype = DRV_NONE;
7025 break;
7026 case 4: // KS 1.2, OCS Agnus, 0.5M Chip
7027 roms[0] = 5;
7028 roms[1] = 4;
7029 roms[2] = 3;
7030 p->bogomem_size = 0;
7031 p->chipset_mask = 0;
7032 p->cs_rtc = 0;
7033 p->floppyslots[1].dfxtype = DRV_NONE;
7034 break;
7035 case 5: // KS 1.2, OCS Agnus, 0.5M Chip + 0.5M Slow
7036 roms[0] = 5;
7037 roms[1] = 4;
7038 roms[2] = 3;
7039 p->chipset_mask = 0;
7040 break;
7041 }
7042 set_68000_compa (p, compa);
7043 p->cs_compatible = CP_A500;
7044 built_in_chipset_prefs (p);
7045 return configure_rom (p, roms, romcheck);
7046 }
7047
bip_super(struct uae_prefs * p,int config,int compa,int romcheck)7048 static int bip_super (struct uae_prefs *p, int config, int compa, int romcheck)
7049 {
7050 int roms[7];
7051
7052 roms[0] = 16;
7053 roms[1] = 31;
7054 roms[2] = 15;
7055 roms[3] = 14;
7056 roms[4] = 12;
7057 roms[5] = 11;
7058 roms[6] = -1;
7059 p->bogomem_size = 0;
7060 p->chipmem_size = 0x400000;
7061 p->z3fastmem_size = 8 * 1024 * 1024;
7062 p->rtgmem_size = 16 * 1024 * 1024;
7063 p->cpu_model = 68040;
7064 p->fpu_model = 68040;
7065 p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
7066 p->cpu_compatible = p->address_space_24 = 0;
7067 p->m68k_speed = -1;
7068 p->immediate_blits = 1;
7069 p->produce_sound = 2;
7070 p->cachesize = MAX_JIT_CACHE;
7071 p->floppyslots[0].dfxtype = DRV_35_HD;
7072 p->floppyslots[1].dfxtype = DRV_35_HD;
7073 p->floppy_speed = 0;
7074 p->cpu_idle = 150;
7075 p->scsi = 1;
7076 p->uaeserial = 1;
7077 p->socket_emu = 1;
7078 p->cart_internal = 0;
7079 p->picasso96_nocustom = 1;
7080 p->cs_compatible = 1;
7081 built_in_chipset_prefs (p);
7082 p->cs_ide = -1;
7083 p->cs_ciaatod = p->ntscmode ? 2 : 1;
7084 //_tcscat(p->flashfile, _T("battclock.nvr"));
7085 return configure_rom (p, roms, romcheck);
7086 }
7087
bip_arcadia(struct uae_prefs * p,int config,int compa,int romcheck)7088 static int bip_arcadia (struct uae_prefs *p, int config, int compa, int romcheck)
7089 {
7090 int roms[4], i;
7091 struct romlist **rl;
7092
7093 p->bogomem_size = 0;
7094 p->chipset_mask = 0;
7095 p->cs_rtc = 0;
7096 p->nr_floppies = 0;
7097 p->floppyslots[0].dfxtype = DRV_NONE;
7098 p->floppyslots[1].dfxtype = DRV_NONE;
7099 set_68000_compa (p, compa);
7100 p->cs_compatible = CP_A500;
7101 built_in_chipset_prefs (p);
7102 fetch_datapath (p->flashfile, sizeof (p->flashfile) / sizeof (TCHAR));
7103 _tcscat (p->flashfile, _T("arcadia.nvr"));
7104 roms[0] = 5;
7105 roms[1] = 4;
7106 roms[2] = -1;
7107 if (!configure_rom (p, roms, romcheck))
7108 return 0;
7109 roms[0] = 51;
7110 roms[1] = 49;
7111 roms[2] = -1;
7112 if (!configure_rom (p, roms, romcheck))
7113 return 0;
7114 rl = getarcadiaroms ();
7115 for (i = 0; rl[i]; i++) {
7116 if (config-- == 0) {
7117 roms[0] = rl[i]->rd->id;
7118 roms[1] = -1;
7119 configure_rom (p, roms, 0);
7120 break;
7121 }
7122 }
7123 xfree (rl);
7124 return 1;
7125 }
7126
built_in_prefs(struct uae_prefs * p,int model,int config,int compa,int romcheck)7127 int built_in_prefs (struct uae_prefs *p, int model, int config, int compa, int romcheck)
7128 {
7129 int v = 0;
7130
7131 buildin_default_prefs (p);
7132 switch (model)
7133 {
7134 case 0:
7135 v = bip_a500 (p, config, compa, romcheck);
7136 break;
7137 case 1:
7138 v = bip_a500p (p, config, compa, romcheck);
7139 break;
7140 case 2:
7141 v = bip_a600 (p, config, compa, romcheck);
7142 break;
7143 case 3:
7144 v = bip_a1000 (p, config, compa, romcheck);
7145 break;
7146 case 4:
7147 v = bip_a1200 (p, config, compa, romcheck);
7148 break;
7149 case 5:
7150 v = bip_a3000 (p, config, compa, romcheck);
7151 break;
7152 case 6:
7153 v = bip_a4000 (p, config, compa, romcheck);
7154 break;
7155 case 7:
7156 v = bip_a4000t (p, config, compa, romcheck);
7157 break;
7158 case 8:
7159 v = bip_cd32 (p, config, compa, romcheck);
7160 break;
7161 case 9:
7162 v = bip_cdtv (p, config, compa, romcheck);
7163 break;
7164 case 10:
7165 v = bip_arcadia (p, config , compa, romcheck);
7166 break;
7167 case 11:
7168 v = bip_super (p, config, compa, romcheck);
7169 break;
7170 }
7171 if ((p->cpu_model >= 68020 || !p->cpu_cycle_exact || !p->cpu_memory_cycle_exact) && !p->immediate_blits)
7172 p->waiting_blits = 1;
7173 if (p->sound_filter_type == FILTER_SOUND_TYPE_A500 && (p->chipset_mask & CSMASK_AGA))
7174 p->sound_filter_type = FILTER_SOUND_TYPE_A1200;
7175 else if (p->sound_filter_type == FILTER_SOUND_TYPE_A1200 && !(p->chipset_mask & CSMASK_AGA))
7176 p->sound_filter_type = FILTER_SOUND_TYPE_A500;
7177 if (p->cpu_model >= 68040)
7178 p->cs_bytecustomwritebug = true;
7179 return v;
7180 }
7181
7182 #ifdef FSUAE
7183 /**
7184 * This function will be called (twice) by fixup_prefs after custom uae_
7185 * options have been applied, and may reset some (chipset) options overriden
7186 * by the user unless also uae_chipset_compatible has been set to -.
7187 */
7188 #endif
built_in_chipset_prefs(struct uae_prefs * p)7189 int built_in_chipset_prefs (struct uae_prefs *p)
7190 {
7191 #ifdef FSUAE
7192 write_log("built_in_chipset_prefs, ignore = %d\n", !p->cs_compatible);
7193 #endif
7194 if (!p->cs_compatible)
7195 return 1;
7196
7197 p->cs_a1000ram = 0;
7198 p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = 0;
7199 p->cs_cdtvcd = p->cs_cdtvram = p->cs_cdtvscsi = p->cs_cdtvcr = 0;
7200 p->cs_fatgaryrev = -1;
7201 p->cs_ide = 0;
7202 p->cs_ramseyrev = -1;
7203 p->cs_deniserev = -1;
7204 p->cs_agnusrev = -1;
7205 p->cs_denisenoehb = 0;
7206 p->cs_dipagnus = 0;
7207 p->cs_agnusbltbusybug = 0;
7208 p->cs_mbdmac = 0;
7209 p->cs_pcmcia = 0;
7210 p->cs_ksmirror_e0 = 1;
7211 p->cs_ksmirror_a8 = 0;
7212 p->cs_ciaoverlay = 1;
7213 p->cs_ciaatod = 0;
7214 #ifdef FSUAE
7215 /* Allow RTC to be set without disabling cs_compatible */
7216 #else
7217 p->cs_rtc = 0;
7218 #endif
7219 p->cs_rtc_adjust_mode = p->cs_rtc_adjust = 0;
7220 p->cs_df0idhw = 1;
7221 p->cs_resetwarning = 1;
7222 p->cs_slowmemisfast = 0;
7223 p->cs_ciatodbug = false;
7224 p->cs_z3autoconfig = false;
7225 p->cs_bytecustomwritebug = false;
7226
7227 switch (p->cs_compatible)
7228 {
7229 case CP_GENERIC: // generic
7230 if (p->cpu_model >= 68020) {
7231 // big box-like
7232 p->cs_rtc = 2;
7233 p->cs_fatgaryrev = 0;
7234 p->cs_ide = -1;
7235 p->cs_mbdmac = -1;
7236 p->cs_ramseyrev = 0x0f;
7237 } else if (p->cpu_compatible) {
7238 // very A500-like
7239 p->cs_df0idhw = 0;
7240 p->cs_resetwarning = 0;
7241 if (p->bogomem_size || p->chipmem_size > 0x80000 || p->fastmem_size)
7242 p->cs_rtc = 1;
7243 p->cs_ciatodbug = true;
7244 } else {
7245 // sort of A500-like
7246 p->cs_ide = -1;
7247 p->cs_rtc = 1;
7248 }
7249 break;
7250 case CP_CDTV: // CDTV
7251 p->cs_rtc = 1;
7252 p->cs_cdtvcd = p->cs_cdtvram = 1;
7253 p->cs_df0idhw = 1;
7254 p->cs_ksmirror_e0 = 0;
7255 break;
7256 case CP_CDTVCR: // CDTV-CR
7257 p->cs_rtc = 1;
7258 p->cs_cdtvcd = p->cs_cdtvram = 1;
7259 p->cs_cdtvcr = true;
7260 p->cs_df0idhw = 1;
7261 p->cs_ksmirror_e0 = 0;
7262 p->cs_ide = IDE_A600A1200;
7263 p->cs_pcmcia = 1;
7264 p->cs_ksmirror_a8 = 1;
7265 p->cs_ciaoverlay = 0;
7266 p->cs_resetwarning = 0;
7267 p->cs_ciatodbug = true;
7268 break;
7269 case CP_CD32: // CD32
7270 p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = true;
7271 p->cs_ksmirror_e0 = 0;
7272 p->cs_ksmirror_a8 = 1;
7273 p->cs_ciaoverlay = 0;
7274 p->cs_resetwarning = 0;
7275 break;
7276 case CP_A500: // A500
7277 p->cs_df0idhw = 0;
7278 p->cs_resetwarning = 0;
7279 if (p->bogomem_size || p->chipmem_size > 0x80000 || p->fastmem_size)
7280 p->cs_rtc = 1;
7281 p->cs_ciatodbug = true;
7282 break;
7283 case CP_A500P: // A500+
7284 p->cs_rtc = 1;
7285 p->cs_resetwarning = 0;
7286 p->cs_ciatodbug = true;
7287 break;
7288 case CP_A600: // A600
7289 #ifdef FSUAE
7290 if (p->chipmem_size > 0x100000 || p->fastmem_size)
7291 p->cs_rtc = 1;
7292 #endif
7293 p->cs_ide = IDE_A600A1200;
7294 p->cs_pcmcia = 1;
7295 p->cs_ksmirror_a8 = 1;
7296 p->cs_ciaoverlay = 0;
7297 p->cs_resetwarning = 0;
7298 p->cs_ciatodbug = true;
7299 break;
7300 case CP_A1000: // A1000
7301 p->cs_a1000ram = 1;
7302 p->cs_ciaatod = p->ntscmode ? 2 : 1;
7303 p->cs_ksmirror_e0 = 0;
7304 p->cs_agnusbltbusybug = 1;
7305 p->cs_dipagnus = 1;
7306 p->cs_ciatodbug = true;
7307 break;
7308 case CP_VELVET: // A1000 Prototype
7309 p->cs_ciaatod = p->ntscmode ? 2 : 1;
7310 p->cs_ksmirror_e0 = 0;
7311 p->cs_agnusbltbusybug = 1;
7312 p->cs_dipagnus = 1;
7313 p->cs_denisenoehb = 1;
7314 break;
7315 case CP_A1200: // A1200
7316 p->cs_ide = IDE_A600A1200;
7317 p->cs_pcmcia = 1;
7318 p->cs_ksmirror_a8 = 1;
7319 p->cs_ciaoverlay = 0;
7320 if (p->fastmem_size || p->z3fastmem_size || p->cpuboard_type)
7321 p->cs_rtc = 1;
7322 break;
7323 case CP_A2000: // A2000
7324 p->cs_rtc = 1;
7325 p->cs_ciaatod = p->ntscmode ? 2 : 1;
7326 p->cs_ciatodbug = true;
7327 break;
7328 case CP_A3000: // A3000
7329 p->cs_rtc = 2;
7330 p->cs_fatgaryrev = 0;
7331 p->cs_ramseyrev = 0x0d;
7332 p->cs_mbdmac = 1;
7333 p->cs_ksmirror_e0 = 0;
7334 p->cs_ciaatod = p->ntscmode ? 2 : 1;
7335 p->cs_z3autoconfig = true;
7336 break;
7337 case CP_A3000T: // A3000T
7338 p->cs_rtc = 2;
7339 p->cs_fatgaryrev = 0;
7340 p->cs_ramseyrev = 0x0d;
7341 p->cs_mbdmac = 1;
7342 p->cs_ksmirror_e0 = 0;
7343 p->cs_ciaatod = p->ntscmode ? 2 : 1;
7344 p->cs_z3autoconfig = true;
7345 break;
7346 case CP_A4000: // A4000
7347 p->cs_rtc = 2;
7348 p->cs_fatgaryrev = 0;
7349 p->cs_ramseyrev = 0x0f;
7350 p->cs_ide = IDE_A4000;
7351 p->cs_mbdmac = 0;
7352 p->cs_ksmirror_a8 = 0;
7353 p->cs_ksmirror_e0 = 0;
7354 p->cs_ciaoverlay = 0;
7355 p->cs_z3autoconfig = true;
7356 break;
7357 case CP_A4000T: // A4000T
7358 p->cs_rtc = 2;
7359 p->cs_fatgaryrev = 0;
7360 p->cs_ramseyrev = 0x0f;
7361 p->cs_ide = IDE_A4000;
7362 p->cs_mbdmac = 2;
7363 p->cs_ksmirror_a8 = 0;
7364 p->cs_ksmirror_e0 = 0;
7365 p->cs_ciaoverlay = 0;
7366 p->cs_z3autoconfig = true;
7367 break;
7368 }
7369 if (p->cpu_model >= 68040)
7370 p->cs_bytecustomwritebug = true;
7371 return 1;
7372 }
7373
built_in_cpuboard_prefs(struct uae_prefs * p)7374 int built_in_cpuboard_prefs(struct uae_prefs *p)
7375 {
7376 int roms[2], roms2[2];
7377
7378 roms[0] = -1;
7379 roms[1] = -1;
7380 roms2[0] = -1;
7381 roms2[1] = -1;
7382
7383 switch(cpuboards[p->cpuboard_type].id)
7384 {
7385 case BOARD_MACROSYSTEM:
7386 switch(p->cpuboard_subtype)
7387 {
7388 case BOARD_MACROSYSTEM_SUB_WARPENGINE_A4000:
7389 roms[0] = 93;
7390 break;
7391 }
7392 break;
7393 case BOARD_BLIZZARD:
7394 switch(p->cpuboard_subtype)
7395 {
7396 case BOARD_BLIZZARD_SUB_1230IV:
7397 roms[0] = 89;
7398 break;
7399 case BOARD_BLIZZARD_SUB_1260:
7400 roms[0] = 90;
7401 break;
7402 case BOARD_BLIZZARD_SUB_2060:
7403 roms[0] = 92;
7404 break;
7405 case BOARD_BLIZZARD_SUB_PPC:
7406 roms[0] = p->cpu_model == 68040 ? 99 : 100;
7407 break;
7408 }
7409 break;
7410 case BOARD_CYBERSTORM:
7411 switch(p->cpuboard_subtype)
7412 {
7413 case BOARD_CYBERSTORM_SUB_MK1:
7414 roms[0] = p->cpu_model == 68040 ? 95 : 101;
7415 break;
7416 case BOARD_CYBERSTORM_SUB_MK2:
7417 roms[0] = 96;
7418 break;
7419 case BOARD_CYBERSTORM_SUB_MK3:
7420 roms[0] = 97;
7421 break;
7422 case BOARD_CYBERSTORM_SUB_PPC:
7423 roms[0] = 98;
7424 break;
7425 }
7426 break;
7427 }
7428 if (!configure_rom(p, roms, 0))
7429 return 0;
7430 if (!configure_rom(p, roms2, 0))
7431 return 0;
7432 return 1;
7433 }
7434
set_config_changed(void)7435 void set_config_changed (void)
7436 {
7437 config_changed = 1;
7438 }
7439
config_check_vsync(void)7440 void config_check_vsync (void)
7441 {
7442 if (config_changed) {
7443 #ifdef WITH_LUA
7444 if (config_changed == 1) {
7445 createconfigstore (&currprefs);
7446 uae_lua_run_handler ("on_uae_config_changed");
7447 }
7448 #endif
7449 config_changed++;
7450 if (config_changed >= 3)
7451 config_changed = 0;
7452 }
7453 }
7454
is_error_log(void)7455 bool is_error_log (void)
7456 {
7457 return error_lines != NULL;
7458 }
get_error_log(void)7459 TCHAR *get_error_log (void)
7460 {
7461 strlist *sl;
7462 int len = 0;
7463 for (sl = error_lines; sl; sl = sl->next) {
7464 len += _tcslen (sl->option) + 1;
7465 }
7466 if (!len)
7467 return NULL;
7468 TCHAR *s = xcalloc (TCHAR, len + 1);
7469 for (sl = error_lines; sl; sl = sl->next) {
7470 _tcscat (s, sl->option);
7471 _tcscat (s, _T("\n"));
7472 }
7473 return s;
7474 }
error_log(const TCHAR * format,...)7475 void error_log (const TCHAR *format, ...)
7476 {
7477 TCHAR buffer[256], *bufp;
7478 int bufsize = 256;
7479 va_list parms;
7480
7481 if (format == NULL) {
7482 struct strlist **ps = &error_lines;
7483 while (*ps) {
7484 struct strlist *s = *ps;
7485 *ps = s->next;
7486 xfree (s->value);
7487 xfree (s->option);
7488 xfree (s);
7489 }
7490 return;
7491 }
7492
7493 va_start (parms, format);
7494 bufp = buffer;
7495 for (;;) {
7496 int count = _vsntprintf (bufp, bufsize - 1, format, parms);
7497 if (count < 0) {
7498 bufsize *= 10;
7499 if (bufp != buffer)
7500 xfree (bufp);
7501 bufp = xmalloc (TCHAR, bufsize);
7502 continue;
7503 }
7504 break;
7505 }
7506 bufp[bufsize - 1] = 0;
7507 write_log (_T("%s\n"), bufp);
7508 va_end (parms);
7509
7510 strlist *u = xcalloc (struct strlist, 1);
7511 u->option = my_strdup (bufp);
7512 u->next = error_lines;
7513 error_lines = u;
7514
7515 #ifdef FSUAE // NL
7516 gui_message("%s", bufp);
7517 #endif
7518
7519 if (bufp != buffer)
7520 xfree (bufp);
7521 }
7522