|
|
1.1 root 1: /*
2: Hatari
3: */
4:
5: #include <time.h>
1.1.1.2 root 6: #include <signal.h>
7: #include <sys/time.h>
1.1.1.5 ! root 8: #include <unistd.h>
1.1 root 9:
10: #include <SDL.h>
11:
12: #include "main.h"
13: #include "configuration.h"
14: #include "decode.h"
15: #include "dialog.h"
16: #include "createDiscImage.h"
17: #include "audio.h"
18: #include "debug.h"
19: #include "joy.h"
20: #include "errlog.h"
21: #include "file.h"
22: #include "floppy.h"
23: #include "gemdos.h"
1.1.1.4 root 24: #include "hdc.h"
1.1 root 25: #include "ikbd.h"
26: #include "intercept.h"
27: #include "reset.h"
1.1.1.5 ! root 28: #include "keymap.h"
1.1 root 29: #include "m68000.h"
30: #include "memorySnapShot.h"
31: #include "misc.h"
32: #include "printer.h"
33: #include "rs232.h"
34: #include "screen.h"
1.1.1.5 ! root 35: #include "sdlgui.h"
1.1 root 36: #include "shortcut.h"
37: #include "sound.h"
38: #include "tos.h"
1.1.1.5 ! root 39: #include "vdi.h"
1.1 root 40: #include "video.h"
41: #include "ymFormat.h"
1.1.1.2 root 42: #include "debugui.h"
1.1 root 43:
44: #include "uae-cpu/hatari-glue.h"
45:
46:
1.1.1.4 root 47: #define FORCE_WORKING_DIR /* Set default directory to cwd */
48:
1.1 root 49:
1.1.1.2 root 50: SDL_TimerID hSoundTimer; /* Handle to sound playback */
1.1 root 51:
52: BOOL bQuitProgram=FALSE; /* Flag to quit program cleanly */
53: BOOL bUseFullscreen=FALSE;
1.1.1.4 root 54: BOOL bEmulationActive=TRUE; /* Run emulation when started */
1.1 root 55: BOOL bAppActive = FALSE;
1.1.1.2 root 56: BOOL bEnableDebug=FALSE; /* Enable debug UI? */
1.1 root 57: unsigned int TimerID; /* Timer ID for main window */
58: char szBootDiscImage[MAX_FILENAME_LENGTH] = { "" };
59:
60: char szWorkingDir[MAX_FILENAME_LENGTH] = { "" };
61: char szCurrentDir[MAX_FILENAME_LENGTH] = { "" };
62:
63: unsigned char STRam[16*1024*1024]; /* This is our ST Ram, includes all TOS/hardware areas for ease */
64:
65: int STSpeedMilliSeconds[] = { /* Convert option 'nMinMaxSpeed' into milliseconds */
66: 1000/50, /* MINMAXSPEED_MIN(20ms) */
67: 1000/66, /* MINMAXSPEED_1(15ms) */
68: 1000/100, /* MINMAXSPEED_2(10ms) */
69: 1000/200, /* MINMAXSPEED_3(5ms) */
70: 1, /* MINMAXSPEED_MAX(1ms) */
71: };
72:
73:
74:
75:
76: /*-----------------------------------------------------------------------*/
77: /*
78: Save/Restore snapshot of local variables('MemorySnapShot_Store' handles type)
79: */
80: void Main_MemorySnapShot_Capture(BOOL bSave)
81: {
82: int nBytes;
83:
84: /* Save/Restore details */
85: /* Only save/restore area of memory machine ie set to, eg 1Mb */
86: if (bSave) {
87: nBytes = STRamEnd_BusErr;
88: MemorySnapShot_Store(&nBytes,sizeof(nBytes));
89: MemorySnapShot_Store(STRam,nBytes);
90: }
91: else {
92: MemorySnapShot_Store(&nBytes,sizeof(nBytes));
93: MemorySnapShot_Store(STRam,nBytes);
94: }
95: /* And Cart/TOS/Hardware area */
96: MemorySnapShot_Store(&STRam[0xE00000],0x200000);
97: MemorySnapShot_Store(szBootDiscImage,sizeof(szBootDiscImage));
98: MemorySnapShot_Store(szWorkingDir,sizeof(szWorkingDir));
99: MemorySnapShot_Store(szCurrentDir,sizeof(szCurrentDir));
100: }
101:
102:
103: /*-----------------------------------------------------------------------*/
104: /*
105: Error handler
106: */
107: void Main_SysError(char *Error,char *Title)
108: {
1.1.1.2 root 109: fprintf(stderr,"%s : %s\n",Title,Error);
1.1 root 110: }
111:
1.1.1.2 root 112:
1.1 root 113: /*-----------------------------------------------------------------------*/
114: /*
115: Bring up message(handles full-screen as well as Window)
116: */
117: int Main_Message(char *lpText, char *lpCaption/*,unsigned int uType*/)
118: {
119: int Ret=0;
120:
121: /* Show message */
1.1.1.5 ! root 122: fprintf(stderr,"%s: %s\n", lpCaption, lpText);
1.1 root 123:
124: return(Ret);
125: }
126:
127: /*-----------------------------------------------------------------------*/
128: /*
129: Pause emulation, stop sound
130: */
131: void Main_PauseEmulation(void)
132: {
1.1.1.4 root 133: if( bEmulationActive )
134: {
135: SDL_PauseAudio(TRUE);
136: bEmulationActive = FALSE;
137: }
1.1 root 138: }
139:
1.1.1.2 root 140: /*-----------------------------------------------------------------------*/
1.1 root 141: /*
142: Start emulation
143: */
144: void Main_UnPauseEmulation(void)
145: {
1.1.1.4 root 146: if( !bEmulationActive )
147: {
148: SDL_PauseAudio(FALSE);
149: bFullScreenHold = FALSE; /* Release hold */
150: Screen_SetFullUpdate(); /* Cause full screen update(to clear all) */
1.1 root 151:
1.1.1.4 root 152: bEmulationActive = TRUE;
153: Audio_ResetBuffer();
154: }
1.1 root 155: }
156:
157: /* ----------------------------------------------------------------------- */
158: /*
159: Message handler ( actually called from Video_InterruptHandler_VBL() )
160: Here we process the SDL events (keyboard, mouse, ...) and map it to
161: Atari IKBD events.
162: */
163: #ifndef SDL_BUTTON_LEFT /* Seems not to be defined in old SDL versions */
164: #define SDL_BUTTON_LEFT 1
165: #define SDL_BUTTON_MIDDLE 2
166: #define SDL_BUTTON_RIGHT 3
167: #endif
168: void Main_EventHandler()
169: {
1.1.1.4 root 170: SDL_Event event;
1.1 root 171:
1.1.1.4 root 172: if( SDL_PollEvent(&event) )
173: switch( event.type )
1.1 root 174: {
175: case SDL_QUIT:
1.1.1.4 root 176: bQuitProgram = TRUE;
1.1 root 177: break;
1.1.1.4 root 178: case SDL_MOUSEMOTION: /* Read/Update internal mouse position */
179: KeyboardProcessor.Mouse.dx += event.motion.xrel;
180: KeyboardProcessor.Mouse.dy += event.motion.yrel;
1.1 root 181: break;
182: case SDL_MOUSEBUTTONDOWN:
183: if( event.button.button==SDL_BUTTON_LEFT )
1.1.1.4 root 184: {
185: if(Keyboard.LButtonDblClk==0)
186: Keyboard.bLButtonDown |= BUTTON_MOUSE; /* Set button down flag */
187: }
1.1 root 188: else if( event.button.button==SDL_BUTTON_RIGHT )
1.1.1.4 root 189: Keyboard.bRButtonDown |= BUTTON_MOUSE;
1.1 root 190: else if( event.button.button==SDL_BUTTON_MIDDLE )
191: Keyboard.LButtonDblClk = 1; /* Start double-click sequence in emulation time */
192: break;
193: case SDL_MOUSEBUTTONUP:
194: if( event.button.button==SDL_BUTTON_LEFT )
1.1.1.4 root 195: Keyboard.bLButtonDown &= ~BUTTON_MOUSE;
1.1 root 196: else if( event.button.button==SDL_BUTTON_RIGHT )
1.1.1.4 root 197: Keyboard.bRButtonDown &= ~BUTTON_MOUSE;;
1.1 root 198: break;
199: case SDL_KEYDOWN:
1.1.1.4 root 200: Keymap_KeyDown( event.key.keysym.sym, event.key.keysym.mod );
1.1 root 201: break;
202: case SDL_KEYUP:
1.1.1.4 root 203: Keymap_KeyUp( event.key.keysym.sym, event.key.keysym.mod );
1.1 root 204: break;
205: }
206: }
207:
208:
209:
1.1.1.2 root 210: /*-----------------------------------------------------------------------*/
1.1 root 211: /*
1.1.1.3 root 212: This thread runs at 50fps and passes sound samples to the sound interface and also
1.1 root 213: set the counter/events to govern emulation speed to match the two together.
214: */
1.1.1.3 root 215: Uint32 Main_SoundTimerFunc(Uint32 interval, void *param)
1.1 root 216: {
1.1.1.2 root 217: /* Advance frame counter, used to draw screen to window at 50fps */
1.1 root 218: VBLCounter++;
1.1.1.3 root 219: return(interval);
1.1 root 220: }
221:
1.1.1.2 root 222:
223: /*-----------------------------------------------------------------------*/
1.1 root 224: /*
1.1.1.2 root 225: Create sound timer to handle sound
1.1 root 226: */
1.1.1.2 root 227: void Main_CreateSoundTimer(void)
1.1 root 228: {
1.1.1.3 root 229: /* Create thread to run every 20ms (50fps) to handle emulation samples */
230: hSoundTimer = SDL_AddTimer(20, Main_SoundTimerFunc, NULL);
1.1 root 231: }
232:
1.1.1.2 root 233: /*-----------------------------------------------------------------------*/
1.1 root 234: /*
1.1.1.2 root 235: Delete sound timer
1.1 root 236: */
1.1.1.2 root 237: void Main_RemoveSoundTimer(void)
1.1 root 238: {
1.1.1.3 root 239: SDL_RemoveTimer(hSoundTimer);
1.1 root 240: }
1.1.1.2 root 241:
242:
1.1 root 243:
244: /*-----------------------------------------------------------------------*/
245: /*
246: Check for any passed parameters
247: */
248: void Main_ReadParameters(int argc, char *argv[])
249: {
1.1.1.4 root 250: int i;
1.1 root 251:
1.1.1.4 root 252: /* Scan for any which we can use */
253: for(i=1; i<argc; i++)
1.1 root 254: {
1.1.1.4 root 255: if (strlen(argv[i])>0)
1.1 root 256: {
1.1.1.4 root 257: if (!strcmp(argv[i],"--help") || !strcmp(argv[i],"-h"))
1.1 root 258: {
1.1.1.4 root 259: printf("Usage:\n hatari [options] [disk image name]\n"
260: "Where options are:\n"
261: " --help or -h Print this help text and exit.\n"
262: " --version or -v Print version number and exit.\n"
263: " --mono or -m Start in monochrome mode instead of color.\n"
264: " --fullscreen or -f Try to use fullscreen mode.\n"
265: " --joystick or -j Emulate a ST joystick with the cursor keys.\n"
266: " --nosound Disable sound (faster!).\n"
267: " --frameskip Skip every second frame (speeds up emulation!).\n"
268: " --debug or -D Allow debug interface.\n"
269: " --harddrive <dir> Emulate an ST harddrive\n"
270: " or -d <dir> (<dir> = root directory).\n"
271: " --hdimage <imagename> Emulate an ST harddrive with an image.\n"
272: " --tos <file> Use TOS image <file>.\n"
273: " --cpulevel x Set the CPU type (x => 680x0) (TOS 2.06 only!).\n"
274: " --compatible Use a more compatible (but slower) 68000 CPU mode.\n"
1.1.1.5 ! root 275: " --blitter Enable blitter emulation (unstable!)\n"
! 276: " --vdi Use extended VDI resolution\n"
1.1.1.4 root 277: );
278: exit(0);
1.1 root 279: }
280: else if (!strcmp(argv[i],"--version") || !strcmp(argv[i],"-v"))
281: {
1.1.1.4 root 282: printf("This is %s.\n", PROG_NAME);
283: printf("This program is free software licensed under the GNU GPL.\n");
284: exit(0);
1.1 root 285: }
1.1.1.2 root 286: else if (!strcmp(argv[i],"--mono") || !strcmp(argv[i],"-m"))
1.1 root 287: {
1.1.1.4 root 288: bUseHighRes=TRUE;
289: ConfigureParams.Screen.bUseHighRes=TRUE;
290: STRes=PrevSTRes=ST_HIGH_RES;
1.1 root 291: }
292: else if (!strcmp(argv[i],"--fullscreen") || !strcmp(argv[i],"-f"))
293: {
1.1.1.4 root 294: bUseFullscreen=TRUE;
1.1 root 295: }
296: else if (!strcmp(argv[i],"--joystick") || !strcmp(argv[i],"-j"))
297: {
1.1.1.4 root 298: ConfigureParams.Joysticks.Joy[1].bCursorEmulation=TRUE;
1.1 root 299: }
1.1.1.4 root 300: else if ( !strcmp(argv[i],"--nosound") )
1.1.1.2 root 301: {
1.1.1.4 root 302: bDisableSound=TRUE;
303: ConfigureParams.Sound.bEnableSound = FALSE;
1.1.1.2 root 304: }
305: else if ( !strcmp(argv[i],"--frameskip") )
306: {
1.1.1.4 root 307: ConfigureParams.Screen.Advanced.bFrameSkip = TRUE;
1.1.1.2 root 308: }
1.1.1.4 root 309: else if (!strcmp(argv[i],"--debug") || !strcmp(argv[i],"-D"))
1.1.1.2 root 310: {
1.1.1.4 root 311: bEnableDebug=TRUE;
1.1.1.2 root 312: }
1.1.1.4 root 313: else if (!strcmp(argv[i],"--hdimage"))
1.1.1.3 root 314: {
1.1.1.4 root 315: if( argc>i+1 && strlen(argv[i+1])<=MAX_FILENAME_LENGTH )
316: {
317: if( HDC_Init(argv[i+1]) == TRUE)
318: {
319: strcpy(ConfigureParams.HardDisc.szHardDiscImage, argv[i+1]);
320: printf("Hard drive image %s mounted.\n", argv[i+1]);
321: i++;
322: }
323: else
324: {
1.1.1.5 ! root 325: printf("Couldn't open file: %s, or no partitions\n", argv[i+1]);
1.1.1.4 root 326: }
327: }
328: }
329: else if (!strcmp(argv[i],"--harddrive") || !strcmp(argv[i],"-d"))
330: {
331: if( i+1<argc && strlen(argv[i+1])<=MAX_PATH ) /* both parameters exist */
332: {
333: strcpy(ConfigureParams.HardDisc.szHardDiscDirectories[0], argv[i+1]);
334: GemDOS_InitDrives();
335: i += 1;
336: }
1.1.1.3 root 337: }
338: else if (!strcmp(argv[i],"--tos"))
339: {
1.1.1.4 root 340: if(i+1>=argc)
341: fprintf(stderr,"Missing argument for --tos.\n");
1.1.1.3 root 342: else
1.1.1.4 root 343: strncpy(ConfigureParams.TOSGEM.szTOSImageFileName, argv[++i], MAX_FILENAME_LENGTH);
1.1.1.3 root 344: }
345: else if (!strcmp(argv[i],"--cpulevel"))
346: {
1.1.1.4 root 347: if(i+1>=argc)
348: fprintf(stderr,"Missing argument for --cpulevel.\n");
349: else
350: cpu_level = atoi(argv[++i]);
351: if(cpu_level<0 || cpu_level>4)
352: cpu_level = 0;
1.1.1.5 ! root 353: ConfigureParams.System.nCpuLevel = cpu_level;
1.1.1.3 root 354: }
355: else if (!strcmp(argv[i],"--compatible") || !strcmp(argv[i],"-d"))
356: {
1.1.1.4 root 357: cpu_compatible = TRUE;
1.1.1.5 ! root 358: ConfigureParams.System.bCompatibleCpu = TRUE;
! 359: }
! 360: else if (!strcmp(argv[i],"--blitter"))
! 361: {
! 362: bEnableBlitter = TRUE;
! 363: ConfigureParams.System.bBlitter = TRUE;
! 364: }
! 365: else if(!strcmp(argv[i], "--vdi"))
! 366: {
! 367: bUseVDIRes = ConfigureParams.TOSGEM.bUseExtGEMResolutions = TRUE;
1.1.1.3 root 368: }
1.1 root 369: else
370: {
1.1.1.4 root 371: /* Possible passed disc image filename, ie starts with character other than '-' */
372: if (argv[i][0]!='-')
373: strcpy(szBootDiscImage,argv[i]);
1.1.1.3 root 374: else
1.1.1.4 root 375: fprintf(stderr,"Illegal parameter: %s\n",argv[i]);
1.1 root 376: }
377: }
378: }
379: }
380:
1.1.1.2 root 381:
382: /*-----------------------------------------------------------------------*/
1.1 root 383: /*
384: Initialise emulation
385: */
386: void Main_Init(void)
387: {
1.1.1.5 ! root 388: /* Init SDL's video and timer subsystem. Note: Audio and joystick subsystems
! 389: will be initialized later (failures there are not fatal). */
! 390: if( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0 )
1.1.1.4 root 391: {
1.1.1.2 root 392: fprintf(stderr, "Could not initialize the SDL library:\n %s\n", SDL_GetError() );
393: exit(-1);
1.1.1.4 root 394: }
1.1.1.2 root 395:
1.1 root 396: Misc_SeedRandom(1043618);
1.1.1.4 root 397: Configuration_Init();
398: SDLGui_Init();
1.1 root 399: Printer_Init();
400: RS232_Init();
401: Screen_Init();
402: Floppy_Init();
1.1.1.4 root 403: Init680x0(); /* Init CPU emulation */
404: Reset_Cold(); /* Reset all systems */
1.1 root 405: GemDOS_Init();
406: Intercept_Init();
407: Joy_Init();
1.1.1.2 root 408: Audio_Init();
1.1 root 409: Sound_Init();
1.1.1.2 root 410: Main_CreateSoundTimer();
1.1 root 411:
1.1.1.2 root 412: /* Check passed disc image parameter, boot directly into emulator */
1.1 root 413: if (strlen(szBootDiscImage)>0) {
414: Floppy_InsertDiscIntoDrive(0,szBootDiscImage);
415: }
416: }
417:
1.1.1.2 root 418: /*-----------------------------------------------------------------------*/
1.1 root 419: /*
420: Un-Initialise emulation
421: */
422: void Main_UnInit(void)
423: {
424: Screen_ReturnFromFullScreen();
1.1.1.2 root 425: Main_RemoveSoundTimer();
1.1 root 426: Floppy_EjectBothDrives();
427: Floppy_UnInit();
1.1.1.4 root 428: HDC_UnInit();
1.1 root 429: RS232_UnInit();
430: Printer_UnInit();
431: Intercept_UnInit();
1.1.1.4 root 432: GemDOS_UnInitDrives();
1.1.1.5 ! root 433: if(Sound_AreWeRecording())
! 434: Sound_EndRecording();
1.1.1.2 root 435: Audio_UnInit();
1.1 root 436: YMFormat_FreeRecording();
1.1.1.4 root 437: SDLGui_UnInit();
1.1 root 438: Screen_UnInit();
439:
440: #ifdef USE_DEBUGGER
441: FreeDebugDialog();
442: #endif
443: Configuration_UnInit();
1.1.1.2 root 444:
445: /* SDL uninit: */
446: SDL_Quit();
1.1 root 447: }
448:
1.1.1.2 root 449: /*-----------------------------------------------------------------------*/
1.1 root 450: /*
451: Main
452: */
453: int main(int argc, char *argv[])
454: {
455:
456: /* Generate random seed */
457: srand( time(NULL) );
458:
459: /* Get working directory, if in MSDev force */
1.1.1.4 root 460: Misc_FindWorkingDirectory(argv[0]);
1.1 root 461: #ifdef FORCE_WORKING_DIR
462: getcwd(szWorkingDir, MAX_FILENAME_LENGTH);
463: #endif
464:
465: /* Create debug files */
466: Debug_OpenFiles();
467: ErrLog_OpenFile();
468:
1.1.1.2 root 469: /* Set default configuration values: */
470: Configuration_SetDefault();
471:
1.1 root 472: /* Check for any passed parameters */
1.1.1.2 root 473: Main_ReadParameters(argc, argv);
1.1 root 474:
475: /* Init emulator system */
476: Main_Init();
477:
1.1.1.2 root 478: /* Switch immediately to fullscreen if user wants to */
479: if( bUseFullscreen )
480: Screen_EnterFullScreen();
481:
1.1 root 482: /* Set timing threads to govern timing and debug display */
483: //FM Main_SetSpeedThreadTimer(ConfigureParams.Configure.nMinMaxSpeed);
484: //FM TimerID = SetTimer(hWnd,1,1000,NULL);
485:
1.1.1.4 root 486: /* Run emulation */
1.1 root 487: Main_UnPauseEmulation();
1.1.1.4 root 488: Start680x0(); /* Start emulation */
1.1 root 489:
490: /* Un-init emulation system */
491: //FM KillTimer(hWnd,TimerID);
492: Main_UnInit();
493:
494: /* Close debug files */
495: ErrLog_CloseFile();
496: Debug_CloseFiles();
497:
498: return(0);
499: }
1.1.1.3 root 500:
501:
502:
503:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.