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  * Copyright 2006 Richard Drummond
9  * Copyright 2008 Mustafa Tufan
10  */
11 
12 #include "sysconfig.h"
13 #include "sysdeps.h"
14 
15 #include <ctype.h>
16 #include <wctype.h>
17 
18 #include "cfgfile.h"
19 #include "uae.h"
20 #include "audio.h"
21 #include "autoconf.h"
22 #include "events.h"
23 #include "custom.h"
24 #include "inputdevice.h"
25 #include "gfxfilter.h"
26 #include "savestate.h"
27 #include "memory_uae.h"
28 #include "rommgr.h"
29 #include "gui.h"
30 #include "newcpu.h"
31 #include "filesys.h"
32 #include "fsdb.h"
33 #include "disk.h"
34 #include "blkdev.h"
35 #include "statusline.h"
36 #include "debug.h"
37 #include "calc.h"
38 #include "sounddep/sound.h"
39 #include "misc.h"
40 
41 static int config_newfilesystem;
42 static struct strlist *temp_lines;
43 static struct zfile *default_file, *configstore;
44 static int uaeconfig;
45 static int unicode_config = 0;
46 
47 /* @@@ need to get rid of this... just cut part of the manual and print that
48 * as a help text.  */
49 struct cfg_lines
50 {
51 	const TCHAR *config_label, *config_help;
52 };
53 
54 static const struct cfg_lines opttable[] =
55 {
56 	{_T("help"), _T("Prints this help") },
57 	{_T("config_description"), _T("") },
58 	{_T("config_info"), _T("") },
59 	{_T("use_gui"), _T("Enable the GUI?  If no, then goes straight to emulator") },
60 #ifdef DEBUGGER
61 	{_T("use_debugger"), _T("Enable the debugger?") },
62 #endif
63 	{_T("cpu_speed"), _T("can be max, real, or a number between 1 and 20") },
64 	{_T("cpu_model"), _T("Can be 68000, 68010, 68020, 68030, 68040, 68060") },
65 	{_T("fpu_model"), _T("Can be 68881, 68882, 68040, 68060") },
66 	{_T("cpu_compatible"), _T("yes enables compatibility-mode") },
67 	{_T("cpu_24bit_addressing"), _T("must be set to 'no' in order for Z3mem or P96mem to work") },
68 	{_T("autoconfig"), _T("yes = add filesystems and extra ram") },
69 	{_T("log_illegal_mem"), _T("print illegal memory access by Amiga software?") },
70 	{_T("fastmem_size"), _T("Size in megabytes of fast-memory") },
71 	{_T("chipmem_size"), _T("Size in megabytes of chip-memory") },
72 	{_T("bogomem_size"), _T("Size in megabytes of bogo-memory at 0xC00000") },
73 	{_T("a3000mem_size"), _T("Size in megabytes of A3000 memory") },
74 	{_T("gfxcard_size"), _T("Size in megabytes of Picasso96 graphics-card memory") },
75 	{_T("z3mem_size"), _T("Size in megabytes of Zorro-III expansion memory") },
76 	{_T("gfx_test_speed"), _T("Test graphics speed?") },
77 	{_T("gfx_framerate"), _T("Print every nth frame") },
78 	{_T("gfx_width"), _T("Screen width") },
79 	{_T("gfx_height"), _T("Screen height") },
80 	{_T("gfx_refreshrate"), _T("Fullscreen refresh rate") },
81 	{_T("gfx_vsync"), _T("Sync screen refresh to refresh rate") },
82 	{_T("gfx_lores"), _T("Treat display as lo-res?") },
83 	{_T("gfx_linemode"), _T("Can be none, double, or scanlines") },
84 	{_T("gfx_fullscreen_amiga"), _T("Amiga screens are fullscreen?") },
85 	{_T("gfx_fullscreen_picasso"), _T("Picasso screens are fullscreen?") },
86 	{_T("gfx_center_horizontal"), _T("Center display horizontally?") },
87 	{_T("gfx_center_vertical"), _T("Center display vertically?") },
88 	{_T("gfx_colour_mode"), _T("") },
89 	{_T("32bit_blits"), _T("Enable 32 bit blitter emulation") },
90 	{_T("immediate_blits"), _T("Perform blits immediately") },
91 	{_T("show_leds"), _T("LED display") },
92 	{_T("keyboard_leds"), _T("Keyboard LEDs") },
93 	{_T("gfxlib_replacement"), _T("Use graphics.library replacement?") },
94 	{_T("sound_output"), _T("") },
95 	{_T("sound_frequency"), _T("") },
96 	{_T("sound_bits"), _T("") },
97 	{_T("sound_channels"), _T("") },
98 	{_T("sound_max_buff"), _T("") },
99 #ifdef JIT
100 	{_T("comp_trustbyte"), _T("How to access bytes in compiler (direct/indirect/indirectKS/afterPic") },
101 	{_T("comp_trustword"), _T("How to access words in compiler (direct/indirect/indirectKS/afterPic") },
102 	{_T("comp_trustlong"), _T("How to access longs in compiler (direct/indirect/indirectKS/afterPic") },
103 	{_T("comp_nf"), _T("Whether to optimize away flag generation where possible") },
104 	{_T("comp_fpu"), _T("Whether to provide JIT FPU emulation") },
105 	{_T("compforcesettings"), _T("Whether to force the JIT compiler settings") },
106 	{_T("cachesize"), _T("How many MB to use to buffer translated instructions")},
107 #endif
108 	{_T("override_dga_address"),_T("Address from which to map the frame buffer (upper 16 bits) (DANGEROUS!)")},
109 	{_T("avoid_cmov"), _T("Set to yes on machines that lack the CMOV instruction") },
110 	{_T("avoid_dga"), _T("Set to yes if the use of DGA extension creates problems") },
111 	{_T("avoid_vid"), _T("Set to yes if the use of the Vidmode extension creates problems") },
112 	{_T("parallel_on_demand"), _T("") },
113 	{_T("serial_on_demand"), _T("") },
114 	{_T("scsi"), _T("scsi.device emulation") },
115 	{_T("joyport0"), _T("") },
116 	{_T("joyport1"), _T("") },
117 	{_T("pci_devices"), _T("List of PCI devices to make visible to the emulated Amiga") },
118 	{_T("kickstart_rom_file"), _T("Kickstart ROM image, (C) Copyright Amiga, Inc.") },
119 	{_T("kickstart_ext_rom_file"), _T("Extended Kickstart ROM image, (C) Copyright Amiga, Inc.") },
120 	{_T("kickstart_key_file"), _T("Key-file for encrypted ROM images (from Cloanto's Amiga Forever)") },
121 	{_T("flash_ram_file"), _T("Flash/battery backed RAM image file.") },
122 #ifdef ACTION_REPLAY
123 	{_T("cart_file"), _T("Freezer cartridge ROM image file.") },
124 #endif
125 	{_T("floppy0"), _T("Diskfile for drive 0") },
126 	{_T("floppy1"), _T("Diskfile for drive 1") },
127 	{_T("floppy2"), _T("Diskfile for drive 2") },
128 	{_T("floppy3"), _T("Diskfile for drive 3") },
129 #ifdef FILESYS
130 	{_T("hardfile"), _T("access,sectors, surfaces, reserved, blocksize, path format") },
131 	{_T("filesystem"), _T("access,'Amiga volume-name':'host directory path' - where 'access' can be 'read-only' or 'read-write'") },
132 #endif
133 #ifdef CATWEASEL
134 	{_T("catweasel"), _T("Catweasel board io base address") }
135 #endif
136 };
137 
138 static const TCHAR *guimode1[] = { _T("no"), _T("yes"), _T("nowait"), 0 };
139 static const TCHAR *guimode2[] = { _T("false"), _T("true"), _T("nowait"), 0 };
140 static const TCHAR *guimode3[] = { _T("0"), _T("1"), _T("nowait"), 0 };
141 static const TCHAR *csmode[] = { _T("ocs"), _T("ecs_agnus"), _T("ecs_denise"), _T("ecs"), _T("aga"), 0 };
142 static const TCHAR *linemode[] = { _T("none"), _T("none"), _T("double"), _T("scanlines"), 0 };
143 static const TCHAR *speedmode[] = { _T("max"), _T("real"), 0 };
144 static const TCHAR *colormode1[] = { _T("8bit"), _T("15bit"), _T("16bit"), _T("8bit_dither"), _T("4bit_dither"), _T("32bit"), 0 };
145 static const TCHAR *colormode2[] = { _T("8"), _T("15"), _T("16"), _T("8d"), _T("4d"), _T("32"), 0 };
146 static const TCHAR *soundmode1[] = { _T("none"), _T("interrupts"), _T("normal"), _T("exact"), 0 };
147 static const TCHAR *soundmode2[] = { _T("none"), _T("interrupts"), _T("good"), _T("best"), 0 };
148 static const TCHAR *centermode1[] = { _T("none"), _T("simple"), _T("smart"), 0 };
149 static const TCHAR *centermode2[] = { _T("false"), _T("true"), _T("smart"), 0 };
150 static const TCHAR *stereomode[] = { _T("mono"), _T("stereo"), _T("clonedstereo"), _T("4ch"), _T("clonedstereo6ch"), _T("6ch"), _T("mixed"), 0 };
151 static const TCHAR *interpolmode[] = { _T("none"), _T("anti"), _T("sinc"), _T("rh"), _T("crux"), 0 };
152 static const TCHAR *collmode[] = { _T("none"), _T("sprites"), _T("playfields"), _T("full"), 0 };
153 static const TCHAR *compmode[] = { _T("direct"), _T("indirect"), _T("indirectKS"), _T("afterPic"), 0 };
154 static const TCHAR *flushmode[] = { _T("soft"), _T("hard"), 0 };
155 static const TCHAR *kbleds[] = { _T("none"), _T("POWER"), _T("DF0"), _T("DF1"), _T("DF2"), _T("DF3"), _T("HD"), _T("CD"), 0 };
156 
157 /// REMOVEME: nowhere used
158 #if 0
159 static const TCHAR *onscreenleds[] = { _T("false"), _T("true"), _T("rtg"), _T("both"), 0 };
160 #endif // 0
161 
162 static const TCHAR *soundfiltermode1[] = { _T("off"), _T("emulated"), _T("on"), 0 };
163 static const TCHAR *soundfiltermode2[] = { _T("standard"), _T("enhanced"), 0 };
164 static const TCHAR *lorestype1[] = { _T("lores"), _T("hires"), _T("superhires"), 0 };
165 static const TCHAR *lorestype2[] = { _T("true"), _T("false"), 0 };
166 static const TCHAR *loresmode[] = { _T("normal"), _T("filtered"), 0 };
167 static const TCHAR *horizmode[] = { _T("vertical"), _T("lores"), _T("hires"), _T("superhires"), 0 };
168 static const TCHAR *vertmode[] = { _T("horizontal"), _T("single"), _T("double"), _T("quadruple"), 0 };
169 #ifdef GFXFILTER
170 static const TCHAR *filtermode2[] = { _T("1x"), _T("2x"), _T("3x"), _T("4x"), 0 };
171 #endif
172 static const TCHAR *cartsmode[] = { _T("none"), _T("hrtmon"), 0 };
173 static const TCHAR *idemode[] = { _T("none"), _T("a600/a1200"), _T("a4000"), 0 };
174 static const TCHAR *rtctype[] = { _T("none"), _T("MSM6242B"), _T("RP5C01A"), _T("MSM6242B_A2000"), 0 };
175 static const TCHAR *ciaatodmode[] = { _T("vblank"), _T("50hz"), _T("60hz"), 0 };
176 
177 /// REMOVEME: nowhere used
178 #if 0
179 static const TCHAR *ksmirrortype[] = { _T("none"), _T("e0"), _T("a8+e0"), 0 };
180 #endif // 0
181 
182 static const TCHAR *cscompa[] = {
183 	_T("-"), _T("Generic"), _T("CDTV"), _T("CD32"), _T("A500"), _T("A500+"), _T("A600"),
184 	_T("A1000"), _T("A1200"), _T("A2000"), _T("A3000"), _T("A3000T"), _T("A4000"), _T("A4000T"), 0
185 };
186 static const TCHAR *qsmodes[] = {
187 	_T("A500"), _T("A500+"), _T("A600"), _T("A1000"), _T("A1200"), _T("A3000"), _T("A4000"), _T(""), _T("CD32"), _T("CDTV"), _T("ARCADIA"), NULL };
188 /* 3-state boolean! */
189 static const TCHAR *fullmodes[] = { _T("false"), _T("true"), /* "FILE_NOT_FOUND", */ _T("fullwindow"), 0 };
190 /* bleh for compatibility */
191 static const TCHAR *scsimode[] = { _T("false"), _T("true"), _T("scsi"), 0 };
192 static const TCHAR *maxhoriz[] = { _T("lores"), _T("hires"), _T("superhires"), 0 };
193 static const TCHAR *maxvert[] = { _T("nointerlace"), _T("interlace"), 0 };
194 static const TCHAR *abspointers[] = { _T("none"), _T("mousehack"), _T("tablet"), 0 };
195 static const TCHAR *magiccursors[] = { _T("both"), _T("native"), _T("host"), 0 };
196 static const TCHAR *autoscale[] = { _T("none"), _T("auto"), _T("standard"), _T("max"), _T("scale"), _T("resize"), _T("center"), _T("manual"), _T("integer"), _T("integer_auto"), 0 };
197 static const TCHAR *joyportmodes[] = { _T(""), _T("mouse"), _T("mousenowheel"), _T("djoy"), _T("gamepad"), _T("ajoy"), _T("cdtvjoy"), _T("cd32joy"), _T("lightpen"), 0 };
198 static const TCHAR *joyaf[] = { _T("none"), _T("normal"), _T("toggle"), 0 };
199 static const TCHAR *epsonprinter[] = { _T("none"), _T("ascii"), _T("epson_matrix_9pin"), _T("epson_matrix_24pin"), _T("epson_matrix_48pin"), 0 };
200 static const TCHAR *aspects[] = { _T("none"), _T("vga"), _T("tv"), 0 };
201 static const TCHAR *vsyncmodes[] = { _T("false"), _T("true"), _T("autoswitch"), 0 };
202 static const TCHAR *vsyncmodes2[] = { _T("normal"), _T("busywait"), 0 };
203 static const TCHAR *filterapi[] = { _T("directdraw"), _T("direct3d"), 0 };
204 static const TCHAR *dongles[] =
205 {
206 	_T("none"),
207 	_T("robocop 3"), _T("leaderboard"), _T("b.a.t. ii"), _T("italy'90 soccer"), _T("dames grand maitre"),
208 	_T("rugby coach"), _T("cricket captain"), _T("leviathan"),
209 	NULL
210 };
211 static const TCHAR *cdmodes[] = { _T("disabled"), _T(""), _T("image"), _T("ioctl"), _T("spti"), _T("aspi"), 0 };
212 static const TCHAR *cdconmodes[] = { _T(""), _T("uae"), _T("ide"), _T("scsi"), _T("cdtv"), _T("cd32"), 0 };
213 static const TCHAR *specialmonitors[] = { _T("none"), _T("autodetect"), _T("a2024"), _T("graffiti"), 0 };
214 static const TCHAR *rtgtype[] = { _T("ZorroII"), _T("ZorroIII"), 0 };
215 static const TCHAR *waitblits[] = { _T("disabled"), _T("automatic"), _T("noidleonly"), _T("always"), 0 };
216 static const TCHAR *autoext2[] = { _T("disabled"), _T("copy"), _T("replace"), 0 };
217 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 };
218 static int leds_order[] = { 3, 6, 7, 8, 9, 4, 5, 2, 1, 0, 9 };
219 
220 static const TCHAR *obsolete[] = {
221 	_T("accuracy"), _T("gfx_opengl"), _T("gfx_32bit_blits"), _T("32bit_blits"),
222 	_T("gfx_immediate_blits"), _T("gfx_ntsc"), _T("win32"), _T("gfx_filter_bits"),
223 	_T("sound_pri_cutoff"), _T("sound_pri_time"), _T("sound_min_buff"), _T("sound_bits"),
224 	_T("gfx_test_speed"), _T("gfxlib_replacement"), _T("enforcer"), _T("catweasel_io"),
225 	_T("kickstart_key_file"), _T("fast_copper"), _T("sound_adjust"), _T("sound_latency"),
226 	_T("serial_hardware_dtrdsr"), _T("gfx_filter_upscale"),
227 	_T("gfx_correct_aspect"), _T("gfx_autoscale"), _T("parallel_sampler"), _T("parallel_ascii_emulation"),
228 	_T("avoid_vid"), _T("avoid_dga"), _T("z3chipmem_size"), _T("state_replay_buffer"), _T("state_replay"),
229 
230 	_T("gfx_filter_vert_zoom"),_T("gfx_filter_horiz_zoom"),
231 	_T("gfx_filter_vert_zoom_mult"), _T("gfx_filter_horiz_zoom_mult"),
232 	_T("gfx_filter_vert_offset"), _T("gfx_filter_horiz_offset"),
233 	_T("rtg_vert_zoom_multf"), _T("rtg_horiz_zoom_multf"),
234 
235 	NULL
236 };
237 
238 /* internal prototypes */
239 void cfgfile_write_str (struct zfile *f, const TCHAR *option, const TCHAR *value);
240 void cfgfile_dwrite_str (struct zfile *f, const TCHAR *option, const TCHAR *value);
241 void cfgfile_target_write_str (struct zfile *f, const TCHAR *option, const TCHAR *value);
242 void cfgfile_target_dwrite_str (struct zfile *f, const TCHAR *option, const TCHAR *value);
243 void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type);
244 int cfgfile_yesno2 (const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location);
245 int cfgfile_doubleval (const TCHAR *option, const TCHAR *value, const TCHAR *name, double *location);
246 int cfgfile_floatval (const TCHAR *option, const TCHAR *value, const TCHAR *name, float *location);
247 int cfgfile_intval_unsigned (const TCHAR *option, const TCHAR *value, const TCHAR *name, unsigned int *location, int scale);
248 int cfgfile_strboolval (const TCHAR *option, const TCHAR *value, const TCHAR *name, bool *location, const TCHAR *table[], int more);
249 int cfgfile_path_mp (const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz, struct multipath *mp);
250 int cfgfile_path (const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz);
251 int cfgfile_multipath (const TCHAR *option, const TCHAR *value, const TCHAR *name, struct multipath *mp);
252 int cfgfile_rom (const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz);
253 
254 /* external prototypes */
255 int machdep_parse_option (struct uae_prefs *, const char *, const char *);
256 int gfx_parse_option (struct uae_prefs *, const char *, const char *);
257 int audio_parse_option (struct uae_prefs *, const char *, const char *);
258 void machdep_default_options (struct uae_prefs *);
259 void gfx_default_options (struct uae_prefs *);
260 void audio_default_options (struct uae_prefs *);
261 void my_trim (TCHAR *s);
262 TCHAR *my_strdup_trim (const TCHAR *s);
263 
264 #define UNEXPANDED _T("$(FILE_PATH)")
265 
266 
trimwsa(char * s)267 static void trimwsa (char *s)
268 {
269 	/* Delete trailing whitespace.  */
270 	int len = strlen (s);
271 	while (len > 0 && strcspn (s + len - 1, "\t \r\n") == 0)
272 		s[--len] = '\0';
273 }
274 
match_string(const TCHAR * table[],const TCHAR * str)275 static int match_string (const TCHAR *table[], const TCHAR *str)
276 {
277 	int i;
278 	for (i = 0; table[i] != 0; i++)
279 		if (strcasecmp (table[i], str) == 0)
280 			return i;
281 	return -1;
282 }
283 
cfgfile_subst_path2(const TCHAR * path,const TCHAR * subst,const TCHAR * file)284 static TCHAR *cfgfile_subst_path2 (const TCHAR *path, const TCHAR *subst, const TCHAR *file)
285 {
286 	/* @@@ use strcasecmp for some targets.  */
287 	if (_tcslen (path) > 0 && _tcsncmp (file, path, _tcslen (path)) == 0) {
288 		int l;
289 		TCHAR *p2, *p = xmalloc (TCHAR, _tcslen (file) + _tcslen (subst) + 2);
290 		_tcscpy (p, subst);
291 		l = _tcslen (p);
292 		while (l > 0 && p[l - 1] == '/')
293 			p[--l] = '\0';
294 		l = _tcslen (path);
295 		while (file[l] == '/')
296 			l++;
297 		_tcscat (p, _T("/"));
298 		_tcscat (p, file + l);
299 		return p;
300 	}
301 	return NULL;
302 }
303 
cfgfile_subst_path(const TCHAR * path,const TCHAR * subst,const TCHAR * file)304 TCHAR *cfgfile_subst_path (const TCHAR *path, const TCHAR *subst, const TCHAR *file)
305 {
306 	TCHAR *s = cfgfile_subst_path2 (path, subst, file);
307 	if (s)
308 		return s;
309 	return my_strdup(file);
310 	// No matter what cfgfile_subst_path2() returns, the returned value is
311 	// malloc'd. So free it!
312 
313 /*	s = target_expand_environment (file);
314 	if (s) {
315 		TCHAR tmp[MAX_DPATH];
316 		_tcscpy (tmp, s);
317 		xfree (s);
318 		fullpath (tmp, sizeof tmp / sizeof (TCHAR));
319 		s = my_strdup (tmp);
320 	}
321 	return s; */
322 }
323 
cfgfile_get_multipath2(struct multipath * mp,const TCHAR * path,const TCHAR * file,bool dir)324 static TCHAR *cfgfile_get_multipath2 (struct multipath *mp, const TCHAR *path, const TCHAR *file, bool dir)
325 {
326 	for (int i = 0; i < MAX_PATHS; i++) {
327 		if (mp->path[i][0] && _tcscmp (mp->path[i], _T(".\\")) != 0 && _tcscmp (mp->path[i], _T("./")) != 0 && (file[0] != '/' && file[0] != '\\' && !_tcschr(file, ':'))) {
328 			TCHAR *s = NULL;
329 			if (path)
330 				s = cfgfile_subst_path2 (path, mp->path[i], file);
331 			if (!s) {
332 				TCHAR np[MAX_DPATH];
333 				_tcscpy (np, mp->path[i]);
334 				fixtrailing (np);
335 				_tcscat (np, file);
336 				fullpath (np, sizeof np / sizeof (TCHAR));
337 				s = my_strdup (np);
338 			}
339 			if (dir) {
340 				if (my_existsdir (s))
341 					return s;
342 			} else {
343 				if (zfile_exists (s))
344 					return s;
345 			}
346 			xfree (s);
347 		}
348 	}
349 	return NULL;
350 }
351 
cfgfile_get_multipath(struct multipath * mp,const TCHAR * path,const TCHAR * file,bool dir)352 static TCHAR *cfgfile_get_multipath (struct multipath *mp, const TCHAR *path, const TCHAR *file, bool dir)
353 {
354 	TCHAR *s = cfgfile_get_multipath2 (mp, path, file, dir);
355 	if (s)
356 		return s;
357 	return my_strdup (file);
358 }
359 
cfgfile_put_multipath(struct multipath * mp,const TCHAR * s)360 static TCHAR *cfgfile_put_multipath (struct multipath *mp, const TCHAR *s)
361 {
362 	for (int i = 0; i < MAX_PATHS; i++) {
363 		if (mp->path[i][0] && _tcscmp (mp->path[i], _T(".\\")) != 0 && _tcscmp (mp->path[i], _T("./")) != 0) {
364 			if (_tcsnicmp (mp->path[i], s, _tcslen (mp->path[i])) == 0) {
365 				return my_strdup (s + _tcslen (mp->path[i]));
366 			}
367 		}
368 	}
369 	return my_strdup (s);
370 }
371 
cfgfile_subst_path_load(const TCHAR * path,struct multipath * mp,const TCHAR * file,bool dir)372 static TCHAR *cfgfile_subst_path_load (const TCHAR *path, struct multipath *mp, const TCHAR *file, bool dir)
373 {
374 	TCHAR *s = cfgfile_get_multipath2 (mp, path, file, dir);
375 	if (s)
376 		return s;
377 	return cfgfile_subst_path (path, mp->path[0], file);
378 }
379 
isdefault(const TCHAR * s)380 static bool isdefault (const TCHAR *s)
381 {
382 	TCHAR tmp[MAX_DPATH];
383 	if (!default_file || uaeconfig)
384 		return false;
385 	zfile_fseek (default_file, 0, SEEK_SET);
386 	while (zfile_fgets (tmp, sizeof tmp / sizeof (TCHAR), default_file)) {
387 		if (tmp[0] && tmp[_tcslen (tmp) - 1] == '\n')
388 			tmp[_tcslen (tmp) - 1] = 0;
389 		if (!_tcscmp (tmp, s))
390 			return true;
391 	}
392 	return false;
393 }
394 
cfg_write(const void * b,struct zfile * z)395 static size_t cfg_write (const void *b, struct zfile *z)
396 {
397 	size_t v;
398 	if (unicode_config) {
399 		TCHAR lf = 10;
400 		v = zfile_fwrite (b, _tcslen ((TCHAR*)b), sizeof (TCHAR), z);
401 		zfile_fwrite (&lf, 1, 1, z);
402 	} else {
403 		char lf = 10;
404 		char *s = ua ((TCHAR*)b);
405 		v = zfile_fwrite (s, strlen (s), 1, z);
406 		zfile_fwrite (&lf, 1, 1, z);
407 		xfree (s);
408 	}
409 	return v;
410 }
411 
412 #define UTF8NAME _T(".utf8")
413 
cfg_dowrite(struct zfile * f,const TCHAR * option,const TCHAR * value,int d,int target)414 static void cfg_dowrite (struct zfile *f, const TCHAR *option, const TCHAR *value, int d, int target)
415 {
416 	char lf = 10;
417 	TCHAR tmp[CONFIG_BLEN];
418 	char tmpa[CONFIG_BLEN];
419 	char *tmp1, *tmp2;
420 	int utf8;
421 
422 	if (value == NULL)
423 		return;
424 	utf8 = 0;
425 	tmp1 = ua (value);
426 	tmp2 = uutf8 (value);
427 	if (strcmp (tmp1, tmp2) && tmp2[0] != 0)
428 		utf8 = 1;
429 
430 	if (target)
431 		_stprintf (tmp, _T("%s.%s=%s"), TARGET_NAME, option, value);
432 	else
433 		_stprintf (tmp, _T("%s=%s"), option, value);
434 	if (d && isdefault (tmp))
435 		goto end;
436 	cfg_write (tmp, f);
437 	if (utf8 && !unicode_config) {
438 		char *opt = ua (option);
439 		if (target) {
440 			char *tna = ua (TARGET_NAME);
441 			sprintf (tmpa, "%s.%s.utf8=%s", tna, opt, tmp2);
442 			xfree (tna);
443 		} else {
444 			sprintf (tmpa, "%s.utf8=%s", opt, tmp2);
445 		}
446 		xfree (opt);
447 		zfile_fwrite (tmpa, strlen (tmpa), 1, f);
448 		zfile_fwrite (&lf, 1, 1, f);
449 	}
450 end:
451 	xfree (tmp2);
452 	xfree (tmp1);
453 }
454 
cfgfile_write_bool(struct zfile * f,const TCHAR * option,bool b)455 void cfgfile_write_bool (struct zfile *f, const TCHAR *option, bool b)
456 {
457 	cfg_dowrite (f, option, b ? _T("true") : _T("false"), 0, 0);
458 }
cfgfile_dwrite_bool(struct zfile * f,const TCHAR * option,bool b)459 void cfgfile_dwrite_bool (struct zfile *f, const TCHAR *option, bool b)
460 {
461 	cfg_dowrite (f, option, b ? _T("true") : _T("false"), 1, 0);
462 }
463 /*void cfgfile_dwrite_bool (struct zfile *f, const TCHAR *option, int b)
464 {
465 	cfgfile_dwrite_bool (f, option, b != 0);
466 }*/
cfgfile_write_str(struct zfile * f,const TCHAR * option,const TCHAR * value)467 void cfgfile_write_str (struct zfile *f, const TCHAR *option, const TCHAR *value)
468 {
469 	cfg_dowrite (f, option, value, 0, 0);
470 }
cfgfile_dwrite_str(struct zfile * f,const TCHAR * option,const TCHAR * value)471 void cfgfile_dwrite_str (struct zfile *f, const TCHAR *option, const TCHAR *value)
472 {
473 	cfg_dowrite (f, option, value, 1, 0);
474 }
475 
cfgfile_target_write_bool(struct zfile * f,const TCHAR * option,bool b)476 void cfgfile_target_write_bool (struct zfile *f, const TCHAR *option, bool b)
477 {
478 	cfg_dowrite (f, option, b ? _T("true") : _T("false"), 0, 1);
479 }
cfgfile_target_dwrite_bool(struct zfile * f,const TCHAR * option,bool b)480 void cfgfile_target_dwrite_bool (struct zfile *f, const TCHAR *option, bool b)
481 {
482 	cfg_dowrite (f, option, b ? _T("true") : _T("false"), 1, 1);
483 }
cfgfile_target_write_str(struct zfile * f,const TCHAR * option,const TCHAR * value)484 void cfgfile_target_write_str (struct zfile *f, const TCHAR *option, const TCHAR *value)
485 {
486 	cfg_dowrite (f, option, value, 0, 1);
487 }
cfgfile_target_dwrite_str(struct zfile * f,const TCHAR * option,const TCHAR * value)488 void cfgfile_target_dwrite_str (struct zfile *f, const TCHAR *option, const TCHAR *value)
489 {
490 	cfg_dowrite (f, option, value, 1, 1);
491 }
492 
cfgfile_write(struct zfile * f,const TCHAR * option,const TCHAR * format,...)493 void cfgfile_write (struct zfile *f, const TCHAR *option, const TCHAR *format,...)
494 {
495 	va_list parms;
496 	TCHAR tmp[CONFIG_BLEN];
497 
498 	va_start (parms, format);
499 	_vsntprintf (tmp, CONFIG_BLEN, format, parms);
500 	cfg_dowrite (f, option, tmp, 0, 0);
501 	va_end (parms);
502 }
cfgfile_dwrite(struct zfile * f,const TCHAR * option,const TCHAR * format,...)503 void cfgfile_dwrite (struct zfile *f, const TCHAR *option, const TCHAR *format,...)
504 {
505 	va_list parms;
506 	TCHAR tmp[CONFIG_BLEN];
507 
508 	va_start (parms, format);
509 	_vsntprintf (tmp, CONFIG_BLEN, format, parms);
510 	cfg_dowrite (f, option, tmp, 1, 0);
511 	va_end (parms);
512 }
cfgfile_target_write(struct zfile * f,const TCHAR * option,const TCHAR * format,...)513 void cfgfile_target_write (struct zfile *f, const TCHAR *option, const TCHAR *format,...)
514 {
515 	va_list parms;
516 	TCHAR tmp[CONFIG_BLEN];
517 
518 	va_start (parms, format);
519 	_vsntprintf (tmp, CONFIG_BLEN, format, parms);
520 	cfg_dowrite (f, option, tmp, 0, 1);
521 	va_end (parms);
522 }
cfgfile_target_dwrite(struct zfile * f,const TCHAR * option,const TCHAR * format,...)523 void cfgfile_target_dwrite (struct zfile *f, const TCHAR *option, const TCHAR *format,...)
524 {
525 	va_list parms;
526 	TCHAR tmp[CONFIG_BLEN];
527 
528 	va_start (parms, format);
529 	_vsntprintf (tmp, CONFIG_BLEN, format, parms);
530 	cfg_dowrite (f, option, tmp, 1, 1);
531 	va_end (parms);
532 }
533 
cfgfile_write_rom(struct zfile * f,struct multipath * mp,const TCHAR * romfile,const TCHAR * name)534 static void cfgfile_write_rom (struct zfile *f, struct multipath *mp, const TCHAR *romfile, const TCHAR *name)
535 {
536 	TCHAR *str = cfgfile_subst_path (mp->path[0], UNEXPANDED, romfile);
537 	str = cfgfile_put_multipath (mp, str);
538 	cfgfile_write_str (f, name, str);
539 	struct zfile *zf = zfile_fopen (str, _T("rb"), ZFD_ALL);
540 	if (zf) {
541 		struct romdata *rd = getromdatabyzfile (zf);
542 		if (rd) {
543 			TCHAR name2[MAX_DPATH], str2[MAX_DPATH];
544 			_tcscpy (name2, name);
545 			_tcscat (name2, _T("_id"));
546 			_stprintf (str2, _T("%08X,%s"), rd->crc32, rd->name);
547 			cfgfile_write_str (f, name2, str2);
548 		}
549 		zfile_fclose (zf);
550 	}
551 	xfree (str);
552 
553 }
554 
cfgfile_write_path(struct zfile * f,struct multipath * mp,const TCHAR * option,const TCHAR * value)555 static void cfgfile_write_path (struct zfile *f, struct multipath *mp, const TCHAR *option, const TCHAR *value)
556 {
557 	TCHAR *s = cfgfile_put_multipath (mp, value);
558 	cfgfile_write_str (f, option, s);
559 	xfree (s);
560 }
cfgfile_dwrite_path(struct zfile * f,struct multipath * mp,const TCHAR * option,const TCHAR * value)561 static void cfgfile_dwrite_path (struct zfile *f, struct multipath *mp, const TCHAR *option, const TCHAR *value)
562 {
563 	TCHAR *s = cfgfile_put_multipath (mp, value);
564 	cfgfile_dwrite_str (f, option, s);
565 	xfree (s);
566 }
567 
write_filesys_config(struct uae_prefs * p,struct zfile * f)568 static void write_filesys_config (struct uae_prefs *p, struct zfile *f)
569 {
570 	int i;
571 	TCHAR tmp[MAX_DPATH], tmp2[MAX_DPATH];
572 	TCHAR *hdcontrollers[] = { _T("uae"),
573 		_T("ide0"), _T("ide1"), _T("ide2"), _T("ide3"),
574 		_T("scsi0"), _T("scsi1"), _T("scsi2"), _T("scsi3"), _T("scsi4"), _T("scsi5"), _T("scsi6"),
575 		_T("scsram"), _T("scide") }; /* scsram = smart card sram = pcmcia sram card */
576 
577 	for (i = 0; i < p->mountitems; i++) {
578 		struct uaedev_config_data *uci = &p->mountconfig[i];
579 		struct uaedev_config_info *ci = &uci->ci;
580 		TCHAR *str;
581 		int bp = ci->bootpri;
582 
583 		str = cfgfile_put_multipath (&p->path_hardfile, ci->rootdir);
584 		if (ci->type == UAEDEV_DIR) {
585 			_stprintf (tmp, _T("%s,%s:%s:%s,%d"), ci->readonly ? _T("ro") : _T("rw"),
586 				ci->devname ? ci->devname : _T(""), ci->volname, str, bp);
587 			cfgfile_write_str (f, _T("filesystem2"), tmp);
588 #if 0
589 			_stprintf (tmp2, _T("filesystem=%s,%s:%s"), uci->readonly ? _T("ro") : _T("rw"),
590 				uci->volname, str);
591 			zfile_fputs (f, tmp2);
592 #endif
593 		} else if (ci->type == UAEDEV_HDF || ci->type == UAEDEV_CD) {
594 			_stprintf (tmp, _T("%s,%s:%s,%d,%d,%d,%d,%d,%s,%s"),
595 				ci->readonly ? _T("ro") : _T("rw"),
596 				ci->devname ? ci->devname : _T(""), str,
597 				ci->sectors, ci->surfaces, ci->reserved, ci->blocksize,
598 				bp, ci->filesys ? ci->filesys : _T(""), hdcontrollers[ci->controller]);
599 			if (ci->highcyl) {
600 				TCHAR *s = tmp + _tcslen (tmp);
601 				_stprintf (s, _T(",%d"), ci->highcyl);
602 				if (ci->pcyls && ci->pheads && ci->psecs) {
603 				TCHAR *s = tmp + _tcslen (tmp);
604 					_stprintf (s, _T(",%d/%d/%d"), ci->pcyls, ci->pheads, ci->psecs);
605 				}
606 			}
607 			if (ci->type == UAEDEV_HDF)
608 			cfgfile_write_str (f, _T("hardfile2"), tmp);
609 #if 0
610 			_stprintf (tmp2, _T("hardfile=%s,%d,%d,%d,%d,%s"),
611 				uci->readonly ? "ro" : "rw", uci->sectors,
612 				uci->surfaces, uci->reserved, uci->blocksize, str);
613 			zfile_fputs (f, tmp2);
614 #endif
615 		}
616 		_stprintf (tmp2, _T("uaehf%d"), i);
617 		if (ci->type == UAEDEV_CD) {
618 			cfgfile_write (f, tmp2, _T("cd%d,%s"), ci->cd_emu_unit, tmp);
619 		} else {
620 			cfgfile_write (f, tmp2, _T("%s,%s"), ci->type == UAEDEV_HDF ? _T("hdf") : _T("dir"), tmp);
621 		}
622 		xfree (str);
623 	}
624 }
625 
write_compatibility_cpu(struct zfile * f,struct uae_prefs * p)626 static void write_compatibility_cpu (struct zfile *f, struct uae_prefs *p)
627 {
628 	TCHAR tmp[100];
629 	int model;
630 
631 	model = p->cpu_model;
632 	if (model == 68030)
633 		model = 68020;
634 	if (model == 68060)
635 		model = 68040;
636 	if (p->address_space_24 && model == 68020)
637 		_tcscpy (tmp, _T("68ec020"));
638 	else
639 		_stprintf (tmp, _T("%d"), model);
640 	if (model == 68020 && (p->fpu_model == 68881 || p->fpu_model == 68882))
641 		_tcscat (tmp, _T("/68881"));
642 	cfgfile_write (f, _T("cpu_type"), tmp);
643 }
644 
write_leds(struct zfile * f,const TCHAR * name,int mask)645 static void write_leds (struct zfile *f, const TCHAR *name, int mask)
646 {
647 	TCHAR tmp[MAX_DPATH];
648 	tmp[0] = 0;
649 	for (int i = 0; leds[i]; i++) {
650 		bool got = false;
651 		for (int j = 0; leds[j]; j++) {
652 			if (leds_order[j] == i) {
653 				if (mask & (1 << j)) {
654 					if (got)
655 						_tcscat (tmp, _T(":"));
656 					_tcscat (tmp, leds[j]);
657 					got = true;
658 				}
659 			}
660 		}
661 		if (leds[i + 1] && got)
662 			_tcscat (tmp, _T(","));
663 	}
664 	while (tmp[0] && tmp[_tcslen (tmp) - 1] == ',')
665 		tmp[_tcslen (tmp) - 1] = 0;
666 	cfgfile_dwrite_str (f, name, tmp);
667 }
668 
write_resolution(struct zfile * f,const TCHAR * ws,const TCHAR * hs,struct wh * wh)669 static void write_resolution (struct zfile *f, const TCHAR *ws, const TCHAR *hs, struct wh *wh)
670 {
671 	if (wh->width <= 0 || wh->height <= 0 || wh->special == WH_NATIVE) {
672 		cfgfile_write_str (f, ws, _T("native"));
673 		cfgfile_write_str (f, hs, _T("native"));
674 	} else {
675 		cfgfile_write (f, ws, _T("%d"), wh->width);
676 		cfgfile_write (f, hs, _T("%d"), wh->height);
677 	}
678 }
679 
cfgfile_save_options(struct zfile * f,struct uae_prefs * p,int type)680 void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
681 {
682 	struct strlist *sl;
683 	TCHAR tmp[MAX_DPATH];
684 	int i;
685 
686 	cfgfile_write_str (f, _T("config_description"), p->description);
687 	cfgfile_write_bool (f, _T("config_hardware"), type & CONFIG_TYPE_HARDWARE);
688 	cfgfile_write_bool (f, _T("config_host"), !!(type & CONFIG_TYPE_HOST));
689 	if (p->info[0])
690 		cfgfile_write (f, _T("config_info"), p->info);
691 	cfgfile_write (f, _T("config_version"), _T("%d.%d.%d"), UAEMAJOR, UAEMINOR, UAESUBREV);
692 	cfgfile_write_str (f, _T("config_hardware_path"), p->config_hardware_path);
693 	cfgfile_write_str (f, _T("config_host_path"), p->config_host_path);
694 	if (p->config_window_title[0])
695 		cfgfile_write_str (f, _T("config_window_title"), p->config_window_title);
696 
697 	for (sl = p->all_lines; sl; sl = sl->next) {
698 		if (sl->unknown) {
699 			if (sl->option)
700 				cfgfile_write_str (f, sl->option, sl->value);
701 		}
702 	}
703 
704 	for (i = 0; i < MAX_PATHS; i++) {
705 		if (p->path_rom.path[i][0]) {
706 			_stprintf (tmp, _T("%s.rom_path"), TARGET_NAME);
707 			cfgfile_write_str (f, tmp, p->path_rom.path[i]);
708 		}
709 	}
710 	for (i = 0; i < MAX_PATHS; i++) {
711 		if (p->path_floppy.path[i][0]) {
712 			_stprintf (tmp, _T("%s.floppy_path"), TARGET_NAME);
713 			cfgfile_write_str (f, tmp, p->path_floppy.path[i]);
714 		}
715 	}
716 	for (i = 0; i < MAX_PATHS; i++) {
717 		if (p->path_hardfile.path[i][0]) {
718 			_stprintf (tmp, _T("%s.hardfile_path"), TARGET_NAME);
719 			cfgfile_write_str (f, tmp, p->path_hardfile.path[i]);
720 		}
721 	}
722 	for (i = 0; i < MAX_PATHS; i++) {
723 		if (p->path_cd.path[i][0]) {
724 			_stprintf (tmp, _T("%s.cd_path"), TARGET_NAME);
725 			cfgfile_write_str (f, tmp, p->path_cd.path[i]);
726 		}
727 	}
728 
729 	cfg_write (_T("; host-specific"), f);
730 
731 	target_save_options (f, p);
732 
733 	cfg_write (_T("; common"), f);
734 
735 	cfgfile_write_str (f, _T("use_gui"), guimode1[p->start_gui]);
736 	cfgfile_write_bool (f, _T("use_debugger"), p->start_debugger);
737 	cfgfile_write_rom (f, &p->path_rom, p->romfile, _T("kickstart_rom_file"));
738 	cfgfile_write_rom (f, &p->path_rom, p->romextfile, _T("kickstart_ext_rom_file"));
739 	if (p->romextfile2addr) {
740 		cfgfile_write (f, _T("kickstart_ext_rom_file2_address"), _T("%x"), p->romextfile2addr);
741 		cfgfile_write_rom (f, &p->path_rom, p->romextfile2, _T("kickstart_ext_rom_file2"));
742 	}
743 	if (p->romident[0])
744 		cfgfile_dwrite_str (f, _T("kickstart_rom"), p->romident);
745 	if (p->romextident[0])
746 		cfgfile_write_str (f, _T("kickstart_ext_rom="), p->romextident);
747 	cfgfile_write_path (f, &p->path_rom, _T("flash_file"), p->flashfile);
748 	cfgfile_write_path (f, &p->path_rom, _T("cart_file"), p->cartfile);
749 	cfgfile_write_path (f, &p->path_rom, _T("rtc_file"), p->rtcfile);
750 	if (p->cartident[0])
751 		cfgfile_write_str (f, _T("cart"), p->cartident);
752 	if (p->amaxromfile[0])
753 		cfgfile_write_path (f, &p->path_rom, _T("amax_rom_file"), p->amaxromfile);
754 
755 	cfgfile_write_bool (f, _T("kickshifter"), p->kickshifter);
756 	cfgfile_write_bool (f, _T("ks_write_enabled"), p->rom_readwrite);
757 
758 	p->nr_floppies = 4;
759 	for (i = 0; i < 4; i++) {
760 		_stprintf (tmp, _T("floppy%d"), i);
761 		cfgfile_write_path (f, &p->path_floppy, tmp, p->floppyslots[i].df);
762 		_stprintf (tmp, _T("floppy%dwp"), i);
763 		cfgfile_dwrite_bool (f, tmp, p->floppyslots[i].forcedwriteprotect);
764 		_stprintf (tmp, _T("floppy%dtype"), i);
765 		cfgfile_dwrite (f, tmp, _T("%d"), p->floppyslots[i].dfxtype);
766 		_stprintf (tmp, _T("floppy%dsound"), i);
767 		cfgfile_dwrite (f, tmp, _T("%d"), p->floppyslots[i].dfxclick);
768 		if (p->floppyslots[i].dfxclick < 0 && p->floppyslots[i].dfxclickexternal[0]) {
769 			_stprintf (tmp, _T("floppy%dsoundext"), i);
770 			cfgfile_dwrite (f, tmp, p->floppyslots[i].dfxclickexternal);
771 		}
772 		if (p->floppyslots[i].dfxtype < 0 && p->nr_floppies > i)
773 			p->nr_floppies = i;
774 	}
775 	for (i = 0; i < MAX_SPARE_DRIVES; i++) {
776 		if (p->dfxlist[i][0]) {
777 			_stprintf (tmp, _T("diskimage%d"), i);
778 			cfgfile_dwrite_path (f, &p->path_floppy, tmp, p->dfxlist[i]);
779 		}
780 	}
781 
782 	for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
783 		if (p->cdslots[i].name[0] || p->cdslots[i].inuse) {
784 			TCHAR tmp2[MAX_DPATH];
785 			_stprintf (tmp, _T("cdimage%d"), i);
786 			TCHAR *s = cfgfile_put_multipath (&p->path_cd, p->cdslots[i].name);
787 			_tcscpy (tmp2, s);
788 			xfree (s);
789 			if (p->cdslots[i].type != SCSI_UNIT_DEFAULT || _tcschr (p->cdslots[i].name, ',') || p->cdslots[i].delayed) {
790 				_tcscat (tmp2, _T(","));
791 				if (p->cdslots[i].delayed) {
792 					_tcscat (tmp2, _T("delay"));
793 					_tcscat (tmp2, _T(":"));
794 				}
795 				if (p->cdslots[i].type != SCSI_UNIT_DEFAULT) {
796 					_tcscat (tmp2, cdmodes[p->cdslots[i].type + 1]);
797 				}
798 			}
799 			cfgfile_write_str (f, tmp, tmp2);
800 		}
801 	}
802 
803 	if (p->statefile[0])
804 		cfgfile_write_str (f, _T("statefile"), p->statefile);
805 	if (p->quitstatefile[0])
806 		cfgfile_write_str (f, _T("statefile_quit"), p->quitstatefile);
807 
808 	cfgfile_write (f, _T("nr_floppies"), _T("%d"), p->nr_floppies);
809 	cfgfile_dwrite_bool (f, _T("floppy_write_protect"), p->floppy_read_only);
810 	cfgfile_write (f, _T("floppy_speed"), _T("%d"), p->floppy_speed);
811 #ifdef DRIVESOUND
812 	cfgfile_write (f, _T("floppy_volume"), _T("%d"), p->dfxclickvolume);
813 	cfgfile_dwrite (f, _T("floppy_channel_mask"), _T("0x%x"), p->dfxclickchannelmask);
814 #endif
815 	cfgfile_write_bool (f, _T("parallel_on_demand"), p->parallel_demand);
816 	cfgfile_write_bool (f, _T("serial_on_demand"), p->serial_demand);
817 	cfgfile_write_bool (f, _T("serial_hardware_ctsrts"), p->serial_hwctsrts);
818 	cfgfile_write_bool (f, _T("serial_direct"), p->serial_direct);
819 	cfgfile_dwrite (f, _T("serial_stopbits"), _T("%d"), p->serial_stopbits);
820 	cfgfile_write_str (f, _T("scsi"), scsimode[p->scsi]);
821 	cfgfile_write_bool (f, _T("uaeserial"), p->uaeserial);
822 	cfgfile_write_bool (f, _T("sana2"), p->sana2);
823 
824 	cfgfile_write_str (f, _T("sound_output"), soundmode1[p->produce_sound]);
825 	cfgfile_write_str (f, _T("sound_channels"), stereomode[p->sound_stereo]);
826 	cfgfile_write (f, _T("sound_stereo_separation"), _T("%d"), p->sound_stereo_separation);
827 	cfgfile_write (f, _T("sound_stereo_mixing_delay"), _T("%d"), p->sound_mixed_stereo_delay >= 0 ? p->sound_mixed_stereo_delay : 0);
828 	cfgfile_write (f, _T("sound_max_buff"), _T("%d"), p->sound_maxbsiz);
829 	cfgfile_write (f, _T("sound_frequency"), _T("%d"), p->sound_freq);
830 	cfgfile_write_str (f, _T("sound_interpol"), interpolmode[p->sound_interpol]);
831 	cfgfile_write_str (f, _T("sound_filter"), soundfiltermode1[p->sound_filter]);
832 	cfgfile_write_str (f, _T("sound_filter_type"), soundfiltermode2[p->sound_filter_type]);
833 	cfgfile_write (f, _T("sound_volume"), _T("%d"), p->sound_volume);
834 	if (p->sound_volume_cd >= 0)
835 		cfgfile_write (f, _T("sound_volume_cd"), _T("%d"), p->sound_volume_cd);
836 	cfgfile_write_bool (f, _T("sound_auto"), p->sound_auto);
837 	cfgfile_write_bool (f, _T("sound_stereo_swap_paula"), p->sound_stereo_swap_paula);
838 	cfgfile_write_bool (f, _T("sound_stereo_swap_ahi"), p->sound_stereo_swap_ahi);
839 	cfgfile_dwrite (f, _T("sampler_frequency"), _T("%d"), p->sampler_freq);
840 	cfgfile_dwrite (f, _T("sampler_buffer"), _T("%d"), p->sampler_buffer);
841 	cfgfile_dwrite_bool (f, _T("sampler_stereo"), p->sampler_stereo);
842 
843 #ifdef JIT
844 	cfgfile_write_str (f, _T("comp_trustbyte"), compmode[p->comptrustbyte]);
845 	cfgfile_write_str (f, _T("comp_trustword"), compmode[p->comptrustword]);
846 	cfgfile_write_str (f, _T("comp_trustlong"), compmode[p->comptrustlong]);
847 	cfgfile_write_str (f, _T("comp_trustnaddr"), compmode[p->comptrustnaddr]);
848 	cfgfile_write_bool (f, _T("comp_nf"), p->compnf);
849 	cfgfile_write_bool (f, _T("comp_constjump"), p->comp_constjump);
850 	cfgfile_write_bool (f, _T("comp_oldsegv"), p->comp_oldsegv);
851 
852 	cfgfile_write_str (f, _T("comp_flushmode"), flushmode[p->comp_hardflush]);
853 	cfgfile_write_bool (f, _T("compfpu"), p->compfpu);
854 	cfgfile_write_bool (f, _T("fpu_strict"), p->fpu_strict);
855 	cfgfile_write_bool (f, _T("comp_midopt"), p->comp_midopt);
856 	cfgfile_write_bool (f, _T("comp_lowopt"), p->comp_lowopt);
857 #endif
858 	cfgfile_write_bool (f, _T("avoid_cmov"), p->avoid_cmov);
859 	cfgfile_write (f, _T("cachesize"), _T("%d"), p->cachesize);
860 
861 	for (i = 0; i < MAX_JPORTS; i++) {
862 		struct jport *jp = &p->jports[i];
863 		int v = jp->id;
864 		TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH];
865 		if (v == JPORT_CUSTOM) {
866 			_tcscpy (tmp2, _T("custom"));
867 		} else if (v == JPORT_NONE) {
868 			_tcscpy (tmp2, _T("none"));
869 		} else if (v < JSEM_JOYS) {
870 			_stprintf (tmp2, _T("kbd%d"), v + 1);
871 		} else if (v < JSEM_MICE) {
872 			_stprintf (tmp2, _T("joy%d"), v - JSEM_JOYS);
873 		} else {
874 			_tcscpy (tmp2, _T("mouse"));
875 			if (v - JSEM_MICE > 0)
876 				_stprintf (tmp2, _T("mouse%d"), v - JSEM_MICE);
877 		}
878 		if (i < 2 || jp->id >= 0) {
879 			_stprintf (tmp1, _T("joyport%d"), i);
880 			cfgfile_write (f, tmp1, tmp2);
881 			_stprintf (tmp1, _T("joyport%dautofire"), i);
882 			cfgfile_write (f, tmp1, joyaf[jp->autofire]);
883 			if (i < 2 && jp->mode > 0) {
884 				_stprintf (tmp1, _T("joyport%dmode"), i);
885 				cfgfile_write (f, tmp1, joyportmodes[jp->mode]);
886 			}
887 			if (jp->name[0]) {
888 				_stprintf (tmp1, _T("joyportfriendlyname%d"), i);
889 				cfgfile_write (f, tmp1, jp->name);
890 			}
891 			if (jp->configname[0]) {
892 				_stprintf (tmp1, _T("joyportname%d"), i);
893 				cfgfile_write (f, tmp1, jp->configname);
894 			}
895 		}
896 	}
897 	if (p->dongle) {
898 		if (p->dongle + 1 >= (int)(sizeof (dongles) / sizeof (TCHAR*)) )
899 			cfgfile_write (f, _T("dongle"), _T("%d"), p->dongle);
900 		else
901 			cfgfile_write_str (f, _T("dongle"), dongles[p->dongle]);
902 	}
903 
904 	cfgfile_write_bool (f, _T("bsdsocket_emu"), p->socket_emu);
905 	if (p->a2065name[0])
906 		cfgfile_write_str (f, _T("a2065"), p->a2065name);
907 
908 	cfgfile_write_bool (f, _T("synchronize_clock"), p->tod_hack);
909 	cfgfile_write (f, _T("maprom"), _T("0x%x"), p->maprom);
910 	cfgfile_dwrite_str (f, _T("parallel_matrix_emulation"), epsonprinter[p->parallel_matrix_emulation]);
911 	cfgfile_write_bool (f, _T("parallel_postscript_emulation"), p->parallel_postscript_emulation);
912 	cfgfile_write_bool (f, _T("parallel_postscript_detection"), p->parallel_postscript_detection);
913 	cfgfile_write_str (f, _T("ghostscript_parameters"), p->ghostscript_parameters);
914 	cfgfile_write (f, _T("parallel_autoflush"), _T("%d"), p->parallel_autoflush_time);
915 	cfgfile_dwrite (f, _T("uae_hide"), _T("%d"), p->uae_hide);
916 	cfgfile_dwrite_bool (f, _T("magic_mouse"), p->input_magic_mouse);
917 	cfgfile_dwrite_str (f, _T("magic_mousecursor"), magiccursors[p->input_magic_mouse_cursor]);
918 	cfgfile_dwrite_str (f, _T("absolute_mouse"), abspointers[p->input_tablet]);
919 	cfgfile_dwrite_bool (f, _T("clipboard_sharing"), p->clipboard_sharing);
920 	cfgfile_dwrite_bool (f, _T("native_code"), p->native_code);
921 
922 	cfgfile_write (f, _T("gfx_display"), _T("%d"), p->gfx_apmode[APMODE_NATIVE].gfx_display);
923 	cfgfile_write_str (f, _T("gfx_display_friendlyname"), target_get_display_name (p->gfx_apmode[APMODE_NATIVE].gfx_display, true));
924 	cfgfile_write_str (f, _T("gfx_display_name"), target_get_display_name (p->gfx_apmode[APMODE_NATIVE].gfx_display, false));
925 	cfgfile_write (f, _T("gfx_display_rtg"), _T("%d"), p->gfx_apmode[APMODE_RTG].gfx_display);
926 	cfgfile_write_str (f, _T("gfx_display_friendlyname_rtg"), target_get_display_name (p->gfx_apmode[APMODE_RTG].gfx_display, true));
927 	cfgfile_write_str (f, _T("gfx_display_name_rtg"), target_get_display_name (p->gfx_apmode[APMODE_RTG].gfx_display, false));
928 
929 	cfgfile_write (f, _T("gfx_framerate"), _T("%d"), p->gfx_framerate);
930 	write_resolution (f, _T("gfx_width"), _T("gfx_height"), &p->gfx_size_win); /* compatibility with old versions */
931 	cfgfile_write (f, _T("gfx_top_windowed"), _T("%d"), p->gfx_size_win.x);
932 	cfgfile_write (f, _T("gfx_left_windowed"), _T("%d"), p->gfx_size_win.y);
933 	write_resolution (f, _T("gfx_width_windowed"), _T("gfx_height_windowed"), &p->gfx_size_win);
934 	write_resolution (f, _T("gfx_width_fullscreen"), _T("gfx_height_fullscreen"), &p->gfx_size_fs);
935 	cfgfile_write (f, _T("gfx_refreshrate"), _T("%d"), p->gfx_apmode[0].gfx_refreshrate);
936 	cfgfile_dwrite (f, _T("gfx_refreshrate_rtg"), _T("%d"), p->gfx_apmode[1].gfx_refreshrate);
937 	cfgfile_write_bool (f, _T("gfx_autoresolution"), p->gfx_autoresolution);
938 	cfgfile_dwrite (f, _T("gfx_autoresolution_delay"), _T("%d"), p->gfx_autoresolution_delay);
939 	cfgfile_dwrite (f, _T("gfx_autoresolution_min_vertical"), vertmode[p->gfx_autoresolution_minv + 1]);
940 	cfgfile_dwrite (f, _T("gfx_autoresolution_min_horizontal"), horizmode[p->gfx_autoresolution_minh + 1]);
941 
942 	cfgfile_write (f, _T("gfx_backbuffers"), _T("%d"), p->gfx_apmode[0].gfx_backbuffers);
943 	cfgfile_write (f, _T("gfx_backbuffers_rtg"), _T("%d"), p->gfx_apmode[1].gfx_backbuffers);
944 	if (p->gfx_apmode[APMODE_NATIVE].gfx_interlaced)
945 		cfgfile_write_bool (f, _T("gfx_interlace"), p->gfx_apmode[APMODE_NATIVE].gfx_interlaced);
946 	cfgfile_write_str (f, _T("gfx_vsync"), vsyncmodes[p->gfx_apmode[0].gfx_vsync]);
947 	cfgfile_write_str (f, _T("gfx_vsyncmode"), vsyncmodes2[p->gfx_apmode[0].gfx_vsyncmode]);
948 	cfgfile_write_str (f, _T("gfx_vsync_picasso"), vsyncmodes[p->gfx_apmode[1].gfx_vsync]);
949 	cfgfile_write_str (f, _T("gfx_vsyncmode_picasso"), vsyncmodes2[p->gfx_apmode[1].gfx_vsyncmode]);
950 	cfgfile_write_bool (f, _T("gfx_lores"), p->gfx_resolution == 0);
951 	cfgfile_write_str (f, _T("gfx_resolution"), lorestype1[p->gfx_resolution]);
952 	cfgfile_write_str (f, _T("gfx_lores_mode"), loresmode[p->gfx_lores_mode]);
953 	cfgfile_write_bool (f, _T("gfx_flickerfixer"), p->gfx_scandoubler);
954 	cfgfile_write_str (f, _T("gfx_linemode"), linemode[p->gfx_vresolution * 2 + p->gfx_scanlines]);
955 	cfgfile_write_str (f, _T("gfx_fullscreen_amiga"), fullmodes[p->gfx_apmode[0].gfx_fullscreen]);
956 	cfgfile_write_str (f, _T("gfx_fullscreen_picasso"), fullmodes[p->gfx_apmode[1].gfx_fullscreen]);
957 	cfgfile_write_str (f, _T("gfx_center_horizontal"), centermode1[p->gfx_xcenter]);
958 	cfgfile_write_str (f, _T("gfx_center_vertical"), centermode1[p->gfx_ycenter]);
959 	cfgfile_write_str (f, _T("gfx_colour_mode"), colormode1[p->color_mode]);
960 	cfgfile_write_bool (f, _T("gfx_blacker_than_black"), p->gfx_blackerthanblack);
961 	cfgfile_dwrite_bool (f, _T("gfx_black_frame_insertion"), p->lightboost_strobo);
962 	cfgfile_write_str (f, _T("gfx_api"), filterapi[p->gfx_api]);
963 	cfgfile_dwrite (f, _T("gfx_horizontal_tweak"), _T("%d"), p->gfx_extrawidth);
964 
965 #ifdef GFXFILTER
966 	for (int i = 0; i <MAX_FILTERSHADERS; i++) {
967 		if (p->gfx_filtershader[i][0])
968 			cfgfile_write (f, _T("gfx_filter_pre"), _T("D3D:%s"), p->gfx_filtershader[i]);
969 		if (p->gfx_filtermask[i][0])
970 			cfgfile_write_str (f, _T("gfx_filtermask_pre"), p->gfx_filtermask[i]);
971 	}
972 	for (int i = 0; i <MAX_FILTERSHADERS; i++) {
973 		if (p->gfx_filtershader[i + MAX_FILTERSHADERS][0])
974 			cfgfile_write (f, _T("gfx_filter_post"), _T("D3D:%s"), p->gfx_filtershader[i + MAX_FILTERSHADERS]);
975 		if (p->gfx_filtermask[i + MAX_FILTERSHADERS][0])
976 			cfgfile_write_str (f, _T("gfx_filtermask_post"), p->gfx_filtermask[i + MAX_FILTERSHADERS]);
977 	}
978 	cfgfile_dwrite_str (f, _T("gfx_filter_mask"), p->gfx_filtermask[2 * MAX_FILTERSHADERS]);
979 	{
980 		bool d3dfound = false;
981 		if (p->gfx_filtershader[2 * MAX_FILTERSHADERS][0] && p->gfx_api) {
982 			cfgfile_dwrite (f, _T("gfx_filter"), _T("D3D:%s"), p->gfx_filtershader[2 * MAX_FILTERSHADERS]);
983 			d3dfound = true;
984 		}
985 		if (!d3dfound) {
986 			if (p->gfx_filter > 0) {
987 				int i = 0;
988 				struct uae_filter *uf;
989 				while (uaefilters[i].name) {
990 					uf = &uaefilters[i];
991 					if (uf->type == p->gfx_filter) {
992 						cfgfile_dwrite_str (f, _T("gfx_filter"), uf->cfgname);
993 					}
994 					i++;
995 				}
996 			} else {
997 				cfgfile_dwrite (f, _T("gfx_filter"), _T("no"));
998 			}
999 		}
1000 	}
1001 	cfgfile_dwrite_str (f, _T("gfx_filter_mode"), filtermode2[p->gfx_filter_filtermode]);
1002 	cfgfile_dwrite (f, _T("gfx_filter_vert_zoomf"), _T("%f"), p->gfx_filter_vert_zoom);
1003 	cfgfile_dwrite (f, _T("gfx_filter_horiz_zoomf"), _T("%f"), p->gfx_filter_horiz_zoom);
1004 	cfgfile_dwrite (f, _T("gfx_filter_vert_zoom_multf"), _T("%f"), p->gfx_filter_vert_zoom_mult);
1005 	cfgfile_dwrite (f, _T("gfx_filter_horiz_zoom_multf"), _T("%f"), p->gfx_filter_horiz_zoom_mult);
1006 	cfgfile_dwrite (f, _T("gfx_filter_vert_offsetf"), _T("%f"), p->gfx_filter_vert_offset);
1007 	cfgfile_dwrite (f, _T("gfx_filter_horiz_offsetf"), _T("%f"), p->gfx_filter_horiz_offset);
1008 	cfgfile_dwrite (f, _T("gfx_filter_scanlines"), _T("%d"), p->gfx_filter_scanlines);
1009 	cfgfile_dwrite (f, _T("gfx_filter_scanlinelevel"), _T("%d"), p->gfx_filter_scanlinelevel);
1010 	cfgfile_dwrite (f, _T("gfx_filter_scanlineratio"), _T("%d"), p->gfx_filter_scanlineratio);
1011 	cfgfile_dwrite (f, _T("gfx_filter_luminance"), _T("%d"), p->gfx_filter_luminance);
1012 	cfgfile_dwrite (f, _T("gfx_filter_contrast"), _T("%d"), p->gfx_filter_contrast);
1013 	cfgfile_dwrite (f, _T("gfx_filter_saturation"), _T("%d"), p->gfx_filter_saturation);
1014 	cfgfile_dwrite (f, _T("gfx_filter_gamma"), _T("%d"), p->gfx_filter_gamma);
1015 	cfgfile_dwrite (f, _T("gfx_filter_blur"), _T("%d"), p->gfx_filter_blur);
1016 	cfgfile_dwrite (f, _T("gfx_filter_noise"), _T("%d"), p->gfx_filter_noise);
1017 	cfgfile_dwrite_bool (f, _T("gfx_filter_bilinear"), p->gfx_filter_bilinear != 0);
1018 	cfgfile_dwrite (f, _T("gfx_filter_keep_autoscale_aspect"), _T("%d"), p->gfx_filter_keep_autoscale_aspect);
1019 	cfgfile_dwrite_str (f, _T("gfx_filter_keep_aspect"), aspects[p->gfx_filter_keep_aspect]);
1020 	cfgfile_dwrite_str (f, _T("gfx_filter_autoscale"), autoscale[p->gfx_filter_autoscale]);
1021 	cfgfile_dwrite (f, _T("gfx_filter_aspect_ratio"), _T("%d:%d"),
1022 		p->gfx_filter_aspect >= 0 ? (p->gfx_filter_aspect / ASPECTMULT) : -1,
1023 		p->gfx_filter_aspect >= 0 ? (p->gfx_filter_aspect & (ASPECTMULT - 1)) : -1);
1024 	cfgfile_dwrite (f, _T("gfx_luminance"), _T("%d"), p->gfx_luminance);
1025 	cfgfile_dwrite (f, _T("gfx_contrast"), _T("%d"), p->gfx_contrast);
1026 	cfgfile_dwrite (f, _T("gfx_gamma"), _T("%d"), p->gfx_gamma);
1027 	if (p->gfx_filteroverlay[0]) {
1028 		cfgfile_dwrite (f, _T("gfx_filter_overlay"), _T("%s%s"),
1029 			p->gfx_filteroverlay, _tcschr (p->gfx_filteroverlay, ',') ? _T(",") : _T(""));
1030 
1031 #if 0
1032 		cfgfile_dwrite (f, _T("gfx_filter_overlay"), _T("%s,%d%s:%d%s:%d%s:%d%s:%d%%"),
1033 			p->gfx_filteroverlay,
1034 			p->gfx_filteroverlay_pos.x >= -24000 ? p->gfx_filteroverlay_pos.x : -p->gfx_filteroverlay_pos.x - 30000,
1035 			p->gfx_filteroverlay_pos.x >= -24000 ? _T("") : _T("%"),
1036 			p->gfx_filteroverlay_pos.y >= -24000 ? p->gfx_filteroverlay_pos.y : -p->gfx_filteroverlay_pos.y - 30000,
1037 			p->gfx_filteroverlay_pos.y >= -24000 ? _T("") : _T("%"),
1038 			p->gfx_filteroverlay_pos.width >= -24000 ? p->gfx_filteroverlay_pos.width : -p->gfx_filteroverlay_pos.width - 30000,
1039 			p->gfx_filteroverlay_pos.width >= -24000 ? _T("") : _T("%"),
1040 			p->gfx_filteroverlay_pos.height >= -24000 ? p->gfx_filteroverlay_pos.height : -p->gfx_filteroverlay_pos.height - 30000,
1041 			p->gfx_filteroverlay_pos.height >= -24000 ? _T("") : _T("%"),
1042 			p->gfx_filteroverlay_overscan
1043 			);
1044 #endif
1045 	}
1046 
1047 	cfgfile_dwrite (f, _T("gfx_center_horizontal_position"), _T("%d"), p->gfx_xcenter_pos);
1048 	cfgfile_dwrite (f, _T("gfx_center_vertical_position"), _T("%d"), p->gfx_ycenter_pos);
1049 	cfgfile_dwrite (f, _T("gfx_center_horizontal_size"), _T("%d"), p->gfx_xcenter_size);
1050 	cfgfile_dwrite (f, _T("gfx_center_vertical_size"), _T("%d"), p->gfx_ycenter_size);
1051 
1052 	cfgfile_dwrite (f, _T("rtg_vert_zoom_multf"), _T("%.f"), p->rtg_vert_zoom_mult);
1053 	cfgfile_dwrite (f, _T("rtg_horiz_zoom_multf"), _T("%.f"), p->rtg_horiz_zoom_mult);
1054 
1055 #endif
1056 
1057 	cfgfile_write_bool (f, _T("immediate_blits"), p->immediate_blits);
1058 	cfgfile_dwrite_str (f, _T("waiting_blits"), waitblits[p->waiting_blits]);
1059 	cfgfile_write_bool (f, _T("ntsc"), p->ntscmode);
1060 	cfgfile_write_bool (f, _T("genlock"), p->genlock);
1061 	cfgfile_dwrite_str (f, _T("monitoremu"), specialmonitors[p->monitoremu]);
1062 
1063 	cfgfile_dwrite_bool (f, _T("show_leds"), !!(p->leds_on_screen & STATUSLINE_CHIPSET));
1064 	cfgfile_dwrite_bool (f, _T("show_leds_rtg"), !!(p->leds_on_screen & STATUSLINE_RTG));
1065 	write_leds(f, _T("show_leds_enabled"), p->leds_on_screen_mask[0]);
1066 	write_leds(f, _T("show_leds_enabled_rtg"), p->leds_on_screen_mask[1]);
1067 
1068 	if (p->osd_pos.y || p->osd_pos.x) {
1069 		cfgfile_dwrite (f, _T("osd_position"), _T("%.1f%s:%.1f%s"),
1070 			p->osd_pos.x >= 20000 ? (p->osd_pos.x - 30000) / 10.0 : (float)p->osd_pos.x, p->osd_pos.x >= 20000 ? _T("%") : _T(""),
1071 			p->osd_pos.y >= 20000 ? (p->osd_pos.y - 30000) / 10.0 : (float)p->osd_pos.y, p->osd_pos.y >= 20000 ? _T("%") : _T(""));
1072 	}
1073 	cfgfile_dwrite (f, _T("keyboard_leds"), _T("numlock:%s,capslock:%s,scrolllock:%s"),
1074 		kbleds[p->keyboard_leds[0]], kbleds[p->keyboard_leds[1]], kbleds[p->keyboard_leds[2]]);
1075 	if (p->chipset_mask & CSMASK_AGA)
1076 		cfgfile_write (f, _T("chipset"),_T("aga"));
1077 	else if ((p->chipset_mask & CSMASK_ECS_AGNUS) && (p->chipset_mask & CSMASK_ECS_DENISE))
1078 		cfgfile_write (f, _T("chipset"),_T("ecs"));
1079 	else if (p->chipset_mask & CSMASK_ECS_AGNUS)
1080 		cfgfile_write (f, _T("chipset"),_T("ecs_agnus"));
1081 	else if (p->chipset_mask & CSMASK_ECS_DENISE)
1082 		cfgfile_write (f, _T("chipset"),_T("ecs_denise"));
1083 	else
1084 		cfgfile_write (f, _T("chipset"), _T("ocs"));
1085 	if (p->chipset_refreshrate > 0)
1086 		cfgfile_write (f, _T("chipset_refreshrate"), _T("%f"), p->chipset_refreshrate);
1087 
1088 	for (int i = 0; i < MAX_CHIPSET_REFRESH_TOTAL; i++) {
1089 		if (p->cr[i].rate <= 0)
1090 			continue;
1091 		struct chipset_refresh *cr = &p->cr[i];
1092 		cr->index = i;
1093 		_stprintf (tmp, _T("%f"), cr->rate);
1094 		TCHAR *s = tmp + _tcslen (tmp);
1095 		if (cr->label[0] > 0 && i < MAX_CHIPSET_REFRESH)
1096 			s += _stprintf (s, _T(",t=%s"), cr->label);
1097 		if (cr->horiz > 0)
1098 			s += _stprintf (s, _T(",h=%d"), cr->horiz);
1099 		if (cr->vert > 0)
1100 			s += _stprintf (s, _T(",v=%d"), cr->vert);
1101 		if (cr->locked)
1102 			_tcscat (s, _T(",locked"));
1103 		if (cr->ntsc > 0)
1104 			_tcscat (s, _T(",ntsc"));
1105 		else if (cr->ntsc == 0)
1106 			_tcscat (s, _T(",pal"));
1107 		if (cr->lace > 0)
1108 			_tcscat (s, _T(",lace"));
1109 		else if (cr->lace == 0)
1110 			_tcscat (s, _T(",nlace"));
1111 		if (cr->framelength > 0)
1112 			_tcscat (s, _T(",lof"));
1113 		else if (cr->framelength == 0)
1114 			_tcscat (s, _T(",shf"));
1115 		if (cr->vsync > 0)
1116 			_tcscat (s, _T(",vsync"));
1117 		else if (cr->vsync == 0)
1118 			_tcscat (s, _T(",nvsync"));
1119 		if (cr->rtg)
1120 			_tcscat (s, _T(",rtg"));
1121 		if (cr->commands[0]) {
1122 			_tcscat (s, _T(","));
1123 			_tcscat (s, cr->commands);
1124 			for (int j = 0; j < _tcslen (s); j++) {
1125 				if (s[j] == '\n')
1126 					s[j] = ',';
1127 			}
1128 			s[_tcslen (s) - 1] = 0;
1129 		}
1130 		if (i == CHIPSET_REFRESH_PAL)
1131 			cfgfile_dwrite (f, _T("displaydata_pal"), tmp);
1132 		else if (i == CHIPSET_REFRESH_NTSC)
1133 			cfgfile_dwrite (f, _T("displaydata_ntsc"), tmp);
1134 		else
1135 			cfgfile_dwrite (f, _T("displaydata"), tmp);
1136 	}
1137 
1138 	cfgfile_write_str (f, _T("collision_level"), collmode[p->collision_level]);
1139 
1140 	cfgfile_write_str(f, _T("chipset_compatible"), cscompa[p->cs_compatible]);
1141 	cfgfile_dwrite_str (f, _T("ciaatod"), ciaatodmode[p->cs_ciaatod]);
1142 	cfgfile_dwrite_str (f, _T("rtc"), rtctype[p->cs_rtc]);
1143 	//cfgfile_dwrite (f, _T("chipset_rtc_adjust"), _T("%d"), p->cs_rtc_adjust);
1144 	cfgfile_dwrite_bool (f, _T("ksmirror_e0"), p->cs_ksmirror_e0);
1145 	cfgfile_dwrite_bool (f, _T("ksmirror_a8"), p->cs_ksmirror_a8);
1146 	cfgfile_dwrite_bool (f, _T("cd32cd"), p->cs_cd32cd);
1147 	cfgfile_dwrite_bool (f, _T("cd32c2p"), p->cs_cd32c2p);
1148 	cfgfile_dwrite_bool (f, _T("cd32nvram"), p->cs_cd32nvram);
1149 	cfgfile_dwrite_bool (f, _T("cdtvcd"), p->cs_cdtvcd);
1150 	cfgfile_dwrite_bool (f, _T("cdtvram"), p->cs_cdtvram);
1151 	cfgfile_dwrite (f, _T("cdtvramcard"), _T("%d"), p->cs_cdtvcard);
1152 	cfgfile_dwrite_str (f, _T("ide"), p->cs_ide == IDE_A600A1200 ? _T("a600/a1200") : (p->cs_ide == IDE_A4000 ? _T("a4000") : _T("none")));
1153 	cfgfile_dwrite_bool (f, _T("a1000ram"), p->cs_a1000ram);
1154 	cfgfile_dwrite (f, _T("fatgary"), _T("%d"), p->cs_fatgaryrev);
1155 	cfgfile_dwrite (f, _T("ramsey"), _T("%d"), p->cs_ramseyrev);
1156 	cfgfile_dwrite_bool (f, _T("pcmcia"), p->cs_pcmcia);
1157 	cfgfile_dwrite_bool (f, _T("scsi_cdtv"), p->cs_cdtvscsi);
1158 	cfgfile_dwrite_bool (f, _T("scsi_a2091"), p->cs_a2091);
1159 	cfgfile_dwrite_bool (f, _T("scsi_a4091"), p->cs_a4091);
1160 	cfgfile_dwrite_bool (f, _T("scsi_a3000"), p->cs_mbdmac == 1);
1161 	cfgfile_dwrite_bool (f, _T("scsi_a4000t"), p->cs_mbdmac == 2);
1162 	cfgfile_dwrite_bool (f, _T("bogomem_fast"), p->cs_slowmemisfast);
1163 	cfgfile_dwrite_bool (f, _T("resetwarning"), p->cs_resetwarning);
1164 	cfgfile_dwrite_bool (f, _T("denise_noehb"), p->cs_denisenoehb);
1165 	cfgfile_dwrite_bool (f, _T("agnus_bltbusybug"), p->cs_agnusbltbusybug);
1166 	cfgfile_dwrite_bool (f, _T("ics_agnus"), p->cs_dipagnus);
1167 	cfgfile_dwrite (f, _T("chipset_hacks"), _T("0x%x"), p->cs_hacks);
1168 
1169 	cfgfile_dwrite_bool (f, _T("fastmem_autoconfig"), p->fastmem_autoconfig);
1170 	cfgfile_write (f, _T("fastmem_size"), _T("%d"), p->fastmem_size / 0x100000);
1171 	cfgfile_dwrite (f, _T("fastmem2_size"), _T("%d"), p->fastmem2_size / 0x100000);
1172 	cfgfile_write (f, _T("a3000mem_size"), _T("%d"), p->mbresmem_low_size / 0x100000);
1173 	cfgfile_write (f, _T("mbresmem_size"), _T("%d"), p->mbresmem_high_size / 0x100000);
1174 	cfgfile_write (f, _T("z3mem_size"), _T("%d"), p->z3fastmem_size / 0x100000);
1175 	cfgfile_dwrite (f, _T("z3mem2_size"), _T("%d"), p->z3fastmem2_size / 0x100000);
1176 	cfgfile_write (f, _T("z3mem_start"), _T("0x%x"), p->z3fastmem_start);
1177 	cfgfile_write (f, _T("bogomem_size"), _T("%d"), p->bogomem_size / 0x40000);
1178 	cfgfile_write (f, _T("gfxcard_size"), _T("%d"), p->rtgmem_size / 0x100000);
1179 	cfgfile_write_str (f, _T("gfxcard_type"), rtgtype[p->rtgmem_type]);
1180 	cfgfile_write_bool (f, _T("gfxcard_hardware_vblank"), p->rtg_hardwareinterrupt);
1181 	cfgfile_write_bool (f, _T("gfxcard_hardware_sprite"), p->rtg_hardwaresprite);
1182 	cfgfile_write (f, _T("chipmem_size"), _T("%d"), p->chipmem_size == 0x20000 ? -1 : (int)(p->chipmem_size == 0x40000 ? 0 : p->chipmem_size / 0x80000));
1183 	cfgfile_dwrite (f, _T("megachipmem_size"), _T("%d"), p->z3chipmem_size / 0x100000);
1184 	if (p->custom_memory_sizes[0])
1185 		cfgfile_write (f, _T("addmem1"), _T("0x%x,0x%x"), p->custom_memory_addrs[0], p->custom_memory_sizes[0]);
1186 	if (p->custom_memory_sizes[1])
1187 		cfgfile_write (f, _T("addmem2"), _T("0x%x,0x%x"), p->custom_memory_addrs[1], p->custom_memory_sizes[1]);
1188 
1189 	if (p->m68k_speed > 0) {
1190 		cfgfile_write (f, _T("finegrain_cpu_speed"), _T("%d"), p->m68k_speed);
1191 	} else {
1192 		cfgfile_write_str (f, _T("cpu_speed"), p->m68k_speed < 0 ? _T("max") : _T("real"));
1193 	}
1194 	cfgfile_write (f, _T("cpu_throttle"), _T("%.1f"), p->m68k_speed_throttle);
1195 
1196 	/* do not reorder start */
1197 	write_compatibility_cpu(f, p);
1198 	cfgfile_write (f, _T("cpu_model"), _T("%d"), p->cpu_model);
1199 	if (p->fpu_model)
1200 		cfgfile_write (f, _T("fpu_model"), _T("%d"), p->fpu_model);
1201 	if (p->mmu_model)
1202 		cfgfile_write (f, _T("mmu_model"), _T("%d"), p->mmu_model);
1203 	cfgfile_write_bool (f, _T("cpu_compatible"), p->cpu_compatible);
1204 	cfgfile_write_bool (f, _T("cpu_24bit_addressing"), p->address_space_24);
1205 	/* do not reorder end */
1206 
1207 	if (p->cpu_cycle_exact) {
1208 		if (p->cpu_frequency)
1209 			cfgfile_write (f, _T("cpu_frequency"), _T("%d"), p->cpu_frequency);
1210 		if (p->cpu_clock_multiplier) {
1211 			if (p->cpu_clock_multiplier >= 256)
1212 				cfgfile_write (f, _T("cpu_multiplier"), _T("%d"), p->cpu_clock_multiplier >> 8);
1213 		}
1214 	}
1215 
1216 	cfgfile_write_bool (f, _T("cpu_cycle_exact"), p->cpu_cycle_exact);
1217 	cfgfile_write_bool (f, _T("blitter_cycle_exact"), p->blitter_cycle_exact);
1218 	cfgfile_write_bool (f, _T("cycle_exact"), p->cpu_cycle_exact && p->blitter_cycle_exact ? 1 : 0);
1219 	cfgfile_dwrite_bool (f, _T("fpu_no_unimplemented"), p->fpu_no_unimplemented);
1220 	cfgfile_dwrite_bool (f, _T("cpu_no_unimplemented"), p->int_no_unimplemented);
1221 
1222 	cfgfile_write_bool (f, _T("rtg_nocustom"), p->picasso96_nocustom);
1223 	cfgfile_write (f, _T("rtg_modes"), _T("0x%x"), p->picasso96_modeflags);
1224 
1225 	cfgfile_write_bool (f, _T("log_illegal_mem"), p->illegal_mem);
1226 	if (p->catweasel >= 100)
1227 		cfgfile_dwrite (f, _T("catweasel"), _T("0x%x"), p->catweasel);
1228 	else
1229 		cfgfile_dwrite (f, _T("catweasel"), _T("%d"), p->catweasel);
1230 
1231 	cfgfile_write_str (f, _T("kbd_lang"), (p->keyboard_lang == KBD_LANG_DE ? _T("de")
1232 		: p->keyboard_lang == KBD_LANG_DK ? _T("dk")
1233 		: p->keyboard_lang == KBD_LANG_ES ? _T("es")
1234 		: p->keyboard_lang == KBD_LANG_US ? _T("us")
1235 		: p->keyboard_lang == KBD_LANG_SE ? _T("se")
1236 		: p->keyboard_lang == KBD_LANG_FR ? _T("fr")
1237 		: p->keyboard_lang == KBD_LANG_IT ? _T("it")
1238 		: p->keyboard_lang == KBD_LANG_FI ? _T("fi")
1239 		: p->keyboard_lang == KBD_LANG_TR ? _T("tr")
1240 		: _T("FOO")));
1241 
1242 #ifdef SAVESTATE
1243 	cfgfile_dwrite (f, _T("state_replay_rate"), _T("%d"), p->statecapturerate);
1244 	cfgfile_dwrite (f, _T("state_replay_buffers"), _T("%d"), p->statecapturebuffersize);
1245 	cfgfile_dwrite_bool (f, _T("state_replay_autoplay"), p->inprec_autoplay);
1246 #endif
1247 	cfgfile_dwrite_bool (f, _T("warp"), p->turbo_emulation);
1248 
1249 #ifdef FILESYS
1250 	write_filesys_config (p, f);
1251 	if (p->filesys_no_uaefsdb)
1252 		cfgfile_write_bool (f, _T("filesys_no_fsdb"), p->filesys_no_uaefsdb);
1253 	cfgfile_dwrite (f, _T("filesys_max_size"), _T("%d"), p->filesys_limit);
1254 #endif
1255 	write_inputdevice_config (p, f);
1256 }
1257 
cfgfile_yesno2(const TCHAR * option,const TCHAR * value,const TCHAR * name,int * location)1258 int cfgfile_yesno2 (const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location)
1259 {
1260 	if (name != NULL && _tcscmp (option, name) != 0)
1261 		return 0;
1262 	if (strcasecmp (value, _T("yes")) == 0 || strcasecmp (value, _T("y")) == 0
1263 		|| strcasecmp (value, _T("true")) == 0 || strcasecmp (value, _T("t")) == 0)
1264 		*location = 1;
1265 	else if (strcasecmp (value, _T("no")) == 0 || strcasecmp (value, _T("n")) == 0
1266 		|| strcasecmp (value, _T("false")) == 0 || strcasecmp (value, _T("f")) == 0
1267 		|| strcasecmp (value, _T("0")) == 0)
1268 		*location = 0;
1269 	else {
1270 		write_log (_T("Option `%s' requires a value of either `yes' or `no' (was '%s').\n"), option, value);
1271 		return -1;
1272 	}
1273 	return 1;
1274 }
cfgfile_yesno(const TCHAR * option,const TCHAR * value,const TCHAR * name,bool * location)1275 int cfgfile_yesno (const TCHAR *option, const TCHAR *value, const TCHAR *name, bool *location)
1276 {
1277 	int val;
1278 	int ret = cfgfile_yesno2 (option, value, name, &val);
1279 	if (ret == 0)
1280 		return 0;
1281 	if (ret < 0)
1282 		*location = false;
1283 	else
1284 		*location = val != 0;
1285 	return 1;
1286 }
1287 
cfgfile_doubleval(const TCHAR * option,const TCHAR * value,const TCHAR * name,double * location)1288 int cfgfile_doubleval (const TCHAR *option, const TCHAR *value, const TCHAR *name, double *location)
1289 {
1290 	int base = 10;
1291 	TCHAR *endptr;
1292 	if (name != NULL && _tcscmp (option, name) != 0)
1293 		return 0;
1294 	*location = _tcstod (value, &endptr);
1295 	return 1;
1296 }
1297 
cfgfile_floatval(const TCHAR * option,const TCHAR * value,const TCHAR * name,float * location)1298 int cfgfile_floatval (const TCHAR *option, const TCHAR *value, const TCHAR *name, float *location)
1299 {
1300 	int base = 10;
1301 	TCHAR *endptr;
1302 	if (name != NULL && _tcscmp (option, name) != 0)
1303 		return 0;
1304 	*location = (float)_tcstod (value, &endptr);
1305 	return 1;
1306 }
1307 
cfgfile_intval_unsigned(const TCHAR * option,const TCHAR * value,const TCHAR * name,unsigned int * location,int scale)1308 int cfgfile_intval_unsigned (const TCHAR *option, const TCHAR *value, const TCHAR *name, unsigned int *location, int scale)
1309 {
1310 	int base = 10;
1311 	TCHAR *endptr;
1312 	if (name != NULL && _tcscmp (option, name) != 0)
1313 		return 0;
1314 	/* I guess octal isn't popular enough to worry about here...  */
1315 	if (value[0] == '0' && _totupper (value[1]) == 'X')
1316 		value += 2, base = 16;
1317 	*location = _tcstol (value, &endptr, base) * scale;
1318 
1319 	if (*endptr != '\0' || *value == '\0') {
1320 		if (strcasecmp (value, _T("false")) == 0 || strcasecmp (value, _T("no")) == 0) {
1321 			*location = 0;
1322 			return 1;
1323 		}
1324 		if (strcasecmp (value, _T("true")) == 0 || strcasecmp (value, _T("yes")) == 0) {
1325 			*location = 1;
1326 			return 1;
1327 		}
1328 		write_log (_T("Option '%s' requires a numeric argument but got '%s'\n"), option, value);
1329 		return -1;
1330 	}
1331 	return 1;
1332 }
1333 
cfgfile_intval(const TCHAR * option,const TCHAR * value,const TCHAR * name,int * location,int scale)1334 int cfgfile_intval (const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location, int scale)
1335 {
1336 	unsigned int v = 0;
1337 	int r = cfgfile_intval_unsigned (option, value, name, &v, scale);
1338 	if (!r)
1339 		return 0;
1340 	*location = (int)v;
1341 	return r;
1342 }
1343 
cfgfile_strval(const TCHAR * option,const TCHAR * value,const TCHAR * name,int * location,const TCHAR * table[],int more)1344 int cfgfile_strval (const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location, const TCHAR *table[], int more)
1345 {
1346 	int val;
1347 	if (name != NULL && _tcscmp (option, name) != 0)
1348 		return 0;
1349 	val = match_string (table, value);
1350 	if (val == -1) {
1351 		if (more)
1352 			return 0;
1353 		if (!strcasecmp (value, _T("yes")) || !strcasecmp (value, _T("true"))) {
1354 			val = 1;
1355 		} else if  (!strcasecmp (value, _T("no")) || !strcasecmp (value, _T("false"))) {
1356 			val = 0;
1357 		} else {
1358 		write_log (_T("Unknown value ('%s') for option '%s'.\n"), value, option);
1359 		return -1;
1360 	}
1361 	}
1362 	*location = val;
1363 	return 1;
1364 }
1365 
cfgfile_strboolval(const TCHAR * option,const TCHAR * value,const TCHAR * name,bool * location,const TCHAR * table[],int more)1366 int cfgfile_strboolval (const TCHAR *option, const TCHAR *value, const TCHAR *name, bool *location, const TCHAR *table[], int more)
1367 {
1368 	int locationint;
1369 	if (!cfgfile_strval (option, value, name, &locationint, table, more))
1370 		return 0;
1371 	*location = locationint != 0;
1372 	return 1;
1373 }
1374 
cfgfile_string(const TCHAR * option,const TCHAR * value,const TCHAR * name,TCHAR * location,int maxsz)1375 int cfgfile_string (const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz)
1376 {
1377 	if (_tcscmp (option, name) != 0)
1378 		return 0;
1379 	_tcsncpy (location, value, maxsz - 1);
1380 	location[maxsz - 1] = '\0';
1381 	return 1;
1382 }
1383 
cfgfile_path_mp(const TCHAR * option,const TCHAR * value,const TCHAR * name,TCHAR * location,int maxsz,struct multipath * mp)1384 int cfgfile_path_mp (const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz, struct multipath *mp)
1385 {
1386 	if (!cfgfile_string (option, value, name, location, maxsz))
1387 		return 0;
1388 	//TCHAR *s = target_expand_environment (location);
1389 	//_tcsncpy (location, location, maxsz - 1);
1390 	location[maxsz - 1] = 0;
1391 	if (mp) {
1392 		for (int i = 0; i < MAX_PATHS; i++) {
1393 			if (mp->path[i][0] && _tcscmp (mp->path[i], _T(".\\")) != 0 && _tcscmp (mp->path[i], _T("./")) != 0 && (location[0] != '/' && location[0] != '\\' && !_tcschr(location, ':'))) {
1394 				TCHAR np[MAX_DPATH];
1395 				_tcscpy (np, mp->path[i]);
1396 				fixtrailing (np);
1397 				_tcscat (np, location);
1398 				fullpath (np, sizeof np / sizeof (TCHAR));
1399 				if (zfile_exists (np)) {
1400 					_tcsncpy (location, np, maxsz - 1);
1401 					location[maxsz - 1] = 0;
1402 					break;
1403 				}
1404 			}
1405 		}
1406 	}
1407 
1408 	return 1;
1409 }
1410 
cfgfile_path(const TCHAR * option,const TCHAR * value,const TCHAR * name,TCHAR * location,int maxsz)1411 int cfgfile_path (const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz)
1412 {
1413 	return cfgfile_path_mp (option, value, name, location, maxsz, NULL);
1414 }
1415 
cfgfile_multipath(const TCHAR * option,const TCHAR * value,const TCHAR * name,struct multipath * mp)1416 int cfgfile_multipath (const TCHAR *option, const TCHAR *value, const TCHAR *name, struct multipath *mp)
1417 {
1418 	TCHAR tmploc[MAX_DPATH];
1419 	if (!cfgfile_string (option, value, name, tmploc, 256))
1420 		return 0;
1421 	for (int i = 0; i < MAX_PATHS; i++) {
1422 		if (mp->path[i][0] == 0 || (i == 0 && (!_tcscmp (mp->path[i], _T(".\\")) || !_tcscmp (mp->path[i], _T("./"))))) {
1423 			//TCHAR *s = target_expand_environment (tmploc);
1424 			_tcsncpy (mp->path[i], tmploc, 256 - 1);
1425 			mp->path[i][256 - 1] = 0;
1426 			fixtrailing (mp->path[i]);
1427 			return 1;
1428 		}
1429 	}
1430 	return 1;
1431 }
1432 
cfgfile_rom(const TCHAR * option,const TCHAR * value,const TCHAR * name,TCHAR * location,int maxsz)1433 int cfgfile_rom (const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz)
1434 {
1435 	TCHAR id[MAX_DPATH];
1436 	if (!cfgfile_string (option, value, name, id, sizeof id / sizeof (TCHAR)))
1437 		return 0;
1438 	if (zfile_exists (location))
1439 		return 1;
1440 	TCHAR *p = _tcschr (id, ',');
1441 	if (p) {
1442 		TCHAR *endptr, tmp;
1443 		*p = 0;
1444 		tmp = id[4];
1445 		id[4] = 0;
1446 		uae_u32 crc32 = _tcstol (id, &endptr, 16) << 16;
1447 		id[4] = tmp;
1448 		crc32 |= _tcstol (id + 4, &endptr, 16);
1449 		struct romdata *rd = getromdatabycrc (crc32);
1450 		if (rd) {
1451 			struct romlist *rl = getromlistbyromdata (rd);
1452 			if (rl) {
1453 				write_log (_T("%s: %s -> %s\n"), name, location, rl->path);
1454 				_tcsncpy (location, rl->path, maxsz);
1455 			}
1456 		}
1457 	}
1458 	return 1;
1459 }
1460 
getintval(TCHAR ** p,int * result,int delim)1461 static int getintval (TCHAR **p, int *result, int delim)
1462 {
1463 	TCHAR *value = *p;
1464 	int base = 10;
1465 	TCHAR *endptr;
1466 	TCHAR *p2 = _tcschr (*p, delim);
1467 
1468 	if (p2 == 0)
1469 		return 0;
1470 
1471 	*p2++ = '\0';
1472 
1473 	if (value[0] == '0' && _totupper (value[1]) == 'X')
1474 		value += 2, base = 16;
1475 	*result = _tcstol (value, &endptr, base);
1476 	*p = p2;
1477 
1478 	if (*endptr != '\0' || *value == '\0')
1479 		return 0;
1480 
1481 	return 1;
1482 }
1483 
getintval2(TCHAR ** p,int * result,int delim)1484 static int getintval2 (TCHAR **p, int *result, int delim)
1485 {
1486 	TCHAR *value = *p;
1487 	int base = 10;
1488 	TCHAR *endptr;
1489 	TCHAR *p2 = _tcschr (*p, delim);
1490 
1491 	if (p2 == 0) {
1492 		p2 = _tcschr (*p, 0);
1493 		if (p2 == 0) {
1494 			*p = 0;
1495 			return 0;
1496 		}
1497 	}
1498 	if (*p2 != 0)
1499 		*p2++ = '\0';
1500 
1501 	if (value[0] == '0' && _totupper (value[1]) == 'X')
1502 		value += 2, base = 16;
1503 	*result = _tcstol (value, &endptr, base);
1504 	*p = p2;
1505 
1506 	if (*endptr != '\0' || *value == '\0') {
1507 		*p = 0;
1508 		return 0;
1509 	}
1510 
1511 	return 1;
1512 }
1513 
set_chipset_mask(struct uae_prefs * p,int val)1514 static void set_chipset_mask (struct uae_prefs *p, int val)
1515 {
1516 	p->chipset_mask = (val == 0 ? 0
1517 		: val == 1 ? CSMASK_ECS_AGNUS
1518 		: val == 2 ? CSMASK_ECS_DENISE
1519 		: val == 3 ? CSMASK_ECS_DENISE | CSMASK_ECS_AGNUS
1520 		: CSMASK_AGA | CSMASK_ECS_DENISE | CSMASK_ECS_AGNUS);
1521 }
1522 
cfgfile_parse_host(struct uae_prefs * p,TCHAR * option,TCHAR * value)1523 static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
1524 {
1525 	int i;
1526 	bool vb;
1527 	TCHAR *section = 0;
1528 	TCHAR *tmpp;
1529 	TCHAR tmpbuf[CONFIG_BLEN];
1530 
1531 	if (_tcsncmp (option, _T("input."), 6) == 0) {
1532 		read_inputdevice_config (p, option, value);
1533 		return 1;
1534 	}
1535 
1536 	for (tmpp = option; *tmpp != '\0'; tmpp++)
1537 		if (_istupper (*tmpp))
1538 			*tmpp = _totlower (*tmpp);
1539 	tmpp = _tcschr (option, '.');
1540 	if (tmpp) {
1541 		section = option;
1542 		option = tmpp + 1;
1543 		*tmpp = '\0';
1544 		if (_tcscmp (section, TARGET_NAME) == 0) {
1545 			/* We special case the various path options here.  */
1546 			if (cfgfile_multipath (option, value, _T("rom_path"), &p->path_rom)
1547 				|| cfgfile_multipath (option, value, _T("floppy_path"), &p->path_floppy)
1548 				|| cfgfile_multipath (option, value, _T("cd_path"), &p->path_cd)
1549 				|| cfgfile_multipath (option, value, _T("hardfile_path"), &p->path_hardfile))
1550 				return 1;
1551 			return target_parse_option (p, option, value);
1552 		}
1553 	if (strcmp (section, MACHDEP_NAME) == 0)
1554 	    return machdep_parse_option (p, option, value);
1555 	if (strcmp (section, GFX_NAME) == 0)
1556 	    return gfx_parse_option (p, option, value);
1557 	if (strcmp (section, AUDIO_NAME) == 0)
1558 	    return audio_parse_option (p, option, value);
1559 
1560 		return 0;
1561 	}
1562 	for (i = 0; i < MAX_SPARE_DRIVES; i++) {
1563 		_stprintf (tmpbuf, _T("diskimage%d"), i);
1564 		if (cfgfile_path_mp (option, value, tmpbuf, p->dfxlist[i], sizeof p->dfxlist[i] / sizeof (TCHAR), &p->path_floppy)) {
1565 #if 0
1566 			if (i < 4 && !p->df[i][0])
1567 				_tcscpy (p->df[i], p->dfxlist[i]);
1568 #endif
1569 			return 1;
1570 		}
1571 	}
1572 
1573 	for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
1574 		TCHAR tmp[20];
1575 		_stprintf (tmp, _T("cdimage%d"), i);
1576 		if (!_tcsicmp (option, tmp)) {
1577 			if (!_tcsicmp (value, _T("autodetect"))) {
1578 				p->cdslots[i].type = SCSI_UNIT_DEFAULT;
1579 				p->cdslots[i].inuse = true;
1580 				p->cdslots[i].name[0] = 0;
1581 			} else {
1582 			p->cdslots[i].delayed = false;
1583 			TCHAR *next = _tcsrchr (value, ',');
1584 			int type = SCSI_UNIT_DEFAULT;
1585 			int mode = 0;
1586 			int unitnum = 0;
1587 			for (;;) {
1588 				if (!next)
1589 					break;
1590 				*next++ = 0;
1591 				TCHAR *next2 = _tcschr (next, ':');
1592 				if (next2)
1593 					*next2++ = 0;
1594 				int tmpval = 0;
1595 					if (!_tcsicmp (next, _T("delay"))) {
1596 					p->cdslots[i].delayed = true;
1597 					next = next2;
1598 					if (!next)
1599 						break;
1600 					next2 = _tcschr (next, ':');
1601 					if (next2)
1602 						*next2++ = 0;
1603 				}
1604 				type = match_string (cdmodes, next);
1605 				if (type < 0)
1606 					type = SCSI_UNIT_DEFAULT;
1607 				else
1608 					type--;
1609 				next = next2;
1610 				if (!next)
1611 					break;
1612 				next2 = _tcschr (next, ':');
1613 				if (next2)
1614 					*next2++ = 0;
1615 				mode = match_string (cdconmodes, next);
1616 				if (mode < 0)
1617 					mode = 0;
1618 				next = next2;
1619 				if (!next)
1620 					break;
1621 				next2 = _tcschr (next, ':');
1622 				if (next2)
1623 					*next2++ = 0;
1624 				cfgfile_intval (option, next, tmp, &unitnum, 1);
1625 			}
1626 			if (_tcslen (value) > 0) {
1627 				TCHAR *s = cfgfile_get_multipath (&p->path_cd, NULL, value, false);
1628 				_tcsncpy (p->cdslots[i].name, s, sizeof p->cdslots[i].name / sizeof (TCHAR));
1629 				xfree (s);
1630 			}
1631 			p->cdslots[i].name[sizeof p->cdslots[i].name - 1] = 0;
1632 			p->cdslots[i].inuse = true;
1633 			p->cdslots[i].type = type;
1634 			}
1635 			// disable all following units
1636 			i++;
1637 			while (i < MAX_TOTAL_SCSI_DEVICES) {
1638 				p->cdslots[i].type = SCSI_UNIT_DISABLED;
1639 				i++;
1640 			}
1641 			return 1;
1642 		}
1643 	}
1644 
1645 	if (cfgfile_strval (option, value, _T("gfx_autoresolution_min_vertical"), &p->gfx_autoresolution_minv, vertmode, 0)) {
1646 		p->gfx_autoresolution_minv--;
1647 		return 1;
1648 	}
1649 	if (cfgfile_strval (option, value, _T("gfx_autoresolution_min_horizontal"), &p->gfx_autoresolution_minh, horizmode, 0)) {
1650 		p->gfx_autoresolution_minh--;
1651 		return 1;
1652 	}
1653 
1654 	if (cfgfile_intval (option, value, _T("sound_frequency"), &p->sound_freq, 1)
1655 		|| cfgfile_intval (option, value, _T("sound_max_buff"), &p->sound_maxbsiz, 1)
1656 		|| cfgfile_intval (option, value, _T("state_replay_rate"), &p->statecapturerate, 1)
1657 		|| cfgfile_intval (option, value, _T("state_replay_buffers"), &p->statecapturebuffersize, 1)
1658 		|| cfgfile_yesno (option, value, _T("state_replay_autoplay"), &p->inprec_autoplay)
1659 		|| cfgfile_intval (option, value, _T("sound_frequency"), &p->sound_freq, 1)
1660 		|| cfgfile_intval (option, value, _T("sound_volume"), &p->sound_volume, 1)
1661 		|| cfgfile_intval (option, value, _T("sound_volume_cd"), &p->sound_volume_cd, 1)
1662 		|| cfgfile_intval (option, value, _T("sound_stereo_separation"), &p->sound_stereo_separation, 1)
1663 		|| cfgfile_intval (option, value, _T("sound_stereo_mixing_delay"), &p->sound_mixed_stereo_delay, 1)
1664 		|| cfgfile_intval (option, value, _T("sampler_frequency"), &p->sampler_freq, 1)
1665 		|| cfgfile_intval (option, value, _T("sampler_buffer"), &p->sampler_buffer, 1)
1666 
1667 		|| cfgfile_intval (option, value, _T("gfx_framerate"), &p->gfx_framerate, 1)
1668 		|| cfgfile_intval (option, value, _T("gfx_top_windowed"), &p->gfx_size_win.x, 1)
1669 		|| cfgfile_intval (option, value, _T("gfx_left_windowed"), &p->gfx_size_win.y, 1)
1670 		|| cfgfile_intval (option, value, _T("gfx_refreshrate"), &p->gfx_apmode[APMODE_NATIVE].gfx_refreshrate, 1)
1671 		|| cfgfile_intval (option, value, _T("gfx_refreshrate_rtg"), &p->gfx_apmode[APMODE_RTG].gfx_refreshrate, 1)
1672 		|| cfgfile_yesno (option, value, _T("gfx_autoresolution"), &p->gfx_autoresolution)
1673 		|| cfgfile_intval (option, value, _T("gfx_autoresolution_delay"), &p->gfx_autoresolution_delay, 1)
1674 		|| cfgfile_intval (option, value, _T("gfx_backbuffers"), &p->gfx_apmode[APMODE_NATIVE].gfx_backbuffers, 1)
1675 		|| cfgfile_intval (option, value, _T("gfx_backbuffers_rtg"), &p->gfx_apmode[APMODE_RTG].gfx_backbuffers, 1)
1676 		|| cfgfile_yesno (option, value, _T("gfx_interlace"), &p->gfx_apmode[APMODE_NATIVE].gfx_interlaced)
1677 		|| cfgfile_yesno (option, value, _T("gfx_interlace_rtg"), &p->gfx_apmode[APMODE_RTG].gfx_interlaced)
1678 
1679 		|| cfgfile_intval (option, value, _T("gfx_center_horizontal_position"), &p->gfx_xcenter_pos, 1)
1680 		|| cfgfile_intval (option, value, _T("gfx_center_vertical_position"), &p->gfx_ycenter_pos, 1)
1681 		|| cfgfile_intval (option, value, _T("gfx_center_horizontal_size"), &p->gfx_xcenter_size, 1)
1682 		|| cfgfile_intval (option, value, _T("gfx_center_vertical_size"), &p->gfx_ycenter_size, 1)
1683 
1684 #ifdef GFXFILTER
1685 		|| cfgfile_floatval (option, value, _T("gfx_filter_vert_zoomf"), &p->gfx_filter_vert_zoom)
1686 		|| cfgfile_floatval (option, value, _T("gfx_filter_horiz_zoomf"), &p->gfx_filter_horiz_zoom)
1687 		|| cfgfile_floatval (option, value, _T("gfx_filter_vert_zoom_multf"), &p->gfx_filter_vert_zoom_mult)
1688 		|| cfgfile_floatval (option, value, _T("gfx_filter_horiz_zoom_multf"), &p->gfx_filter_horiz_zoom_mult)
1689 		|| cfgfile_floatval (option, value, _T("gfx_filter_vert_offsetf"), &p->gfx_filter_vert_offset)
1690 		|| cfgfile_floatval (option, value, _T("gfx_filter_horiz_offsetf"), &p->gfx_filter_horiz_offset)
1691 		|| cfgfile_intval (option, value, _T("gfx_filter_scanlines"), &p->gfx_filter_scanlines, 1)
1692 		|| cfgfile_intval (option, value, _T("gfx_filter_scanlinelevel"), &p->gfx_filter_scanlinelevel, 1)
1693 		|| cfgfile_intval (option, value, _T("gfx_filter_scanlineratio"), &p->gfx_filter_scanlineratio, 1)
1694 		|| cfgfile_intval (option, value, _T("gfx_filter_luminance"), &p->gfx_filter_luminance, 1)
1695 		|| cfgfile_intval (option, value, _T("gfx_filter_contrast"), &p->gfx_filter_contrast, 1)
1696 		|| cfgfile_intval (option, value, _T("gfx_filter_saturation"), &p->gfx_filter_saturation, 1)
1697 		|| cfgfile_intval (option, value, _T("gfx_filter_gamma"), &p->gfx_filter_gamma, 1)
1698 		|| cfgfile_intval (option, value, _T("gfx_filter_blur"), &p->gfx_filter_blur, 1)
1699 		|| cfgfile_intval (option, value, _T("gfx_filter_noise"), &p->gfx_filter_noise, 1)
1700 		|| cfgfile_intval (option, value, _T("gfx_filter_bilinear"), &p->gfx_filter_bilinear, 1)
1701 		|| cfgfile_intval (option, value, _T("gfx_luminance"), &p->gfx_luminance, 1)
1702 		|| cfgfile_intval (option, value, _T("gfx_contrast"), &p->gfx_contrast, 1)
1703 		|| cfgfile_intval (option, value, _T("gfx_gamma"), &p->gfx_gamma, 1)
1704 		|| cfgfile_intval (option, value, _T("gfx_filter_keep_autoscale_aspect"), &p->gfx_filter_keep_autoscale_aspect, 1)
1705 		|| cfgfile_intval (option, value, _T("gfx_horizontal_tweak"), &p->gfx_extrawidth, 1)
1706 		|| cfgfile_string (option, value, _T("gfx_filter_mask"), p->gfx_filtermask[2 * MAX_FILTERSHADERS - 1], sizeof p->gfx_filtermask[2 * MAX_FILTERSHADERS - 1] / sizeof (TCHAR))
1707 		|| cfgfile_intval (option, value, _T("filesys_max_size"), &p->filesys_limit, 1)
1708 
1709 		|| cfgfile_floatval (option, value, _T("rtg_vert_zoom_multf"), &p->rtg_vert_zoom_mult)
1710 		|| cfgfile_floatval (option, value, _T("rtg_horiz_zoom_multf"), &p->rtg_horiz_zoom_mult)
1711 #endif
1712 #ifdef DRIVESOUND
1713 		|| cfgfile_intval (option, value, _T("floppy0sound"), &p->floppyslots[0].dfxclick, 1)
1714 		|| cfgfile_intval (option, value, _T("floppy1sound"), &p->floppyslots[1].dfxclick, 1)
1715 		|| cfgfile_intval (option, value, _T("floppy2sound"), &p->floppyslots[2].dfxclick, 1)
1716 		|| cfgfile_intval (option, value, _T("floppy3sound"), &p->floppyslots[3].dfxclick, 1)
1717 		|| cfgfile_intval (option, value, _T("floppy_channel_mask"), &p->dfxclickchannelmask, 1)
1718 		|| cfgfile_intval (option, value, _T("floppy_volume"), &p->dfxclickvolume, 1)
1719 #endif
1720 		)
1721 		return 1;
1722 
1723 	if (
1724 #ifdef DRIVESOUND
1725 cfgfile_path (option, value, _T("floppy0soundext"), p->floppyslots[0].dfxclickexternal, sizeof p->floppyslots[0].dfxclickexternal / sizeof (TCHAR))
1726 		|| cfgfile_path (option, value, _T("floppy1soundext"), p->floppyslots[1].dfxclickexternal, sizeof p->floppyslots[1].dfxclickexternal / sizeof (TCHAR))
1727 		|| cfgfile_path (option, value, _T("floppy2soundext"), p->floppyslots[2].dfxclickexternal, sizeof p->floppyslots[2].dfxclickexternal / sizeof (TCHAR))
1728 		|| cfgfile_path (option, value, _T("floppy3soundext"), p->floppyslots[3].dfxclickexternal, sizeof p->floppyslots[3].dfxclickexternal / sizeof (TCHAR))
1729 		||
1730 #endif
1731 		   cfgfile_string (option, value, _T("config_window_title"), p->config_window_title, sizeof p->config_window_title / sizeof (TCHAR))
1732 		|| cfgfile_string (option, value, _T("config_info"), p->info, sizeof p->info / sizeof (TCHAR))
1733 		|| cfgfile_string (option, value, _T("config_description"), p->description, sizeof p->description / sizeof (TCHAR)))
1734 		return 1;
1735 
1736 	if (cfgfile_yesno (option, value, _T("use_debugger"), &p->start_debugger)
1737 		|| cfgfile_yesno (option, value, _T("floppy0wp"), &p->floppyslots[0].forcedwriteprotect)
1738 		|| cfgfile_yesno (option, value, _T("floppy1wp"), &p->floppyslots[1].forcedwriteprotect)
1739 		|| cfgfile_yesno (option, value, _T("floppy2wp"), &p->floppyslots[2].forcedwriteprotect)
1740 		|| cfgfile_yesno (option, value, _T("floppy3wp"), &p->floppyslots[3].forcedwriteprotect)
1741 		|| cfgfile_yesno (option, value, _T("sampler_stereo"), &p->sampler_stereo)
1742 		|| cfgfile_yesno (option, value, _T("sound_auto"), &p->sound_auto)
1743 		|| cfgfile_yesno (option, value, _T("sound_stereo_swap_paula"), &p->sound_stereo_swap_paula)
1744 		|| cfgfile_yesno (option, value, _T("sound_stereo_swap_ahi"), &p->sound_stereo_swap_ahi)
1745 		|| cfgfile_yesno (option, value, _T("avoid_cmov"), &p->avoid_cmov)
1746 		|| cfgfile_yesno (option, value, _T("log_illegal_mem"), &p->illegal_mem)
1747 		|| cfgfile_yesno (option, value, _T("filesys_no_fsdb"), &p->filesys_no_uaefsdb)
1748 		|| cfgfile_yesno (option, value, _T("gfx_blacker_than_black"), &p->gfx_blackerthanblack)
1749 		|| cfgfile_yesno (option, value, _T("gfx_black_frame_insertion"), &p->lightboost_strobo)
1750 		|| cfgfile_yesno (option, value, _T("gfx_flickerfixer"), &p->gfx_scandoubler)
1751 		|| cfgfile_yesno (option, value, _T("magic_mouse"), &p->input_magic_mouse)
1752 		|| cfgfile_yesno (option, value, _T("warp"), &p->turbo_emulation)
1753 		|| cfgfile_yesno (option, value, _T("headless"), &p->headless)
1754 		|| cfgfile_yesno (option, value, _T("clipboard_sharing"), &p->clipboard_sharing)
1755 		|| cfgfile_yesno (option, value, _T("native_code"), &p->native_code)
1756 		|| cfgfile_yesno (option, value, _T("bsdsocket_emu"), &p->socket_emu))
1757 		return 1;
1758 
1759 	if (cfgfile_strval (option, value, _T("sound_output"), &p->produce_sound, soundmode1, 1)
1760 		|| cfgfile_strval (option, value, _T("sound_output"), &p->produce_sound, soundmode2, 0)
1761 		|| cfgfile_strval (option, value, _T("sound_interpol"), &p->sound_interpol, interpolmode, 0)
1762 		|| cfgfile_strval (option, value, _T("sound_filter"), &p->sound_filter, soundfiltermode1, 0)
1763 		|| cfgfile_strval (option, value, _T("sound_filter_type"), &p->sound_filter_type, soundfiltermode2, 0)
1764 		|| cfgfile_strboolval (option, value, _T("use_gui"), &p->start_gui, guimode1, 1)
1765 		|| cfgfile_strboolval (option, value, _T("use_gui"), &p->start_gui, guimode2, 1)
1766 		|| cfgfile_strboolval (option, value, _T("use_gui"), &p->start_gui, guimode3, 0)
1767 		|| cfgfile_strval (option, value, _T("gfx_resolution"), &p->gfx_resolution, lorestype1, 0)
1768 		|| cfgfile_strval (option, value, _T("gfx_lores"), &p->gfx_resolution, lorestype2, 0)
1769 		|| cfgfile_strval (option, value, _T("gfx_lores_mode"), &p->gfx_lores_mode, loresmode, 0)
1770 		|| cfgfile_strval (option, value, _T("gfx_fullscreen_amiga"), &p->gfx_apmode[APMODE_NATIVE].gfx_fullscreen, fullmodes, 0)
1771 		|| cfgfile_strval (option, value, _T("gfx_fullscreen_picasso"), &p->gfx_apmode[APMODE_RTG].gfx_fullscreen, fullmodes, 0)
1772 		|| cfgfile_strval (option, value, _T("gfx_center_horizontal"), &p->gfx_xcenter, centermode1, 1)
1773 		|| cfgfile_strval (option, value, _T("gfx_center_vertical"), &p->gfx_ycenter, centermode1, 1)
1774 		|| cfgfile_strval (option, value, _T("gfx_center_horizontal"), &p->gfx_xcenter, centermode2, 0)
1775 		|| cfgfile_strval (option, value, _T("gfx_center_vertical"), &p->gfx_ycenter, centermode2, 0)
1776 		|| cfgfile_strval (option, value, _T("gfx_colour_mode"), &p->color_mode, colormode1, 1)
1777 		|| cfgfile_strval (option, value, _T("gfx_colour_mode"), &p->color_mode, colormode2, 0)
1778 		|| cfgfile_strval (option, value, _T("gfx_color_mode"), &p->color_mode, colormode1, 1)
1779 		|| cfgfile_strval (option, value, _T("gfx_color_mode"), &p->color_mode, colormode2, 0)
1780 		|| cfgfile_strval (option, value, _T("gfx_max_horizontal"), &p->gfx_max_horizontal, maxhoriz, 0)
1781 		|| cfgfile_strval (option, value, _T("gfx_max_vertical"), &p->gfx_max_vertical, maxvert, 0)
1782 		|| cfgfile_strval (option, value, _T("gfx_filter_autoscale"), &p->gfx_filter_autoscale, autoscale, 0)
1783 		|| cfgfile_strval (option, value, _T("gfx_api"), &p->gfx_api, filterapi, 0)
1784 		|| cfgfile_strval (option, value, _T("magic_mousecursor"), &p->input_magic_mouse_cursor, magiccursors, 0)
1785 		|| cfgfile_strval (option, value, _T("gfx_filter_keep_aspect"), &p->gfx_filter_keep_aspect, aspects, 0)
1786 		|| cfgfile_strval (option, value, _T("absolute_mouse"), &p->input_tablet, abspointers, 0))
1787 		return 1;
1788 
1789 	if (_tcscmp (option, _T("gfx_width_windowed")) == 0) {
1790 		if (!_tcscmp (value, _T("native"))) {
1791 			p->gfx_size_win.width = 0;
1792 			p->gfx_size_win.height = 0;
1793 		} else {
1794 			cfgfile_intval (option, value, _T("gfx_width_windowed"), &p->gfx_size_win.width, 1);
1795 		}
1796 		return 1;
1797 	}
1798 	if (_tcscmp (option, _T("gfx_height_windowed")) == 0) {
1799 		if (!_tcscmp (value, _T("native"))) {
1800 			p->gfx_size_win.width = 0;
1801 			p->gfx_size_win.height = 0;
1802 		} else {
1803 			cfgfile_intval (option, value, _T("gfx_height_windowed"), &p->gfx_size_win.height, 1);
1804 		}
1805 		return 1;
1806 	}
1807 	if (_tcscmp (option, _T("gfx_width_fullscreen")) == 0) {
1808 		if (!_tcscmp (value, _T("native"))) {
1809 			p->gfx_size_fs.width = 0;
1810 			p->gfx_size_fs.height = 0;
1811 			p->gfx_size_fs.special = WH_NATIVE;
1812 		} else {
1813 			cfgfile_intval (option, value, _T("gfx_width_fullscreen"), &p->gfx_size_fs.width, 1);
1814 			p->gfx_size_fs.special = 0;
1815 		}
1816 		return 1;
1817 	}
1818 	if (_tcscmp (option, _T("gfx_height_fullscreen")) == 0) {
1819 		if (!_tcscmp (value, _T("native"))) {
1820 			p->gfx_size_fs.width = 0;
1821 			p->gfx_size_fs.height = 0;
1822 			p->gfx_size_fs.special = WH_NATIVE;
1823 		} else {
1824 			cfgfile_intval (option, value, _T("gfx_height_fullscreen"), &p->gfx_size_fs.height, 1);
1825 			p->gfx_size_fs.special = 0;
1826 		}
1827 		return 1;
1828 	}
1829 
1830 	if (cfgfile_intval (option, value, _T("gfx_display"), &p->gfx_apmode[APMODE_NATIVE].gfx_display, 1)) {
1831 		p->gfx_apmode[APMODE_RTG].gfx_display = p->gfx_apmode[APMODE_NATIVE].gfx_display;
1832 		return 1;
1833 	}
1834 	if (cfgfile_intval (option, value, _T("gfx_display_rtg"), &p->gfx_apmode[APMODE_RTG].gfx_display, 1)) {
1835 		return 1;
1836 	}
1837 	if (_tcscmp (option, _T("gfx_display_friendlyname")) == 0 || _tcscmp (option, _T("gfx_display_name")) == 0) {
1838 		TCHAR tmp[MAX_DPATH];
1839 		if (cfgfile_string (option, value, _T("gfx_display_friendlyname"), tmp, sizeof tmp / sizeof (TCHAR))) {
1840 			int num = target_get_display (tmp);
1841 			if (num >= 0)
1842 				p->gfx_apmode[APMODE_RTG].gfx_display = p->gfx_apmode[APMODE_NATIVE].gfx_display = num;
1843 		}
1844 		if (cfgfile_string (option, value, _T("gfx_display_name"), tmp, sizeof tmp / sizeof (TCHAR))) {
1845 			int num = target_get_display (tmp);
1846 			if (num >= 0)
1847 				p->gfx_apmode[APMODE_RTG].gfx_display = p->gfx_apmode[APMODE_NATIVE].gfx_display = num;
1848 		}
1849 		return 1;
1850 	}
1851 	if (_tcscmp (option, _T("gfx_display_friendlyname_rtg")) == 0 || _tcscmp (option, _T("gfx_display_name_rtg")) == 0) {
1852 		TCHAR tmp[MAX_DPATH];
1853 		if (cfgfile_string (option, value, _T("gfx_display_friendlyname_rtg"), tmp, sizeof tmp / sizeof (TCHAR))) {
1854 			int num = target_get_display (tmp);
1855 			if (num >= 0)
1856 				p->gfx_apmode[APMODE_RTG].gfx_display = num;
1857 		}
1858 		if (cfgfile_string (option, value, _T("gfx_display_name_rtg"), tmp, sizeof tmp / sizeof (TCHAR))) {
1859 			int num = target_get_display (tmp);
1860 			if (num >= 0)
1861 				p->gfx_apmode[APMODE_RTG].gfx_display = num;
1862 		}
1863 		return 1;
1864 	}
1865 
1866 	if (_tcscmp (option, _T("gfx_linemode")) == 0) {
1867 		int v;
1868 		p->gfx_vresolution = VRES_DOUBLE;
1869 		p->gfx_scanlines = false;
1870 		if (cfgfile_strval (option, value, _T("gfx_linemode"), &v, linemode, 0)) {
1871 			p->gfx_scanlines = v & 1;
1872 			p->gfx_vresolution = v / 2;
1873 		}
1874 		return 1;
1875 	}
1876 	if (_tcscmp (option, _T("gfx_vsync")) == 0) {
1877 		if (cfgfile_strval (option, value, _T("gfx_vsync"), &p->gfx_apmode[APMODE_NATIVE].gfx_vsync, vsyncmodes, 0) >= 0)
1878 			return 1;
1879 		return cfgfile_yesno (option, value, _T("gfx_vsync"), &p->gfx_apmode[APMODE_NATIVE].gfx_vsync);
1880 	}
1881 	if (_tcscmp (option, _T("gfx_vsync_picasso")) == 0) {
1882 		if (cfgfile_strval (option, value, _T("gfx_vsync_picasso"), &p->gfx_apmode[APMODE_RTG].gfx_vsync, vsyncmodes, 0) >= 0)
1883 			return 1;
1884 		return cfgfile_yesno (option, value, _T("gfx_vsync_picasso"), &p->gfx_apmode[APMODE_RTG].gfx_vsync);
1885 	}
1886 	if (cfgfile_strval (option, value, _T("gfx_vsyncmode"), &p->gfx_apmode[APMODE_NATIVE].gfx_vsyncmode, vsyncmodes2, 0))
1887 		return 1;
1888 	if (cfgfile_strval (option, value, _T("gfx_vsyncmode_picasso"), &p->gfx_apmode[APMODE_RTG].gfx_vsyncmode, vsyncmodes2, 0))
1889 		return 1;
1890 
1891 	if (cfgfile_yesno (option, value, _T("show_leds"), &vb)) {
1892 		if (vb)
1893 			p->leds_on_screen |= STATUSLINE_CHIPSET;
1894 		else
1895 			p->leds_on_screen &= ~STATUSLINE_CHIPSET;
1896 		return 1;
1897 	}
1898 	if (cfgfile_yesno (option, value, _T("show_leds_rtg"), &vb)) {
1899 		if (vb)
1900 			p->leds_on_screen |= STATUSLINE_RTG;
1901 		else
1902 			p->leds_on_screen &= ~STATUSLINE_RTG;
1903 		return 1;
1904 	}
1905 	if (_tcscmp (option, _T("show_leds_enabled")) == 0 || _tcscmp (option, _T("show_leds_enabled_rtg")) == 0) {
1906 		TCHAR tmp[MAX_DPATH];
1907 		int idx = _tcscmp (option, _T("show_leds_enabled")) == 0 ? 0 : 1;
1908 		p->leds_on_screen_mask[idx] = 0;
1909 		_tcscpy (tmp, value);
1910 		_tcscat (tmp, _T(","));
1911 		TCHAR *s = tmp;
1912 		for (;;) {
1913 			TCHAR *s2 = s;
1914 			TCHAR *s3 = _tcschr (s, ':');
1915 			s = _tcschr (s, ',');
1916 			if (!s)
1917 				break;
1918 			if (s3 && s3 < s)
1919 				s = s3;
1920 			*s = 0;
1921 			for (int i = 0; leds[i]; i++) {
1922 				if (!_tcsicmp (s2, leds[i])) {
1923 					p->leds_on_screen_mask[idx] |= 1 << i;
1924 				}
1925 			}
1926 			s++;
1927 		}
1928 		return 1;
1929 	}
1930 
1931 	if (!_tcscmp (option, _T("osd_position"))) {
1932 		TCHAR *s = value;
1933 		p->osd_pos.x = 0;
1934 		p->osd_pos.y = 0;
1935 		while (s) {
1936 			if (!_tcschr (s, ':'))
1937 				break;
1938 			p->osd_pos.x =  (int)(_tstof (s) * 10.0);
1939 			s = _tcschr (s, ':');
1940 			if (!s)
1941 				break;
1942 			if (s[-1] == '%')
1943 				p->osd_pos.x += 30000;
1944 			s++;
1945 			p->osd_pos.y = (int)(_tstof (s) * 10.0);
1946 			s += _tcslen (s);
1947 			if (s[-1] == '%')
1948 				p->osd_pos.y += 30000;
1949 			break;
1950 		}
1951 		return 1;
1952 	}
1953 
1954 #ifdef GFXFILTER
1955 	if (_tcscmp (option, _T("gfx_filter_overlay")) == 0) {
1956 		TCHAR *s = _tcschr (value, ',');
1957 		p->gfx_filteroverlay_overscan = 0;
1958 		p->gfx_filteroverlay_pos.x = 0;
1959 		p->gfx_filteroverlay_pos.y = 0;
1960 		p->gfx_filteroverlay_pos.width = 0;
1961 		p->gfx_filteroverlay_pos.height = 0;
1962 		if (s)
1963 			*s = 0;
1964 		while (s) {
1965 			*s++ = 0;
1966 			p->gfx_filteroverlay_overscan = _tstol (s);
1967 			s = _tcschr (s, ':');
1968 			if (!s)
1969 				break;
1970 #if 0
1971 			p->gfx_filteroverlay_pos.x = _tstol (s);
1972 			s = _tcschr (s, ',');
1973 			if (!s)
1974 				break;
1975 			if (s[-1] == '%')
1976 				p->gfx_filteroverlay_pos.x = -30000 - p->gfx_filteroverlay_pos.x;
1977 			*s++ = 0;
1978 			p->gfx_filteroverlay_pos.y = _tstol (s);
1979 			s = _tcschr (s, ',');
1980 			if (!s)
1981 				break;
1982 			if (s[-1] == '%')
1983 				p->gfx_filteroverlay_pos.y = -30000 - p->gfx_filteroverlay_pos.y;
1984 			*s++ = 0;
1985 			p->gfx_filteroverlay_pos.width = _tstol (s);
1986 			s = _tcschr (s, ',');
1987 			if (!s)
1988 				break;
1989 			if (s[-1] == '%')
1990 				p->gfx_filteroverlay_pos.width = -30000 - p->gfx_filteroverlay_pos.width;
1991 			*s++ = 0;
1992 			p->gfx_filteroverlay_pos.height = _tstol (s);
1993 			s = _tcschr (s, ',');
1994 			if (!s)
1995 				break;
1996 			if (s[-1] == '%')
1997 				p->gfx_filteroverlay_pos.height = -30000 - p->gfx_filteroverlay_pos.height;
1998 			*s++ = 0;
1999 			p->gfx_filteroverlay_overscan = _tstol (s);
2000 			TCHAR *s2 = _tcschr (s, ',');
2001 			if (s2)
2002 				*s2 = 0;
2003 #endif
2004 			break;
2005 		}
2006 		_tcsncpy (p->gfx_filteroverlay, value, sizeof p->gfx_filteroverlay / sizeof (TCHAR) - 1);
2007 		p->gfx_filteroverlay[sizeof p->gfx_filteroverlay / sizeof (TCHAR) - 1] = 0;
2008 		return 1;
2009 	}
2010 
2011 	if (_tcscmp (option, _T("gfx_filtermask_pre")) == 0 || _tcscmp (option, _T("gfx_filtermask_post")) == 0) {
2012 		if (_tcscmp (option, _T("gfx_filtermask_pre")) == 0) {
2013 			for (int i = 0; i < MAX_FILTERSHADERS; i++) {
2014 				if (p->gfx_filtermask[i][0] == 0) {
2015 					_tcscpy (p->gfx_filtermask[i], value);
2016 					break;
2017 				}
2018 			}
2019 		} else {
2020 			for (int i = 0; i < MAX_FILTERSHADERS; i++) {
2021 				if (p->gfx_filtermask[i + MAX_FILTERSHADERS][0] == 0) {
2022 					_tcscpy (p->gfx_filtermask[i + MAX_FILTERSHADERS], value);
2023 					break;
2024 				}
2025 			}
2026 		}
2027 		return 1;
2028 	}
2029 
2030 	if (_tcscmp (option, _T("gfx_filter_pre")) == 0 || _tcscmp (option, _T("gfx_filter_post")) == 0) {
2031 		TCHAR *s = _tcschr (value, ':');
2032 		if (s) {
2033 			*s++ = 0;
2034 			if (!_tcscmp (value, _T("D3D"))) {
2035 				p->gfx_api = 1;
2036 				if (_tcscmp (option, _T("gfx_filter_pre")) == 0) {
2037 					for (int i = 0; i < MAX_FILTERSHADERS; i++) {
2038 						if (p->gfx_filtershader[i][0] == 0) {
2039 							_tcscpy (p->gfx_filtershader[i], s);
2040 							break;
2041 						}
2042 					}
2043 				} else {
2044 					for (int i = 0; i < MAX_FILTERSHADERS; i++) {
2045 						if (p->gfx_filtershader[i + MAX_FILTERSHADERS][0] == 0) {
2046 							_tcscpy (p->gfx_filtershader[i + MAX_FILTERSHADERS], s);
2047 							break;
2048 						}
2049 					}
2050 				}
2051 			}
2052 		}
2053 		return 1;
2054 	}
2055 
2056 	if (_tcscmp (option, _T("gfx_filter")) == 0) {
2057 		TCHAR *s = _tcschr (value, ':');
2058 		p->gfx_filter = 0;
2059 		if (s) {
2060 			*s++ = 0;
2061 			if (!_tcscmp (value, _T("D3D"))) {
2062 				p->gfx_api = 1;
2063 				_tcscpy (p->gfx_filtershader[2 * MAX_FILTERSHADERS], s);
2064 				for (int i = 0; i < 2 * MAX_FILTERSHADERS; i++) {
2065 					if (!_tcsicmp (p->gfx_filtershader[i], s)) {
2066 						p->gfx_filtershader[i][0] = 0;
2067 						p->gfx_filtermask[i][0] = 0;
2068 					}
2069 				}
2070 			}
2071 		}
2072 		if (!_tcscmp (value, _T("direct3d"))) {
2073 			p->gfx_api = 1; // forwards compatibiity
2074 		} else {
2075 			int i = 0;
2076 			while(uaefilters[i].name) {
2077 				if (!_tcscmp (uaefilters[i].cfgname, value)) {
2078 					p->gfx_filter = uaefilters[i].type;
2079 					break;
2080 				}
2081 				i++;
2082 			}
2083 		}
2084 		return 1;
2085 	}
2086 	if (_tcscmp (option, _T("gfx_filter_mode")) == 0) {
2087 		cfgfile_strval (option, value, _T("gfx_filter_mode"), &p->gfx_filter_filtermode, filtermode2, 0);
2088 		return 1;
2089 	}
2090 
2091 	if (cfgfile_string (option, value, _T("gfx_filter_aspect_ratio"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
2092 		int v1, v2;
2093 		TCHAR *s;
2094 
2095 		p->gfx_filter_aspect = -1;
2096 		v1 = _tstol (tmpbuf);
2097 		s = _tcschr (tmpbuf, ':');
2098 		if (s) {
2099 			v2 = _tstol (s + 1);
2100 			if (v1 < 0 || v2 < 0)
2101 				p->gfx_filter_aspect = -1;
2102 			else if (v1 == 0 || v2 == 0)
2103 				p->gfx_filter_aspect = 0;
2104 			else
2105 				p->gfx_filter_aspect = v1 * ASPECTMULT + v2;
2106 		}
2107 		return 1;
2108 	}
2109 #endif
2110 
2111 	if (_tcscmp (option, _T("gfx_width")) == 0 || _tcscmp (option, _T("gfx_height")) == 0) {
2112 		cfgfile_intval (option, value, _T("gfx_width"), &p->gfx_size_win.width, 1);
2113 		cfgfile_intval (option, value, _T("gfx_height"), &p->gfx_size_win.height, 1);
2114 		p->gfx_size_fs.width = p->gfx_size_win.width;
2115 		p->gfx_size_fs.height = p->gfx_size_win.height;
2116 		return 1;
2117 	}
2118 
2119 	if (_tcscmp (option, _T("gfx_fullscreen_multi")) == 0 || _tcscmp (option, _T("gfx_windowed_multi")) == 0) {
2120 		TCHAR tmp[256], *tmpp, *tmpp2;
2121 		struct wh *wh = p->gfx_size_win_xtra;
2122 		if (_tcscmp (option, _T("gfx_fullscreen_multi")) == 0)
2123 			wh = p->gfx_size_fs_xtra;
2124 		_stprintf (tmp, _T(",%s,"), value);
2125 		tmpp2 = tmp;
2126 		for (i = 0; i < 4; i++) {
2127 			tmpp = _tcschr (tmpp2, ',');
2128 			tmpp++;
2129 			wh[i].width = _tstol (tmpp);
2130 			while (*tmpp != ',' && *tmpp != 'x' && *tmpp != '*')
2131 				tmpp++;
2132 			wh[i].height = _tstol (tmpp + 1);
2133 			tmpp2 = tmpp;
2134 		}
2135 		return 1;
2136 	}
2137 
2138 	if (_tcscmp (option, _T("joyportfriendlyname0")) == 0 || _tcscmp (option, _T("joyportfriendlyname1")) == 0) {
2139 		inputdevice_joyport_config (p, value, _tcscmp (option, _T("joyportfriendlyname0")) == 0 ? 0 : 1, -1, 2);
2140 		return 1;
2141 	}
2142 	if (_tcscmp (option, _T("joyportfriendlyname2")) == 0 || _tcscmp (option, _T("joyportfriendlyname3")) == 0) {
2143 		inputdevice_joyport_config (p, value, _tcscmp (option, _T("joyportfriendlyname2")) == 0 ? 2 : 3, -1, 2);
2144 		return 1;
2145 	}
2146 	if (_tcscmp (option, _T("joyportname0")) == 0 || _tcscmp (option, _T("joyportname1")) == 0) {
2147 		inputdevice_joyport_config (p, value, _tcscmp (option, _T("joyportname0")) == 0 ? 0 : 1, -1, 1);
2148 		return 1;
2149 	}
2150 	if (_tcscmp (option, _T("joyportname2")) == 0 || _tcscmp (option, _T("joyportname3")) == 0) {
2151 		inputdevice_joyport_config (p, value, _tcscmp (option, _T("joyportname2")) == 0 ? 2 : 3, -1, 1);
2152 		return 1;
2153 	}
2154 	if (_tcscmp (option, _T("joyport0")) == 0 || _tcscmp (option, _T("joyport1")) == 0) {
2155 		inputdevice_joyport_config (p, value, _tcscmp (option, _T("joyport0")) == 0 ? 0 : 1, -1, 0);
2156 		return 1;
2157 	}
2158 	if (_tcscmp (option, _T("joyport2")) == 0 || _tcscmp (option, _T("joyport3")) == 0) {
2159 		inputdevice_joyport_config (p, value, _tcscmp (option, _T("joyport2")) == 0 ? 2 : 3, -1, 0);
2160 		return 1;
2161 	}
2162 	if (cfgfile_strval (option, value, _T("joyport0mode"), &p->jports[0].mode, joyportmodes, 0))
2163 		return 1;
2164 	if (cfgfile_strval (option, value, _T("joyport1mode"), &p->jports[1].mode, joyportmodes, 0))
2165 		return 1;
2166 	if (cfgfile_strval (option, value, _T("joyport2mode"), &p->jports[2].mode, joyportmodes, 0))
2167 		return 1;
2168 	if (cfgfile_strval (option, value, _T("joyport3mode"), &p->jports[3].mode, joyportmodes, 0))
2169 		return 1;
2170 	if (cfgfile_strval (option, value, _T("joyport0autofire"), &p->jports[0].autofire, joyaf, 0))
2171 		return 1;
2172 	if (cfgfile_strval (option, value, _T("joyport1autofire"), &p->jports[1].autofire, joyaf, 0))
2173 		return 1;
2174 	if (cfgfile_strval (option, value, _T("joyport2autofire"), &p->jports[2].autofire, joyaf, 0))
2175 		return 1;
2176 	if (cfgfile_strval (option, value, _T("joyport3autofire"), &p->jports[3].autofire, joyaf, 0))
2177 		return 1;
2178 
2179 	if (cfgfile_path (option, value, _T("statefile_quit"), p->quitstatefile, sizeof p->quitstatefile / sizeof (TCHAR)))
2180 		return 1;
2181 
2182 	if (cfgfile_string (option, value, _T("statefile_name"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
2183 		fetch_statefilepath (savestate_fname, sizeof savestate_fname / sizeof (TCHAR));
2184 		_tcscat (savestate_fname, tmpbuf);
2185 		if (_tcslen (savestate_fname) >= 4 && _tcsicmp (savestate_fname + _tcslen (savestate_fname) - 4, _T(".uss")))
2186 			_tcscat (savestate_fname, _T(".uss"));
2187 		return 1;
2188 	}
2189 
2190 #ifdef SAVESTATE
2191 	if (cfgfile_path (option, value, _T("statefile"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
2192 		_tcscpy (p->statefile, tmpbuf);
2193 		_tcscpy (savestate_fname, tmpbuf);
2194 		if (zfile_exists (savestate_fname)) {
2195 			savestate_state = STATE_DORESTORE;
2196 		} else {
2197 			int ok = 0;
2198 			if (savestate_fname[0]) {
2199 				for (;;) {
2200 					TCHAR *p;
2201 					if (my_existsdir (savestate_fname)) {
2202 						ok = 1;
2203 						break;
2204 					}
2205 					p = _tcsrchr (savestate_fname, '\\');
2206 					if (!p)
2207 						p = _tcsrchr (savestate_fname, '/');
2208 					if (!p)
2209 						break;
2210 					*p = 0;
2211 				}
2212 			}
2213 			if (!ok) {
2214 				TCHAR tmp[MAX_DPATH];
2215 				//fetch_statefilepath (tmp, sizeof tmp / sizeof (TCHAR));
2216 				_tcscat (tmp, savestate_fname);
2217 				if (zfile_exists (tmp)) {
2218 					_tcscpy (savestate_fname, tmp);
2219 					savestate_state = STATE_DORESTORE;
2220 				} else {
2221 					savestate_fname[0] = 0;
2222 				}
2223 			}
2224 		}
2225 		return 1;
2226 	}
2227 #endif // SAVESTATE
2228 
2229 	if (cfgfile_strval (option, value, _T("sound_channels"), &p->sound_stereo, stereomode, 1)) {
2230 		if (p->sound_stereo == SND_NONE) { /* "mixed stereo" compatibility hack */
2231 			p->sound_stereo = SND_STEREO;
2232 			p->sound_mixed_stereo_delay = 5;
2233 			p->sound_stereo_separation = 7;
2234 		}
2235 		return 1;
2236 	}
2237 
2238 	if (_tcscmp (option, _T("kbd_lang")) == 0) {
2239 		KbdLang l;
2240 		if ((l = KBD_LANG_DE, strcasecmp (value, _T("de")) == 0)
2241 			|| (l = KBD_LANG_DK, strcasecmp (value, _T("dk")) == 0)
2242 			|| (l = KBD_LANG_SE, strcasecmp (value, _T("se")) == 0)
2243 			|| (l = KBD_LANG_US, strcasecmp (value, _T("us")) == 0)
2244 			|| (l = KBD_LANG_FR, strcasecmp (value, _T("fr")) == 0)
2245 			|| (l = KBD_LANG_IT, strcasecmp (value, _T("it")) == 0)
2246 			|| (l = KBD_LANG_ES, strcasecmp (value, _T("es")) == 0)
2247 			|| (l = KBD_LANG_FI, strcasecmp (value, _T("fi")) == 0)
2248 			|| (l = KBD_LANG_TR, strcasecmp (value, _T("tr")) == 0))
2249 			p->keyboard_lang = l;
2250 		else
2251 			write_log (_T("Unknown keyboard language\n"));
2252 		return 1;
2253 	}
2254 
2255 	if (cfgfile_string (option, value, _T("config_version"), tmpbuf, sizeof (tmpbuf) / sizeof (TCHAR))) {
2256 		TCHAR *tmpp2;
2257 		tmpp = _tcschr (value, '.');
2258 		if (tmpp) {
2259 			*tmpp++ = 0;
2260 			tmpp2 = tmpp;
2261 			p->config_version = _tstol (tmpbuf) << 16;
2262 			tmpp = _tcschr (tmpp, '.');
2263 			if (tmpp) {
2264 				*tmpp++ = 0;
2265 				p->config_version |= _tstol (tmpp2) << 8;
2266 				p->config_version |= _tstol (tmpp);
2267 			}
2268 		}
2269 		return 1;
2270 	}
2271 
2272 	if (cfgfile_string (option, value, _T("keyboard_leds"), tmpbuf, sizeof (tmpbuf) / sizeof (TCHAR))) {
2273 		TCHAR *tmpp2 = tmpbuf;
2274 		int i, num;
2275 		p->keyboard_leds[0] = p->keyboard_leds[1] = p->keyboard_leds[2] = 0;
2276 		p->keyboard_leds_in_use = 0;
2277 		_tcscat (tmpbuf, _T(","));
2278 		for (i = 0; i < 3; i++) {
2279 			tmpp = _tcschr (tmpp2, ':');
2280 			if (!tmpp)
2281 				break;
2282 			*tmpp++= 0;
2283 			num = -1;
2284 			if (!strcasecmp (tmpp2, _T("numlock")))
2285 				num = 0;
2286 			if (!strcasecmp (tmpp2, _T("capslock")))
2287 				num = 1;
2288 			if (!strcasecmp (tmpp2, _T("scrolllock")))
2289 				num = 2;
2290 			tmpp2 = tmpp;
2291 			tmpp = _tcschr (tmpp2, ',');
2292 			if (!tmpp)
2293 				break;
2294 			*tmpp++= 0;
2295 			if (num >= 0) {
2296 				p->keyboard_leds[num] = match_string (kbleds, tmpp2);
2297 				if (p->keyboard_leds[num])
2298 					p->keyboard_leds_in_use = 1;
2299 			}
2300 			tmpp2 = tmpp;
2301 		}
2302 		return 1;
2303 	}
2304 
2305 	if (_tcscmp (option, _T("displaydata")) == 0 || _tcscmp (option, _T("displaydata_pal")) == 0 || _tcscmp (option, _T("displaydata_ntsc")) == 0) {
2306 	    _tcsncpy (tmpbuf, value, sizeof tmpbuf / sizeof (TCHAR) - 1);
2307 	    tmpbuf[sizeof tmpbuf / sizeof (TCHAR) - 1] = '\0';
2308 
2309 	    int vert = -1, horiz = -1, lace = -1, ntsc = -1, framelength = -1, vsync = -1;
2310 	    bool locked = false;
2311 	    bool rtg = false;
2312 	    double rate = -1;
2313 	    TCHAR cmd[MAX_DPATH], label[16] = { 0 };
2314 	    TCHAR *tmpp = tmpbuf;
2315 	    TCHAR *end = tmpbuf + _tcslen (tmpbuf);
2316 	    cmd[0] = 0;
2317 	    for (;;) {
2318 	      TCHAR *next = _tcschr (tmpp, ',');
2319 	      TCHAR *equals = _tcschr (tmpp, '=');
2320 
2321 	      if (!next)
2322 	        next = end;
2323 	      if (equals == NULL || equals > next)
2324 	        equals = NULL;
2325 	      else
2326 	        equals++;
2327 	      *next = 0;
2328 
2329 	      if (rate < 0)
2330 	        rate = _tstof (tmpp);
2331 			else if (!_tcsnicmp (tmpp, _T("v="), 2))
2332 	        vert = _tstol (equals);
2333 			else if (!_tcsnicmp (tmpp, _T("h="), 2))
2334 	        horiz = _tstol (equals);
2335 			else if (!_tcsnicmp (tmpp, _T("t="), 2))
2336 	        _tcsncpy (label, equals, sizeof label / sizeof (TCHAR) - 1);
2337 	      else if (equals) {
2338 	        if (_tcslen (cmd) + _tcslen (tmpp) + 2 < sizeof (cmd) / sizeof(TCHAR)) {
2339 	          _tcscat (cmd, tmpp);
2340 					_tcscat (cmd, _T("\n"));
2341 	        }
2342 	      }
2343 			if (!_tcsnicmp (tmpp, _T("locked"), 4))
2344 				locked = true;
2345 			if (!_tcsnicmp (tmpp, _T("nlace"), 5))
2346 				lace = 0;
2347 			if (!_tcsnicmp (tmpp, _T("lace"), 4))
2348 				lace = 1;
2349 			if (!_tcsnicmp (tmpp, _T("nvsync"), 5))
2350 				vsync = 0;
2351 			if (!_tcsnicmp (tmpp, _T("vsync"), 4))
2352 				vsync = 1;
2353 			if (!_tcsnicmp (tmpp, _T("ntsc"), 4))
2354 				ntsc = 1;
2355 			if (!_tcsnicmp (tmpp, _T("pal"), 3))
2356 				ntsc = 0;
2357 			if (!_tcsnicmp (tmpp, _T("lof"), 3))
2358 				framelength = 1;
2359 			if (!_tcsnicmp (tmpp, _T("shf"), 3))
2360 				framelength = 0;
2361 			if (!_tcsnicmp (tmpp, _T("rtg"), 3))
2362 				rtg = true;
2363 			tmpp = next;
2364 			if (tmpp >= end)
2365 				break;
2366 			tmpp++;
2367 		}
2368 		if (rate > 0) {
2369 			for (int i = 0; i < MAX_CHIPSET_REFRESH; i++) {
2370 				if (_tcscmp (option, _T("displaydata_pal")) == 0) {
2371 	          i = CHIPSET_REFRESH_PAL;
2372 	          p->cr[i].rate = -1;
2373 					_tcscpy (label, _T("PAL"));
2374 				} else if (_tcscmp (option, _T("displaydata_ntsc")) == 0) {
2375 	          i = CHIPSET_REFRESH_NTSC;
2376 	          p->cr[i].rate = -1;
2377 					_tcscpy (label, _T("NTSC"));
2378 	        }
2379 	        if (p->cr[i].rate <= 0) {
2380 	          p->cr[i].horiz = horiz;
2381 	          p->cr[i].vert = vert;
2382 	          p->cr[i].lace = lace;
2383 	          p->cr[i].ntsc = ntsc;
2384 	          p->cr[i].vsync = vsync;
2385 	          p->cr[i].locked = locked;
2386 	          p->cr[i].rtg = rtg;
2387 	          p->cr[i].framelength = framelength;
2388 	          p->cr[i].rate = rate;
2389 	          _tcscpy (p->cr[i].commands, cmd);
2390 	          _tcscpy (p->cr[i].label, label);
2391 	          break;
2392 	        }
2393 	      }
2394 	    }
2395 	    return 1;
2396 	  }
2397 
2398 	return 0;
2399 }
2400 
decode_rom_ident(TCHAR * romfile,int maxlen,const TCHAR * ident,int romflags)2401 static void decode_rom_ident (TCHAR *romfile, int maxlen, const TCHAR *ident, int romflags)
2402 {
2403 	const TCHAR *p;
2404 	int ver, rev, subver, subrev, round, i;
2405 	TCHAR model[64], *modelp;
2406 	struct romlist **rl;
2407 	TCHAR *romtxt;
2408 
2409 	if (!ident[0])
2410 		return;
2411 	romtxt = xmalloc (TCHAR, 10000);
2412 	romtxt[0] = 0;
2413 	for (round = 0; round < 2; round++) {
2414 		ver = rev = subver = subrev = -1;
2415 		modelp = NULL;
2416 		memset (model, 0, sizeof model);
2417 		p = ident;
2418 		while (*p) {
2419 			TCHAR c = *p++;
2420 			int *pp1 = NULL, *pp2 = NULL;
2421 			if (_totupper (c) == 'V' && _istdigit (*p)) {
2422 				pp1 = &ver;
2423 				pp2 = &rev;
2424 			} else if (_totupper (c) == 'R' && _istdigit (*p)) {
2425 				pp1 = &subver;
2426 				pp2 = &subrev;
2427 			} else if (!_istdigit (c) && c != ' ') {
2428 				_tcsncpy (model, p - 1, (sizeof model) / sizeof (TCHAR) - 1);
2429 				p += _tcslen (model);
2430 				modelp = model;
2431 			}
2432 			if (pp1) {
2433 				*pp1 = _tstol (p);
2434 				while (*p != 0 && *p != '.' && *p != ' ')
2435 					p++;
2436 				if (*p == '.') {
2437 					p++;
2438 					if (pp2)
2439 						*pp2 = _tstol (p);
2440 				}
2441 			}
2442 			if (*p == 0 || *p == ';') {
2443 				rl = getromlistbyident (ver, rev, subver, subrev, modelp, romflags, round > 0);
2444 				if (rl) {
2445 					for (i = 0; rl[i]; i++) {
2446 						if (round) {
2447 							TCHAR romname[MAX_DPATH];
2448 							getromname(rl[i]->rd, romname);
2449 							_tcscat (romtxt, romname);
2450 							_tcscat (romtxt, _T("\n"));
2451 						} else {
2452 							_tcsncpy (romfile, rl[i]->path, maxlen);
2453 							goto end;
2454 						}
2455 					}
2456 					xfree (rl);
2457 				}
2458 			}
2459 		}
2460 	}
2461 end:
2462 	if (round && romtxt[0]) {
2463 		gui_message("One of the following system ROMs is required:\n\n%s\n\nCheck the System ROM path in the Paths panel and click Rescan ROMs.\n");
2464 	}
2465 	xfree (romtxt);
2466 }
2467 
getuci(struct uae_prefs * p)2468 static struct uaedev_config_data *getuci (struct uae_prefs *p)
2469 {
2470 	if (p->mountitems < MOUNT_CONFIG_SIZE)
2471 		return &p->mountconfig[p->mountitems++];
2472 	return NULL;
2473 }
2474 
add_filesys_config(struct uae_prefs * p,int index,struct uaedev_config_info * ci)2475 struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, struct uaedev_config_info *ci)
2476 {
2477 	struct uaedev_config_data *uci;
2478 	int i;
2479 
2480 	if (index < 0 && ci->devname && _tcslen (ci->devname) > 0) {
2481 		for (i = 0; i < p->mountitems; i++) {
2482 			if (p->mountconfig[i].ci.devname && !_tcscmp (p->mountconfig[i].ci.devname, ci->devname))
2483 				return 0;
2484 		}
2485 	}
2486 	if (ci->type == UAEDEV_CD) {
2487 		if (ci->controller > HD_CONTROLLER_SCSI6 || ci->controller < HD_CONTROLLER_IDE0)
2488 			return NULL;
2489 	}
2490 	if (index < 0) {
2491 		if (ci->controller != HD_CONTROLLER_UAE) {
2492 			int ctrl = ci->controller;
2493 			for (;;) {
2494 				for (i = 0; i < p->mountitems; i++) {
2495 					if (p->mountconfig[i].ci.controller == ctrl) {
2496 						ctrl++;
2497 						if (ctrl == HD_CONTROLLER_IDE3 + 1 || ctrl == HD_CONTROLLER_SCSI6 + 1)
2498 							return 0;
2499 					}
2500 				}
2501 				if (i == p->mountitems) {
2502 					ci->controller = ctrl;
2503 					break;
2504 				}
2505 			}
2506 		}
2507 		if (ci->type == UAEDEV_CD) {
2508 			for (i = 0; i < p->mountitems; i++) {
2509 				if (p->mountconfig[i].ci.type == UAEDEV_CD)
2510 					return 0;
2511 			}
2512 		}
2513 		uci = getuci(p);
2514 		uci->configoffset = -1;
2515 	} else {
2516 		uci = &p->mountconfig[index];
2517 	}
2518 	if (!uci)
2519 		return 0;
2520 
2521 	memcpy (&uci->ci, ci, sizeof (struct uaedev_config_info));
2522 	validatedevicename (uci->ci.devname);
2523 	validatevolumename (uci->ci.volname);
2524 	if (!uci->ci.devname[0] && ci->type != UAEDEV_CD) {
2525 		TCHAR base[32];
2526 		TCHAR base2[32];
2527 		int num = 0;
2528 		if (uci->ci.rootdir[0] == 0 && ci->type == UAEDEV_DIR)
2529 			_tcscpy (base, _T("RDH"));
2530 		else
2531 			_tcscpy (base, _T("DH"));
2532 		_tcscpy (base2, base);
2533 		for (i = 0; i < p->mountitems; i++) {
2534 			_stprintf (base2, _T("%s%d"), base, num);
2535 			if (!_tcsicmp(base2, p->mountconfig[i].ci.devname)) {
2536 				num++;
2537 				i = -1;
2538 				continue;
2539 			}
2540 		}
2541 		_tcscpy (uci->ci.devname, base2);
2542 		validatedevicename (uci->ci.devname);
2543 	}
2544 	if (ci->type == UAEDEV_DIR) {
2545 		TCHAR *s = filesys_createvolname (uci->ci.volname, uci->ci.rootdir, _T("Harddrive"));
2546 		_tcscpy (uci->ci.volname, s);
2547 		xfree (s);
2548 	}
2549 	return uci;
2550 }
2551 
parse_addmem(struct uae_prefs * p,TCHAR * buf,int num)2552 static void parse_addmem (struct uae_prefs *p, TCHAR *buf, int num)
2553 {
2554 	int size = 0, addr = 0;
2555 
2556 	if (!getintval2 (&buf, &addr, ','))
2557 		return;
2558 	if (!getintval2 (&buf, &size, 0))
2559 		return;
2560 	if (addr & 0xffff)
2561 		return;
2562 	if ((size & 0xffff) || (size & 0xffff0000) == 0)
2563 		return;
2564 	p->custom_memory_addrs[num] = addr;
2565 	p->custom_memory_sizes[num] = size;
2566 }
2567 
get_filesys_controller(const TCHAR * hdc)2568 static int get_filesys_controller (const TCHAR *hdc)
2569 {
2570 	int hdcv = HD_CONTROLLER_UAE;
2571 	if(_tcslen (hdc) >= 4 && !_tcsncmp (hdc, _T("ide"), 3)) {
2572 		hdcv = hdc[3] - '0' + HD_CONTROLLER_IDE0;
2573 		if (hdcv < HD_CONTROLLER_IDE0 || hdcv > HD_CONTROLLER_IDE3)
2574 			hdcv = 0;
2575 	}
2576 	if(_tcslen (hdc) >= 5 && !_tcsncmp (hdc, _T("scsi"), 4)) {
2577 		hdcv = hdc[4] - '0' + HD_CONTROLLER_SCSI0;
2578 		if (hdcv < HD_CONTROLLER_SCSI0 || hdcv > HD_CONTROLLER_SCSI6)
2579 			hdcv = 0;
2580 	}
2581 	if (_tcslen (hdc) >= 6 && !_tcsncmp (hdc, _T("scsram"), 6))
2582 		hdcv = HD_CONTROLLER_PCMCIA_SRAM;
2583 	if (_tcslen (hdc) >= 5 && !_tcsncmp (hdc, _T("scide"), 6))
2584 		hdcv = HD_CONTROLLER_PCMCIA_IDE;
2585 	return hdcv;
2586 }
2587 
parse_geo(const TCHAR * tname,struct uaedev_config_info * uci,struct hardfiledata * hfd,bool empty)2588 static bool parse_geo (const TCHAR *tname, struct uaedev_config_info *uci, struct hardfiledata *hfd, bool empty)
2589 {
2590 	struct zfile *f;
2591 	int found;
2592 	TCHAR buf[200];
2593 
2594 	f = zfile_fopen (tname, _T("r"), 0);
2595 	if (!f)
2596 		return false;
2597 	found = hfd == NULL && !empty ? 2 : 0;
2598 	if (found)
2599 		write_log (_T("Geometry file '%s' detected\n"), tname);
2600 	while (zfile_fgets (buf, sizeof buf / sizeof (TCHAR), f)) {
2601 		int v;
2602 		TCHAR *sep;
2603 
2604 		my_trim (buf);
2605 		if (_tcslen (buf) == 0)
2606 			continue;
2607 		if (buf[0] == '[' && buf[_tcslen (buf) - 1] == ']') {
2608 			if (found > 1) {
2609 				zfile_fclose (f);
2610 				return true;
2611 			}
2612 			found = 0;
2613 			buf[_tcslen (buf) - 1] = 0;
2614 			my_trim (buf + 1);
2615 			if (!_tcsicmp (buf + 1, _T("empty"))) {
2616 				if (empty)
2617 					found = 1;
2618 			} else if (!_tcsicmp (buf + 1, _T("default"))) {
2619 				if (!empty)
2620 					found = 1;
2621 			} else if (hfd) {
2622 				uae_u64 size = atoi (buf + 1);
2623 				if (size == hfd->virtsize)
2624 					found = 2;
2625 			}
2626 			if (found)
2627 				write_log (_T("Geometry file '%s', entry '%s' detected\n"), tname, buf + 1);
2628 			continue;
2629 		}
2630 		if (!found)
2631 			continue;
2632 
2633 		sep =  _tcschr (buf, '=');
2634 		if (!sep)
2635 			continue;
2636 		sep[0] = 0;
2637 
2638 		TCHAR *key = my_strdup_trim (buf);
2639 		TCHAR *val = my_strdup_trim (sep + 1);
2640 		if (val[0] == '0' && _totupper (val[1]) == 'X') {
2641 			TCHAR *endptr;
2642 			v = _tcstol (val, &endptr, 16);
2643 		} else {
2644 			v = _tstol (val);
2645 		}
2646 		if (!_tcsicmp (key, _T("surfaces")))
2647 			uci->surfaces = v;
2648 		if (!_tcsicmp (key, _T("sectorspertrack")) || !_tcsicmp (key, _T("blockspertrack")))
2649 			uci->sectors = v;
2650 		if (!_tcsicmp (key, _T("sectorsperblock")))
2651 			uci->sectorsperblock = v;
2652 		if (!_tcsicmp (key, _T("reserved")))
2653 			uci->reserved = v;
2654 		if (!_tcsicmp (key, _T("lowcyl")))
2655 			uci->lowcyl = v;
2656 		if (!_tcsicmp (key, _T("highcyl")) || !_tcsicmp (key, _T("cyl")))
2657 			uci->highcyl = v;
2658 		if (!_tcsicmp (key, _T("blocksize")) || !_tcsicmp (key, _T("sectorsize")))
2659 			uci->blocksize = v;
2660 		if (!_tcsicmp (key, _T("buffers")))
2661 			uci->buffers = v;
2662 		if (!_tcsicmp (key, _T("maxtransfer")))
2663 			uci->maxtransfer = v;
2664 		if (!_tcsicmp (key, _T("interleave")))
2665 			uci->interleave = v;
2666 		if (!_tcsicmp (key, _T("dostype")))
2667 			uci->dostype = v;
2668 		if (!_tcsicmp (key, _T("bufmemtype")))
2669 			uci->bufmemtype = v;
2670 		if (!_tcsicmp (key, _T("stacksize")))
2671 			uci->stacksize = v;
2672 		if (!_tcsicmp (key, _T("mask")))
2673 			uci->mask = v;
2674 		if (!_tcsicmp (key, _T("unit")))
2675 			uci->unit = v;
2676 		if (!_tcsicmp (key, _T("controller")))
2677 			uci->controller = get_filesys_controller (val);
2678 		if (!_tcsicmp (key, _T("flags")))
2679 			uci->flags = v;
2680 		if (!_tcsicmp (key, _T("priority")))
2681 			uci->priority = v;
2682 		if (!_tcsicmp (key, _T("forceload")))
2683 			uci->forceload = v;
2684 		if (!_tcsicmp (key, _T("bootpri"))) {
2685 			if (v < -129)
2686 				v = -129;
2687 			if (v > 127)
2688 				v = 127;
2689 			uci->bootpri = v;
2690 		}
2691 		if (!_tcsicmp (key, _T("filesystem")))
2692 			_tcscpy (uci->filesys, val);
2693 		if (!_tcsicmp (key, _T("device")))
2694 			_tcscpy (uci->devname, val);
2695 		xfree (val);
2696 		xfree (key);
2697 	}
2698 	zfile_fclose (f);
2699 	return false;
2700 }
get_hd_geometry(struct uaedev_config_info * uci)2701 bool get_hd_geometry (struct uaedev_config_info *uci)
2702 {
2703 	TCHAR tname[MAX_DPATH];
2704 
2705 	fetch_configurationpath (tname, sizeof tname / sizeof (TCHAR));
2706 	_tcscat (tname, _T("default.geo"));
2707 	if (zfile_exists (tname)) {
2708 		struct hardfiledata hfd;
2709 		memset (&hfd, 0, sizeof hfd);
2710 		hfd.ci.readonly = true;
2711 		hfd.ci.blocksize = 512;
2712 		if (hdf_open (&hfd, uci->rootdir)) {
2713 			parse_geo (tname, uci, &hfd, false);
2714 			hdf_close (&hfd);
2715 		} else {
2716 			parse_geo (tname, uci, NULL, true);
2717 		}
2718 	}
2719 	if (uci->rootdir[0]) {
2720 		_tcscpy (tname, uci->rootdir);
2721 		_tcscat (tname, _T(".geo"));
2722 		return parse_geo (tname, uci, NULL, false);
2723 	}
2724 	return false;
2725 }
2726 
cfgfile_parse_newfilesys(struct uae_prefs * p,int nr,int type,TCHAR * value,int unit,bool uaehfentry)2727 static int cfgfile_parse_newfilesys (struct uae_prefs *p, int nr, int type, TCHAR *value, int unit, bool uaehfentry)
2728 {
2729 	struct uaedev_config_info uci;
2730 	TCHAR *tmpp = _tcschr (value, ','), *tmpp2;
2731 	TCHAR *str = NULL;
2732 	TCHAR devname[MAX_DPATH], volname[MAX_DPATH];
2733 
2734 	devname[0] = volname[0] = 0;
2735 	uci_set_defaults (&uci, false);
2736 
2737 	config_newfilesystem = 1;
2738 	if (tmpp == 0)
2739 		goto invalid_fs;
2740 
2741 	*tmpp++ = '\0';
2742 	if (strcasecmp (value, _T("ro")) == 0)
2743 		uci.readonly = true;
2744 	else if (strcasecmp (value, _T("rw")) == 0)
2745 		uci.readonly = false;
2746 	else
2747 		goto invalid_fs;
2748 
2749 	value = tmpp;
2750 	if (type == 0) {
2751 		uci.type = UAEDEV_DIR;
2752 		tmpp = _tcschr (value, ':');
2753 		if (tmpp == 0)
2754 			goto empty_fs;
2755 		*tmpp++ = 0;
2756 		_tcscpy (devname, value);
2757 		tmpp2 = tmpp;
2758 		tmpp = _tcschr (tmpp, ':');
2759 		if (tmpp == 0)
2760 			goto empty_fs;
2761 		*tmpp++ = 0;
2762 		_tcscpy (volname, tmpp2);
2763 		tmpp2 = tmpp;
2764 		tmpp = _tcschr (tmpp, ',');
2765 		if (tmpp == 0)
2766 			goto empty_fs;
2767 		*tmpp++ = 0;
2768 		_tcscpy (uci.rootdir, tmpp2);
2769 		_tcscpy (uci.volname, volname);
2770 		_tcscpy (uci.devname, devname);
2771 		if (! getintval (&tmpp, &uci.bootpri, 0))
2772 			goto empty_fs;
2773 	} else if (type == 1 || (type == 2 && uaehfentry)) {
2774 		tmpp = _tcschr (value, ':');
2775 		if (tmpp == 0)
2776 			goto invalid_fs;
2777 		*tmpp++ = '\0';
2778 		_tcscpy (devname, value);
2779 		tmpp2 = tmpp;
2780 		tmpp = _tcschr (tmpp, ',');
2781 		if (tmpp == 0)
2782 			goto invalid_fs;
2783 		*tmpp++ = 0;
2784 		_tcscpy (uci.rootdir, tmpp2);
2785 		if (uci.rootdir[0] != ':')
2786 			get_hd_geometry (&uci);
2787 		_tcscpy (uci.devname, devname);
2788 		if (! getintval (&tmpp, &uci.sectors, ',')
2789 			|| ! getintval (&tmpp, &uci.surfaces, ',')
2790 			|| ! getintval (&tmpp, &uci.reserved, ',')
2791 			|| ! getintval (&tmpp, &uci.blocksize, ','))
2792 			goto invalid_fs;
2793 		if (getintval2 (&tmpp, &uci.bootpri, ',')) {
2794 			tmpp2 = tmpp;
2795 			tmpp = _tcschr (tmpp, ',');
2796 			if (tmpp != 0) {
2797 				*tmpp++ = 0;
2798 				_tcscpy (uci.filesys, tmpp2);
2799 				TCHAR *tmpp2 = _tcschr (tmpp, ',');
2800 				if (tmpp2)
2801 					*tmpp2++ = 0;
2802 				uci.controller = get_filesys_controller (tmpp);
2803 				if (tmpp2) {
2804 					if (getintval2 (&tmpp2, &uci.highcyl, ',')) {
2805 						getintval (&tmpp2, &uci.pcyls, '/');
2806 						getintval (&tmpp2, &uci.pheads, '/');
2807 						getintval2 (&tmpp2, &uci.psecs, '/');
2808 					}
2809 				}
2810 			}
2811 		}
2812 		if (type == 2) {
2813 			uci.cd_emu_unit = unit;
2814 			uci.blocksize = 2048;
2815 			uci.readonly = true;
2816 			uci.type = UAEDEV_CD;
2817 		} else {
2818 			uci.type = UAEDEV_HDF;
2819 		}
2820 	} else {
2821 		goto invalid_fs;
2822 	}
2823 empty_fs:
2824 	if (uci.rootdir[0]) {
2825 		if (_tcslen (uci.rootdir) > 3 && uci.rootdir[0] == 'H' && uci.rootdir[1] == 'D' && uci.rootdir[2] == '_') {
2826 			memmove (uci.rootdir, uci.rootdir + 2, (_tcslen (uci.rootdir + 2) + 1) * sizeof (TCHAR));
2827 			uci.rootdir[0] = ':';
2828 		}
2829 		str = cfgfile_subst_path_load (UNEXPANDED, &p->path_hardfile, uci.rootdir, false);
2830 		_tcscpy (uci.rootdir, str);
2831 	}
2832 #ifdef FILESYS
2833 	add_filesys_config (p, nr, &uci);
2834 #endif
2835 //	xfree (str);
2836 	return 1;
2837 
2838 invalid_fs:
2839 	write_log (_T("Invalid filesystem/hardfile/cd specification.\n"));
2840 	return 1;
2841 }
2842 
cfgfile_parse_filesys(struct uae_prefs * p,const TCHAR * option,TCHAR * value)2843 static int cfgfile_parse_filesys (struct uae_prefs *p, const TCHAR *option, TCHAR *value)
2844 {
2845 	int i;
2846 
2847 	for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) {
2848 		TCHAR tmp[100];
2849 		_stprintf (tmp, _T("uaehf%d"), i);
2850 		if (_tcscmp (option, tmp) == 0) {
2851 			for (;;) {
2852 				int  type = -1;
2853 				int unit = -1;
2854 				TCHAR *tmpp = _tcschr (value, ',');
2855 				if (tmpp == NULL)
2856 					return 1;
2857 				*tmpp++ = 0;
2858 				if (_tcsicmp (value, _T("hdf")) == 0) {
2859 					type = 1;
2860 					return 1; /* ignore for now */
2861 				} else if (_tcsnicmp (value, _T("cd"), 2) == 0 && (value[2] == 0 || value[3] == 0)) {
2862 					unit = 0;
2863 					if (value[2] > 0)
2864 						unit = value[2] - '0';
2865 					if (unit >= 0 && unit <= MAX_TOTAL_SCSI_DEVICES) {
2866 						type = 2;
2867 				}
2868 				} else if (_tcsicmp (value, _T("dir")) != 0) {
2869 					type = 0;
2870 					return 1;  /* ignore for now */
2871 				}
2872 				if (type >= 0)
2873 					return cfgfile_parse_newfilesys (p, -1, type, tmpp, unit, true);
2874 				return 1;
2875 			}
2876 			return 1;
2877 		} else if (!_tcsncmp (option, tmp, _tcslen (tmp)) && option[_tcslen (tmp)] == '_') {
2878 			struct uaedev_config_info *uci = &currprefs.mountconfig[i].ci;
2879 			if (uci->devname) {
2880 				const TCHAR *s = &option[_tcslen (tmp) + 1];
2881 				if (!_tcscmp (s, _T("bootpri"))) {
2882 					getintval (&value, &uci->bootpri, 0);
2883 				} else if (!_tcscmp (s, _T("read-only"))) {
2884 					cfgfile_yesno (NULL, value, NULL, &uci->readonly);
2885 				} else if (!_tcscmp (s, _T("volumename"))) {
2886 					_tcscpy (uci->volname, value);
2887 				} else if (!_tcscmp (s, _T("devicename"))) {
2888 					_tcscpy (uci->devname, value);
2889 				} else if (!_tcscmp (s, _T("root"))) {
2890 					_tcscpy (uci->rootdir, value);
2891 				} else if (!_tcscmp (s, _T("filesys"))) {
2892 					_tcscpy (uci->filesys, value);
2893 				} else if (!_tcscmp (s, _T("controller"))) {
2894 					uci->controller = get_filesys_controller (value);
2895 				}
2896 			}
2897 		}
2898 	}
2899 
2900 	if (_tcscmp (option, _T("filesystem")) == 0
2901 		|| _tcscmp (option, _T("hardfile")) == 0)
2902 	{
2903 		struct uaedev_config_info uci;
2904 		TCHAR *tmpp = _tcschr (value, ',');
2905 		TCHAR *str;
2906 		bool hdf;
2907 
2908 		uci_set_defaults (&uci, false);
2909 
2910 		if (config_newfilesystem)
2911 			return 1;
2912 
2913 		if (tmpp == 0)
2914 			goto invalid_fs;
2915 
2916 		*tmpp++ = '\0';
2917 		if (_tcscmp (value, _T("1")) == 0 || strcasecmp (value, _T("ro")) == 0
2918 			|| strcasecmp (value, _T("readonly")) == 0
2919 			|| strcasecmp (value, _T("read-only")) == 0)
2920 			uci.readonly = true;
2921 		else if (_tcscmp (value, _T("0")) == 0 || strcasecmp (value, _T("rw")) == 0
2922 			|| strcasecmp (value, _T("readwrite")) == 0
2923 			|| strcasecmp (value, _T("read-write")) == 0)
2924 			uci.readonly = false;
2925 		else
2926 			goto invalid_fs;
2927 
2928 		value = tmpp;
2929 		if (_tcscmp (option, _T("filesystem")) == 0) {
2930 			hdf = false;
2931 			tmpp = _tcschr (value, ':');
2932 			if (tmpp == 0)
2933 				goto invalid_fs;
2934 			*tmpp++ = '\0';
2935 			_tcscpy (uci.volname, value);
2936 			_tcscpy (uci.rootdir, tmpp);
2937 		} else {
2938 			hdf = true;
2939 			if (! getintval (&value, &uci.sectors, ',')
2940 				|| ! getintval (&value, &uci.surfaces, ',')
2941 				|| ! getintval (&value, &uci.reserved, ',')
2942 				|| ! getintval (&value, &uci.blocksize, ','))
2943 				goto invalid_fs;
2944 			_tcscpy (uci.rootdir, value);
2945 		}
2946 		str = cfgfile_subst_path_load (UNEXPANDED, &p->path_hardfile, uci.rootdir, true);
2947 #ifdef FILESYS
2948 		uci.type = hdf ? UAEDEV_HDF : UAEDEV_DIR;
2949 		add_filesys_config (p, -1, &uci);
2950 #endif
2951 		xfree (str);
2952 		return 1;
2953 invalid_fs:
2954 		write_log (_T("Invalid filesystem/hardfile specification.\n"));
2955 		return 1;
2956 
2957 	}
2958 
2959 	if (_tcscmp (option, _T("filesystem2")) == 0)
2960 		return cfgfile_parse_newfilesys (p, -1, 0, value, -1, false);
2961 	if (_tcscmp (option, _T("hardfile2")) == 0)
2962 		return cfgfile_parse_newfilesys (p, -1, 1, value, -1, false);
2963 
2964 	return 0;
2965 }
2966 
cfgfile_parse_hardware(struct uae_prefs * p,const TCHAR * option,TCHAR * value)2967 static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCHAR *value)
2968 {
2969 	int tmpval, dummyint, i;
2970 	bool tmpbool, dummybool;
2971 	TCHAR *section = 0;
2972 	TCHAR tmpbuf[CONFIG_BLEN];
2973 
2974 	if (cfgfile_yesno (option, value, _T("cpu_cycle_exact"), &p->cpu_cycle_exact)
2975 		|| cfgfile_yesno (option, value, _T("blitter_cycle_exact"), &p->blitter_cycle_exact)) {
2976 #ifdef JIT
2977 			if (p->cpu_model >= 68020 && p->cachesize > 0)
2978 				p->cpu_cycle_exact = p->blitter_cycle_exact = 0;
2979 			/* we don't want cycle-exact in 68020/40+JIT modes */
2980 #endif
2981 			return 1;
2982 	}
2983 	if (cfgfile_yesno (option, value, _T("cycle_exact"), &tmpbool)) {
2984 		p->cpu_cycle_exact = p->blitter_cycle_exact = tmpbool;
2985 #ifdef JIT
2986 		if (p->cpu_model >= 68020 && p->cachesize > 0)
2987 			p->cpu_cycle_exact = p->blitter_cycle_exact = false;
2988 #endif
2989 		return 1;
2990 	}
2991 
2992 	if (cfgfile_string (option, value, _T("cpu_multiplier"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
2993 		p->cpu_clock_multiplier = (int)(_tstof (tmpbuf) * 256.0);
2994 		return 1;
2995 	}
2996 
2997 
2998 	if (cfgfile_yesno (option, value, _T("scsi_a3000"), &dummybool)) {
2999 		if (dummybool)
3000 			p->cs_mbdmac = 1;
3001 		return 1;
3002 	}
3003 	if (cfgfile_yesno (option, value, _T("scsi_a4000t"), &dummybool)) {
3004 		if (dummybool)
3005 			p->cs_mbdmac = 2;
3006 		return 1;
3007 	}
3008 
3009 	if (cfgfile_string (option, value, _T("a2065"), p->a2065name, sizeof p->a2065name / sizeof (TCHAR)))
3010 		return 1;
3011 
3012 	if (cfgfile_yesno (option, value, _T("immediate_blits"), &p->immediate_blits)
3013 		|| cfgfile_yesno (option, value, _T("fpu_no_unimplemented"), &p->fpu_no_unimplemented)
3014 		|| cfgfile_yesno (option, value, _T("cpu_no_unimplemented"), &p->int_no_unimplemented)
3015 		|| cfgfile_yesno (option, value, _T("cd32cd"), &p->cs_cd32cd)
3016 		|| cfgfile_yesno (option, value, _T("cd32c2p"), &p->cs_cd32c2p)
3017 		|| cfgfile_yesno (option, value, _T("cd32nvram"), &p->cs_cd32nvram)
3018 		|| cfgfile_yesno (option, value, _T("cdtvcd"), &p->cs_cdtvcd)
3019 		|| cfgfile_yesno (option, value, _T("cdtvram"), &p->cs_cdtvram)
3020 		|| cfgfile_yesno (option, value, _T("a1000ram"), &p->cs_a1000ram)
3021 		|| cfgfile_yesno (option, value, _T("pcmcia"), &p->cs_pcmcia)
3022 		|| cfgfile_yesno (option, value, _T("scsi_cdtv"), &p->cs_cdtvscsi)
3023 		|| cfgfile_yesno (option, value, _T("scsi_a4091"), &p->cs_a4091)
3024 		|| cfgfile_yesno (option, value, _T("scsi_a2091"), &p->cs_a2091)
3025 		|| cfgfile_yesno (option, value, _T("cia_overlay"), &p->cs_ciaoverlay)
3026 		|| cfgfile_yesno (option, value, _T("bogomem_fast"), &p->cs_slowmemisfast)
3027 		|| cfgfile_yesno (option, value, _T("ksmirror_e0"), &p->cs_ksmirror_e0)
3028 		|| cfgfile_yesno (option, value, _T("ksmirror_a8"), &p->cs_ksmirror_a8)
3029 		|| cfgfile_yesno (option, value, _T("resetwarning"), &p->cs_resetwarning)
3030 		|| cfgfile_yesno (option, value, _T("denise_noehb"), &p->cs_denisenoehb)
3031 		|| cfgfile_yesno (option, value, _T("ics_agnus"), &p->cs_dipagnus)
3032 		|| cfgfile_yesno (option, value, _T("agnus_bltbusybug"), &p->cs_agnusbltbusybug)
3033 		|| cfgfile_yesno (option, value, _T("fastmem_autoconfig"), &p->fastmem_autoconfig)
3034 		|| cfgfile_yesno (option, value, _T("gfxcard_hardware_vblank"), &p->rtg_hardwareinterrupt)
3035 		|| cfgfile_yesno (option, value, _T("gfxcard_hardware_sprite"), &p->rtg_hardwaresprite)
3036 		|| cfgfile_yesno (option, value, _T("synchronize_clock"), &p->tod_hack)
3037 
3038 		|| cfgfile_yesno (option, value, _T("kickshifter"), &p->kickshifter)
3039 		|| cfgfile_yesno (option, value, _T("ks_write_enabled"), &p->rom_readwrite)
3040 		|| cfgfile_yesno (option, value, _T("ntsc"), &p->ntscmode)
3041 		|| cfgfile_yesno (option, value, _T("sana2"), &p->sana2)
3042 		|| cfgfile_yesno (option, value, _T("genlock"), &p->genlock)
3043 		|| cfgfile_yesno (option, value, _T("cpu_compatible"), &p->cpu_compatible)
3044 		|| cfgfile_yesno (option, value, _T("cpu_24bit_addressing"), &p->address_space_24)
3045 		|| cfgfile_yesno (option, value, _T("parallel_on_demand"), &p->parallel_demand)
3046 		|| cfgfile_yesno (option, value, _T("parallel_postscript_emulation"), &p->parallel_postscript_emulation)
3047 		|| cfgfile_yesno (option, value, _T("parallel_postscript_detection"), &p->parallel_postscript_detection)
3048 		|| cfgfile_yesno (option, value, _T("serial_on_demand"), &p->serial_demand)
3049 		|| cfgfile_yesno (option, value, _T("serial_hardware_ctsrts"), &p->serial_hwctsrts)
3050 		|| cfgfile_yesno (option, value, _T("serial_direct"), &p->serial_direct)
3051 #ifdef JIT
3052 		|| cfgfile_yesno (option, value, _T("comp_nf"), &p->compnf)
3053 		|| cfgfile_yesno (option, value, _T("comp_constjump"), &p->comp_constjump)
3054 		|| cfgfile_yesno (option, value, _T("comp_oldsegv"), &p->comp_oldsegv)
3055 		|| cfgfile_yesno (option, value, _T("compforcesettings"), &dummybool)
3056 		|| cfgfile_yesno (option, value, _T("compfpu"), &p->compfpu)
3057 #endif
3058 #ifdef FPU
3059 		|| cfgfile_yesno (option, value, _T("fpu_strict"), &p->fpu_strict)
3060 #endif
3061 #ifdef JIT
3062 		|| cfgfile_yesno (option, value, _T("comp_midopt"), &p->comp_midopt)
3063 		|| cfgfile_yesno (option, value, _T("comp_lowopt"), &p->comp_lowopt)
3064 #endif
3065 		|| cfgfile_yesno (option, value, _T("rtg_nocustom"), &p->picasso96_nocustom)
3066 		|| cfgfile_yesno (option, value, _T("floppy_write_protected"), &p->floppy_read_only)
3067 		|| cfgfile_yesno (option, value, _T("uaeserial"), &p->uaeserial))
3068 		return 1;
3069 
3070 	if (cfgfile_intval (option, value, _T("cachesize"), &p->cachesize, 1)
3071 		|| cfgfile_intval (option, value, _T("chipset_hacks"), &p->cs_hacks, 1)
3072 		|| cfgfile_intval (option, value, _T("serial_stopbits"), &p->serial_stopbits, 1)
3073 		|| cfgfile_intval (option, value, _T("cpu060_revision"), &p->cpu060_revision, 1)
3074 		|| cfgfile_intval (option, value, _T("fpu_revision"), &p->fpu_revision, 1)
3075 		|| cfgfile_intval (option, value, _T("cdtvramcard"), &p->cs_cdtvcard, 1)
3076 		|| cfgfile_intval (option, value, _T("fatgary"), &p->cs_fatgaryrev, 1)
3077 		|| cfgfile_intval (option, value, _T("ramsey"), &p->cs_ramseyrev, 1)
3078 		|| cfgfile_doubleval (option, value, _T("chipset_refreshrate"), &p->chipset_refreshrate)
3079 		|| cfgfile_intval (option, value, _T("fastmem_size"), (int*)&p->fastmem_size, 0x100000)
3080 		|| cfgfile_intval (option, value, _T("fastmem2_size"), (int*)&p->fastmem2_size, 0x100000)
3081 		|| cfgfile_intval (option, value, _T("a3000mem_size"), (int*)&p->mbresmem_low_size, 0x100000)
3082 		|| cfgfile_intval (option, value, _T("mbresmem_size"), (int*)&p->mbresmem_high_size, 0x100000)
3083 		|| cfgfile_intval (option, value, _T("z3mem_size"), (int*)&p->z3fastmem_size, 0x100000)
3084 		|| cfgfile_intval (option, value, _T("z3mem2_size"), (int*)&p->z3fastmem2_size, 0x100000)
3085 		|| cfgfile_intval (option, value, _T("megachipmem_size"), (int*)&p->z3chipmem_size, 0x100000)
3086 		|| cfgfile_intval (option, value, _T("z3mem_start"), (int*)&p->z3fastmem_start, 1)
3087 		|| cfgfile_intval (option, value, _T("bogomem_size"), (int*)&p->bogomem_size, 0x40000)
3088 		|| cfgfile_intval (option, value, _T("gfxcard_size"), (int*)&p->rtgmem_size, 0x100000)
3089 		|| cfgfile_strval (option, value, _T("gfxcard_type"), &p->rtgmem_type, rtgtype, 0)
3090 		|| cfgfile_intval (option, value, _T("rtg_modes"), &p->picasso96_modeflags, 1)
3091 		|| cfgfile_intval (option, value, _T("floppy_speed"), &p->floppy_speed, 1)
3092 		|| cfgfile_intval (option, value, _T("floppy_write_length"), &p->floppy_write_length, 1)
3093 		|| cfgfile_intval (option, value, _T("floppy_random_bits_min"), &p->floppy_random_bits_min, 1)
3094 		|| cfgfile_intval (option, value, _T("floppy_random_bits_max"), &p->floppy_random_bits_max, 1)
3095 		|| cfgfile_intval (option, value, _T("nr_floppies"), &p->nr_floppies, 1)
3096 		|| cfgfile_intval (option, value, _T("floppy0type"), &p->floppyslots[0].dfxtype, 1)
3097 		|| cfgfile_intval (option, value, _T("floppy1type"), &p->floppyslots[1].dfxtype, 1)
3098 		|| cfgfile_intval (option, value, _T("floppy2type"), &p->floppyslots[2].dfxtype, 1)
3099 		|| cfgfile_intval (option, value, _T("floppy3type"), &p->floppyslots[3].dfxtype, 1)
3100 		|| cfgfile_intval (option, value, _T("maprom"), (int*)&p->maprom, 1)
3101 		|| cfgfile_intval (option, value, _T("parallel_autoflush"), &p->parallel_autoflush_time, 1)
3102 		|| cfgfile_intval (option, value, _T("uae_hide"), &p->uae_hide, 1)
3103 		|| cfgfile_intval (option, value, _T("cpu_frequency"), &p->cpu_frequency, 1)
3104 		|| cfgfile_intval (option, value, _T("kickstart_ext_rom_file2addr"), (int*)&p->romextfile2addr, 1)
3105 		|| cfgfile_intval (option, value, _T("catweasel"), &p->catweasel, 1))
3106 	return 1;
3107 
3108 #ifdef JIT
3109 	if (
3110 #ifdef NATMEM_OFFSET
3111            cfgfile_strval (option, value, _T("comp_trustbyte"), &p->comptrustbyte, compmode, 0)
3112 	|| cfgfile_strval (option, value, _T("comp_trustword"), &p->comptrustword, compmode, 0)
3113 	|| cfgfile_strval (option, value, _T("comp_trustlong"), &p->comptrustlong, compmode, 0)
3114 	|| cfgfile_strval (option, value, _T("comp_trustnaddr"), &p->comptrustnaddr, compmode, 0)
3115 #else
3116            cfgfile_strval (option, value, _T("comp_trustbyte"), &p->comptrustbyte, compmode, 1)
3117 	|| cfgfile_strval (option, value, _T("comp_trustword"), &p->comptrustword, compmode, 1)
3118 	|| cfgfile_strval (option, value, _T("comp_trustlong"), &p->comptrustlong, compmode, 1)
3119 	|| cfgfile_strval (option, value, _T("comp_trustnaddr"), &p->comptrustnaddr, compmode, 1)
3120 #endif
3121 	|| cfgfile_strboolval (option, value, _T("comp_flushmode"), &p->comp_hardflush, flushmode, 0))
3122 	return 1;
3123 #endif
3124 
3125 	if (cfgfile_strval (option, value, _T("rtc"), &p->cs_rtc, rtctype, 0)
3126 		|| cfgfile_strval (option, value, _T("ciaatod"), &p->cs_ciaatod, ciaatodmode, 0)
3127 		|| cfgfile_strval (option, value, _T("ide"), &p->cs_ide, idemode, 0)
3128 		|| cfgfile_strval (option, value, _T("scsi"), &p->scsi, scsimode, 0)
3129 		|| cfgfile_strval (option, value, _T("collision_level"), &p->collision_level, collmode, 0)
3130 		|| cfgfile_strval (option, value, _T("parallel_matrix_emulation"), &p->parallel_matrix_emulation, epsonprinter, 0)
3131 		|| cfgfile_strval (option, value, _T("monitoremu"), &p->monitoremu, specialmonitors, 0)
3132 		|| cfgfile_strval (option, value, _T("waiting_blits"), &p->waiting_blits, waitblits, 0)
3133 		|| cfgfile_strval (option, value, _T("floppy_auto_extended_adf"), &p->floppy_auto_ext2, autoext2, 0))
3134 		return 1;
3135 
3136 	if (cfgfile_path_mp (option, value, _T("kickstart_rom_file"), p->romfile, sizeof p->romfile / sizeof (TCHAR), &p->path_rom)
3137 		|| cfgfile_path_mp (option, value, _T("kickstart_ext_rom_file"), p->romextfile, sizeof p->romextfile / sizeof (TCHAR), &p->path_rom)
3138 		|| cfgfile_path_mp (option, value, _T("kickstart_ext_rom_file2"), p->romextfile2, sizeof p->romextfile2 / sizeof (TCHAR), &p->path_rom)
3139 		|| cfgfile_rom (option, value, _T("kickstart_rom_file_id"), p->romfile, sizeof p->romfile / sizeof (TCHAR))
3140 		|| cfgfile_rom (option, value, _T("kickstart_ext_rom_file_id"), p->romextfile, sizeof p->romextfile / sizeof (TCHAR))
3141 		|| cfgfile_path (option, value, _T("amax_rom_file"), p->amaxromfile, sizeof p->amaxromfile / sizeof (TCHAR))
3142 		|| cfgfile_path_mp (option, value, _T("flash_file"), p->flashfile, sizeof p->flashfile / sizeof (TCHAR), &p->path_rom)
3143 		|| cfgfile_path_mp (option, value, _T("cart_file"), p->cartfile, sizeof p->cartfile / sizeof (TCHAR), &p->path_rom)
3144 		|| cfgfile_path_mp (option, value, _T("rtc_file"), p->rtcfile, sizeof p->rtcfile / sizeof (TCHAR), &p->path_rom)
3145 		|| cfgfile_string (option, value, _T("pci_devices"), p->pci_devices, sizeof p->pci_devices / sizeof (TCHAR))
3146 		|| cfgfile_string (option, value, _T("ghostscript_parameters"), p->ghostscript_parameters, sizeof p->ghostscript_parameters / sizeof (TCHAR)))
3147 	return 1;
3148 
3149 	if (cfgfile_strval (option, value, _T("chipset_compatible"), &p->cs_compatible, cscompa, 0)) {
3150 		built_in_chipset_prefs (p);
3151 		return 1;
3152 	}
3153 
3154 
3155 	if (cfgfile_strval (option, value, _T("cart_internal"), &p->cart_internal, cartsmode, 0)) {
3156 		if (p->cart_internal) {
3157 			struct romdata *rd = getromdatabyid (63);
3158 			if (rd)
3159 				_stprintf (p->cartfile, _T(":%s"), rd->configname);
3160 		}
3161 		return 1;
3162 	}
3163 	if (cfgfile_string (option, value, _T("kickstart_rom"), p->romident, sizeof p->romident / sizeof (TCHAR))) {
3164 		decode_rom_ident (p->romfile, sizeof p->romfile / sizeof (TCHAR), p->romident, ROMTYPE_ALL_KICK);
3165 		return 1;
3166 	}
3167 	if (cfgfile_string (option, value, _T("kickstart_ext_rom"), p->romextident, sizeof p->romextident / sizeof (TCHAR))) {
3168 		decode_rom_ident (p->romextfile, sizeof p->romextfile / sizeof (TCHAR), p->romextident, ROMTYPE_ALL_EXT);
3169 		return 1;
3170 	}
3171 	if (cfgfile_string (option, value, _T("cart"), p->cartident, sizeof p->cartident / sizeof (TCHAR))) {
3172 		decode_rom_ident (p->cartfile, sizeof p->cartfile / sizeof (TCHAR), p->cartident, ROMTYPE_ALL_CART);
3173 		return 1;
3174 	}
3175 
3176 	for (i = 0; i < 4; i++) {
3177 		_stprintf (tmpbuf, _T("floppy%d"), i);
3178 		if (cfgfile_path_mp (option, value, tmpbuf, p->floppyslots[i].df, sizeof p->floppyslots[i].df / sizeof (TCHAR), &p->path_floppy))
3179 			return 1;
3180 	}
3181 
3182 	if (cfgfile_intval (option, value, _T("chipmem_size"), &dummyint, 1)) {
3183 		if (dummyint < 0)
3184 			p->chipmem_size = 0x20000; /* 128k, prototype support */
3185 		else if (dummyint == 0)
3186 			p->chipmem_size = 0x40000; /* 256k */
3187 		else
3188 			p->chipmem_size = dummyint * 0x80000;
3189 		return 1;
3190 	}
3191 
3192 	if (cfgfile_string (option, value, _T("addmem1"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
3193 		parse_addmem (p, tmpbuf, 0);
3194 		return 1;
3195 	}
3196 	if (cfgfile_string (option, value, _T("addmem2"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
3197 		parse_addmem (p, tmpbuf, 1);
3198 		return 1;
3199 	}
3200 
3201 	if (cfgfile_strval (option, value, _T("chipset"), &tmpval, csmode, 0)) {
3202 		set_chipset_mask (p, tmpval);
3203 		return 1;
3204 	}
3205 
3206 	if (cfgfile_string (option, value, _T("mmu_model"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
3207 		p->mmu_model = _tstol(tmpbuf);
3208 		return 1;
3209 	}
3210 
3211 	if (cfgfile_string (option, value, _T("fpu_model"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
3212 		p->fpu_model = _tstol(tmpbuf);
3213 		return 1;
3214 	}
3215 
3216 	if (cfgfile_string (option, value, _T("cpu_model"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
3217 		p->cpu_model = _tstol(tmpbuf);
3218 		p->fpu_model = 0;
3219 		return 1;
3220 	}
3221 
3222 	/* old-style CPU configuration */
3223 	if (cfgfile_string (option, value, _T("cpu_type"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
3224 		p->fpu_model = 0;
3225 		p->address_space_24 = 0;
3226 		p->cpu_model = 680000;
3227 		if (!_tcscmp (tmpbuf, _T("68000"))) {
3228 			p->cpu_model = 68000;
3229 		} else if (!_tcscmp (tmpbuf, _T("68010"))) {
3230 			p->cpu_model = 68010;
3231 		} else if (!_tcscmp (tmpbuf, _T("68ec020"))) {
3232 			p->cpu_model = 68020;
3233 			p->address_space_24 = 1;
3234 		} else if (!_tcscmp (tmpbuf, _T("68020"))) {
3235 			p->cpu_model = 68020;
3236 		} else if (!_tcscmp (tmpbuf, _T("68ec020/68881"))) {
3237 			p->cpu_model = 68020;
3238 			p->fpu_model = 68881;
3239 			p->address_space_24 = 1;
3240 		} else if (!_tcscmp (tmpbuf, _T("68020/68881"))) {
3241 			p->cpu_model = 68020;
3242 			p->fpu_model = 68881;
3243 		} else if (!_tcscmp (tmpbuf, _T("68040"))) {
3244 			p->cpu_model = 68040;
3245 			p->fpu_model = 68040;
3246 		} else if (!_tcscmp (tmpbuf, _T("68060"))) {
3247 			p->cpu_model = 68060;
3248 			p->fpu_model = 68060;
3249 		}
3250 		return 1;
3251 	}
3252 
3253 			/* Broken earlier versions used to write this out as a string.  */
3254 	if (cfgfile_strval (option, value, _T("finegraincpu_speed"), &p->m68k_speed, speedmode, 1)) {
3255 			p->m68k_speed--;
3256 			return 1;
3257 		}
3258 
3259 	if (cfgfile_strval (option, value, _T("cpu_speed"), &p->m68k_speed, speedmode, 1)) {
3260 		p->m68k_speed--;
3261 		return 1;
3262 	}
3263 	if (cfgfile_intval (option, value, _T("cpu_speed"), &p->m68k_speed, 1)) {
3264 		p->m68k_speed *= CYCLE_UNIT;
3265 		return 1;
3266 	}
3267 	if (cfgfile_doubleval (option, value, _T("cpu_throttle"), &p->m68k_speed_throttle)) {
3268 		return 1;
3269 	}
3270 	if (cfgfile_intval (option, value, _T("finegrain_cpu_speed"), &p->m68k_speed, 1)) {
3271 		if (OFFICIAL_CYCLE_UNIT > CYCLE_UNIT) {
3272 			int factor = OFFICIAL_CYCLE_UNIT / CYCLE_UNIT;
3273 			p->m68k_speed = (p->m68k_speed + factor - 1) / factor;
3274 		}
3275 		if (strcasecmp (value, _T("max")) == 0)
3276 			p->m68k_speed = -1;
3277 		return 1;
3278 	}
3279 
3280 	if (cfgfile_intval (option, value, _T("dongle"), &p->dongle, 1)) {
3281 		if (p->dongle == 0)
3282 			cfgfile_strval (option, value, _T("dongle"), &p->dongle, dongles, 0);
3283 		return 1;
3284 	}
3285 
3286 	if (strcasecmp (option, _T("quickstart")) == 0) {
3287 		int model = 0;
3288 		TCHAR *tmpp = _tcschr (value, ',');
3289 		if (tmpp) {
3290 			*tmpp++ = 0;
3291 			TCHAR *tmpp2 = _tcschr (value, ',');
3292 			if (tmpp2)
3293 				*tmpp2 = 0;
3294 			cfgfile_strval (option, value, option, &model, qsmodes,  0);
3295 			if (model >= 0) {
3296 				int config = _tstol (tmpp);
3297 				built_in_prefs (p, model, config, 0, 0);
3298 			}
3299 		}
3300 		return 1;
3301 	}
3302 
3303 	if (cfgfile_parse_filesys (p, option, value))
3304 		return 1;
3305 
3306 	return 0;
3307 }
3308 
3309 
3310 static bool createconfigstore (struct uae_prefs*);
3311 static int getconfigstoreline (const TCHAR *option, TCHAR *value);
3312 
calcformula(struct uae_prefs * prefs,TCHAR * in)3313 static void calcformula (struct uae_prefs *prefs, TCHAR *in)
3314 {
3315 	TCHAR out[MAX_DPATH], configvalue[CONFIG_BLEN];
3316 	TCHAR *p = out;
3317 	double val;
3318 	int cnt1, cnt2;
3319 	static bool updatestore;
3320 
3321 	if (_tcslen (in) < 2 || in[0] != '[' || in[_tcslen (in) - 1] != ']')
3322 		return;
3323 	if (!configstore || updatestore)
3324 		createconfigstore (prefs);
3325 	updatestore = false;
3326 	if (!configstore)
3327 		return;
3328 	cnt1 = cnt2 = 0;
3329 	for (int i = 1; i < _tcslen (in) - 1; i++) {
3330 		TCHAR c = _totupper (in[i]);
3331 		if (c >= 'A' && c <='Z') {
3332 			TCHAR *start = &in[i];
3333 			while (_istalnum (c) || c == '_' || c == '.') {
3334 				i++;
3335 				c = in[i];
3336 			}
3337 			TCHAR store = in[i];
3338 			in[i] = 0;
3339 			//write_log (_T("'%s'\n"), start);
3340 			if (!getconfigstoreline (start, configvalue))
3341 				return;
3342 			_tcscpy (p, configvalue);
3343 			p += _tcslen (p);
3344 			in[i] = store;
3345 			i--;
3346 			cnt1++;
3347 		} else {
3348 			cnt2++;
3349 			*p ++= c;
3350 		}
3351 	}
3352 	*p = 0;
3353 	if (cnt1 == 0 && cnt2 == 0)
3354 		return;
3355 	/* single config entry only? */
3356 	if (cnt1 == 1 && cnt2 == 0) {
3357 		_tcscpy (in, out);
3358 		updatestore = true;
3359 		return;
3360 	}
3361 	if (calc (out, &val)) {
3362 		if (val - (int)val != 0.0f)
3363 			_stprintf (in, _T("%f"), val);
3364 		else
3365 			_stprintf (in, _T("%d"), (int)val);
3366 		updatestore = true;
3367 		return;
3368 	}
3369 }
3370 
cfgfile_parse_option(struct uae_prefs * p,TCHAR * option,TCHAR * value,int type)3371 int cfgfile_parse_option (struct uae_prefs *p, TCHAR *option, TCHAR *value, int type)
3372 {
3373 	calcformula (p, value);
3374 
3375 	if (!_tcscmp (option, _T("debug"))) {
3376 		write_log (_T("CONFIG DEBUG: '%s'\n"), value);
3377 		return 1;
3378 	}
3379 	if (!_tcscmp (option, _T("config_hardware")))
3380 		return 1;
3381 	if (!_tcscmp (option, _T("config_host")))
3382 		return 1;
3383 	if (cfgfile_path (option, value, _T("config_hardware_path"), p->config_hardware_path, sizeof p->config_hardware_path / sizeof (TCHAR)))
3384 		return 1;
3385 	if (cfgfile_path (option, value, _T("config_host_path"), p->config_host_path, sizeof p->config_host_path / sizeof (TCHAR)))
3386 		return 1;
3387 	if (type == 0 || (type & CONFIG_TYPE_HARDWARE)) {
3388 		if (cfgfile_parse_hardware (p, option, value))
3389 			return 1;
3390 	}
3391 	if (type == 0 || (type & CONFIG_TYPE_HOST)) {
3392 		if (cfgfile_parse_host (p, option, value))
3393 			return 1;
3394 	}
3395 	if (type > 0 && (type & (CONFIG_TYPE_HARDWARE | CONFIG_TYPE_HOST)) != (CONFIG_TYPE_HARDWARE | CONFIG_TYPE_HOST))
3396 		return 1;
3397 	return 0;
3398 }
3399 
isutf8ext(TCHAR * s)3400 static int isutf8ext (TCHAR *s)
3401 {
3402 	if (_tcslen (s) > _tcslen (UTF8NAME) && !_tcscmp (s + _tcslen (s) - _tcslen (UTF8NAME), UTF8NAME)) {
3403 		s[_tcslen (s) - _tcslen (UTF8NAME)] = 0;
3404 		return 1;
3405 	}
3406 	return 0;
3407 }
3408 
cfgfile_separate_linea(const TCHAR * filename,char * line,TCHAR * line1b,TCHAR * line2b)3409 static int cfgfile_separate_linea (const TCHAR *filename, char *line, TCHAR *line1b, TCHAR *line2b)
3410 {
3411 	char *line1, *line2;
3412 	int i;
3413 
3414 	line1 = line;
3415 	line1 += strspn (line1, "\t \r\n");
3416 	if (*line1 == ';')
3417 		return 0;
3418 	line2 = strchr (line, '=');
3419 	if (! line2) {
3420 		TCHAR *s = au (line1);
3421 		write_log (_T("CFGFILE: '%s', linea was incomplete with only %s\n"), filename, s);
3422 		xfree (s);
3423 		return 0;
3424 	}
3425 	*line2++ = '\0';
3426 
3427 	/* Get rid of whitespace.  */
3428 	i = strlen (line2);
3429 	while (i > 0 && (line2[i - 1] == '\t' || line2[i - 1] == ' '
3430 		|| line2[i - 1] == '\r' || line2[i - 1] == '\n'))
3431 		line2[--i] = '\0';
3432 	line2 += strspn (line2, "\t \r\n");
3433 
3434 	i = strlen (line);
3435 	while (i > 0 && (line[i - 1] == '\t' || line[i - 1] == ' '
3436 		|| line[i - 1] == '\r' || line[i - 1] == '\n'))
3437 		line[--i] = '\0';
3438 	line += strspn (line, "\t \r\n");
3439 	au_copy (line1b, MAX_DPATH, line);
3440 	if (isutf8ext (line1b)) {
3441 		if (line2[0]) {
3442 			TCHAR *s = utf8u (line2);
3443 			_tcscpy (line2b, s);
3444 			xfree (s);
3445 		}
3446 	} else {
3447 		au_copy (line2b, MAX_DPATH, line2);
3448 	}
3449 	return 1;
3450 }
3451 
cfgfile_separate_line(TCHAR * line,TCHAR * line1b,TCHAR * line2b)3452 static int cfgfile_separate_line (TCHAR *line, TCHAR *line1b, TCHAR *line2b)
3453 {
3454 	TCHAR *line1, *line2;
3455 	int i;
3456 
3457 	line1 = line;
3458 	line1 += _tcsspn (line1, _T("\t \r\n"));
3459 	if (*line1 == ';')
3460 		return 0;
3461 	line2 = _tcschr (line, '=');
3462 	if (! line2) {
3463 		write_log (_T("CFGFILE: line was incomplete with only %s\n"), line1);
3464 		return 0;
3465 	}
3466 	*line2++ = '\0';
3467 
3468 	/* Get rid of whitespace.  */
3469 	i = _tcslen (line2);
3470 	while (i > 0 && (line2[i - 1] == '\t' || line2[i - 1] == ' '
3471 		|| line2[i - 1] == '\r' || line2[i - 1] == '\n'))
3472 		line2[--i] = '\0';
3473 	line2 += _tcsspn (line2, _T("\t \r\n"));
3474 	_tcscpy (line2b, line2);
3475 	i = _tcslen (line);
3476 	while (i > 0 && (line[i - 1] == '\t' || line[i - 1] == ' '
3477 		|| line[i - 1] == '\r' || line[i - 1] == '\n'))
3478 		line[--i] = '\0';
3479 	line += _tcsspn (line, _T("\t \r\n"));
3480 	_tcscpy (line1b, line);
3481 
3482 	if (line2b[0] == '"' || line2b[0] == '\"') {
3483 		TCHAR c = line2b[0];
3484 		int i = 0;
3485 		memmove (line2b, line2b + 1, (_tcslen (line2b) + 1) * sizeof (TCHAR));
3486 		while (line2b[i] != 0 && line2b[i] != c)
3487 			i++;
3488 		line2b[i] = 0;
3489 	}
3490 
3491 	if (isutf8ext (line1b))
3492 		return 0;
3493 	return 1;
3494 }
3495 
isobsolete(TCHAR * s)3496 static int isobsolete (TCHAR *s)
3497 {
3498 	int i = 0;
3499 	while (obsolete[i]) {
3500 		if (!strcasecmp (s, obsolete[i])) {
3501 			write_log (_T("obsolete config entry '%s'\n"), s);
3502 			return 1;
3503 		}
3504 		i++;
3505 	}
3506 	if (_tcslen (s) > 2 && !_tcsncmp (s, _T("w."), 2))
3507 		return 1;
3508 	if (_tcslen (s) >= 10 && !_tcsncmp (s, _T("gfx_opengl"), 10)) {
3509 		write_log (_T("obsolete config entry '%s\n"), s);
3510 		return 1;
3511 	}
3512 	if (_tcslen (s) >= 6 && !_tcsncmp (s, _T("gfx_3d"), 6)) {
3513 		write_log (_T("obsolete config entry '%s\n"), s);
3514 		return 1;
3515 	}
3516 	return 0;
3517 }
3518 
cfgfile_parse_separated_line(struct uae_prefs * p,TCHAR * line1b,TCHAR * line2b,int type)3519 static void cfgfile_parse_separated_line (struct uae_prefs *p, TCHAR *line1b, TCHAR *line2b, int type)
3520 {
3521 	TCHAR line3b[CONFIG_BLEN], line4b[CONFIG_BLEN];
3522 	struct strlist *sl;
3523 	int ret;
3524 
3525 	_tcscpy (line3b, line1b);
3526 	_tcscpy (line4b, line2b);
3527 	ret = cfgfile_parse_option (p, line1b, line2b, type);
3528 	if (!isobsolete (line3b)) {
3529 		for (sl = p->all_lines; sl; sl = sl->next) {
3530 			if (sl->option && !strcasecmp (line1b, sl->option)) break;
3531 		}
3532 		if (!sl) {
3533 			struct strlist *u = xcalloc (struct strlist, 1);
3534 			u->option = my_strdup (line3b);
3535 			u->value = my_strdup (line4b);
3536 			u->next = p->all_lines;
3537 			p->all_lines = u;
3538 			if (!ret) {
3539 				u->unknown = 1;
3540 				write_log (_T("unknown config entry: '%s=%s'\n"), u->option, u->value);
3541 			}
3542 		}
3543 	}
3544 }
3545 
cfgfile_parse_lines(struct uae_prefs * p,const TCHAR * lines,int type)3546 void cfgfile_parse_lines (struct uae_prefs *p, const TCHAR *lines, int type)
3547 {
3548   TCHAR *buf = my_strdup (lines);
3549   TCHAR *t = buf;
3550   for (;;) {
3551     if (_tcslen (t) == 0)
3552       break;
3553     TCHAR *t2 = _tcschr (t, '\n');
3554     if (t2)
3555       *t2 = 0;
3556     cfgfile_parse_line (p, t, type);
3557     if (!t2)
3558       break;
3559     t = t2 + 1;
3560   }
3561   xfree (buf);
3562 }
3563 
cfgfile_parse_line(struct uae_prefs * p,TCHAR * line,int type)3564 void cfgfile_parse_line (struct uae_prefs *p, TCHAR *line, int type)
3565 {
3566 	TCHAR line1b[CONFIG_BLEN], line2b[CONFIG_BLEN];
3567 
3568 	if (!cfgfile_separate_line (line, line1b, line2b))
3569 		return;
3570 	cfgfile_parse_separated_line (p, line1b, line2b, type);
3571 }
3572 
subst(TCHAR * p,TCHAR * f,int n)3573 static void subst (TCHAR *p, TCHAR *f, int n)
3574 {
3575 	TCHAR *str = cfgfile_subst_path (UNEXPANDED, p, f);
3576 	_tcsncpy (f, str, n - 1);
3577 	f[n - 1] = '\0';
3578 	xfree (str);
3579 }
3580 
getconfigstoreline(const TCHAR * option,TCHAR * value)3581 static int getconfigstoreline (const TCHAR *option, TCHAR *value)
3582 {
3583 	TCHAR tmp[CONFIG_BLEN * 2], tmp2[CONFIG_BLEN * 2];
3584 	int idx = 0;
3585 
3586 	if (!configstore)
3587 		return 0;
3588 	zfile_fseek (configstore, 0, SEEK_SET);
3589 	for (;;) {
3590 		if (!zfile_fgets (tmp, sizeof tmp / sizeof (TCHAR), configstore))
3591 			return 0;
3592 		if (!cfgfile_separate_line (tmp, tmp2, value))
3593 			continue;
3594 		if (!_tcsicmp (option, tmp2))
3595 			return 1;
3596 	}
3597 }
3598 
createconfigstore(struct uae_prefs * p)3599 static bool createconfigstore (struct uae_prefs *p)
3600 {
3601 	uae_u8 zeros[4] = { 0 };
3602 	zfile_fclose (configstore);
3603 	configstore = zfile_fopen_empty (NULL, _T("configstore"), 50000);
3604 	if (!configstore)
3605 		return false;
3606 	zfile_fseek (configstore, 0, SEEK_SET);
3607 	uaeconfig++;
3608 	cfgfile_save_options (configstore, p, 0);
3609 	uaeconfig--;
3610 	zfile_fwrite (zeros, 1, sizeof zeros, configstore);
3611 	zfile_fseek (configstore, 0, SEEK_SET);
3612 	return true;
3613 }
3614 
cfg_fgets(char * line,int max,struct zfile * fh)3615 static char *cfg_fgets (char *line, int max, struct zfile *fh)
3616 {
3617 #ifdef SINGLEFILE
3618 	extern TCHAR singlefile_config[];
3619 	static TCHAR *sfile_ptr;
3620 	TCHAR *p;
3621 #endif
3622 
3623 	if (fh)
3624 		return zfile_fgetsa (line, max, fh);
3625 #ifdef SINGLEFILE
3626 	if (sfile_ptr == 0) {
3627 		sfile_ptr = singlefile_config;
3628 		if (*sfile_ptr) {
3629 			write_log (_T("singlefile config found\n"));
3630 			while (*sfile_ptr++);
3631 		}
3632 	}
3633 	if (*sfile_ptr == 0) {
3634 		sfile_ptr = singlefile_config;
3635 		return 0;
3636 	}
3637 	p = sfile_ptr;
3638 	while (*p != 13 && *p != 10 && *p != 0) p++;
3639 	memset (line, 0, max);
3640 	memcpy (line, sfile_ptr, (p - sfile_ptr) * sizeof (TCHAR));
3641 	sfile_ptr = p + 1;
3642 	if (*sfile_ptr == 13)
3643 		sfile_ptr++;
3644 	if (*sfile_ptr == 10)
3645 		sfile_ptr++;
3646 	return line;
3647 #endif
3648 	return 0;
3649 }
3650 
cfgfile_load_2(struct uae_prefs * p,const TCHAR * filename,bool real,int * type)3651 static int cfgfile_load_2 (struct uae_prefs *p, const TCHAR *filename, bool real, int *type)
3652 {
3653 	int i;
3654 	struct zfile *fh;
3655 	char linea[CONFIG_BLEN];
3656 	TCHAR line[CONFIG_BLEN], line1b[CONFIG_BLEN], line2b[CONFIG_BLEN];
3657 	struct strlist *sl;
3658 	bool type1 = false, type2 = false;
3659 	int askedtype = 0;
3660 
3661 	if (type) {
3662 		askedtype = *type;
3663 		*type = 0;
3664 	}
3665 	if (real) {
3666 		p->config_version = 0;
3667 		config_newfilesystem = 0;
3668 		//reset_inputdevice_config (p);
3669 	}
3670 
3671 	write_log ("Opening cfgfile '%s': ", filename);
3672 	fh = zfile_fopen (filename, _T("r"), ZFD_NORMAL);
3673 #ifndef	SINGLEFILE
3674 	if (! fh) {
3675 		write_log ("failed\n");
3676 		return 0;
3677 	}
3678 #endif
3679 	write_log ("OK\n");
3680 
3681 	while (cfg_fgets (linea, sizeof (linea), fh) != 0) {
3682 		trimwsa (linea);
3683 		if (strlen (linea) > 0) {
3684 			if (linea[0] == '#' || linea[0] == ';') {
3685 				struct strlist *u = xcalloc (struct strlist, 1);
3686 				u->option = NULL;
3687 				TCHAR *com = au (linea);
3688 				u->value = my_strdup (com);
3689 				xfree (com);
3690 				u->unknown = 1;
3691 				u->next = p->all_lines;
3692 				p->all_lines = u;
3693 				continue;
3694 			}
3695 			if (!cfgfile_separate_linea (filename, linea, line1b, line2b))
3696 				continue;
3697 			type1 = type2 = 0;
3698 			if (cfgfile_yesno (line1b, line2b, _T("config_hardware"), &type1) ||
3699 				cfgfile_yesno (line1b, line2b, _T("config_host"), &type2)) {
3700 					if (type1 && type)
3701 						*type |= CONFIG_TYPE_HARDWARE;
3702 					if (type2 && type)
3703 						*type |= CONFIG_TYPE_HOST;
3704 					continue;
3705 			}
3706 			if (real) {
3707 				cfgfile_parse_separated_line (p, line1b, line2b, askedtype);
3708 			} else {
3709 				cfgfile_string (line1b, line2b, _T("config_description"), p->description, sizeof p->description / sizeof (TCHAR));
3710 				cfgfile_path (line1b, line2b, _T("config_hardware_path"), p->config_hardware_path, sizeof p->config_hardware_path / sizeof (TCHAR));
3711 				cfgfile_path (line1b, line2b, _T("config_host_path"), p->config_host_path, sizeof p->config_host_path / sizeof (TCHAR));
3712 				cfgfile_string (line1b, line2b, _T("config_window_title"), p->config_window_title, sizeof p->config_window_title / sizeof (TCHAR));
3713 			}
3714 		}
3715 	}
3716 
3717 	if (type && *type == 0)
3718 		*type = CONFIG_TYPE_HARDWARE | CONFIG_TYPE_HOST;
3719 	if (fh)
3720 		zfile_fclose (fh);
3721 
3722 	if (!real)
3723 		return 1;
3724 
3725 	for (sl = temp_lines; sl; sl = sl->next) {
3726 		_stprintf (line, _T("%s=%s"), sl->option, sl->value);
3727 		cfgfile_parse_line (p, line, 0);
3728 	}
3729 
3730 	for (i = 0; i < 4; i++)
3731 		subst (p->path_floppy.path[0], p->floppyslots[i].df, sizeof p->floppyslots[i].df / sizeof (TCHAR));
3732 	subst (p->path_rom.path[0], p->romfile, sizeof p->romfile / sizeof (TCHAR));
3733 	subst (p->path_rom.path[0], p->romextfile, sizeof p->romextfile / sizeof (TCHAR));
3734 	subst (p->path_rom.path[0], p->romextfile2, sizeof p->romextfile2 / sizeof (TCHAR));
3735 
3736 	return 1;
3737 }
3738 
cfgfile_load(struct uae_prefs * p,const TCHAR * filename,int * type,int ignorelink,int userconfig)3739 int cfgfile_load (struct uae_prefs *p, const TCHAR *filename, int *type, int ignorelink, int userconfig)
3740 {
3741 	int v;
3742 	TCHAR tmp[MAX_DPATH];
3743 	int type2;
3744 	static int recursive;
3745 
3746 	memset(tmp, 0, MAX_DPATH * sizeof(TCHAR));
3747 
3748 	if (recursive > 1)
3749 		return 0;
3750 	recursive++;
3751 	write_log (_T("load config '%s':%d\n"), filename, type ? *type : -1);
3752 	v = cfgfile_load_2 (p, filename, 1, type);
3753 	if (!v) {
3754 		write_log (_T("load failed\n"));
3755 		goto end;
3756 	}
3757 
3758 
3759 	if (!ignorelink) {
3760 		size_t rest_len = 0;
3761 		if (p->config_hardware_path[0]) {
3762 			fetch_configurationpath (tmp, MAX_DPATH - 1);
3763 			rest_len = MAX_DPATH - 1 - _tcslen(tmp);
3764 			_tcsncat (tmp, p->config_hardware_path, rest_len );
3765 			type2 = CONFIG_TYPE_HARDWARE;
3766 			cfgfile_load (p, tmp, &type2, 1, 0);
3767 		}
3768 		if (p->config_host_path[0]) {
3769 			fetch_configurationpath (tmp, MAX_DPATH - 1);
3770 			rest_len = MAX_DPATH - 1 - _tcslen(tmp);
3771 			_tcsncat (tmp, p->config_host_path, rest_len );
3772 			type2 = CONFIG_TYPE_HOST;
3773 			cfgfile_load (p, tmp, &type2, 1, 0);
3774 		}
3775 	}
3776 end:
3777 	recursive--;
3778 	fixup_prefs (p);
3779 	return v;
3780 }
3781 
cfgfile_backup(const TCHAR * path)3782 void cfgfile_backup (const TCHAR *path)
3783 {
3784 	TCHAR dpath[MAX_DPATH];
3785 
3786 	fetch_configurationpath (dpath, sizeof (dpath) / sizeof (TCHAR));
3787 	_tcscat (dpath, _T("configuration.backup"));
3788 	//bool hidden = my_isfilehidden (dpath);
3789 	my_unlink (dpath);
3790 	my_rename (path, dpath);
3791 	//if (hidden)
3792 		//my_setfilehidden (dpath, hidden);
3793 }
3794 
cfgfile_save(struct uae_prefs * p,const TCHAR * filename,int type)3795 int cfgfile_save (struct uae_prefs *p, const TCHAR *filename, int type)
3796 {
3797 	struct zfile *fh;
3798 
3799 	cfgfile_backup (filename);
3800 	fh = zfile_fopen (filename, unicode_config ? _T("w, ccs=UTF-8") : _T("w"), ZFD_NORMAL);
3801 	if (! fh)
3802 		return 0;
3803 
3804 	if (!type)
3805 		type = CONFIG_TYPE_HARDWARE | CONFIG_TYPE_HOST;
3806 	cfgfile_save_options (fh, p, type);
3807 	zfile_fclose (fh);
3808 	return 1;
3809 }
3810 
cfgfile_get_description(const TCHAR * filename,TCHAR * description,TCHAR * hostlink,TCHAR * hardwarelink,int * type)3811 int cfgfile_get_description (const TCHAR *filename, TCHAR *description, TCHAR *hostlink, TCHAR *hardwarelink, int *type)
3812 {
3813 	int result = 0;
3814 	struct uae_prefs *p = xmalloc (struct uae_prefs, 1);
3815 
3816 	p->description[0] = 0;
3817 	p->config_host_path[0] = 0;
3818 	p->config_hardware_path[0] = 0;
3819 	if (cfgfile_load_2 (p, filename, 0, type)) {
3820 		result = 1;
3821 		if (description)
3822 			_tcscpy (description, p->description);
3823 		if (hostlink)
3824 			_tcscpy (hostlink, p->config_host_path);
3825 		if (hardwarelink)
3826 			_tcscpy (hardwarelink, p->config_hardware_path);
3827 	}
3828 	xfree (p);
3829 	return result;
3830 }
3831 
cfgfile_configuration_change(int v)3832 int cfgfile_configuration_change (int v)
3833 {
3834 	static int mode;
3835 	if (v >= 0)
3836 		mode = v;
3837 	return mode;
3838 }
3839 
cfgfile_show_usage(void)3840 void cfgfile_show_usage (void)
3841 {
3842 	size_t i = 0;
3843 	write_log (_T("UAE Configuration Help:\n"));
3844 	write_log (_T("=======================\n"));
3845 	for (; i < sizeof opttable / sizeof *opttable; i++)
3846 		write_log (_T("%s: %s\n"), opttable[i].config_label, opttable[i].config_help);
3847 }
3848 
3849 /* This implements the old commandline option parsing.  I've re-added this
3850    because the new way of doing things is painful for me (it requires me
3851    to type a couple hundred characters when invoking UAE).  The following
3852    is far less annoying to use.  */
parse_gfx_specs(struct uae_prefs * p,const TCHAR * spec)3853 static void parse_gfx_specs (struct uae_prefs *p, const TCHAR *spec)
3854 {
3855 	TCHAR *x0 = my_strdup (spec);
3856 	TCHAR *x1, *x2;
3857 
3858 	x1 = _tcschr (x0, ':');
3859 	if (x1 == 0)
3860 		goto argh;
3861 	x2 = _tcschr (x1+1, ':');
3862 	if (x2 == 0)
3863 		goto argh;
3864 	*x1++ = 0; *x2++ = 0;
3865 
3866 	p->gfx_size_win.width = p->gfx_size_fs.width = _tstoi (x0);
3867 	p->gfx_size_win.height = p->gfx_size_fs.height = _tstoi (x1);
3868 	p->gfx_resolution = _tcschr (x2, 'l') != 0 ? 1 : 0;
3869 	p->gfx_xcenter = _tcschr (x2, 'x') != 0 ? 1 : _tcschr (x2, 'X') != 0 ? 2 : 0;
3870 	p->gfx_ycenter = _tcschr (x2, 'y') != 0 ? 1 : _tcschr (x2, 'Y') != 0 ? 2 : 0;
3871 	p->gfx_vresolution = _tcschr (x2, 'd') != 0 ? VRES_DOUBLE : VRES_NONDOUBLE;
3872 	p->gfx_scanlines = _tcschr (x2, 'D') != 0;
3873 	if (p->gfx_scanlines)
3874 		p->gfx_vresolution = VRES_DOUBLE;
3875 	p->gfx_apmode[0].gfx_fullscreen = _tcschr (x2, 'a') != 0;
3876 	p->gfx_apmode[1].gfx_fullscreen = _tcschr (x2, 'p') != 0;
3877 
3878 	xfree (x0);
3879 	return;
3880 
3881 argh:
3882 	write_log (_T("Bad display mode specification.\n"));
3883 	write_log (_T("The format to use is: \"width:height:modifiers\"\n"));
3884 	write_log (_T("Type \"uae -h\" for detailed help.\n"));
3885 	xfree (x0);
3886 }
3887 
parse_sound_spec(struct uae_prefs * p,const TCHAR * spec)3888 static void parse_sound_spec (struct uae_prefs *p, const TCHAR *spec)
3889 {
3890 	TCHAR *x0 = my_strdup (spec);
3891 	TCHAR *x1, *x2 = NULL, *x3 = NULL, *x4 = NULL, *x5 = NULL;
3892 
3893 	x1 = _tcschr (x0, ':');
3894 	if (x1 != NULL) {
3895 		*x1++ = '\0';
3896 		x2 = _tcschr (x1 + 1, ':');
3897 		if (x2 != NULL) {
3898 			*x2++ = '\0';
3899 			x3 = _tcschr (x2 + 1, ':');
3900 			if (x3 != NULL) {
3901 				*x3++ = '\0';
3902 				x4 = _tcschr (x3 + 1, ':');
3903 				if (x4 != NULL) {
3904 					*x4++ = '\0';
3905 					x5 = _tcschr (x4 + 1, ':');
3906 				}
3907 			}
3908 		}
3909 	}
3910 	p->produce_sound = _tstoi (x0);
3911 	if (x1) {
3912 		p->sound_stereo_separation = 0;
3913 		if (*x1 == 'S') {
3914 			p->sound_stereo = SND_STEREO;
3915 			p->sound_stereo_separation = 7;
3916 		} else if (*x1 == 's')
3917 			p->sound_stereo = SND_STEREO;
3918 		else
3919 			p->sound_stereo = SND_MONO;
3920 	}
3921 	if (x3)
3922 		p->sound_freq = _tstoi (x3);
3923 	if (x4)
3924 		p->sound_maxbsiz = _tstoi (x4);
3925 	xfree (x0);
3926 }
3927 
3928 
parse_joy_spec(struct uae_prefs * p,const TCHAR * spec)3929 static void parse_joy_spec (struct uae_prefs *p, const TCHAR *spec)
3930 {
3931 	int v0 = 2, v1 = 0;
3932 	if (_tcslen(spec) != 2)
3933 		goto bad;
3934 
3935 	switch (spec[0]) {
3936 	case '0': v0 = JSEM_JOYS; break;
3937 	case '1': v0 = JSEM_JOYS + 1; break;
3938 	case 'M': case 'm': v0 = JSEM_MICE; break;
3939 	case 'A': case 'a': v0 = JSEM_KBDLAYOUT; break;
3940 	case 'B': case 'b': v0 = JSEM_KBDLAYOUT + 1; break;
3941 	case 'C': case 'c': v0 = JSEM_KBDLAYOUT + 2; break;
3942 	default: goto bad;
3943 	}
3944 
3945 	switch (spec[1]) {
3946 	case '0': v1 = JSEM_JOYS; break;
3947 	case '1': v1 = JSEM_JOYS + 1; break;
3948 	case 'M': case 'm': v1 = JSEM_MICE; break;
3949 	case 'A': case 'a': v1 = JSEM_KBDLAYOUT; break;
3950 	case 'B': case 'b': v1 = JSEM_KBDLAYOUT + 1; break;
3951 	case 'C': case 'c': v1 = JSEM_KBDLAYOUT + 2; break;
3952 	default: goto bad;
3953 	}
3954 	if (v0 == v1)
3955 		goto bad;
3956 	/* Let's scare Pascal programmers */
3957 	if (0)
3958 bad:
3959 	write_log (_T("Bad joystick mode specification. Use -J xy, where x and y\n"));
3960 	write_log (_T("can be 0 for joystick 0, 1 for joystick 1, M for mouse, and\n"));
3961 	write_log (_T("a, b or c for different keyboard settings.\n"));
3962 
3963 	p->jports[0].id = v0;
3964 	p->jports[1].id = v1;
3965 }
3966 
parse_filesys_spec(struct uae_prefs * p,bool readonly,const TCHAR * spec)3967 static void parse_filesys_spec (struct uae_prefs *p, bool readonly, const TCHAR *spec)
3968 {
3969 	struct uaedev_config_info uci;
3970 	TCHAR buf[256];
3971 	TCHAR *s2;
3972 
3973 	uci_set_defaults (&uci, false);
3974 	_tcsncpy (buf, spec, 255); buf[255] = 0;
3975 	s2 = _tcschr (buf, ':');
3976 	if (s2) {
3977 		*s2++ = '\0';
3978 #ifdef __DOS__
3979 		{
3980 			TCHAR *tmp;
3981 
3982 			while ((tmp = _tcschr (s2, '\\')))
3983 				*tmp = '/';
3984 		}
3985 #endif
3986 #ifdef FILESYS
3987 		_tcscpy (uci.volname, buf);
3988 		_tcscpy (uci.rootdir, s2);
3989 		uci.readonly = readonly;
3990 		uci.type = UAEDEV_DIR;
3991 		add_filesys_config (p, -1, &uci);
3992 #endif
3993 	} else {
3994 		write_log (_T("Usage: [-m | -M] VOLNAME:mount_point\n"));
3995 	}
3996 }
3997 
parse_hardfile_spec(struct uae_prefs * p,const TCHAR * spec)3998 static void parse_hardfile_spec (struct uae_prefs *p, const TCHAR *spec)
3999 {
4000 	struct uaedev_config_info uci;
4001 	TCHAR *x0 = my_strdup (spec);
4002 	TCHAR *x1, *x2, *x3, *x4;
4003 
4004 	uci_set_defaults (&uci, false);
4005 	x1 = _tcschr (x0, ':');
4006 	if (x1 == NULL)
4007 		goto argh;
4008 	*x1++ = '\0';
4009 	x2 = _tcschr (x1 + 1, ':');
4010 	if (x2 == NULL)
4011 		goto argh;
4012 	*x2++ = '\0';
4013 	x3 = _tcschr (x2 + 1, ':');
4014 	if (x3 == NULL)
4015 		goto argh;
4016 	*x3++ = '\0';
4017 	x4 = _tcschr (x3 + 1, ':');
4018 	if (x4 == NULL)
4019 		goto argh;
4020 	*x4++ = '\0';
4021 #ifdef FILESYS
4022 	_tcscpy (uci.rootdir, x4);
4023 #endif
4024 	xfree (x0);
4025 	return;
4026 
4027 argh:
4028 	xfree (x0);
4029 	write_log (_T("Bad hardfile parameter specified - type \"uae -h\" for help.\n"));
4030 	return;
4031 }
4032 
parse_cpu_specs(struct uae_prefs * p,const TCHAR * spec)4033 static void parse_cpu_specs (struct uae_prefs *p, const TCHAR *spec)
4034 {
4035 	if (*spec < '0' || *spec > '4') {
4036 		write_log (_T("CPU parameter string must begin with '0', '1', '2', '3' or '4'.\n"));
4037 		return;
4038 	}
4039 
4040 	//p->cpu_model = (*spec++) * 10 + 68000;
4041 	p->cpu_model = atoi(spec) * 10 + 68000;
4042 	p->address_space_24 = p->cpu_model < 68020;
4043 	p->cpu_compatible = 0;
4044 	while (*spec != '\0') {
4045 		switch (*spec) {
4046 		case 'a':
4047 			if (p->cpu_model < 68020)
4048 				write_log (_T("In 68000/68010 emulation, the address space is always 24 bit.\n"));
4049 			else if (p->cpu_model >= 68040)
4050 				write_log (_T("In 68040/060 emulation, the address space is always 32 bit.\n"));
4051 			else
4052 				p->address_space_24 = 1;
4053 			break;
4054 		case 'c':
4055 			if (p->cpu_model != 68000)
4056 				write_log (_T("The more compatible CPU emulation is only available for 68000\nemulation, not for 68010 upwards.\n"));
4057 			else
4058 				p->cpu_compatible = 1;
4059 			break;
4060 		default:
4061 			write_log (_T("Bad CPU parameter specified - type \"uae -h\" for help.\n"));
4062 			break;
4063 		}
4064 		spec++;
4065 	}
4066 }
4067 
cmdpath(TCHAR * dst,const TCHAR * src,int maxsz)4068 static void cmdpath (TCHAR *dst, const TCHAR *src, int maxsz)
4069 {
4070 	_tcsncpy (dst, src, maxsz);
4071 	dst[maxsz] = 0;
4072 }
4073 
4074 /* Returns the number of args used up (0 or 1).  */
parse_cmdline_option(struct uae_prefs * p,TCHAR c,const TCHAR * arg)4075 int parse_cmdline_option (struct uae_prefs *p, TCHAR c, const TCHAR *arg)
4076 {
4077 	struct strlist *u = xcalloc (struct strlist, 1);
4078 	const TCHAR arg_required[] = "0123rKpImWSAJwNCZUFcblOdHRv";
4079 
4080 	if (_tcschr (arg_required, c) && ! arg) {
4081 		write_log (_T("Missing argument for option `-%c'!\n"), c);
4082 		return 0;
4083 	}
4084 
4085 	u->option = xmalloc (TCHAR, 2);
4086 	u->option[0] = c;
4087 	u->option[1] = 0;
4088 	u->value = my_strdup (arg);
4089 	u->next = p->all_lines;
4090 	p->all_lines = u;
4091 
4092 	switch (c) {
4093 	case 'h': usage (); exit (0);
4094 
4095 	case '0': cmdpath (p->floppyslots[0].df, arg, 255); break;
4096 	case '1': cmdpath (p->floppyslots[1].df, arg, 255); break;
4097 	case '2': cmdpath (p->floppyslots[2].df, arg, 255); break;
4098 	case '3': cmdpath (p->floppyslots[3].df, arg, 255); break;
4099 	case 'r': cmdpath (p->romfile, arg, 255); break;
4100 	case 'K': cmdpath (p->romextfile, arg, 255); break;
4101 	case 'p': _tcsncpy (p->prtname, arg, 255); p->prtname[255] = 0; break;
4102 	case 'I': cmdpath (p->sername, arg, 255); currprefs.use_serial = 1; break;
4103 	case 'm': case 'M': parse_filesys_spec (p, c == 'M', arg); break;
4104 	case 'W': parse_hardfile_spec (p, arg); break;
4105 	case 'S': parse_sound_spec (p, arg); break;
4106 	case 'R': p->gfx_framerate = _tstoi (arg); break;
4107 	case 'i': p->illegal_mem = 1; break;
4108 	case 'J': parse_joy_spec (p, arg); break;
4109 
4110 #if defined USE_X11_GFX
4111 	case 'L': p->x11_use_low_bandwidth = 1; break;
4112 	case 'T': p->x11_use_mitshm = 1; break;
4113 #elif defined USE_AMIGA_GFX
4114 	case 'T': p->amiga_use_grey = 1; break;
4115 	case 'x': p->amiga_use_dither = 0; break;
4116 #elif defined USE_CURSES_GFX
4117 	case 'x': p->curses_reverse_video = 1; break;
4118 #endif
4119 	case 'w': p->m68k_speed = _tstoi (arg); break;
4120 
4121 	/* case 'g': p->use_gfxlib = 1; break; */
4122 	case 'G': p->start_gui = 0; break;
4123 #ifdef DEBUGGER
4124 	case 'D': p->start_debugger = 1; break;
4125 #endif
4126 
4127 	case 'n':
4128 		if (_tcschr (arg, 'i') != 0)
4129 			p->immediate_blits = 1;
4130 		break;
4131 
4132 	case 'v':
4133 		set_chipset_mask (p, _tstoi (arg));
4134 		break;
4135 
4136 	case 'C':
4137 		parse_cpu_specs (p, arg);
4138 		break;
4139 
4140 	case 'Z':
4141 		p->z3fastmem_size = _tstoi (arg) * 0x100000;
4142 		break;
4143 
4144 	case 'U':
4145 		p->rtgmem_size = _tstoi (arg) * 0x100000;
4146 		break;
4147 
4148 	case 'F':
4149 		p->fastmem_size = _tstoi (arg) * 0x100000;
4150 		break;
4151 
4152 	case 'b':
4153 		p->bogomem_size = _tstoi (arg) * 0x40000;
4154 		break;
4155 
4156 	case 'c':
4157 		p->chipmem_size = _tstoi (arg) * 0x80000;
4158 		break;
4159 
4160 	case 'l':
4161 		if (0 == strcasecmp(arg, _T("de")))
4162 			p->keyboard_lang = KBD_LANG_DE;
4163 		else if (0 == strcasecmp(arg, _T("dk")))
4164 			p->keyboard_lang = KBD_LANG_DK;
4165 		else if (0 == strcasecmp(arg, _T("us")))
4166 			p->keyboard_lang = KBD_LANG_US;
4167 		else if (0 == strcasecmp(arg, _T("se")))
4168 			p->keyboard_lang = KBD_LANG_SE;
4169 		else if (0 == strcasecmp(arg, _T("fr")))
4170 			p->keyboard_lang = KBD_LANG_FR;
4171 		else if (0 == strcasecmp(arg, _T("it")))
4172 			p->keyboard_lang = KBD_LANG_IT;
4173 		else if (0 == strcasecmp(arg, _T("es")))
4174 			p->keyboard_lang = KBD_LANG_ES;
4175 		else if (0 == strcasecmp(arg, _T("fi")))
4176 			p->keyboard_lang = KBD_LANG_FI;
4177 		else if (0 == strcasecmp(arg, _T("tr")))
4178 			p->keyboard_lang = KBD_LANG_TR;
4179 		break;
4180 
4181 	case 'O': parse_gfx_specs (p, arg); break;
4182 	case 'd':
4183 		if (_tcschr (arg, 'S') != NULL || _tcschr (arg, 's')) {
4184 			write_log (_T("  Serial on demand.\n"));
4185 			p->serial_demand = 1;
4186 		}
4187 		if (_tcschr (arg, 'P') != NULL || _tcschr (arg, 'p')) {
4188 			write_log (_T("  Parallel on demand.\n"));
4189 			p->parallel_demand = 1;
4190 		}
4191 
4192 		break;
4193 
4194 	case 'H':
4195 #ifndef USE_AMIGA_GFX
4196 		p->color_mode = _tstoi (arg);
4197 		if (p->color_mode < 0) {
4198 			write_log (_T("Bad color mode selected. Using default.\n"));
4199 			p->color_mode = 0;
4200 		}
4201 #else
4202 	p->amiga_screen_type = atoi (arg);
4203 	if (p->amiga_screen_type < 0 || p->amiga_screen_type > 2) {
4204 	    write_log (_T("Bad screen-type selected. Defaulting to public screen.\n"));
4205 	    p->amiga_screen_type = 2;
4206 	}
4207 #endif
4208 		break;
4209 	default:
4210 		write_log (_T("Unknown option `-%c'!\n"), c);
4211 		break;
4212 	}
4213 	return !! _tcschr (arg_required, c);
4214 }
4215 
cfgfile_addcfgparam(TCHAR * line)4216 void cfgfile_addcfgparam (TCHAR *line)
4217 {
4218 	struct strlist *u;
4219 	TCHAR line1b[CONFIG_BLEN], line2b[CONFIG_BLEN];
4220 
4221 	if (!line) {
4222 		struct strlist **ps = &temp_lines;
4223 		while (*ps) {
4224 			struct strlist *s = *ps;
4225 			*ps = s->next;
4226 			xfree (s->value);
4227 			xfree (s->option);
4228 			xfree (s);
4229 		}
4230 		temp_lines = 0;
4231 		return;
4232 	}
4233 	if (!cfgfile_separate_line (line, line1b, line2b))
4234 		return;
4235 	u = xcalloc (struct strlist, 1);
4236 	u->option = my_strdup (line1b);
4237 	u->value = my_strdup (line2b);
4238 	u->next = temp_lines;
4239 	temp_lines = u;
4240 }
4241 
4242 #if 0
4243 static int cfgfile_handle_custom_event (TCHAR *custom, int mode)
4244 {
4245 	TCHAR option[CONFIG_BLEN], value[CONFIG_BLEN];
4246 	TCHAR option2[CONFIG_BLEN], value2[CONFIG_BLEN];
4247 	TCHAR *tmp, *p, *nextp;
4248 	struct zfile *configstore = NULL;
4249 	int cnt = 0, cnt_ok = 0;
4250 
4251 	if (!mode) {
4252 		TCHAR zero = 0;
4253 		configstore = zfile_fopen_empty ("configstore", 50000);
4254 		cfgfile_save_options (configstore, &currprefs, 0);
4255 		cfg_write (&zero, configstore);
4256 	}
4257 
4258 	nextp = NULL;
4259 	tmp = p = xcalloc (TCHAR, _tcslen (custom) + 2);
4260 	_tcscpy (tmp, custom);
4261 	while (p && *p) {
4262 		if (*p == '\"') {
4263 			TCHAR *p2;
4264 			p++;
4265 			p2 = p;
4266 			while (*p2 != '\"' && *p2 != 0)
4267 				p2++;
4268 			if (*p2 == '\"') {
4269 				*p2++ = 0;
4270 				nextp = p2 + 1;
4271 				if (*nextp == ' ')
4272 					nextp++;
4273 			}
4274 		}
4275 		if (cfgfile_separate_line (p, option, value)) {
4276 			cnt++;
4277 			if (mode) {
4278 				cfgfile_parse_option (&changed_prefs, option, value, 0);
4279 			} else {
4280 				zfile_fseek (configstore, 0, SEEK_SET);
4281 				for (;;) {
4282 					if (!getconfigstoreline (configstore, option2, value2))
4283 						break;
4284 					if (!_tcscmpi (option, option2) && !_tcscmpi (value, value2)) {
4285 						cnt_ok++;
4286 						break;
4287 					}
4288 				}
4289 			}
4290 		}
4291 		p = nextp;
4292 	}
4293 	xfree (tmp);
4294 	zfile_fclose (configstore);
4295 	if (cnt > 0 && cnt == cnt_ok)
4296 		return 1;
4297 	return 0;
4298 }
4299 #endif
4300 
cmdlineparser(const TCHAR * s,TCHAR * outp[],int max)4301 int cmdlineparser (const TCHAR *s, TCHAR *outp[], int max)
4302 {
4303 	int j, cnt = 0;
4304 	int slash = 0;
4305 	int quote = 0;
4306 	TCHAR tmp1[MAX_DPATH];
4307 	const TCHAR *prev;
4308 	int doout;
4309 
4310 	doout = 0;
4311 	prev = s;
4312 	j = 0;
4313 	outp[0] = 0;
4314 	while (cnt < max) {
4315 		TCHAR c = *s++;
4316 		if (!c)
4317 			break;
4318 		if (c < 32)
4319 			continue;
4320 		if (c == '\\')
4321 			slash = 1;
4322 		if (!slash && c == '"') {
4323 			if (quote) {
4324 				quote = 0;
4325 				doout = 1;
4326 			} else {
4327 				quote = 1;
4328 				j = -1;
4329 			}
4330 		}
4331 		if (!quote && c == ' ')
4332 			doout = 1;
4333 		if (!doout) {
4334 			if (j >= 0) {
4335 				tmp1[j] = c;
4336 				tmp1[j + 1] = 0;
4337 			}
4338 			j++;
4339 		}
4340 		if (doout) {
4341 			if (_tcslen (tmp1) > 0) {
4342 				outp[cnt++] = my_strdup (tmp1);
4343 				outp[cnt] = 0;
4344 			}
4345 			tmp1[0] = 0;
4346 			doout = 0;
4347 			j = 0;
4348 		}
4349 		slash = 0;
4350 	}
4351 	if (j > 0 && cnt < max) {
4352 		outp[cnt++] = my_strdup (tmp1);
4353 		outp[cnt] = 0;
4354 	}
4355 	return cnt;
4356 }
4357 
4358 #define UAELIB_MAX_PARSE 100
4359 
cfgfile_parse_uaelib_option(struct uae_prefs * p,TCHAR * option,TCHAR * value,int type)4360 static bool cfgfile_parse_uaelib_option (struct uae_prefs *p, TCHAR *option, TCHAR *value, int type)
4361 {
4362 	return false;
4363 }
4364 
cfgfile_modify(uae_u32 index,TCHAR * parms,uae_u32 size,TCHAR * out,uae_u32 outsize)4365 uae_u32 cfgfile_modify (uae_u32 index, TCHAR *parms, uae_u32 size, TCHAR *out, uae_u32 outsize)
4366 {
4367 	TCHAR *p;
4368 	TCHAR *argc[UAELIB_MAX_PARSE];
4369 	uae_u32 err;
4370 	size_t argv = 0, i = 0, j = 0;
4371 	TCHAR zero = 0;
4372 	static TCHAR *configsearch;
4373 	static int configsearchfound;
4374 
4375 	config_changed = 1;
4376 	err = 0;
4377 	argv = 0;
4378 	p = 0;
4379 	if (index != 0xffffffff) {
4380 		if (!configstore) {
4381 			err = 20;
4382 			goto end;
4383 		}
4384 		if (configsearch) {
4385 			TCHAR tmp[CONFIG_BLEN];
4386 			TCHAR *in = configsearch;
4387 			size_t inlen = _tcslen (configsearch);
4388 			int joker = 0;
4389 
4390 			if (in[inlen - 1] == '*') {
4391 				joker = 1;
4392 				inlen--;
4393 			}
4394 
4395 			for (;;) {
4396 				uae_u8 b = 0;
4397 
4398 				if (zfile_fread (&b, 1, 1, configstore) != 1) {
4399 					err = 10;
4400 					if (configsearch)
4401 						err = 5;
4402 					if (configsearchfound)
4403 						err = 0;
4404 					goto end;
4405 				}
4406 				if (j >= sizeof (tmp) / sizeof (TCHAR) - 1)
4407 					j = sizeof (tmp) / sizeof (TCHAR) - 1;
4408 				if (b == 0) {
4409 					err = 10;
4410 					if (configsearch)
4411 						err = 5;
4412 					if (configsearchfound)
4413 						err = 0;
4414 					goto end;
4415 				}
4416 				if (b == '\n') {
4417 					if (configsearch && !_tcsncmp (tmp, in, inlen) &&
4418 						((inlen > 0 && _tcslen (tmp) > inlen && tmp[inlen] == '=') || (joker))) {
4419 							TCHAR *p;
4420 							if (joker)
4421 								p = tmp - 1;
4422 							else
4423 								p = _tcschr (tmp, '=');
4424 							if (p) {
4425 								for (i = 0; out && i < outsize - 1; i++) {
4426 									TCHAR b = *++p;
4427 									out[i] = b;
4428 									out[i + 1] = 0;
4429 									if (!b)
4430 										break;
4431 								}
4432 							}
4433 							err = 0xffffffff;
4434 							configsearchfound++;
4435 							goto end;
4436 					}
4437 					index--;
4438 					j = 0;
4439 				} else {
4440 					tmp[j++] = b;
4441 					tmp[j] = 0;
4442 				}
4443 			}
4444 		}
4445 		err = 0xffffffff;
4446 		for (i = 0; out && i < outsize - 1; i++) {
4447 			uae_u8 b = 0;
4448 			if (zfile_fread (&b, 1, 1, configstore) != 1)
4449 				err = 0;
4450 			if (b == 0)
4451 				err = 0;
4452 			if (b == '\n')
4453 				b = 0;
4454 			out[i] = b;
4455 			out[i + 1] = 0;
4456 			if (!b)
4457 				break;
4458 		}
4459 		goto end;
4460 	}
4461 
4462 	if (size > 10000)
4463 		return 10;
4464 	argv = cmdlineparser (parms, argc, UAELIB_MAX_PARSE);
4465 
4466 	if (argv <= 1 && index == 0xffffffff) {
4467 		createconfigstore (&currprefs);
4468 		xfree (configsearch);
4469 		configsearch = NULL;
4470 		if (!configstore) {
4471 			err = 20;
4472 			goto end;
4473 		}
4474 		if (argv > 0 && _tcslen (argc[0]) > 0)
4475 			configsearch = my_strdup (argc[0]);
4476 		err = 0xffffffff;
4477 		configsearchfound = 0;
4478 		goto end;
4479 	}
4480 
4481 	for (i = 0; i < argv; i++) {
4482 		if (i + 2 <= argv) {
4483 			if (!_tcsicmp (argc[i], _T("dbg"))) {
4484 				debug_parser (argc[i + 1], out, outsize);
4485 			} else if (!inputdevice_uaelib (argc[i], argc[i + 1])) {
4486 				if (!cfgfile_parse_uaelib_option (&changed_prefs, argc[i], argc[i + 1], 0)) {
4487 				if (!cfgfile_parse_option (&changed_prefs, argc[i], argc[i + 1], 0)) {
4488 					err = 5;
4489 					break;
4490 				}
4491 			}
4492 			}
4493 			set_special (SPCFLAG_BRK);
4494 			i++;
4495 		}
4496 	}
4497 end:
4498 	for (i = 0; i < argv; i++)
4499 		xfree (argc[i]);
4500 	xfree (p);
4501 	return err;
4502 }
4503 
cfgfile_uaelib_modify(uae_u32 index,uae_u32 parms,uae_u32 size,uae_u32 out,uae_u32 outsize)4504 uae_u32 cfgfile_uaelib_modify (uae_u32 index, uae_u32 parms, uae_u32 size, uae_u32 out, uae_u32 outsize)
4505 {
4506 	uae_char *p, *parms_p = NULL, *parms_out = NULL;
4507 	uae_u32 i, ret;
4508 	TCHAR *out_p = NULL, *parms_in = NULL;
4509 
4510 	if (out)
4511 		put_byte (out, 0);
4512 	if (size == 0) {
4513 		while (get_byte (parms + size) != 0)
4514 			size++;
4515 	}
4516 	parms_p = xmalloc (uae_char, size + 1);
4517 	if (!parms_p) {
4518 		ret = 10;
4519 		goto end;
4520 	}
4521 	if (out) {
4522 		out_p = xmalloc (TCHAR, outsize + 1);
4523 		if (!out_p) {
4524 			ret = 10;
4525 			goto end;
4526 		}
4527 		out_p[0] = 0;
4528 	}
4529 	p = parms_p;
4530 	for (i = 0; i < size; i++) {
4531 		p[i] = get_byte (parms + i);
4532 		if (p[i] == 10 || p[i] == 13 || p[i] == 0)
4533 			break;
4534 	}
4535 	p[i] = 0;
4536 	parms_in = au (parms_p);
4537 	ret = cfgfile_modify (index, parms_in, size, out_p, outsize);
4538 	xfree (parms_in);
4539 	if (out) {
4540 		parms_out = ua (out_p);
4541 		p = parms_out;
4542 		for (i = 0; i < outsize - 1; i++) {
4543 			uae_u8 b = *p++;
4544 			put_byte (out + i, b);
4545 			put_byte (out + i + 1, 0);
4546 			if (!b)
4547 				break;
4548 		}
4549 	}
4550 	xfree (parms_out);
4551 end:
4552 	xfree (out_p);
4553 	xfree (parms_p);
4554 	return ret;
4555 }
4556 
cfgfile_uaelib(int mode,uae_u32 name,uae_u32 dst,uae_u32 maxlen)4557 uae_u32 cfgfile_uaelib (int mode, uae_u32 name, uae_u32 dst, uae_u32 maxlen)
4558 {
4559 	TCHAR tmp[CONFIG_BLEN];
4560 	size_t i;
4561 	struct strlist *sl;
4562 
4563 	if (mode)
4564 		return 0;
4565 
4566 	for (i = 0; i < sizeof (tmp) / sizeof (TCHAR); i++) {
4567 		tmp[i] = get_byte (name + i);
4568 		if (tmp[i] == 0)
4569 			break;
4570 	}
4571 	tmp[sizeof(tmp) / sizeof (TCHAR) - 1] = 0;
4572 	if (tmp[0] == 0)
4573 		return 0;
4574 	for (sl = currprefs.all_lines; sl; sl = sl->next) {
4575 		if (!strcasecmp (sl->option, tmp))
4576 			break;
4577 	}
4578 
4579 	if (sl) {
4580 		char *s = ua (sl->value);
4581 		for (i = 0; i < maxlen; i++) {
4582 			put_byte (dst + i, s[i]);
4583 			if (s[i] == 0)
4584 				break;
4585 		}
4586 		xfree (s);
4587 		return dst;
4588 	}
4589 	return 0;
4590 }
4591 
restore_configuration(uae_u8 * src)4592 uae_u8 *restore_configuration (uae_u8 *src)
4593 {
4594 	TCHAR *s = au ((char*)src);
4595 	//write_log (s);
4596 	xfree (s);
4597 	src += strlen ((char*)src) + 1;
4598 	return src;
4599 }
4600 
save_configuration(int * len,bool fullconfig)4601 uae_u8 *save_configuration (int *len, bool fullconfig)
4602 {
4603 	int tmpsize = 100000;
4604 	uae_u8 *dstbak, *dst, *p;
4605 	int index = -1;
4606 
4607 	dstbak = dst = xcalloc (uae_u8, tmpsize);
4608 	p = dst;
4609 	for (;;) {
4610 		TCHAR tmpout[1000];
4611 		int ret;
4612 		tmpout[0] = 0;
4613 		ret = cfgfile_modify (index, _T("*"), 1, tmpout, sizeof (tmpout) / sizeof (TCHAR));
4614 		index++;
4615 		if (_tcslen (tmpout) > 0) {
4616 			char *out;
4617 			if (!fullconfig && !_tcsncmp (tmpout, _T("input."), 6))
4618 				continue;
4619 			//write_log (_T("'%s'\n"), tmpout);
4620 			out = uutf8 (tmpout);
4621 			strcpy ((char*)p, out);
4622 			xfree (out);
4623 			strcat ((char*)p, "\n");
4624 			p += strlen ((char*)p);
4625 			if ((size_t)(p - dstbak) >= (size_t)(tmpsize - sizeof (tmpout)) )
4626 				break;
4627 		}
4628 		if (ret >= 0)
4629 			break;
4630 	}
4631 	*len = p - dstbak + 1;
4632 	return dstbak;
4633 }
4634 
default_prefs_mini(struct uae_prefs * p,int type)4635 static void default_prefs_mini (struct uae_prefs *p, int type)
4636 {
4637 	_tcscpy (p->description, _T("UAE default A500 configuration"));
4638 
4639 	p->nr_floppies = 1;
4640 	p->floppyslots[0].dfxtype = DRV_35_DD;
4641 	p->floppyslots[1].dfxtype = DRV_NONE;
4642 	p->cpu_model = 68000;
4643 	p->address_space_24 = 1;
4644 	p->chipmem_size = 0x00080000;
4645 	p->bogomem_size = 0x00080000;
4646 }
4647 
default_prefs(struct uae_prefs * p,int type)4648 void default_prefs (struct uae_prefs *p, int type)
4649 {
4650 	int i;
4651 	int roms[] = { 6, 7, 8, 9, 10, 14, 5, 4, 3, 2, 1, -1 };
4652 	TCHAR zero = 0;
4653 	struct zfile *f;
4654 
4655 	reset_inputdevice_config (p);
4656 	memset (p, 0, sizeof (*p));
4657 	_tcscpy (p->description, _T("UAE default configuration"));
4658 	p->config_hardware_path[0] = 0;
4659 	p->config_host_path[0] = 0;
4660 
4661 	p->gfx_scandoubler = 0;
4662 	p->start_gui = 1;
4663 #ifdef DEBUGGER
4664 	p->start_debugger = 0;
4665 #endif
4666 
4667 	p->all_lines = 0;
4668 	/* Note to porters: please don't change any of these options! UAE is supposed
4669 	 * to behave identically on all platforms if possible.
4670 	 * (TW says: maybe it is time to update default config..) */
4671 	p->illegal_mem = 0;
4672 #ifdef __LIBRETRO__
4673 	p->use_serial = 1;
4674 #else
4675 	p->use_serial = 0;
4676 #endif
4677 	p->serial_demand = 0;
4678 	p->serial_hwctsrts = 1;
4679 	p->serial_stopbits = 0;
4680 	p->parallel_demand = 0;
4681 	p->parallel_matrix_emulation = 0;
4682 	p->parallel_postscript_emulation = 0;
4683 	p->parallel_postscript_detection = 0;
4684 	p->parallel_autoflush_time = 5;
4685 	p->ghostscript_parameters[0] = 0;
4686 	p->uae_hide = 0;
4687 
4688 	p->mountitems = 0;
4689 	for (i = 0; i < MOUNT_CONFIG_SIZE; i++) {
4690 		p->mountconfig[i].configoffset = -1;
4691 	}
4692 
4693 	memset (&p->jports[0], 0, sizeof (struct jport));
4694 	memset (&p->jports[1], 0, sizeof (struct jport));
4695 	memset (&p->jports[2], 0, sizeof (struct jport));
4696 	memset (&p->jports[3], 0, sizeof (struct jport));
4697 	p->jports[0].id = JSEM_MICE;
4698 #ifdef __LIBRETRO__
4699 	p->jports[1].id = JSEM_JOYS;
4700 #else
4701 	p->jports[1].id = JSEM_KBDLAYOUT;
4702 #endif
4703 	p->jports[2].id = -1;
4704 	p->jports[3].id = -1;
4705 	p->keyboard_lang = KBD_LANG_US;
4706 
4707 	p->produce_sound = 3;
4708 	p->sound_stereo = SND_STEREO;
4709 	p->sound_stereo_separation = 7;
4710 	p->sound_mixed_stereo_delay = 0;
4711 	p->sound_freq = DEFAULT_SOUND_FREQ;
4712 	p->sound_maxbsiz = DEFAULT_SOUND_MAXB;
4713 	p->sound_interpol = 1;
4714 	p->sound_filter = FILTER_SOUND_EMUL;
4715 	p->sound_filter_type = 0;
4716 #ifdef __LIBRETRO__
4717 	p->sound_auto = 0;
4718 #else
4719 	p->sound_auto = 1;
4720 #endif
4721 	p->sampler_stereo = false;
4722 	p->sampler_buffer = 0;
4723 	p->sampler_freq = 0;
4724 
4725 #ifdef JIT
4726 #ifdef NATMEM_OFFSET
4727 	p->comptrustbyte = 0;
4728 	p->comptrustword = 0;
4729 	p->comptrustlong = 0;
4730 	p->comptrustnaddr= 0;
4731 #else
4732 	p->comptrustbyte = 1;
4733 	p->comptrustword = 1;
4734 	p->comptrustlong = 1;
4735 	p->comptrustnaddr= 1;
4736 #endif
4737 	p->compnf = 1;
4738 	p->comp_hardflush = 0;
4739 	p->comp_constjump = 1;
4740 	p->comp_oldsegv = 0;
4741 	p->compfpu = 1;
4742 	p->fpu_strict = 0;
4743 	p->cachesize = 0;
4744 	p->avoid_cmov = 0;
4745 	p->comp_midopt = 0;
4746 	p->comp_lowopt = 0;
4747 
4748 	for (i = 0;i < 10; i++)
4749 		p->optcount[i] = -1;
4750 	p->optcount[0] = 4;	/* How often a block has to be executed before it is translated */
4751 	p->optcount[1] = 0;	/* How often to use the naive translation */
4752 	p->optcount[2] = 0;
4753 	p->optcount[3] = 0;
4754 	p->optcount[4] = 0;
4755 	p->optcount[5] = 0;
4756 #endif
4757 	p->gfx_framerate = 1;
4758 	p->gfx_autoframerate = 50;
4759 	p->gfx_size_fs.width = 800;
4760 	p->gfx_size_fs.height = 600;
4761 	p->gfx_size_win.width = 720;
4762 	p->gfx_size_win.height = 568;
4763 	for (i = 0; i < 4; i++) {
4764 		p->gfx_size_fs_xtra[i].width = 0;
4765 		p->gfx_size_fs_xtra[i].height = 0;
4766 		p->gfx_size_win_xtra[i].width = 0;
4767 		p->gfx_size_win_xtra[i].height = 0;
4768 	}
4769 	p->gfx_resolution = RES_HIRES;
4770 	p->gfx_vresolution = VRES_DOUBLE;
4771 	p->gfx_apmode[0].gfx_fullscreen = GFX_WINDOW;
4772 	p->gfx_apmode[1].gfx_fullscreen = GFX_WINDOW;
4773 	p->gfx_xcenter = 0; p->gfx_ycenter = 0;
4774 	p->gfx_xcenter_pos = -1;
4775 	p->gfx_ycenter_pos = -1;
4776 	p->gfx_xcenter_size = -1;
4777 	p->gfx_ycenter_size = -1;
4778 	p->gfx_max_horizontal = RES_HIRES;
4779 	p->gfx_max_vertical = VRES_DOUBLE;
4780 	p->gfx_autoresolution_minv = 0;
4781 	p->gfx_autoresolution_minh = 0;
4782 	p->color_mode = 2;
4783 	p->gfx_blackerthanblack = 0;
4784 	p->gfx_apmode[0].gfx_backbuffers = 2;
4785 	p->gfx_apmode[1].gfx_backbuffers = 1;
4786 
4787 #ifdef USE_X11_GFX
4788 	p->x11_use_low_bandwidth = 0;
4789 	p->x11_use_mitshm = 0;
4790 	p->x11_hide_cursor = 1;
4791 #endif
4792 #ifdef SVGA
4793 	p->svga_no_linear = 0;
4794 #endif
4795 #ifdef NCURSES
4796 	p->curses_reverse_video = 0;
4797 #endif
4798         machdep_default_options (p);
4799 	target_default_options (p, type);
4800         gfx_default_options (p);
4801         audio_default_options (p);
4802 
4803 	p->immediate_blits = 0;
4804 	p->waiting_blits = 0;
4805 	p->collision_level = 2;
4806 #ifdef __LIBRETRO__
4807 	p->leds_on_screen = 1;
4808 #else
4809 	p->leds_on_screen = 0;
4810 #endif
4811 	p->leds_on_screen_mask[0] = p->leds_on_screen_mask[1] = (1 << LED_MAX) - 1;
4812 	p->keyboard_leds_in_use = 0;
4813 	p->keyboard_leds[0] = p->keyboard_leds[1] = p->keyboard_leds[2] = 0;
4814 	p->scsi = 0;
4815 	p->uaeserial = 0;
4816 	p->cpu_idle = 0;
4817 	p->turbo_emulation = 0;
4818 	p->headless = 0;
4819 	p->catweasel = 0;
4820 	p->tod_hack = 0;
4821 	p->maprom = 0;
4822 	p->filesys_no_uaefsdb = 0;
4823 	p->filesys_custom_uaefsdb = 1;
4824 	p->picasso96_nocustom = 1;
4825 	p->cart_internal = 1;
4826 	p->sana2 = 0;
4827 	p->clipboard_sharing = false;
4828 	p->native_code = false;
4829 
4830 	p->cs_compatible = 1;
4831 	p->cs_rtc = 2;
4832 	p->cs_df0idhw = 1;
4833 	p->cs_a1000ram = 0;
4834 	p->cs_fatgaryrev = -1;
4835 	p->cs_ramseyrev = -1;
4836 	p->cs_agnusrev = -1;
4837 	p->cs_deniserev = -1;
4838 	p->cs_mbdmac = 0;
4839 	p->cs_a2091 = 0;
4840 	p->cs_a4091 = 0;
4841 	p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = false;
4842 	p->cs_cdtvcd = p->cs_cdtvram = false;
4843 	p->cs_cdtvcard = 0;
4844 	p->cs_pcmcia = 0;
4845 	p->cs_ksmirror_e0 = 1;
4846 	p->cs_ksmirror_a8 = 0;
4847 	p->cs_ciaoverlay = 1;
4848 	p->cs_ciaatod = 0;
4849 	p->cs_df0idhw = 1;
4850 	p->cs_slowmemisfast = 0;
4851 	p->cs_resetwarning = 1;
4852 
4853 #ifdef GFXFILTER
4854 	p->gfx_filter = 0;
4855 	for (int i = 0; i < 2 * MAX_FILTERSHADERS; i++) {
4856 		p->gfx_filtershader[i][0] = 0;
4857 		p->gfx_filtermask[i][0] = 0;
4858 	}
4859 	p->gfx_filter_horiz_zoom_mult = 1.0;
4860 	p->gfx_filter_vert_zoom_mult = 1.0;
4861 	p->gfx_filter_bilinear = 0;
4862 	p->gfx_filter_filtermode = 0;
4863 	p->gfx_filter_scanlineratio = (1 << 4) | 1;
4864 	p->gfx_filter_keep_aspect = 0;
4865 	p->gfx_filter_autoscale = AUTOSCALE_STATIC_AUTO;
4866 	p->gfx_filter_keep_autoscale_aspect = false;
4867 	p->gfx_filteroverlay_overscan = 0;
4868 #endif
4869 
4870 	p->rtg_horiz_zoom_mult = 1.0;
4871 	p->rtg_vert_zoom_mult = 1.0;
4872 
4873 	_tcscpy (p->floppyslots[0].df, _T("df0.adf"));
4874 	_tcscpy (p->floppyslots[1].df, _T("df1.adf"));
4875 	_tcscpy (p->floppyslots[2].df, _T("df2.adf"));
4876 	_tcscpy (p->floppyslots[3].df, _T("df3.adf"));
4877 
4878 	configure_rom (p, roms, 0);
4879 	_tcscpy (p->romfile, _T("kick.rom"));
4880 	_tcscpy (p->romextfile, _T(""));
4881 	_tcscpy (p->romextfile2, _T(""));
4882 	p->romextfile2addr = 0;
4883 	_tcscpy (p->flashfile, _T(""));
4884 #ifdef ACTION_REPLAY
4885 	_tcscpy (p->cartfile, _T(""));
4886 #endif
4887 	_tcscpy (p->rtcfile, _T(""));
4888 
4889 	_tcscpy (p->path_rom.path[0], _T("./"));
4890 	_tcscpy (p->path_floppy.path[0], _T("./"));
4891 	_tcscpy (p->path_hardfile.path[0], _T("./"));
4892 
4893 	p->prtname[0] = 0;
4894 	p->sername[0] = 0;
4895 
4896 	p->fpu_model = 0;
4897 	p->cpu_model = 68000;
4898 	p->m68k_speed_throttle = 0;
4899 	p->cpu_clock_multiplier = 0;
4900 	p->cpu_frequency = 0;
4901 	p->mmu_model = 0;
4902 	p->cpu060_revision = 6;
4903 	p->fpu_revision = -1;
4904 	p->fpu_no_unimplemented = false;
4905 	p->int_no_unimplemented = false;
4906 	p->m68k_speed = 0;
4907 	p->cpu_compatible = 1;
4908 	p->address_space_24 = 1;
4909 	p->cpu_cycle_exact = 0;
4910 	p->blitter_cycle_exact = 0;
4911 	p->chipset_mask = CSMASK_ECS_AGNUS;
4912 	p->genlock = 0;
4913 	p->ntscmode = 0;
4914 	p->filesys_limit = 0;
4915 
4916 	p->fastmem_size = 0x00000000;
4917 	p->fastmem2_size = 0x00000000;
4918 	p->mbresmem_low_size = 0x00000000;
4919 	p->mbresmem_high_size = 0x00000000;
4920 	p->z3fastmem_size = 0x00000000;
4921 	p->z3fastmem2_size = 0x00000000;
4922 	p->z3fastmem_start = 0x10000000;
4923 	p->chipmem_size = 0x00080000;
4924 #ifdef __LIBRETRO__
4925 	p->bogomem_size = 0x00000000;
4926 #else
4927 	p->bogomem_size = 0x00080000;
4928 #endif
4929 	p->rtgmem_size = 0x00000000;
4930 	p->rtgmem_type = 1;
4931 	p->custom_memory_addrs[0] = 0;
4932 	p->custom_memory_sizes[0] = 0;
4933 	p->custom_memory_addrs[1] = 0;
4934 	p->custom_memory_sizes[1] = 0;
4935 	p->fastmem_autoconfig = true;
4936 
4937 #ifdef __LIBRETRO__
4938 	p->nr_floppies = 1;
4939 #else
4940 	p->nr_floppies = 2;
4941 #endif
4942 	p->floppy_read_only = false;
4943 	p->floppyslots[0].dfxtype = DRV_35_DD;
4944 #ifdef __LIBRETRO__
4945 	p->floppyslots[1].dfxtype = DRV_NONE;
4946 #else
4947 	p->floppyslots[1].dfxtype = DRV_35_DD;
4948 #endif
4949 	p->floppyslots[2].dfxtype = DRV_NONE;
4950 	p->floppyslots[3].dfxtype = DRV_NONE;
4951 	p->floppy_speed = 100;
4952 	p->floppy_write_length = 0;
4953 	p->floppy_random_bits_min = 1;
4954 	p->floppy_random_bits_max = 3;
4955 #ifdef DRIVESOUND
4956 	p->dfxclickvolume = 33;
4957 	p->dfxclickchannelmask = 0xffff;
4958 #endif
4959 
4960 #ifdef SAVESTATE
4961 	p->statecapturebuffersize = 100;
4962 	p->statecapturerate = 5 * 50;
4963 	p->inprec_autoplay = true;
4964 #endif
4965 
4966 #ifdef UAE_MINI
4967 	default_prefs_mini (p, 0);
4968 #endif
4969 
4970 	p->input_tablet = TABLET_OFF;
4971 	p->input_magic_mouse = 0;
4972 	p->input_magic_mouse_cursor = 0;
4973 
4974 	inputdevice_default_prefs (p);
4975 
4976 #ifdef SCSIEMU
4977 	blkdev_default_prefs (p);
4978 #endif
4979 
4980 	p->cr_selected = -1;
4981 	struct chipset_refresh *cr;
4982 	for (int i = 0; i < MAX_CHIPSET_REFRESH_TOTAL; i++) {
4983 		cr = &p->cr[i];
4984 		cr->index = i;
4985 		cr->rate = -1;
4986 	}
4987 	cr = &p->cr[CHIPSET_REFRESH_PAL];
4988 	cr->index = CHIPSET_REFRESH_PAL;
4989 	cr->horiz = -1;
4990 	cr->vert = -1;
4991 	cr->lace = -1;
4992 	cr->vsync = - 1;
4993 	cr->framelength = -1;
4994 	cr->rate = 50.0;
4995 	cr->ntsc = 0;
4996 	cr->locked = false;
4997 	_tcscpy (cr->label, _T("PAL"));
4998 	cr = &p->cr[CHIPSET_REFRESH_NTSC];
4999 	cr->index = CHIPSET_REFRESH_NTSC;
5000 	cr->horiz = -1;
5001 	cr->vert = -1;
5002 	cr->lace = -1;
5003 	cr->vsync = - 1;
5004 	cr->framelength = -1;
5005 	cr->rate = 60.0;
5006 	cr->ntsc = 1;
5007 	cr->locked = false;
5008 	_tcscpy (cr->label, _T("NTSC"));
5009 
5010 	//target_default_options (p, type);
5011 
5012 	zfile_fclose (default_file);
5013 	default_file = NULL;
5014 	f = zfile_fopen_empty (NULL, _T("configstore"), 0);
5015 	if (f) {
5016 		uaeconfig++;
5017 		cfgfile_save_options (f, p, 0);
5018 		uaeconfig--;
5019 		cfg_write (&zero, f);
5020 		default_file = f;
5021 	}
5022 }
5023 
buildin_default_prefs_68020(struct uae_prefs * p)5024 static void buildin_default_prefs_68020 (struct uae_prefs *p)
5025 {
5026 	p->cpu_model = 68020;
5027 	p->address_space_24 = 1;
5028 	p->cpu_compatible = 1;
5029 	p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE | CSMASK_AGA;
5030 	p->chipmem_size = 0x200000;
5031 	p->bogomem_size = 0;
5032 	p->m68k_speed = -1;
5033 }
5034 
buildin_default_host_prefs(struct uae_prefs * p)5035 static void buildin_default_host_prefs (struct uae_prefs *p)
5036 {
5037 #if 0
5038 	p->sound_filter = FILTER_SOUND_OFF;
5039 	p->sound_stereo = SND_STEREO;
5040 	p->sound_stereo_separation = 7;
5041 	p->sound_mixed_stereo = 0;
5042 #endif
5043 }
5044 
buildin_default_prefs(struct uae_prefs * p)5045 static void buildin_default_prefs (struct uae_prefs *p)
5046 {
5047 	buildin_default_host_prefs (p);
5048 
5049 	p->floppyslots[0].dfxtype = DRV_35_DD;
5050 	if (p->nr_floppies != 1 && p->nr_floppies != 2)
5051 		p->nr_floppies = 2;
5052 	p->floppyslots[1].dfxtype = p->nr_floppies >= 2 ? DRV_35_DD : DRV_NONE;
5053 	p->floppyslots[2].dfxtype = DRV_NONE;
5054 	p->floppyslots[3].dfxtype = DRV_NONE;
5055 	p->floppy_speed = 100;
5056 
5057 	p->fpu_model = 0;
5058 	p->cpu_model = 68000;
5059 	p->cpu_clock_multiplier = 0;
5060 	p->cpu_frequency = 0;
5061 	p->cpu060_revision = 1;
5062 	p->fpu_revision = -1;
5063 	p->m68k_speed = 0;
5064 	p->cpu_compatible = 1;
5065 	p->address_space_24 = 1;
5066 	p->cpu_cycle_exact = 0;
5067 	p->blitter_cycle_exact = 0;
5068 	p->chipset_mask = CSMASK_ECS_AGNUS;
5069 	p->immediate_blits = 0;
5070 	p->waiting_blits = 0;
5071 	p->collision_level = 2;
5072 	if (p->produce_sound < 1)
5073 		p->produce_sound = 1;
5074 	p->scsi = 0;
5075 	p->uaeserial = 0;
5076 	p->cpu_idle = 0;
5077 	p->turbo_emulation = 0;
5078 	p->catweasel = 0;
5079 	p->tod_hack = 0;
5080 	p->maprom = 0;
5081 #ifdef JIT
5082 	p->cachesize = 0;
5083 #endif
5084 	p->socket_emu = 0;
5085 	p->sound_volume = 0;
5086 	p->sound_volume_cd = 0;
5087 	p->clipboard_sharing = false;
5088 
5089 	p->chipmem_size = 0x00080000;
5090 	p->bogomem_size = 0x00080000;
5091 	p->fastmem_size = 0x00000000;
5092 	p->mbresmem_low_size = 0x00000000;
5093 	p->mbresmem_high_size = 0x00000000;
5094 	p->z3fastmem_size = 0x00000000;
5095 	p->z3fastmem2_size = 0x00000000;
5096 	p->z3chipmem_size = 0x00000000;
5097 	p->rtgmem_size = 0x00000000;
5098 	p->rtgmem_type = 1;
5099 
5100 	p->cs_rtc = 0;
5101 	p->cs_a1000ram = false;
5102 	p->cs_fatgaryrev = -1;
5103 	p->cs_ramseyrev = -1;
5104 	p->cs_agnusrev = -1;
5105 	p->cs_deniserev = -1;
5106 	p->cs_mbdmac = 0;
5107 	p->cs_a2091 = false;
5108 	p->cs_a4091 = false;
5109 	p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = false;
5110 	p->cs_cdtvcd = p->cs_cdtvram = p->cs_cdtvcard = false;
5111 	p->cs_ide = 0;
5112 	p->cs_pcmcia = 0;
5113 	p->cs_ksmirror_e0 = 1;
5114 	p->cs_ksmirror_a8 = 0;
5115 	p->cs_ciaoverlay = 1;
5116 	p->cs_ciaatod = 0;
5117 	p->cs_df0idhw = 1;
5118 	p->cs_resetwarning = 0;
5119 
5120 	_tcscpy (p->romfile, _T(""));
5121 	_tcscpy (p->romextfile, _T(""));
5122 	_tcscpy (p->flashfile, _T(""));
5123 	_tcscpy (p->cartfile, _T(""));
5124 	_tcscpy (p->rtcfile, _T(""));
5125 	_tcscpy (p->amaxromfile, _T(""));
5126 	p->prtname[0] = 0;
5127 	p->sername[0] = 0;
5128 
5129 	p->mountitems = 0;
5130 
5131 	target_default_options (p, 1);
5132 }
5133 
set_68020_compa(struct uae_prefs * p,int compa,int cd32)5134 static void set_68020_compa (struct uae_prefs *p, int compa, int cd32)
5135 {
5136 	switch (compa)
5137 	{
5138 	case 0:
5139 		p->blitter_cycle_exact = 1;
5140 		p->m68k_speed = 0;
5141 #ifdef JIT
5142 		if (p->cpu_model == 68020 && p->cachesize == 0) {
5143 			p->cpu_cycle_exact = 1;
5144 			p->cpu_clock_multiplier = 4 << 8;
5145 		}
5146 #endif
5147 	break;
5148 	case 1:
5149 		p->cpu_compatible = true;
5150 		p->m68k_speed = 0;
5151 		break;
5152 	case 2:
5153 		p->cpu_compatible = 0;
5154 		p->m68k_speed = -1;
5155 		p->address_space_24 = 0;
5156 		break;
5157 	case 3:
5158 		p->cpu_compatible = 0;
5159 		p->address_space_24 = 0;
5160 #ifdef JIT
5161 		p->cachesize = 8192;
5162 #endif
5163 		break;
5164 	}
5165 }
5166 
5167 /* 0: cycle-exact
5168 * 1: more compatible
5169 * 2: no more compatible, no 100% sound
5170 * 3: no more compatible, waiting blits, no 100% sound
5171 */
5172 
set_68000_compa(struct uae_prefs * p,int compa)5173 static void set_68000_compa (struct uae_prefs *p, int compa)
5174 {
5175 	p->cpu_clock_multiplier = 2 << 8;
5176 	switch (compa)
5177 	{
5178 	case 0:
5179 		p->cpu_cycle_exact = p->blitter_cycle_exact = 1;
5180 		break;
5181 	case 1:
5182 		break;
5183 	case 2:
5184 		p->cpu_compatible = 0;
5185 		break;
5186 	case 3:
5187 		p->produce_sound = 2;
5188 		p->cpu_compatible = 0;
5189 		break;
5190 	}
5191 }
5192 
bip_a3000(struct uae_prefs * p,int config,int compa,int romcheck)5193 static int bip_a3000 (struct uae_prefs *p, int config, int compa, int romcheck)
5194 {
5195 	int roms[2];
5196 
5197 	if (config == 2)
5198 		roms[0] = 61;
5199 	else if (config == 1)
5200 		roms[0] = 71;
5201 	else
5202 		roms[0] = 59;
5203 	roms[1] = -1;
5204 	p->bogomem_size = 0;
5205 	p->chipmem_size = 0x200000;
5206 	p->cpu_model = 68030;
5207 	p->fpu_model = 68882;
5208 	p->fpu_no_unimplemented = true;
5209 	if (compa == 0)
5210 		p->mmu_model = 68030;
5211 #ifdef JIT
5212 	else
5213 		p->cachesize = 8192;
5214 #endif
5215 	p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
5216 	p->cpu_compatible = p->address_space_24 = 0;
5217 	p->m68k_speed = -1;
5218 	p->immediate_blits = 0;
5219 	p->produce_sound = 2;
5220 	p->floppyslots[0].dfxtype = DRV_35_HD;
5221 	p->floppy_speed = 0;
5222 	p->cpu_idle = 150;
5223 	p->cs_compatible = CP_A3000;
5224 	p->mbresmem_low_size = 8 * 1024 * 1024;
5225 	built_in_chipset_prefs (p);
5226 	p->cs_ciaatod = p->ntscmode ? 2 : 1;
5227 	return configure_rom (p, roms, romcheck);
5228 }
bip_a4000(struct uae_prefs * p,int config,int compa,int romcheck)5229 static int bip_a4000 (struct uae_prefs *p, int config, int compa, int romcheck)
5230 {
5231 	int roms[8];
5232 
5233 	roms[0] = 16;
5234 	roms[1] = 31;
5235 	roms[2] = 13;
5236 	roms[3] = 12;
5237 	roms[4] = -1;
5238 
5239 	p->bogomem_size = 0;
5240 	p->chipmem_size = 0x200000;
5241 	p->mbresmem_low_size = 8 * 1024 * 1024;
5242 	p->cpu_model = 68030;
5243 	p->fpu_model = 68882;
5244 	if (config > 0)
5245 		p->cpu_model = p->fpu_model = 68040;
5246 	p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
5247 	p->cpu_compatible = p->address_space_24 = 0;
5248 	p->m68k_speed = -1;
5249 	p->immediate_blits = 0;
5250 	p->produce_sound = 2;
5251 #ifdef JIT
5252 	p->cachesize = 8192;
5253 #endif
5254 	p->floppyslots[0].dfxtype = DRV_35_HD;
5255 	p->floppyslots[1].dfxtype = DRV_35_HD;
5256 	p->floppy_speed = 0;
5257 	p->cpu_idle = 150;
5258 	p->cs_compatible = CP_A4000;
5259 	built_in_chipset_prefs (p);
5260 	p->cs_ciaatod = p->ntscmode ? 2 : 1;
5261 	return configure_rom (p, roms, romcheck);
5262 }
bip_a4000t(struct uae_prefs * p,int config,int compa,int romcheck)5263 static int bip_a4000t (struct uae_prefs *p, int config, int compa, int romcheck)
5264 {
5265 
5266 	int roms[8];
5267 
5268 	roms[0] = 16;
5269 	roms[1] = 31;
5270 	roms[2] = 13;
5271 	roms[3] = -1;
5272 
5273 	p->bogomem_size = 0;
5274 	p->chipmem_size = 0x200000;
5275 	p->mbresmem_low_size = 8 * 1024 * 1024;
5276 	p->cpu_model = 68030;
5277 	p->fpu_model = 68882;
5278 	if (config > 0)
5279 		p->cpu_model = p->fpu_model = 68040;
5280 	p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
5281 	p->cpu_compatible = p->address_space_24 = 0;
5282 	p->m68k_speed = -1;
5283 	p->immediate_blits = 0;
5284 	p->produce_sound = 2;
5285 #ifdef JIT
5286 	p->cachesize = 8192;
5287 #endif
5288 	p->floppyslots[0].dfxtype = DRV_35_HD;
5289 	p->floppyslots[1].dfxtype = DRV_35_HD;
5290 	p->floppy_speed = 0;
5291 	p->cpu_idle = 150;
5292 	p->cs_compatible = CP_A4000T;
5293 	built_in_chipset_prefs (p);
5294 	p->cs_ciaatod = p->ntscmode ? 2 : 1;
5295 	return configure_rom (p, roms, romcheck);
5296 }
5297 
bip_a1000(struct uae_prefs * p,int config,int compa,int romcheck)5298 static int bip_a1000 (struct uae_prefs *p, int config, int compa, int romcheck)
5299 {
5300 	int roms[2];
5301 
5302 	roms[0] = 24;
5303 	roms[1] = -1;
5304 	p->chipset_mask = 0;
5305 	p->bogomem_size = 0;
5306 	p->sound_filter = FILTER_SOUND_ON;
5307 	set_68000_compa (p, compa);
5308 	p->floppyslots[1].dfxtype = DRV_NONE;
5309 	p->cs_compatible = CP_A1000;
5310 	p->cs_slowmemisfast = 1;
5311 	p->cs_dipagnus = 1;
5312 	p->cs_agnusbltbusybug = 1;
5313 	built_in_chipset_prefs (p);
5314 	if (config > 0)
5315 		p->cs_denisenoehb = 1;
5316 	if (config > 1)
5317 		p->chipmem_size = 0x40000;
5318 	return configure_rom (p, roms, romcheck);
5319 }
5320 
bip_cdtv(struct uae_prefs * p,int config,int compa,int romcheck)5321 static int bip_cdtv (struct uae_prefs *p, int config, int compa, int romcheck)
5322 {
5323 	int roms[4];
5324 
5325 	p->bogomem_size = 0;
5326 	p->chipmem_size = 0x100000;
5327 	p->chipset_mask = CSMASK_ECS_AGNUS;
5328 	p->cs_cdtvcd = p->cs_cdtvram = 1;
5329 	if (config > 0)
5330 		p->cs_cdtvcard = 64;
5331 	p->cs_rtc = 1;
5332 	p->nr_floppies = 0;
5333 	p->floppyslots[0].dfxtype = DRV_NONE;
5334 	if (config > 0)
5335 		p->floppyslots[0].dfxtype = DRV_35_DD;
5336 	p->floppyslots[1].dfxtype = DRV_NONE;
5337 	set_68000_compa (p, compa);
5338 	p->cs_compatible = CP_CDTV;
5339 	built_in_chipset_prefs (p);
5340 	fetch_datapath (p->flashfile, sizeof (p->flashfile) / sizeof (TCHAR));
5341 	_tcscat (p->flashfile, _T("cdtv.nvr"));
5342 	roms[0] = 6;
5343 	roms[1] = 32;
5344 	roms[2] = -1;
5345 	if (!configure_rom (p, roms, romcheck))
5346 		return 0;
5347 	roms[0] = 20;
5348 	roms[1] = 21;
5349 	roms[2] = 22;
5350 	roms[3] = -1;
5351 	if (!configure_rom (p, roms, romcheck))
5352 		return 0;
5353 	return 1;
5354 }
5355 
bip_cd32(struct uae_prefs * p,int config,int compa,int romcheck)5356 static int bip_cd32 (struct uae_prefs *p, int config, int compa, int romcheck)
5357 {
5358 	int roms[2];
5359 
5360 	buildin_default_prefs_68020 (p);
5361 	p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = 1;
5362 	p->nr_floppies = 0;
5363 	p->floppyslots[0].dfxtype = DRV_NONE;
5364 	p->floppyslots[1].dfxtype = DRV_NONE;
5365 	set_68020_compa (p, compa, 1);
5366 	p->cs_compatible = CP_CD32;
5367 	built_in_chipset_prefs (p);
5368 	fetch_datapath (p->flashfile, sizeof (p->flashfile) / sizeof (TCHAR));
5369 	_tcscat (p->flashfile, _T("cd32.nvr"));
5370 	roms[0] = 64;
5371 	roms[1] = -1;
5372 	if (!configure_rom (p, roms, 0)) {
5373 		roms[0] = 18;
5374 		roms[1] = -1;
5375 		if (!configure_rom (p, roms, romcheck))
5376 			return 0;
5377 		roms[0] = 19;
5378 		if (!configure_rom (p, roms, romcheck))
5379 			return 0;
5380 	}
5381 	if (config > 0) {
5382 		roms[0] = 23;
5383 		if (!configure_rom (p, roms, romcheck))
5384 			return 0;
5385 	}
5386 	return 1;
5387 }
5388 
bip_a1200(struct uae_prefs * p,int config,int compa,int romcheck)5389 static int bip_a1200 (struct uae_prefs *p, int config, int compa, int romcheck)
5390 {
5391 	int roms[4];
5392 
5393 	buildin_default_prefs_68020 (p);
5394 	roms[0] = 11;
5395 	roms[1] = 15;
5396 	roms[2] = 31;
5397 	roms[3] = -1;
5398 	p->cs_rtc = 0;
5399 	if (config == 1) {
5400 		p->fastmem_size = 0x400000;
5401 		p->cs_rtc = 2;
5402 	}
5403 	set_68020_compa (p, compa, 0);
5404 	p->cs_compatible = CP_A1200;
5405 	built_in_chipset_prefs (p);
5406 	return configure_rom (p, roms, romcheck);
5407 }
5408 
bip_a600(struct uae_prefs * p,int config,int compa,int romcheck)5409 static int bip_a600 (struct uae_prefs *p, int config, int compa, int romcheck)
5410 {
5411 	int roms[4];
5412 
5413 	roms[0] = 10;
5414 	roms[1] = 9;
5415 	roms[2] = 8;
5416 	roms[3] = -1;
5417 	p->bogomem_size = 0;
5418 	p->chipmem_size = 0x100000;
5419 	if (config > 0)
5420 		p->cs_rtc = 1;
5421 	if (config == 1)
5422 		p->chipmem_size = 0x200000;
5423 	if (config == 2)
5424 		p->fastmem_size = 0x400000;
5425 	p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
5426 	set_68000_compa (p, compa);
5427 	p->cs_compatible = CP_A600;
5428 	built_in_chipset_prefs (p);
5429 	return configure_rom (p, roms, romcheck);
5430 }
5431 
bip_a500p(struct uae_prefs * p,int config,int compa,int romcheck)5432 static int bip_a500p (struct uae_prefs *p, int config, int compa, int romcheck)
5433 {
5434 	int roms[2];
5435 
5436 	roms[0] = 7;
5437 	roms[1] = -1;
5438 	p->bogomem_size = 0;
5439 	p->chipmem_size = 0x100000;
5440 	if (config > 0)
5441 		p->cs_rtc = 1;
5442 	if (config == 1)
5443 		p->chipmem_size = 0x200000;
5444 	if (config == 2)
5445 		p->fastmem_size = 0x400000;
5446 	p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
5447 	set_68000_compa (p, compa);
5448 	p->cs_compatible = CP_A500P;
5449 	built_in_chipset_prefs (p);
5450 	return configure_rom (p, roms, romcheck);
5451 }
bip_a500(struct uae_prefs * p,int config,int compa,int romcheck)5452 static int bip_a500 (struct uae_prefs *p, int config, int compa, int romcheck)
5453 {
5454 	int roms[4];
5455 
5456 	roms[0] = roms[1] = roms[2] = roms[3] = -1;
5457 	switch (config)
5458 	{
5459 	case 0: // KS 1.3, OCS Agnus, 0.5M Chip + 0.5M Slow
5460 		roms[0] = 6;
5461 		roms[1] = 32;
5462 		p->chipset_mask = 0;
5463 		break;
5464 	case 1: // KS 1.3, ECS Agnus, 0.5M Chip + 0.5M Slow
5465 		roms[0] = 6;
5466 		roms[1] = 32;
5467 		break;
5468 	case 2: // KS 1.3, ECS Agnus, 1.0M Chip
5469 		roms[0] = 6;
5470 		roms[1] = 32;
5471 		p->bogomem_size = 0;
5472 		p->chipmem_size = 0x100000;
5473 		break;
5474 	case 3: // KS 1.3, OCS Agnus, 0.5M Chip
5475 		roms[0] = 6;
5476 		roms[1] = 32;
5477 		p->bogomem_size = 0;
5478 		p->chipset_mask = 0;
5479 		p->cs_rtc = 0;
5480 		p->floppyslots[1].dfxtype = DRV_NONE;
5481 		break;
5482 	case 4: // KS 1.2, OCS Agnus, 0.5M Chip
5483 		roms[0] = 5;
5484 		roms[1] = 4;
5485 		roms[2] = 3;
5486 		p->bogomem_size = 0;
5487 		p->chipset_mask = 0;
5488 		p->cs_rtc = 0;
5489 		p->floppyslots[1].dfxtype = DRV_NONE;
5490 		break;
5491 	case 5: // KS 1.2, OCS Agnus, 0.5M Chip + 0.5M Slow
5492 		roms[0] = 5;
5493 		roms[1] = 4;
5494 		roms[2] = 3;
5495 		p->chipset_mask = 0;
5496 		break;
5497 	}
5498 	set_68000_compa (p, compa);
5499 	p->cs_compatible = CP_A500;
5500 	built_in_chipset_prefs (p);
5501 	return configure_rom (p, roms, romcheck);
5502 }
5503 
bip_super(struct uae_prefs * p,int config,int compa,int romcheck)5504 static int bip_super (struct uae_prefs *p, int config, int compa, int romcheck)
5505 {
5506 	int roms[8];
5507 
5508 	roms[0] = 46;
5509 	roms[1] = 16;
5510 	roms[2] = 31;
5511 	roms[3] = 15;
5512 	roms[4] = 14;
5513 	roms[5] = 12;
5514 	roms[6] = 11;
5515 	roms[7] = -1;
5516 	p->bogomem_size = 0;
5517 	p->chipmem_size = 0x400000;
5518 	p->z3fastmem_size = 8 * 1024 * 1024;
5519 	p->rtgmem_size = 16 * 1024 * 1024;
5520 	p->cpu_model = 68040;
5521 	p->fpu_model = 68040;
5522 	p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
5523 	p->cpu_compatible = p->address_space_24 = 0;
5524 	p->m68k_speed = -1;
5525 	p->immediate_blits = 1;
5526 	p->produce_sound = 2;
5527 #ifdef JIT
5528 	p->cachesize = 8192;
5529 #endif
5530 	p->floppyslots[0].dfxtype = DRV_35_HD;
5531 	p->floppyslots[1].dfxtype = DRV_35_HD;
5532 	p->floppy_speed = 0;
5533 	p->cpu_idle = 150;
5534 	p->scsi = 1;
5535 	p->uaeserial = 1;
5536 	p->socket_emu = 1;
5537 	p->cart_internal = 0;
5538 	p->picasso96_nocustom = 1;
5539 	p->cs_compatible = 1;
5540 	built_in_chipset_prefs (p);
5541 	p->cs_ide = -1;
5542 	p->cs_ciaatod = p->ntscmode ? 2 : 1;
5543 	//_tcscat(p->flashfile, _T("battclock.nvr"));
5544 	return configure_rom (p, roms, romcheck);
5545 }
5546 
bip_arcadia(struct uae_prefs * p,int config,int compa,int romcheck)5547 static int bip_arcadia (struct uae_prefs *p, int config, int compa, int romcheck)
5548 {
5549 	int roms[4], i;
5550 	struct romlist **rl;
5551 
5552 	p->bogomem_size = 0;
5553 	p->chipset_mask = 0;
5554 	p->cs_rtc = 0;
5555 	p->nr_floppies = 0;
5556 	p->floppyslots[0].dfxtype = DRV_NONE;
5557 	p->floppyslots[1].dfxtype = DRV_NONE;
5558 	set_68000_compa (p, compa);
5559 	p->cs_compatible = CP_A500;
5560 	built_in_chipset_prefs (p);
5561 	fetch_datapath (p->flashfile, sizeof (p->flashfile) / sizeof (TCHAR));
5562 	_tcscat (p->flashfile, _T("arcadia.nvr"));
5563 	roms[0] = 5;
5564 	roms[1] = 4;
5565 	roms[2] = -1;
5566 	if (!configure_rom (p, roms, romcheck))
5567 		return 0;
5568 	roms[0] = 49;
5569 	roms[1] = 50;
5570 	roms[2] = 51;
5571 	roms[3] = -1;
5572 	if (!configure_rom (p, roms, romcheck))
5573 		return 0;
5574 	rl = getarcadiaroms ();
5575 	for (i = 0; rl[i]; i++) {
5576 		if (config-- == 0) {
5577 			roms[0] = rl[i]->rd->id;
5578 			roms[1] = -1;
5579 			configure_rom (p, roms, 0);
5580 			break;
5581 		}
5582 	}
5583 	xfree (rl);
5584 	return 1;
5585 }
5586 
built_in_prefs(struct uae_prefs * p,int model,int config,int compa,int romcheck)5587 int built_in_prefs (struct uae_prefs *p, int model, int config, int compa, int romcheck)
5588 {
5589 	write_log(_T("built in model: %d, config: %d, compa: %d, romchk: %d\n"), model, config, compa, romcheck);
5590 
5591 	int v = 0;
5592 
5593 	buildin_default_prefs (p);
5594 	switch (model)
5595 	{
5596 	case 0:
5597 		v = bip_a500 (p, config, compa, romcheck);
5598 		break;
5599 	case 1:
5600 		v = bip_a500p (p, config, compa, romcheck);
5601 		break;
5602 	case 2:
5603 		v = bip_a600 (p, config, compa, romcheck);
5604 		break;
5605 	case 3:
5606 		v = bip_a1000 (p, config, compa, romcheck);
5607 		break;
5608 	case 4:
5609 		v = bip_a1200 (p, config, compa, romcheck);
5610 		break;
5611 	case 5:
5612 		v = bip_a3000 (p, config, compa, romcheck);
5613 		break;
5614 	case 6:
5615 		v = bip_a4000 (p, config, compa, romcheck);
5616 		break;
5617 	case 7:
5618 		v = bip_a4000t (p, config, compa, romcheck);
5619 		break;
5620 	case 8:
5621 		v = bip_cd32 (p, config, compa, romcheck);
5622 		break;
5623 	case 9:
5624 		v = bip_cdtv (p, config, compa, romcheck);
5625 		break;
5626 	case 10:
5627 		v = bip_arcadia (p, config , compa, romcheck);
5628 		break;
5629 	case 11:
5630 		v = bip_super (p, config, compa, romcheck);
5631 		break;
5632 	}
5633 	if ((p->cpu_model >= 68020 || !p->cpu_cycle_exact) && !p->immediate_blits)
5634 		p->waiting_blits = 1;
5635 	return v;
5636 }
5637 
built_in_chipset_prefs(struct uae_prefs * p)5638 int built_in_chipset_prefs (struct uae_prefs *p)
5639 {
5640 	if (!p->cs_compatible)
5641 		return 1;
5642 
5643 	p->cs_a1000ram = 0;
5644 	p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = 0;
5645 	p->cs_cdtvcd = p->cs_cdtvram = p->cs_cdtvscsi = 0;
5646 	p->cs_a2091 = p->cs_a4091 = 0;
5647 	p->cs_fatgaryrev = -1;
5648 	p->cs_ide = 0;
5649 	p->cs_ramseyrev = -1;
5650 	p->cs_deniserev = -1;
5651 	p->cs_agnusrev = -1;
5652 	p->cs_denisenoehb = 0;
5653 	p->cs_dipagnus = 0;
5654 	p->cs_agnusbltbusybug = 0;
5655 	p->cs_mbdmac = 0;
5656 	p->cs_pcmcia = 0;
5657 	p->cs_ksmirror_e0 = 1;
5658 	p->cs_ksmirror_a8 = 0;
5659 	p->cs_ciaoverlay = 1;
5660 	p->cs_ciaatod = 0;
5661 	p->cs_rtc = 0;
5662 	p->cs_rtc_adjust_mode = p->cs_rtc_adjust = 0;
5663 	p->cs_df0idhw = 1;
5664 	p->cs_resetwarning = 1;
5665 	p->cs_slowmemisfast = 0;
5666 
5667 	switch (p->cs_compatible)
5668 	{
5669 	case CP_GENERIC: // generic
5670 		p->cs_rtc = 2;
5671 		p->cs_fatgaryrev = 0;
5672 		p->cs_ide = -1;
5673 		p->cs_mbdmac = -1;
5674 		p->cs_ramseyrev = 0x0f;
5675 		break;
5676 	case CP_CDTV: // CDTV
5677 		p->cs_rtc = 1;
5678 		p->cs_cdtvcd = p->cs_cdtvram = 1;
5679 		p->cs_df0idhw = 1;
5680 		p->cs_ksmirror_e0 = 0;
5681 		break;
5682 	case CP_CD32: // CD32
5683 		p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = 1;
5684 		p->cs_ksmirror_e0 = 0;
5685 		p->cs_ksmirror_a8 = 1;
5686 		p->cs_ciaoverlay = 0;
5687 		p->cs_resetwarning = 0;
5688 		break;
5689 	case CP_A500: // A500
5690 		p->cs_df0idhw = 0;
5691 		p->cs_resetwarning = 0;
5692 		if (p->bogomem_size || p->chipmem_size > 0x80000 || p->fastmem_size)
5693 			p->cs_rtc = 1;
5694 		break;
5695 	case CP_A500P: // A500+
5696 		p->cs_rtc = 1;
5697 		p->cs_resetwarning = 0;
5698 		break;
5699 	case CP_A600: // A600
5700 		p->cs_rtc = 1;
5701 		p->cs_ide = IDE_A600A1200;
5702 		p->cs_pcmcia = 1;
5703 		p->cs_ksmirror_a8 = 1;
5704 		p->cs_ciaoverlay = 0;
5705 		p->cs_resetwarning = 0;
5706 		break;
5707 	case CP_A1000: // A1000
5708 		p->cs_a1000ram = 1;
5709 		p->cs_ciaatod = p->ntscmode ? 2 : 1;
5710 		p->cs_ksmirror_e0 = 0;
5711 		p->cs_agnusbltbusybug = 1;
5712 		p->cs_dipagnus = 1;
5713 		break;
5714 	case CP_A1200: // A1200
5715 		p->cs_ide = IDE_A600A1200;
5716 		p->cs_pcmcia = 1;
5717 		p->cs_ksmirror_a8 = 1;
5718 		p->cs_ciaoverlay = 0;
5719 		if (p->fastmem_size || p->z3fastmem_size)
5720 			p->cs_rtc = 1;
5721 		break;
5722 	case CP_A2000: // A2000
5723 		p->cs_rtc = 1;
5724 		p->cs_ciaatod = p->ntscmode ? 2 : 1;
5725 		break;
5726 	case CP_A3000: // A3000
5727 		p->cs_rtc = 2;
5728 		p->cs_fatgaryrev = 0;
5729 		p->cs_ramseyrev = 0x0d;
5730 		p->cs_mbdmac = 1;
5731 		p->cs_ksmirror_e0 = 0;
5732 		p->cs_ciaatod = p->ntscmode ? 2 : 1;
5733 		break;
5734 	case CP_A3000T: // A3000T
5735 		p->cs_rtc = 2;
5736 		p->cs_fatgaryrev = 0;
5737 		p->cs_ramseyrev = 0x0d;
5738 		p->cs_mbdmac = 1;
5739 		p->cs_ksmirror_e0 = 0;
5740 		p->cs_ciaatod = p->ntscmode ? 2 : 1;
5741 		break;
5742 	case CP_A4000: // A4000
5743 		p->cs_rtc = 2;
5744 		p->cs_fatgaryrev = 0;
5745 		p->cs_ramseyrev = 0x0f;
5746 		p->cs_ide = IDE_A4000;
5747 		p->cs_mbdmac = 0;
5748 		p->cs_ksmirror_a8 = 0;
5749 		p->cs_ksmirror_e0 = 0;
5750 		p->cs_ciaoverlay = 0;
5751 		break;
5752 	case CP_A4000T: // A4000T
5753 		p->cs_rtc = 2;
5754 		p->cs_fatgaryrev = 0;
5755 		p->cs_ramseyrev = 0x0f;
5756 		p->cs_ide = IDE_A4000;
5757 		p->cs_mbdmac = 2;
5758 		p->cs_ksmirror_a8 = 0;
5759 		p->cs_ksmirror_e0 = 0;
5760 		p->cs_ciaoverlay = 0;
5761 		break;
5762 	}
5763 	return 1;
5764 }
5765 
config_check_vsync(void)5766 void config_check_vsync (void)
5767 {
5768 	if (config_changed) {
5769 //		if (config_changed == 1)
5770 //			write_log (_T("* configuration check trigger\n"));
5771 		config_changed++;
5772 		if (config_changed >= 3)
5773 			config_changed = 0;
5774 	}
5775 }
5776 
5777