mirror of
https://github.com/ksherlock/mpw.git
synced 2024-11-21 09:30:55 +00:00
Time Manager stuff
This commit is contained in:
parent
eda186e9ff
commit
c03938ca7d
178
toolbox/os.cpp
178
toolbox/os.cpp
@ -1197,4 +1197,182 @@ namespace OS
|
||||
return MacOS::prWrErr;
|
||||
}
|
||||
|
||||
#pragma mark - Timer
|
||||
|
||||
struct TimerEntry {
|
||||
uint32_t tmTaskPtr = 0; // address of the queue. passed back in A1.
|
||||
uint32_t tmAddr = 0;
|
||||
bool extended = false;
|
||||
bool active = false;
|
||||
|
||||
std::chrono::time_point<std::chrono::steady_clock> when;
|
||||
|
||||
TimerEntry(uint32_t a, uint32_t b) : tmTaskPtr(a), tmAddr(b)
|
||||
{}
|
||||
};
|
||||
|
||||
// heap sorted by next task to run?
|
||||
static std::deque<TimerEntry> TimerQueue;
|
||||
|
||||
namespace TMTask {
|
||||
enum {
|
||||
_qLink = 0,
|
||||
_qType = 4,
|
||||
_tmAddr = 6,
|
||||
_tmCount = 10,
|
||||
_tmWakeUp = 14,
|
||||
_tmReserved = 18
|
||||
};
|
||||
}
|
||||
|
||||
uint16_t InsTime(uint16_t trap)
|
||||
{
|
||||
// PROCEDURE InsTime (tmTaskPtr: QElemPtr);
|
||||
|
||||
// this adds an entry to the queue but does not schedule it.
|
||||
|
||||
/*
|
||||
* on entry
|
||||
* A0 Address of the task record
|
||||
*
|
||||
* on exit
|
||||
* D0 Result code
|
||||
*/
|
||||
|
||||
using namespace TMTask;
|
||||
|
||||
uint32_t tmTaskPtr = cpuGetAReg(0);
|
||||
|
||||
Log("%04x InsTime(%08x)\n", trap, tmTaskPtr);
|
||||
|
||||
if (tmTaskPtr)
|
||||
{
|
||||
memoryWriteLong(0, tmTaskPtr + _qLink);
|
||||
memoryWriteWord(0, tmTaskPtr + _qType);
|
||||
memoryWriteLong(0, tmTaskPtr + _tmCount);
|
||||
memoryWriteLong(0, tmTaskPtr + _tmWakeUp);
|
||||
memoryWriteLong(0, tmTaskPtr + _tmReserved);
|
||||
|
||||
TimerQueue.emplace_back(tmTaskPtr, memoryReadLong(tmTaskPtr + _tmAddr));
|
||||
}
|
||||
|
||||
return MacOS::noErr;
|
||||
}
|
||||
|
||||
uint16_t PrimeTime(uint16_t trap)
|
||||
{
|
||||
// PROCEDURE PrimeTime (tmTaskPtr: QElemPtr; count: LongInt);
|
||||
// this activates an entry.
|
||||
|
||||
/*
|
||||
* on entry
|
||||
* A0 Address of the task record
|
||||
* D0 Specified delay time (long)
|
||||
*
|
||||
* on exit
|
||||
* D0 Result code
|
||||
*/
|
||||
|
||||
using namespace TMTask;
|
||||
|
||||
uint32_t tmTaskPtr = cpuGetAReg(0);
|
||||
uint32_t count = cpuGetDReg(0);
|
||||
|
||||
Log("%04x PrimeTime(%08x, %08x)\n", trap, tmTaskPtr, count);
|
||||
|
||||
if (tmTaskPtr)
|
||||
{
|
||||
auto iter = std::find_if(TimerQueue.begin(), TimerQueue.end(), [tmTaskPtr](const TimerEntry &e){
|
||||
return e.tmTaskPtr == tmTaskPtr;
|
||||
});
|
||||
|
||||
if (iter != TimerQueue.end() && !iter->active)
|
||||
{
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
|
||||
iter->active = true;
|
||||
|
||||
if (count == 0) {
|
||||
// retain the original time or set it to now.
|
||||
iter->when = std::max(now, iter->when);
|
||||
}
|
||||
else
|
||||
{
|
||||
int64_t micro;
|
||||
if (count < 0x80000000)
|
||||
micro = count * 1000;
|
||||
else
|
||||
micro = -(int32_t)count;
|
||||
|
||||
|
||||
iter->when = now + std::chrono::microseconds(micro);
|
||||
|
||||
}
|
||||
memoryWriteWord(tmTaskPtr + _qType, 0x8000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return MacOS::noErr;
|
||||
|
||||
}
|
||||
|
||||
uint16_t RmvTime(uint16_t trap)
|
||||
{
|
||||
// PROCEDURE RmvTime (tmTaskPtr: QElemPtr);
|
||||
|
||||
// unschedule (but not actually remove)
|
||||
|
||||
/*
|
||||
* on entry
|
||||
* A0 Address of the task record
|
||||
*
|
||||
* on exit
|
||||
* D0 Result code
|
||||
*/
|
||||
|
||||
using namespace TMTask;
|
||||
|
||||
uint32_t tmTaskPtr = cpuGetAReg(0);
|
||||
|
||||
Log("%04x RmvTime(%08x)\n", trap, tmTaskPtr);
|
||||
|
||||
if (tmTaskPtr)
|
||||
{
|
||||
auto iter = std::find_if(TimerQueue.begin(), TimerQueue.end(), [tmTaskPtr](const TimerEntry &e){
|
||||
return e.tmTaskPtr == tmTaskPtr;
|
||||
});
|
||||
|
||||
if (iter != TimerQueue.end())
|
||||
{
|
||||
uint32_t count = 0;
|
||||
if (iter->active)
|
||||
{
|
||||
iter->active = false;
|
||||
|
||||
|
||||
// update tmCount to the amount of time remaining.
|
||||
// uses negative microseconds
|
||||
// or positive milliseconds.
|
||||
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
|
||||
int64_t micro = std::chrono::duration_cast< std::chrono::microseconds >(iter->when - now).count();
|
||||
|
||||
if (micro < 0)
|
||||
count = 0;
|
||||
else if (micro < 0x80000000)
|
||||
count = -micro;
|
||||
else
|
||||
count = micro / 10000;
|
||||
}
|
||||
|
||||
memoryWriteWord(tmTaskPtr + _qType, 0);
|
||||
memoryWriteLong(tmTaskPtr + _tmCount, count);
|
||||
}
|
||||
}
|
||||
|
||||
return MacOS::noErr;
|
||||
}
|
||||
|
||||
}
|
@ -98,6 +98,11 @@ namespace OS
|
||||
uint16_t ReadXPRam(uint16_t trap);
|
||||
uint16_t WriteXPRam(uint16_t trap);
|
||||
|
||||
uint16_t InsTime(uint16_t trap);
|
||||
uint16_t InsXTime(uint16_t trap);
|
||||
uint16_t PrimeTime(uint16_t trap);
|
||||
uint16_t RmvTime(uint16_t trap);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -65,6 +65,7 @@ namespace OS {
|
||||
|
||||
std::map<uint32_t, uint32_t> GestaltMap = {
|
||||
{'alis', 1}, // Alias Manager
|
||||
{'tmgr', 2}, // Time Manager (2 = revised, 3 = extended.)
|
||||
};
|
||||
|
||||
uint16_t Gestalt(uint16_t trap)
|
||||
|
@ -358,6 +358,19 @@ namespace ToolBox {
|
||||
d0 = MM::EmptyHandle(trap);
|
||||
break;
|
||||
|
||||
|
||||
case 0xa058:
|
||||
d0 = OS::InsTime(trap);
|
||||
break;
|
||||
|
||||
case 0xa059:
|
||||
d0 = OS::RmvTime(trap);
|
||||
break;
|
||||
|
||||
case 0xa05a:
|
||||
d0 = OS::PrimeTime(trap);
|
||||
break;
|
||||
|
||||
// resource manager stuff.
|
||||
|
||||
// Count1Resources (theType: ResType): Integer;
|
||||
|
Loading…
Reference in New Issue
Block a user