Annotation of hatari/src/gemdos.c, revision 1.1.1.1

1.1       root        1: /*
                      2:   Hatari
                      3: 
                      4:   GEMDos intercept routines. These are used mainly for Hard Drive redirection of high level
                      5:   file routines.
                      6: */
                      7: 
                      8: #include <sys/types.h>
                      9: #include <sys/stat.h>
                     10: #include <fcntl.h>
                     11: 
                     12: #include "main.h"
                     13: #include "cart.h"
                     14: #include "debug.h"
                     15: #include "decode.h"
                     16: #include "dialog.h"
                     17: #include "file.h"
                     18: #include "floppy.h"
                     19: #include "gemdos.h"
                     20: #include "m68000.h"
                     21: #include "memAlloc.h"
                     22: #include "memorySnapShot.h"
                     23: #include "misc.h"
                     24: #include "printer.h"
                     25: #include "rs232.h"
                     26: #include "statusBar.h"
                     27: #include "stMemory.h"
                     28: #include "view.h"
                     29: 
                     30: #define ENABLE_SAVING             /* Turn on saving stuff */
                     31: 
                     32: #define INVALID_HANDLE_VALUE -1
                     33: 
                     34: #ifndef MAX_PATH
                     35: #define MAX_PATH 256
                     36: #endif
                     37: 
                     38: typedef struct 
                     39: {
                     40:  BOOL bUsed;
                     41:  int FileHandle;
                     42: } FILE_HANDLE;
                     43: 
                     44: FILE_HANDLE  FileHandles[MAX_FILE_HANDLES];
                     45: //INTERNAL_DTA InternalDTAs[MAX_DTAS_FILES];
                     46: int DTAIndex;                                 /* Circular index into above */
                     47: BOOL bInitGemDOS;                             /* Have we re-directed GemDOS vector to our own routines yet? */
                     48: DTA *pDTA;                                    /* Our GEMDOS hard drive Disc Transfer Address structure */
                     49: unsigned short int CurrentDrive;              /* Current drive (0=A,1=B,2=C etc...) */
                     50: 
                     51: #ifdef DEBUG_TO_FILE
                     52: /* List of GEMDos functions... */
                     53: char *pszGemDOSNames[] = {
                     54:   "Term",                 //0x00
                     55:   "Conin",                //0x01
                     56:   "ConOut",               //0x02
                     57:   "Auxiliary Input",      //0x03
                     58:   "Auxiliary Output",     //0x04
                     59:   "Printer Output",       //0x05
                     60:   "RawConIO",             //0x06
                     61:   "Direct Conin no echo", //0x07
                     62:   "Conin no echo",        //0x08
                     63:   "Print line",           //0x09
                     64:   "ReadLine",             //0x0a
                     65:   "ConStat",              //0x0b
                     66:   "",                     //0x0c
                     67:   "",                     //0x0d
                     68:   "SetDrv",               //0x0e
                     69:   "",                     //0x0f
                     70:   "Conout Stat",          //0x10
                     71:   "PrtOut Stat",          //0x11
                     72:   "Auxin Stat",           //0x12
                     73:   "AuxOut Stat",          //0x13
                     74:   "",                     //0x14
                     75:   "",                     //0x15
                     76:   "",                     //0x16
                     77:   "",                     //0x17
                     78:   "",                     //0x18
                     79:   "Current Disk",         //0x19
                     80:   "Set DTA",              //0x1a
                     81:   "",        //0x1b
                     82:   "",        //0x1c
                     83:   "",        //0x1d
                     84:   "",        //0x1e
                     85:   "",        //0x1f
                     86:   "Super",   //0x20
                     87:   "",        //0x21
                     88:   "",        //0x22
                     89:   "",        //0x23
                     90:   "",        //0x24
                     91:   "",        //0x25
                     92:   "",        //0x26
                     93:   "",        //0x27
                     94:   "",        //0x28
                     95:   "",        //0x29
                     96:   "Get Date",      //0x2a
                     97:   "Set Date",      //0x2b
                     98:   "Get Time",      //0x2c
                     99:   "Set Time",      //0x2d
                    100:   "",              //0x2e
                    101:   "Get DTA",       //0x2f
                    102:   "Get Version Number",   //0x30
                    103:   "Keep Process",         //0x31
                    104:   "",        //0x32
                    105:   "",        //0x33
                    106:   "",        //0x34
                    107:   "",        //0x35
                    108:   "Get Disk Free Space",  //0x36
                    109:   "",           //0x37
                    110:   "",           //0x38
                    111:   "MkDir",      //0x39
                    112:   "RmDir",      //0x3a
                    113:   "ChDir",      //0x3b
                    114:   "Create",     //0x3c
                    115:   "Open",       //0x3d
                    116:   "Close",      //0x3e
                    117:   "Read",       //0x3f
                    118:   "Write",      //0x40
                    119:   "UnLink",     //0x41
                    120:   "LSeek",      //0x42
                    121:   "ChMod",      //0x43
                    122:   "",           //0x44
                    123:   "Dup",        //0x45
                    124:   "Force",      //0x46
                    125:   "GetDir",     //0x47
                    126:   "Malloc",     //0x48
                    127:   "MFree",      //0x49
                    128:   "SetBlock",   //0x4a
                    129:   "Exec",       //0x4b
                    130:   "Term",       //0x4c
                    131:   "",           //0x4d
                    132:   "SFirst",     //0x4e
                    133:   "SNext",      //0x4f
                    134:   "",           //0x50
                    135:   "",           //0x51
                    136:   "",           //0x52
                    137:   "",           //0x53
                    138:   "",           //0x54
                    139:   "",           //0x55
                    140:   "Rename",     //0x56
                    141:   "GSDTof"      //0x57
                    142: };
                    143: #endif
                    144: 
                    145: 
                    146: 
                    147: /* Convert a string to uppercase */
                    148: void strupr(char *string)
                    149: {
                    150:  int i;
                    151:  for(i=0; i<strlen(string); i++)
                    152:    string[i] = toupper(string[i]);
                    153: }
                    154: 
                    155: 
                    156: //-----------------------------------------------------------------------
                    157: /*
                    158:   Initialize GemDOS/PC file system
                    159: */
                    160: void GemDOS_Init(void)
                    161: {
                    162:   // Clear handles structure
                    163:   Memory_Clear(FileHandles,sizeof(FILE_HANDLE)*MAX_FILE_HANDLES);
                    164: }
                    165: 
                    166: //-----------------------------------------------------------------------
                    167: /*
                    168:   Reset GemDOS file system
                    169: */
                    170: void GemDOS_Reset(void)
                    171: {
                    172:   int i;
                    173: 
                    174:   // Init file handles table
                    175:   for(i=0; i<MAX_FILE_HANDLES; i++) {
                    176:     // Was file open? If so close it
                    177:     if (FileHandles[i].bUsed)
                    178:       close(FileHandles[i].FileHandle);
                    179: 
                    180:     FileHandles[i].FileHandle = INVALID_HANDLE_VALUE;
                    181:     FileHandles[i].bUsed = FALSE;
                    182:   }
                    183: 
                    184:   // Reset
                    185:   bInitGemDOS = FALSE;
                    186:   CurrentDrive = nBootDrive;
                    187:   pDTA = NULL;
                    188:   DTAIndex = 0;
                    189: }
                    190: 
                    191: //-----------------------------------------------------------------------
                    192: /*
                    193:   Save/Restore snapshot of local variables('MemorySnapShot_Store' handles type)
                    194: */
                    195: void GemDOS_MemorySnapShot_Capture(BOOL bSave)
                    196: {
                    197:   unsigned int Addr;
                    198:   int i;
                    199: 
                    200:   // Save/Restore details
                    201:   MemorySnapShot_Store(&DTAIndex,sizeof(DTAIndex));
                    202:   MemorySnapShot_Store(&bInitGemDOS,sizeof(bInitGemDOS));
                    203:   if (bSave) {
                    204:     Addr = (unsigned int)pDTA-(unsigned int)STRam;
                    205:     MemorySnapShot_Store(&Addr,sizeof(Addr));
                    206:   }
                    207:   else {
                    208:     MemorySnapShot_Store(&Addr,sizeof(Addr));
                    209:     pDTA = (DTA *)((unsigned int)STRam+(unsigned int)Addr);
                    210:   }
                    211:   MemorySnapShot_Store(&CurrentDrive,sizeof(CurrentDrive));
                    212:   // Don't save file handles as files may have changed which makes
                    213:   // it impossible to get a valid handle back
                    214:   if (!bSave) {
                    215:     // Clear file handles
                    216:     for(i=0; i<MAX_FILE_HANDLES; i++) {
                    217:       FileHandles[i].FileHandle = INVALID_HANDLE_VALUE;
                    218:       FileHandles[i].bUsed = FALSE;
                    219:     }
                    220:     // And DTAs
                    221: /*FIXME*/
                    222: /*    for(i=0; i<MAX_DTAS_FILES; i++) {
                    223:       InternalDTAs[i].FileHandle = INVALID_HANDLE_VALUE;
                    224:       memset(&InternalDTAs[i].FindFileData,0x0,sizeof(WIN32_FIND_DATA));
                    225:     }
                    226: */
                    227:   }
                    228: }
                    229: 
                    230: //-----------------------------------------------------------------------
                    231: /*
                    232:   Return free PC file handle table index, or -1 if error
                    233: */
                    234: int GemDOS_FindFreeFileHandle(void)
                    235: {
                    236:   int i;
                    237: 
                    238:   /* Scan our file list for free slot */
                    239:   for(i=0; i<MAX_FILE_HANDLES; i++) {
                    240:     if (!FileHandles[i].bUsed)
                    241:       return(i);
                    242:   }
                    243: 
                    244:   /* Cannot open any more files, return error */
                    245:   return(-1);
                    246: }
                    247: 
                    248: //-----------------------------------------------------------------------
                    249: /*
                    250:   Check ST handle is within our table range, return TRUE if not
                    251: */
                    252: BOOL GemDOS_IsInvalidFileHandle(int Handle)
                    253: {
                    254:   BOOL bInvalidHandle=FALSE;
                    255: 
                    256:   /* Check handle was valid with our handle table */
                    257:   if ( (Handle<0) || (Handle>=MAX_FILE_HANDLES) )
                    258:     bInvalidHandle = TRUE;
                    259:   else if (!FileHandles[Handle].bUsed)
                    260:     bInvalidHandle = TRUE;
                    261: 
                    262:   return(bInvalidHandle);
                    263: }
                    264: 
                    265: //-----------------------------------------------------------------------
                    266: /*
                    267:   Find drive letter from a filename, eg C,D... and return as drive ID(C:2, D:3...)
                    268: */
                    269: int GemDOS_FindDriveNumber(char *pszFileName)
                    270: {
                    271:   /* Does have 'A:' or 'C:' etc.. at start of string? */
                    272:   if ( (pszFileName[0]!='\0') && (pszFileName[1]==':') ) {
                    273:     if ( (pszFileName[0]>='a') && (pszFileName[0]<='z') )
                    274:       return(pszFileName[0]-'a');
                    275:     else if ( (pszFileName[0]>='A') && (pszFileName[0]<='Z') )
                    276:       return(pszFileName[0]-'A');
                    277:   }
                    278: 
                    279:   return(CurrentDrive);
                    280: }
                    281: 
                    282: //-----------------------------------------------------------------------
                    283: /*
                    284:   Return drive ID(C:2, D:3 etc...) or -1 if not one of our emulation hard-drives
                    285: */
                    286: int GemDOS_IsFileNameAHardDrive(char *pszFileName)
                    287: {
                    288:   int DriveLetter;
                    289: 
                    290:   /* Do we even have a hard-drive? */
                    291:   if (ConfigureParams.HardDisc.nDriveList!=DRIVELIST_NONE) {
                    292:     // Find drive letter(as number)
                    293:     DriveLetter = GemDOS_FindDriveNumber(pszFileName);
                    294:     // Does match one of our drives?
                    295:     if ( (DriveLetter>=2) && (DriveLetter<=DRIVELIST_TO_DRIVE_INDEX(ConfigureParams.HardDisc.nDriveList)) )
                    296:       return(DriveLetter);
                    297:   }
                    298: 
                    299:   // No, let TOS handle it
                    300:   return(-1);
                    301: }
                    302: 
                    303: //-----------------------------------------------------------------------
                    304: /*
                    305:   Use hard-drive directory, current ST directory and filename to create full path
                    306: */
                    307: void GemDOS_CreateHardDriveFileName(int Drive,char *pszFileName,char *pszDestName)
                    308: {
                    309:   int DirIndex = Misc_LimitInt(Drive-2, 0,ConfigureParams.HardDisc.nDriveList-1);
                    310: //  debug << "::" << pszFileName << endl;
                    311:   /* Combine names */
                    312:   if (File_IsRootFileName(pszFileName))
                    313:     sprintf(pszDestName,"%s%s",ConfigureParams.HardDisc.szHardDiscDirectories[DirIndex],File_RemoveFileNameDrive(pszFileName));
                    314:   else {
                    315:     if (File_DoesFileNameEndWithSlash(szCurrentDir))
                    316:       sprintf(pszDestName,"%s%s%s",ConfigureParams.HardDisc.szHardDiscDirectories[DirIndex],File_RemoveFileNameDrive(szCurrentDir),File_RemoveFileNameDrive(pszFileName));
                    317:     else
                    318:       sprintf(pszDestName,"%s%s/%s",ConfigureParams.HardDisc.szHardDiscDirectories[DirIndex],File_RemoveFileNameDrive(szCurrentDir),File_RemoveFileNameDrive(pszFileName));
                    319:   }
                    320:   // Remove any '/'s at end of filenames
                    321:   File_RemoveFileNameTrailingSlashes(pszDestName);
                    322: 
                    323:   // And make all upper case, as original ST
                    324:   strupr(pszDestName);
                    325: //  debug << "\t" << pszDestName << endl;
                    326: }
                    327: 
                    328: //-----------------------------------------------------------------------
                    329: /*
                    330:   Covert from FindFirstFile/FindNextFile attribute to GemDOS format
                    331: */
                    332: char GemDOS_ConvertAttribute(int dwFileAttributes)
                    333: {
                    334:   char Attrib=0;
                    335: /* FIXME */
                    336: /*
                    337:   // Look up attributes
                    338:   if (dwFileAttributes&FILE_ATTRIBUTE_READONLY)
                    339:     Attrib |= GEMDOS_FILE_ATTRIB_READONLY;
                    340:   if (dwFileAttributes&FILE_ATTRIBUTE_HIDDEN)
                    341:     Attrib |= GEMDOS_FILE_ATTRIB_HIDDEN;
                    342:   if (dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
                    343:     Attrib |= GEMDOS_FILE_ATTRIB_SUBDIRECTORY;
                    344: */
                    345:   return(Attrib);
                    346: }
                    347: 
                    348: //-----------------------------------------------------------------------
                    349: /*
                    350:   GEMDOS Cauxin
                    351:   Call 0x3
                    352: */
                    353: BOOL GemDOS_Cauxin(unsigned long Params)
                    354: {
                    355:   unsigned char Char;
                    356: 
                    357:   // Wait here until a character is ready
                    358:   while(!RS232_GetStatus());
                    359: 
                    360:   // And read character
                    361:   RS232_ReadBytes(&Char,1);
                    362:   Regs[REG_D0] = Char;
                    363: 
                    364:   return(TRUE);
                    365: }
                    366: 
                    367: //-----------------------------------------------------------------------
                    368: /*
                    369:   GEMDOS Cauxout
                    370:   Call 0x4
                    371: */
                    372: BOOL GemDOS_Cauxout(unsigned long Params)
                    373: {
                    374:   unsigned char Char;
                    375: 
                    376:   // Send character to RS232
                    377:   Char = STMemory_ReadWord(Params+SIZE_WORD);
                    378:   RS232_TransferBytesTo(&Char,1);
                    379: 
                    380:   return(TRUE);
                    381: }
                    382: 
                    383: //-----------------------------------------------------------------------
                    384: /*
                    385:   GEMDOS Cprnout
                    386:   Call 0x5
                    387: */
                    388: BOOL GemDOS_Cprnout(unsigned long Params)
                    389: {
                    390:   unsigned char Char;
                    391: 
                    392:   // Send character to printer(or file)
                    393:   Char = STMemory_ReadWord(Params+SIZE_WORD);
                    394:   Printer_TransferByteTo(Char);
                    395:   Regs[REG_D0] = -1;                // Printer OK
                    396: 
                    397:   return(TRUE);
                    398: }
                    399: 
                    400: //-----------------------------------------------------------------------
                    401: /*
                    402:   GEMDOS Set drive (0=A,1=B,2=C etc...)
                    403:   Call 0xE
                    404: */
                    405: BOOL GemDOS_SetDrv(unsigned long Params)
                    406: {
                    407:   // Read details from stack for our own use
                    408:   CurrentDrive = STMemory_ReadWord(Params+SIZE_WORD);
                    409: //  debug << "CurrentDrive: " << CurrentDrive << endl;
                    410: 
                    411:   // Still re-direct to TOS
                    412:   return(FALSE);
                    413: }
                    414: 
                    415: //-----------------------------------------------------------------------
                    416: /*
                    417:   GEMDOS Cprnos
                    418:   Call 0x11
                    419: */
                    420: BOOL GemDOS_Cprnos(unsigned long Params)
                    421: {
                    422:   Regs[REG_D0] = -1;                // Printer OK
                    423: 
                    424:   return(TRUE);
                    425: }
                    426: 
                    427: //-----------------------------------------------------------------------
                    428: /*
                    429:   GEMDOS Cauxis
                    430:   Call 0x12
                    431: */
                    432: BOOL GemDOS_Cauxis(unsigned long Params)
                    433: {
                    434:   // Read our RS232 state
                    435:   if (RS232_GetStatus())
                    436:     Regs[REG_D0] = -1;              // Chars waiting
                    437:   else
                    438:     Regs[REG_D0] = 0;
                    439: 
                    440:   return(TRUE);
                    441: }
                    442: 
                    443: //-----------------------------------------------------------------------
                    444: /*
                    445:   GEMDOS Cauxos
                    446:   Call 0x13
                    447: */
                    448: BOOL GemDOS_Cauxos(unsigned long Params)
                    449: {
                    450:   Regs[REG_D0] = -1;                // Device ready
                    451: 
                    452:   return(TRUE);
                    453: }
                    454: 
                    455: //-----------------------------------------------------------------------
                    456: /*
                    457:   GEMDOS Set Disc Transfer Address (DTA)
                    458:   Call 0x1A
                    459: */
                    460: BOOL GemDOS_SetDTA(unsigned long Params)
                    461: {
                    462:   // Look up on stack to find where DTA is! Store as PC pointer
                    463:   pDTA = (DTA *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD));
                    464:   
                    465: //  char szString[256];
                    466: //  sprintf(szString,"0x%X",STMemory_ReadLong(Params+SIZE_WORD));
                    467: //  debug << " to " << szString << endl;
                    468: 
                    469:   // Still re-direct to TOS
                    470:   return(FALSE);
                    471: }
                    472: 
                    473: //-----------------------------------------------------------------------
                    474: /*
                    475:   GEMDOS MkDir
                    476:   Call 0x39
                    477: */
                    478: BOOL GemDOS_MkDir(unsigned long Params)
                    479: {  
                    480:   char szDirPath[MAX_PATH];
                    481:   char *pDirName;
                    482:   int Drive;
                    483: 
                    484:   // Find directory to make
                    485:   pDirName = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD));
                    486: //  debug << pDirName << endl;
                    487:   Drive = GemDOS_IsFileNameAHardDrive(pDirName);
                    488: //  debug << Drive << endl;
                    489:   if (ISHARDDRIVE(Drive)) {
                    490:     // Copy old directory, as if calls fails keep this one
                    491:     GemDOS_CreateHardDriveFileName(Drive,pDirName,szDirPath);
                    492: 
                    493:     // Attempt to make directory
                    494:     if ( mkdir(szDirPath, 0755)==0 )
                    495:       Regs[REG_D0] = GEMDOS_EOK;
                    496:     else
                    497:       Regs[REG_D0] = GEMDOS_EACCDN;        // Access denied
                    498: 
                    499:     return(TRUE);
                    500:   }
                    501:   return(FALSE);
                    502: }
                    503: 
                    504: //-----------------------------------------------------------------------
                    505: /*
                    506:   GEMDOS RmDir
                    507:   Call 0x3A
                    508: */
                    509: BOOL GemDOS_RmDir(unsigned long Params)
                    510: {  
                    511:   char szDirPath[MAX_PATH];
                    512:   char *pDirName;
                    513:   int Drive;
                    514: 
                    515:   // Find directory to make
                    516:   pDirName = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD));
                    517:   Drive = GemDOS_IsFileNameAHardDrive(pDirName);
                    518:   if (ISHARDDRIVE(Drive)) {
                    519:     // Copy old directory, as if calls fails keep this one
                    520:     GemDOS_CreateHardDriveFileName(Drive,pDirName,szDirPath);
                    521: 
                    522:     // Attempt to make directory
                    523:     if ( rmdir(szDirPath)==0 )
                    524:       Regs[REG_D0] = GEMDOS_EOK;
                    525:     else
                    526:       Regs[REG_D0] = GEMDOS_EACCDN;        // Access denied
                    527: 
                    528:     return(TRUE);
                    529:   }
                    530:   return(FALSE);
                    531: }
                    532: 
                    533: //-----------------------------------------------------------------------
                    534: /*
                    535:   GEMDOS ChDir
                    536:   Call 0x3B
                    537: */
                    538: BOOL GemDOS_ChDir(unsigned long Params)
                    539: {  
                    540:   char szDirPath[MAX_PATH];
                    541:   char *pDirName;
                    542:   int Drive;
                    543: 
                    544:   // Find new directory
                    545:   pDirName = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD));
                    546: //  debug << pDirName << endl;
                    547:   Drive = GemDOS_IsFileNameAHardDrive(pDirName);
                    548:   if (ISHARDDRIVE(Drive)) {
                    549:     // Check path exists, else error
                    550:     GemDOS_CreateHardDriveFileName(Drive,"",szDirPath);
                    551: 
                    552:     if ( chdir(szDirPath)==0 ) {
                    553:       strcpy(szCurrentDir,pDirName);
                    554:       Regs[REG_D0] = GEMDOS_EOK;
                    555:     }
                    556:     else
                    557:       Regs[REG_D0] = GEMDOS_EPTHNF;        // Path not found
                    558: 
                    559:     return(TRUE);
                    560:   }
                    561: 
                    562:   return(FALSE);
                    563: }
                    564: 
                    565: //-----------------------------------------------------------------------
                    566: /*
                    567:   GEMDOS Create file
                    568:   Call 0x3C
                    569: */
                    570: BOOL GemDOS_Create(unsigned long Params)
                    571: {
                    572:   char szActualFileName[MAX_PATH];
                    573:   char *pszFileName;
                    574:   unsigned int Access;
                    575:   int Drive,Index,Mode;
                    576: 
                    577:   // Find filename
                    578:   pszFileName = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD));
                    579:   Mode = STMemory_ReadWord(Params+SIZE_WORD+SIZE_LONG);
                    580:   Drive = GemDOS_IsFileNameAHardDrive(pszFileName);
                    581:   if (ISHARDDRIVE(Drive)) {
                    582:     // And convert to hard drive filename
                    583:     GemDOS_CreateHardDriveFileName(Drive,pszFileName,szActualFileName);
                    584: 
                    585:     // Find slot to store file handle, as need to return WORD handle for ST (NOTE PC's Window handles are all LONGS)
                    586:     Index = GemDOS_FindFreeFileHandle();
                    587:     if (Index==-1) {
                    588:       // No free handles, return error code
                    589:       Regs[REG_D0] = GEMDOS_ENHNDL;       // No more handles
                    590:       return(TRUE);
                    591:     }
                    592:     else {
                    593: #ifdef ENABLE_SAVING
                    594:       // Select mode
                    595:       switch(Mode&0x01) {                 // Top bits used in some TOSes
                    596:         case 0:                           // Read/Write
                    597: //FIXME          Access = GENERIC_READ|GENERIC_WRITE;
                    598:           break;
                    599:         case 1:                           // Write only
                    600: //FIXME          Access = GENERIC_WRITE;
                    601:           break;
                    602:       }
                    603: 
                    604: //FIXME      FileHandles[Index].FileHandle = CreateFile(szActualFileName,Access,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
                    605:       if (FileHandles[Index].FileHandle!=INVALID_HANDLE_VALUE) {
                    606:         /* Tag handle table entry as used and return handle */
                    607:         FileHandles[Index].bUsed = TRUE;
                    608:         Regs[REG_D0] = Index+BASE_FILEHANDLE;  // Return valid ST file handle from range 6 to 45! (ours start from 0)
                    609: 
                    610:         return(TRUE);
                    611:       }
                    612:       else {
                    613:         Regs[REG_D0] = GEMDOS_EFILNF;     // File not found
                    614:         return(TRUE);
                    615:       }
                    616: #else
                    617:       Regs[REG_D0] = GEMDOS_EFILNF;       // File not found
                    618:       return(TRUE);
                    619: #endif
                    620:     }
                    621:   }
                    622: 
                    623:   return(FALSE);
                    624: }
                    625: 
                    626: //-----------------------------------------------------------------------
                    627: /*
                    628:   GEMDOS Open file
                    629:   Call 0x3D
                    630: */
                    631: BOOL GemDOS_Open(unsigned long Params)
                    632: {
                    633:   char szActualFileName[MAX_PATH];
                    634:   char *pszFileName;
                    635:   unsigned int Access;
                    636:   int Drive,Index,Mode;
                    637: 
                    638:   // Find filename
                    639:   pszFileName = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD));
                    640:   Mode = STMemory_ReadWord(Params+SIZE_WORD+SIZE_LONG);
                    641:   Drive = GemDOS_IsFileNameAHardDrive(pszFileName);
                    642: //  Debug_File("Open %s\n",pszFileName);
                    643:   if (ISHARDDRIVE(Drive)) {
                    644:     // And convert to hard drive filename
                    645:     GemDOS_CreateHardDriveFileName(Drive,pszFileName,szActualFileName);
                    646: 
                    647:     // Find slot to store file handle, as need to return WORD handle for ST (NOTE PC's Window handles are all LONGS)
                    648:     Index = GemDOS_FindFreeFileHandle();
                    649:     if (Index==-1) {
                    650:       // No free handles, return error code
                    651:       Regs[REG_D0] = GEMDOS_ENHNDL;       // No more handles
                    652:       return(TRUE);
                    653:     }
                    654:     else {
                    655:       // Select mode
                    656:       switch(Mode&0x03) {                 // Top bits used in some TOSes
                    657:         case 0:                           // Read only
                    658: //FIXME          Access = GENERIC_READ;
                    659:           break;
                    660:         case 1:                           // Write only
                    661: //FIXME          Access = GENERIC_WRITE;
                    662:           break;
                    663:         case 2:                           // Read/Write
                    664: //FIXME          Access = GENERIC_READ|GENERIC_WRITE;
                    665:           break;
                    666:       }
                    667: 
                    668:       // Open file
                    669: //FIXME      FileHandles[Index].FileHandle = CreateFile(szActualFileName,Access,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
                    670:       if (FileHandles[Index].FileHandle!=INVALID_HANDLE_VALUE) {
                    671:         // Tag handle table entry as used and return handle
                    672:         FileHandles[Index].bUsed = TRUE;
                    673:         Regs[REG_D0] = Index+BASE_FILEHANDLE;  // Return valid ST file handle from range 6 to 45! (ours start from 0)
                    674: 
                    675:         return(TRUE);
                    676:       }
                    677:       else {
                    678:         Regs[REG_D0] = GEMDOS_EFILNF;     // File not found
                    679:         return(TRUE);
                    680:       }
                    681:     }
                    682:   }
                    683: 
                    684:   return(FALSE);
                    685: }
                    686: 
                    687: //-----------------------------------------------------------------------
                    688: /*
                    689:   GEMDOS Close file
                    690:   Call 0x3E  
                    691: */
                    692: BOOL GemDOS_Close(unsigned long Params)
                    693: {
                    694:   int Handle;
                    695: 
                    696:   // Find our handle - may belong to TOS
                    697:   Handle = STMemory_ReadWord(Params+SIZE_WORD)-BASE_FILEHANDLE;
                    698: 
                    699:   // Check handle was valid
                    700:   if (GemDOS_IsInvalidFileHandle(Handle)) {
                    701:     // No assume was TOS
                    702:     return(FALSE);
                    703:   }
                    704:   else {
                    705:     // Close file and free up handle table
                    706:     close(FileHandles[Handle].FileHandle);
                    707:     FileHandles[Handle].bUsed = FALSE;
                    708:     // Return no error
                    709:     Regs[REG_D0] = GEMDOS_EOK;
                    710:     return(TRUE);
                    711:   }
                    712: }
                    713: 
                    714: //-----------------------------------------------------------------------
                    715: /*
                    716:   GEMDOS Read file
                    717:   Call 0x3F
                    718: */
                    719: BOOL GemDOS_Read(unsigned long Params)
                    720: {
                    721:   char *pBuffer;
                    722:   unsigned long nBytesRead,Size,CurrentPos,FileSize,nBytesLeft;
                    723:   int Handle;
                    724: 
                    725:   // Read details from stack
                    726:   Handle = STMemory_ReadWord(Params+SIZE_WORD)-BASE_FILEHANDLE;
                    727:   Size = STMemory_ReadLong(Params+SIZE_WORD+SIZE_WORD);
                    728:   pBuffer = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD+SIZE_WORD+SIZE_LONG));
                    729: 
                    730:   // Check handle was valid
                    731:   if (GemDOS_IsInvalidFileHandle(Handle)) {
                    732:     // No assume was TOS
                    733:     return(FALSE);
                    734:   }
                    735:   else {
                    736:     StatusBar_SetIcon(STATUS_ICON_HARDDRIVE,ICONSTATE_UPDATE);
                    737: 
                    738:     // To quick check to see where our file pointer is and how large the file is
                    739:     CurrentPos = lseek(FileHandles[Handle].FileHandle, 0, SEEK_CUR);
                    740:     FileSize = lseek(FileHandles[Handle].FileHandle, 0, SEEK_END);
                    741:     lseek(FileHandles[Handle].FileHandle, CurrentPos, SEEK_SET);
                    742: 
                    743:     nBytesLeft = FileSize-CurrentPos;
                    744: 
                    745:     // Check for End Of File
                    746:     if (nBytesLeft<0) {
                    747:       Regs[REG_D0] = GEMDOS_ERROR;
                    748: 
                    749:       return(TRUE);
                    750:     }
                    751:     else {
                    752:       // Limit to size of file to prevent windows error
                    753:       if (Size>FileSize)
                    754:         Size = FileSize;
                    755:       // And read data in
                    756:       nBytesRead = read(FileHandles[Handle].FileHandle, pBuffer, Size);
                    757: //???      FlushFileBuffers(FileHandles[Handle].FileHandle);
                    758: 
                    759:       // Return number of bytes read
                    760:       Regs[REG_D0] = nBytesRead;
                    761: 
                    762:       return(TRUE);
                    763:     }
                    764:   }
                    765: }
                    766: 
                    767: //-----------------------------------------------------------------------
                    768: /*
                    769:   GEMDOS Write file
                    770:   Call 0x40
                    771: */
                    772: BOOL GemDOS_Write(unsigned long Params)
                    773: {
                    774:   char *pBuffer;
                    775:   unsigned long Size,nBytesWritten;
                    776:   int Handle;
                    777: 
                    778: #ifdef ENABLE_SAVING
                    779:   // Read details from stack
                    780:   Handle = STMemory_ReadWord(Params+SIZE_WORD)-BASE_FILEHANDLE;
                    781:   Size = STMemory_ReadLong(Params+SIZE_WORD+SIZE_WORD);
                    782:   pBuffer = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD+SIZE_WORD+SIZE_LONG));
                    783: 
                    784:   // Check handle was valid
                    785:   if (GemDOS_IsInvalidFileHandle(Handle)) {
                    786:     // No assume was TOS
                    787:     return(FALSE);
                    788:   }
                    789:   else {
                    790:     StatusBar_SetIcon(STATUS_ICON_HARDDRIVE,ICONSTATE_UPDATE);
                    791: 
                    792:     nBytesWritten = write(FileHandles[Handle].FileHandle, pBuffer, Size);
                    793:     if (nBytesWritten>=0) {
                    794: //???      FlushFileBuffers(FileHandles[Handle].FileHandle);
                    795: 
                    796:       Regs[REG_D0] = nBytesWritten;      // OK
                    797:     }
                    798:     else
                    799:       Regs[REG_D0] = GEMDOS_EACCDN;      // Access denied(ie read-only)
                    800: 
                    801:     return(TRUE);
                    802:   }
                    803: #endif
                    804: 
                    805:   return(FALSE);
                    806: }
                    807: 
                    808: //-----------------------------------------------------------------------
                    809: /*
                    810:   GEMDOS UnLink(Delete) file
                    811:   Call 0x41
                    812: */
                    813: BOOL GemDOS_UnLink(unsigned long Params)
                    814: {
                    815: #ifdef ENABLE_SAVING
                    816:   char szActualFileName[MAX_PATH];
                    817:   char *pszFileName;
                    818:   int Drive;
                    819: 
                    820:   // Find filename
                    821:   pszFileName = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD));
                    822:   Drive = GemDOS_IsFileNameAHardDrive(pszFileName);
                    823:   if (ISHARDDRIVE(Drive)) {
                    824:     // And convert to hard drive filename
                    825:     GemDOS_CreateHardDriveFileName(Drive,pszFileName,szActualFileName);
                    826: 
                    827:     // Now delete file??
                    828:     if ( unlink(szActualFileName)==0 )
                    829:       Regs[REG_D0] = GEMDOS_EOK;          // OK
                    830:     else
                    831:       Regs[REG_D0] = GEMDOS_EFILNF;       // File not found
                    832: 
                    833:     return(TRUE);
                    834:   }
                    835: #endif
                    836: 
                    837:   return(FALSE);
                    838: }
                    839: 
                    840: //-----------------------------------------------------------------------
                    841: /*
                    842:   GEMDOS File seek
                    843:   Call 0x42
                    844: */
                    845: BOOL GemDOS_LSeek(unsigned long Params)
                    846: {
                    847:   long Offset;
                    848:   int Handle,Mode;
                    849: 
                    850:   // Read details from stack
                    851:   Offset = (long)STMemory_ReadLong(Params+SIZE_WORD);
                    852:   Handle = STMemory_ReadWord(Params+SIZE_WORD+SIZE_LONG)-BASE_FILEHANDLE;
                    853:   Mode = STMemory_ReadWord(Params+SIZE_WORD+SIZE_LONG+SIZE_WORD);
                    854: 
                    855:   // Check handle was valid
                    856:   if (GemDOS_IsInvalidFileHandle(Handle)) {
                    857:     // No assume was TOS
                    858:     return(FALSE);
                    859:   }
                    860:   else {
                    861:     // Return offset from start of file
                    862:     Regs[REG_D0] = lseek(FileHandles[Handle].FileHandle, Offset, Mode);
                    863:     return(TRUE);
                    864:   }
                    865: }
                    866: 
                    867: //-----------------------------------------------------------------------
                    868: /*
                    869:   PExec Load And Go - Redirect to cart' routine at address 0xFA1000
                    870: 
                    871:   If loading from hard-drive(ie drive ID 2 or more) set condition codes to run own GEMDos routines
                    872: */
                    873: void GemDOS_Pexec_LoadAndGo(unsigned long Params)
                    874: {
                    875:   // Hard-drive?
                    876:   if (CurrentDrive>=2)                // If not using A: or B:, use my own routines to load
                    877:     SR = (SR&0xff00) | SR_OVERFLOW;
                    878: }
                    879: 
                    880: //-----------------------------------------------------------------------
                    881: /*
                    882:   PExec Load But Don't Go - Redirect to cart' routine at address 0xFA1000
                    883: */
                    884: void GemDOS_Pexec_LoadDontGo(unsigned long Params)
                    885: {
                    886:   // Hard-drive?
                    887:   if (CurrentDrive>=2)
                    888:     SR = (SR&0xff00) | SR_OVERFLOW;
                    889: }
                    890: 
                    891: //-----------------------------------------------------------------------
                    892: /*
                    893:   GEMDOS PExec handler
                    894:   Call 0x4B
                    895: */
                    896: BOOL GemDOS_Pexec(unsigned long Params)
                    897: {
                    898:   unsigned short int Mode;
                    899: 
                    900:   // Find PExec mode
                    901:   Mode = STMemory_ReadWord(Params+SIZE_WORD);
                    902: //  Debug_File("Pexec %d (Drv:%d)\n",Mode,CurrentDrive);
                    903: 
                    904:   // Re-direct as needed
                    905:   switch(Mode) {
                    906:     case 0:      // Load and go
                    907:       GemDOS_Pexec_LoadAndGo(Params);
                    908:       return(FALSE);
                    909:     case 3:      // Load, don't go
                    910:       GemDOS_Pexec_LoadDontGo(Params);
                    911:       return(FALSE);
                    912:     case 4:      // Just go
                    913:       return(FALSE);
                    914:     case 5:      // Create basepage
                    915:       return(FALSE);
                    916:     case 6:
                    917:       return(FALSE);
                    918: 
                    919:     default:
                    920:       return(FALSE);
                    921:   }
                    922: 
                    923:   // Still re-direct to TOS
                    924:   return(FALSE);
                    925: }
                    926: 
                    927: //-----------------------------------------------------------------------
                    928: /*
                    929:   GEMDOS Find first file
                    930:   Call 0x4E
                    931: */
                    932: BOOL GemDOS_SFirst(unsigned long Params)
                    933: {
                    934:   int FatDate, FatTime;
                    935:   char szActualFileName[MAX_PATH];
                    936:   char *pszFileName;
                    937:   unsigned short int Attr;
                    938:   int Drive;
                    939: 
                    940:   // Find filename to search for
                    941:   pszFileName = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD));
                    942:   Attr = STMemory_ReadWord(Params+SIZE_WORD+SIZE_LONG);
                    943: //  debug << "SFirst: " << pszFileName << endl;
                    944: //  M68000_OutputHistory();
                    945: 
                    946:   Drive = GemDOS_IsFileNameAHardDrive(pszFileName);
                    947:   if (ISHARDDRIVE(Drive)) {
                    948:     StatusBar_SetIcon(STATUS_ICON_HARDDRIVE,ICONSTATE_UPDATE);
                    949: 
                    950:     // And convert to hard drive filename
                    951:     GemDOS_CreateHardDriveFileName(Drive,pszFileName,szActualFileName);
                    952: 
                    953:     // Populate DTA, set index for our use
                    954:     STMemory_WriteWord_PCSpace(pDTA->index,DTAIndex);
                    955:     STMemory_WriteLong_PCSpace(pDTA->magic,DTA_MAGIC_NUMBER);
                    956:     strcpy(pDTA->dta_pat,"");
                    957:     pDTA->dta_sattrib = 0;
                    958:     pDTA->dta_attrib = 0;
                    959: 
                    960:     // Were we looking for the volume label? Read directly from drive
                    961:     if (Attr&GEMDOS_FILE_ATTRIB_VOLUME_LABEL) {
                    962:       // Default and find drive from filename
                    963:       strcpy(pDTA->dta_name,"");
                    964:       File_GetFileNameDrive(pszFileName);
                    965: //FIXME      if (GetVolumeInformation(pszFileName,pDTA->dta_name,TOS_NAMELEN,NULL,NULL,NULL,NULL,0))
                    966: //        strupr(pDTA->dta_name);
                    967:       Regs[REG_D0] = GEMDOS_EOK;          // Got volume
                    968:       return(TRUE);
                    969:     }
                    970: 
                    971:     // Scan for first file
                    972: /* FIXME */
                    973: /*
                    974:     InternalDTAs[DTAIndex].FileHandle = FindFirstFile(szActualFileName,&InternalDTAs[DTAIndex].FindFileData);
                    975:     if (InternalDTAs[DTAIndex].FileHandle==INVALID_HANDLE_VALUE) {
                    976:       // No files of that match, return error code
                    977:       Regs[REG_D0] = GEMDOS_EFILNF;        // File not found
                    978:       return(TRUE);
                    979:     }
                    980:     else {
                    981:       // Repeat find until have useable filename! The PC returns '.' and '..' - ignore '.'!
                    982:       while( !stricmp(InternalDTAs[DTAIndex].FindFileData.cFileName,".") ) {
                    983:         if (FindNextFile(InternalDTAs[DTAIndex].FileHandle,&InternalDTAs[DTAIndex].FindFileData)==0) {
                    984:           // If this is all there is, then error
                    985:           Regs[REG_D0] = GEMDOS_ENMFIL;    // No more files
                    986:           return(TRUE);
                    987:         }
                    988:       }
                    989: 
                    990:       // And make all upper case, as original ST
                    991:       strupr(InternalDTAs[DTAIndex].FindFileData.cFileName);
                    992:       strcpy(pDTA->dta_name,InternalDTAs[DTAIndex].FindFileData.cFileName);
                    993: 
                    994:       // Fill remaining details, as PC
                    995: //FIXME      STMemory_WriteLong_PCSpace(pDTA->dta_size,InternalDTAs[DTAIndex].FindFileData.nFileSizeLow);
                    996: //FIXME      Misc_TimeDataToDos(&InternalDTAs[DTAIndex].FindFileData.ftLastWriteTime,&FatDate,&FatTime);
                    997:       STMemory_WriteWord_PCSpace(pDTA->dta_time,FatTime);
                    998:       STMemory_WriteWord_PCSpace(pDTA->dta_date,FatDate);
                    999: //FIXME      pDTA->dta_attrib = GemDOS_ConvertAttribute(InternalDTAs[DTAIndex].FindFileData.dwFileAttributes);
                   1000: 
                   1001:       Regs[REG_D0] = GEMDOS_EOK;
                   1002: 
                   1003:       DTAIndex++;
                   1004:       DTAIndex&=(MAX_DTAS_FILES-1);
                   1005:     }
                   1006:     return(TRUE);
                   1007: */
                   1008:   }
                   1009:   return(FALSE);
                   1010: }
                   1011: 
                   1012: //-----------------------------------------------------------------------
                   1013: /*
                   1014:   GEMDOS Search Next
                   1015:   Call 0x4F
                   1016: */
                   1017: BOOL GemDOS_SNext(unsigned long Params)
                   1018: {
                   1019:   int FatDate, FatTime;
                   1020:   int DTAIndex;
                   1021: 
                   1022:   // Was DTA ours or TOS?
                   1023:   if (STMemory_ReadLong_PCSpace(pDTA->magic)==DTA_MAGIC_NUMBER) {
                   1024:     StatusBar_SetIcon(STATUS_ICON_HARDDRIVE,ICONSTATE_UPDATE);
                   1025: 
                   1026:     // Find index into our list of structures
                   1027:     DTAIndex = STMemory_ReadWord_PCSpace(pDTA->index)&(MAX_DTAS_FILES-1);
                   1028: /*FIXME
                   1029:     if (FindNextFile(InternalDTAs[DTAIndex].FileHandle,&InternalDTAs[DTAIndex].FindFileData)==0) {
                   1030:       Regs[REG_D0] = GEMDOS_ENMFIL;        // No more files
                   1031:       return(TRUE);
                   1032:     }
                   1033:     // Find next file on hard drive
                   1034:     else {
                   1035:       // And make all upper case, as original ST
                   1036:       strupr(InternalDTAs[DTAIndex].FindFileData.cFileName);
                   1037:       strcpy(pDTA->dta_name,InternalDTAs[DTAIndex].FindFileData.cFileName);
                   1038:       // Fill remaining details, as PC
                   1039:       STMemory_WriteLong_PCSpace(pDTA->dta_size,InternalDTAs[DTAIndex].FindFileData.nFileSizeLow);
                   1040:       Misc_TimeDataToDos(&InternalDTAs[DTAIndex].FindFileData.ftLastWriteTime,&FatDate,&FatTime);
                   1041:       STMemory_WriteWord_PCSpace(pDTA->dta_time,FatTime);
                   1042:       STMemory_WriteWord_PCSpace(pDTA->dta_date,FatDate);
                   1043:       pDTA->dta_attrib = GemDOS_ConvertAttribute(InternalDTAs[DTAIndex].FindFileData.dwFileAttributes);
                   1044:   
                   1045:       Regs[REG_D0] = GEMDOS_EOK;
                   1046:       return(TRUE);
                   1047:     }
                   1048: */
                   1049:   }
                   1050: 
                   1051:   return(FALSE);
                   1052: }
                   1053: 
                   1054: //-----------------------------------------------------------------------
                   1055: /*
                   1056:   GEMDOS Rename
                   1057:   Call 0x56
                   1058: */
                   1059: BOOL GemDOS_Rename(unsigned long Params)
                   1060: {
                   1061:   char *pszNewFileName,*pszOldFileName;
                   1062:   char szNewActualFileName[MAX_PATH],szOldActualFileName[MAX_PATH];
                   1063:   int NewDrive, OldDrive;
                   1064: 
                   1065:   // Read details from stack
                   1066:   pszOldFileName = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD+SIZE_WORD));
                   1067:   pszNewFileName = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD+SIZE_WORD+SIZE_LONG));
                   1068: 
                   1069:   NewDrive = GemDOS_IsFileNameAHardDrive(pszNewFileName);
                   1070:   OldDrive = GemDOS_IsFileNameAHardDrive(pszOldFileName);
                   1071:   if (ISHARDDRIVE(NewDrive) && ISHARDDRIVE(OldDrive)) {
                   1072:     // And convert to hard drive filenames
                   1073:     GemDOS_CreateHardDriveFileName(NewDrive,pszNewFileName,szNewActualFileName);
                   1074:     GemDOS_CreateHardDriveFileName(OldDrive,pszOldFileName,szOldActualFileName);
                   1075: 
                   1076:     // Rename files
                   1077:     if ( rename(szOldActualFileName,szNewActualFileName)==0 )
                   1078:       Regs[REG_D0] = GEMDOS_EOK;
                   1079:     else
                   1080:       Regs[REG_D0] = GEMDOS_EACCDN;        // Access denied
                   1081:     return(TRUE);
                   1082:   }
                   1083: 
                   1084:   return(FALSE);
                   1085: }
                   1086: 
                   1087: //-----------------------------------------------------------------------
                   1088: /*
                   1089:   GEMDOS GSDToF
                   1090:   Call 0x57
                   1091: */
                   1092: BOOL GemDOS_GSDToF(unsigned long Params)
                   1093: {
                   1094: /*FIXME*/
                   1095: /*
                   1096:   BY_HANDLE_FILE_INFORMATION FileInfo;
                   1097:   WORD FatDate,FatTime;
                   1098:   DATETIME DateTime;
                   1099:   char *pBuffer;
                   1100:   int Handle,Flag;
                   1101: 
                   1102:   // Read details from stack
                   1103:   pBuffer = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD));
                   1104:   Handle = STMemory_ReadWord(Params+SIZE_WORD+SIZE_LONG)-BASE_FILEHANDLE;
                   1105:   Flag = STMemory_ReadWord(Params+SIZE_WORD+SIZE_WORD+SIZE_LONG);
                   1106: 
                   1107:   // Check handle was valid
                   1108:   if (GemDOS_IsInvalidFileHandle(Handle)) {
                   1109:     // No assume was TOS
                   1110:     return(FALSE);
                   1111:   }
                   1112:   else {
                   1113:     Regs[REG_D0] = GEMDOS_ERROR;  // Invalid parameter
                   1114: 
                   1115:     if (Flag==0) {    // Read time
                   1116:       if (GetFileInformationByHandle(FileHandles[Handle].FileHandle,&FileInfo)) {
                   1117:         if (FileTimeToDosDateTime(&FileInfo.ftCreationTime,&FatDate,&FatTime)) {
                   1118:           DateTime.hour = FatTime>>11;
                   1119:           DateTime.minute = FatTime>>5;
                   1120:           DateTime.second = FatTime;
                   1121:           DateTime.year = FatDate>>9;
                   1122:           DateTime.month = FatDate>>5;
                   1123:           DateTime.day = FatDate;
                   1124: 
                   1125:           Regs[REG_D0] = GEMDOS_EOK;
                   1126:         }
                   1127:       }
                   1128:     }
                   1129:     else if (Flag==1) {
                   1130:       Regs[REG_D0] = GEMDOS_EOK;
                   1131:     }
                   1132:     
                   1133:      return(TRUE);
                   1134:   }
                   1135: */
                   1136:   return(FALSE);
                   1137: }
                   1138: 
                   1139: //-----------------------------------------------------------------------
                   1140: /*
                   1141:   This is called when we get a GemDOS exception. We then re-direct vector to our
                   1142:   own routine. This forces execution through TOS which sets up the stack etc... and
                   1143:   then calls our own routine in the cart' space which has the illegal instruction
                   1144:   'GEMDOS_OPCODE'.
                   1145: */
                   1146: BOOL GemDOS(void)
                   1147: {
                   1148:   unsigned long OldGemDOSVector;
                   1149: 
                   1150:   // Init Gemdos if not already
                   1151:   if (!bInitGemDOS) {
                   1152:     OldGemDOSVector = STMemory_ReadLong(0x84);
                   1153:     STMemory_WriteLong(CART_OLDGEMDOS,OldGemDOSVector);  // Store original gemdos handler
                   1154:     STMemory_WriteLong(0x84,CART_GEMDOS);                // And redirect to new one (see cart.s)
                   1155: 
                   1156:     bInitGemDOS = TRUE;
                   1157:   }
                   1158: 
                   1159:   // Now execute as normal, we may intercept it again later (see cart.s)
                   1160:   return(FALSE);
                   1161: }
                   1162: 
                   1163: 
                   1164: /*-----------------------------------------------------------------------*/
                   1165: /*
                   1166:   Run GEMDos call, and re-direct if need to. Used to handle hard-disc emulation etc...
                   1167:   This sets the condition codes(in SR), which are used in the 'cart.s' program to decide if we
                   1168:   need to run old GEM vector, or PExec or nothing.
                   1169: 
                   1170:   This method keeps the stack and other states consistant with the original ST which is very important
                   1171:   for the PExec call and maximum compatibility through-out
                   1172: */
                   1173: void GemDOS_OpCode(void)
                   1174: {
                   1175:   unsigned short int GemDOSCall,CallingSReg;
                   1176:   unsigned long Params;
                   1177: 
                   1178:   /* Read SReg from stack to see if parameters are on User or Super stack (We enter here ALWAYS in super mode) */
                   1179:   CallingSReg = STMemory_ReadWord(Regs[REG_A7]);
                   1180:   if ((CallingSReg&SR_SUPERMODE)==0)      /* Calling from user mode */
                   1181:     Params = Regs[REG_A8];
                   1182:   else              /* Calling from super mode */
                   1183:     Params = Regs[REG_A7]+SIZE_WORD+SIZE_LONG;
                   1184: 
                   1185:   /* Default to run TOS GemDos (SR_NEG run Gemdos, SR_ZERO already done, SR_OVERFLOW run own 'Pexec' */
                   1186:   SR &= SR_CLEAR_OVERFLOW;
                   1187:   SR &= SR_CLEAR_ZERO;
                   1188:   SR |= SR_NEG;
                   1189: 
                   1190:   /* Find pointer to call parameters */
                   1191:   GemDOSCall = STMemory_ReadWord(Params);
                   1192: #ifdef DEBUG_TO_FILE
                   1193:   Debug_File("GemDOS 0x%X (%s)\n",GemDOSCall,pszGemDOSNames[GemDOSCall]);
                   1194: #endif
                   1195: 
                   1196:   /* Intercept call */
                   1197:   switch(GemDOSCall) {
                   1198:     case 0x3:
                   1199:       if (GemDOS_Cauxin(Params))
                   1200:         SR |= SR_ZERO;
                   1201:       break;
                   1202:     case 0x4:
                   1203:       if (GemDOS_Cauxout(Params))
                   1204:         SR |= SR_ZERO;
                   1205:       break;
                   1206:     case 0x5:
                   1207:       if (GemDOS_Cprnout(Params))
                   1208:         SR |= SR_ZERO;
                   1209:       break;
                   1210:     case 0xe:
                   1211:       if (GemDOS_SetDrv(Params))
                   1212:         SR |= SR_ZERO;
                   1213:       break;      
                   1214:     case 0x11:
                   1215:       if (GemDOS_Cprnos(Params))
                   1216:         SR |= SR_ZERO;
                   1217:       break;
                   1218:     case 0x12:
                   1219:       if (GemDOS_Cauxis(Params))
                   1220:         SR |= SR_ZERO;
                   1221:       break;
                   1222:     case 0x13:
                   1223:       if (GemDOS_Cauxos(Params))
                   1224:         SR |= SR_ZERO;
                   1225:       break;
                   1226:     case 0x1a:
                   1227:       if (GemDOS_SetDTA(Params))
                   1228:         SR |= SR_ZERO;
                   1229:       break;
                   1230:     case 0x39:
                   1231:       if (GemDOS_MkDir(Params))
                   1232:         SR |= SR_ZERO;
                   1233:       break;
                   1234:     case 0x3a:
                   1235:       if (GemDOS_RmDir(Params))
                   1236:         SR |= SR_ZERO;
                   1237:       break;
                   1238:     case 0x3b:
                   1239:       if (GemDOS_ChDir(Params))
                   1240:         SR |= SR_ZERO;
                   1241:       break;
                   1242:     case 0x3c:
                   1243:       if (GemDOS_Create(Params))
                   1244:         SR |= SR_ZERO;
                   1245:       break;
                   1246:     case 0x3d:
                   1247:       if (GemDOS_Open(Params))
                   1248:         SR |= SR_ZERO;
                   1249:       break;
                   1250:     case 0x3e:
                   1251:       if (GemDOS_Close(Params))
                   1252:         SR |= SR_ZERO;
                   1253:       break;
                   1254:     case 0x3f:
                   1255:       if (GemDOS_Read(Params))
                   1256:         SR |= SR_ZERO;
                   1257:       break;
                   1258:     case 0x40:
                   1259:       if (GemDOS_Write(Params))
                   1260:         SR |= SR_ZERO;
                   1261:       break;
                   1262:     case 0x41:
                   1263:       if (GemDOS_UnLink(Params))
                   1264:         SR |= SR_ZERO;
                   1265:       break;
                   1266:     case 0x42:
                   1267:       if (GemDOS_LSeek(Params))
                   1268:         SR |= SR_ZERO;
                   1269:       break;
                   1270:     case 0x4b:
                   1271:       if (GemDOS_Pexec(Params))
                   1272:         SR |= SR_ZERO;
                   1273:       break;
                   1274:     case 0x4e:
                   1275:       if (GemDOS_SFirst(Params))
                   1276:         SR |= SR_ZERO;
                   1277:       break;
                   1278:     case 0x4f:
                   1279:       if (GemDOS_SNext(Params))
                   1280:         SR |= SR_ZERO;
                   1281:       break;
                   1282:     case 0x56:
                   1283:       if (GemDOS_Rename(Params))
                   1284:         SR |= SR_ZERO;
                   1285:       break;
                   1286:     case 0x57:
                   1287:       if (GemDOS_GSDToF(Params))
                   1288:         SR |= SR_ZERO;
                   1289:       break;
                   1290:   }
                   1291: 
                   1292:   /* Write back to emulation condition codes, used for code re-direction */
                   1293:   EmuCCode = SR<<4;
                   1294: }
                   1295: 
                   1296: 
                   1297: //-----------------------------------------------------------------------
                   1298: /*
                   1299:   Re-direct execution to old GEM calls, used in 'cart.s'
                   1300: */
                   1301: void GemDOS_RunOldOpCode(void)
                   1302: {
                   1303:   /* Set 'PC' to that of old GemDOS routines (see 'old_gemdos' in cart.s) */
                   1304:   m68k_setpc( STMemory_ReadLong(0xfa1004) );    /* Address of 'old_gemdos' in cart.s */
                   1305: /*  __asm {
                   1306:     mov    ecx,[STRAM_OFFSET+0xfa1004]    // Address of 'old_gemdos' in cart.s
                   1307:     bswap  ecx
                   1308:     and    ecx,0x00ffffff
                   1309:     mov    esi,ecx
                   1310:     add    esi,STRAM_OFFSET      // New PC
                   1311:     RET
                   1312:   }
                   1313: */
                   1314: }

unix.superglobalmegacorp.com

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