From 91e142446be56f11c79f6ccb5e3eb3de7274eda2 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 14 Dec 2014 19:51:49 -0500 Subject: [PATCH 01/11] MM::PurgeSpace call --- toolbox/mm.cpp | 16 ++++++++++++++++ toolbox/mm.h | 1 + toolbox/toolbox.cpp | 4 ++++ 3 files changed, 21 insertions(+) diff --git a/toolbox/mm.cpp b/toolbox/mm.cpp index 51ee9ed..d7ff43d 100644 --- a/toolbox/mm.cpp +++ b/toolbox/mm.cpp @@ -1469,4 +1469,20 @@ namespace MM return 0; } + uint32_t PurgeSpace(uint16_t trap) + { + // PROCEDURE PurgeSpace (VAR total: LongInt; VAR contig: LongInt); + + /* + * Registers on exit: + * A0 Maximum number of contiguous bytes after purge + * D0 Total free memory after purge + */ + + Log("%04x PurgeSpace()\n", trap); + + SetMemError(0); + cpuSetAReg(0, mplite_maxmem(&pool)); + return mplite_freemem(&pool); + } } diff --git a/toolbox/mm.h b/toolbox/mm.h index 2961e66..725b3fd 100644 --- a/toolbox/mm.h +++ b/toolbox/mm.h @@ -41,6 +41,7 @@ namespace MM uint32_t MaxBlock(uint16_t trap); uint32_t FreeMem(uint16_t trap); uint16_t ReserveMem(uint16_t trap); + uint32_t PurgeSpace(uint16_t trap); uint16_t DisposeHandle(uint16_t trap); diff --git a/toolbox/toolbox.cpp b/toolbox/toolbox.cpp index e5b4ee1..fe7657f 100644 --- a/toolbox/toolbox.cpp +++ b/toolbox/toolbox.cpp @@ -263,6 +263,10 @@ namespace ToolBox { d0 = MM::MaxApplZone(trap); break; + case 0xa162: + d0 = MM::PurgeSpace(trap); + break; + // ReadDateTime (VAR sees: LONGINT) : OSErr; case 0xa039: d0 = OS::ReadDateTime(trap); From f6f7964f819d67d3d323fb9fc8c0c8587de3412d Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 14 Dec 2014 19:52:08 -0500 Subject: [PATCH 02/11] OSDispatch call --- toolbox/mm.cpp | 21 +++++++++++++++++++++ toolbox/mm.h | 4 ++++ toolbox/toolbox.cpp | 27 +++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/toolbox/mm.cpp b/toolbox/mm.cpp index d7ff43d..4069dd5 100644 --- a/toolbox/mm.cpp +++ b/toolbox/mm.cpp @@ -40,6 +40,8 @@ #include #include +#include "stackframe.h" + using ToolBox::Log; namespace @@ -1485,4 +1487,23 @@ namespace MM cpuSetAReg(0, mplite_maxmem(&pool)); return mplite_freemem(&pool); } + + uint16_t TempMaxMem(void) + { + // FUNCTION TempMaxMem (VAR grow: Size): Size; + + uint32_t address; + + uint32_t sp = StackFrame<4>(address); + + Log(" TempMaxMem(%08x)\n", address); + + if (address) memoryWriteLong(0, address); + + ToolReturn<4>(sp, mplite_maxmem(&pool)); + SetMemError(0); // not sure if this is correct. oh well. + + return 0; + } + } diff --git a/toolbox/mm.h b/toolbox/mm.h index 725b3fd..e15a728 100644 --- a/toolbox/mm.h +++ b/toolbox/mm.h @@ -84,6 +84,10 @@ namespace MM uint16_t SetZone(uint16_t trap); uint16_t MaxApplZone(uint16_t trap); + + // OS Dispatch + + uint16_t TempMaxMem(void); } diff --git a/toolbox/toolbox.cpp b/toolbox/toolbox.cpp index fe7657f..6ba6ffb 100644 --- a/toolbox/toolbox.cpp +++ b/toolbox/toolbox.cpp @@ -42,6 +42,8 @@ #include "utility.h" #include "loader.h" #include "macos/traps.h" +#include "stackframe.h" + // yuck. TST.W d0 extern "C" void cpuSetFlagsNZ00NewW(UWO res); @@ -50,6 +52,27 @@ namespace ToolBox { bool Trace = false; + uint16_t OSDispatch(uint16_t trap) + { + uint16_t selector; + + + StackFrame<2>(selector); + Log("%04x OSDispatch(%04x)\n", trap, selector); + + switch(selector) + { + case 0x0015: + return MM::TempMaxMem(); + + default: + fprintf(stderr, "OSDispatch: selector %04x not implemented\n", + selector); + exit(1); + } + + } + void dispatch(uint16_t trap) { // todo -- check/remove extra bits for save a0, toolglue, etc. @@ -522,6 +545,10 @@ namespace ToolBox { d0 = Utility::BitTst(trap); break; + case 0xa88f: + d0 = OSDispatch(trap); + break; + default: fprintf(stderr, "Unsupported tool trap: %04x (%s)\n", trap, TrapName(trap)); From 294a0c901b6fd612b45c2dcb825071726a346521 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 14 Dec 2014 19:52:33 -0500 Subject: [PATCH 03/11] PBSetCatInfo (stub for now) --- toolbox/os_hfs_dispatch.cpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/toolbox/os_hfs_dispatch.cpp b/toolbox/os_hfs_dispatch.cpp index 4f07e86..bcbd35a 100644 --- a/toolbox/os_hfs_dispatch.cpp +++ b/toolbox/os_hfs_dispatch.cpp @@ -25,6 +25,7 @@ */ #include + #include #include #include #include @@ -223,6 +224,37 @@ namespace OS { return 0; } + + uint16_t PBSetCatInfo(uint32_t parm) + { + + uint16_t d0; + + // yuck. this is sort of a getdirent/stat call.... + + //uint32_t ioCompletion = memoryReadLong(parm + 12); + uint32_t ioNamePtr = memoryReadLong(parm + 18); + //uint16_t ioVRefNum = memoryReadWord(parm + 22); + //uint8_t ioFVersNum = memoryReadByte(parm + 26); + //int16_t ioFDirIndex = memoryReadWord(parm + 28); + + if (!ioNamePtr) + { + memoryWriteWord(MacOS::bdNamErr, parm + 16); + assert("PGSetCatInfo - no name."); + return MacOS::bdNamErr; + } + + std::string sname = ToolBox::ReadPString(ioNamePtr, true); + + Log(" PBSetCatInfo(%s)\n", sname.c_str()); + + // todo -- should set the finder info, I suppose. + + return 0; + } + + uint16_t PBOpenDF(uint32_t paramBlock) { Log(" PBOpenDF\n"); @@ -288,6 +320,10 @@ namespace OS { return PBGetCatInfo(paramBlock); break; + case 0x000a: + return PBSetCatInfo(paramBlock); + break; + case 0x001a: return PBHOpenDF(paramBlock); From 80be590e7609217c5ba7a7b70bfff8dd447dcbc4 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 14 Dec 2014 19:52:49 -0500 Subject: [PATCH 04/11] fgetenv / fsetenv --- toolbox/sane.cpp | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/toolbox/sane.cpp b/toolbox/sane.cpp index 1de42da..c7633ad 100644 --- a/toolbox/sane.cpp +++ b/toolbox/sane.cpp @@ -47,6 +47,11 @@ namespace SANE using std::to_string; + namespace { + + uint16_t Environment = 0; + } + // long double is an 80-bit extended with an extra 48-bits of 0 padding. typedef long double extended; @@ -667,6 +672,36 @@ using std::to_string; return 0; } + #pragma mark - environment + + uint16_t fgetenv(void) + { + uint32_t address; + uint16_t op; + + StackFrame<6>(address, op); + Log(" FGETENV(%08x)\n", address); + + memoryWriteWord(Environment, address); + return 0; + } + + uint16_t fsetenv(void) + { + uint32_t address; + uint16_t value; + uint16_t op; + + + StackFrame<6>(address, op); + value = memoryReadWord(address); + Log(" FSETENV(%08x (%04x))\n", address, value); + + Environment = value; + return 0; + } + + extern "C" void cpuSetFlagsAbs(UWO f); uint16_t fp68k(uint16_t trap) @@ -677,7 +712,7 @@ using std::to_string; sp = cpuGetAReg(7); op = memoryReadWord(sp); - Log("%04x FP68K(%04x)\n", op); + Log("%04x FP68K(%04x)\n", trap, op); cpuSetFlagsAbs(0x4); @@ -756,6 +791,8 @@ using std::to_string; break; + case 0x0003: return fgetenv(); + case 0x0001: return fsetenv(); } From d79f498cfdf72cf65a0ac04a732f6c31ada1e8ee Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Mon, 15 Dec 2014 08:55:06 -0500 Subject: [PATCH 05/11] increase default stack size for MrC --- bin/loader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/loader.h b/bin/loader.h index 7f61033..91eecaa 100644 --- a/bin/loader.h +++ b/bin/loader.h @@ -9,7 +9,7 @@ struct Settings { // command-line settings. uint32_t memorySize = 16 * 1024 * 1024; - uint32_t stackSize = 16 * 1024; + uint32_t stackSize = 32 * 1024; uint32_t machine = 68030; bool traceCPU = false; From 0b76b9266eaabb8df1fdf9080a51a050730d9d8f Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Mon, 15 Dec 2014 08:56:26 -0500 Subject: [PATCH 06/11] move stack to the top of the memory to make MrC's stack checks happy. --- bin/loader.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/bin/loader.cpp b/bin/loader.cpp index 34ade2f..49f5161 100644 --- a/bin/loader.cpp +++ b/bin/loader.cpp @@ -418,7 +418,7 @@ void GlobalInit() // so put stack at top of memory? // 0x0130 -- ApplLimit - memoryWriteLong(Flags.memorySize - 1, MacOS::ApplLimit); + memoryWriteLong(Flags.memorySize - Flags.stackSize - 1, MacOS::ApplLimit); } @@ -429,6 +429,7 @@ void CreateStack() uint32_t address; uint16_t error; +#if 0 Flags.stackSize = (Flags.stackSize + 3) & ~0x03; error = MM::Native::NewPtr(Flags.stackSize, true, address); @@ -437,7 +438,11 @@ void CreateStack() fprintf(stderr, "Unable to allocate stack (%08x bytes)\n", Flags.stackSize); exit(EX_CONFIG); } +#else + address = Flags.memorySize - Flags.stackSize; + +#endif Flags.stackRange.first = address; Flags.stackRange.second = address + Flags.stackSize; @@ -865,6 +870,9 @@ int main(int argc, char **argv) exit(EX_USAGE); } + Flags.stackSize = (Flags.stackSize + 0xff) & ~0xff; + Flags.memorySize = (Flags.memorySize + 0xff) & ~0xff; + if (Flags.stackSize < 0x100) { fprintf(stderr, "Invalid stack size\n"); @@ -877,6 +885,12 @@ int main(int argc, char **argv) exit(EX_CONFIG); } + if (Flags.stackSize >= Flags.memorySize) + { + fprintf(stderr, "Invalid stack/ram size\n"); + exit(EX_CONFIG); + } + std::string command(argv[0]); // InitMPW updates argv... @@ -903,7 +917,7 @@ int main(int argc, char **argv) // should we subtract memory from the top // for the stack vs allocating it? - MM::Init(Memory, MemorySize, kGlobalSize); + MM::Init(Memory, MemorySize - Flags.stackSize, kGlobalSize); OS::Init(); MPW::Init(argc, argv, defines); @@ -911,7 +925,6 @@ int main(int argc, char **argv) cpuStartup(); cpuSetModel(3,0); - CreateStack(); #ifdef LOADER_LOAD From 85e515bdeb6cbd6752ce9cb60708a67efcc4efb6 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Tue, 16 Dec 2014 13:07:37 -0500 Subject: [PATCH 07/11] split FSSpecManager out so RM can use it (HOpenResFile) --- toolbox/CMakeLists.txt | 1 + toolbox/fs_spec.cpp | 113 +++++++++++++++++++++++++++++++++++++++ toolbox/fs_spec.h | 42 +++++++++++++++ toolbox/os_highlevel.cpp | 107 +++--------------------------------- 4 files changed, 163 insertions(+), 100 deletions(-) create mode 100644 toolbox/fs_spec.cpp create mode 100644 toolbox/fs_spec.h diff --git a/toolbox/CMakeLists.txt b/toolbox/CMakeLists.txt index 0fafe2b..5412a4a 100644 --- a/toolbox/CMakeLists.txt +++ b/toolbox/CMakeLists.txt @@ -21,6 +21,7 @@ set(TOOLBOX_SRC saneparser.cpp pathnames.cpp utility.cpp + fs_spec.cpp ) diff --git a/toolbox/fs_spec.cpp b/toolbox/fs_spec.cpp new file mode 100644 index 0000000..22cd60d --- /dev/null +++ b/toolbox/fs_spec.cpp @@ -0,0 +1,113 @@ +#include "fs_spec.h" + +#include +#include + +namespace OS { + + std::deque FSSpecManager::_pathQueue; + + void FSSpecManager::Init() + { + static bool initialized = false; + + if (!initialized) + { + // "/" is item #1 + //IDForPath("/", true); + static std::string RootPath("/"); + + std::hash hasher; + size_t hash = hasher(RootPath); + _pathQueue.emplace_back(FSSpecManager::Entry(RootPath, hash)); + assert(_pathQueue.size() == 1); + initialized = true; + } + + } + + int32_t FSSpecManager::IDForPath(const std::string &path, bool insert) + { + /* + char buffer[PATH_MAX + 1]; + + char *cp = realpath(path.c_str(), buffer); + if (!cp) return -1; + + std::string s(cp); + */ + + std::hash hasher; + size_t hash = hasher(path); + + Init(); + + int i = 1; + for (const auto &e : _pathQueue) + { + if (e.hash == hash && e.path == path) return i; + ++i; + } + + if (!insert) return -1; + + _pathQueue.emplace_back(FSSpecManager::Entry(path, hash)); + return _pathQueue.size(); + } + + int32_t FSSpecManager::IDForPath(std::string &&path, bool insert) + { + /* + char buffer[PATH_MAX + 1]; + + char *cp = realpath(path.c_str(), buffer); + if (!cp) return -1; + + std::string s(cp); + */ + + std::hash hasher; + size_t hash = hasher(path); + + Init(); + + int i = 1; + for (const auto &e : _pathQueue) + { + if (e.hash == hash && e.path == path) return i; + ++i; + } + + if (!insert) return -1; + + _pathQueue.emplace_back(FSSpecManager::Entry(std::move(path), hash)); + return _pathQueue.size(); + } + + + const std::string &FSSpecManager::PathForID(int32_t id) + { + static std::string NullString; + + Init(); + + if (id < 1) return NullString; + if (id > _pathQueue.size()) return NullString; + + return _pathQueue[id - 1].path; + } + + std::string FSSpecManager::ExpandPath(const std::string &path, int32_t id) + { + if (path.length() && path[0] == '/') return path; + if (id == 0) return path; + + const std::string &dir = PathForID(id); + + if (dir.empty()) return dir; + return dir + path; + } + + + +} \ No newline at end of file diff --git a/toolbox/fs_spec.h b/toolbox/fs_spec.h new file mode 100644 index 0000000..20a8183 --- /dev/null +++ b/toolbox/fs_spec.h @@ -0,0 +1,42 @@ +#ifndef __fs_spec_h__ +#define __fs_spec_h__ + +#include +#include +#include + +namespace OS { + + class FSSpecManager + { + public: + + static std::string ExpandPath(const std::string &path, int32_t id); + static const std::string &PathForID(int32_t id); + static int32_t IDForPath(const std::string &path, bool insert = true); + static int32_t IDForPath(std::string &&path, bool insert = true); + + static void Init(); + + private: + + struct Entry + { + Entry(const std::string &p, size_t h) : + path(p), hash(h) + {} + + Entry(std::string &&p, size_t h) : + path(p), hash(h) + {} + + std::string path; + size_t hash = 0; + }; + + static std::deque _pathQueue; + }; + +} + +#endif \ No newline at end of file diff --git a/toolbox/os_highlevel.cpp b/toolbox/os_highlevel.cpp index 1bcc9fa..0ef432a 100644 --- a/toolbox/os_highlevel.cpp +++ b/toolbox/os_highlevel.cpp @@ -51,102 +51,11 @@ #include "os_internal.h" #include "toolbox.h" #include "stackframe.h" - +#include "fs_spec.h" using ToolBox::Log; using OS::Internal::errno_to_oserr; -namespace { - - // FSSpec garbage - class FSSpecManager - { - public: - - static const std::string &pathForID(int32_t id); - static int32_t idForPath(const std::string &path, bool insert = true); - - static void Init(); - - private: - - struct Entry - { - #if 0 - Entry(std::string &&p) : path(p), hash(std::hash(path)) - {} - Entry(const std::string &p) : path(p), hash(std::hash(path)) - {} - #endif - - Entry(const std::string &p, size_t h) : - path(p), hash(h) - {} - - Entry(std::string &&p, size_t h) : - path(p), hash(h) - {} - - std::string path; - size_t hash; - }; - - static std::deque _pathQueue; - }; - - std::deque FSSpecManager::_pathQueue; - - void FSSpecManager::Init() - { - static bool initialized = false; - - if (!initialized) - { - // "/" is item #1 - idForPath("/", true); - initialized = true; - } - - } - - int32_t FSSpecManager::idForPath(const std::string &path, bool insert) - { - /* - char buffer[PATH_MAX + 1]; - - char *cp = realpath(path.c_str(), buffer); - if (!cp) return -1; - - std::string s(cp); - */ - - std::hash hasher; - size_t hash = hasher(path); - - int i = 1; - for (const auto &e : _pathQueue) - { - if (e.hash == hash && e.path == path) return i; - ++i; - } - - if (!insert) return -1; - - _pathQueue.emplace_back(FSSpecManager::Entry(path, hash)); - return _pathQueue.size(); - } - - - const std::string &FSSpecManager::pathForID(int32_t id) - { - static std::string NullString; - if (id < 1) return NullString; - if (id > _pathQueue.size()) return NullString; - - return _pathQueue[id - 1].path; - } - -} namespace OS { @@ -190,7 +99,7 @@ namespace OS { { // SC uses dirID + relative path. - std::string root = FSSpecManager::pathForID(dirID); + std::string root = FSSpecManager::PathForID(dirID); if (root.empty()) { std::memset(memoryPointer(spec), 0, 8); @@ -239,7 +148,7 @@ namespace OS { path = path.substr(0, pos + 1); // include the / } - int parentID = FSSpecManager::idForPath(path, true); + int parentID = FSSpecManager::IDForPath(path, true); memoryWriteWord(vRefNum, spec + 0); memoryWriteLong(parentID, spec + 2); @@ -274,7 +183,7 @@ namespace OS { int parentID = memoryReadLong(spec + 2); std::string leaf = ToolBox::ReadPString(spec + 6, false); - std::string path = FSSpecManager::pathForID(parentID); + std::string path = FSSpecManager::PathForID(parentID); path += leaf; @@ -299,7 +208,7 @@ namespace OS { int parentID = memoryReadLong(spec + 2); std::string leaf = ToolBox::ReadPString(spec + 6, false); - std::string path = FSSpecManager::pathForID(parentID); + std::string path = FSSpecManager::PathForID(parentID); path += leaf; @@ -325,7 +234,7 @@ namespace OS { int parentID = memoryReadLong(spec + 2); std::string leaf = ToolBox::ReadPString(spec + 6, false); - std::string path = FSSpecManager::pathForID(parentID); + std::string path = FSSpecManager::PathForID(parentID); path += leaf; @@ -355,8 +264,6 @@ namespace OS { uint16_t selector; - FSSpecManager::Init(); - selector = cpuGetDReg(0) & 0xffff; Log("%04x HighLevelHFSDispatch(%04x)\n", trap, selector); @@ -436,7 +343,7 @@ namespace OS { if (ioDirID && !absolute) { - std::string dir = FSSpecManager::pathForID(ioDirID); + std::string dir = FSSpecManager::PathForID(ioDirID); if (dir.empty()) { d0 = MacOS::dirNFErr; From bd93788eefca604d7af25afa42f92ab22b861339 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Tue, 16 Dec 2014 13:07:51 -0500 Subject: [PATCH 08/11] RM::HOpenResFile --- toolbox/rm.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++++- toolbox/rm.h | 2 ++ toolbox/toolbox.cpp | 4 +++ 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/toolbox/rm.cpp b/toolbox/rm.cpp index efe2b73..6d75edb 100644 --- a/toolbox/rm.cpp +++ b/toolbox/rm.cpp @@ -45,7 +45,7 @@ #include #include "stackframe.h" - +#include "fs_spec.h" using ToolBox::Log; using namespace OS::Internal; @@ -494,6 +494,63 @@ namespace RM return SetResError(error); } + uint16_t HOpenResFile(uint16_t trap) + { + // FUNCTION HOpenResFile (vRefNum: Integer; dirID: LongInt; + // fileName: Str255; permission: SignedByte): Integer; + + ResFileRefNum refNum; + FSRef ref; + OSErr error; + + uint32_t sp; + + uint16_t vRefNum; + uint32_t dirID; + uint32_t fileName; + uint16_t permission; + + sp = StackFrame<12>(vRefNum, dirID, fileName, permission); + + std::string sname = ToolBox::ReadPString(fileName, true); + + Log("%04x HOpenResFile(%04x, %08x, %s, %04x)\n", + trap, vRefNum, dirID, sname.c_str(), permission); + + if (vRefNum) { + fprintf(stderr, "HOpenResFile: vRefNum not supported yet.\n"); + exit(1); + } + + sname = OS::FSSpecManager::ExpandPath(sname, dirID); + if (sname.empty()) + { + error = MacOS::dirNFErr; + ToolReturn<2>(sp, (uint16_t)-1); + return SetResError(error); + } + + error = ::FSPathMakeRef( (const UInt8 *)sname.c_str(), &ref, NULL); + if (error != noErr) + { + ToolReturn<2>(sp, (uint16_t)-1); + return SetResError(error); + } + + HFSUniStr255 fork = {0,{0}}; + ::FSGetResourceForkName(&fork); + + refNum = -1; + error = ::FSOpenResourceFile(&ref, + fork.length, + fork.unicode, + permission, + &refNum); + + ToolReturn<2>(sp, (uint16_t)refNum); + + return SetResError(0); + } uint16_t OpenRFPerm(uint16_t trap) diff --git a/toolbox/rm.h b/toolbox/rm.h index be4ddd0..8befbcb 100644 --- a/toolbox/rm.h +++ b/toolbox/rm.h @@ -25,6 +25,7 @@ namespace RM uint16_t OpenResFile(uint16_t trap); uint16_t OpenRFPerm(uint16_t trap); + uint16_t HOpenResFile(uint16_t trap); uint16_t SetResLoad(uint16_t trap); @@ -55,6 +56,7 @@ namespace RM uint16_t Count1Types(uint16_t trap); uint16_t Get1IndType(uint16_t trap); + } diff --git a/toolbox/toolbox.cpp b/toolbox/toolbox.cpp index 6ba6ffb..9abc98b 100644 --- a/toolbox/toolbox.cpp +++ b/toolbox/toolbox.cpp @@ -369,6 +369,10 @@ namespace ToolBox { d0 = RM::Get1IndType(trap); break; + case 0xa81a: + d0 = RM::HOpenResFile(trap); + break; + case 0xa81c: d0 = RM::Count1Types(trap); break; From 18b2e7ff67f94697d3d7785580b72aa0bc09bdf1 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Tue, 16 Dec 2014 13:47:33 -0500 Subject: [PATCH 09/11] ReadXPRam call (DumpXCOFF) --- toolbox/os.cpp | 16 ++++++++++++++++ toolbox/os.h | 4 ++++ toolbox/toolbox.cpp | 4 ++++ 3 files changed, 24 insertions(+) diff --git a/toolbox/os.cpp b/toolbox/os.cpp index 4ba6043..4d76ee1 100644 --- a/toolbox/os.cpp +++ b/toolbox/os.cpp @@ -1180,5 +1180,21 @@ namespace OS } + #pragma mark XP - RAM + + // these are not particularly documented. + uint16_t ReadXPRam(uint16_t trap) + { + // a0 = address? + // d0 = count? item? + Log("%04x ReadXPRam()\n", trap); + return MacOS::prWrErr; + } + + uint16_t WriteXPRam(uint16_t trap) + { + Log("%04x WriteXPRam()\n", trap); + return MacOS::prWrErr; + } } \ No newline at end of file diff --git a/toolbox/os.h b/toolbox/os.h index 08c1d39..4e75094 100644 --- a/toolbox/os.h +++ b/toolbox/os.h @@ -94,6 +94,10 @@ namespace OS #pragma mark - Gestalt Manager uint16_t Gestalt(uint16_t trap); + #pragma mark - XP Ram + uint16_t ReadXPRam(uint16_t trap); + uint16_t WriteXPRam(uint16_t trap); + } #endif diff --git a/toolbox/toolbox.cpp b/toolbox/toolbox.cpp index 9abc98b..60f9564 100644 --- a/toolbox/toolbox.cpp +++ b/toolbox/toolbox.cpp @@ -155,6 +155,10 @@ namespace ToolBox { d0 = OS::SetFPos(trap); break; + case 0xa051: + d0 = OS::ReadXPRam(trap); + break; + case 0xa060: d0 = OS::FSDispatch(trap); break; From 325c1c5850f4974e2bc1469ff8d66610bb83d4a9 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Tue, 16 Dec 2014 17:35:49 -0500 Subject: [PATCH 10/11] PBSetCatInfo now sets finder info. PBGetCatInfo now uses nice enums. --- toolbox/os_hfs_dispatch.cpp | 214 ++++++++++++++++++++++++++++-------- 1 file changed, 168 insertions(+), 46 deletions(-) diff --git a/toolbox/os_hfs_dispatch.cpp b/toolbox/os_hfs_dispatch.cpp index bcbd35a..1700063 100644 --- a/toolbox/os_hfs_dispatch.cpp +++ b/toolbox/os_hfs_dispatch.cpp @@ -119,15 +119,61 @@ namespace OS { uint16_t PBGetCatInfo(uint32_t parm) { + + enum { // FileParam + _qLink = 0, + _qType = 4, + _ioTrap = 6, + _ioCmdAddr = 8, + _ioCompletion = 12, + _ioResult = 16, + _ioNamePtr = 18, + _ioVRefNum = 22, + _ioFRefNum = 24, + _ioFVersNum = 26, + _filler1 = 27, + _ioFDirIndex = 28, + _ioFlAttrib = 30, + _ioACUser = 31, + + /* HFileInfo */ + _ioFlFndrInfo = 32, + _ioDirID = 48, + _ioFlStBlk = 52, + _ioFlLgLen = 54, + _ioFlPyLen = 58, + _ioFlRStBlk = 62, + _ioFlRLgLen = 64, + _ioFlRPyLen = 68, + _ioFlCrDat = 72, + _ioFlMdDat = 76, + _ioFlBkDat = 80, + _ioFlXFndrInfo = 84, + _ioFlParID = 100, + _ioFlClpSiz = 104, + + /* DirInfo */ + _ioDrUsrWds = 32, + _ioDrDirID = 48, + _ioDrNmFls = 52, + _filler3 = 54, + _ioDrCrDat = 72, + _ioDrMdDat = 76, + _ioDrBkDat = 80, + _ioDrFndrInfo = 84, + _ioDrParID = 100, + }; + + uint16_t d0; // yuck. this is sort of a getdirent/stat call.... - //uint32_t ioCompletion = memoryReadLong(parm + 12); - uint32_t ioNamePtr = memoryReadLong(parm + 18); - //uint16_t ioVRefNum = memoryReadWord(parm + 22); - //uint8_t ioFVersNum = memoryReadByte(parm + 26); - int16_t ioFDirIndex = memoryReadWord(parm + 28); + //uint32_t ioCompletion = memoryReadLong(parm + _ioCompletion); + uint32_t ioNamePtr = memoryReadLong(parm + _ioNamePtr); + //uint16_t ioVRefNum = memoryReadWord(parm + _ioVRefNum); + //uint8_t ioFVersNum = memoryReadByte(parm + _ioFVersNum); + int16_t ioFDirIndex = memoryReadWord(parm + _ioFDirIndex); if (ioFDirIndex <= 0) { @@ -136,7 +182,7 @@ namespace OS { if (!ioNamePtr) { - memoryWriteWord(MacOS::bdNamErr, parm + 16); + memoryWriteWord(MacOS::bdNamErr, parm + _ioResult); return MacOS::bdNamErr; } @@ -150,68 +196,74 @@ namespace OS { { d0 = errno_to_oserr(errno); - memoryWriteWord(d0, parm + 16); + memoryWriteWord(d0, parm + _ioResult); return d0; } if (S_ISDIR(st.st_mode)) { // bit 4 - is a directory. - memoryWriteByte(1 << 4, parm + 30); // ioFlAttrib - memoryWriteByte(0, parm + 31); //ioACUser + memoryWriteByte(1 << 4, parm + _ioFlAttrib); + memoryWriteByte(0, parm + _ioACUser); - std::memset(memoryPointer(parm + 32), 0, 16); // DInfo - memoryWriteLong(0, parm + 48); // ioDrDirID - memoryWriteWord(0, parm + 52); // ioDrNmFls - # of files in dir + std::memset(memoryPointer(parm + _ioDrUsrWds), 0, 16); // DInfo + memoryWriteLong(0, parm + _ioDrDirID); - memoryWriteLong(UnixToMac(st.st_birthtime), parm + 60); // create - memoryWriteLong(UnixToMac(st.st_mtime), parm + 64); // modify - memoryWriteLong(UnixToMac(st.st_mtime), parm + 68); // backup + // the links count should be ~= number of dirents ( +2 for . and ..) + int links = st.st_nlink - 2; + if (links < 0) links = 0; + if (links > 65535) links = 65535; - std::memset(memoryPointer(parm + 72), 0, 16); // DXInfo - memoryWriteLong(0, parm + 88); // ioDrParID + memoryWriteWord(links, parm + _ioDrNmFls); // ioDrNmFls - # of files in dir + + memoryWriteLong(UnixToMac(st.st_birthtime), parm + _ioDrCrDat); // create + memoryWriteLong(UnixToMac(st.st_mtime), parm + _ioDrMdDat); // modify + memoryWriteLong(UnixToMac(st.st_mtime), parm + _ioDrBkDat); // backup + + std::memset(memoryPointer(parm + _ioDrFndrInfo), 0, 16); // DXInfo + memoryWriteLong(0, parm + _ioDrParID); } else { - memoryWriteByte(0, parm + 30); + memoryWriteByte(0, parm + _ioFlAttrib); - memoryWriteByte(0, parm + 31); //ioACUser - Internal::GetFinderInfo(sname, memoryPointer(parm + 32), false); // finder info - memoryWriteLong(0, parm + 48); // ioDrDirID - memoryWriteWord(0, parm + 52); // ioFlStBlk - memoryWriteLong(st.st_size, parm + 54); // ioFlLgLen - memoryWriteLong(st.st_size, parm + 58); // ioFlPyLen + memoryWriteByte(0, parm + _ioACUser); + Internal::GetFinderInfo(sname, memoryPointer(parm + _ioFlFndrInfo), false); // finder info + memoryWriteLong(0, parm + _ioDirID); + memoryWriteWord(0, parm + _ioFlStBlk); + memoryWriteLong(st.st_size, parm + _ioFlLgLen); + memoryWriteLong(st.st_size, parm + _ioFlPyLen); // resource info... below - memoryWriteLong(UnixToMac(st.st_birthtime), parm + 72); // create - memoryWriteLong(UnixToMac(st.st_mtime), parm + 76); // modify - memoryWriteLong(UnixToMac(st.st_mtime), parm + 80); // backup + memoryWriteLong(UnixToMac(st.st_birthtime), parm + _ioFlCrDat); // create + memoryWriteLong(UnixToMac(st.st_mtime), parm + _ioFlMdDat); // modify + memoryWriteLong(UnixToMac(st.st_mtime), parm + _ioFlBkDat); // backup - std::memset(memoryPointer(parm + 84), 0, 16); // FXInfo + std::memset(memoryPointer(parm + _ioFlXFndrInfo), 0, 16); // FXInfo - memoryWriteWord(0, parm + 100); // ioFlParID - memoryWriteWord(0, parm + 104); // ioFlClpSiz + memoryWriteWord(0, parm + _ioFlParID); + memoryWriteWord(0, parm + _ioFlClpSiz); sname.append(_PATH_RSRCFORKSPEC); if (::stat(sname.c_str(), &st) >= 0) { - memoryWriteWord(0, parm + 62); - memoryWriteLong(st.st_size, parm + 64); - memoryWriteLong(st.st_size, parm + 68); + memoryWriteWord(0, parm + _ioFlRStBlk); + memoryWriteLong(st.st_size, parm + _ioFlRLgLen); + memoryWriteLong(st.st_size, parm + _ioFlRPyLen); } else { - memoryWriteWord(0, parm + 62); - memoryWriteLong(0, parm + 64); - memoryWriteLong(0, parm + 68); + memoryWriteWord(0, parm + _ioFlRStBlk); + memoryWriteLong(0, parm + _ioFlRLgLen); + memoryWriteLong(0, parm + _ioFlRPyLen); } } // no error. - memoryWriteWord(0, parm + 16); + memoryWriteWord(0, parm + _ioResult); return 0; } @@ -228,19 +280,62 @@ namespace OS { uint16_t PBSetCatInfo(uint32_t parm) { + enum { // FileParam + _qLink = 0, + _qType = 4, + _ioTrap = 6, + _ioCmdAddr = 8, + _ioCompletion = 12, + _ioResult = 16, + _ioNamePtr = 18, + _ioVRefNum = 22, + _ioFRefNum = 24, + _ioFVersNum = 26, + _filler1 = 27, + _ioFDirIndex = 28, + _ioFlAttrib = 30, + _ioACUser = 31, + + /* HFileInfo */ + _ioFlFndrInfo = 32, + _ioDirID = 48, + _ioFlStBlk = 52, + _ioFlLgLen = 54, + _ioFlPyLen = 58, + _ioFlRStBlk = 62, + _ioFlRLgLen = 64, + _ioFlRPyLen = 68, + _ioFlCrDat = 72, + _ioFlMdDat = 76, + _ioFlBkDat = 80, + _ioFlXFndrInfo = 84, + _ioFlParID = 100, + _ioFlClpSiz = 104, + + /* DirInfo */ + _ioDrUsrWds = 32, + _ioDrDirID = 48, + _ioDrNmFls = 52, + _filler3 = 54, + _ioDrCrDat = 72, + _ioDrMdDat = 76, + _ioDrBkDat = 80, + _ioDrFndrInfo = 84, + _ioDrParID = 100, + }; + uint16_t d0; - // yuck. this is sort of a getdirent/stat call.... - //uint32_t ioCompletion = memoryReadLong(parm + 12); - uint32_t ioNamePtr = memoryReadLong(parm + 18); - //uint16_t ioVRefNum = memoryReadWord(parm + 22); - //uint8_t ioFVersNum = memoryReadByte(parm + 26); - //int16_t ioFDirIndex = memoryReadWord(parm + 28); + //uint32_t ioCompletion = memoryReadLong(parm + _ioCompletion); + uint32_t ioNamePtr = memoryReadLong(parm + _ioNamePtr); + //uint16_t ioVRefNum = memoryReadWord(parm + _ioVRefNum); + //uint8_t ioFVersNum = memoryReadByte(parm + _ioFVersNum); + //int16_t ioFDirIndex = memoryReadWord(parm + _ioFDirIndex); if (!ioNamePtr) { - memoryWriteWord(MacOS::bdNamErr, parm + 16); + memoryWriteWord(MacOS::bdNamErr, parm + _ioResult); assert("PGSetCatInfo - no name."); return MacOS::bdNamErr; } @@ -249,9 +344,36 @@ namespace OS { Log(" PBSetCatInfo(%s)\n", sname.c_str()); - // todo -- should set the finder info, I suppose. - return 0; + // check if the file actually exists + { + struct stat st; + int ok; + + ok = ::stat(sname.c_str(), &st); + if (ok < 0) + { + d0 = errno_to_oserr(errno); + memoryWriteWord(d0, parm + _ioResult); + return d0; + } + + // just nop if it's a directory. + if (S_ISDIR(st.st_mode)) + { + d0 = 0; + memoryWriteWord(d0, parm + _ioResult); + return d0; + } + } + + + // set the finder info. could also call utimes, I suppose. + d0 = Internal::SetFinderInfo(sname, memoryPointer(parm + _ioFlFndrInfo), false); + + memoryWriteWord(d0, parm + _ioResult); + return d0; + } From 6a8a30df5aaccedd43bfbca8ee5b9e9279685539 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Wed, 17 Dec 2014 07:53:25 -0500 Subject: [PATCH 11/11] . --- toolbox/os_hfs_dispatch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolbox/os_hfs_dispatch.cpp b/toolbox/os_hfs_dispatch.cpp index 1700063..a7aba7e 100644 --- a/toolbox/os_hfs_dispatch.cpp +++ b/toolbox/os_hfs_dispatch.cpp @@ -368,7 +368,7 @@ namespace OS { } - // set the finder info. could also call utimes, I suppose. + // set the finder info. could also call utimes or setattrlist, I suppose. d0 = Internal::SetFinderInfo(sname, memoryPointer(parm + _ioFlFndrInfo), false); memoryWriteWord(d0, parm + _ioResult);