|
|
1.1 root 1: /*
2: Hatari - change.c
3:
4: This file is distributed under the GNU Public License, version 2 or at
5: your option any later version. Read the file gpl.txt for details.
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:
45:
46: /*-----------------------------------------------------------------------*/
47: /**
48: * Check if user needs to be warned that changes will take place after reset.
1.1.1.3 root 49: * Return true if wants to reset.
1.1 root 50: */
51: bool Change_DoNeedReset(CNF_PARAMS *current, CNF_PARAMS *changed)
52: {
53: /* Did we change monitor type? If so, must reset */
54: if (current->Screen.nMonitorType != changed->Screen.nMonitorType
55: && (changed->System.nMachineType == MACHINE_FALCON
56: || current->Screen.nMonitorType == MONITOR_TYPE_MONO
57: || changed->Screen.nMonitorType == MONITOR_TYPE_MONO))
1.1.1.3 root 58: return true;
1.1 root 59:
60: /* Did change to GEM VDI display? */
61: if (current->Screen.bUseExtVdiResolutions != changed->Screen.bUseExtVdiResolutions)
1.1.1.3 root 62: return true;
1.1 root 63:
64: /* Did change GEM resolution or color depth? */
65: if (changed->Screen.bUseExtVdiResolutions &&
66: (current->Screen.nVdiWidth != changed->Screen.nVdiWidth
67: || current->Screen.nVdiHeight != changed->Screen.nVdiHeight
68: || current->Screen.nVdiColors != changed->Screen.nVdiColors))
1.1.1.3 root 69: return true;
1.1 root 70:
71: /* Did change TOS ROM image? */
72: if (strcmp(changed->Rom.szTosImageFileName, current->Rom.szTosImageFileName))
1.1.1.3 root 73: return true;
1.1 root 74:
1.1.1.3 root 75: /* Did change ACSI hard disk image? */
1.1 root 76: if (changed->HardDisk.bUseHardDiskImage != current->HardDisk.bUseHardDiskImage
77: || (strcmp(changed->HardDisk.szHardDiskImage, current->HardDisk.szHardDiskImage)
78: && changed->HardDisk.bUseHardDiskImage))
1.1.1.3 root 79: return true;
80:
1.1.1.4 ! root 81: /* Did change IDE master hard disk image? */
! 82: if (changed->HardDisk.bUseIdeMasterHardDiskImage != current->HardDisk.bUseIdeMasterHardDiskImage
! 83: || strcmp(changed->HardDisk.szIdeMasterHardDiskImage, current->HardDisk.szIdeMasterHardDiskImage))
! 84: return true;
! 85:
! 86: /* Did change IDE slave hard disk image? */
! 87: if (changed->HardDisk.bUseIdeSlaveHardDiskImage != current->HardDisk.bUseIdeSlaveHardDiskImage
! 88: || strcmp(changed->HardDisk.szIdeSlaveHardDiskImage, current->HardDisk.szIdeSlaveHardDiskImage))
1.1.1.3 root 89: return true;
1.1 root 90:
91: /* Did change GEMDOS drive? */
92: if (changed->HardDisk.bUseHardDiskDirectories != current->HardDisk.bUseHardDiskDirectories
93: || (strcmp(changed->HardDisk.szHardDiskDirectories[0], current->HardDisk.szHardDiskDirectories[0])
94: && changed->HardDisk.bUseHardDiskDirectories))
1.1.1.3 root 95: return true;
1.1 root 96:
97: /* Did change machine type? */
98: if (changed->System.nMachineType != current->System.nMachineType)
1.1.1.3 root 99: return true;
1.1 root 100:
101: /* Did change size of memory? */
102: if (current->Memory.nMemorySize != changed->Memory.nMemorySize)
1.1.1.3 root 103: return true;
1.1 root 104:
1.1.1.3 root 105: return false;
1.1 root 106: }
107:
108:
109: /*-----------------------------------------------------------------------*/
110: /**
111: * Copy details back to configuration and perform reset.
112: */
113: void Change_CopyChangedParamsToConfiguration(CNF_PARAMS *current, CNF_PARAMS *changed, bool bForceReset)
114: {
115: bool NeedReset;
1.1.1.3 root 116: bool bReInitGemdosDrive = false;
117: bool bReInitAcsiEmu = false;
118: bool bReInitIDEEmu = false;
119: bool bReInitIoMem = false;
120: bool bScreenModeChange = false;
121: bool bReInitMidi = false;
1.1 root 122: bool bFloppyInsert[MAX_FLOPPYDRIVES];
123: int i;
124:
125: /* Do we need to warn user that changes will only take effect after reset? */
126: if (bForceReset)
127: NeedReset = bForceReset;
128: else
129: NeedReset = Change_DoNeedReset(current, changed);
130:
131: /* Do need to change resolution? Need if change display/overscan settings
132: * (if switch between Colour/Mono cause reset later) or toggle statusbar
133: */
134: if (!NeedReset &&
135: (changed->Screen.nForceBpp != current->Screen.nForceBpp
1.1.1.4 ! root 136: || changed->Screen.bAspectCorrect != current->Screen.bAspectCorrect
! 137: || changed->Screen.nMaxWidth != current->Screen.nMaxWidth
! 138: || changed->Screen.nMaxHeight != current->Screen.nMaxHeight
1.1 root 139: || changed->Screen.bAllowOverscan != current->Screen.bAllowOverscan
140: || changed->Screen.bShowStatusbar != current->Screen.bShowStatusbar))
141: {
1.1.1.3 root 142: bScreenModeChange = true;
1.1 root 143: }
144:
145: /* Did set new printer parameters? */
146: if (changed->Printer.bEnablePrinting != current->Printer.bEnablePrinting
147: || changed->Printer.bPrintToFile != current->Printer.bPrintToFile
148: || strcmp(changed->Printer.szPrintToFileName,current->Printer.szPrintToFileName))
149: {
150: Printer_CloseAllConnections();
151: }
152:
153: /* Did set new RS232 parameters? */
154: if (changed->RS232.bEnableRS232 != current->RS232.bEnableRS232
155: || strcmp(changed->RS232.szOutFileName, current->RS232.szOutFileName)
156: || strcmp(changed->RS232.szInFileName, current->RS232.szInFileName))
157: {
158: RS232_UnInit();
159: }
160:
161: /* Did stop sound? Or change playback Hz. If so, also stop sound recording */
1.1.1.3 root 162: if (!changed->Sound.bEnableSound || changed->Sound.nPlaybackFreq != current->Sound.nPlaybackFreq)
1.1 root 163: {
164: if (Sound_AreWeRecording())
165: Sound_EndRecording();
166: Audio_UnInit();
167: }
168:
169: /* Did change floppy (images)? */
170: for (i = 0; i < MAX_FLOPPYDRIVES; i++)
171: {
172: /*
173: Log_Printf(LOG_DEBUG, "Old and new disk %c:\n\t%s\n\t%s", 'A'+i,
174: current->DiskImage.szDiskFileName[i],
175: changed->DiskImage.szDiskFileName[i]);
176: */
177: if (strcmp(changed->DiskImage.szDiskFileName[i],
178: current->DiskImage.szDiskFileName[i])
179: || strcmp(changed->DiskImage.szDiskZipPath[i],
180: current->DiskImage.szDiskZipPath[i]))
1.1.1.3 root 181: bFloppyInsert[i] = true;
1.1 root 182: else
1.1.1.3 root 183: bFloppyInsert[i] = false;
1.1 root 184: }
185:
186: /* Did change GEMDOS drive? */
187: if (changed->HardDisk.bUseHardDiskDirectories != current->HardDisk.bUseHardDiskDirectories
188: || (strcmp(changed->HardDisk.szHardDiskDirectories[0], current->HardDisk.szHardDiskDirectories[0])
189: && changed->HardDisk.bUseHardDiskDirectories))
190: {
191: GemDOS_UnInitDrives();
1.1.1.3 root 192: bReInitGemdosDrive = true;
1.1 root 193: }
194:
195: /* Did change HD image? */
196: if (changed->HardDisk.bUseHardDiskImage != current->HardDisk.bUseHardDiskImage
197: || (strcmp(changed->HardDisk.szHardDiskImage, current->HardDisk.szHardDiskImage)
198: && changed->HardDisk.bUseHardDiskImage))
199: {
200: HDC_UnInit();
1.1.1.3 root 201: bReInitAcsiEmu = true;
202: }
203:
1.1.1.4 ! root 204: /* Did change IDE HD master image? */
! 205: if (changed->HardDisk.bUseIdeMasterHardDiskImage != current->HardDisk.bUseIdeMasterHardDiskImage
! 206: || (strcmp(changed->HardDisk.szIdeMasterHardDiskImage, current->HardDisk.szIdeMasterHardDiskImage)
! 207: && changed->HardDisk.bUseIdeMasterHardDiskImage))
! 208: {
! 209: Ide_UnInit();
! 210: bReInitIDEEmu = true;
! 211: }
! 212:
! 213: /* Did change IDE HD slave image? */
! 214: if (changed->HardDisk.bUseIdeSlaveHardDiskImage != current->HardDisk.bUseIdeSlaveHardDiskImage
! 215: || (strcmp(changed->HardDisk.szIdeSlaveHardDiskImage, current->HardDisk.szIdeSlaveHardDiskImage)
! 216: && changed->HardDisk.bUseIdeSlaveHardDiskImage))
1.1.1.3 root 217: {
218: Ide_UnInit();
219: bReInitIDEEmu = true;
1.1 root 220: }
221:
222: /* Did change blitter, rtc or system type? */
223: if (changed->System.bBlitter != current->System.bBlitter
224: #if ENABLE_DSP_EMU
225: || changed->System.nDSPType != current->System.nDSPType
226: #endif
227: || changed->System.bRealTimeClock != current->System.bRealTimeClock
228: || changed->System.nMachineType != current->System.nMachineType)
229: {
230: IoMem_UnInit();
1.1.1.3 root 231: bReInitIoMem = true;
1.1 root 232: }
233:
234: #if ENABLE_DSP_EMU
235: /* Disabled DSP? */
1.1.1.3 root 236: if (current->System.nDSPType == DSP_TYPE_EMU &&
237: changed->System.nDSPType != DSP_TYPE_EMU)
1.1 root 238: {
239: DSP_UnInit();
240: }
241: #endif
242:
1.1.1.2 root 243: /* Did change MIDI settings? */
244: if (current->Midi.bEnableMidi != changed->Midi.bEnableMidi
245: || ((strcmp(changed->Midi.sMidiOutFileName, current->Midi.sMidiOutFileName)
246: || strcmp(changed->Midi.sMidiInFileName, current->Midi.sMidiInFileName))
247: && changed->Midi.bEnableMidi))
248: {
249: Midi_UnInit();
250: bReInitMidi = true;
251: }
252:
1.1 root 253: /* Copy details to configuration,
254: * so it can be saved out or set on reset
255: */
256: if (changed != &ConfigureParams)
257: {
258: ConfigureParams = *changed;
259: }
260:
261: /* Copy details to global, if we reset copy them all */
262: Configuration_Apply(NeedReset);
263:
264: #if ENABLE_DSP_EMU
1.1.1.3 root 265: if (current->System.nDSPType != DSP_TYPE_EMU &&
266: changed->System.nDSPType == DSP_TYPE_EMU)
1.1 root 267: {
268: DSP_Init();
269: }
270: #endif
271:
272: /* Set keyboard remap file */
273: if (ConfigureParams.Keyboard.nKeymapType == KEYMAP_LOADED)
274: Keymap_LoadRemapFile(ConfigureParams.Keyboard.szMappingFileName);
275:
276: /* Mount a new HD image: */
277: if (bReInitAcsiEmu && ConfigureParams.HardDisk.bUseHardDiskImage)
278: {
1.1.1.4 ! root 279: HDC_Init();
1.1 root 280: }
281:
1.1.1.4 ! root 282: /* Mount a new IDE HD master or slave image: */
! 283: if (bReInitIDEEmu && (ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage || ConfigureParams.HardDisk.bUseIdeSlaveHardDiskImage))
1.1.1.3 root 284: {
285: Ide_Init();
286: }
287:
1.1 root 288: /* Insert floppies? */
289: for (i = 0; i < MAX_FLOPPYDRIVES; i++)
290: {
291: if (bFloppyInsert[i])
292: Floppy_InsertDiskIntoDrive(i);
293: }
294:
295: /* Mount a new GEMDOS drive? */
296: if (bReInitGemdosDrive && ConfigureParams.HardDisk.bUseHardDiskDirectories)
297: {
298: GemDOS_InitDrives();
299: }
300:
301: /* Restart audio sub system if necessary: */
302: if (ConfigureParams.Sound.bEnableSound && !bSoundWorking)
303: {
304: Audio_Init();
305: }
306:
307: /* Re-initialize the RS232 emulation: */
308: if (ConfigureParams.RS232.bEnableRS232 && !bConnectedRS232)
309: {
310: RS232_Init();
311: }
312:
313: /* Re-init IO memory map? */
314: if (bReInitIoMem)
315: {
316: IoMem_Init();
317: }
318:
1.1.1.2 root 319: /* Re-init MIDI emulation? */
320: if (bReInitMidi)
321: {
322: Midi_Init();
323: }
324:
1.1 root 325: /* Force things associated with screen change */
326: if (bScreenModeChange)
327: {
328: Screen_ModeChanged();
329: }
330:
331: /* Do we need to perform reset? */
332: if (NeedReset)
333: {
334: Reset_Cold();
335: }
336:
337: /* Go into/return from full screen if flagged */
338: if (!bInFullScreen && ConfigureParams.Screen.bFullScreen)
339: Screen_EnterFullScreen();
340: else if (bInFullScreen && !ConfigureParams.Screen.bFullScreen)
341: Screen_ReturnFromFullScreen();
1.1.1.4 ! root 342:
! 343: /* update statusbar info (CPU, MHz, mem etc) */
! 344: Statusbar_UpdateInfo();
1.1 root 345: }
346:
347:
348: /*-----------------------------------------------------------------------*/
349: /**
350: * Change given Hatari options
1.1.1.3 root 351: * Return false if parsing failed, true otherwise
1.1 root 352: */
353: static bool Change_Options(int argc, const char *argv[])
354: {
355: bool bOK;
356: CNF_PARAMS current;
357:
1.1.1.3 root 358: Main_PauseEmulation(false);
1.1 root 359:
360: /* get configuration changes */
361: current = ConfigureParams;
362: ConfigureParams.Screen.bFullScreen = bInFullScreen;
363: bOK = Opt_ParseParameters(argc, argv);
364:
365: /* Check if reset is required and ask user if he really wants to continue */
366: if (bOK && Change_DoNeedReset(¤t, &ConfigureParams)
367: && current.Log.nAlertDlgLogLevel >= LOG_WARN) {
368: bOK = DlgAlert_Query("The emulated system must be "
369: "reset to apply these changes. "
370: "Apply changes now and reset "
371: "the emulator?");
372: }
373: /* Copy details to configuration */
374: if (bOK) {
1.1.1.3 root 375: Change_CopyChangedParamsToConfiguration(¤t, &ConfigureParams, false);
1.1 root 376: } else {
377: ConfigureParams = current;
378: }
379:
380: Main_UnPauseEmulation();
381: return bOK;
382: }
383:
384:
385: /*-----------------------------------------------------------------------*/
386: /**
387: * Parse given command line and change Hatari options accordingly
1.1.1.3 root 388: * Return false if parsing failed or there were no args, true otherwise
1.1 root 389: */
390: bool Change_ApplyCommandline(char *cmdline)
391: {
392: int i, argc, inarg;
393: const char **argv;
394: bool ret;
395:
396: /* count args */
397: inarg = argc = 0;
398: for (i = 0; cmdline[i]; i++)
399: {
400: if (isspace(cmdline[i]))
401: {
402: inarg = 0;
403: continue;
404: }
405: if (!inarg)
406: {
407: inarg++;
408: argc++;
409: }
410: }
411: if (!argc)
412: {
1.1.1.3 root 413: return false;
1.1 root 414: }
415: /* 2 = "hatari" + NULL */
416: argv = malloc((argc+2) * sizeof(char*));
417: if (!argv)
418: {
419: perror("command line alloc");
1.1.1.3 root 420: return false;
1.1 root 421: }
422:
423: /* parse them to array */
424: fprintf(stderr, "Command line with '%d' arguments:\n", argc);
425: inarg = argc = 0;
426: argv[argc++] = "hatari";
427: for (i = 0; cmdline[i]; i++)
428: {
429: if (isspace(cmdline[i]))
430: {
431: cmdline[i] = '\0';
432: if (inarg)
433: {
434: fprintf(stderr, "- '%s'\n", argv[argc-1]);
435: }
436: inarg = 0;
437: continue;
438: }
439: if (!inarg)
440: {
441: argv[argc++] = &(cmdline[i]);
442: inarg++;
443: }
444: }
445: if (inarg)
446: {
447: fprintf(stderr, "- '%s'\n", argv[argc-1]);
448: }
449: argv[argc] = NULL;
450:
451: /* do args */
452: ret = Change_Options(argc, argv);
1.1.1.3 root 453: free((void *)argv);
1.1 root 454: return ret;
455: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.