Annotation of hatari/src/main.c, revision 1.1.1.5

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.