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

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

unix.superglobalmegacorp.com

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