mirror of
https://github.com/ksherlock/mpw.git
synced 2024-06-07 11:29:29 +00:00
more native functions.
This commit is contained in:
parent
a4fb750886
commit
72c6cb043d
233
toolbox/mm.cpp
233
toolbox/mm.cpp
|
@ -331,7 +331,7 @@ namespace MM
|
|||
}
|
||||
|
||||
/* create a NULL handle (for resource manager) */
|
||||
tool_return<uint32_t> NewHandle()
|
||||
tool_return<uint32_t> NewEmptyHandle()
|
||||
{
|
||||
uint32_t hh;
|
||||
|
||||
|
@ -370,14 +370,6 @@ namespace MM
|
|||
hh = HandleQueue.front();
|
||||
HandleQueue.pop_front();
|
||||
|
||||
ptr = nullptr;
|
||||
|
||||
// todo -- size 0 should have a ptr to differentiate
|
||||
// from purged.
|
||||
|
||||
// PPCLink calls NewHandle(0) but expects a valid pointer
|
||||
// Assertion failed: *fHandle != NULL
|
||||
|
||||
ptr = (uint8_t *)mplite_malloc(&pool, size ? size : 1);
|
||||
if (!ptr)
|
||||
{
|
||||
|
@ -399,6 +391,46 @@ namespace MM
|
|||
}
|
||||
|
||||
|
||||
tool_return<hp> NewHandleWithAttr(uint32_t size, unsigned attr)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
uint32_t hh;
|
||||
|
||||
uint32_t handle = 0;
|
||||
uint32_t mcptr = 0;
|
||||
|
||||
if (!HandleQueue.size())
|
||||
{
|
||||
if (!alloc_handle_block())
|
||||
{
|
||||
return SetMemError(MacOS::memFullErr);
|
||||
}
|
||||
}
|
||||
|
||||
hh = HandleQueue.front();
|
||||
HandleQueue.pop_front();
|
||||
|
||||
ptr = (uint8_t *)mplite_malloc(&pool, size ? size : 1);
|
||||
if (!ptr)
|
||||
{
|
||||
HandleQueue.push_back(hh);
|
||||
return SetMemError(MacOS::memFullErr);
|
||||
}
|
||||
mcptr = ptr - Memory;
|
||||
|
||||
// always clear it.
|
||||
std::memset(ptr, 0, size);
|
||||
|
||||
// need a handle -> ptr map?
|
||||
HandleMap.emplace(std::make_pair(hh, HandleInfo(mcptr, size, attr)));
|
||||
|
||||
memoryWriteLong(mcptr, hh);
|
||||
handle = hh;
|
||||
SetMemError(0);
|
||||
return hp{handle, mcptr};
|
||||
}
|
||||
|
||||
|
||||
tool_return<void> DisposeHandle(uint32_t handle)
|
||||
{
|
||||
auto iter = HandleMap.find(handle);
|
||||
|
@ -423,8 +455,9 @@ namespace MM
|
|||
|
||||
|
||||
|
||||
tool_return<void> ReallocHandle(uint32_t handle, uint32_t logicalSize)
|
||||
tool_return<uint32_t> ReallocHandle(uint32_t handle, uint32_t logicalSize)
|
||||
{
|
||||
if (handle == 0) return SetMemError(MacOS::nilHandleErr);
|
||||
|
||||
auto iter = HandleMap.find(handle);
|
||||
|
||||
|
@ -434,18 +467,15 @@ namespace MM
|
|||
|
||||
if (info.locked) return SetMemError(MacOS::memLockedErr);
|
||||
|
||||
|
||||
uint32_t mcptr = 0;
|
||||
|
||||
if (logicalSize)
|
||||
{
|
||||
// todo -- purge & retry on failure.
|
||||
// todo -- purge & retry on failure.
|
||||
|
||||
void *address = mplite_malloc(&pool, logicalSize);
|
||||
if (!address) return SetMemError(MacOS::memFullErr);
|
||||
void *address = mplite_malloc(&pool, logicalSize ? logicalSize : 1);
|
||||
if (!address) return SetMemError(MacOS::memFullErr);
|
||||
|
||||
mcptr = (uint8_t *)address - Memory;
|
||||
}
|
||||
std::memset(address, 0, logicalSize);
|
||||
mcptr = (uint8_t *)address - Memory;
|
||||
|
||||
// the handle is not altered in the event of an error.
|
||||
if (info.address)
|
||||
|
@ -458,16 +488,46 @@ namespace MM
|
|||
info.address = mcptr;
|
||||
info.size = logicalSize;
|
||||
|
||||
// "The new block is unlocked and unpurgeable."
|
||||
info.locked = false;
|
||||
info.purgeable = false;
|
||||
|
||||
|
||||
memoryWriteLong(mcptr, handle);
|
||||
|
||||
// lock? clear purged flag?
|
||||
|
||||
return MacOS::noErr;
|
||||
return mcptr;
|
||||
|
||||
}
|
||||
|
||||
/* returns true if memory has been purged. */
|
||||
bool Purge(uint32_t but_not_this_handle = 0) {
|
||||
bool rv = false;
|
||||
|
||||
tool_return<void> SetHandleSize(uint32_t handle, uint32_t newSize)
|
||||
for (auto & kv : HandleMap)
|
||||
{
|
||||
uint32_t ph = kv.first;
|
||||
auto &info = kv.second;
|
||||
|
||||
if (info.address == 0) continue;
|
||||
if (ph == but_not_this_handle) continue;
|
||||
|
||||
if (info.purgeable && !info.locked)
|
||||
{
|
||||
mplite_free(&pool, Memory + info.address);
|
||||
info.size = 0;
|
||||
info.address = 0;
|
||||
|
||||
// also need to update memory
|
||||
memoryWriteLong(0, ph);
|
||||
|
||||
rv = true;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
tool_return<uint32_t> SetHandleSize(uint32_t handle, uint32_t newSize)
|
||||
{
|
||||
if (handle == 0) return SetMemError(MacOS::nilHandleErr);
|
||||
|
||||
|
@ -503,7 +563,9 @@ namespace MM
|
|||
info.size = 0;
|
||||
|
||||
memoryWriteLong(info.address, handle);
|
||||
return SetMemError(0);
|
||||
SetMemError(0);
|
||||
return info.address;
|
||||
|
||||
}
|
||||
|
||||
// 2. - resizing from 0.
|
||||
|
@ -520,7 +582,8 @@ namespace MM
|
|||
info.size = newSize;
|
||||
|
||||
memoryWriteLong(info.address, handle);
|
||||
return SetMemError(0);
|
||||
SetMemError(0);
|
||||
return info.address;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < 2; ++i)
|
||||
|
@ -532,7 +595,8 @@ namespace MM
|
|||
if (mplite_resize(&pool, ptr, mplite_roundup(&pool, newSize)) == MPLITE_OK)
|
||||
{
|
||||
info.size = newSize;
|
||||
return SetMemError(0);
|
||||
SetMemError(0);
|
||||
return info.address;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -549,7 +613,8 @@ namespace MM
|
|||
info.size = newSize;
|
||||
|
||||
memoryWriteLong(info.address, handle);
|
||||
return SetMemError(0);
|
||||
SetMemError(0);
|
||||
return info.address;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -557,30 +622,30 @@ namespace MM
|
|||
fprintf(stderr, "mplite_realloc failed.\n");
|
||||
Native::PrintMemoryStats();
|
||||
|
||||
if (i > 0) return SetMemError(MacOS::memFullErr);
|
||||
|
||||
// purge...
|
||||
for (auto & kv : HandleMap)
|
||||
{
|
||||
uint32_t ph = kv.first;
|
||||
auto &info = kv.second;
|
||||
|
||||
if (ph == handle) continue;
|
||||
if (info.size && info.purgeable && !info.locked)
|
||||
{
|
||||
mplite_free(&pool, Memory + info.address);
|
||||
info.size = 0;
|
||||
info.address = 0;
|
||||
|
||||
// also need to update memory
|
||||
memoryWriteLong(0, ph);
|
||||
}
|
||||
}
|
||||
if (i > 0 || !Purge(handle)) break;
|
||||
}
|
||||
return SetMemError(MacOS::memFullErr);
|
||||
|
||||
}
|
||||
|
||||
tool_return<void> HSetState(uint32_t handle, uint16_t attr)
|
||||
{
|
||||
return __with_handle(handle, [attr](HandleInfo &info){
|
||||
info.resource = attr & attrResource;
|
||||
info.purgeable = attr & attrPurgeable;
|
||||
info.locked = attr & attrLocked;
|
||||
});
|
||||
}
|
||||
|
||||
tool_return<uint16_t> HGetState(uint32_t handle)
|
||||
{
|
||||
return __with_handle(handle, [](const HandleInfo &info){
|
||||
uint16_t attr = 0;
|
||||
if (info.resource) attr |= attrResource;
|
||||
if (info.purgeable) attr |= attrPurgeable;
|
||||
if (info.locked) attr |= attrLocked;
|
||||
return attr;
|
||||
});
|
||||
}
|
||||
|
||||
tool_return<void> HSetRBit(uint32_t handle)
|
||||
{
|
||||
|
@ -613,6 +678,24 @@ namespace MM
|
|||
}
|
||||
|
||||
|
||||
tool_return<void> EmptyHandle(uint32_t handle) {
|
||||
return __with_handle(handle, [handle](HandleInfo &info) {
|
||||
|
||||
if (info.address == 0) return MacOS::noErr;
|
||||
// "The block whose handle is h must be unlocked but need not be purgeable."
|
||||
if (info.locked) return MacOS::memPurErr;
|
||||
|
||||
void *address = Memory + info.address;
|
||||
|
||||
mplite_free(&pool, address);
|
||||
|
||||
info.address = 0;
|
||||
info.size = 0;
|
||||
|
||||
memoryWriteLong(0, handle);
|
||||
return MacOS::noErr;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -989,23 +1072,7 @@ namespace MM
|
|||
uint32_t hh = cpuGetAReg(0);
|
||||
Log("%04x EmptyHandle(%08x)\n", trap, hh);
|
||||
|
||||
auto iter = HandleMap.find(hh);
|
||||
|
||||
if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr);
|
||||
|
||||
auto &info = iter->second;
|
||||
if (info.address == 0) return SetMemError(0);
|
||||
if (info.locked) return SetMemError(MacOS::memLockedErr); // ?
|
||||
|
||||
void *address = Memory + info.address;
|
||||
|
||||
mplite_free(&pool, address);
|
||||
|
||||
info.address = 0;
|
||||
info.size = 0;
|
||||
|
||||
memoryWriteLong(0, hh);
|
||||
return 0;
|
||||
return Native::EmptyHandle(hh).error();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1164,31 +1231,8 @@ namespace MM
|
|||
|
||||
Log("%04x HGetState(%08x)\n", trap, hh);
|
||||
|
||||
|
||||
auto iter = HandleMap.find(hh);
|
||||
|
||||
if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr);
|
||||
|
||||
/*
|
||||
* flag bits:
|
||||
* 0-4: reserved
|
||||
* 5: is a resource
|
||||
* 6: set if purgeable
|
||||
* 7: set if locked
|
||||
*/
|
||||
|
||||
const auto &info = iter->second;
|
||||
|
||||
// resouce not yet supported...
|
||||
// would need extra field and support in RM:: when
|
||||
// creating.
|
||||
// see HSetRBit, HClrRBit
|
||||
if (info.resource) flags |= (1 << 5);
|
||||
if (info.purgeable) flags |= (1 << 6);
|
||||
if (info.locked) flags |= (1 << 7);
|
||||
|
||||
SetMemError(0);
|
||||
return flags;
|
||||
auto rv = Native::HGetState(hh);
|
||||
return rv.error() ? rv.error() : rv.value();
|
||||
}
|
||||
|
||||
uint16_t HSetState(uint16_t trap)
|
||||
|
@ -1208,18 +1252,7 @@ namespace MM
|
|||
|
||||
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);
|
||||
return Native::HSetState(hh, flags).error();
|
||||
}
|
||||
|
||||
uint16_t HPurge(uint16_t trap)
|
||||
|
|
28
toolbox/mm.h
28
toolbox/mm.h
|
@ -9,6 +9,12 @@
|
|||
namespace MM
|
||||
{
|
||||
|
||||
enum {
|
||||
attrResource = 1 << 5,
|
||||
attrPurgeable = 1 << 6,
|
||||
attrLocked = 1 << 7,
|
||||
};
|
||||
|
||||
struct HandleInfo
|
||||
{
|
||||
uint32_t address = 0;
|
||||
|
@ -20,6 +26,15 @@ namespace MM
|
|||
HandleInfo(uint32_t a = 0, uint32_t s = 0) :
|
||||
address(a), size(s)
|
||||
{}
|
||||
|
||||
HandleInfo(uint32_t a, uint32_t s, unsigned attr) :
|
||||
address(a), size(s)
|
||||
{
|
||||
resource = attr & attrResource;
|
||||
purgeable = attr & attrPurgeable;
|
||||
locked = attr & attrLocked;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -40,7 +55,8 @@ namespace MM
|
|||
void PrintMemoryStats();
|
||||
|
||||
tool_return<hp> NewHandle(uint32_t size, bool clear);
|
||||
tool_return<uint32_t> NewHandle();
|
||||
tool_return<hp> NewHandleWithAttr(uint32_t size, unsigned attr);
|
||||
tool_return<uint32_t> NewEmptyHandle();
|
||||
|
||||
tool_return<uint32_t> NewPtr(uint32_t size, bool clear);
|
||||
|
||||
|
@ -49,8 +65,11 @@ namespace MM
|
|||
|
||||
tool_return<uint32_t> GetHandleSize(uint32_t handle);
|
||||
|
||||
tool_return<void> SetHandleSize(uint32_t handle, uint32_t newSize);
|
||||
tool_return<void> ReallocHandle(uint32_t handle, uint32_t newSize);
|
||||
tool_return<uint32_t> SetHandleSize(uint32_t handle, uint32_t newSize);
|
||||
tool_return<uint32_t> ReallocHandle(uint32_t handle, uint32_t newSize);
|
||||
|
||||
tool_return<void> HSetState(uint32_t handle, uint16_t attr);
|
||||
tool_return<uint16_t> HGetState(uint32_t handle);
|
||||
|
||||
tool_return<void> HSetRBit(uint32_t handle);
|
||||
tool_return<void> HClrRBit(uint32_t handle);
|
||||
|
@ -58,6 +77,9 @@ namespace MM
|
|||
tool_return<void> HLock(uint32_t handle);
|
||||
tool_return<void> HUnlock(uint32_t handle);
|
||||
|
||||
tool_return<void> EmptyHandle(uint32_t handle);
|
||||
|
||||
|
||||
|
||||
tool_return<HandleInfo> GetHandleInfo(uint32_t handle);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user