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