|
|
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
11: needs to be rebooted
12: */
13: const char Change_fileid[] = "Hatari change.c : " __DATE__ " " __TIME__;
14:
15: #include <ctype.h>
16: #include "main.h"
17: #include "configuration.h"
18: #include "change.h"
19: #include "dialog.h"
20: #include "ioMem.h"
21: #include "m68000.h"
22: #include "options.h"
23: #include "reset.h"
24: #include "screen.h"
25: #include "statusbar.h"
26: #include "video.h"
27: #include "hatari-glue.h"
1.1.1.3 root 28: #include "scsi.h"
1.1.1.4 ! root 29: #include "mo.h"
! 30: #include "floppy.h"
! 31: #include "ethernet.h"
! 32: #include "snd.h"
1.1 root 33:
1.1.1.3 root 34: #define DEBUG 1
1.1.1.2 root 35: #if DEBUG
36: #define Dprintf(a) printf(a)
37: #else
38: #define Dprintf(a)
39: #endif
1.1 root 40:
41: /*-----------------------------------------------------------------------*/
42: /**
43: * Check if user needs to be warned that changes will take place after reset.
44: * Return true if wants to reset.
45: */
46: bool Change_DoNeedReset(CNF_PARAMS *current, CNF_PARAMS *changed)
47: {
1.1.1.4 ! root 48: int i;
! 49:
1.1.1.3 root 50: /* Did we change ROM file? */
51: if (current->System.nMachineType == NEXT_CUBE030 && strcmp(current->Rom.szRom030FileName, changed->Rom.szRom030FileName)) {
52: printf("rom030 reset\n");
53: return true;
54: }
55: if (current->System.nMachineType == NEXT_CUBE040 || current->System.nMachineType == NEXT_STATION) {
56: if (!current->System.bTurbo && strcmp(current->Rom.szRom040FileName, changed->Rom.szRom040FileName)) {
57: printf("rom040 reset\n");
58: return true;
59: }
60: if (current->System.bTurbo && strcmp(current->Rom.szRomTurboFileName, changed->Rom.szRomTurboFileName)) {
61: printf("romturbo reset\n");
62: return true;
63: }
64: }
65:
66: /* Did we change machine type? */
67: if (current->System.nMachineType != changed->System.nMachineType) {
68: printf("machine type reset\n");
69: return true;
70: }
71: if (current->System.bColor != changed->System.bColor) {
72: printf("machine type reset (color)\n");
73: return true;
74: }
75: if (current->System.bTurbo != changed->System.bTurbo) {
76: printf("machine type reset (turbo)\n");
77: return true;
78: }
79:
80: /* Did we change CPU type? */
1.1.1.4 ! root 81: if ((current->System.nCpuLevel != changed->System.nCpuLevel) ||
! 82: (current->System.nCpuFreq != changed->System.nCpuFreq)) {
1.1.1.3 root 83: printf("cpu type reset\n");
84: return true;
85: }
86:
87: /* Did we change FPU type? */
88: if (current->System.n_FPUType != changed->System.n_FPUType) {
89: printf("fpu type reset\n");
90: return true;
91: }
1.1.1.4 ! root 92:
! 93: /* Did we change DSP type or memory? */
! 94: if ((current->System.nDSPType != changed->System.nDSPType) ||
! 95: (current->System.bDSPMemoryExpansion != changed->System.bDSPMemoryExpansion)) {
! 96: printf("dsp type reset\n");
! 97: return true;
! 98: }
1.1.1.3 root 99:
100: /* Did we change SCSI controller? */
101: if (current->System.nSCSI != changed->System.nSCSI) {
102: printf("scsi controller reset\n");
103: return true;
104: }
105:
106: /* Did we change RTC chip? */
107: if (current->System.nRTC != changed->System.nRTC) {
108: printf("rtc chip reset\n");
109: return true;
110: }
111:
1.1.1.4 ! root 112: /* Did we change NBIC emulation? */
! 113: if (current->System.bNBIC != changed->System.bNBIC) {
! 114: printf("nbic reset\n");
1.1.1.3 root 115: return true;
116: }
117:
118: /* Did we change memory size? */
119: for (i = 0; i < 4; i++) {
120: if (current->Memory.nMemoryBankSize[i] != changed->Memory.nMemoryBankSize[i]) {
121: printf("memory size reset\n");
122: return true;
123: }
124: }
125:
126: /* Did we change boot options? */
127: if (current->Boot.nBootDevice != changed->Boot.nBootDevice) {
128: printf("boot options reset\n");
129: return true;
130: }
131: if (current->Boot.bEnableDRAMTest != changed->Boot.bEnableDRAMTest) {
132: printf("boot options reset\n");
133: return true;
134: }
135: if (current->Boot.bEnablePot != changed->Boot.bEnablePot) {
136: printf("boot options reset\n");
137: return true;
138: }
139: if (current->Boot.bEnableSoundTest != changed->Boot.bEnableSoundTest) {
140: printf("boot options reset\n");
141: return true;
142: }
143: if (current->Boot.bEnableSCSITest != changed->Boot.bEnableSCSITest) {
144: printf("boot options reset\n");
145: return true;
146: }
147: if (current->Boot.bLoopPot != changed->Boot.bLoopPot) {
148: printf("boot options reset\n");
149: return true;
150: }
151: if (current->Boot.bVerbose != changed->Boot.bVerbose) {
152: printf("boot options reset\n");
153: return true;
154: }
155: if (current->Boot.bExtendedPot != changed->Boot.bExtendedPot) {
156: printf("boot options reset\n");
157: return true;
158: }
159:
160: /* Did we change SCSI disk? */
1.1.1.4 ! root 161: for (i = 0; i < ESP_MAX_DEVS; i++) {
! 162: if (current->SCSI.target[i].nDeviceType != changed->SCSI.target[i].nDeviceType ||
! 163: (current->SCSI.target[i].nDeviceType==DEVTYPE_HARDDISK &&
! 164: (current->SCSI.target[i].bWriteProtected != changed->SCSI.target[i].bWriteProtected ||
! 165: strcmp(current->SCSI.target[i].szImageName, changed->SCSI.target[i].szImageName)))) {
! 166: printf("scsi disk reset\n");
! 167: return true;
! 168: }
! 169: }
! 170:
! 171: /* Did we change MO drive? */
! 172: for (i = 0; i < MO_MAX_DRIVES; i++) {
! 173: if (current->MO.drive[i].bDriveConnected != changed->MO.drive[i].bDriveConnected) {
! 174: printf("mo drive reset\n");
! 175: return true;
1.1.1.3 root 176: }
177: }
1.1.1.4 ! root 178:
! 179: /* Did we change floppy drive? */
! 180: for (i = 0; i < FLP_MAX_DRIVES; i++) {
! 181: if (current->Floppy.drive[i].bDriveConnected != changed->Floppy.drive[i].bDriveConnected) {
! 182: printf("floppy drive reset\n");
! 183: return true;
! 184: }
! 185: }
! 186:
! 187: /* Did we change printer? */
! 188: if (current->Printer.bPrinterConnected != changed->Printer.bPrinterConnected) {
! 189: printf("printer reset\n");
1.1.1.3 root 190: return true;
191: }
192:
1.1.1.4 ! root 193: /* Did we change NeXTdimension? */
! 194: if (current->Dimension.bEnabled != changed->Dimension.bEnabled ||
! 195: strcmp(current->Dimension.szRomFileName, changed->Dimension.szRomFileName)) {
! 196: printf("dimension reset\n");
! 197: return true;
! 198: }
! 199: for (i = 0; i < 4; i++) {
! 200: if (current->Dimension.nMemoryBankSize[i] != changed->Dimension.nMemoryBankSize[i]) {
! 201: printf("dimension memory size reset\n");
! 202: return true;
! 203: }
! 204: }
! 205:
! 206: /* Did we change monitor count? */
! 207: if (current->Screen.nMonitorType != changed->Screen.nMonitorType &&
! 208: (current->Screen.nMonitorType == MONITOR_TYPE_DUAL ||
! 209: changed->Screen.nMonitorType == MONITOR_TYPE_DUAL)) {
! 210: printf("monitor reset\n");
! 211: return true;
! 212: }
! 213:
1.1.1.3 root 214: /* Else no reset is required */
215: printf("No Reset needed!\n");
216: return false;
1.1 root 217: }
218:
219:
220: /*-----------------------------------------------------------------------*/
221: /**
222: * Copy details back to configuration and perform reset.
223: */
1.1.1.3 root 224: bool Change_CopyChangedParamsToConfiguration(CNF_PARAMS *current, CNF_PARAMS *changed, bool bForceReset)
1.1 root 225: {
226: bool NeedReset;
1.1.1.3 root 227: bool bReInitSCSIEmu = false;
1.1.1.4 ! root 228: bool bReInitEnetEmu = false;
! 229: bool bReInitSoundEmu = false;
1.1 root 230: bool bReInitIoMem = false;
1.1.1.4 ! root 231: bool bReInitScreen = false;
1.1 root 232: bool bScreenModeChange = false;
233: int i;
234:
1.1.1.2 root 235: Dprintf("Changes for:\n");
1.1 root 236: /* Do we need to warn user that changes will only take effect after reset? */
237: if (bForceReset)
238: NeedReset = bForceReset;
239: else
240: NeedReset = Change_DoNeedReset(current, changed);
1.1.1.3 root 241:
242: /* Do we need to change SCSI disks? */
1.1.1.4 ! root 243: for (i = 0; i < ESP_MAX_DEVS; i++) {
! 244: if (!NeedReset &&
! 245: (current->SCSI.target[i].bDiskInserted != changed->SCSI.target[i].bDiskInserted ||
! 246: current->SCSI.target[i].bWriteProtected != changed->SCSI.target[i].bWriteProtected ||
! 247: strcmp(current->SCSI.target[i].szImageName, changed->SCSI.target[i].szImageName))) {
1.1.1.3 root 248: bReInitSCSIEmu = true;
249: break;
250: }
251: }
1.1.1.4 ! root 252:
! 253: /* Note: MO and floppy disk insert/eject called from GUI */
! 254:
! 255: /* Do we need to change Ethernet connection? */
! 256: if (!NeedReset && current->Ethernet.bEthernetConnected != changed->Ethernet.bEthernetConnected) {
! 257: bReInitEnetEmu = true;
! 258: }
! 259:
! 260: /* Do we need to change Sound configuration? */
! 261: if (!NeedReset &&
! 262: (current->Sound.bEnableSound != changed->Sound.bEnableSound ||
! 263: current->Sound.bEnableMicrophone != changed->Sound.bEnableMicrophone)) {
! 264: bReInitSoundEmu = true;
! 265: }
! 266:
! 267: /* Do we need to change Screen configuration? */
! 268: if (!NeedReset &&
! 269: current->Screen.nMonitorType != changed->Screen.nMonitorType) {
! 270: bReInitScreen = true;
! 271: }
1.1 root 272:
273: /* Copy details to configuration,
274: * so it can be saved out or set on reset
275: */
276: if (changed != &ConfigureParams)
277: {
278: ConfigureParams = *changed;
279: }
280:
281: /* Copy details to global, if we reset copy them all */
282: Configuration_Apply(NeedReset);
1.1.1.3 root 283:
284: /* Check if all necessary files exist */
285: Dialog_CheckFiles();
286: if (bQuitProgram)
287: {
288: SDL_Quit();
289: exit(-2);
290: }
1.1 root 291:
292: /* Re-init IO memory map? */
293: if (bReInitIoMem)
294: {
1.1.1.2 root 295: Dprintf("- IO mem<\n");
1.1 root 296: IoMem_Init();
297: }
1.1.1.3 root 298:
299: /* Re-init SCSI disks? */
300: if (bReInitSCSIEmu) {
301: Dprintf("- SCSI disks<\n");
302: SCSI_Reset();
303: }
1.1.1.4 ! root 304:
! 305: /* Re-init Ethernet? */
! 306: if (bReInitEnetEmu) {
! 307: Dprintf("- Ethernet<\n");
! 308: Ethernet_Reset(false);
! 309: }
! 310:
! 311: /* Re-init Sound? */
! 312: if (bReInitSoundEmu) {
! 313: Dprintf("- Sound<\n");
! 314: Sound_Reset();
! 315: }
! 316:
! 317: /* Re-init Screen */
! 318: if (bReInitScreen) {
! 319: Dprintf("- Screen<\n");
! 320: Screen_SetFullUpdate();
! 321: }
1.1 root 322:
323: /* Force things associated with screen change */
324: if (bScreenModeChange)
325: {
1.1.1.2 root 326: Dprintf("- screenmode<\n");
1.1 root 327: Screen_ModeChanged();
328: }
329:
330: /* Do we need to perform reset? */
331: if (NeedReset)
332: {
1.1.1.3 root 333: const char *err_msg;
1.1.1.2 root 334: Dprintf("- reset\n");
1.1.1.3 root 335: err_msg=Reset_Cold();
336: // if (err_msg!=NULL) {
337: // DlgAlert_Notice(err_msg);
338: // return false;
339: // }
1.1 root 340: }
341:
342: /* Go into/return from full screen if flagged */
343: if (!bInFullScreen && ConfigureParams.Screen.bFullScreen)
344: Screen_EnterFullScreen();
345: else if (bInFullScreen && !ConfigureParams.Screen.bFullScreen)
346: Screen_ReturnFromFullScreen();
347:
348: /* update statusbar info (CPU, MHz, mem etc) */
349: Statusbar_UpdateInfo();
1.1.1.2 root 350: Dprintf("done.\n");
1.1.1.3 root 351: return true;
1.1 root 352: }
353:
354:
355: /*-----------------------------------------------------------------------*/
356: /**
357: * Change given Hatari options
358: * Return false if parsing failed, true otherwise
359: */
360: static bool Change_Options(int argc, const char *argv[])
361: {
362: bool bOK;
363: CNF_PARAMS current;
364:
365: Main_PauseEmulation(false);
366:
367: /* get configuration changes */
368: current = ConfigureParams;
369: ConfigureParams.Screen.bFullScreen = bInFullScreen;
370: bOK = Opt_ParseParameters(argc, argv);
371:
372: /* Check if reset is required and ask user if he really wants to continue */
373: if (bOK && Change_DoNeedReset(¤t, &ConfigureParams)
1.1.1.2 root 374: && current.Log.nAlertDlgLogLevel > LOG_FATAL) {
1.1 root 375: bOK = DlgAlert_Query("The emulated system must be "
376: "reset to apply these changes. "
377: "Apply changes now and reset "
378: "the emulator?");
379: }
380: /* Copy details to configuration */
381: if (bOK) {
1.1.1.3 root 382: if (!Change_CopyChangedParamsToConfiguration(¤t, &ConfigureParams, false)) {
383: ConfigureParams = current;
384: DlgAlert_Notice("Return to old parameters...");
385: Reset_Cold();
386: }
1.1 root 387: } else {
388: ConfigureParams = current;
389: }
390:
391: Main_UnPauseEmulation();
392: return bOK;
393: }
394:
395:
396: /*-----------------------------------------------------------------------*/
397: /**
398: * Parse given command line and change Hatari options accordingly
399: * Return false if parsing failed or there were no args, true otherwise
400: */
401: bool Change_ApplyCommandline(char *cmdline)
402: {
403: int i, argc, inarg;
404: const char **argv;
405: bool ret;
406:
407: /* count args */
408: inarg = argc = 0;
409: for (i = 0; cmdline[i]; i++)
410: {
411: if (isspace(cmdline[i]))
412: {
413: inarg = 0;
414: continue;
415: }
416: if (!inarg)
417: {
418: inarg++;
419: argc++;
420: }
421: }
422: if (!argc)
423: {
424: return false;
425: }
426: /* 2 = "hatari" + NULL */
427: argv = malloc((argc+2) * sizeof(char*));
428: if (!argv)
429: {
430: perror("command line alloc");
431: return false;
432: }
433:
434: /* parse them to array */
435: fprintf(stderr, "Command line with '%d' arguments:\n", argc);
436: inarg = argc = 0;
437: argv[argc++] = "hatari";
438: for (i = 0; cmdline[i]; i++)
439: {
440: if (isspace(cmdline[i]))
441: {
442: cmdline[i] = '\0';
443: if (inarg)
444: {
445: fprintf(stderr, "- '%s'\n", argv[argc-1]);
446: }
447: inarg = 0;
448: continue;
449: }
450: if (!inarg)
451: {
452: argv[argc++] = &(cmdline[i]);
453: inarg++;
454: }
455: }
456: if (inarg)
457: {
458: fprintf(stderr, "- '%s'\n", argv[argc-1]);
459: }
460: argv[argc] = NULL;
461:
462: /* do args */
463: ret = Change_Options(argc, argv);
464: free((void *)argv);
465: return ret;
466: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.