|
|
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:
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 root 106:
1.1.1.5 ! root 107: #if ENABLE_DSP_EMU
! 108: /* enabling DSP needs reset (disabling it not) */
! 109: if (current->System.nDSPType != DSP_TYPE_EMU &&
! 110: changed->System.nDSPType == DSP_TYPE_EMU)
! 111: {
! 112: return true;
! 113: }
! 114: #endif
! 115:
! 116: #if ENABLE_WINUAE_CPU
! 117: /* Did change CPU prefetch mode? */
! 118: if (changed->System.bCompatibleCpu != current->System.bCompatibleCpu)
! 119: return true;
! 120:
! 121: /* Did change CPU cycle exact? */
! 122: if (changed->System.bCycleExactCpu != current->System.bCycleExactCpu)
! 123: return true;
! 124:
! 125: /* Did change MMU? */
! 126: if (changed->System.bMMU != current->System.bMMU)
! 127: return true;
! 128: #endif
! 129:
1.1 root 130: /* Did change size of memory? */
131: if (current->Memory.nMemorySize != changed->Memory.nMemorySize)
1.1.1.3 root 132: return true;
1.1 root 133:
1.1.1.3 root 134: return false;
1.1 root 135: }
136:
137:
138: /*-----------------------------------------------------------------------*/
139: /**
140: * Copy details back to configuration and perform reset.
141: */
142: void Change_CopyChangedParamsToConfiguration(CNF_PARAMS *current, CNF_PARAMS *changed, bool bForceReset)
143: {
144: bool NeedReset;
1.1.1.3 root 145: bool bReInitGemdosDrive = false;
146: bool bReInitAcsiEmu = false;
147: bool bReInitIDEEmu = false;
148: bool bReInitIoMem = false;
149: bool bScreenModeChange = false;
150: bool bReInitMidi = false;
1.1 root 151: bool bFloppyInsert[MAX_FLOPPYDRIVES];
152: int i;
153:
1.1.1.5 ! root 154: Dprintf("Changes for:\n");
1.1 root 155: /* Do we need to warn user that changes will only take effect after reset? */
156: if (bForceReset)
157: NeedReset = bForceReset;
158: else
159: NeedReset = Change_DoNeedReset(current, changed);
160:
161: /* Do need to change resolution? Need if change display/overscan settings
162: * (if switch between Colour/Mono cause reset later) or toggle statusbar
163: */
164: if (!NeedReset &&
165: (changed->Screen.nForceBpp != current->Screen.nForceBpp
1.1.1.4 root 166: || changed->Screen.bAspectCorrect != current->Screen.bAspectCorrect
167: || changed->Screen.nMaxWidth != current->Screen.nMaxWidth
168: || changed->Screen.nMaxHeight != current->Screen.nMaxHeight
1.1 root 169: || changed->Screen.bAllowOverscan != current->Screen.bAllowOverscan
170: || changed->Screen.bShowStatusbar != current->Screen.bShowStatusbar))
171: {
1.1.1.5 ! root 172: Dprintf("- screenmode>\n");
1.1.1.3 root 173: bScreenModeChange = true;
1.1 root 174: }
175:
176: /* Did set new printer parameters? */
177: if (changed->Printer.bEnablePrinting != current->Printer.bEnablePrinting
178: || changed->Printer.bPrintToFile != current->Printer.bPrintToFile
179: || strcmp(changed->Printer.szPrintToFileName,current->Printer.szPrintToFileName))
180: {
1.1.1.5 ! root 181: Dprintf("- printer>\n");
1.1 root 182: Printer_CloseAllConnections();
183: }
184:
185: /* Did set new RS232 parameters? */
186: if (changed->RS232.bEnableRS232 != current->RS232.bEnableRS232
187: || strcmp(changed->RS232.szOutFileName, current->RS232.szOutFileName)
188: || strcmp(changed->RS232.szInFileName, current->RS232.szInFileName))
189: {
1.1.1.5 ! root 190: Dprintf("- RS-232>\n");
1.1 root 191: RS232_UnInit();
192: }
193:
194: /* Did stop sound? Or change playback Hz. If so, also stop sound recording */
1.1.1.3 root 195: if (!changed->Sound.bEnableSound || changed->Sound.nPlaybackFreq != current->Sound.nPlaybackFreq)
1.1 root 196: {
1.1.1.5 ! root 197: Dprintf("- sound>\n");
1.1 root 198: if (Sound_AreWeRecording())
199: Sound_EndRecording();
200: Audio_UnInit();
201: }
202:
203: /* Did change floppy (images)? */
204: for (i = 0; i < MAX_FLOPPYDRIVES; i++)
205: {
206: /*
207: Log_Printf(LOG_DEBUG, "Old and new disk %c:\n\t%s\n\t%s", 'A'+i,
208: current->DiskImage.szDiskFileName[i],
209: changed->DiskImage.szDiskFileName[i]);
210: */
211: if (strcmp(changed->DiskImage.szDiskFileName[i],
212: current->DiskImage.szDiskFileName[i])
213: || strcmp(changed->DiskImage.szDiskZipPath[i],
214: current->DiskImage.szDiskZipPath[i]))
1.1.1.3 root 215: bFloppyInsert[i] = true;
1.1 root 216: else
1.1.1.3 root 217: bFloppyInsert[i] = false;
1.1 root 218: }
219:
220: /* Did change GEMDOS drive? */
221: if (changed->HardDisk.bUseHardDiskDirectories != current->HardDisk.bUseHardDiskDirectories
222: || (strcmp(changed->HardDisk.szHardDiskDirectories[0], current->HardDisk.szHardDiskDirectories[0])
223: && changed->HardDisk.bUseHardDiskDirectories))
224: {
1.1.1.5 ! root 225: Dprintf("- gemdos HD>\n");
1.1 root 226: GemDOS_UnInitDrives();
1.1.1.3 root 227: bReInitGemdosDrive = true;
1.1 root 228: }
229:
230: /* Did change HD image? */
231: if (changed->HardDisk.bUseHardDiskImage != current->HardDisk.bUseHardDiskImage
232: || (strcmp(changed->HardDisk.szHardDiskImage, current->HardDisk.szHardDiskImage)
233: && changed->HardDisk.bUseHardDiskImage))
234: {
1.1.1.5 ! root 235: Dprintf("- HD image>\n");
1.1 root 236: HDC_UnInit();
1.1.1.3 root 237: bReInitAcsiEmu = true;
238: }
239:
1.1.1.4 root 240: /* Did change IDE HD master image? */
241: if (changed->HardDisk.bUseIdeMasterHardDiskImage != current->HardDisk.bUseIdeMasterHardDiskImage
242: || (strcmp(changed->HardDisk.szIdeMasterHardDiskImage, current->HardDisk.szIdeMasterHardDiskImage)
243: && changed->HardDisk.bUseIdeMasterHardDiskImage))
244: {
1.1.1.5 ! root 245: Dprintf("- IDE master>\n");
1.1.1.4 root 246: Ide_UnInit();
247: bReInitIDEEmu = true;
248: }
249:
250: /* Did change IDE HD slave image? */
251: if (changed->HardDisk.bUseIdeSlaveHardDiskImage != current->HardDisk.bUseIdeSlaveHardDiskImage
252: || (strcmp(changed->HardDisk.szIdeSlaveHardDiskImage, current->HardDisk.szIdeSlaveHardDiskImage)
253: && changed->HardDisk.bUseIdeSlaveHardDiskImage))
1.1.1.3 root 254: {
1.1.1.5 ! root 255: Dprintf("- IDE slave>\n");
1.1.1.3 root 256: Ide_UnInit();
257: bReInitIDEEmu = true;
1.1 root 258: }
259:
260: /* Did change blitter, rtc or system type? */
261: if (changed->System.bBlitter != current->System.bBlitter
262: #if ENABLE_DSP_EMU
263: || changed->System.nDSPType != current->System.nDSPType
264: #endif
265: || changed->System.bRealTimeClock != current->System.bRealTimeClock
266: || changed->System.nMachineType != current->System.nMachineType)
267: {
1.1.1.5 ! root 268: Dprintf("- blitter/rtc/dsp/machine>\n");
1.1 root 269: IoMem_UnInit();
1.1.1.3 root 270: bReInitIoMem = true;
1.1 root 271: }
272:
273: #if ENABLE_DSP_EMU
274: /* Disabled DSP? */
1.1.1.3 root 275: if (current->System.nDSPType == DSP_TYPE_EMU &&
276: changed->System.nDSPType != DSP_TYPE_EMU)
1.1 root 277: {
1.1.1.5 ! root 278: Dprintf("- DSP>\n");
1.1 root 279: DSP_UnInit();
280: }
281: #endif
282:
1.1.1.2 root 283: /* Did change MIDI settings? */
284: if (current->Midi.bEnableMidi != changed->Midi.bEnableMidi
285: || ((strcmp(changed->Midi.sMidiOutFileName, current->Midi.sMidiOutFileName)
286: || strcmp(changed->Midi.sMidiInFileName, current->Midi.sMidiInFileName))
287: && changed->Midi.bEnableMidi))
288: {
1.1.1.5 ! root 289: Dprintf("- midi>\n");
1.1.1.2 root 290: Midi_UnInit();
291: bReInitMidi = true;
292: }
293:
1.1 root 294: /* Copy details to configuration,
295: * so it can be saved out or set on reset
296: */
297: if (changed != &ConfigureParams)
298: {
299: ConfigureParams = *changed;
300: }
301:
302: /* Copy details to global, if we reset copy them all */
303: Configuration_Apply(NeedReset);
304:
305: #if ENABLE_DSP_EMU
1.1.1.3 root 306: if (current->System.nDSPType != DSP_TYPE_EMU &&
307: changed->System.nDSPType == DSP_TYPE_EMU)
1.1 root 308: {
1.1.1.5 ! root 309: Dprintf("- DSP<\n");
1.1 root 310: DSP_Init();
311: }
312: #endif
313:
314: /* Set keyboard remap file */
315: if (ConfigureParams.Keyboard.nKeymapType == KEYMAP_LOADED)
1.1.1.5 ! root 316: {
! 317: Dprintf("- keymap<\n");
1.1 root 318: Keymap_LoadRemapFile(ConfigureParams.Keyboard.szMappingFileName);
1.1.1.5 ! root 319: }
1.1 root 320:
321: /* Mount a new HD image: */
322: if (bReInitAcsiEmu && ConfigureParams.HardDisk.bUseHardDiskImage)
323: {
1.1.1.5 ! root 324: Dprintf("- HD<\n");
1.1.1.4 root 325: HDC_Init();
1.1 root 326: }
327:
1.1.1.4 root 328: /* Mount a new IDE HD master or slave image: */
329: if (bReInitIDEEmu && (ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage || ConfigureParams.HardDisk.bUseIdeSlaveHardDiskImage))
1.1.1.3 root 330: {
1.1.1.5 ! root 331: Dprintf("- IDE<\n");
1.1.1.3 root 332: Ide_Init();
333: }
334:
1.1 root 335: /* Insert floppies? */
336: for (i = 0; i < MAX_FLOPPYDRIVES; i++)
337: {
338: if (bFloppyInsert[i])
1.1.1.5 ! root 339: {
! 340: Dprintf("- floppy<\n");
1.1 root 341: Floppy_InsertDiskIntoDrive(i);
1.1.1.5 ! root 342: }
1.1 root 343: }
344:
345: /* Mount a new GEMDOS drive? */
346: if (bReInitGemdosDrive && ConfigureParams.HardDisk.bUseHardDiskDirectories)
347: {
1.1.1.5 ! root 348: Dprintf("- gemdos HD<\n");
1.1 root 349: GemDOS_InitDrives();
350: }
351:
352: /* Restart audio sub system if necessary: */
353: if (ConfigureParams.Sound.bEnableSound && !bSoundWorking)
354: {
1.1.1.5 ! root 355: Dprintf("- audio<\n");
1.1 root 356: Audio_Init();
357: }
358:
359: /* Re-initialize the RS232 emulation: */
360: if (ConfigureParams.RS232.bEnableRS232 && !bConnectedRS232)
361: {
1.1.1.5 ! root 362: Dprintf("- RS-232<\n");
1.1 root 363: RS232_Init();
364: }
365:
366: /* Re-init IO memory map? */
367: if (bReInitIoMem)
368: {
1.1.1.5 ! root 369: Dprintf("- IO mem<\n");
1.1 root 370: IoMem_Init();
371: }
372:
1.1.1.2 root 373: /* Re-init MIDI emulation? */
374: if (bReInitMidi)
375: {
1.1.1.5 ! root 376: Dprintf("- midi<\n");
1.1.1.2 root 377: Midi_Init();
378: }
379:
1.1 root 380: /* Force things associated with screen change */
381: if (bScreenModeChange)
382: {
1.1.1.5 ! root 383: Dprintf("- screenmode<\n");
1.1 root 384: Screen_ModeChanged();
385: }
386:
387: /* Do we need to perform reset? */
388: if (NeedReset)
389: {
1.1.1.5 ! root 390: Dprintf("- reset\n");
1.1 root 391: Reset_Cold();
392: }
393:
394: /* Go into/return from full screen if flagged */
395: if (!bInFullScreen && ConfigureParams.Screen.bFullScreen)
396: Screen_EnterFullScreen();
397: else if (bInFullScreen && !ConfigureParams.Screen.bFullScreen)
398: Screen_ReturnFromFullScreen();
1.1.1.4 root 399:
400: /* update statusbar info (CPU, MHz, mem etc) */
401: Statusbar_UpdateInfo();
1.1.1.5 ! root 402: Dprintf("done.\n");
1.1 root 403: }
404:
405:
406: /*-----------------------------------------------------------------------*/
407: /**
408: * Change given Hatari options
1.1.1.3 root 409: * Return false if parsing failed, true otherwise
1.1 root 410: */
411: static bool Change_Options(int argc, const char *argv[])
412: {
413: bool bOK;
414: CNF_PARAMS current;
415:
1.1.1.3 root 416: Main_PauseEmulation(false);
1.1 root 417:
418: /* get configuration changes */
419: current = ConfigureParams;
420: ConfigureParams.Screen.bFullScreen = bInFullScreen;
421: bOK = Opt_ParseParameters(argc, argv);
422:
423: /* Check if reset is required and ask user if he really wants to continue */
424: if (bOK && Change_DoNeedReset(¤t, &ConfigureParams)
1.1.1.5 ! root 425: && current.Log.nAlertDlgLogLevel > LOG_FATAL) {
1.1 root 426: bOK = DlgAlert_Query("The emulated system must be "
427: "reset to apply these changes. "
428: "Apply changes now and reset "
429: "the emulator?");
430: }
431: /* Copy details to configuration */
432: if (bOK) {
1.1.1.3 root 433: Change_CopyChangedParamsToConfiguration(¤t, &ConfigureParams, false);
1.1 root 434: } else {
435: ConfigureParams = current;
436: }
437:
438: Main_UnPauseEmulation();
439: return bOK;
440: }
441:
442:
443: /*-----------------------------------------------------------------------*/
444: /**
445: * Parse given command line and change Hatari options accordingly
1.1.1.3 root 446: * Return false if parsing failed or there were no args, true otherwise
1.1 root 447: */
448: bool Change_ApplyCommandline(char *cmdline)
449: {
450: int i, argc, inarg;
451: const char **argv;
452: bool ret;
453:
454: /* count args */
455: inarg = argc = 0;
456: for (i = 0; cmdline[i]; i++)
457: {
458: if (isspace(cmdline[i]))
459: {
460: inarg = 0;
461: continue;
462: }
463: if (!inarg)
464: {
465: inarg++;
466: argc++;
467: }
468: }
469: if (!argc)
470: {
1.1.1.3 root 471: return false;
1.1 root 472: }
473: /* 2 = "hatari" + NULL */
474: argv = malloc((argc+2) * sizeof(char*));
475: if (!argv)
476: {
477: perror("command line alloc");
1.1.1.3 root 478: return false;
1.1 root 479: }
480:
481: /* parse them to array */
482: fprintf(stderr, "Command line with '%d' arguments:\n", argc);
483: inarg = argc = 0;
484: argv[argc++] = "hatari";
485: for (i = 0; cmdline[i]; i++)
486: {
487: if (isspace(cmdline[i]))
488: {
489: cmdline[i] = '\0';
490: if (inarg)
491: {
492: fprintf(stderr, "- '%s'\n", argv[argc-1]);
493: }
494: inarg = 0;
495: continue;
496: }
497: if (!inarg)
498: {
499: argv[argc++] = &(cmdline[i]);
500: inarg++;
501: }
502: }
503: if (inarg)
504: {
505: fprintf(stderr, "- '%s'\n", argv[argc-1]);
506: }
507: argv[argc] = NULL;
508:
509: /* do args */
510: ret = Change_Options(argc, argv);
1.1.1.3 root 511: free((void *)argv);
1.1 root 512: return ret;
513: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.