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