|
|
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: }
1.1.1.5 ! root 86:
! 87: /* Did we change the realtime flag? */
! 88: if(current->System.bRealtime != changed->System.bRealtime) {
! 89: printf("realtime flag reset\n");
! 90: return true;
! 91: }
! 92:
1.1.1.3 root 93: /* Did we change FPU type? */
94: if (current->System.n_FPUType != changed->System.n_FPUType) {
95: printf("fpu type reset\n");
96: return true;
97: }
1.1.1.4 root 98:
99: /* Did we change DSP type or memory? */
100: if ((current->System.nDSPType != changed->System.nDSPType) ||
101: (current->System.bDSPMemoryExpansion != changed->System.bDSPMemoryExpansion)) {
102: printf("dsp type reset\n");
103: return true;
104: }
1.1.1.3 root 105:
106: /* Did we change SCSI controller? */
107: if (current->System.nSCSI != changed->System.nSCSI) {
108: printf("scsi controller reset\n");
109: return true;
110: }
111:
112: /* Did we change RTC chip? */
113: if (current->System.nRTC != changed->System.nRTC) {
114: printf("rtc chip reset\n");
115: return true;
116: }
117:
1.1.1.4 root 118: /* Did we change NBIC emulation? */
119: if (current->System.bNBIC != changed->System.bNBIC) {
120: printf("nbic reset\n");
1.1.1.3 root 121: return true;
122: }
123:
124: /* Did we change memory size? */
125: for (i = 0; i < 4; i++) {
126: if (current->Memory.nMemoryBankSize[i] != changed->Memory.nMemoryBankSize[i]) {
127: printf("memory size reset\n");
128: return true;
129: }
130: }
131:
132: /* Did we change boot options? */
133: if (current->Boot.nBootDevice != changed->Boot.nBootDevice) {
134: printf("boot options reset\n");
135: return true;
136: }
137: if (current->Boot.bEnableDRAMTest != changed->Boot.bEnableDRAMTest) {
138: printf("boot options reset\n");
139: return true;
140: }
141: if (current->Boot.bEnablePot != changed->Boot.bEnablePot) {
142: printf("boot options reset\n");
143: return true;
144: }
145: if (current->Boot.bEnableSoundTest != changed->Boot.bEnableSoundTest) {
146: printf("boot options reset\n");
147: return true;
148: }
149: if (current->Boot.bEnableSCSITest != changed->Boot.bEnableSCSITest) {
150: printf("boot options reset\n");
151: return true;
152: }
153: if (current->Boot.bLoopPot != changed->Boot.bLoopPot) {
154: printf("boot options reset\n");
155: return true;
156: }
157: if (current->Boot.bVerbose != changed->Boot.bVerbose) {
158: printf("boot options reset\n");
159: return true;
160: }
161: if (current->Boot.bExtendedPot != changed->Boot.bExtendedPot) {
162: printf("boot options reset\n");
163: return true;
164: }
165:
166: /* Did we change SCSI disk? */
1.1.1.4 root 167: for (i = 0; i < ESP_MAX_DEVS; i++) {
168: if (current->SCSI.target[i].nDeviceType != changed->SCSI.target[i].nDeviceType ||
169: (current->SCSI.target[i].nDeviceType==DEVTYPE_HARDDISK &&
170: (current->SCSI.target[i].bWriteProtected != changed->SCSI.target[i].bWriteProtected ||
171: strcmp(current->SCSI.target[i].szImageName, changed->SCSI.target[i].szImageName)))) {
172: printf("scsi disk reset\n");
173: return true;
174: }
175: }
1.1.1.5 ! root 176: if(current->SCSI.nWriteProtection != changed->SCSI.nWriteProtection) {
! 177: printf("scsi disk reset\n");
! 178: return true;
! 179: }
1.1.1.4 root 180:
181: /* Did we change MO drive? */
182: for (i = 0; i < MO_MAX_DRIVES; i++) {
183: if (current->MO.drive[i].bDriveConnected != changed->MO.drive[i].bDriveConnected) {
184: printf("mo drive reset\n");
185: return true;
1.1.1.3 root 186: }
187: }
1.1.1.4 root 188:
189: /* Did we change floppy drive? */
190: for (i = 0; i < FLP_MAX_DRIVES; i++) {
191: if (current->Floppy.drive[i].bDriveConnected != changed->Floppy.drive[i].bDriveConnected) {
192: printf("floppy drive reset\n");
193: return true;
194: }
195: }
196:
197: /* Did we change printer? */
198: if (current->Printer.bPrinterConnected != changed->Printer.bPrinterConnected) {
199: printf("printer reset\n");
1.1.1.3 root 200: return true;
201: }
202:
1.1.1.4 root 203: /* Did we change NeXTdimension? */
204: if (current->Dimension.bEnabled != changed->Dimension.bEnabled ||
1.1.1.5 ! root 205: current->Dimension.bI860Thread != changed->Dimension.bI860Thread ||
! 206: current->Dimension.bMainDisplay != changed->Dimension.bMainDisplay ||
1.1.1.4 root 207: strcmp(current->Dimension.szRomFileName, changed->Dimension.szRomFileName)) {
208: printf("dimension reset\n");
209: return true;
210: }
211: for (i = 0; i < 4; i++) {
212: if (current->Dimension.nMemoryBankSize[i] != changed->Dimension.nMemoryBankSize[i]) {
213: printf("dimension memory size reset\n");
214: return true;
215: }
216: }
217:
218: /* Did we change monitor count? */
219: if (current->Screen.nMonitorType != changed->Screen.nMonitorType &&
220: (current->Screen.nMonitorType == MONITOR_TYPE_DUAL ||
221: changed->Screen.nMonitorType == MONITOR_TYPE_DUAL)) {
222: printf("monitor reset\n");
223: return true;
224: }
225:
1.1.1.3 root 226: /* Else no reset is required */
227: printf("No Reset needed!\n");
228: return false;
1.1 root 229: }
230:
231:
232: /*-----------------------------------------------------------------------*/
233: /**
234: * Copy details back to configuration and perform reset.
235: */
1.1.1.3 root 236: bool Change_CopyChangedParamsToConfiguration(CNF_PARAMS *current, CNF_PARAMS *changed, bool bForceReset)
1.1 root 237: {
238: bool NeedReset;
1.1.1.4 root 239: bool bReInitEnetEmu = false;
240: bool bReInitSoundEmu = false;
1.1 root 241: bool bScreenModeChange = false;
242:
1.1.1.2 root 243: Dprintf("Changes for:\n");
1.1 root 244: /* Do we need to warn user that changes will only take effect after reset? */
245: if (bForceReset)
246: NeedReset = bForceReset;
247: else
248: NeedReset = Change_DoNeedReset(current, changed);
1.1.1.3 root 249:
1.1.1.5 ! root 250: /* Note: SCSI, MO and floppy disk insert/eject called from GUI */
1.1.1.4 root 251:
252: /* Do we need to change Ethernet connection? */
253: if (!NeedReset && current->Ethernet.bEthernetConnected != changed->Ethernet.bEthernetConnected) {
254: bReInitEnetEmu = true;
255: }
256:
257: /* Do we need to change Sound configuration? */
258: if (!NeedReset &&
259: (current->Sound.bEnableSound != changed->Sound.bEnableSound ||
260: current->Sound.bEnableMicrophone != changed->Sound.bEnableMicrophone)) {
261: bReInitSoundEmu = true;
262: }
263:
264: /* Do we need to change Screen configuration? */
265: if (!NeedReset &&
266: current->Screen.nMonitorType != changed->Screen.nMonitorType) {
267: }
1.1 root 268:
269: /* Copy details to configuration,
270: * so it can be saved out or set on reset
271: */
272: if (changed != &ConfigureParams)
273: {
274: ConfigureParams = *changed;
275: }
276:
277: /* Copy details to global, if we reset copy them all */
278: Configuration_Apply(NeedReset);
1.1.1.3 root 279:
1.1.1.4 root 280: /* Re-init Ethernet? */
281: if (bReInitEnetEmu) {
282: Dprintf("- Ethernet<\n");
283: Ethernet_Reset(false);
284: }
285:
286: /* Re-init Sound? */
287: if (bReInitSoundEmu) {
288: Dprintf("- Sound<\n");
289: Sound_Reset();
290: }
291:
1.1 root 292: /* Force things associated with screen change */
293: if (bScreenModeChange)
294: {
1.1.1.2 root 295: Dprintf("- screenmode<\n");
1.1 root 296: Screen_ModeChanged();
297: }
298:
299: /* Do we need to perform reset? */
300: if (NeedReset)
301: {
1.1.1.5 ! root 302: /* Check if all necessary files exist */
! 303: Dialog_CheckFiles();
! 304: if (bQuitProgram)
! 305: {
! 306: SDL_Quit();
! 307: exit(-2);
! 308: }
! 309:
1.1.1.2 root 310: Dprintf("- reset\n");
1.1.1.5 ! root 311: Reset_Cold();
1.1 root 312: }
313:
314: /* Go into/return from full screen if flagged */
315: if (!bInFullScreen && ConfigureParams.Screen.bFullScreen)
316: Screen_EnterFullScreen();
317: else if (bInFullScreen && !ConfigureParams.Screen.bFullScreen)
318: Screen_ReturnFromFullScreen();
319:
320: /* update statusbar info (CPU, MHz, mem etc) */
321: Statusbar_UpdateInfo();
1.1.1.2 root 322: Dprintf("done.\n");
1.1.1.3 root 323: return true;
1.1 root 324: }
325:
326:
327: /*-----------------------------------------------------------------------*/
328: /**
329: * Change given Hatari options
330: * Return false if parsing failed, true otherwise
331: */
332: static bool Change_Options(int argc, const char *argv[])
333: {
334: bool bOK;
335: CNF_PARAMS current;
336:
337: Main_PauseEmulation(false);
338:
339: /* get configuration changes */
340: current = ConfigureParams;
341: ConfigureParams.Screen.bFullScreen = bInFullScreen;
342: bOK = Opt_ParseParameters(argc, argv);
343:
344: /* Check if reset is required and ask user if he really wants to continue */
345: if (bOK && Change_DoNeedReset(¤t, &ConfigureParams)
1.1.1.2 root 346: && current.Log.nAlertDlgLogLevel > LOG_FATAL) {
1.1 root 347: bOK = DlgAlert_Query("The emulated system must be "
348: "reset to apply these changes. "
349: "Apply changes now and reset "
350: "the emulator?");
351: }
352: /* Copy details to configuration */
353: if (bOK) {
1.1.1.3 root 354: if (!Change_CopyChangedParamsToConfiguration(¤t, &ConfigureParams, false)) {
355: ConfigureParams = current;
356: DlgAlert_Notice("Return to old parameters...");
357: Reset_Cold();
358: }
1.1 root 359: } else {
360: ConfigureParams = current;
361: }
362:
363: Main_UnPauseEmulation();
364: return bOK;
365: }
366:
367:
368: /*-----------------------------------------------------------------------*/
369: /**
370: * Parse given command line and change Hatari options accordingly
371: * Return false if parsing failed or there were no args, true otherwise
372: */
373: bool Change_ApplyCommandline(char *cmdline)
374: {
375: int i, argc, inarg;
376: const char **argv;
377: bool ret;
378:
379: /* count args */
380: inarg = argc = 0;
381: for (i = 0; cmdline[i]; i++)
382: {
383: if (isspace(cmdline[i]))
384: {
385: inarg = 0;
386: continue;
387: }
388: if (!inarg)
389: {
390: inarg++;
391: argc++;
392: }
393: }
394: if (!argc)
395: {
396: return false;
397: }
398: /* 2 = "hatari" + NULL */
399: argv = malloc((argc+2) * sizeof(char*));
400: if (!argv)
401: {
402: perror("command line alloc");
403: return false;
404: }
405:
406: /* parse them to array */
407: fprintf(stderr, "Command line with '%d' arguments:\n", argc);
408: inarg = argc = 0;
409: argv[argc++] = "hatari";
410: for (i = 0; cmdline[i]; i++)
411: {
412: if (isspace(cmdline[i]))
413: {
414: cmdline[i] = '\0';
415: if (inarg)
416: {
417: fprintf(stderr, "- '%s'\n", argv[argc-1]);
418: }
419: inarg = 0;
420: continue;
421: }
422: if (!inarg)
423: {
424: argv[argc++] = &(cmdline[i]);
425: inarg++;
426: }
427: }
428: if (inarg)
429: {
430: fprintf(stderr, "- '%s'\n", argv[argc-1]);
431: }
432: argv[argc] = NULL;
433:
434: /* do args */
435: ret = Change_Options(argc, argv);
436: free((void *)argv);
437: return ret;
438: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.