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

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

unix.superglobalmegacorp.com

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