mirror of
https://github.com/ksherlock/mpw.git
synced 2025-01-08 07:31:45 +00:00
Merge branch 'DumpPEF'
support for MrC, MrCPP, DumpPEF (?) and DumpXCOFF.
This commit is contained in:
commit
eda186e9ff
@ -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
|
||||
|
@ -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;
|
||||
|
@ -21,6 +21,7 @@ set(TOOLBOX_SRC
|
||||
saneparser.cpp
|
||||
pathnames.cpp
|
||||
utility.cpp
|
||||
fs_spec.cpp
|
||||
)
|
||||
|
||||
|
||||
|
113
toolbox/fs_spec.cpp
Normal file
113
toolbox/fs_spec.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
#include "fs_spec.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
namespace OS {
|
||||
|
||||
std::deque<FSSpecManager::Entry> FSSpecManager::_pathQueue;
|
||||
|
||||
void FSSpecManager::Init()
|
||||
{
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
// "/" is item #1
|
||||
//IDForPath("/", true);
|
||||
static std::string RootPath("/");
|
||||
|
||||
std::hash<std::string> 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<std::string> 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<std::string> 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
42
toolbox/fs_spec.h
Normal file
42
toolbox/fs_spec.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef __fs_spec_h__
|
||||
#define __fs_spec_h__
|
||||
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
#include <deque>
|
||||
|
||||
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<Entry> _pathQueue;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -40,6 +40,8 @@
|
||||
#include <macos/sysequ.h>
|
||||
#include <macos/errors.h>
|
||||
|
||||
#include "stackframe.h"
|
||||
|
||||
using ToolBox::Log;
|
||||
|
||||
namespace
|
||||
@ -1469,4 +1471,39 @@ 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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
@ -83,6 +84,10 @@ namespace MM
|
||||
uint16_t SetZone(uint16_t trap);
|
||||
|
||||
uint16_t MaxApplZone(uint16_t trap);
|
||||
|
||||
// OS Dispatch
|
||||
|
||||
uint16_t TempMaxMem(void);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -25,6 +25,7 @@
|
||||
*/
|
||||
|
||||
#include <cerrno>
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
#include <ctime>
|
||||
#include <algorithm>
|
||||
@ -118,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)
|
||||
{
|
||||
@ -135,7 +182,7 @@ namespace OS {
|
||||
|
||||
if (!ioNamePtr)
|
||||
{
|
||||
memoryWriteWord(MacOS::bdNamErr, parm + 16);
|
||||
memoryWriteWord(MacOS::bdNamErr, parm + _ioResult);
|
||||
return MacOS::bdNamErr;
|
||||
}
|
||||
|
||||
@ -149,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;
|
||||
}
|
||||
|
||||
@ -223,6 +276,107 @@ namespace OS {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
//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 + _ioResult);
|
||||
assert("PGSetCatInfo - no name.");
|
||||
return MacOS::bdNamErr;
|
||||
}
|
||||
|
||||
std::string sname = ToolBox::ReadPString(ioNamePtr, true);
|
||||
|
||||
Log(" PBSetCatInfo(%s)\n", sname.c_str());
|
||||
|
||||
|
||||
// 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 or setattrlist, I suppose.
|
||||
d0 = Internal::SetFinderInfo(sname, memoryPointer(parm + _ioFlFndrInfo), false);
|
||||
|
||||
memoryWriteWord(d0, parm + _ioResult);
|
||||
return d0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
uint16_t PBOpenDF(uint32_t paramBlock)
|
||||
{
|
||||
Log(" PBOpenDF\n");
|
||||
@ -288,6 +442,10 @@ namespace OS {
|
||||
return PBGetCatInfo(paramBlock);
|
||||
break;
|
||||
|
||||
case 0x000a:
|
||||
return PBSetCatInfo(paramBlock);
|
||||
break;
|
||||
|
||||
case 0x001a:
|
||||
return PBHOpenDF(paramBlock);
|
||||
|
||||
|
@ -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<Entry> _pathQueue;
|
||||
};
|
||||
|
||||
std::deque<FSSpecManager::Entry> 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<std::string> 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;
|
||||
|
@ -45,7 +45,7 @@
|
||||
#include <macos/errors.h>
|
||||
|
||||
#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)
|
||||
|
@ -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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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.
|
||||
@ -132,6 +155,10 @@ namespace ToolBox {
|
||||
d0 = OS::SetFPos(trap);
|
||||
break;
|
||||
|
||||
case 0xa051:
|
||||
d0 = OS::ReadXPRam(trap);
|
||||
break;
|
||||
|
||||
case 0xa060:
|
||||
d0 = OS::FSDispatch(trap);
|
||||
break;
|
||||
@ -263,6 +290,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);
|
||||
@ -342,6 +373,10 @@ namespace ToolBox {
|
||||
d0 = RM::Get1IndType(trap);
|
||||
break;
|
||||
|
||||
case 0xa81a:
|
||||
d0 = RM::HOpenResFile(trap);
|
||||
break;
|
||||
|
||||
case 0xa81c:
|
||||
d0 = RM::Count1Types(trap);
|
||||
break;
|
||||
@ -518,6 +553,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));
|
||||
|
Loading…
Reference in New Issue
Block a user