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

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

unix.superglobalmegacorp.com

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