diff --git a/toolbox/CMakeLists.txt b/toolbox/CMakeLists.txt index 51ed02b..b9a3dc8 100644 --- a/toolbox/CMakeLists.txt +++ b/toolbox/CMakeLists.txt @@ -12,6 +12,7 @@ set(TOOLBOX_SRC os_internal.cpp os_hfs_dispatch.cpp os_highlevel.cpp + os_alias.cpp qd.cpp sane.cpp utility.cpp diff --git a/toolbox/os.h b/toolbox/os.h index f56e3e4..346803e 100644 --- a/toolbox/os.h +++ b/toolbox/os.h @@ -49,6 +49,7 @@ namespace OS uint16_t SetFPos(uint16_t trap); uint16_t GetVol(uint16_t trap); + uint16_t HGetVol(uint16_t trap); uint16_t Open(uint16_t trap); uint16_t Read(uint16_t trap); @@ -72,6 +73,12 @@ namespace OS uint16_t GetToolTrapAddress(uint16_t trap); uint16_t GetOSTrapAddress(uint16_t trap); + + #pragma mark - Alias Manager + + uint16_t ResolveAliasFile(); + uint16_t AliasDispatch(uint16_t trap); + } #endif diff --git a/toolbox/os_alias.cpp b/toolbox/os_alias.cpp new file mode 100644 index 0000000..8e942eb --- /dev/null +++ b/toolbox/os_alias.cpp @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "os.h" +#include "os_internal.h" +#include "toolbox.h" +#include "stackframe.h" + +using ToolBox::Log; +using namespace ToolBox::Errors; + +namespace OS { + + + + + uint16_t AliasDispatch(uint16_t trap) + { + + uint16_t selector = cpuGetDReg(0); + + Log("%04x AliasDispatch($%04x)\n", trap, selector); + + switch (selector) + { + + case 0x000c: + return ResolveAliasFile(); + break; + + default: + fprintf(stderr, "AliasDispatch: selector $%04x not implemented\n", + selector); + exit(1); + } + + + return 0; + } + +} \ No newline at end of file diff --git a/toolbox/os_highlevel.cpp b/toolbox/os_highlevel.cpp index 252d0be..05042e9 100644 --- a/toolbox/os_highlevel.cpp +++ b/toolbox/os_highlevel.cpp @@ -244,6 +244,44 @@ namespace OS { } + + uint16_t ResolveAliasFile() + { + uint32_t spec; + uint16_t resolveAliasChains; + uint32_t targetIsFolder; + uint32_t wasAliased; + + StackFrame<14>(spec, resolveAliasChains, targetIsFolder, wasAliased); + + int parentID = memoryReadLong(spec + 2); + + std::string leaf = ToolBox::ReadPString(spec + 6, false); + std::string path = FSSpecManager::pathForID(parentID); + + path += leaf; + + Log(" ResolveAliasFile(%s)\n", path.c_str()); + + struct stat st; + int rv; + + rv = ::stat(path.c_str(), &st); + if (rv < 0) return errno_to_oserr(errno); + + if (targetIsFolder) + { + memoryWriteWord(S_ISDIR(st.st_mode) ? 1 : 0, targetIsFolder); + } + + // don't bother pretending a soft link is an alias. + if (wasAliased) memoryWriteWord(0, wasAliased); + + return 0; + } + + + uint16_t HighLevelHFSDispatch(uint16_t trap) { @@ -274,6 +312,38 @@ namespace OS { } + uint16_t HGetVol(uint16_t trap) + { + uint32_t parm = cpuGetAReg(0); + + Log("%04x HGetVol(%08x)\n", trap, parm); + + //uint32_t ioCompletion = memoryReadLong(parm + 12); + uint32_t namePtr = memoryReadLong(parm + 18); + + // ioResult + memoryWriteWord(0, parm + 16); + // ioVRefNum + memoryWriteWord(0, parm + 22); + + // ioWDProcID + memoryWriteLong(0, parm + 28); + + // ioWDVRefNum + memoryWriteWord(0, parm + 32); + + + // todo -- this should create an FSSpec entry for + // the current wd and return the id. + // (FSMakeSpec handles 0 as a dir, so ok for now) + // ioWDDirID + memoryWriteLong(0, parm + 48); + + std::string tmp = "MacOS"; + ToolBox::WritePString(namePtr, tmp); + + return 0; + } diff --git a/toolbox/toolbox.cpp b/toolbox/toolbox.cpp index b689ff6..0a8bcf9 100644 --- a/toolbox/toolbox.cpp +++ b/toolbox/toolbox.cpp @@ -76,6 +76,10 @@ namespace ToolBox { d0 = OS::GetVol(trap); break; + case 0xa214: + d0 = OS::HGetVol(trap); + break; + case 0xa044: d0 = OS::SetFPos(trap); break; @@ -98,6 +102,10 @@ namespace ToolBox { d0 = OS::GetOSTrapAddress(trap); break; + case 0xA823: + d0 = OS::AliasDispatch(trap); + break; + // SetPtrSize (p: Ptr; newSize: Size); case 0xa020: