|
|
1.1 root 1: /*
2: Hatari - change.c
3:
1.1.1.8 ! root 4: This file is distributed under the GNU General Public License, version 2
! 5: or at your option any later version. Read the file gpl.txt for details.
1.1 root 6:
7: This code handles run-time configuration changes. We keep all our
8: configuration details in a structure called 'ConfigureParams'. Before
9: doing he changes, a backup copy is done of this structure. When
10: the changes are done, these are compared to see whether emulator
1.1.1.2 root 11: needs to be rebooted
1.1 root 12: */
1.1.1.2 root 13: const char Change_fileid[] = "Hatari change.c : " __DATE__ " " __TIME__;
1.1 root 14:
15: #include <ctype.h>
16: #include "main.h"
17: #include "configuration.h"
18: #include "audio.h"
19: #include "change.h"
20: #include "dialog.h"
21: #include "floppy.h"
22: #include "gemdos.h"
23: #include "hdc.h"
1.1.1.3 root 24: #include "ide.h"
1.1 root 25: #include "ioMem.h"
26: #include "joy.h"
27: #include "keymap.h"
28: #include "m68000.h"
1.1.1.2 root 29: #include "midi.h"
1.1 root 30: #include "options.h"
31: #include "printer.h"
32: #include "reset.h"
33: #include "rs232.h"
34: #include "screen.h"
35: #include "sound.h"
36: #include "statusbar.h"
37: #include "tos.h"
38: #include "vdi.h"
39: #include "video.h"
40: #include "hatari-glue.h"
41: #if ENABLE_DSP_EMU
42: # include "falcon/dsp.h"
43: #endif
44:
1.1.1.5 root 45: #define DEBUG 0
46: #if DEBUG
47: #define Dprintf(a) printf(a)
48: #else
49: #define Dprintf(a)
50: #endif
1.1 root 51:
52: /*-----------------------------------------------------------------------*/
53: /**
54: * Check if user needs to be warned that changes will take place after reset.
1.1.1.3 root 55: * Return true if wants to reset.
1.1 root 56: */
57: bool Change_DoNeedReset(CNF_PARAMS *current, CNF_PARAMS *changed)
58: {
59: /* Did we change monitor type? If so, must reset */
60: if (current->Screen.nMonitorType != changed->Screen.nMonitorType
61: && (changed->System.nMachineType == MACHINE_FALCON
62: || current->Screen.nMonitorType == MONITOR_TYPE_MONO
63: || changed->Screen.nMonitorType == MONITOR_TYPE_MONO))
1.1.1.3 root 64: return true;
1.1 root 65:
66: /* Did change to GEM VDI display? */
67: if (current->Screen.bUseExtVdiResolutions != changed->Screen.bUseExtVdiResolutions)
1.1.1.3 root 68: return true;
1.1 root 69:
70: /* Did change GEM resolution or color depth? */
71: if (changed->Screen.bUseExtVdiResolutions &&
72: (current->Screen.nVdiWidth != changed->Screen.nVdiWidth
73: || current->Screen.nVdiHeight != changed->Screen.nVdiHeight
74: || current->Screen.nVdiColors != changed->Screen.nVdiColors))
1.1.1.3 root 75: return true;
1.1 root 76:
77: /* Did change TOS ROM image? */
78: if (strcmp(changed->Rom.szTosImageFileName, current->Rom.szTosImageFileName))
1.1.1.3 root 79: return true;
1.1 root 80:
1.1.1.3 root 81: /* Did change ACSI hard disk image? */
1.1 root 82: if (changed->HardDisk.bUseHardDiskImage != current->HardDisk.bUseHardDiskImage
83: || (strcmp(changed->HardDisk.szHardDiskImage, current->HardDisk.szHardDiskImage)
84: && changed->HardDisk.bUseHardDiskImage))
1.1.1.3 root 85: return true;
86:
1.1.1.4 root 87: /* Did change IDE master hard disk image? */
88: if (changed->HardDisk.bUseIdeMasterHardDiskImage != current->HardDisk.bUseIdeMasterHardDiskImage
89: || strcmp(changed->HardDisk.szIdeMasterHardDiskImage, current->HardDisk.szIdeMasterHardDiskImage))
90: return true;
91:
92: /* Did change IDE slave hard disk image? */
93: if (changed->HardDisk.bUseIdeSlaveHardDiskImage != current->HardDisk.bUseIdeSlaveHardDiskImage
94: || strcmp(changed->HardDisk.szIdeSlaveHardDiskImage, current->HardDisk.szIdeSlaveHardDiskImage))
1.1.1.3 root 95: return true;
1.1 root 96:
97: /* Did change GEMDOS drive? */
98: if (changed->HardDisk.bUseHardDiskDirectories != current->HardDisk.bUseHardDiskDirectories
99: || (strcmp(changed->HardDisk.szHardDiskDirectories[0], current->HardDisk.szHardDiskDirectories[0])
100: && changed->HardDisk.bUseHardDiskDirectories))
1.1.1.3 root 101: return true;
1.1 root 102:
103: /* Did change machine type? */
104: if (changed->System.nMachineType != current->System.nMachineType)
1.1.1.3 root 105: return true;
1.1.1.8 ! root 106: /* did change ST Blitter? */
! 107: else if (current->System.nMachineType == MACHINE_ST &&
! 108: current->System.bBlitter != changed->System.bBlitter)
! 109: return true;
1.1 root 110:
1.1.1.5 root 111: #if ENABLE_DSP_EMU
112: /* enabling DSP needs reset (disabling it not) */
113: if (current->System.nDSPType != DSP_TYPE_EMU &&
114: changed->System.nDSPType == DSP_TYPE_EMU)
115: return true;
116: #endif
117:
1.1.1.8 ! root 118: /* did change CPU type? */
! 119: if (changed->System.nCpuLevel != current->System.nCpuLevel)
! 120: return true;
! 121:
1.1.1.5 root 122: #if ENABLE_WINUAE_CPU
1.1.1.6 root 123: /* Did change CPU address mode? */
124: if (changed->System.bAddressSpace24 != current->System.bAddressSpace24)
125: return true;
126:
1.1.1.5 root 127: /* Did change CPU prefetch mode? */
128: if (changed->System.bCompatibleCpu != current->System.bCompatibleCpu)
129: return true;
130:
131: /* Did change CPU cycle exact? */
132: if (changed->System.bCycleExactCpu != current->System.bCycleExactCpu)
133: return true;
134:
135: /* Did change MMU? */
136: if (changed->System.bMMU != current->System.bMMU)
137: return true;
1.1.1.7 root 138:
139: /* Did change FPU? */
140: if (changed->System.n_FPUType != current->System.n_FPUType)
141: return true;
1.1.1.5 root 142: #endif
143:
1.1 root 144: /* Did change size of memory? */
145: if (current->Memory.nMemorySize != changed->Memory.nMemorySize)
1.1.1.3 root 146: return true;
1.1 root 147:
1.1.1.8 ! root 148: /* MIDI related IRQs start/stop needs reset */
! 149: if (current->Midi.bEnableMidi != changed->Midi.bEnableMidi)
! 150: return true;
! 151:
1.1.1.3 root 152: return false;
1.1 root 153: }
154:
155:
156: /*-----------------------------------------------------------------------*/
157: /**
158: * Copy details back to configuration and perform reset.
159: */
160: void Change_CopyChangedParamsToConfiguration(CNF_PARAMS *current, CNF_PARAMS *changed, bool bForceReset)
161: {
162: bool NeedReset;
1.1.1.3 root 163: bool bReInitGemdosDrive = false;
164: bool bReInitAcsiEmu = false;
165: bool bReInitIDEEmu = false;
166: bool bReInitIoMem = false;
167: bool bScreenModeChange = false;
168: bool bReInitMidi = false;
1.1.1.7 root 169: bool bReInitPrinter = false;
1.1 root 170: bool bFloppyInsert[MAX_FLOPPYDRIVES];
171: int i;
172:
1.1.1.5 root 173: Dprintf("Changes for:\n");
1.1 root 174: /* Do we need to warn user that changes will only take effect after reset? */
175: if (bForceReset)
176: NeedReset = bForceReset;
177: else
178: NeedReset = Change_DoNeedReset(current, changed);
179:
180: /* Do need to change resolution? Need if change display/overscan settings
181: * (if switch between Colour/Mono cause reset later) or toggle statusbar
182: */
183: if (!NeedReset &&
184: (changed->Screen.nForceBpp != current->Screen.nForceBpp
1.1.1.4 root 185: || changed->Screen.bAspectCorrect != current->Screen.bAspectCorrect
186: || changed->Screen.nMaxWidth != current->Screen.nMaxWidth
187: || changed->Screen.nMaxHeight != current->Screen.nMaxHeight
1.1 root 188: || changed->Screen.bAllowOverscan != current->Screen.bAllowOverscan
189: || changed->Screen.bShowStatusbar != current->Screen.bShowStatusbar))
190: {
1.1.1.5 root 191: Dprintf("- screenmode>\n");
1.1.1.3 root 192: bScreenModeChange = true;
1.1 root 193: }
194:
195: /* Did set new printer parameters? */
196: if (changed->Printer.bEnablePrinting != current->Printer.bEnablePrinting
197: || strcmp(changed->Printer.szPrintToFileName,current->Printer.szPrintToFileName))
198: {
1.1.1.5 root 199: Dprintf("- printer>\n");
1.1.1.7 root 200: Printer_UnInit();
201: bReInitPrinter = true;
1.1 root 202: }
203:
204: /* Did set new RS232 parameters? */
205: if (changed->RS232.bEnableRS232 != current->RS232.bEnableRS232
206: || strcmp(changed->RS232.szOutFileName, current->RS232.szOutFileName)
207: || strcmp(changed->RS232.szInFileName, current->RS232.szInFileName))
208: {
1.1.1.5 root 209: Dprintf("- RS-232>\n");
1.1 root 210: RS232_UnInit();
211: }
212:
213: /* Did stop sound? Or change playback Hz. If so, also stop sound recording */
1.1.1.3 root 214: if (!changed->Sound.bEnableSound || changed->Sound.nPlaybackFreq != current->Sound.nPlaybackFreq)
1.1 root 215: {
1.1.1.5 root 216: Dprintf("- sound>\n");
1.1 root 217: if (Sound_AreWeRecording())
218: Sound_EndRecording();
219: Audio_UnInit();
220: }
221:
222: /* Did change floppy (images)? */
223: for (i = 0; i < MAX_FLOPPYDRIVES; i++)
224: {
225: /*
226: Log_Printf(LOG_DEBUG, "Old and new disk %c:\n\t%s\n\t%s", 'A'+i,
227: current->DiskImage.szDiskFileName[i],
228: changed->DiskImage.szDiskFileName[i]);
229: */
230: if (strcmp(changed->DiskImage.szDiskFileName[i],
231: current->DiskImage.szDiskFileName[i])
232: || strcmp(changed->DiskImage.szDiskZipPath[i],
233: current->DiskImage.szDiskZipPath[i]))
1.1.1.3 root 234: bFloppyInsert[i] = true;
1.1 root 235: else
1.1.1.3 root 236: bFloppyInsert[i] = false;
1.1 root 237: }
238:
239: /* Did change GEMDOS drive? */
240: if (changed->HardDisk.bUseHardDiskDirectories != current->HardDisk.bUseHardDiskDirectories
241: || (strcmp(changed->HardDisk.szHardDiskDirectories[0], current->HardDisk.szHardDiskDirectories[0])
242: && changed->HardDisk.bUseHardDiskDirectories))
243: {
1.1.1.5 root 244: Dprintf("- gemdos HD>\n");
1.1 root 245: GemDOS_UnInitDrives();
1.1.1.3 root 246: bReInitGemdosDrive = true;
1.1 root 247: }
248:
249: /* Did change HD image? */
250: if (changed->HardDisk.bUseHardDiskImage != current->HardDisk.bUseHardDiskImage
251: || (strcmp(changed->HardDisk.szHardDiskImage, current->HardDisk.szHardDiskImage)
252: && changed->HardDisk.bUseHardDiskImage))
253: {
1.1.1.5 root 254: Dprintf("- HD image>\n");
1.1 root 255: HDC_UnInit();
1.1.1.3 root 256: bReInitAcsiEmu = true;
257: }
258:
1.1.1.4 root 259: /* Did change IDE HD master image? */
260: if (changed->HardDisk.bUseIdeMasterHardDiskImage != current->HardDisk.bUseIdeMasterHardDiskImage
261: || (strcmp(changed->HardDisk.szIdeMasterHardDiskImage, current->HardDisk.szIdeMasterHardDiskImage)
262: && changed->HardDisk.bUseIdeMasterHardDiskImage))
263: {
1.1.1.5 root 264: Dprintf("- IDE master>\n");
1.1.1.4 root 265: Ide_UnInit();
266: bReInitIDEEmu = true;
267: }
268:
269: /* Did change IDE HD slave image? */
270: if (changed->HardDisk.bUseIdeSlaveHardDiskImage != current->HardDisk.bUseIdeSlaveHardDiskImage
271: || (strcmp(changed->HardDisk.szIdeSlaveHardDiskImage, current->HardDisk.szIdeSlaveHardDiskImage)
272: && changed->HardDisk.bUseIdeSlaveHardDiskImage))
1.1.1.3 root 273: {
1.1.1.5 root 274: Dprintf("- IDE slave>\n");
1.1.1.3 root 275: Ide_UnInit();
276: bReInitIDEEmu = true;
1.1 root 277: }
278:
279: /* Did change blitter, rtc or system type? */
280: if (changed->System.bBlitter != current->System.bBlitter
281: #if ENABLE_DSP_EMU
282: || changed->System.nDSPType != current->System.nDSPType
283: #endif
284: || changed->System.bRealTimeClock != current->System.bRealTimeClock
285: || changed->System.nMachineType != current->System.nMachineType)
286: {
1.1.1.5 root 287: Dprintf("- blitter/rtc/dsp/machine>\n");
1.1 root 288: IoMem_UnInit();
1.1.1.3 root 289: bReInitIoMem = true;
1.1 root 290: }
291:
292: #if ENABLE_DSP_EMU
293: /* Disabled DSP? */
1.1.1.3 root 294: if (current->System.nDSPType == DSP_TYPE_EMU &&
295: changed->System.nDSPType != DSP_TYPE_EMU)
1.1 root 296: {
1.1.1.5 root 297: Dprintf("- DSP>\n");
1.1 root 298: DSP_UnInit();
299: }
300: #endif
301:
1.1.1.2 root 302: /* Did change MIDI settings? */
303: if (current->Midi.bEnableMidi != changed->Midi.bEnableMidi
304: || ((strcmp(changed->Midi.sMidiOutFileName, current->Midi.sMidiOutFileName)
305: || strcmp(changed->Midi.sMidiInFileName, current->Midi.sMidiInFileName))
306: && changed->Midi.bEnableMidi))
307: {
1.1.1.5 root 308: Dprintf("- midi>\n");
1.1.1.2 root 309: Midi_UnInit();
310: bReInitMidi = true;
311: }
312:
1.1 root 313: /* Copy details to configuration,
314: * so it can be saved out or set on reset
315: */
316: if (changed != &ConfigureParams)
317: {
318: ConfigureParams = *changed;
319: }
320:
321: /* Copy details to global, if we reset copy them all */
322: Configuration_Apply(NeedReset);
323:
324: #if ENABLE_DSP_EMU
1.1.1.3 root 325: if (current->System.nDSPType != DSP_TYPE_EMU &&
326: changed->System.nDSPType == DSP_TYPE_EMU)
1.1 root 327: {
1.1.1.5 root 328: Dprintf("- DSP<\n");
1.1 root 329: DSP_Init();
330: }
331: #endif
332:
333: /* Set keyboard remap file */
334: if (ConfigureParams.Keyboard.nKeymapType == KEYMAP_LOADED)
1.1.1.5 root 335: {
336: Dprintf("- keymap<\n");
1.1 root 337: Keymap_LoadRemapFile(ConfigureParams.Keyboard.szMappingFileName);
1.1.1.5 root 338: }
1.1 root 339:
340: /* Mount a new HD image: */
341: if (bReInitAcsiEmu && ConfigureParams.HardDisk.bUseHardDiskImage)
342: {
1.1.1.5 root 343: Dprintf("- HD<\n");
1.1.1.4 root 344: HDC_Init();
1.1 root 345: }
346:
1.1.1.4 root 347: /* Mount a new IDE HD master or slave image: */
348: if (bReInitIDEEmu && (ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage || ConfigureParams.HardDisk.bUseIdeSlaveHardDiskImage))
1.1.1.3 root 349: {
1.1.1.5 root 350: Dprintf("- IDE<\n");
1.1.1.3 root 351: Ide_Init();
352: }
353:
1.1 root 354: /* Insert floppies? */
355: for (i = 0; i < MAX_FLOPPYDRIVES; i++)
356: {
357: if (bFloppyInsert[i])
1.1.1.5 root 358: {
359: Dprintf("- floppy<\n");
1.1 root 360: Floppy_InsertDiskIntoDrive(i);
1.1.1.5 root 361: }
1.1 root 362: }
363:
364: /* Mount a new GEMDOS drive? */
365: if (bReInitGemdosDrive && ConfigureParams.HardDisk.bUseHardDiskDirectories)
366: {
1.1.1.5 root 367: Dprintf("- gemdos HD<\n");
1.1 root 368: GemDOS_InitDrives();
369: }
370:
371: /* Restart audio sub system if necessary: */
372: if (ConfigureParams.Sound.bEnableSound && !bSoundWorking)
373: {
1.1.1.5 root 374: Dprintf("- audio<\n");
1.1 root 375: Audio_Init();
376: }
377:
378: /* Re-initialize the RS232 emulation: */
1.1.1.7 root 379: if (ConfigureParams.RS232.bEnableRS232)
1.1 root 380: {
1.1.1.5 root 381: Dprintf("- RS-232<\n");
1.1 root 382: RS232_Init();
383: }
384:
385: /* Re-init IO memory map? */
386: if (bReInitIoMem)
387: {
1.1.1.5 root 388: Dprintf("- IO mem<\n");
1.1 root 389: IoMem_Init();
390: }
391:
1.1.1.7 root 392: /* Re-init Printer emulation? */
393: if (bReInitPrinter)
394: {
395: Dprintf("- printer<\n");
396: Printer_Init();
397: }
398:
1.1.1.2 root 399: /* Re-init MIDI emulation? */
400: if (bReInitMidi)
401: {
1.1.1.5 root 402: Dprintf("- midi<\n");
1.1.1.2 root 403: Midi_Init();
404: }
405:
1.1 root 406: /* Force things associated with screen change */
407: if (bScreenModeChange)
408: {
1.1.1.5 root 409: Dprintf("- screenmode<\n");
1.1 root 410: Screen_ModeChanged();
411: }
412:
413: /* Do we need to perform reset? */
414: if (NeedReset)
415: {
1.1.1.5 root 416: Dprintf("- reset\n");
1.1 root 417: Reset_Cold();
418: }
419:
420: /* Go into/return from full screen if flagged */
421: if (!bInFullScreen && ConfigureParams.Screen.bFullScreen)
422: Screen_EnterFullScreen();
423: else if (bInFullScreen && !ConfigureParams.Screen.bFullScreen)
424: Screen_ReturnFromFullScreen();
1.1.1.4 root 425:
426: /* update statusbar info (CPU, MHz, mem etc) */
427: Statusbar_UpdateInfo();
1.1.1.5 root 428: Dprintf("done.\n");
1.1 root 429: }
430:
431:
432: /*-----------------------------------------------------------------------*/
433: /**
434: * Change given Hatari options
1.1.1.3 root 435: * Return false if parsing failed, true otherwise
1.1 root 436: */
437: static bool Change_Options(int argc, const char *argv[])
438: {
439: bool bOK;
440: CNF_PARAMS current;
441:
1.1.1.3 root 442: Main_PauseEmulation(false);
1.1 root 443:
444: /* get configuration changes */
445: current = ConfigureParams;
446: ConfigureParams.Screen.bFullScreen = bInFullScreen;
447: bOK = Opt_ParseParameters(argc, argv);
448:
449: /* Check if reset is required and ask user if he really wants to continue */
450: if (bOK && Change_DoNeedReset(¤t, &ConfigureParams)
1.1.1.5 root 451: && current.Log.nAlertDlgLogLevel > LOG_FATAL) {
1.1 root 452: bOK = DlgAlert_Query("The emulated system must be "
453: "reset to apply these changes. "
454: "Apply changes now and reset "
455: "the emulator?");
456: }
457: /* Copy details to configuration */
458: if (bOK) {
1.1.1.3 root 459: Change_CopyChangedParamsToConfiguration(¤t, &ConfigureParams, false);
1.1 root 460: } else {
461: ConfigureParams = current;
462: }
463:
464: Main_UnPauseEmulation();
465: return bOK;
466: }
467:
468:
469: /*-----------------------------------------------------------------------*/
470: /**
1.1.1.7 root 471: * Parse given command line and change Hatari options accordingly.
472: * Given string must be stripped and not empty.
1.1.1.3 root 473: * Return false if parsing failed or there were no args, true otherwise
1.1 root 474: */
475: bool Change_ApplyCommandline(char *cmdline)
476: {
477: int i, argc, inarg;
478: const char **argv;
479: bool ret;
480:
481: /* count args */
482: inarg = argc = 0;
483: for (i = 0; cmdline[i]; i++)
484: {
1.1.1.7 root 485: if (isspace(cmdline[i]) && cmdline[i-1] != '\\')
1.1 root 486: {
487: inarg = 0;
488: continue;
489: }
490: if (!inarg)
491: {
492: inarg++;
493: argc++;
494: }
495: }
496: if (!argc)
497: {
1.1.1.3 root 498: return false;
1.1 root 499: }
500: /* 2 = "hatari" + NULL */
501: argv = malloc((argc+2) * sizeof(char*));
502: if (!argv)
503: {
504: perror("command line alloc");
1.1.1.3 root 505: return false;
1.1 root 506: }
507:
508: /* parse them to array */
509: fprintf(stderr, "Command line with '%d' arguments:\n", argc);
510: inarg = argc = 0;
511: argv[argc++] = "hatari";
512: for (i = 0; cmdline[i]; i++)
513: {
514: if (isspace(cmdline[i]))
515: {
1.1.1.7 root 516: if (cmdline[i-1] != '\\')
1.1 root 517: {
1.1.1.7 root 518: cmdline[i] = '\0';
519: if (inarg)
520: {
521: fprintf(stderr, "- '%s'\n", argv[argc-1]);
522: }
523: inarg = 0;
524: continue;
525: }
526: else
527: {
528: /* remove quote for space */
529: memcpy(cmdline+i-1, cmdline+i, strlen(cmdline+i)+1);
530: i--;
1.1 root 531: }
532: }
533: if (!inarg)
534: {
535: argv[argc++] = &(cmdline[i]);
536: inarg++;
537: }
538: }
539: if (inarg)
540: {
541: fprintf(stderr, "- '%s'\n", argv[argc-1]);
542: }
543: argv[argc] = NULL;
544:
545: /* do args */
546: ret = Change_Options(argc, argv);
1.1.1.3 root 547: free((void *)argv);
1.1 root 548: return ret;
549: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.