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