diff --git a/toolbox/mm.cpp b/toolbox/mm.cpp index 66d2a32..dc99775 100644 --- a/toolbox/mm.cpp +++ b/toolbox/mm.cpp @@ -24,8 +24,18 @@ namespace // map of ptr -> size std::map PtrMap; + struct HandleInfo + { + uint32_t address; + uint32_t size; + + HandleInfo(uint32_t a = 0, uint32_t s = 0) : + address(a), size(s) + {} + }; + // map of handle -> size [? just use Ptr map?] - std::map HandleMap; + std::map HandleMap; inline uint16_t SetMemError(uint16_t error) { @@ -132,16 +142,50 @@ namespace MM auto iter = PtrMap.find(mcptr); - if (iter == PtrMap.end()) return memWZErr; + if (iter == PtrMap.end()) return SetMemError(memWZErr); PtrMap.erase(iter); uint8_t *ptr = mcptr + Memory; mplite_free(&pool, ptr); - return 0; + return SetMemError(0); } + uint16_t DisposeHandle(uint16_t trap) + { + /* + * on entry: + * A0 Handle to be disposed of + * + * on exit: + * D0 Result code + * + */ + + uint32_t hh = cpuGetAReg(0); + + fprintf(stderr, "%04x DisposeHandle(%08x)\n", trap, hh); + + + auto iter = HandleMap.find(hh); + + if (iter == HandleMap.end()) return SetMemError(memWZErr); + + HandleInfo info = iter->second; + + HandleMap.erase(iter); + + uint8_t *ptr = info.address + Memory; + + mplite_free(&pool, ptr); + + HandleQueue.push_back(hh); + + return SetMemError(0); + } + + uint16_t NewPtr(uint16_t trap) @@ -173,7 +217,7 @@ namespace MM return SetMemError(0); } - uint8_t *ptr = NULL; + uint8_t *ptr = nullptr; ptr = (uint8_t *)mplite_malloc(&pool, size); if (!ptr) { @@ -192,5 +236,67 @@ namespace MM return SetMemError(0); } + uint16_t NewHandle(uint16_t trap) + { + /* + * on entry: + * D0 Number of logical bytes requested + * + * on exit: + * A0 Address of the new handle or NIL + * D0 Result code + * + */ + + uint32_t hh = 0; + uint8_t *ptr; + uint32_t mcptr; + + bool clear = trap & (1 << 9); + //bool sys = trap & (1 << 10); + + uint32_t size = cpuGetDReg(0); + + fprintf(stderr, "%04x NewHandle(%08x)\n", trap, size); + + if (!HandleQueue.size()) + { + if (!alloc_handle_block()) + { + cpuSetAReg(0, 0); + return SetMemError(memFullErr); + } + } + + hh = HandleQueue.front(); + HandleQueue.pop_front(); + + ptr = nullptr; + mcptr = 0; + + if (size) + { + ptr = (uint8_t *)mplite_malloc(&pool, size); + if (!ptr) + { + HandleQueue.push_back(hh); + cpuSetAReg(0, 0); + return SetMemError(memFullErr); + } + mcptr = ptr - Memory; + + if (clear) + std::memset(ptr, 0, size); + } + + // need a handle -> ptr map? + HandleMap.emplace(std::make_pair(hh, HandleInfo(mcptr, size))); + + memoryWriteLong(mcptr, hh); + cpuSetAReg(0, hh); + return SetMemError(0); + } + + } \ No newline at end of file diff --git a/toolbox/mm.h b/toolbox/mm.h index 5d0f959..77d3cfc 100644 --- a/toolbox/mm.h +++ b/toolbox/mm.h @@ -15,7 +15,10 @@ namespace MM uint16_t BlockMove(uint16_t trap); uint16_t DisposePtr(uint16_t trap); + uint16_t DisposeHandle(uint16_t trap); + uint16_t NewPtr(uint16_t trap); + uint16_t NewHandle(uint16_t trap); } #endif \ No newline at end of file diff --git a/toolbox/toolbox.cpp b/toolbox/toolbox.cpp index dc57eee..c0bf330 100644 --- a/toolbox/toolbox.cpp +++ b/toolbox/toolbox.cpp @@ -49,6 +49,10 @@ namespace ToolBox { d0 = OS::GetVol(trap); break; + case 0xA023: + d0 = MM::DisposeHandle(trap); + break; + // BlockMove (sourcePtr,destPtr: Ptr; byteCount: Size); case 0xa02e: d0 = MM::BlockMove(trap); @@ -79,6 +83,12 @@ namespace ToolBox { d0 = MM::DisposePtr(trap); break; + // NewHandle (logicalSize: Size) : Handle; + case 0xA122: + case 0xa322: + d0 = MM::NewHandle(trap); + break; + // resource manager stuff. // Get1NamedResource (theType: ResType; name: Str255) : Handle;