1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * Main program
5 *
6 * Copyright 1995 Ed Hanway
7 * Copyright 1995, 1996, 1997 Bernd Schmidt
8 * Copyright 2006-2007 Richard Drummond
9 * Copyright 2010 Mustafa Tufan
10 */
11 #include "sysconfig.h"
12 #include "sysdeps.h"
13 #include <assert.h>
14 #include <wchar.h>
15
16 #include "cfgfile.h"
17 #include "threaddep/thread.h"
18 #include "uae.h"
19 #include "gensound.h"
20 #include "audio.h"
21 #include "sounddep/sound.h"
22 #include "events.h"
23 #include "memory_uae.h"
24 #include "custom.h"
25 #include "serial.h"
26 #include "newcpu.h"
27 #include "disk.h"
28 #include "debug.h"
29 #include "xwin.h"
30 #include "inputdevice.h"
31 #include "keybuf.h"
32 #include "gui.h"
33 #include "autoconf.h"
34 #include "traps.h"
35 #include "osemu.h"
36 #include "picasso96.h"
37 #include "bsdsocket.h"
38 #include "uaeexe.h"
39 #include "native2amiga.h"
40 #include "scsidev.h"
41 #include "uaeserial.h"
42 #include "akiko.h"
43 #include "cdtv.h"
44 #include "savestate.h"
45 #include "filesys.h"
46 #include "parallel.h"
47 #include "a2091.h"
48 #include "a2065.h"
49 #include "ncr_scsi.h"
50 #include "scsi.h"
51 #include "sana2.h"
52 #include "blkdev.h"
53 #include "gfxfilter.h"
54 #include "uaeresource.h"
55 #include "dongle.h"
56 #include "sampler.h"
57 #include "consolehook.h"
58 #include "gayle.h"
59 #include "misc.h"
60 #include "keyboard.h"
61 #ifdef RETROPLATFORM
62 #include "rp.h"
63 #endif
64 #ifdef USE_SDL
65 #include "SDL.h"
66 #endif
67
68 /* internal prototypes */
69 uae_u32 uaerand (void);
70 uae_u32 uaesrand (uae_u32 seed);
71 uae_u32 uaerandgetseed (void);
72 void my_trim (TCHAR *s);
73 TCHAR *my_strdup_trim (const TCHAR *s);
74
75 /* internal members */
76 long int version = 256 * 65536L * UAEMAJOR + 65536L * UAEMINOR + UAESUBREV;
77
78 struct uae_prefs currprefs, changed_prefs;
79 int config_changed;
80
81 int pissoff_value = 15000 * CYCLE_UNIT;
82 int pause_emulation;
83 char start_path_data[MAX_DPATH];
84 bool no_gui = 0, quit_to_gui = 0;
85 bool cloanto_rom = 0;
86 bool kickstart_rom = 1;
87 bool console_emulation = 0;
88
89 struct gui_info gui_data;
90
91 TCHAR warning_buffer[256];
92
93 TCHAR optionsfile[256];
94
95 static unsigned long randseed;
96 static unsigned long oldhcounter;
97
98 #ifndef _WIN32
99 // Prototype in sysdeps.h
GetLastError(void)100 DWORD GetLastError(void)
101 {
102 return errno;
103 }
104 #endif
105
hr(void)106 static void hr (void)
107 {
108 write_log (_T("------------------------------------------------------------------------------------\n"));
109 }
110
show_version(void)111 static void show_version (void)
112 {
113 write_log (_T("P-UAE %d.%d.%d\n"), UAEMAJOR, UAEMINOR, UAESUBREV);
114 write_log (_T("Git Commit: %s\n"), PACKAGE_COMMIT);
115 write_log (_T("Build date: " __DATE__ " " __TIME__ "\n"));
116 }
117
show_version_full(void)118 static void show_version_full (void)
119 {
120 hr ();
121 show_version ();
122 hr ();
123 write_log (_T("Copyright 1995-2002 Bernd Schmidt\n"));
124 write_log (_T(" 1999-2013 Toni Wilen\n"));
125 write_log (_T(" 2003-2007 Richard Drummond\n"));
126 write_log (_T(" 2006-2013 Mustafa 'GnoStiC' Tufan\n\n"));
127 write_log (_T("See the source for a full list of contributors.\n"));
128 write_log (_T("This is free software; see the file COPYING for copying conditions. There is NO\n"));
129 write_log (_T("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"));
130 hr ();
131 }
132
uaesrand(uae_u32 seed)133 uae_u32 uaesrand (uae_u32 seed)
134 {
135 oldhcounter = -1;
136 randseed = seed;
137 //randseed = 0x12345678;
138 //write_log (_T("seed=%08x\n"), randseed);
139 return randseed;
140 }
141
uaerand(void)142 uae_u32 uaerand (void)
143 {
144 if (oldhcounter != hsync_counter) {
145 srand (hsync_counter ^ randseed);
146 oldhcounter = hsync_counter;
147 }
148 uae_u32 r = rand ();
149 //write_log (_T("rand=%08x\n"), r);
150 return r;
151 }
152
uaerandgetseed(void)153 uae_u32 uaerandgetseed (void)
154 {
155 return randseed;
156 }
157
my_trim(TCHAR * s)158 void my_trim (TCHAR *s)
159 {
160 int len;
161 while (_tcscspn (s, _T("\t \r\n")) == 0)
162 memmove (s, s + 1, (_tcslen (s + 1) + 1) * sizeof (TCHAR));
163 len = _tcslen (s);
164 while (len > 0 && _tcscspn (s + len - 1, _T("\t \r\n")) == 0)
165 s[--len] = '\0';
166 }
167
my_strdup_trim(const TCHAR * s)168 TCHAR *my_strdup_trim (const TCHAR *s)
169 {
170 TCHAR *out;
171 int len;
172
173 while (_tcscspn (s, _T("\t \r\n")) == 0)
174 s++;
175 len = _tcslen (s);
176 while (len > 0 && _tcscspn (s + len - 1, _T("\t \r\n")) == 0)
177 len--;
178 out = xmalloc (TCHAR, len + 1);
179 memcpy (out, s, len * sizeof (TCHAR));
180 out[len] = 0;
181 return out;
182 }
183
discard_prefs(struct uae_prefs * p,int type)184 void discard_prefs (struct uae_prefs *p, int type)
185 {
186 struct strlist **ps = &p->all_lines;
187 while (*ps) {
188 struct strlist *s = *ps;
189 *ps = s->next;
190 xfree (s->value);
191 xfree (s->option);
192 xfree (s);
193 }
194 #ifdef FILESYS
195 filesys_cleanup ();
196 #endif
197 }
198
fixup_prefs_dim2(struct wh * wh)199 static void fixup_prefs_dim2 (struct wh *wh)
200 {
201 if (wh->width < 160)
202 wh->width = 160;
203 if (wh->height < 128)
204 wh->height = 128;
205 if (wh->width > MAX_UAE_WIDTH)
206 wh->width = MAX_UAE_WIDTH;
207 if (wh->height > MAX_UAE_HEIGHT)
208 wh->height = MAX_UAE_HEIGHT;
209 }
210
fixup_prefs_dimensions(struct uae_prefs * prefs)211 void fixup_prefs_dimensions (struct uae_prefs *prefs)
212 {
213 fixup_prefs_dim2 (&prefs->gfx_size_fs);
214 fixup_prefs_dim2 (&prefs->gfx_size_win);
215 if (prefs->gfx_apmode[1].gfx_vsync)
216 prefs->gfx_apmode[1].gfx_vsyncmode = 1;
217
218 for (int i = 0; i < 2; i++) {
219 struct apmode *ap = &prefs->gfx_apmode[i];
220 ap->gfx_vflip = 0;
221 ap->gfx_strobo = false;
222 if (ap->gfx_vsync) {
223 if (ap->gfx_vsyncmode) {
224 // low latency vsync: no flip only if no-buffer
225 if (ap->gfx_backbuffers >= 1)
226 ap->gfx_vflip = 1;
227 if (!i && ap->gfx_backbuffers == 2)
228 ap->gfx_vflip = 1;
229 ap->gfx_strobo = prefs->lightboost_strobo;
230 } else {
231 // legacy vsync: always wait for flip
232 ap->gfx_vflip = -1;
233 if (prefs->gfx_api && ap->gfx_backbuffers < 1)
234 ap->gfx_backbuffers = 1;
235 if (ap->gfx_vflip)
236 ap->gfx_strobo = prefs->lightboost_strobo;;
237 }
238 } else {
239 // no vsync: wait if triple bufferirng
240 if (ap->gfx_backbuffers >= 2)
241 ap->gfx_vflip = -1;
242 }
243 }
244
245 if (prefs->gfx_filter == 0 && ((prefs->gfx_filter_autoscale && !prefs->gfx_api) || (prefs->gfx_apmode[0].gfx_vsyncmode)))
246 prefs->gfx_filter = 1;
247 if (prefs->gfx_filter == 0 && prefs->monitoremu)
248 prefs->gfx_filter = 1;
249 }
250
fixup_cpu(struct uae_prefs * p)251 void fixup_cpu (struct uae_prefs *p)
252 {
253 if (p->cpu_frequency == 1000000)
254 p->cpu_frequency = 0;
255 switch (p->cpu_model)
256 {
257 case 68000:
258 p->address_space_24 = 1;
259 if (p->cpu_compatible || p->cpu_cycle_exact)
260 p->fpu_model = 0;
261 break;
262 case 68010:
263 p->address_space_24 = 1;
264 if (p->cpu_compatible || p->cpu_cycle_exact)
265 p->fpu_model = 0;
266 break;
267 case 68020:
268 break;
269 case 68030:
270 p->address_space_24 = 0;
271 break;
272 case 68040:
273 p->address_space_24 = 0;
274 if (p->fpu_model)
275 p->fpu_model = 68040;
276 break;
277 case 68060:
278 p->address_space_24 = 0;
279 if (p->fpu_model)
280 p->fpu_model = 68060;
281 break;
282 }
283
284 if (p->cpu_model >= 68040 && p->cachesize && p->cpu_compatible)
285 p->cpu_compatible = false;
286
287 if (p->cpu_model < 68030 || p->cachesize)
288 p->mmu_model = 0;
289
290 if (p->cachesize && p->cpu_cycle_exact)
291 p->cachesize = 0;
292
293 if (p->cpu_cycle_exact && p->m68k_speed < 0)
294 p->m68k_speed = 0;
295
296 if (p->immediate_blits && p->blitter_cycle_exact)
297 p->immediate_blits = false;
298 if (p->immediate_blits && p->waiting_blits)
299 p->waiting_blits = 0;
300 }
301
302
303
fixup_prefs(struct uae_prefs * p)304 void fixup_prefs (struct uae_prefs *p)
305 {
306 /** FIXME:
307 * There must be a way to a) have a sane max_z3fastmem value
308 * without NATMEM being used and b) a way to use fastmem and
309 * rtg mem without crashing 64bit linux systems.
310 **/
311 #ifndef NATMEM_OFFSET
312 max_z3fastmem = 0;
313 #endif // NATMEM_OFFSET
314
315 int err = 0;
316
317 built_in_chipset_prefs (p);
318 fixup_cpu (p);
319
320 if (((p->chipmem_size & (p->chipmem_size - 1)) != 0 && p->chipmem_size != 0x180000)
321 || p->chipmem_size < 0x20000
322 || p->chipmem_size > 0x800000)
323 {
324 write_log (_T("Unsupported chipmem size %x!\n"), p->chipmem_size);
325 p->chipmem_size = 0x200000;
326 err = 1;
327 }
328 if ((p->fastmem_size & (p->fastmem_size - 1)) != 0
329 || (p->fastmem_size != 0 && (p->fastmem_size < 0x100000 || p->fastmem_size > 0x800000)))
330 {
331 write_log (_T("Unsupported fastmem size %x!\n"), p->fastmem_size);
332 err = 1;
333 }
334 if ((p->rtgmem_size & (p->rtgmem_size - 1)) != 0
335 || (p->rtgmem_size != 0 && (p->rtgmem_size < 0x100000 || p->rtgmem_size > max_z3fastmem)))
336 {
337 write_log (_T("Unsupported graphics card memory size %x (%x)!\n"), p->rtgmem_size, max_z3fastmem);
338 if (p->rtgmem_size > max_z3fastmem)
339 p->rtgmem_size = max_z3fastmem;
340 else
341 p->rtgmem_size = 0;
342 err = 1;
343 }
344
345 if ((p->z3fastmem_size & (p->z3fastmem_size - 1)) != 0
346 || (p->z3fastmem_size != 0 && (p->z3fastmem_size < 0x100000 || p->z3fastmem_size > max_z3fastmem)))
347 {
348 write_log (_T("Unsupported Zorro III fastmem size %x (%x)!\n"), p->z3fastmem_size, max_z3fastmem);
349 if (p->z3fastmem_size > max_z3fastmem)
350 p->z3fastmem_size = max_z3fastmem;
351 else
352 p->z3fastmem_size = 0;
353 err = 1;
354 }
355 if ((p->z3fastmem2_size & (p->z3fastmem2_size - 1)) != 0
356 || (p->z3fastmem2_size != 0 && (p->z3fastmem2_size < 0x100000 || p->z3fastmem2_size > max_z3fastmem)))
357 {
358 write_log (_T("Unsupported Zorro III fastmem size %x (%x)!\n"), p->z3fastmem2_size, max_z3fastmem);
359 if (p->z3fastmem2_size > max_z3fastmem)
360 p->z3fastmem2_size = max_z3fastmem;
361 else
362 p->z3fastmem2_size = 0;
363 err = 1;
364 }
365 p->z3fastmem_start &= ~0xffff;
366 if (p->z3fastmem_start < 0x1000000)
367 p->z3fastmem_start = 0x1000000;
368 if ((p->z3chipmem_size & (p->z3chipmem_size - 1)) != 0
369 || (p->z3chipmem_size != 0 && (p->z3chipmem_size < 0x100000 || p->z3chipmem_size > max_z3fastmem)))
370 {
371 write_log (_T("Unsupported Zorro III fake chipmem size %x (%x)!\n"), p->z3chipmem_size, max_z3fastmem);
372 if (p->z3chipmem_size > max_z3fastmem)
373 p->z3chipmem_size = max_z3fastmem;
374 else
375 p->z3chipmem_size = 0;
376 err = 1;
377 }
378
379 if (p->address_space_24 && (p->z3fastmem_size != 0 || p->z3fastmem2_size != 0 || p->z3chipmem_size != 0)) {
380 p->z3fastmem_size = p->z3fastmem2_size = p->z3chipmem_size = 0;
381 write_log (_T("Can't use a graphics card or 32-bit memory when using a 24 bit\naddress space.\n"));
382 }
383 if (p->bogomem_size != 0 && p->bogomem_size != 0x80000 && p->bogomem_size != 0x100000 && p->bogomem_size != 0x180000 && p->bogomem_size != 0x1c0000) {
384 p->bogomem_size = 0;
385 write_log (_T("Unsupported bogomem size!\n"));
386 err = 1;
387 }
388 if (p->bogomem_size > 0x180000 && (p->cs_fatgaryrev >= 0 || p->cs_ide || p->cs_ramseyrev >= 0)) {
389 p->bogomem_size = 0x180000;
390 write_log (_T("Possible Gayle bogomem conflict fixed\n"));
391 }
392 if (p->chipmem_size > 0x200000 && p->fastmem_size != 0) {
393 write_log (_T("You can't use fastmem and more than 2MB chip at the same time!\n"));
394 p->fastmem_size = 0;
395 err = 1;
396 }
397 if (p->mbresmem_low_size > 0x04000000 || (p->mbresmem_low_size & 0xfffff)) {
398 p->mbresmem_low_size = 0;
399 write_log (_T("Unsupported A3000 MB RAM size\n"));
400 }
401 if (p->mbresmem_high_size > 0x04000000 || (p->mbresmem_high_size & 0xfffff)) {
402 p->mbresmem_high_size = 0;
403 write_log (_T("Unsupported Motherboard RAM size\n"));
404 }
405
406 if (p->address_space_24 && p->rtgmem_size)
407 p->rtgmem_type = 0;
408 if (!p->rtgmem_type && (p->chipmem_size > 2 * 1024 * 1024 || getz2size (p) > 8 * 1024 * 1024 || getz2size (p) < 0)) {
409 p->rtgmem_size = 0;
410 write_log (_T("Too large Z2 RTG memory size\n"));
411 }
412
413
414 #if 0
415 if (p->m68k_speed < -1 || p->m68k_speed > 20) {
416 write_log (_T("Bad value for -w parameter: must be -1, 0, or within 1..20.\n"));
417 p->m68k_speed = 4;
418 err = 1;
419 }
420 #endif
421
422 if (p->produce_sound < 0 || p->produce_sound > 3) {
423 write_log (_T("Bad value for -S parameter: enable value must be within 0..3\n"));
424 p->produce_sound = 0;
425 err = 1;
426 }
427 #ifdef JIT
428 if (p->comptrustbyte < 0 || p->comptrustbyte > 3) {
429 write_log (_T("Bad value for comptrustbyte parameter: value must be within 0..2\n"));
430 p->comptrustbyte = 1;
431 err = 1;
432 }
433 if (p->comptrustword < 0 || p->comptrustword > 3) {
434 write_log (_T("Bad value for comptrustword parameter: value must be within 0..2\n"));
435 p->comptrustword = 1;
436 err = 1;
437 }
438 if (p->comptrustlong < 0 || p->comptrustlong > 3) {
439 write_log (_T("Bad value for comptrustlong parameter: value must be within 0..2\n"));
440 p->comptrustlong = 1;
441 err = 1;
442 }
443 if (p->comptrustnaddr < 0 || p->comptrustnaddr > 3) {
444 write_log (_T("Bad value for comptrustnaddr parameter: value must be within 0..2\n"));
445 p->comptrustnaddr = 1;
446 err = 1;
447 }
448 if (p->cachesize < 0 || p->cachesize > 16384) {
449 write_log (_T("Bad value for cachesize parameter: value must be within 0..16384\n"));
450 p->cachesize = 0;
451 err = 1;
452 }
453 #endif
454 if (p->z3fastmem_size > 0 && (p->address_space_24 || p->cpu_model < 68020)) {
455 write_log (_T("Z3 fast memory can't be used with a 68000/68010 emulation. It\n"));
456 write_log (_T("requires a 68020 emulation. Turning off Z3 fast memory.\n"));
457 p->z3fastmem_size = 0;
458 err = 1;
459 }
460 if (p->rtgmem_size > 0 && p->rtgmem_type && (p->cpu_model < 68020 || p->address_space_24)) {
461 write_log (_T("RTG can't be used with a 68000/68010 or 68EC020 emulation. It\n"));
462 write_log (_T("requires a 68020 emulation. Turning off RTG.\n"));
463 p->rtgmem_size = 0;
464 err = 1;
465 }
466 #if !defined (BSDSOCKET)
467 if (p->socket_emu) {
468 write_log (_T("Compile-time option of BSDSOCKET_SUPPORTED was not enabled. You can't use bsd-socket emulation.\n"));
469 p->socket_emu = 0;
470 err = 1;
471 }
472 #endif
473
474 if (p->nr_floppies < 0 || p->nr_floppies > 4) {
475 write_log (_T("Invalid number of floppies. Using 4.\n"));
476 p->nr_floppies = 4;
477 p->floppyslots[0].dfxtype = 0;
478 p->floppyslots[1].dfxtype = 0;
479 p->floppyslots[2].dfxtype = 0;
480 p->floppyslots[3].dfxtype = 0;
481 err = 1;
482 }
483 if (p->floppy_speed > 0 && p->floppy_speed < 10) {
484 p->floppy_speed = 100;
485 }
486 if (p->input_mouse_speed < 1 || p->input_mouse_speed > 1000) {
487 p->input_mouse_speed = 100;
488 }
489 if (p->collision_level < 0 || p->collision_level > 3) {
490 write_log (_T("Invalid collision support level. Using 1.\n"));
491 p->collision_level = 1;
492 err = 1;
493 }
494 if (p->parallel_postscript_emulation)
495 p->parallel_postscript_detection = 1;
496 if (p->cs_compatible == 1) {
497 p->cs_fatgaryrev = p->cs_ramseyrev = p->cs_mbdmac = -1;
498 p->cs_ide = 0;
499 if (p->cpu_model >= 68020) {
500 p->cs_fatgaryrev = 0;
501 p->cs_ide = -1;
502 p->cs_ramseyrev = 0x0f;
503 p->cs_mbdmac = 0;
504 }
505 } else if (p->cs_compatible == 0) {
506 if (p->cs_ide == IDE_A4000) {
507 if (p->cs_fatgaryrev < 0)
508 p->cs_fatgaryrev = 0;
509 if (p->cs_ramseyrev < 0)
510 p->cs_ramseyrev = 0x0f;
511 }
512 }
513 /* Can't fit genlock and A2024 or Graffiti at the same time,
514 * also Graffiti uses genlock audio bit as an enable signal
515 */
516 if (p->genlock && p->monitoremu)
517 p->genlock = false;
518
519
520 fixup_prefs_dimensions (p);
521
522 #if !defined (JIT)
523 p->cachesize = 0;
524 #endif
525 #ifdef CPU_68000_ONLY
526 p->cpu_model = 68000;
527 p->fpu_model = 0;
528 #endif
529 #ifndef CPUEMU_0
530 p->cpu_compatible = 1;
531 p->address_space_24 = 1;
532 #endif
533 #if !defined (CPUEMU_11) && !defined (CPUEMU_12)
534 p->cpu_compatible = 0;
535 p->address_space_24 = 0;
536 #endif
537 #if !defined (CPUEMU_12)
538 p->cpu_cycle_exact = p->blitter_cycle_exact = 0;
539 #endif
540 #ifndef AGA
541 p->chipset_mask &= ~CSMASK_AGA;
542 #endif
543 #ifndef AUTOCONFIG
544 p->z3fastmem_size = 0;
545 p->fastmem_size = 0;
546 p->rtgmem_size = 0;
547 #endif
548 #if !defined (BSDSOCKET)
549 p->socket_emu = 0;
550 #endif
551 #if !defined (SCSIEMU)
552 p->scsi = 0;
553 #endif
554 #if !defined (SANA2)
555 p->sana2 = 0;
556 #endif
557 #if !defined (UAESERIAL)
558 p->uaeserial = 0;
559 #endif
560 #if defined (CPUEMU_12)
561 if (p->cpu_cycle_exact) {
562 p->gfx_framerate = 1;
563 #ifdef JIT
564 p->cachesize = 0;
565 #endif
566 p->m68k_speed = 0;
567 }
568 #endif
569 if (p->maprom && !p->address_space_24)
570 p->maprom = 0x0f000000;
571 if ((p->maprom & 0xff000000) && p->address_space_24)
572 p->maprom = 0x00e00000;
573 if (p->tod_hack && p->cs_ciaatod == 0)
574 p->cs_ciaatod = p->ntscmode ? 2 : 1;
575
576 built_in_chipset_prefs (p);
577 #ifdef SCSIEMU
578 blkdev_fix_prefs (p);
579 #endif
580 target_fixup_options (p);
581 }
582
583 int quit_program = 0;
584 static int restart_program;
585 static TCHAR restart_config[MAX_DPATH];
586 static int default_config;
587
uae_reset(int hardreset,int keyboardreset)588 void uae_reset (int hardreset, int keyboardreset)
589 {
590 if (debug_dma) {
591 record_dma_reset ();
592 record_dma_reset ();
593 }
594 currprefs.quitstatefile[0] = changed_prefs.quitstatefile[0] = 0;
595
596 if (quit_program == 0) {
597 quit_program = -UAE_RESET;
598 if (keyboardreset)
599 quit_program = -UAE_RESET_KEYBOARD;
600 if (hardreset)
601 quit_program = -UAE_RESET_HARD;
602 }
603
604 }
605
uae_quit(void)606 void uae_quit (void)
607 {
608 deactivate_debugger ();
609 if (quit_program != -UAE_QUIT)
610 quit_program = -UAE_QUIT;
611 target_quit ();
612 }
613
614 /* 0 = normal, 1 = nogui, -1 = disable nogui */
uae_restart(int opengui,const TCHAR * cfgfile)615 void uae_restart (int opengui, const TCHAR *cfgfile)
616 {
617 uae_quit ();
618 restart_program = opengui > 0 ? 1 : (opengui == 0 ? 2 : 3);
619 restart_config[0] = 0;
620 default_config = 0;
621 if (cfgfile)
622 _tcscpy (restart_config, cfgfile);
623 target_restart ();
624 }
625
626 #ifndef DONT_PARSE_CMDLINE
627
usage(void)628 void usage (void)
629 {
630 }
parse_cmdline_2(int argc,TCHAR ** argv)631 static void parse_cmdline_2 (int argc, TCHAR **argv)
632 {
633 int i;
634
635 cfgfile_addcfgparam (0);
636 for (i = 1; i < argc; i++) {
637 if (_tcsncmp (argv[i], _T("-cfgparam="), 10) == 0) {
638 cfgfile_addcfgparam (argv[i] + 10);
639 } else if (_tcscmp (argv[i], _T("-cfgparam")) == 0) {
640 if (i + 1 == argc)
641 write_log (_T("Missing argument for '-cfgparam' option.\n"));
642 else
643 cfgfile_addcfgparam (argv[++i]);
644 }
645 }
646 }
647
diskswapper_cb(struct zfile * f,void * vrsd)648 static int diskswapper_cb (struct zfile *f, void *vrsd)
649 {
650 int *num = (int*)vrsd;
651 if (*num >= MAX_SPARE_DRIVES)
652 return 1;
653 if (zfile_gettype (f) == ZFILE_DISKIMAGE) {
654 _tcsncpy (currprefs.dfxlist[*num], zfile_getname (f), 255);
655 (*num)++;
656 }
657 return 0;
658 }
659
parse_diskswapper(const TCHAR * s)660 static void parse_diskswapper (const TCHAR *s)
661 {
662 TCHAR *tmp = my_strdup (s);
663 TCHAR *delim = _T(",");
664 TCHAR *p1, *p2;
665 int num = 0;
666
667 p1 = tmp;
668 for (;;) {
669 p2 = _tcstok (p1, delim);
670 if (!p2)
671 break;
672 p1 = NULL;
673 if (num >= MAX_SPARE_DRIVES)
674 break;
675 if (!zfile_zopen (p2, diskswapper_cb, &num)) {
676 _tcsncpy (currprefs.dfxlist[num], p2, 255);
677 num++;
678 }
679 }
680 xfree (tmp);
681 }
682
parsetext(const TCHAR * s)683 static TCHAR *parsetext (const TCHAR *s)
684 {
685 if (*s == '"' || *s == '\'') {
686 TCHAR *d;
687 TCHAR c = *s++;
688 int i;
689 d = my_strdup (s);
690 for (i = 0; i < (int)_tcslen (d); i++) {
691 if (d[i] == c) {
692 d[i] = 0;
693 break;
694 }
695 }
696 return d;
697 } else {
698 return my_strdup (s);
699 }
700 }
parsetextpath(const TCHAR * s)701 static TCHAR *parsetextpath (const TCHAR *s)
702 {
703 TCHAR *s3 = parsetext (s);
704 //TCHAR *s3 = target_expand_environment (s2);
705 //xfree (s2);
706 return s3;
707 }
708
parse_cmdline(int argc,TCHAR ** argv)709 static void parse_cmdline (int argc, TCHAR **argv)
710 {
711 int i;
712
713 for (i = 1; i < argc; i++) {
714 if (!_tcsncmp (argv[i], _T("-diskswapper="), 13)) {
715 TCHAR *txt = parsetextpath (argv[i] + 13);
716 parse_diskswapper (txt);
717 xfree (txt);
718 } else if (_tcsncmp (argv[i], _T("-cfgparam="), 10) == 0) {
719 ;
720 } else if (_tcscmp (argv[i], _T("-cfgparam")) == 0) {
721 if (i + 1 < argc)
722 i++;
723 } else if (_tcsncmp (argv[i], _T("-config="), 8) == 0) {
724 TCHAR *txt = parsetextpath (argv[i] + 8);
725 currprefs.mountitems = 0;
726 target_cfgfile_load (&currprefs, txt, -1, 0);
727 xfree (txt);
728 } else if (_tcsncmp (argv[i], _T("-statefile="), 11) == 0) {
729 #ifdef SAVESTATE
730 TCHAR *txt = parsetextpath (argv[i] + 11);
731 savestate_state = STATE_DORESTORE;
732 _tcscpy (savestate_fname, txt);
733 xfree (txt);
734 #else
735 write_log (_T("Option -statefile ignored:\n"));
736 write_log (_T("-> puae has been configured with --disable-save-state\n"));
737 #endif // SAVESTATE
738 } else if (_tcscmp (argv[i], _T("-f")) == 0) {
739 /* Check for new-style "-f xxx" argument, where xxx is config-file */
740 if (i + 1 == argc) {
741 write_log (_T("Missing argument for '-f' option.\n"));
742 } else {
743 TCHAR *txt = parsetextpath (argv[++i]);
744 currprefs.mountitems = 0;
745 target_cfgfile_load (&currprefs, txt, -1, 0);
746 xfree (txt);
747 }
748 } else if (_tcscmp (argv[i], _T("-s")) == 0) {
749 if (i + 1 == argc)
750 write_log (_T("Missing argument for '-s' option.\n"));
751 else
752 cfgfile_parse_line (&currprefs, argv[++i], 0);
753 } else if (_tcscmp (argv[i], _T("-h")) == 0 || _tcscmp (argv[i], _T("-help")) == 0) {
754 usage ();
755 exit (0);
756 } else if (_tcsncmp (argv[i], _T("-cdimage="), 9) == 0) {
757 TCHAR *txt = parsetextpath (argv[i] + 9);
758 TCHAR *txt2 = xmalloc(TCHAR, _tcslen(txt) + 2);
759 _tcscpy(txt2, txt);
760 if (_tcsrchr(txt2, ',') != NULL)
761 _tcscat(txt2, _T(","));
762 cfgfile_parse_option (&currprefs, _T("cdimage0"), txt2, 0);
763 xfree(txt2);
764 xfree (txt);
765 } else {
766 if (argv[i][0] == '-' && argv[i][1] != '\0') {
767 const TCHAR *arg = argv[i] + 2;
768 int extra_arg = *arg == '\0';
769 if (extra_arg)
770 arg = i + 1 < argc ? argv[i + 1] : 0;
771 if (parse_cmdline_option (&currprefs, argv[i][1], arg) && extra_arg)
772 i++;
773 }
774 }
775 }
776 }
777 #endif
778
779 #ifdef __LIBRETRO__
780 #undef OPTIONS_IN_HOME
781 #endif
782
parse_cmdline_and_init_file(int argc,TCHAR ** argv)783 static void parse_cmdline_and_init_file (int argc, TCHAR **argv)
784 {
785
786 _tcscpy (optionsfile, _T(""));
787
788 #ifdef OPTIONS_IN_HOME
789 {
790 TCHAR *home = getenv ("HOME");
791 if (home != NULL && strlen (home) < 240)
792 {
793 _tcscpy (optionsfile, home);
794 _tcscat (optionsfile, _T("/"));
795 }
796 }
797 #endif
798
799 #ifdef __LIBRETRO__
800 #ifdef ANDROID
801 _tcscpy (optionsfile, "/mnt/sdcard/euae");
802 _tcscat (optionsfile, _T("/"));
803 #else
804 _tcscpy (optionsfile, ".");
805 _tcscat (optionsfile, _T("/"));
806 #endif
807 #endif
808 parse_cmdline_2 (argc, argv);
809
810 _tcscat (optionsfile, restart_config);
811
812
813 if (argc > 1 && ! target_cfgfile_load (&currprefs, argv[1], 0, default_config)) {
814 write_log (_T("failed to load config '%s'\n"), optionsfile);
815 #ifdef OPTIONS_IN_HOME
816 /* sam: if not found in $HOME then look in current directory */
817 _tcscpy (optionsfile, restart_config);
818 target_cfgfile_load (&currprefs, optionsfile, 0, default_config);
819 #endif
820 }
821 fixup_prefs (&currprefs);
822
823 parse_cmdline (argc, argv);
824 // fixup_prefs (&currprefs); //fixup after cmdline
825 }
826
reset_all_systems(void)827 void reset_all_systems (void)
828 {
829 init_eventtab ();
830
831 #ifdef PICASSO96
832 picasso_reset ();
833 #endif
834 #ifdef SCSIEMU
835 scsi_reset ();
836 scsidev_reset ();
837 scsidev_start_threads ();
838 #endif
839 #ifdef A2065
840 a2065_reset ();
841 #endif
842 #ifdef SANA2
843 netdev_reset ();
844 netdev_start_threads ();
845 #endif
846 #ifdef FILESYS
847 filesys_prepare_reset ();
848 filesys_reset ();
849 #endif
850 #ifdef NATMEM_OFFSET
851 init_shm ();
852 #endif
853 memory_reset ();
854 #if defined (BSDSOCKET)
855 bsdlib_reset ();
856 #endif
857 #ifdef FILESYS
858 filesys_start_threads ();
859 hardfile_reset ();
860 #endif
861 #ifdef UAESERIAL
862 uaeserialdev_reset ();
863 uaeserialdev_start_threads ();
864 #endif
865 #if defined (PARALLEL_PORT)
866 initparallel ();
867 #endif
868 native2amiga_reset ();
869 dongle_reset ();
870 #ifdef SAMPLER
871 sampler_init ();
872 #endif
873 }
874
875 #ifdef __LIBRETRO__
876 //RETRO FIXME
get_current_config_name()877 const char* get_current_config_name() {
878 if (restart_config[0] == 0) {
879 return optionsfile;
880 } else {
881 return restart_config;
882 }
883 }
884 #endif
885
886 /* Okay, this stuff looks strange, but it is here to encourage people who
887 * port UAE to re-use as much of this code as possible. Functions that you
888 * should be using are do_start_program () and do_leave_program (), as well
889 * as real_main (). Some OSes don't call main () (which is braindamaged IMHO,
890 * but unfortunately very common), so you need to call real_main () from
891 * whatever entry point you have. You may want to write your own versions
892 * of start_program () and leave_program () if you need to do anything special.
893 * Add #ifdefs around these as appropriate.
894 */
895 extern unsigned int pause_uae;
do_start_program(void)896 void do_start_program (void)
897 {
898 if (quit_program == -UAE_QUIT)
899 return;
900 #ifdef JIT
901 if (!canbang && candirect < 0)
902 candirect = 0;
903 if (canbang && candirect < 0)
904 candirect = 1;
905 #endif
906 /* Do a reset on startup. Whether this is elegant is debatable. */
907 inputdevice_updateconfig (&changed_prefs, &currprefs);
908 if (quit_program >= 0)
909 quit_program = UAE_RESET;
910
911 {
912 m68k_go (1);
913 }
914 }
915
do_leave_program(void)916 void do_leave_program (void)
917 {
918 #ifdef SAMPLER
919 sampler_free ();
920 #endif
921 graphics_leave ();
922 inputdevice_close ();
923 DISK_free ();
924 close_sound ();
925 dump_counts ();
926 #ifdef SERIAL_PORT
927 serial_exit ();
928 #endif
929 #ifdef CDTV
930 cdtv_free ();
931 #endif
932 #ifdef A2091
933 a2091_free ();
934 #endif
935 #ifdef NCR
936 ncr_free ();
937 #endif
938 #ifdef CD32
939 akiko_free ();
940 #endif
941 if (! no_gui)
942 gui_exit ();
943 #ifdef USE_SDL
944 SDL_Quit ();
945 #endif
946 #ifdef AUTOCONFIG
947 expansion_cleanup ();
948 #endif
949 #ifdef FILESYS
950 filesys_cleanup ();
951 #endif
952 #ifdef BSDSOCKET
953 bsdlib_reset ();
954 #endif
955 #ifdef SCSIEMU
956 #ifdef GAYLE
957 gayle_free ();
958 #endif
959 device_func_reset ();
960 #endif
961 savestate_free ();
962 memory_cleanup ();
963 #ifdef NATMEM_OFFSET
964 free_shm ();
965 #endif
966 cfgfile_addcfgparam (0);
967 machdep_free ();
968 }
969
start_program(void)970 void start_program (void)
971 {
972 gui_display (-1);
973 do_start_program ();
974 }
975
leave_program(void)976 void leave_program (void)
977 {
978 do_leave_program ();
979 }
980
981
virtualdevice_init(void)982 void virtualdevice_init (void)
983 {
984 #ifdef AUTOCONFIG
985 /* Install resident module to get 8MB chipmem, if requested */
986 rtarea_setup ();
987 #endif
988 #ifdef FILESYS
989 rtarea_init ();
990 uaeres_install ();
991 hardfile_install ();
992 #endif
993 #ifdef SCSIEMU
994 scsi_reset ();
995 scsidev_install ();
996 #endif
997 #ifdef SANA2
998 netdev_install ();
999 #endif
1000 #ifdef UAESERIAL
1001 uaeserialdev_install ();
1002 #endif
1003 #ifdef AUTOCONFIG
1004 expansion_init ();
1005 emulib_install ();
1006 uaeexe_install ();
1007 #endif
1008 #ifdef FILESYS
1009 filesys_install ();
1010 #endif
1011 #if defined (BSDSOCKET)
1012 bsdlib_install ();
1013 #endif
1014 }
1015
real_main2(int argc,TCHAR ** argv)1016 static int real_main2 (int argc, TCHAR **argv)
1017 {
1018 #ifdef USE_SDL
1019 int result = (SDL_Init (SDL_INIT_TIMER | SDL_INIT_JOYSTICK | SDL_INIT_NOPARACHUTE) == 0);
1020 if (result)
1021 atexit (SDL_Quit);
1022 #endif
1023 config_changed = 1;
1024 if (restart_config[0]) {
1025 default_prefs (&currprefs, 0);
1026 fixup_prefs (&currprefs);
1027 }
1028
1029 if (! graphics_setup ()) {
1030 write_log (_T("Graphics Setup Failed\n"));
1031 exit (1);
1032 }
1033
1034 if (restart_config[0])
1035 parse_cmdline_and_init_file (argc, argv);
1036 else
1037 currprefs = changed_prefs;
1038
1039 // uae_inithrtimer ();
1040
1041 if (!machdep_init ()) {
1042 write_log (_T("Machine Init Failed.\n"));
1043 restart_program = 0;
1044 return -1;
1045 }
1046
1047 if (console_emulation) {
1048 consolehook_config (&currprefs);
1049 fixup_prefs (&currprefs);
1050 }
1051
1052 if (! setup_sound ()) {
1053 write_log (_T("Sound driver unavailable: Sound output disabled\n"));
1054 currprefs.produce_sound = 0;
1055 }
1056 inputdevice_init ();
1057
1058 changed_prefs = currprefs;
1059 no_gui = ! currprefs.start_gui;
1060
1061 if (restart_program == 2)
1062 no_gui = 1;
1063 else if (restart_program == 3)
1064 no_gui = 0;
1065
1066 restart_program = 0;
1067 if (! no_gui && currprefs.start_gui) {
1068 int err = gui_init ();
1069 currprefs = changed_prefs;
1070 config_changed = 1;
1071
1072 if (err == -1) {
1073 write_log (_T("Failed to initialize the GUI\n"));
1074 return -1;
1075 } else if (err == -2) {
1076 return 1;
1077 }
1078 }
1079
1080 memset (&gui_data, 0, sizeof gui_data);
1081 gui_data.cd = -1;
1082 gui_data.hd = -1;
1083 gui_data.net = -1;
1084 gui_data.md = (currprefs.cs_cd32nvram || currprefs.cs_cdtvram) ? 0 : -1;
1085
1086 #ifdef NATMEM_OFFSET
1087 init_shm ();
1088 #endif
1089
1090 #ifdef PICASSO96
1091 picasso_reset ();
1092 #endif
1093
1094 fixup_prefs (&currprefs);
1095
1096 #ifdef RETROPLATFORM
1097 rp_fixup_options (&currprefs);
1098 #endif
1099
1100 changed_prefs = currprefs;
1101 target_run ();
1102 /* force sound settings change */
1103 currprefs.produce_sound = 0;
1104
1105 savestate_init ();
1106 keybuf_init (); /* Must come after init_joystick */
1107
1108 memory_hardreset (2);
1109 memory_reset ();
1110
1111 #ifdef AUTOCONFIG
1112 native2amiga_install ();
1113 #endif
1114
1115 custom_init (); /* Must come after memory_init */
1116
1117 #ifdef SERIAL_PORT
1118 serial_init ();
1119 #endif
1120
1121 DISK_init ();
1122
1123 reset_frame_rate_hack ();
1124 init_m68k (); /* must come after reset_frame_rate_hack (); */
1125
1126 gui_update ();
1127
1128 if (graphics_init ()) {
1129
1130 #ifdef DEBUGGER
1131 setup_brkhandler ();
1132 if (currprefs.start_debugger && debuggable ())
1133 activate_debugger ();
1134 #endif
1135
1136 if (!init_audio ()) {
1137 if (sound_available && currprefs.produce_sound > 1) {
1138 write_log (_T("Sound driver unavailable: Sound output disabled\n"));
1139 }
1140 currprefs.produce_sound = 0;
1141 }
1142 start_program ();
1143 }
1144
1145 return 0;
1146 }
1147
real_main(int argc,TCHAR ** argv)1148 void real_main (int argc, TCHAR **argv)
1149 {
1150 show_version_full ();
1151 restart_program = 1;
1152
1153 fetch_configurationpath (restart_config, sizeof (restart_config) / sizeof (TCHAR));
1154
1155 if(argc>1) {
1156 _tcscat (restart_config, argv[1]);
1157 } else _tcscat (restart_config, OPTIONSFILENAME);
1158 default_config = 1;
1159
1160 #ifdef NATMEM_OFFSET
1161 preinit_shm ();
1162 #endif
1163
1164 write_log (_T("Enumerating display devices.. \n"));
1165 #ifndef __LIBRETRO__
1166 enumeratedisplays ();
1167 #endif
1168 write_log (_T("Sorting devices and modes..\n"));
1169 #ifndef __LIBRETRO__
1170 sortdisplays ();
1171 #endif
1172 // write_log (_T("Display buffer mode = %d\n"), ddforceram);
1173 // enumerate_sound_devices ();
1174 write_log (_T("done\n"));
1175
1176 keyboard_settrans ();
1177 #ifdef CATWEASEL
1178 catweasel_init ();
1179 #endif
1180 #ifdef PARALLEL_PORT
1181 paraport_mask = paraport_init ();
1182 #endif
1183 while (restart_program) {
1184 int ret;
1185 changed_prefs = currprefs;
1186 ret = real_main2 (argc, argv);
1187 if (ret == 0 && quit_to_gui)
1188 restart_program = 1;
1189 leave_program ();
1190 quit_program = 0;
1191 }
1192 zfile_exit ();
1193 }
1194
1195 #ifndef NO_MAIN_IN_MAIN_C
1196 #ifdef __LIBRETRO__
umain(int argc,TCHAR ** argv)1197 int umain (int argc, TCHAR **argv)
1198 #else
1199 int main (int argc, TCHAR **argv)
1200 #endif
1201 {
1202 real_main (argc, argv);
1203 return 0;
1204 }
1205 #endif
1206
1207 #ifdef SINGLEFILE
1208 uae_u8 singlefile_config[50000] = { "_CONFIG_STARTS_HERE" };
1209 uae_u8 singlefile_data[1500000] = { "_DATA_STARTS_HERE" };
1210 #endif
1211