diff --git a/toolbox/mm.cpp b/toolbox/mm.cpp index f1778e3..7ca6fc6 100644 --- a/toolbox/mm.cpp +++ b/toolbox/mm.cpp @@ -1180,7 +1180,36 @@ namespace MM return flags; } + uint16_t HSetState(uint16_t trap) + { + /* + * on entry: + * A0 Handle + * D0 flags + * + * on exit: + * D0 flag byte + * + */ + uint32_t hh = cpuGetAReg(0); + uint16_t flags = cpuGetDReg(0); + + Log("%04x HSetState(%08x, %04x)\n", trap, hh, flags); + + auto iter = HandleMap.find(hh); + + if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr); + + auto &info = iter->second; + + info.resource = (flags & (1 << 5)); + info.purgeable = (flags & (1 << 6)); + info.locked = (flags & (1 << 7)); + + + return SetMemError(0); + } uint16_t HPurge(uint16_t trap) { @@ -1265,7 +1294,7 @@ namespace MM * A0 destination Handle * D0 Result code * - */ + */ uint32_t srcHandle = cpuGetAReg(0); @@ -1303,7 +1332,7 @@ namespace MM * A0 destination pointer * D0 Result code * - */ + */ uint32_t mcptr = cpuGetAReg(0); uint32_t size = cpuGetDReg(0); @@ -1322,6 +1351,53 @@ namespace MM return d0; // SetMemError called by Native::NewHandle. } + uint16_t PtrAndHand(uint16_t trap) + { + // FUNCTION PtrAndHand (pntr: Ptr; hndl: Handle; size: LongInt): OSErr; + + /* + * on entry: + * A0 source Pointer + * A1 dest Handle + * D0 number of bytes to concatenate + * + * on exit: + * A0 destination Handle + * D0 Result code + * + */ + + uint32_t ptr = cpuGetAReg(0); + uint32_t handle = cpuGetAReg(1); + uint32_t size = cpuGetDReg(0); + + Log("%04x PtrAndHand(%08x, %08x, %08x)\n", trap, ptr, handle, size); + + cpuSetAReg(0, handle); + + uint32_t oldSize = 0; + uint32_t d0; + + d0 = Native::GetHandleSize(handle, oldSize); + if (d0) return d0; + + if ((uint64_t)oldSize + (uint64_t)size > UINT32_MAX) + return SetMemError(MacOS::memFullErr); + + + d0 = Native::SetHandleSize(handle, oldSize + size); + if (d0) return d0; + + auto iter = HandleMap.find(handle); + if (iter == HandleMap.end()) + return SetMemError(MacOS::memWZErr); + + auto const info = iter->second; + + std::memmove(memoryPointer(info.address + oldSize), memoryPointer(ptr), size); + + return SetMemError(0); + } diff --git a/toolbox/mm.h b/toolbox/mm.h index 9602f71..345956a 100644 --- a/toolbox/mm.h +++ b/toolbox/mm.h @@ -62,6 +62,7 @@ namespace MM uint32_t RecoverHandle(uint16_t); uint16_t HGetState(uint16_t trap); + uint16_t HSetState(uint16_t trap); uint16_t HLock(uint16_t trap); uint16_t HUnlock(uint16_t trap); diff --git a/toolbox/os.cpp b/toolbox/os.cpp index 8f1531c..b7a8091 100644 --- a/toolbox/os.cpp +++ b/toolbox/os.cpp @@ -747,6 +747,57 @@ namespace OS } + + uint16_t HGetVInfo(uint16_t trap) + { + enum { + /* HVolumeParam */ + _qLink = 0, + _qType = 4, + _ioTrap = 6, + _ioCmdAddr = 8, + _ioCompletion = 12, + _ioResult = 16, + _ioNamePtr = 18, + _ioVRefNum = 22, + _filler2 = 24, + _ioVolIndex = 28, + _ioVCrDate = 30, + _ioVLsMod = 34, + _ioVAtrb = 38, + _ioVNmFls = 40, + _ioVBitMap = 42, + _ioAllocPtr = 44, + _ioVNmAlBlks = 46, + _ioVAlBlkSiz = 48, + _ioVClpSiz = 52, + _ioAlBlSt = 56, + _ioVNxtCNID = 58, + _ioVFrBlk = 62, + _ioVSigWord = 64, + _ioVDrvInfo = 66, + _ioVDRefNum = 68, + _ioVFSID = 70, + _ioVBkUp = 72, + _ioVSeqNum = 76, + _ioVWrCnt = 78, + _ioVFilCnt = 82, + _ioVDirCnt = 86, + _ioVFndrInfo = 90, + }; + + + + uint16_t d0; + + uint32_t parm = cpuGetAReg(0); + + Log("%04x HGetVInfo(%08x)\n", trap, parm); + + return MacOS::nsvErr; + } + + #pragma mark - String Utilities uint16_t CmpString(uint16_t trap) diff --git a/toolbox/os.h b/toolbox/os.h index c49f67a..fc7aaa5 100644 --- a/toolbox/os.h +++ b/toolbox/os.h @@ -56,6 +56,7 @@ namespace OS uint16_t GetVol(uint16_t trap); uint16_t HGetVol(uint16_t trap); + uint16_t HGetVInfo(uint16_t trap); uint16_t SetVol(uint16_t trap); diff --git a/toolbox/os_fileinfo.cpp b/toolbox/os_fileinfo.cpp index a4e5fb7..badddab 100644 --- a/toolbox/os_fileinfo.cpp +++ b/toolbox/os_fileinfo.cpp @@ -52,6 +52,7 @@ #include "os_internal.h" #include "toolbox.h" #include "stackframe.h" +#include "fs_spec.h" using ToolBox::Log; @@ -115,6 +116,8 @@ namespace OS { _ioFlRPyLen = 68, _ioFlCrDat = 72, _ioFlMdDat = 76, + + _ioDirID = 48, }; @@ -145,11 +148,15 @@ namespace OS { } sname = ToolBox::ReadPString(ioNamePtr, true); + // a20c HGetFileInfo uses a the dir id + if (trap == 0xa20c) + { + uint32_t ioDirID = memoryReadLong(parm + _ioDirID); + sname = FSSpecManager::ExpandPath(sname, ioDirID); + } Log(" GetFileInfo(%s)\n", sname.c_str()); - // todo -- how are absolute, relative, etc paths handled... - struct stat st; @@ -237,6 +244,8 @@ namespace OS { _ioFlRPyLen = 68, _ioFlCrDat = 72, _ioFlMdDat = 76, + + _ioDirID = 48, }; @@ -254,13 +263,6 @@ namespace OS { //uint8_t ioFVersNum = memoryReadByte(parm + _ioFVersNum); //int16_t ioFDirIndex = memoryReadWord(parm + _ioFDirIndex); - // + 32 = finder data - 16 bytes. - - //uint32_t ioFlCrDat = memoryReadLong(parm + 72); - //uint32_t ioFlMdDat = memoryReadLong(parm + 76); - - // currently, only sets finder info. - if (!ioNamePtr) { d0 = MacOS::bdNamErr; @@ -269,8 +271,19 @@ namespace OS { } sname = ToolBox::ReadPString(ioNamePtr, true); + + // a20d HSetFileInfo uses a the dir id + if (trap == 0xa20d) + { + uint32_t ioDirID = memoryReadLong(parm + _ioDirID); + sname = FSSpecManager::ExpandPath(sname, ioDirID); + } + Log(" SetFileInfo(%s)\n", sname.c_str()); + + + // check if the file actually exists { struct stat st; diff --git a/toolbox/os_hfs_dispatch.cpp b/toolbox/os_hfs_dispatch.cpp index 8a45c4b..65dfe9b 100644 --- a/toolbox/os_hfs_dispatch.cpp +++ b/toolbox/os_hfs_dispatch.cpp @@ -52,7 +52,8 @@ #include "os_internal.h" #include "toolbox.h" #include "stackframe.h" - +#include "fs_spec.h" + using ToolBox::Log; using MacOS::macos_error_from_errno; @@ -187,9 +188,16 @@ namespace OS { } sname = ToolBox::ReadPString(ioNamePtr, true); + { + uint32_t ioDirID = memoryReadLong(parm + _ioDirID); + sname = FSSpecManager::ExpandPath(sname, ioDirID); + } Log(" PBGetCatInfo(%s)\n", sname.c_str()); + + + struct stat st; if (::stat(sname.c_str(), &st) < 0) @@ -341,6 +349,10 @@ namespace OS { } std::string sname = ToolBox::ReadPString(ioNamePtr, true); + { + uint32_t ioDirID = memoryReadLong(parm + _ioDirID); + sname = FSSpecManager::ExpandPath(sname, ioDirID); + } Log(" PBSetCatInfo(%s)\n", sname.c_str()); diff --git a/toolbox/os_highlevel.cpp b/toolbox/os_highlevel.cpp index 74738b2..8506906 100644 --- a/toolbox/os_highlevel.cpp +++ b/toolbox/os_highlevel.cpp @@ -182,6 +182,34 @@ namespace OS { return 0; } + uint16_t FSpOpenDF() + { + // FUNCTION FSpOpenDF (spec: FSSpec; permission: SignedByte; VAR refNum: Integer): OSErr; + + uint32_t spec; + uint8_t permission; + uint32_t refNum; + + StackFrame<10>(spec, permission, refNum); + + int parentID = memoryReadLong(spec + 2); + std::string sname = ToolBox::ReadPString(spec + 6, false); + + Log(" FSpOpenDF(%s, %02x, %04x)\n", sname.c_str(), permission, refNum); + + sname = OS::FSSpecManager::ExpandPath(sname, parentID); + if (sname.empty()) + { + return MacOS::dirNFErr; + } + + int fd = Internal::FDEntry::open(sname, permission, 0); + if (fd < 0) return fd; + + memoryWriteWord(fd, refNum); + + return 0; + } uint16_t FSpGetFInfo() { @@ -363,6 +391,9 @@ namespace OS { case 0x0001: d0 = FSMakeFSSpec(); break; + case 0x0002: + d0 = FSpOpenDF(); + break; case 0x0004: d0 = FSpCreate(); diff --git a/toolbox/pathnames.rl b/toolbox/pathnames.rl index 96c9a5e..22e755f 100644 --- a/toolbox/pathnames.rl +++ b/toolbox/pathnames.rl @@ -42,10 +42,10 @@ namespace { * file -> file * :directory:file -> directory/file * volume:directory -> /volume/directory + * : -> ./ * :: -> ../ * ::: -> ../../ * - * * To Unix: * file -> file * directory/file -> :directory:file @@ -77,6 +77,12 @@ namespace { }; ':' { + /* + if (ts == begin) + rv.append("./"); + else + rv.push_back('/'); + */ if (ts != begin) rv.push_back('/'); }; @@ -151,6 +157,8 @@ namespace ToolBox // no colon - no problem. if (!colon) return path; + // special case ":" -> "." + if (colon && path.length() == 1) return "."; const char *p = path.c_str(); const char *pe = p + path.length(); diff --git a/toolbox/rm.cpp b/toolbox/rm.cpp index e327f90..2d7e30c 100644 --- a/toolbox/rm.cpp +++ b/toolbox/rm.cpp @@ -108,6 +108,8 @@ namespace case 0x4b4f4445: // 'KODE' (Link 32-bit Startup) case 0x45525253: // 'ERRS' (PPCLink) case 0x63667267: // 'cfrg' (PPCLink) + case 0x44415441: // 'DATA' (MetroWorks tools) + case 0x54455854: // 'TEXT' (MetroWorks tools) return true; default: return false; @@ -602,7 +604,7 @@ namespace RM uint16_t vRefNum; uint32_t dirID; uint32_t fileName; - uint16_t permission; + uint8_t permission; sp = StackFrame<12>(vRefNum, dirID, fileName, permission); @@ -636,7 +638,7 @@ namespace RM uint32_t sp; uint32_t spec; - uint16_t permission; + uint8_t permission; sp = StackFrame<6>(spec, permission); diff --git a/toolbox/stackframe.h b/toolbox/stackframe.h index 9b72394..590d39a 100644 --- a/toolbox/stackframe.h +++ b/toolbox/stackframe.h @@ -26,6 +26,9 @@ template uint32_t StackFrame__(uint32_t sp, uint32_t &x, Args&&... args); template uint32_t StackFrame__(uint32_t sp, uint16_t &x, Args&&... args); +template +uint32_t StackFrame__(uint32_t sp, uint8_t &x, Args&&... args); + template uint32_t StackFrame__(uint32_t sp); @@ -55,6 +58,16 @@ uint32_t StackFrame__(uint32_t sp, uint16_t &x, Args&&... args) return StackFrame__(sp, std::forward(args)...); } + +template +uint32_t StackFrame__(uint32_t sp, uint8_t &x, Args&&... args) +{ + // byte pushes as 2 bytes with 1 garbage byte + x = memoryReadByte(sp + Offset - 2); + + return StackFrame__(sp, std::forward(args)...); +} + template uint32_t StackFrame(Args&&... args) { diff --git a/toolbox/toolbox.cpp b/toolbox/toolbox.cpp index ca2f0c1..b769992 100644 --- a/toolbox/toolbox.cpp +++ b/toolbox/toolbox.cpp @@ -119,6 +119,10 @@ namespace ToolBox { d0 = OS::Write(trap); break; + case 0xa207: + d0 = OS::HGetVInfo(trap); + break; + case 0xa008: // Create case 0xa208: // HCreate d0 = OS::Create(trap); @@ -277,6 +281,11 @@ namespace ToolBox { d0 = MM::HGetState(trap); break; + case 0xa06a: + d0 = MM::HSetState(trap); + break; + + // MoveHHi (h: Handle); case 0xa064: d0 = MM::MoveHHi(trap); @@ -289,7 +298,10 @@ namespace ToolBox { case 0xa9e3: d0 = MM::PtrToHand(trap); break; - + case 0xa9ef: + d0 = MM::PtrAndHand(trap); + break; + case 0xa11a: d0 = MM::GetZone(trap); break;