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

1.1       root        1: /*
                      2:   Hatari
                      3: 
1.1.1.2 ! root        4:   GEMDos intercept routines. These are used mainly for Hard Drive redirection of high level file routines.
1.1       root        5: 
1.1.1.2 ! root        6:   Bugs/things to fix:
        !             7:   * RS232/Printing
        !             8:   * Figure out how to handle long file names and case conflicts, 
        !             9:     (eg. FOO.BAR and foo.bar is the same file in TOS but not UNIX)
        !            10:   * rmdir routine, can't remove dir with files in it. (another tos/unix difference)
        !            11:   * Fix bugs, there are probably a few lurking around in here..
        !            12: 
        !            13: */
1.1       root       14: 
                     15: #include "main.h"
                     16: #include "cart.h"
1.1.1.2 ! root       17: #include "tos.h"
1.1       root       18: #include "debug.h"
                     19: #include "decode.h"
                     20: #include "dialog.h"
                     21: #include "file.h"
                     22: #include "floppy.h"
                     23: #include "gemdos.h"
                     24: #include "m68000.h"
                     25: #include "memAlloc.h"
                     26: #include "memorySnapShot.h"
                     27: #include "misc.h"
                     28: #include "printer.h"
                     29: #include "rs232.h"
                     30: #include "statusBar.h"
                     31: #include "stMemory.h"
                     32: #include "view.h"
                     33: 
1.1.1.2 ! root       34: #include "uae-cpu/hatari-glue.h"
        !            35: 
        !            36: #include <sys/stat.h>
        !            37: #include <time.h>
        !            38: 
        !            39: #ifdef dirent                     /* kludge: dirent previously defined in sysdeps.h... */
        !            40: #undef dirent                     
        !            41: #endif
        !            42: #include <dirent.h>               /* ..this conflicts with dirent.h definition */
        !            43: 
1.1       root       44: #define ENABLE_SAVING             /* Turn on saving stuff */
                     45: 
                     46: #define INVALID_HANDLE_VALUE -1
                     47: 
                     48: #ifndef MAX_PATH
                     49: #define MAX_PATH 256
                     50: #endif
                     51: 
1.1.1.2 ! root       52: /* structure with all the drive-specific data for our emulated drives */
        !            53: EMULATEDDRIVE **emudrives = NULL;
        !            54: 
1.1       root       55: typedef struct 
                     56: {
                     57:  BOOL bUsed;
1.1.1.2 ! root       58:  FILE *FileHandle;
        !            59:   char szActualName[MAX_PATH];   /* used by F_DATIME (0x57) */
1.1       root       60: } FILE_HANDLE;
                     61: 
1.1.1.2 ! root       62: typedef struct 
        !            63: {
        !            64:   BOOL bUsed;
        !            65:   int  nentries;                   /* number of entries in fs directory */
        !            66:   int  centry;                     /* current entry # */
        !            67:   struct dirent **found;           /* legal files */
        !            68:   char path[MAX_PATH];             /* sfirst path */
        !            69: } INTERNAL_DTA;
        !            70: 
1.1       root       71: FILE_HANDLE  FileHandles[MAX_FILE_HANDLES];
1.1.1.2 ! root       72: INTERNAL_DTA InternalDTAs[MAX_DTAS_FILES];
1.1       root       73: int DTAIndex;                                 /* Circular index into above */
                     74: BOOL bInitGemDOS;                             /* Have we re-directed GemDOS vector to our own routines yet? */
                     75: DTA *pDTA;                                    /* Our GEMDOS hard drive Disc Transfer Address structure */
                     76: unsigned short int CurrentDrive;              /* Current drive (0=A,1=B,2=C etc...) */
                     77: 
                     78: /* List of GEMDos functions... */
                     79: char *pszGemDOSNames[] = {
1.1.1.2 ! root       80:   "Term",                 /*0x00*/
        !            81:   "Conin",                /*0x01*/
        !            82:   "ConOut",               /*0x02*/
        !            83:   "Auxiliary Input",      /*0x03*/
        !            84:   "Auxiliary Output",     /*0x04*/
        !            85:   "Printer Output",       /*0x05*/
        !            86:   "RawConIO",             /*0x06*/
        !            87:   "Direct Conin no echo", /*0x07*/
        !            88:   "Conin no echo",        /*0x08*/
        !            89:   "Print line",           /*0x09*/
        !            90:   "ReadLine",             /*0x0a*/
        !            91:   "ConStat",              /*0x0b*/
        !            92:   "",                     /*0x0c*/
        !            93:   "",                     /*0x0d*/
        !            94:   "SetDrv",               /*0x0e*/
        !            95:   "",                     /*0x0f*/
        !            96:   "Conout Stat",          /*0x10*/
        !            97:   "PrtOut Stat",          /*0x11*/
        !            98:   "Auxin Stat",           /*0x12*/
        !            99:   "AuxOut Stat",          /*0x13*/
        !           100:   "",                     /*0x14*/
        !           101:   "",                     /*0x15*/
        !           102:   "",                     /*0x16*/
        !           103:   "",                     /*0x17*/
        !           104:   "",                     /*0x18*/
        !           105:   "Current Disk",         /*0x19*/
        !           106:   "Set DTA",              /*0x1a*/
        !           107:   "",        /*0x1b*/
        !           108:   "",        /*0x1c*/
        !           109:   "",        /*0x1d*/
        !           110:   "",        /*0x1e*/
        !           111:   "",        /*0x1f*/
        !           112:   "Super",   /*0x20*/
        !           113:   "",        /*0x21*/
        !           114:   "",        /*0x22*/
        !           115:   "",        /*0x23*/
        !           116:   "",        /*0x24*/
        !           117:   "",        /*0x25*/
        !           118:   "",        /*0x26*/
        !           119:   "",        /*0x27*/
        !           120:   "",        /*0x28*/
        !           121:   "",        /*0x29*/
        !           122:   "Get Date",      /*0x2a*/
        !           123:   "Set Date",      /*0x2b*/
        !           124:   "Get Time",      /*0x2c*/
        !           125:   "Set Time",      /*0x2d*/
        !           126:   "",              /*0x2e*/
        !           127:   "Get DTA",       /*0x2f*/
        !           128:   "Get Version Number",   /*0x30*/
        !           129:   "Keep Process",         /*0x31*/
        !           130:   "",        /*0x32*/
        !           131:   "",        /*0x33*/
        !           132:   "",        /*0x34*/
        !           133:   "",        /*0x35*/
        !           134:   "Get Disk Free Space",  /*0x36*/
        !           135:   "",           /*0x37*/
        !           136:   "",           /*0x38*/
        !           137:   "MkDir",      /*0x39*/
        !           138:   "RmDir",      /*0x3a*/
        !           139:   "ChDir",      /*0x3b*/
        !           140:   "Create",     /*0x3c*/
        !           141:   "Open",       /*0x3d*/
        !           142:   "Close",      /*0x3e*/
        !           143:   "Read",       /*0x3f*/
        !           144:   "Write",      /*0x40*/
        !           145:   "UnLink",     /*0x41*/
        !           146:   "LSeek",      /*0x42*/
        !           147:   "ChMod",      /*0x43*/
        !           148:   "",           /*0x44*/
        !           149:   "Dup",        /*0x45*/
        !           150:   "Force",      /*0x46*/
        !           151:   "GetDir",     /*0x47*/
        !           152:   "Malloc",     /*0x48*/
        !           153:   "MFree",      /*0x49*/
        !           154:   "SetBlock",   /*0x4a*/
        !           155:   "Exec",       /*0x4b*/
        !           156:   "Term",       /*0x4c*/
        !           157:   "",           /*0x4d*/
        !           158:   "SFirst",     /*0x4e*/
        !           159:   "SNext",      /*0x4f*/
        !           160:   "",           /*0x50*/
        !           161:   "",           /*0x51*/
        !           162:   "",           /*0x52*/
        !           163:   "",           /*0x53*/
        !           164:   "",           /*0x54*/
        !           165:   "",           /*0x55*/
        !           166:   "Rename",     /*0x56*/
        !           167:   "GSDTof"      /*0x57*/
1.1       root      168: };
                    169: 
1.1.1.2 ! root      170: unsigned char GemDOS_ConvertAttribute(mode_t mode);
        !           171: 
        !           172: /*-------------------------------------------------------*/
        !           173: /*
        !           174:   Routines to convert time and date to MSDOS format. 
        !           175:   Originally from the STonX emulator. (cheers!)
        !           176: */
        !           177: unsigned short time2dos (time_t t)
        !           178: {
        !           179:        struct tm *x;
        !           180:        x = localtime (&t);
        !           181:        return (x->tm_sec>>1)|(x->tm_min<<5)|(x->tm_hour<<11);
        !           182: }
1.1       root      183: 
1.1.1.2 ! root      184: unsigned short date2dos (time_t t)
        !           185: {
        !           186:        struct tm *x;
        !           187:        x = localtime (&t);
        !           188:        return x->tm_mday | ((x->tm_mon+1)<<5) | ( ((x->tm_year-80>0)?x->tm_year-80:0) << 9);
        !           189: }
1.1       root      190: 
1.1.1.2 ! root      191: /* 
        !           192:    Convert a string to uppercase 
        !           193: */
1.1       root      194: void strupr(char *string)
                    195: {
1.1.1.2 ! root      196:  while(*string){ *string = toupper(*string); string++; }
        !           197: }
        !           198: 
        !           199: /*-----------------------------------------------------------------------*/
        !           200: /*
        !           201:   Populate a DATETIME structure with file info 
        !           202: */
        !           203: BOOL GetFileInformation(char *name, DATETIME *DateTime)
        !           204: {
        !           205:   struct stat filestat;
        !           206:   int n;
        !           207:   struct tm *x;
        !           208: 
        !           209:   n = stat(name, &filestat);
        !           210:   if( n != 0 ) return(FALSE);
        !           211:   x = localtime( &filestat.st_mtime );
        !           212: 
        !           213:   DateTime->word1 = 0;
        !           214:   DateTime->word2 = 0;
        !           215: 
        !           216:   DateTime->word1 |= (x->tm_mday & 0x1F);         /* 5 bits */
        !           217:   DateTime->word1 |= (x->tm_mon & 0x0F)<<5;       /* 4 bits */
        !           218:   DateTime->word1 |= (((x->tm_year-80>0)?x->tm_year-80:0) & 0x7F)<<9;      /* 7 bits*/
        !           219: 
        !           220:   DateTime->word2 |= (x->tm_sec & 0x1F);          /* 5 bits */
        !           221:   DateTime->word2 |= (x->tm_min & 0x3F)<<5;       /* 6 bits */
        !           222:   DateTime->word2 |= (x->tm_hour & 0x1F)<<11;     /* 5 bits */
        !           223: 
        !           224:   return(TRUE);
        !           225: }
        !           226: /*-----------------------------------------------------------------------*/
        !           227: /*
        !           228:   Populate the DTA buffer with file info 
        !           229: */
        !           230: int PopulateDTA(char *path, struct dirent *file)
        !           231: {
        !           232:   char tempstr[MAX_PATH];
        !           233:   struct stat filestat;
        !           234:   int n;
        !           235: 
        !           236:   sprintf(tempstr, "%s/%s", path, file->d_name);
        !           237:   n = stat(tempstr, &filestat);
        !           238:   if(n != 0) return(FALSE); /* return on error */
        !           239: 
        !           240:   if(!pDTA) return(FALSE); /* no DTA pointer set */
        !           241:   strupr(file->d_name);    /* convert to atari-style uppercase */
        !           242:   strncpy(pDTA->dta_name,file->d_name,TOS_NAMELEN); /* FIXME: better handling of long file names */
        !           243:   STMemory_WriteLong_PCSpace(pDTA->dta_size, (long)filestat.st_size);
        !           244:   STMemory_WriteWord_PCSpace(pDTA->dta_time, time2dos(filestat.st_mtime));
        !           245:   STMemory_WriteWord_PCSpace(pDTA->dta_date, date2dos(filestat.st_mtime));
        !           246:   pDTA->dta_attrib = GemDOS_ConvertAttribute(filestat.st_mode);
        !           247: 
        !           248: }
        !           249: 
        !           250: /*-----------------------------------------------------------------------*/
        !           251: /*
        !           252:   Clear a used DTA structure.
        !           253: */
        !           254: void ClearInternalDTA(){
        !           255:   int i;
        !           256: 
        !           257:   /* clear the old DTA structure */
        !           258:   if(InternalDTAs[DTAIndex].found != NULL){
        !           259:     for(i=0; i <InternalDTAs[DTAIndex].nentries; i++)
        !           260:       free(InternalDTAs[DTAIndex].found[i]);
        !           261:     free(InternalDTAs[DTAIndex].found); 
        !           262:   }
        !           263:   InternalDTAs[DTAIndex].bUsed = FALSE;
        !           264: }
        !           265: 
        !           266: /*-----------------------------------------------------------------------*/
        !           267: /*
        !           268:   Match a file to a dir mask.
        !           269: */
        !           270: static int match (char *pat, char *name)
        !           271: {
        !           272:   /* make uppercase copies */
        !           273:   char p0[MAX_PATH], n0[MAX_PATH];
        !           274:   strcpy(p0, pat);
        !           275:   strcpy(n0, name);
        !           276:   strupr(p0); strupr(n0);
        !           277:   
        !           278:   if(name[0] == '.') return(FALSE);                   /* no .* files */
        !           279:   if (strcmp(pat,"*.*")==0) return(TRUE);
        !           280:   else if (strcasecmp(pat,name)==0) return(TRUE);
        !           281:   else
        !           282:     {
        !           283:       char *p=p0,*n=n0;
        !           284:       for(;*n;)
        !           285:        {
        !           286:          if (*p=='*') {while (*n && *n != '.') n++;p++;}
        !           287:          else if (*p=='?' && *n) {n++;p++;}
        !           288:          else if (*p++ != *n++) return(FALSE);
        !           289:        }
        !           290:       if (*p==0)
        !           291:        {
        !           292:          return(TRUE);
        !           293:        }
        !           294:     }
        !           295:   return(FALSE);
        !           296: }
        !           297: 
        !           298: /*-----------------------------------------------------------------------*/
        !           299: /*
        !           300:   Parse directory from sfirst mask - e.g.: input:  "hdemudir/auto/*.*" outputs: "hdemudir/auto" 
        !           301: */
        !           302: void fsfirst_dirname(char *string, char *new){
        !           303:   int i=0;
        !           304:   
        !           305:   sprintf(new, string); 
        !           306:   /* convert to front slashes. */
        !           307:   i=0;
        !           308:   while(new[i] != '\0'){
        !           309:     if(new[i] == '\\') new[i] = '/';
        !           310:     i++;
        !           311:   }
        !           312:   while(string[i] != '\0'){new[i] = string[i]; i++;} /* find end of string */
        !           313:   while(new[i] != '/') i--; /* find last slash */
        !           314:   new[i] = '\0';
1.1       root      315: }
                    316: 
1.1.1.2 ! root      317: /*-----------------------------------------------------------------------*/
        !           318: /*
        !           319:   Parse directory mask, e.g. "*.*" 
        !           320: */
        !           321: void fsfirst_dirmask(char *string, char *new){
        !           322:   int i=0, j=0;
        !           323:   while(string[i] != '\0')i++;   /* go to end of string */
        !           324:   while(string[i] != '/') i--;   /* find last slash */
        !           325:   i++;
        !           326:   while(string[i] != '\0')new[j++] = string[i++]; /* go to end of string */
        !           327:   new[j++] = '\0';
        !           328: }
1.1       root      329: 
1.1.1.2 ! root      330: /*-----------------------------------------------------------------------*/
1.1       root      331: /*
                    332:   Initialize GemDOS/PC file system
                    333: */
                    334: void GemDOS_Init(void)
                    335: {
1.1.1.2 ! root      336:   int i;
        !           337:   bInitGemDOS = FALSE;
        !           338: 
        !           339:   /* Clear handles structure */
1.1       root      340:   Memory_Clear(FileHandles,sizeof(FILE_HANDLE)*MAX_FILE_HANDLES);
1.1.1.2 ! root      341:   /* Clear DTAs */
        !           342:   for(i=0; i<MAX_DTAS_FILES; i++) {
        !           343:     InternalDTAs[i].bUsed = FALSE;
        !           344:     InternalDTAs[i].nentries = 0;
        !           345:     InternalDTAs[i].found = NULL;
        !           346:   }
        !           347:   DTAIndex = 0;
1.1       root      348: }
                    349: 
1.1.1.2 ! root      350: /*-----------------------------------------------------------------------*/
1.1       root      351: /*
                    352:   Reset GemDOS file system
                    353: */
                    354: void GemDOS_Reset(void)
                    355: {
                    356:   int i;
                    357: 
1.1.1.2 ! root      358:   if(emudrives != NULL){
        !           359:     strcpy(emudrives[0]->fs_currpath,"");
        !           360:   }
        !           361:   
        !           362:   /* Init file handles table */
1.1       root      363:   for(i=0; i<MAX_FILE_HANDLES; i++) {
1.1.1.2 ! root      364:     /* Was file open? If so close it */
1.1       root      365:     if (FileHandles[i].bUsed)
1.1.1.2 ! root      366:       fclose(FileHandles[i].FileHandle);
1.1       root      367: 
1.1.1.2 ! root      368:     FileHandles[i].FileHandle = NULL;
1.1       root      369:     FileHandles[i].bUsed = FALSE;
                    370:   }
                    371: 
1.1.1.2 ! root      372:   for(i=0; i<MAX_DTAS_FILES; i++) {
        !           373:     InternalDTAs[i].bUsed = FALSE;
        !           374:     InternalDTAs[i].nentries = 0;
        !           375:     InternalDTAs[i].found = NULL;
        !           376:   }
        !           377: 
        !           378:   /* Reset */
1.1       root      379:   bInitGemDOS = FALSE;
                    380:   CurrentDrive = nBootDrive;
                    381:   pDTA = NULL;
                    382:   DTAIndex = 0;
                    383: }
                    384: 
1.1.1.2 ! root      385: /*-----------------------------------------------------------------------*/
1.1       root      386: /*
                    387:   Save/Restore snapshot of local variables('MemorySnapShot_Store' handles type)
                    388: */
                    389: void GemDOS_MemorySnapShot_Capture(BOOL bSave)
                    390: {
                    391:   unsigned int Addr;
                    392:   int i;
                    393: 
1.1.1.2 ! root      394:   /* Save/Restore details */
1.1       root      395:   MemorySnapShot_Store(&DTAIndex,sizeof(DTAIndex));
                    396:   MemorySnapShot_Store(&bInitGemDOS,sizeof(bInitGemDOS));
                    397:   if (bSave) {
                    398:     Addr = (unsigned int)pDTA-(unsigned int)STRam;
                    399:     MemorySnapShot_Store(&Addr,sizeof(Addr));
                    400:   }
                    401:   else {
                    402:     MemorySnapShot_Store(&Addr,sizeof(Addr));
                    403:     pDTA = (DTA *)((unsigned int)STRam+(unsigned int)Addr);
                    404:   }
                    405:   MemorySnapShot_Store(&CurrentDrive,sizeof(CurrentDrive));
1.1.1.2 ! root      406:   /* Don't save file handles as files may have changed which makes
        !           407:      it impossible to get a valid handle back */
1.1       root      408:   if (!bSave) {
1.1.1.2 ! root      409:     /* Clear file handles  */
1.1       root      410:     for(i=0; i<MAX_FILE_HANDLES; i++) {
1.1.1.2 ! root      411:       FileHandles[i].FileHandle = NULL;
1.1       root      412:       FileHandles[i].bUsed = FALSE;
                    413:     }
                    414:   }
                    415: }
                    416: 
1.1.1.2 ! root      417: /*-----------------------------------------------------------------------*/
1.1       root      418: /*
                    419:   Return free PC file handle table index, or -1 if error
                    420: */
                    421: int GemDOS_FindFreeFileHandle(void)
                    422: {
                    423:   int i;
                    424: 
                    425:   /* Scan our file list for free slot */
                    426:   for(i=0; i<MAX_FILE_HANDLES; i++) {
                    427:     if (!FileHandles[i].bUsed)
                    428:       return(i);
                    429:   }
                    430: 
                    431:   /* Cannot open any more files, return error */
                    432:   return(-1);
                    433: }
                    434: 
1.1.1.2 ! root      435: /*-----------------------------------------------------------------------*/
1.1       root      436: /*
                    437:   Check ST handle is within our table range, return TRUE if not
                    438: */
                    439: BOOL GemDOS_IsInvalidFileHandle(int Handle)
                    440: {
                    441:   BOOL bInvalidHandle=FALSE;
                    442: 
                    443:   /* Check handle was valid with our handle table */
                    444:   if ( (Handle<0) || (Handle>=MAX_FILE_HANDLES) )
                    445:     bInvalidHandle = TRUE;
                    446:   else if (!FileHandles[Handle].bUsed)
                    447:     bInvalidHandle = TRUE;
                    448: 
                    449:   return(bInvalidHandle);
                    450: }
                    451: 
1.1.1.2 ! root      452: /*-----------------------------------------------------------------------*/
1.1       root      453: /*
                    454:   Find drive letter from a filename, eg C,D... and return as drive ID(C:2, D:3...)
                    455: */
                    456: int GemDOS_FindDriveNumber(char *pszFileName)
                    457: {
                    458:   /* Does have 'A:' or 'C:' etc.. at start of string? */
                    459:   if ( (pszFileName[0]!='\0') && (pszFileName[1]==':') ) {
                    460:     if ( (pszFileName[0]>='a') && (pszFileName[0]<='z') )
                    461:       return(pszFileName[0]-'a');
                    462:     else if ( (pszFileName[0]>='A') && (pszFileName[0]<='Z') )
                    463:       return(pszFileName[0]-'A');
                    464:   }
                    465: 
                    466:   return(CurrentDrive);
                    467: }
                    468: 
1.1.1.2 ! root      469: /*-----------------------------------------------------------------------*/
1.1       root      470: /*
                    471:   Return drive ID(C:2, D:3 etc...) or -1 if not one of our emulation hard-drives
                    472: */
                    473: int GemDOS_IsFileNameAHardDrive(char *pszFileName)
                    474: {
                    475:   int DriveLetter;
                    476: 
1.1.1.2 ! root      477:   /* temporary hack, as Configureparams isn't set up yet. */
        !           478:   DriveLetter = GemDOS_FindDriveNumber(pszFileName);
        !           479:   if( DriveLetter >= 2 )
        !           480:     return(DriveLetter);
        !           481:   else
        !           482:     return(-1);
        !           483:   
1.1       root      484:   /* Do we even have a hard-drive? */
                    485:   if (ConfigureParams.HardDisc.nDriveList!=DRIVELIST_NONE) {
1.1.1.2 ! root      486:     /* Find drive letter(as number) */
1.1       root      487:     DriveLetter = GemDOS_FindDriveNumber(pszFileName);
1.1.1.2 ! root      488:     /* Does match one of our drives? */
1.1       root      489:     if ( (DriveLetter>=2) && (DriveLetter<=DRIVELIST_TO_DRIVE_INDEX(ConfigureParams.HardDisc.nDriveList)) )
                    490:       return(DriveLetter);
                    491:   }
                    492: 
1.1.1.2 ! root      493:   /* No, let TOS handle it */
1.1       root      494:   return(-1);
                    495: }
                    496: 
1.1.1.2 ! root      497: /*-----------------------------------------------------------------------*/
1.1       root      498: /*
                    499:   Use hard-drive directory, current ST directory and filename to create full path
                    500: */
                    501: void GemDOS_CreateHardDriveFileName(int Drive,char *pszFileName,char *pszDestName)
                    502: {
                    503:   int DirIndex = Misc_LimitInt(Drive-2, 0,ConfigureParams.HardDisc.nDriveList-1);
1.1.1.2 ! root      504:   int i;
        !           505: 
        !           506:   /* another temporary hack */
        !           507:   if(pszFileName[0] == '\0')return; /* check for valid string */
        !           508:   /* case full filename "C:\foo\bar" */
        !           509:   if(pszFileName[1] == ':') {
        !           510:     sprintf(pszDestName, "%s%s", emudrives[0]->hd_emulation_dir, File_RemoveFileNameDrive(pszFileName)); 
        !           511:   } 
        !           512:   /* Referenced from root:  "\foo\bar" */
        !           513:   else if(pszFileName[0] == '\\'){  
        !           514:     sprintf(pszDestName, "%s%s", emudrives[0]->hd_emulation_dir, pszFileName); 
        !           515:   }
        !           516:   /* referenced from current directory */
        !           517:   else {
        !           518:     sprintf(pszDestName, "%s%s%s", emudrives[0]->hd_emulation_dir, emudrives[0]->fs_currpath, pszFileName);
        !           519:   }
        !           520: 
        !           521:   /* convert to front slashes. */
        !           522:   i=0;
        !           523:   while(pszDestName[i] != '\0'){
        !           524:     if(pszDestName[i] == '\\') pszDestName[i] = '/';
        !           525:     i++;
        !           526:   }
        !           527:   return;
        !           528: 
1.1       root      529:   /* Combine names */
                    530:   if (File_IsRootFileName(pszFileName))
                    531:     sprintf(pszDestName,"%s%s",ConfigureParams.HardDisc.szHardDiscDirectories[DirIndex],File_RemoveFileNameDrive(pszFileName));
                    532:   else {
                    533:     if (File_DoesFileNameEndWithSlash(szCurrentDir))
                    534:       sprintf(pszDestName,"%s%s%s",ConfigureParams.HardDisc.szHardDiscDirectories[DirIndex],File_RemoveFileNameDrive(szCurrentDir),File_RemoveFileNameDrive(pszFileName));
                    535:     else
                    536:       sprintf(pszDestName,"%s%s/%s",ConfigureParams.HardDisc.szHardDiscDirectories[DirIndex],File_RemoveFileNameDrive(szCurrentDir),File_RemoveFileNameDrive(pszFileName));
                    537:   }
1.1.1.2 ! root      538:   /* Remove any trailing slashes at end of filenames */
1.1       root      539:   File_RemoveFileNameTrailingSlashes(pszDestName);
                    540: 
                    541: }
                    542: 
1.1.1.2 ! root      543: /*-----------------------------------------------------------------------*/
1.1       root      544: /*
                    545:   Covert from FindFirstFile/FindNextFile attribute to GemDOS format
                    546: */
1.1.1.2 ! root      547: unsigned char GemDOS_ConvertAttribute(mode_t mode)
1.1       root      548: {
1.1.1.2 ! root      549:   unsigned char Attrib=0;
        !           550: 
        !           551:   /* FIXME: More attributes */
        !           552:   if(S_ISDIR(mode)) Attrib |= GEMDOS_FILE_ATTRIB_SUBDIRECTORY;
        !           553: 
1.1       root      554: /* FIXME */
                    555: /*
                    556:   // Look up attributes
                    557:   if (dwFileAttributes&FILE_ATTRIBUTE_READONLY)
                    558:     Attrib |= GEMDOS_FILE_ATTRIB_READONLY;
                    559:   if (dwFileAttributes&FILE_ATTRIBUTE_HIDDEN)
                    560:     Attrib |= GEMDOS_FILE_ATTRIB_HIDDEN;
                    561:   if (dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
                    562:     Attrib |= GEMDOS_FILE_ATTRIB_SUBDIRECTORY;
                    563: */
                    564:   return(Attrib);
                    565: }
                    566: 
1.1.1.2 ! root      567: /*-----------------------------------------------------------------------*/
1.1       root      568: /*
                    569:   GEMDOS Cauxin
                    570:   Call 0x3
                    571: */
                    572: BOOL GemDOS_Cauxin(unsigned long Params)
                    573: {
                    574:   unsigned char Char;
                    575: 
1.1.1.2 ! root      576:   /* Wait here until a character is ready */
1.1       root      577:   while(!RS232_GetStatus());
                    578: 
1.1.1.2 ! root      579:   /* And read character */
1.1       root      580:   RS232_ReadBytes(&Char,1);
                    581:   Regs[REG_D0] = Char;
                    582: 
                    583:   return(TRUE);
                    584: }
                    585: 
1.1.1.2 ! root      586: /*-----------------------------------------------------------------------*/
1.1       root      587: /*
                    588:   GEMDOS Cauxout
                    589:   Call 0x4
                    590: */
                    591: BOOL GemDOS_Cauxout(unsigned long Params)
                    592: {
                    593:   unsigned char Char;
                    594: 
1.1.1.2 ! root      595:   /* Send character to RS232 */
1.1       root      596:   Char = STMemory_ReadWord(Params+SIZE_WORD);
                    597:   RS232_TransferBytesTo(&Char,1);
                    598: 
                    599:   return(TRUE);
                    600: }
                    601: 
1.1.1.2 ! root      602: /*-----------------------------------------------------------------------*/
1.1       root      603: /*
                    604:   GEMDOS Cprnout
                    605:   Call 0x5
                    606: */
                    607: BOOL GemDOS_Cprnout(unsigned long Params)
                    608: {
                    609:   unsigned char Char;
                    610: 
1.1.1.2 ! root      611:   /* Send character to printer(or file) */
1.1       root      612:   Char = STMemory_ReadWord(Params+SIZE_WORD);
                    613:   Printer_TransferByteTo(Char);
1.1.1.2 ! root      614:   Regs[REG_D0] = -1;                /* Printer OK */
1.1       root      615: 
                    616:   return(TRUE);
                    617: }
                    618: 
1.1.1.2 ! root      619: /*-----------------------------------------------------------------------*/
1.1       root      620: /*
                    621:   GEMDOS Set drive (0=A,1=B,2=C etc...)
                    622:   Call 0xE
                    623: */
                    624: BOOL GemDOS_SetDrv(unsigned long Params)
                    625: {
1.1.1.2 ! root      626:   /* Read details from stack for our own use */
1.1       root      627:   CurrentDrive = STMemory_ReadWord(Params+SIZE_WORD);
                    628: 
1.1.1.2 ! root      629:   /* Still re-direct to TOS */
1.1       root      630:   return(FALSE);
                    631: }
                    632: 
1.1.1.2 ! root      633: /*-----------------------------------------------------------------------*/
1.1       root      634: /*
                    635:   GEMDOS Cprnos
                    636:   Call 0x11
                    637: */
                    638: BOOL GemDOS_Cprnos(unsigned long Params)
                    639: {
1.1.1.2 ! root      640:   Regs[REG_D0] = -1;                /* Printer OK */
1.1       root      641: 
                    642:   return(TRUE);
                    643: }
                    644: 
1.1.1.2 ! root      645: /*-----------------------------------------------------------------------*/
1.1       root      646: /*
                    647:   GEMDOS Cauxis
                    648:   Call 0x12
                    649: */
                    650: BOOL GemDOS_Cauxis(unsigned long Params)
                    651: {
1.1.1.2 ! root      652:   /* Read our RS232 state */
1.1       root      653:   if (RS232_GetStatus())
1.1.1.2 ! root      654:     Regs[REG_D0] = -1;              /* Chars waiting */
1.1       root      655:   else
                    656:     Regs[REG_D0] = 0;
                    657: 
                    658:   return(TRUE);
                    659: }
                    660: 
1.1.1.2 ! root      661: /*-----------------------------------------------------------------------*/
1.1       root      662: /*
                    663:   GEMDOS Cauxos
                    664:   Call 0x13
                    665: */
                    666: BOOL GemDOS_Cauxos(unsigned long Params)
                    667: {
1.1.1.2 ! root      668:   Regs[REG_D0] = -1;                /* Device ready */
1.1       root      669: 
                    670:   return(TRUE);
                    671: }
                    672: 
1.1.1.2 ! root      673: /*-----------------------------------------------------------------------*/
1.1       root      674: /*
                    675:   GEMDOS Set Disc Transfer Address (DTA)
                    676:   Call 0x1A
                    677: */
                    678: BOOL GemDOS_SetDTA(unsigned long Params)
                    679: {
1.1.1.2 ! root      680:   /* Look up on stack to find where DTA is! Store as PC pointer */
1.1       root      681:   pDTA = (DTA *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD));
                    682: 
                    683:   return(FALSE);
                    684: }
                    685: 
1.1.1.2 ! root      686: /*-----------------------------------------------------------------------*/
        !           687: /*
        !           688:   GEMDOS Dfree Free disc space.
        !           689:   Call 0x39
        !           690: */
        !           691: BOOL GemDOS_DFree(unsigned long Params)
        !           692: {
        !           693:   int Drive;
        !           694:   unsigned long Address;
        !           695: 
        !           696:   Address = (unsigned long)STMemory_ReadLong(Params+SIZE_WORD);
        !           697:   Drive = STMemory_ReadWord(Params+SIZE_WORD+SIZE_LONG);
        !           698:   /* is it our drive? */
        !           699:   if((Drive == 0 && CurrentDrive >= 2) || Drive >= 3){
        !           700:     /* FIXME: Report actual free drive space */
        !           701:     
        !           702:     STMemory_WriteLong(Address,  10*2048);           /* free clusters (mock 10 Mb) */
        !           703:     STMemory_WriteLong(Address+SIZE_LONG, 50*2048 ); /* total clusters (mock 50 Mb) */
        !           704: 
        !           705:     STMemory_WriteLong(Address+SIZE_LONG*2, 512 );   /* bytes per sector */
        !           706:     STMemory_WriteLong(Address+SIZE_LONG*3, 1 );     /* sectors per cluster */
        !           707:     return (TRUE); 
        !           708:   } else return(FALSE); /* redirect to TOS */
        !           709: }
        !           710: 
        !           711: /*-----------------------------------------------------------------------*/
1.1       root      712: /*
                    713:   GEMDOS MkDir
                    714:   Call 0x39
                    715: */
                    716: BOOL GemDOS_MkDir(unsigned long Params)
                    717: {  
                    718:   char szDirPath[MAX_PATH];
                    719:   char *pDirName;
                    720:   int Drive;
                    721: 
1.1.1.2 ! root      722:   /* Find directory to make */
1.1       root      723:   pDirName = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD));
1.1.1.2 ! root      724: 
1.1       root      725:   Drive = GemDOS_IsFileNameAHardDrive(pDirName);
1.1.1.2 ! root      726: 
1.1       root      727:   if (ISHARDDRIVE(Drive)) {
1.1.1.2 ! root      728:     /* Copy old directory, as if calls fails keep this one */
1.1       root      729:     GemDOS_CreateHardDriveFileName(Drive,pDirName,szDirPath);
                    730: 
1.1.1.2 ! root      731:     /* Attempt to make directory */
1.1       root      732:     if ( mkdir(szDirPath, 0755)==0 )
                    733:       Regs[REG_D0] = GEMDOS_EOK;
                    734:     else
1.1.1.2 ! root      735:       Regs[REG_D0] = GEMDOS_EACCDN;        /* Access denied */
1.1       root      736: 
                    737:     return(TRUE);
                    738:   }
                    739:   return(FALSE);
                    740: }
                    741: 
1.1.1.2 ! root      742: /*-----------------------------------------------------------------------*/
1.1       root      743: /*
                    744:   GEMDOS RmDir
                    745:   Call 0x3A
                    746: */
                    747: BOOL GemDOS_RmDir(unsigned long Params)
                    748: {  
                    749:   char szDirPath[MAX_PATH];
                    750:   char *pDirName;
                    751:   int Drive;
                    752: 
1.1.1.2 ! root      753:   /* Find directory to make */
1.1       root      754:   pDirName = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD));
                    755:   Drive = GemDOS_IsFileNameAHardDrive(pDirName);
                    756:   if (ISHARDDRIVE(Drive)) {
1.1.1.2 ! root      757:     /* Copy old directory, as if calls fails keep this one */
1.1       root      758:     GemDOS_CreateHardDriveFileName(Drive,pDirName,szDirPath);
                    759: 
1.1.1.2 ! root      760:     /* Attempt to make directory */
1.1       root      761:     if ( rmdir(szDirPath)==0 )
                    762:       Regs[REG_D0] = GEMDOS_EOK;
                    763:     else
1.1.1.2 ! root      764:       Regs[REG_D0] = GEMDOS_EACCDN;        /* Access denied */
1.1       root      765: 
                    766:     return(TRUE);
                    767:   }
                    768:   return(FALSE);
                    769: }
                    770: 
1.1.1.2 ! root      771: /*-----------------------------------------------------------------------*/
1.1       root      772: /*
                    773:   GEMDOS ChDir
                    774:   Call 0x3B
                    775: */
                    776: BOOL GemDOS_ChDir(unsigned long Params)
                    777: {  
                    778:   char szDirPath[MAX_PATH];
                    779:   char *pDirName;
                    780:   int Drive;
1.1.1.2 ! root      781:   int n;
1.1       root      782: 
1.1.1.2 ! root      783:   /* Find new directory */
1.1       root      784:   pDirName = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD));
1.1.1.2 ! root      785: 
1.1       root      786:   Drive = GemDOS_IsFileNameAHardDrive(pDirName);
                    787:   if (ISHARDDRIVE(Drive)) {
1.1.1.2 ! root      788:     /* FIXME: Check path exists, else error (GEMDOS_EPTHNF) */
        !           789:     /*        GemDOS_CreateHardDriveFileName(Drive,"",szDirPath); */
        !           790:     sprintf(szDirPath, "%s%s", emudrives[0]->hd_emulation_dir, pDirName);
1.1       root      791: 
1.1.1.2 ! root      792:     for(n=0;n<MAX_PATH;n++) if(szDirPath[n] == '\\')szDirPath[n] = '/';
        !           793:     strcpy(emudrives[0]->fs_currpath, pDirName); 
        !           794:     Regs[REG_D0] = GEMDOS_EOK;
1.1       root      795:     return(TRUE);
                    796:   }
1.1.1.2 ! root      797:     
1.1       root      798:   return(FALSE);
                    799: }
                    800: 
1.1.1.2 ! root      801: /*-----------------------------------------------------------------------*/
1.1       root      802: /*
                    803:   GEMDOS Create file
                    804:   Call 0x3C
                    805: */
                    806: BOOL GemDOS_Create(unsigned long Params)
                    807: {
                    808:   char szActualFileName[MAX_PATH];
                    809:   char *pszFileName;
1.1.1.2 ! root      810:   char *rwflags[] = { "w+", /* read / write (truncate if exists) */
        !           811:                      "wb"  /* write only */
        !           812:   }; 
1.1       root      813:   unsigned int Access;
                    814:   int Drive,Index,Mode;
                    815: 
1.1.1.2 ! root      816:   /* Find filename */
1.1       root      817:   pszFileName = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD));
                    818:   Mode = STMemory_ReadWord(Params+SIZE_WORD+SIZE_LONG);
                    819:   Drive = GemDOS_IsFileNameAHardDrive(pszFileName);
                    820:   if (ISHARDDRIVE(Drive)) {
1.1.1.2 ! root      821:     /* And convert to hard drive filename */
1.1       root      822:     GemDOS_CreateHardDriveFileName(Drive,pszFileName,szActualFileName);
                    823: 
1.1.1.2 ! root      824:     /* Find slot to store file handle, as need to return WORD handle for ST */
1.1       root      825:     Index = GemDOS_FindFreeFileHandle();
                    826:     if (Index==-1) {
1.1.1.2 ! root      827:       /* No free handles, return error code */
        !           828:       Regs[REG_D0] = GEMDOS_ENHNDL;       /* No more handles */
1.1       root      829:       return(TRUE);
                    830:     }
                    831:     else {
                    832: #ifdef ENABLE_SAVING
                    833: 
1.1.1.2 ! root      834:       FileHandles[Index].FileHandle = fopen(szActualFileName, rwflags[Mode&0x01]);
        !           835: 
        !           836:       if (FileHandles[Index].FileHandle != NULL) {
1.1       root      837:         /* Tag handle table entry as used and return handle */
                    838:         FileHandles[Index].bUsed = TRUE;
1.1.1.2 ! root      839:         Regs[REG_D0] = Index+BASE_FILEHANDLE;  /* Return valid ST file handle from range 6 to 45! (ours start from 0) */
1.1       root      840:         return(TRUE);
                    841:       }
                    842:       else {
1.1.1.2 ! root      843:         Regs[REG_D0] = GEMDOS_EFILNF;     /* File not found */
1.1       root      844:         return(TRUE);
                    845:       }
                    846: #else
1.1.1.2 ! root      847:       Regs[REG_D0] = GEMDOS_EFILNF;       /* File not found */
1.1       root      848:       return(TRUE);
                    849: #endif
                    850:     }
                    851:   }
                    852: 
                    853:   return(FALSE);
                    854: }
                    855: 
1.1.1.2 ! root      856: /*-----------------------------------------------------------------------*/
1.1       root      857: /*
                    858:   GEMDOS Open file
                    859:   Call 0x3D
                    860: */
                    861: BOOL GemDOS_Open(unsigned long Params)
                    862: {
                    863:   char szActualFileName[MAX_PATH];
                    864:   char *pszFileName;
                    865:   unsigned int Access;
1.1.1.2 ! root      866:   char *open_modes[] = { "rb", "wb", "r+" };  /* convert atari modes to stdio modes */
1.1       root      867:   int Drive,Index,Mode;
                    868: 
1.1.1.2 ! root      869:   /* Find filename */
1.1       root      870:   pszFileName = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD));
                    871:   Mode = STMemory_ReadWord(Params+SIZE_WORD+SIZE_LONG);
                    872:   Drive = GemDOS_IsFileNameAHardDrive(pszFileName);
1.1.1.2 ! root      873:   
1.1       root      874:   if (ISHARDDRIVE(Drive)) {
1.1.1.2 ! root      875:     /* And convert to hard drive filename */
1.1       root      876:     GemDOS_CreateHardDriveFileName(Drive,pszFileName,szActualFileName);
1.1.1.2 ! root      877:     /* Find slot to store file handle, as need to return WORD handle for ST  */
1.1       root      878:     Index = GemDOS_FindFreeFileHandle();
1.1.1.2 ! root      879:     if (Index == -1) {
        !           880:       /* No free handles, return error code */
        !           881:       Regs[REG_D0] = GEMDOS_ENHNDL;       /* No more handles */
1.1       root      882:       return(TRUE);
                    883:     }
                    884: 
1.1.1.2 ! root      885:     /* Open file */
        !           886:     FileHandles[Index].FileHandle =  fopen(szActualFileName, open_modes[Mode&0x03]);
1.1       root      887: 
1.1.1.2 ! root      888:     sprintf(FileHandles[Index].szActualName,"%s",szActualFileName);    
        !           889: 
        !           890:     if (FileHandles[Index].FileHandle != NULL) {
        !           891:       /* Tag handle table entry as used and return handle */
        !           892:       FileHandles[Index].bUsed = TRUE;
        !           893:       Regs[REG_D0] = Index+BASE_FILEHANDLE;  /* Return valid ST file handle from range 6 to 45! (ours start from 0) */
        !           894:       return(TRUE);
1.1       root      895:     }
1.1.1.2 ! root      896:     Regs[REG_D0] = GEMDOS_EFILNF;     /* File not found/ error opening */
        !           897:     return(TRUE);
1.1       root      898:   }
1.1.1.2 ! root      899:     
1.1       root      900:   return(FALSE);
                    901: }
                    902: 
1.1.1.2 ! root      903: /*-----------------------------------------------------------------------*/
1.1       root      904: /*
                    905:   GEMDOS Close file
                    906:   Call 0x3E  
                    907: */
                    908: BOOL GemDOS_Close(unsigned long Params)
                    909: {
                    910:   int Handle;
                    911: 
1.1.1.2 ! root      912:   /* Find our handle - may belong to TOS */
1.1       root      913:   Handle = STMemory_ReadWord(Params+SIZE_WORD)-BASE_FILEHANDLE;
                    914: 
1.1.1.2 ! root      915:   /* Check handle was valid */
1.1       root      916:   if (GemDOS_IsInvalidFileHandle(Handle)) {
1.1.1.2 ! root      917:     /* No assume was TOS */
1.1       root      918:     return(FALSE);
                    919:   }
                    920:   else {
1.1.1.2 ! root      921:     /* Close file and free up handle table */
        !           922:     fclose(FileHandles[Handle].FileHandle);
1.1       root      923:     FileHandles[Handle].bUsed = FALSE;
1.1.1.2 ! root      924:     /* Return no error */
1.1       root      925:     Regs[REG_D0] = GEMDOS_EOK;
                    926:     return(TRUE);
                    927:   }
                    928: }
                    929: 
1.1.1.2 ! root      930: /*-----------------------------------------------------------------------*/
1.1       root      931: /*
                    932:   GEMDOS Read file
                    933:   Call 0x3F
                    934: */
                    935: BOOL GemDOS_Read(unsigned long Params)
                    936: {
                    937:   char *pBuffer;
                    938:   unsigned long nBytesRead,Size,CurrentPos,FileSize,nBytesLeft;
                    939:   int Handle;
                    940: 
1.1.1.2 ! root      941:   /* Read details from stack */
1.1       root      942:   Handle = STMemory_ReadWord(Params+SIZE_WORD)-BASE_FILEHANDLE;
                    943:   Size = STMemory_ReadLong(Params+SIZE_WORD+SIZE_WORD);
                    944:   pBuffer = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD+SIZE_WORD+SIZE_LONG));
                    945: 
1.1.1.2 ! root      946:   /* Check handle was valid */
1.1       root      947:   if (GemDOS_IsInvalidFileHandle(Handle)) {
1.1.1.2 ! root      948:     /* No -  assume was TOS */
1.1       root      949:     return(FALSE);
                    950:   }
                    951:   else {
                    952: 
1.1.1.2 ! root      953:     /* To quick check to see where our file pointer is and how large the file is */
        !           954:     CurrentPos = ftell(FileHandles[Handle].FileHandle);
        !           955:     fseek(FileHandles[Handle].FileHandle, 0, SEEK_END);
        !           956:     FileSize = ftell(FileHandles[Handle].FileHandle);
        !           957:     fseek(FileHandles[Handle].FileHandle, CurrentPos, SEEK_SET);
1.1       root      958: 
                    959:     nBytesLeft = FileSize-CurrentPos;
                    960: 
1.1.1.2 ! root      961:     /* Check for End Of File */
        !           962:     // if (nBytesLeft<0) {
        !           963:     if(0)1.1       root      964:       Regs[REG_D0] = GEMDOS_ERROR;
                    965: 
                    966:       return(TRUE);
                    967:     }
                    968:     else {
1.1.1.2 ! root      969:       /* Limit to size of file to prevent windows error */
1.1       root      970:       if (Size>FileSize)
                    971:         Size = FileSize;
1.1.1.2 ! root      972:       /* And read data in */
        !           973:       nBytesRead = fread(pBuffer, 1, Size, FileHandles[Handle].FileHandle);
1.1       root      974: 
1.1.1.2 ! root      975:       /* Return number of bytes read */
1.1       root      976:       Regs[REG_D0] = nBytesRead;
                    977: 
                    978:       return(TRUE);
                    979:     }
                    980:   }
                    981: }
                    982: 
1.1.1.2 ! root      983: /*-----------------------------------------------------------------------*/
1.1       root      984: /*
                    985:   GEMDOS Write file
                    986:   Call 0x40
                    987: */
                    988: BOOL GemDOS_Write(unsigned long Params)
                    989: {
                    990:   char *pBuffer;
                    991:   unsigned long Size,nBytesWritten;
                    992:   int Handle;
                    993: 
                    994: #ifdef ENABLE_SAVING
1.1.1.2 ! root      995:   /* Read details from stack */
1.1       root      996:   Handle = STMemory_ReadWord(Params+SIZE_WORD)-BASE_FILEHANDLE;
                    997:   Size = STMemory_ReadLong(Params+SIZE_WORD+SIZE_WORD);
                    998:   pBuffer = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD+SIZE_WORD+SIZE_LONG));
                    999: 
1.1.1.2 ! root     1000:   /* Check handle was valid */
1.1       root     1001:   if (GemDOS_IsInvalidFileHandle(Handle)) {
1.1.1.2 ! root     1002:     /* No assume was TOS */
1.1       root     1003:     return(FALSE);
                   1004:   }
                   1005:   else {
                   1006: 
1.1.1.2 ! root     1007:     nBytesWritten = fwrite(pBuffer, 1, Size, FileHandles[Handle].FileHandle);
1.1       root     1008:     if (nBytesWritten>=0) {
                   1009: 
1.1.1.2 ! root     1010:       Regs[REG_D0] = nBytesWritten;      /* OK */
1.1       root     1011:     }
                   1012:     else
1.1.1.2 ! root     1013:       Regs[REG_D0] = GEMDOS_EACCDN;      /* Access denied(ie read-only) */
1.1       root     1014: 
                   1015:     return(TRUE);
                   1016:   }
                   1017: #endif
                   1018: 
                   1019:   return(FALSE);
                   1020: }
                   1021: 
1.1.1.2 ! root     1022: /*-----------------------------------------------------------------------*/
1.1       root     1023: /*
                   1024:   GEMDOS UnLink(Delete) file
                   1025:   Call 0x41
                   1026: */
                   1027: BOOL GemDOS_UnLink(unsigned long Params)
                   1028: {
                   1029: #ifdef ENABLE_SAVING
                   1030:   char szActualFileName[MAX_PATH];
                   1031:   char *pszFileName;
                   1032:   int Drive;
                   1033: 
1.1.1.2 ! root     1034:   /* Find filename */
1.1       root     1035:   pszFileName = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD));
                   1036:   Drive = GemDOS_IsFileNameAHardDrive(pszFileName);
                   1037:   if (ISHARDDRIVE(Drive)) {
1.1.1.2 ! root     1038:     /* And convert to hard drive filename */
1.1       root     1039:     GemDOS_CreateHardDriveFileName(Drive,pszFileName,szActualFileName);
                   1040: 
1.1.1.2 ! root     1041:     /* Now delete file?? */
1.1       root     1042:     if ( unlink(szActualFileName)==0 )
1.1.1.2 ! root     1043:       Regs[REG_D0] = GEMDOS_EOK;          /* OK */
1.1       root     1044:     else
1.1.1.2 ! root     1045:       Regs[REG_D0] = GEMDOS_EFILNF;       /* File not found */
1.1       root     1046: 
                   1047:     return(TRUE);
                   1048:   }
                   1049: #endif
                   1050: 
                   1051:   return(FALSE);
                   1052: }
                   1053: 
1.1.1.2 ! root     1054: /*-----------------------------------------------------------------------*/
1.1       root     1055: /*
                   1056:   GEMDOS File seek
                   1057:   Call 0x42
                   1058: */
                   1059: BOOL GemDOS_LSeek(unsigned long Params)
                   1060: {
                   1061:   long Offset;
                   1062:   int Handle,Mode;
                   1063: 
1.1.1.2 ! root     1064:   /* Read details from stack */
1.1       root     1065:   Offset = (long)STMemory_ReadLong(Params+SIZE_WORD);
                   1066:   Handle = STMemory_ReadWord(Params+SIZE_WORD+SIZE_LONG)-BASE_FILEHANDLE;
                   1067:   Mode = STMemory_ReadWord(Params+SIZE_WORD+SIZE_LONG+SIZE_WORD);
                   1068: 
1.1.1.2 ! root     1069:   /* Check handle was valid */
1.1       root     1070:   if (GemDOS_IsInvalidFileHandle(Handle)) {
1.1.1.2 ! root     1071:     /* No assume was TOS */
1.1       root     1072:     return(FALSE);
                   1073:   }
                   1074:   else {
1.1.1.2 ! root     1075:     /* Return offset from start of file */
        !          1076:     fseek(FileHandles[Handle].FileHandle, Offset, Mode);
        !          1077:     Regs[REG_D0] = ftell(FileHandles[Handle].FileHandle);
1.1       root     1078:     return(TRUE);
                   1079:   }
                   1080: }
                   1081: 
1.1.1.2 ! root     1082: /*-----------------------------------------------------------------------*/
        !          1083: /*
        !          1084:   GEMDOS Get Directory
        !          1085:   Call 0x47
        !          1086: */
        !          1087: int GemDOS_GetDir(unsigned long Params){
        !          1088:   unsigned long Address;
        !          1089:   unsigned short Drive;
        !          1090:   int i;
        !          1091: 
        !          1092:   Address = (long)STMemory_ReadLong(Params+SIZE_WORD);
        !          1093:   Drive = STMemory_ReadWord(Params+SIZE_WORD+SIZE_LONG);
        !          1094:   /* is it our drive? */
        !          1095:   if((Drive == 0 && CurrentDrive >= 2) || Drive >= 3){
        !          1096:     STMemory_WriteByte(Address, '\0' );
        !          1097:     Regs[REG_D0] = GEMDOS_EOK;          /* OK */    
        !          1098:     return(TRUE);
        !          1099:   } else return(FALSE);
        !          1100: }
        !          1101: 
        !          1102: /*-----------------------------------------------------------------------*/
1.1       root     1103: /*
                   1104:   PExec Load And Go - Redirect to cart' routine at address 0xFA1000
                   1105: 
                   1106:   If loading from hard-drive(ie drive ID 2 or more) set condition codes to run own GEMDos routines
                   1107: */
1.1.1.2 ! root     1108: int GemDOS_Pexec_LoadAndGo(unsigned long Params)
1.1       root     1109: {
1.1.1.2 ! root     1110:   /* FIXME: will generate problems with ramdiscs/ lowlevel emulated HDs */
        !          1111:   /* Hard-drive? */
        !          1112:   if (CurrentDrive>=2){                /* If not using A: or B:, use my own routines to load */
        !          1113:      return(CALL_PEXEC_ROUTINE); 
        !          1114:   }
        !          1115:   else return(FALSE);
1.1       root     1116: }
                   1117: 
1.1.1.2 ! root     1118: /*-----------------------------------------------------------------------*/
1.1       root     1119: /*
                   1120:   PExec Load But Don't Go - Redirect to cart' routine at address 0xFA1000
                   1121: */
1.1.1.2 ! root     1122: int GemDOS_Pexec_LoadDontGo(unsigned long Params)
1.1       root     1123: {
1.1.1.2 ! root     1124:   /* Hard-drive? */
        !          1125:   if (CurrentDrive>=2){
        !          1126:      return(CALL_PEXEC_ROUTINE); 
        !          1127:   } else return(FALSE);
1.1       root     1128: }
                   1129: 
1.1.1.2 ! root     1130: /*-----------------------------------------------------------------------*/
1.1       root     1131: /*
                   1132:   GEMDOS PExec handler
                   1133:   Call 0x4B
                   1134: */
1.1.1.2 ! root     1135: int GemDOS_Pexec(unsigned long Params)
1.1       root     1136: {
                   1137:   unsigned short int Mode;
                   1138: 
1.1.1.2 ! root     1139:   /* Find PExec mode */
1.1       root     1140:   Mode = STMemory_ReadWord(Params+SIZE_WORD);
                   1141: 
1.1.1.2 ! root     1142:   /* Re-direct as needed */
1.1       root     1143:   switch(Mode) {
1.1.1.2 ! root     1144:   case 0:      /* Load and go */
        !          1145:     return(GemDOS_Pexec_LoadAndGo(Params));
        !          1146:   case 3:      /* Load, don't go */
        !          1147:     return(GemDOS_Pexec_LoadDontGo(Params));
        !          1148:   case 4:      /* Just go */
        !          1149:     return(FALSE);
        !          1150:   case 5:      /* Create basepage */
        !          1151:     return(FALSE);
        !          1152:   case 6:
        !          1153:     return(FALSE);
1.1       root     1154: 
1.1.1.2 ! root     1155:   default:
        !          1156:     return(FALSE);
1.1       root     1157:   }
                   1158: 
1.1.1.2 ! root     1159:   /* Still re-direct to TOS */
1.1       root     1160:   return(FALSE);
                   1161: }
                   1162: 
1.1.1.2 ! root     1163: /*-----------------------------------------------------------------------*/
1.1       root     1164: /*
                   1165:   GEMDOS Find first file
                   1166:   Call 0x4E
                   1167: */
                   1168: BOOL GemDOS_SFirst(unsigned long Params)
                   1169: {
                   1170:   int FatDate, FatTime;
                   1171:   char szActualFileName[MAX_PATH];
1.1.1.2 ! root     1172:   char tempstr[MAX_PATH];
1.1       root     1173:   char *pszFileName;
1.1.1.2 ! root     1174:   struct dirent **files;
1.1       root     1175:   unsigned short int Attr;
                   1176:   int Drive;
1.1.1.2 ! root     1177:   DIR *fsdir;
        !          1178:   int i,j,k;
1.1       root     1179: 
1.1.1.2 ! root     1180:   /* Find filename to search for */
1.1       root     1181:   pszFileName = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD));
                   1182:   Attr = STMemory_ReadWord(Params+SIZE_WORD+SIZE_LONG);
                   1183: 
                   1184:   Drive = GemDOS_IsFileNameAHardDrive(pszFileName);
                   1185:   if (ISHARDDRIVE(Drive)) {
                   1186: 
1.1.1.2 ! root     1187:     /* And convert to hard drive filename */
1.1       root     1188:     GemDOS_CreateHardDriveFileName(Drive,pszFileName,szActualFileName);
1.1.1.2 ! root     1189:         
        !          1190:     /* Populate DTA, set index for our use */
1.1       root     1191:     STMemory_WriteWord_PCSpace(pDTA->index,DTAIndex);
1.1.1.2 ! root     1192:     STMemory_WriteLong_PCSpace(pDTA->magic,DTA_MAGIC_NUMBER); /* set our dta magic num */
        !          1193: 
        !          1194:     if(InternalDTAs[DTAIndex].bUsed == TRUE) ClearInternalDTA();    
        !          1195:     InternalDTAs[DTAIndex].bUsed = TRUE;
1.1       root     1196: 
1.1.1.2 ! root     1197:     /* Were we looking for the volume label? */
1.1       root     1198:     if (Attr&GEMDOS_FILE_ATTRIB_VOLUME_LABEL) {
1.1.1.2 ! root     1199:       /* Volume name */
        !          1200:       strcpy(pDTA->dta_name,"EMULATED.001");
        !          1201:       Regs[REG_D0] = GEMDOS_EOK;          /* Got volume */
1.1       root     1202:       return(TRUE);
                   1203:     }
1.1.1.2 ! root     1204:     
        !          1205:     /* open directory */
        !          1206:     fsfirst_dirname(szActualFileName, InternalDTAs[DTAIndex].path);
1.1       root     1207: 
1.1.1.2 ! root     1208:     fsdir = opendir(InternalDTAs[DTAIndex].path);
        !          1209:     
        !          1210:     if( fsdir == NULL ){
        !          1211:       Regs[REG_D0] = GEMDOS_EPTHNF;        /* Path not found */
1.1       root     1212:       return(TRUE);
                   1213:     }
1.1.1.2 ! root     1214:     /* close directory */
        !          1215:     closedir( fsdir );
        !          1216:     
        !          1217:     InternalDTAs[DTAIndex].nentries = scandir(InternalDTAs[DTAIndex].path, &files, 0, alphasort); 
        !          1218:     if( InternalDTAs[DTAIndex].nentries < 0 ){
        !          1219:       Regs[REG_D0] = GEMDOS_EFILNF;        /* File (directory actually) not found */
        !          1220:       return(TRUE);
        !          1221:     }
        !          1222:     
        !          1223:     InternalDTAs[DTAIndex].centry = 0;        /* current entry is 0 */
        !          1224:     fsfirst_dirmask(szActualFileName, tempstr); /* get directory mask */
1.1       root     1225: 
1.1.1.2 ! root     1226:     /* Create and populate a list of matching files. */
        !          1227:     j = 0;                     /* count number of entries matching mask */
1.1       root     1228: 
1.1.1.2 ! root     1229:     for(i=0;i<InternalDTAs[DTAIndex].nentries;i++)
        !          1230:       if(match(tempstr, files[i]->d_name)) j++;
        !          1231:     
        !          1232:     InternalDTAs[DTAIndex].found = (struct dirent **)malloc(sizeof(struct dirent *) * j);
        !          1233:     
        !          1234:     /* copy the dirent pointers for files matching the mask to our list */
        !          1235:     k = 0;
        !          1236:     for(i=0;i<InternalDTAs[DTAIndex].nentries;i++)
        !          1237:       if(match(tempstr, files[i]->d_name)){
        !          1238:        InternalDTAs[DTAIndex].found[k] = files[i];
        !          1239:        k++;
        !          1240:       }
        !          1241:     InternalDTAs[DTAIndex].nentries = j; /* set number of legal entries */
1.1       root     1242: 
1.1.1.2 ! root     1243:     if(InternalDTAs[DTAIndex].nentries == 0){
        !          1244:       /* No files of that match, return error code */
        !          1245:       Regs[REG_D0] = GEMDOS_EFILNF;        /* File not found */
        !          1246:       return(TRUE);
1.1       root     1247:     }
1.1.1.2 ! root     1248: 
        !          1249:     /* Scan for first file (SNext uses no parameters) */
        !          1250:     GemDOS_SNext(NULL);
        !          1251:     /* increment DTA index */
        !          1252:     DTAIndex++;
        !          1253:     DTAIndex&=(MAX_DTAS_FILES-1);
        !          1254: 
1.1       root     1255:     return(TRUE);
                   1256:   }
                   1257:   return(FALSE);
                   1258: }
                   1259: 
1.1.1.2 ! root     1260: /*-----------------------------------------------------------------------*/
1.1       root     1261: /*
                   1262:   GEMDOS Search Next
                   1263:   Call 0x4F
                   1264: */
                   1265: BOOL GemDOS_SNext(unsigned long Params)
                   1266: {
                   1267:   int FatDate, FatTime;
1.1.1.2 ! root     1268:   struct dirent **temp;
        !          1269:   int Index;
1.1       root     1270: 
1.1.1.2 ! root     1271:   /* Was DTA ours or TOS? */
1.1       root     1272:   if (STMemory_ReadLong_PCSpace(pDTA->magic)==DTA_MAGIC_NUMBER) {
                   1273: 
1.1.1.2 ! root     1274:     /* Find index into our list of structures */
        !          1275:     Index = STMemory_ReadWord_PCSpace(pDTA->index)&(MAX_DTAS_FILES-1);
        !          1276: 
        !          1277:     if(InternalDTAs[Index].centry >= InternalDTAs[Index].nentries){ 
        !          1278:       Regs[REG_D0] = GEMDOS_ENMFIL;    /* No more files */
1.1       root     1279:       return(TRUE);
                   1280:     }
1.1.1.2 ! root     1281: 
        !          1282:     temp = InternalDTAs[Index].found;
        !          1283:     if(PopulateDTA(InternalDTAs[Index].path, temp[InternalDTAs[Index].centry++]) == FALSE){
        !          1284:       fprintf(stderr,"\tError setting DTA.\n");
1.1       root     1285:       return(TRUE);
                   1286:     }
1.1.1.2 ! root     1287:     
        !          1288:     Regs[REG_D0] = GEMDOS_EOK;
        !          1289:     return(TRUE);
1.1       root     1290:   }
                   1291: 
                   1292:   return(FALSE);
                   1293: }
                   1294: 
1.1.1.2 ! root     1295: /*-----------------------------------------------------------------------*/
1.1       root     1296: /*
                   1297:   GEMDOS Rename
                   1298:   Call 0x56
                   1299: */
                   1300: BOOL GemDOS_Rename(unsigned long Params)
                   1301: {
                   1302:   char *pszNewFileName,*pszOldFileName;
                   1303:   char szNewActualFileName[MAX_PATH],szOldActualFileName[MAX_PATH];
                   1304:   int NewDrive, OldDrive;
                   1305: 
1.1.1.2 ! root     1306:   /* Read details from stack */
1.1       root     1307:   pszOldFileName = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD+SIZE_WORD));
                   1308:   pszNewFileName = (char *)STRAM_ADDR(STMemory_ReadLong(Params+SIZE_WORD+SIZE_WORD+SIZE_LONG));
                   1309: 
                   1310:   NewDrive = GemDOS_IsFileNameAHardDrive(pszNewFileName);
                   1311:   OldDrive = GemDOS_IsFileNameAHardDrive(pszOldFileName);
                   1312:   if (ISHARDDRIVE(NewDrive) && ISHARDDRIVE(OldDrive)) {
1.1.1.2 ! root     1313:     /* And convert to hard drive filenames */
1.1       root     1314:     GemDOS_CreateHardDriveFileName(NewDrive,pszNewFileName,szNewActualFileName);
                   1315:     GemDOS_CreateHardDriveFileName(OldDrive,pszOldFileName,szOldActualFileName);
                   1316: 
1.1.1.2 ! root     1317:     /* Rename files */
1.1       root     1318:     if ( rename(szOldActualFileName,szNewActualFileName)==0 )
                   1319:       Regs[REG_D0] = GEMDOS_EOK;
                   1320:     else
1.1.1.2 ! root     1321:       Regs[REG_D0] = GEMDOS_EACCDN;        /* Access denied */
1.1       root     1322:     return(TRUE);
                   1323:   }
                   1324: 
                   1325:   return(FALSE);
                   1326: }
                   1327: 
1.1.1.2 ! root     1328: /*-----------------------------------------------------------------------*/
1.1       root     1329: /*
                   1330:   GEMDOS GSDToF
                   1331:   Call 0x57
                   1332: */
                   1333: BOOL GemDOS_GSDToF(unsigned long Params)
                   1334: {
                   1335:   DATETIME DateTime;
1.1.1.2 ! root     1336:   unsigned long pBuffer;
1.1       root     1337:   int Handle,Flag;
                   1338: 
1.1.1.2 ! root     1339:   /* Read details from stack */
        !          1340:   pBuffer = STMemory_ReadLong(Params+SIZE_WORD);
1.1       root     1341:   Handle = STMemory_ReadWord(Params+SIZE_WORD+SIZE_LONG)-BASE_FILEHANDLE;
                   1342:   Flag = STMemory_ReadWord(Params+SIZE_WORD+SIZE_WORD+SIZE_LONG);
                   1343: 
1.1.1.2 ! root     1344:   /* Check handle was valid */
1.1       root     1345:   if (GemDOS_IsInvalidFileHandle(Handle)) {
1.1.1.2 ! root     1346:     /* No assume was TOS */
1.1       root     1347:     return(FALSE);
                   1348:   }
                   1349: 
1.1.1.2 ! root     1350:   /* Set time/date stamp? Do nothing. */
        !          1351:   if( Flag == 1 ){
        !          1352:     Regs[REG_D0] = GEMDOS_EOK;
        !          1353:     return (TRUE);
1.1       root     1354:   }
1.1.1.2 ! root     1355:   
        !          1356:   Regs[REG_D0] = GEMDOS_ERROR;  /* Invalid parameter */
1.1       root     1357: 
1.1.1.2 ! root     1358:   if (GetFileInformation(FileHandles[Handle].szActualName, &DateTime) == TRUE){
        !          1359:     STMemory_WriteWord(pBuffer, DateTime.word1);
        !          1360:     STMemory_WriteWord(pBuffer+2, DateTime.word2);
        !          1361:     Regs[REG_D0] = GEMDOS_EOK;  
1.1       root     1362:   }
1.1.1.2 ! root     1363:   return (TRUE);
1.1       root     1364: }
                   1365: 
                   1366: /*-----------------------------------------------------------------------*/
                   1367: /*
                   1368:   Run GEMDos call, and re-direct if need to. Used to handle hard-disc emulation etc...
                   1369:   This sets the condition codes(in SR), which are used in the 'cart.s' program to decide if we
                   1370:   need to run old GEM vector, or PExec or nothing.
                   1371: 
                   1372:   This method keeps the stack and other states consistant with the original ST which is very important
                   1373:   for the PExec call and maximum compatibility through-out
                   1374: */
                   1375: void GemDOS_OpCode(void)
                   1376: {
                   1377:   unsigned short int GemDOSCall,CallingSReg;
                   1378:   unsigned long Params;
1.1.1.2 ! root     1379:   short RunOld;
1.1       root     1380: 
1.1.1.2 ! root     1381: 
        !          1382:   /* Read SReg from stack to see if parameters are on User or Super stack  */
        !          1383:   MakeSR();  /* update value of SR */
1.1       root     1384:   CallingSReg = STMemory_ReadWord(Regs[REG_A7]);
                   1385:   if ((CallingSReg&SR_SUPERMODE)==0)      /* Calling from user mode */
1.1.1.2 ! root     1386:     Params = regs.usp;
        !          1387:   else {
        !          1388:     Params = Regs[REG_A7]+SIZE_WORD+SIZE_LONG;  /* super stack */
        !          1389:     if( cpu_level>0 )
        !          1390:       Params += SIZE_WORD;   /* Skip extra word whe CPU is >=68010 */
        !          1391:   }
1.1       root     1392: 
                   1393:   /* Default to run TOS GemDos (SR_NEG run Gemdos, SR_ZERO already done, SR_OVERFLOW run own 'Pexec' */
1.1.1.2 ! root     1394:   RunOld = TRUE;
1.1       root     1395:   SR &= SR_CLEAR_OVERFLOW;
                   1396:   SR &= SR_CLEAR_ZERO;
                   1397:   SR |= SR_NEG;
                   1398: 
                   1399:   /* Find pointer to call parameters */
                   1400:   GemDOSCall = STMemory_ReadWord(Params);
1.1.1.2 ! root     1401: 
        !          1402: #ifdef GEMDOS_VERBOSE
        !          1403:   if(GemDOSCall <= 0x57)
        !          1404:     fprintf(stderr, "GemDOS 0x%X (%s)\n",GemDOSCall,pszGemDOSNames[GemDOSCall]); 
1.1       root     1405: #endif
                   1406: 
                   1407:   /* Intercept call */
                   1408:   switch(GemDOSCall) {
1.1.1.2 ! root     1409: /*    case 0x3: */
        !          1410: /*      if (GemDOS_Cauxin(Params)) */
        !          1411: /*        RunOld = FALSE; */
        !          1412: /*      break; */
        !          1413: /*    case 0x4: */
        !          1414: /*      if (GemDOS_Cauxout(Params)) */
        !          1415: /*        RunOld = FALSE; */
        !          1416: /*      break; */
        !          1417: /*    case 0x5: */
        !          1418: /*      if (GemDOS_Cprnout(Params)) */
        !          1419: /*        RunOld = FALSE; */
        !          1420: /*      break; */
        !          1421:   case 0xe:
        !          1422:     if (GemDOS_SetDrv(Params))
        !          1423:       RunOld = FALSE;
        !          1424:     break;      
        !          1425: /*    case 0x11: */
        !          1426: /*        if (GemDOS_Cprnos(Params)) */
        !          1427: /*          RunOld = FALSE; */
        !          1428: /*        break; */
        !          1429: /*      case 0x12: */
        !          1430: /*        if (GemDOS_Cauxis(Params)) */
        !          1431: /*          RunOld = FALSE; */
        !          1432: /*        break; */
        !          1433: /*      case 0x13: */
        !          1434: /*        if (GemDOS_Cauxos(Params)) */
        !          1435: /*          RunOld = FALSE; */
        !          1436: /*        break; */
1.1       root     1437:     case 0x1a:
                   1438:       if (GemDOS_SetDTA(Params))
1.1.1.2 ! root     1439:        RunOld = FALSE;
        !          1440:       break;
        !          1441:     case 0x36:
        !          1442:       if (GemDOS_DFree(Params))
        !          1443:         RunOld = FALSE;
1.1       root     1444:       break;
                   1445:     case 0x39:
                   1446:       if (GemDOS_MkDir(Params))
1.1.1.2 ! root     1447:         RunOld = FALSE;
1.1       root     1448:       break;
                   1449:     case 0x3a:
                   1450:       if (GemDOS_RmDir(Params))
1.1.1.2 ! root     1451:         RunOld = FALSE;
1.1       root     1452:       break;
                   1453:     case 0x3b:
                   1454:       if (GemDOS_ChDir(Params))
1.1.1.2 ! root     1455:         RunOld = FALSE;
1.1       root     1456:       break;
                   1457:     case 0x3c:
                   1458:       if (GemDOS_Create(Params))
1.1.1.2 ! root     1459:         RunOld = FALSE;
1.1       root     1460:       break;
                   1461:     case 0x3d:
                   1462:       if (GemDOS_Open(Params))
1.1.1.2 ! root     1463:         RunOld = FALSE;
1.1       root     1464:       break;
                   1465:     case 0x3e:
                   1466:       if (GemDOS_Close(Params))
1.1.1.2 ! root     1467:         RunOld = FALSE;
1.1       root     1468:       break;
                   1469:     case 0x3f:
                   1470:       if (GemDOS_Read(Params))
1.1.1.2 ! root     1471:         RunOld = FALSE;
1.1       root     1472:       break;
                   1473:     case 0x40:
                   1474:       if (GemDOS_Write(Params))
1.1.1.2 ! root     1475:         RunOld = FALSE;
1.1       root     1476:       break;
                   1477:     case 0x41:
                   1478:       if (GemDOS_UnLink(Params))
1.1.1.2 ! root     1479:         RunOld = FALSE;
1.1       root     1480:       break;
                   1481:     case 0x42:
                   1482:       if (GemDOS_LSeek(Params))
1.1.1.2 ! root     1483:         RunOld = FALSE;
        !          1484:       break;
        !          1485:     case 0x47:
        !          1486:       if (GemDOS_GetDir(Params))
        !          1487:         RunOld = FALSE;
1.1       root     1488:       break;
                   1489:     case 0x4b:
1.1.1.2 ! root     1490:       if(GemDOS_Pexec(Params) == CALL_PEXEC_ROUTINE);
        !          1491:       RunOld = CALL_PEXEC_ROUTINE;
1.1       root     1492:       break;
                   1493:     case 0x4e:
                   1494:       if (GemDOS_SFirst(Params))
1.1.1.2 ! root     1495:        RunOld = FALSE;
1.1       root     1496:       break;
                   1497:     case 0x4f:
                   1498:       if (GemDOS_SNext(Params))
1.1.1.2 ! root     1499:         RunOld = FALSE;
1.1       root     1500:       break;
1.1.1.2 ! root     1501:     case 0x56: 
        !          1502:       if (GemDOS_Rename(Params)) 
        !          1503:         RunOld = FALSE; 
        !          1504:       break; 
        !          1505:     case 0x57: 
        !          1506:       if (GemDOS_GSDToF(Params)) 
        !          1507:         RunOld = FALSE;
        !          1508:       break; 
        !          1509:   }
        !          1510: 
        !          1511:   switch(RunOld){
        !          1512:   case FALSE:       /* skip over branch to pexec to RTE */
        !          1513:     SR |= SR_ZERO;
        !          1514:     break;
        !          1515:   case CALL_PEXEC_ROUTINE:   /* branch to pexec, then redirect to old gemdos. */
        !          1516:     SR |= SR_OVERFLOW;
        !          1517:     break;
1.1       root     1518:   }
                   1519: 
1.1.1.2 ! root     1520:   MakeFromSR();  /* update the flags from the SR register */
1.1       root     1521: }
                   1522: 
1.1.1.2 ! root     1523: /*-----------------------------------------------------------------------*/
1.1       root     1524: /*
1.1.1.2 ! root     1525:   GemDOS_Boot - routine called on the first occurence of the gemdos opcode.
        !          1526:   used to set up our gemdos handler.
        !          1527:  */
        !          1528: 
        !          1529: void GemDOS_Boot()
        !          1530: {
        !          1531:   bInitGemDOS = TRUE;
        !          1532: 
        !          1533:   /* install our gemdos handler, if -e or --harddrive option used */
        !          1534:   if(emudrives != NULL){
        !          1535:     /* Patch pexec code - coded value is 4, but must be 6 for TOS > 1.00 */
        !          1536:     if(TOSVersion > 0x0100) 
        !          1537:       STMemory_WriteByte(CART_PEXEC_TOS, 0x06);
        !          1538:   
        !          1539:     /* Save old GEMDOS handler adress */
        !          1540:     STMemory_WriteLong(CART_OLDGEMDOS, STMemory_ReadLong(0x0084));
        !          1541:     /* Setup new GEMDOS handler, see cartimg.c */ 
        !          1542:     STMemory_WriteLong(0x0084, CART_GEMDOS);
1.1       root     1543:   }
                   1544: }
1.1.1.2 ! root     1545: 
        !          1546: /*
        !          1547:   GemDOS_RunOldOpCode()
        !          1548:   Has been relocated to a routine in hatari-glue.c
        !          1549: */
        !          1550: 
        !          1551: 

unix.superglobalmegacorp.com

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