Merge branch 'DumpPEF'

support for MrC, MrCPP, DumpPEF (?) and DumpXCOFF.
This commit is contained in:
Kelvin Sherlock 2014-12-17 13:07:18 -05:00
commit eda186e9ff
15 changed files with 574 additions and 143 deletions

View File

@ -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

View File

@ -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;

View File

@ -21,6 +21,7 @@ set(TOOLBOX_SRC
saneparser.cpp
pathnames.cpp
utility.cpp
fs_spec.cpp
)

113
toolbox/fs_spec.cpp Normal file
View 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
View 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

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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));