; AUTO-GENERATED SYMBOL LIST ; IMPORTS: ; NKIndex ; DeleteID ; LookupID ; MakeID ; NKMPCalls ; BlockMPCall ; ReleaseAndReturnMPCall ; ReleaseAndReturnMPCallBlueBlocking ; ReleaseAndReturnMPCallInvalidIDErr ; ReleaseAndReturnMPCallOOM ; ReleaseAndReturnMPCallTaskAborted ; ReleaseAndReturnParamErrFromMPCall ; ReleaseAndReturnZeroFromMPCall ; ReleaseAndScrambleMPCall ; ReleaseAndTimeoutMPCall ; ReturnMPCallOOM ; ReturnZeroFromMPCall ; ScrambleMPCall ; NKPoolAllocator ; PoolAlloc ; PoolAllocClear ; PoolFree ; NKScheduler ; CalculateTimeslice ; FlagSchEvaluationIfTaskRequires ; SchRdyTaskLater ; SchRdyTaskNow ; SchTaskUnrdy ; NKThud ; panic ; NKTimers ; DequeueTimer ; EnqueueTimer ; GetTime ; TimebaseTicksPerPeriod ; EXPORTS: ; CauseNotification (=> NKAddressSpaces, NKInterrupts, NKPrimaryIntHandlers) ; EnqueueMessage (=> NKInterrupts, NKTasks, NKTimers) ; SetEvent (=> NKAddressSpaces, NKTimers) ; SignalSemaphore (=> NKTimers) ; UnblockBlueIfCouldBePolling (=> NKInterrupts) ####### ## ## ######## ## ## ######## ###### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ## ## ###### ###### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##### ## ####### ######## ####### ######## ###### ## ######## ####### ###### ######## ######## ### ######## ######## #### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ####### ## ## ## ######## ###### ## ## ## ###### ## ## ## ## ## ## ## ## ## ######### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ###### ##### ## ###### ## ## ######## ## ## ## ######## ; RET OSStatus r3, QueueID r4 DeclareMPCall 15, MPCreateQueue MPCreateQueue li r8, Queue.Size bl PoolAlloc mr. r31, r8 beq ScrambleMPCall ; List of messages waiting for tasks InitList r8, 'MSGQ', scratch=r16 ; List of blocked tasks waiting to be notified of messages addi r9, r8, Queue.Messages InitList r9, 'NOTQ', scratch=r16 _Lock PSA.SchLock, scratch1=r16, scratch2=r17 li r9, Queue.kIDClass bl MakeID cmpwi r8, 0 bne+ @nofail mr r8, r31 bl PoolFree b ReleaseAndScrambleMPCall @nofail mfsprg r30, 0 lwz r30, EWA.PA_CurTask(r30) stw r8, Queue.BlockedTasks + LLL.Freeform(r31) lwz r17, Task.ProcessID(r30) stw r17, Queue.ProcessID(r31) mr r4, r8 li r17, 0 stw r17, Queue.ReserveCount(r31) stw r17, Queue.ReservePtr(r31) stw r17, Queue.BlockedTaskCount(r31) stw r17, Queue.MessageCount(r31) b ReleaseAndReturnZeroFromMPCall ## ####### ####### ######## ######## ## ######## ######## ######## #### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ######## ## ## ## ## ###### ## ###### ## ###### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ####### ##### ## ######## ######## ######## ######## ## ######## ; Delete a message queue: ; 1. Delete its messages. ; 2. Call UnblockBlueIfCouldBePolling on the queue? ; 3. Unblock waiting tasks with kMPDeletedErr, calling FlagSchEvaluationIfTaskRequires on each. ; 4. Delete the queue structure and its ID. ; ARG QueueID r3 ; RET OSStatus r3 DeclareMPCall 16, MPDeleteQueue MPDeleteQueue _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, Queue.kIDClass mr r31, r8 bne ReleaseAndReturnMPCallInvalidIDErr ; Delete all auto-allocated messages @note_free_loop addi r30, r31, Queue.Messages lwz r8, Queue.Messages + LLL.Next(r31) cmpw r8, r30 beq @exit_note_free_loop RemoveFromList r8, scratch1=r16, scratch2=r17 bl PoolFree b @note_free_loop @exit_note_free_loop ; Delete all pre-allocated messages lwz r30, Queue.ReservePtr(r31) @notr_free_loop mr. r8, r30 beq @exit_notr_free_loop lwz r30, Message.LLL + LLL.Next(r30) bl PoolFree b @notr_free_loop @exit_notr_free_loop mr r8, r3 bl UnblockBlueIfCouldBePolling ; UNBLOCK the tasks that are blocked waiting on this queue. ; From the task's perspective, MPWaitOnQueue will return ; kMPDeletedErr, because we tweak the task's ContextBlock. @task_unblock_loop ; Peek at our MSGQ queue of blocked tasks addi r30, r31, Queue.BlockedTasks lwz r16, Queue.BlockedTasks + LLL.Next(r31) cmpw r16, r30 subi r8, r16, Task.QueueMember beq @exit_task_loop ; Manipulate its r3 from afar lwz r17, Task.ContextBlockPtr(r8) li r18, kMPDeletedErr stw r18, ContextBlock.r3(r17) ; If blocked with timeout, dequeue task's internal timer lbz r17, Task.Timer + Timer.Byte3(r8) cmpwi r17, 1 bne @no_timeout addi r8, r8, Task.Timer bl DequeueTimer @no_timeout ; Remove from this MSGQ lwz r16, Queue.BlockedTasks + LLL.Next(r31) RemoveFromList r16, scratch1=r17, scratch2=r18 ; Put RDYQ subi r8, r16, Task.QueueMember bl SchRdyTaskNow bl FlagSchEvaluationIfTaskRequires b @task_unblock_loop @exit_task_loop ; Delete the actual Queue structure and its ID mr r8, r31 bl PoolFree mr r8, r3 bl DeleteID b ReleaseAndReturnZeroFromMPCall ####### ####### ####### ######## ######## ###### ######## ######## ## ## ######## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ####### ######## ## ## ######## ###### ###### ###### ######## ## ## ###### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ####### ####### ##### ## ## ## ######## ###### ######## ## ## ### ######## ; Reserve space for messages for this queue. ; (guarantees message delivery) ; Reserved messages have signature 'notr' (vs. 'note'). ; ARG QueueID r3, ItemCount r4 ; RET OSStatus r3 DeclareMPCall 39, MPSetQueueReserve MPSetQueueReserve cmpwi r4, 0 blt ReturnMPCallOOM _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, Queue.kIDClass mr r31, r8 bne ReleaseAndReturnMPCallInvalidIDErr lwz r29, Queue.ReserveCount(r31) lwz r30, Queue.ReservePtr(r31) cmpw r29, r4 beq ReleaseAndReturnZeroFromMPCall blt @make_more ; NEW < OLD @free_loop mr. r8, r30 beq @free_loop_failed subi r29, r29, 1 lwz r30, LLL.Next(r30) bl PoolFree cmpw r29, r4 bgt @free_loop ;free loop succeeded stw r4, Queue.ReserveCount(r31) stw r30, Queue.ReservePtr(r31) b ReleaseAndReturnZeroFromMPCall @free_loop_failed stw r29, Queue.ReserveCount(r31) stw r30, Queue.ReservePtr(r31) b ReleaseAndReturnMPCallOOM ; NEW > OLD @make_more @alloc_loop li r8, Message.Size bl PoolAlloc cmpwi r8, 0 beq ReleaseAndScrambleMPCall addi r29, r29, 1 lisori r17, Message.kReservedSignature stw r17, Message.LLL + LLL.Signature(r8) stw r30, Message.LLL + LLL.Next(r8) stw r29, Queue.ReserveCount(r31) cmpw r29, r4 stw r8, Queue.ReservePtr(r31) mr r30, r8 blt @alloc_loop b ReleaseAndReturnZeroFromMPCall ## ######## ####### ## ## ####### ######## #### ######## ## ## #### ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ## #### ## ## ## ## ## ## ## ## ## ## ## ###### ## ## ## ## ## ## ## #### ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ###### ## ##### ## ## ## ####### ## #### ## ## ; Sends a 12-byte message to the specified queue ; ARG QueueID r3, long r4, long r5, long r6 DeclareMPCall 17, MPNotifyQueue MPNotifyQueue _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, Queue.kIDClass mr r31, r8 bne ReleaseAndReturnMPCallInvalidIDErr lwz r16, Queue.ReserveCount(r31) li r8, Message.Size cmpwi r16, 0 bne @try_reserve ;no reservation available bl PoolAlloc cmpwi r8, 0 beq ReleaseAndScrambleMPCall lisori r17, Message.kSignature stw r17, Message.LLL + LLL.Signature(r8) b @common @try_reserve lwz r17, Queue.ReservePtr(r31) mr. r8, r17 beq ReleaseAndReturnMPCallOOM lwz r17, Message.LLL + LLL.Next(r17) stw r17, Queue.ReservePtr(r31) @common ; Got a message ptr in r8! ; Fill it with lies lwz r16, ContextBlock.r6(r6) stw r4, Message.Word1(r8) stw r5, Message.Word2(r8) stw r16, Message.Word3(r8) bl EnqueueMessage ; Message *r8, Queue *r31 b ReleaseAndReturnZeroFromMPCall ### ####### ## ## ###### ###### ### ## ## ## ### ### ## ## ## ## ## ## ## ## #### #### ## ## ## ## ## ## ## ### ## ###### ## #### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ##### ## ## ## ###### ###### ### ; Enqueue a note/notr object. ; Odd way of unblocking task (does not touch r3 directly): ; 1. Add message to queue. ; 2. If task waiting, unblock with rewound PC to retry syscall. ; ARG Message *r8, Queue *r31 EnqueueMessage addi r17, r31, Queue.Messages stw r17, LLL.Freeform(r8) InsertAsPrev r8, r17, scratch=r16 lwz r18, Queue.MessageCount(r31) addi r18, r18, 1 stw r18, Queue.MessageCount(r31) mflr r27 lwz r8, Queue.BlockedTasks + LLL.Freeform(r31) bl UnblockBlueIfCouldBePolling ; Got a task to unblock straight away? lwz r16, Queue.BlockedTasks + LLL.Next(r31) cmpw r16, r31 subi r8, r16, Task.QueueMember beq @no_task ; Saves us special-casing lwz r17, Task.ContextBlockPtr(r8) lwz r18, ContextBlock.CodePtr(r17) subi r18, r18, 4 stw r18, ContextBlock.CodePtr(r17) ; De-fang the task's blocking timeout lbz r17, Task.Timer + Timer.Byte3(r8) cmpwi r17, 1 bne @no_timeout addi r8, r8, Task.Timer bl DequeueTimer @no_timeout ; Remove the task from this MSGQ lwz r16, Queue.BlockedTasks + LLL.Next(r31) RemoveFromList r16, scratch1=r17, scratch2=r18 lwz r18, Queue.BlockedTaskCount(r31) subi r18, r18, 1 stw r18, Queue.BlockedTaskCount(r31) subi r8, r16, Task.QueueMember ; And add it back to the latency-protection RDYQ li r17, Task.kLatencyProtectPriority stb r17, Task.Priority(r8) bl SchRdyTaskNow bl CalculateTimeslice bl FlagSchEvaluationIfTaskRequires @no_task mtlr r27 blr ## ####### ####### ## ## ### #### ######## #### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ####### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ######### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ####### ##### ## ### ### ## ## #### ## ; Get a message from the specified queue, or fail. ; Abbreviated summary of cases: ; 1. Return a pending message ; 2. Time out instantly ; 3. Move task to MSGQ from RDYQ and arm timer ; 4. Move task to MSGQ from RDYQ, no timeout ; ARG QueueID r3, Duration r7 ; RET OSStatus r3, long r4, long r5, long r6 DeclareMPCall 18, MPWaitOnQueue MPWaitOnQueue _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, Queue.kIDClass bne ReleaseAndReturnMPCallInvalidIDErr mr r31, r8 lwz r16, Queue.Messages + LLL.Next(r31) addi r17, r31, Queue.Messages cmpw r16, r17 beq @no_messages_pending ;messages pending lwz r4, Message.Word1(r16) lwz r5, Message.Word2(r16) lwz r17, Message.Word3(r16) stw r17, ContextBlock.r6(r6) RemoveFromList r16, scratch1=r17, scratch2=r18 lwz r18, Queue.MessageCount(r31) subi r18, r18, 1 stw r18, Queue.MessageCount(r31) lbz r17, Message.LLL + LLL.Signature + 3(r16) ; 'r' if mem-reserved message, else 'e' mr r8, r16 cmpwi r17, Message.kReservedSignature & 0xFF beq @immediate_msg_was_reserved ;immediate message was not reserved ... return noErr bl PoolFree b ReleaseAndReturnZeroFromMPCall @immediate_msg_was_reserved ; ... return noErr lwz r17, Queue.ReservePtr(r31) stw r16, Queue.ReservePtr(r31) stw r17, LLL.Next(r16) b ReleaseAndReturnZeroFromMPCall ; The blocking case (eew!) @no_messages_pending lwz r17, ContextBlock.r7(r6) mfsprg r30, 0 ;special case: zero timeout ... return cmpwi r17, 0 lwz r19, EWA.PA_CurTask(r30) beq ReleaseAndTimeoutMPCall ;special case: blue may not block lwz r16, Task.Flags(r19) rlwinm. r16, r16, 0, Task.kFlagBlue, Task.kFlagBlue beq @bot_blue stw r3, PSA.BlueSpinningOn(r1) b ReleaseAndReturnMPCallBlueBlocking @bot_blue ;committed to blocking the calling task ; Remove from ready queue mr r8, r19 bl SchTaskUnrdy ; Add to this queue lwz r19, EWA.PA_CurTask(r30) addi r16, r31, Queue.BlockedTasks addi r17, r19, Task.QueueMember stw r16, LLL.FreeForm(r17) InsertAsPrev r17, r16, scratch=r18 lwz r18, Queue.BlockedTaskCount(r31) addi r18, r18, 1 stw r18, Queue.BlockedTaskCount(r31) ; Decide whether call can time out _lstart r16, 0x7fffffff ; "forever" lwz r17, ContextBlock.r7(r6) _lfinish addi r30, r19, Task.Timer cmpw r17, r16 li r16, 2 beq @wait_forever ;committed to arming task's built-in timer (finite timeout) stb r16, Timer.Kind(r30) stw r19, Timer.ParentTaskPtr(r30) mr r8, r17 ; Convert that timeout to a tick count bl TimebaseTicksPerPeriod mr r27, r8 mr r28, r9 bl GetTime mfxer r16 addc r9, r9, r28 adde r8, r8, r27 mtxer r16 ; Now r8/r9 = absolute timeout date stw r8, Timer.Time(r30) stw r9, Timer.Time+4(r30) mr r8, r30 bl EnqueueTimer @wait_forever b BlockMPCall ## ####### ####### ####### ## ## ######## ######## ## ## #### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #### ## ######## ## ## ## ## ## ## ###### ######## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ####### ##### ## ##### ## ####### ######## ## ## ## ; Non-blocking peek at contents of queue (undocumented) ; Returns timeout if empty, noErr if non-empty ; ARG QueueID r3 ; RET OSStatus r3 DeclareMPCall 19, MPQueryQueue MPQueryQueue _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, Queue.kIDClass bne ReleaseAndReturnMPCallInvalidIDErr mr r31, r8 lwz r16, Queue.Messages + LLL.Next(r31) addi r17, r31, Queue.Messages cmpw r16, r17 beq ReleaseAndTimeoutMPCall b ReleaseAndReturnZeroFromMPCall ###### ######## ## ## ### ######## ## ## ####### ######## ######## ###### ## ## ## ### ### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #### #### ## ## ## ## ## ## ## ## ## ## ## ## ###### ###### ## ### ## ## ## ######## ######### ## ## ######## ###### ###### ## ## ## ## ######### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ######## ## ## ## ## ## ## ## ####### ## ## ######## ###### ####### ##### ###### ###### ######## ######## ### ######## ######## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ####### ## ## ###### ## ######## ###### ## ## ## ###### ## ## ## ## ## ## ## ## ######### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ######### ##### ###### ###### ## ## ######## ## ## ## ######## ; ARG maxValue r3, initialValue r4 ; RET OSStatus r3, SemaphoreID r5 DeclareMPCall 20, MPCreateSemaphore MPCreateSemaphore cmpw r4, r3 bgt ReturnMPCallOOM li r8, Semaphore.Size bl PoolAlloc mr. r31, r8 beq ScrambleMPCall InitList r31, Semaphore.kSignature, scratch=r16 _Lock PSA.SchLock, scratch1=r16, scratch2=r17 li r9, Semaphore.kIDClass bl MakeID cmpwi r8, 0 bne+ @nofail mr r8, r31 bl PoolFree b ReleaseAndScrambleMPCall @nofail li r18, 0x00 stw r8, 0x0000(r31) mfsprg r30, 0 lwz r30, EWA.PA_CurTask(r30) stw r3, Semaphore.MaxValue(r31) stw r4, Semaphore.Value(r31) lwz r17, Task.ProcessID(r30) stw r18, Semaphore.BlockedTaskCount(r31) stw r17, Semaphore.ProcessID(r31) mr r5, r8 b ReleaseAndReturnZeroFromMPCall ####### ####### ###### ## ## ### #### ######## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ####### ####### ###### ## ## ## ## ## ## ## ## ## ## ## ## ## ######### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ######### ####### ###### ### ### ## ## #### ## ; Wait on a semaphore, or fail (similar to MPWaitOnQueue) ; Abbreviated summary of cases: ; 1. Decrement and return instantly ; 2. Time out instantly ; 3. Move task to SEMA from RDYQ and arm timer ; 4. Move task to SEMA from RDYQ, no timeout ; ARG SemaphoreID r3, Duration r4 DeclareMPCall 23, MPWaitOnSemaphore MPWaitOnSemaphore _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, Semaphore.kIDClass bne ReleaseAndReturnMPCallInvalidIDErr mr r31, r8 lwz r16, Semaphore.Value(r31) cmpwi r16, 0 subi r16, r16, 1 ble @must_wait ;easiest case ... decrement and return stw r16, Semaphore.Value(r31) b ReleaseAndReturnZeroFromMPCall @must_wait ;next easiest case ... instant timeout cmpwi r4, 0 mfsprg r30, 0 beq ReleaseAndTimeoutMPCall lwz r8, EWA.PA_CurTask(r30) ;special case: blue may not block lwz r16, Task.Flags(r8) rlwinm. r16, r16, 0, Task.kFlagBlue, Task.kFlagBlue beq @bot_blue stw r3, PSA.BlueSpinningOn(r1) b ReleaseAndReturnMPCallBlueBlocking @bot_blue ;committed to blocking the calling task ; Remove from ready queue bl SchTaskUnrdy ; Add to this queue addi r16, r31, Semaphore.BlockedTasks addi r17, r8, Task.QueueMember stw r16, LLL.FreeForm(r17) InsertAsPrev r17, r16, scratch=r18 lwz r18, Semaphore.BlockedTaskCount(r31) addi r18, r18, 1 stw r18, Semaphore.BlockedTaskCount(r31) _lstart r16, 0x7fffffff addi r30, r8, Task.Timer _lfinish cmpw r4, r16 li r17, 2 beq @wait_forever ;committed to creating a timer (finite timeout) stb r17, Timer.Kind(r30) stw r8, Timer.ParentTaskPtr(r30) mr r8, r4 ; Convert that timeout to a tick count bl TimebaseTicksPerPeriod mr r27, r8 mr r28, r9 bl GetTime mfxer r16 addc r9, r9, r28 adde r8, r8, r27 mtxer r16 ; Now r8/r9 = absolute timeout date stw r8, Timer.Time(r30) stw r9, Timer.Time+4(r30) mr r8, r30 bl EnqueueTimer @wait_forever li r3, 0x00 b BlockMPCall ####### ## ###### ####### ## ## ######## ######## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #### ####### ## ## ###### ## ## ## ## ###### ######## ## ## ######### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ######### ## ###### ##### ## ####### ######## ## ## ## ; Non-blocking peek at semaphore (undocumented) ; Returns timeout if empty, noErr if non-empty ; ARG SemaphoreID r3 ; RET OSStatus r3 DeclareMPCall 24, MPQuerySemaphore MPQuerySemaphore _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, Semaphore.kIDClass bne ReleaseAndReturnMPCallInvalidIDErr mr r31, r8 lwz r16, Semaphore.Value(r31) cmpwi r16, 0 ble ReleaseAndTimeoutMPCall b ReleaseAndReturnZeroFromMPCall ####### ####### ###### ###### #### ###### ## ## ### ## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## #### ## ## ## ## ####### ####### ###### ###### ## ## #### ## ## ## ## ## ## ## ## ## ## ## ## ## ## #### ######### ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ######### ######### ###### ###### #### ###### ## ## ## ## ######## ; ARG SemaphoreID r3 ; RET OSStatus r3 DeclareMPCall 22, MPSignalSemaphore MPSignalSemaphore _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, Semaphore.kIDClass mr r31, r8 bne ReleaseAndReturnMPCallInvalidIDErr bl SignalSemaphore mr r3, r8 b ReleaseAndReturnMPCall ### ###### ###### #### ###### ## ## ### ## ### ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ## ###### ###### ## ## #### ## ## ## ## ## ## ## ## ## ## ## ## ## ## #### ######### ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ### ###### ###### #### ###### ## ## ## ## ######## ### ; ARG Semaphore *r31 SignalSemaphore ; OUTSIDE REFERER mflr r27 lwz r8, Semaphore.BlockedTasks + LLL.Freeform(r31) bl UnblockBlueIfCouldBePolling lwz r16, 0x0008(r31) cmpw r16, r31 beq SignalSemaphore_0x80 addi r8, r16, -0x08 lbz r17, 0x0037(r8) cmpwi r17, 0x01 bne SignalSemaphore_0x30 addi r8, r8, 0x20 bl DequeueTimer SignalSemaphore_0x30 lwz r16, 0x0008(r31) RemoveFromList r16, scratch1=r17, scratch2=r18 lwz r18, 0x001c(r31) addi r18, r18, -0x01 stw r18, 0x001c(r31) addi r8, r16, -0x08 li r17, 0x01 stb r17, 0x0019(r8) bl SchRdyTaskNow bl CalculateTimeslice bl FlagSchEvaluationIfTaskRequires mtlr r27 li r8, 0x00 blr SignalSemaphore_0x80 mtlr r27 lwz r16, 0x0010(r31) lwz r17, 0x0014(r31) cmpw r16, r17 addi r16, r16, 0x01 li r8, kMPInsufficientResourcesErr bgelr stw r16, 0x0010(r31) li r8, 0x00 blr ####### ## ###### ######## ######## ## ######## ######## ######## ## ## #### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ####### ## ###### ## ## ###### ## ###### ## ###### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ######### ###### ###### ######## ######## ######## ######## ## ######## DeclareMPCall 21, MPDeleteSemaphore MPDeleteSemaphore _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, Semaphore.kIDClass mr r31, r8 bne ReleaseAndReturnMPCallInvalidIDErr mr r8, r3 bl UnblockBlueIfCouldBePolling MPCall_21_0x34 addi r30, r31, Semaphore.BlockedTasks lwz r16, LLL.Next(r31) cmpw r16, r30 addi r8, r16, -0x08 beq MPCall_21_0x98 lwz r17, 0x0088(r8) li r18, kMPDeletedErr stw r18, 0x011c(r17) lbz r17, 0x0037(r8) cmpwi r17, 0x01 bne MPCall_21_0x68 addi r8, r8, 0x20 bl DequeueTimer MPCall_21_0x68 lwz r16, 0x0008(r31) RemoveFromList r16, scratch1=r17, scratch2=r18 addi r8, r16, -0x08 bl SchRdyTaskNow bl FlagSchEvaluationIfTaskRequires b MPCall_21_0x34 MPCall_21_0x98 mr r8, r31 bl PoolFree mr r8, r3 bl DeleteID ; r1 = kdp b ReleaseAndReturnZeroFromMPCall ###### ######## #### ######## #### ###### ### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ######## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ######### ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ## ## #### ## #### ###### ## ## ######## ######## ######## ###### #### ####### ## ## ###### ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## #### ## ## ######## ###### ## #### ## ## ## ## ## ## ###### ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ######## ###### #### ####### ## ## ###### ####### ######## ######## ###### ######## ######## ### ######## ######## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ####### ####### ######## ## ######## ###### ## ## ## ###### ## ## ## ## ## ## ## ## ######### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ######### ###### ## ## ###### ## ## ######## ## ## ## ######## DeclareMPCall 25, MPCreateCriticalRegion MPCreateCriticalRegion li r8, 0x24 bl PoolAlloc mr. r31, r8 beq ScrambleMPCall InitList r31, CriticalRegion.kSignature, scratch=r16 _Lock PSA.SchLock, scratch1=r16, scratch2=r17 li r9, 0x06 ; r1 = kdp ; r9 = kind bl MakeID cmpwi r8, 0x00 bne+ MPCall_25_0x58 mr r8, r31 bl PoolFree b ReleaseAndScrambleMPCall MPCall_25_0x58 li r18, 0x00 mfsprg r30, 0 lwz r30, -0x0008(r30) li r16, 0x00 stw r8, 0x0000(r31) stw r16, 0x0014(r31) stw r16, 0x001c(r31) stw r16, 0x0018(r31) lwz r17, 0x0060(r30) stw r18, 0x0020(r31) stw r17, 0x0010(r31) mr r4, r8 ; r1 = kdp b ReleaseAndReturnZeroFromMPCall ####### ######## ######## ######## ## ## ######## ######## ######## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ####### ## ######## ###### ## ## ## ## ###### ######## ## ## ## ## ## ## #### ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ######### ## ## ## ######## ## ## ## ######## ## ## DeclareMPCall 27, MPEnterCriticalRegion MPEnterCriticalRegion _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 ; r8 = id bl LookupID cmpwi r9, CriticalRegion.kIDClass bne ReleaseAndReturnMPCallInvalidIDErr mr r31, r8 mfsprg r17, 0 lwz r18, 0x0014(r31) lwz r30, -0x0008(r17) cmpwi r18, 0x00 lwz r16, 0x0018(r31) beq MPCall_27_0x64 lwz r17, 0x001c(r31) cmpw r16, r30 cmpw cr1, r17, r5 bne MPCall_27_0x78 bne cr1, MPCall_27_0x78 addi r18, r18, 0x01 stw r18, 0x0014(r31) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall MPCall_27_0x64 addi r18, r18, 0x01 stw r30, 0x0018(r31) stw r5, 0x001c(r31) stw r18, 0x0014(r31) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall MPCall_27_0x78 lwz r8, 0x0000(r16) ; r8 = id bl LookupID cmpwi r9, Task.kIDClass bne ReleaseAndReturnMPCallTaskAborted lwz r8, 0x001c(r31) ; r8 = id bl LookupID cmpwi r9, Process.kIDClass bne ReleaseAndReturnMPCallTaskAborted cmpwi r4, 0x00 ;special case: blue may not block lwz r16, Task.Flags(r30) beq ReleaseAndTimeoutMPCall rlwinm. r16, r16, 0, Task.kFlagBlue, Task.kFlagBlue beq @bot_blue stw r3, PSA.BlueSpinningOn(r1) b ReleaseAndReturnMPCallBlueBlocking @bot_blue MPCall_27_0xb4 mr r8, r30 bl SchTaskUnrdy lis r16, 0x7fff addi r18, r30, 0x08 ori r16, r16, 0xffff stw r31, 0x0000(r18) InsertAsPrev r18, r31, scratch=r19 lwz r18, 0x0020(r31) addi r18, r18, 0x01 stw r18, 0x0020(r31) cmpw r4, r16 beq MPCall_27_0x138 addi r29, r30, 0x20 li r8, 0x02 stw r30, 0x0018(r29) stb r8, 0x0014(r29) mr r8, r4 ; r1 = kdp ; r8 = multiple (pos: /250; neg: /250000) bl TimebaseTicksPerPeriod ; r8 = hi ; r9 = lo mr r27, r8 mr r28, r9 bl GetTime mfxer r16 addc r9, r9, r28 adde r8, r8, r27 mtxer r16 stw r8, 0x0038(r29) stw r9, 0x003c(r29) mr r8, r29 bl EnqueueTimer MPCall_27_0x138 b BlockMPCall ####### ####### ######## ####### ## ## ######## ######## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #### ####### ######## ######## ## ## ## ## ###### ######## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ######### ####### ## ## ##### ## ####### ######## ## ## ## DeclareMPCall 29, MPQueryCriticalRegion MPQueryCriticalRegion _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 ; r8 = id bl LookupID cmpwi r9, CriticalRegion.kIDClass bne ReleaseAndReturnMPCallInvalidIDErr mr r31, r8 mfsprg r17, 0 lwz r18, 0x0014(r31) cmpwi r18, 0x00 ; r1 = kdp beq ReleaseAndReturnZeroFromMPCall lwz r30, -0x0008(r17) lwz r16, 0x0018(r31) lwz r17, 0x001c(r31) cmpw r16, r30 cmpw cr1, r17, r4 bne ReleaseAndTimeoutMPCall bne cr1, ReleaseAndTimeoutMPCall ; r1 = kdp b ReleaseAndReturnZeroFromMPCall ####### ####### ######## ######## ## ## #### ######## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ####### ####### ######## ###### ### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ######### ####### ## ## ######## ## ## #### ## DeclareMPCall 28, MPExitCriticalRegion MPExitCriticalRegion _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 ; r8 = id bl LookupID cmpwi r9, CriticalRegion.kIDClass bne ReleaseAndReturnMPCallInvalidIDErr mr r31, r8 mfsprg r17, 0 lwz r16, 0x0018(r31) lwz r30, -0x0008(r17) lwz r18, 0x0014(r31) lwz r17, 0x001c(r31) cmpw r16, r30 cmpw cr1, r17, r4 bne ReleaseAndReturnMPCallOOM bne cr1, ReleaseAndReturnMPCallOOM addi r18, r18, -0x01 cmpwi r18, 0x00 stw r18, 0x0014(r31) ; r1 = kdp bne ReleaseAndReturnZeroFromMPCall stw r18, 0x0018(r31) stw r18, 0x001c(r31) mr r8, r3 bl UnblockBlueIfCouldBePolling lwz r16, 0x0008(r31) cmpw r16, r31 ; r1 = kdp beq ReleaseAndReturnZeroFromMPCall addi r8, r16, -0x08 lbz r17, 0x0037(r8) cmpwi r17, 0x01 bne MPCall_28_0x94 addi r8, r8, 0x20 bl DequeueTimer MPCall_28_0x94 lwz r16, 0x0008(r31) RemoveFromList r16, scratch1=r17, scratch2=r18 lwz r18, 0x0020(r31) addi r18, r18, -0x01 stw r18, 0x0020(r31) addi r8, r16, -0x08 lwz r17, 0x0088(r8) lwz r18, 0x00fc(r17) subi r18, r18, 4 stw r18, 0x00fc(r17) li r17, 0x01 stb r17, 0x0019(r8) bl SchRdyTaskNow bl CalculateTimeslice bl FlagSchEvaluationIfTaskRequires ; r1 = kdp b ReleaseAndReturnZeroFromMPCall ####### ####### ######## ######## ######## ## ######## ######## ######## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ####### ######## ######## ## ## ###### ## ###### ## ###### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ######### ####### ## ## ######## ######## ######## ######## ## ######## DeclareMPCall 26, MPDeleteCriticalRegion MPDeleteCriticalRegion _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 ; r8 = id bl LookupID cmpwi r9, CriticalRegion.kIDClass mr r31, r8 bne ReleaseAndReturnMPCallInvalidIDErr mr r8, r3 bl UnblockBlueIfCouldBePolling MPCall_26_0x34 addi r30, r31, 0x00 lwz r16, 0x0008(r31) cmpw r16, r30 addi r8, r16, -0x08 beq MPCall_26_0x98 lwz r17, 0x0088(r8) li r18, kMPDeletedErr stw r18, 0x011c(r17) lbz r17, 0x0037(r8) cmpwi r17, 0x01 bne MPCall_26_0x68 addi r8, r8, 0x20 bl DequeueTimer MPCall_26_0x68 lwz r16, 0x0008(r31) RemoveFromList r16, scratch1=r17, scratch2=r18 addi r8, r16, -0x08 bl SchRdyTaskNow bl FlagSchEvaluationIfTaskRequires b MPCall_26_0x34 MPCall_26_0x98 mr r8, r31 bl PoolFree mr r8, r3 bl DeleteID ; r1 = kdp b ReleaseAndReturnZeroFromMPCall ######## ## ## ######## ## ## ######## ## ## ## ## ### ## ## ## ## ## ## #### ## ## ###### ## ## ###### ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ## ### ## ######## ### ######## ## ## ## ###### ######## ####### ## ## ######## ###### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #### ######## ## ## ## ## ######## ###### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ## ## ####### ####### ## ###### ;_______________________________________________________________________ ; Lifted from docs: ; ; An event group is essentially a group of binary semaphores. You can use ; event groups to indicate a number of simple events. For example, a task ; running on a server may need to be aware of multiple message queues. ; Instead of trying to poll each one in turn, the server task can wait on ; an event group. Whenever a message is posted on a queue, the poster can ; also set the bit corresponding to that queue in the event group. Doing ; so notifies the task, and it then knows which queue to access to extract ; the message. In Multiprocessing Services, an event group consists of ; thirty-two 1-bit flags, each of which may be set independently. When a ; task receives an event group, it receives all 32-bits at once (that is, ; it cannot poll individual bits), and all the bits in the event group are ; subsequently cleared. ;_______________________________________________________________________ ## ####### ######## ###### ######## ######## ### ######## ######## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ######## ###### ## ######## ###### ## ## ## ###### ######### ## ## ## ## ## ## ######### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ####### ######## ###### ## ## ######## ## ## ## ######## DeclareMPCall 49, MPCreateEvent ; RET OSStatus r3, MPEventID r4 ; called using the FE1F trap by the 68k ROM MPCreateEvent li r8, EventGroup.Size bl PoolAllocClear mr. r31, r8 beq ScrambleMPCall InitList r8, EventGroup.kSignature, scratch=r16 _Lock PSA.SchLock, scratch1=r16, scratch2=r17 li r9, EventGroup.kIDClass bl MakeID cmpwi r8, 0 bne+ @success mr r8, r31 bl PoolFree b ReleaseAndScrambleMPCall @success mfsprg r30, 0 lwz r30, EWA.PA_CurTask(r30) stw r8, EventGroup.LLL + LLL.Freeform(r31) lwz r17, Task.ProcessID(r30) stw r17, EventGroup.ProcessID(r31) mr r4, r8 b ReleaseAndReturnZeroFromMPCall ######## ##### ######## ######## ######## ## ######## ######## ######## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ####### ## ## ###### ## ## ###### ## ###### ## ###### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ##### ######## ######## ######## ######## ######## ## ######## DeclareMPCall 50, MPDeleteEvent ; ARG MPEventID r3 ; RET OSStatus r3 MPDeleteEvent _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 ; r8 = id bl LookupID cmpwi r9, EventGroup.kIDClass mr r31, r8 bne ReleaseAndReturnMPCallInvalidIDErr mr r8, r3 bl UnblockBlueIfCouldBePolling MPDeleteEvent_0x34 addi r30, r31, 0x00 lwz r16, 0x0008(r31) cmpw r16, r30 addi r8, r16, -0x08 beq MPDeleteEvent_0x98 lwz r17, 0x0088(r8) li r18, kMPDeletedErr stw r18, 0x011c(r17) lbz r17, 0x0037(r8) cmpwi r17, 0x01 bne MPDeleteEvent_0x68 addi r8, r8, 0x20 bl DequeueTimer MPDeleteEvent_0x68 lwz r16, 0x0008(r31) RemoveFromList r16, scratch1=r17, scratch2=r18 addi r8, r16, -0x08 bl SchRdyTaskNow bl FlagSchEvaluationIfTaskRequires b MPDeleteEvent_0x34 MPDeleteEvent_0x98 mr r8, r31 bl PoolFree mr r8, r3 bl DeleteID ; r1 = kdp b ReleaseAndReturnZeroFromMPCall ######## ## ######## ###### ######## ######## ## #### ## ## ## ## ## ## ## ## ## ## ## ####### ## ###### ###### ###### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ###### ######## ###### ######## ## DeclareMPCall 51, MPSetEvent ; ARG MPEventID r3, MPEventFlags r4 ; RET OSStatus r3 MPSetEvent _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, EventGroup.kIDClass mr r31, r8 bne ReleaseAndReturnMPCallInvalidIDErr mr r8, r4 bl SetEvent ; r1 = kdp b ReleaseAndReturnZeroFromMPCall ### ######## ###### ######## ######## ### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ###### ###### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ######## ###### ######## ## ### ; ARG Event *r31, flags r8 SetEvent lwz r16, EventGroup.Flags(r31) or r16, r16, r8 stw r16, EventGroup.Flags(r31) mflr r27 lwz r8, EventGroup.LLL + LLL.Freeform(r31) bl UnblockBlueIfCouldBePolling ; lwz r16, EventGroup.LLL + LLL.Next(r31) cmpw r16, r31 subi r8, r16, Task.QueueMember beq @no_task_waiting ; CASE 1: task needs unblocking ; Rerun SC instruction in task context lwz r17, Task.ContextBlockPtr(r8) lwz r18, ContextBlock.CodePtr(r17) subi r18, r18, 4 stw r18, ContextBlock.CodePtr(r17) ; Cancel timeout lbz r17, Task.Timer + Timer.Byte3(r8) cmpwi r17, 1 bne @timer_not_armed addi r8, r8, Task.Timer bl DequeueTimer @timer_not_armed ; Remove this task from my wait queue lwz r16, EventGroup.LLL + LLL.Next(r31) RemoveFromList r16, scratch1=r17, scratch2=r18 lwz r18, EventGroup.Counter(r31) subi r18, r18, 1 stw r18, EventGroup.Counter(r31) ; Latency protection priority subi r8, r16, Task.QueueMember li r17, Task.kLatencyProtectPriority stb r17, Task.Priority(r8) bl SchRdyTaskNow bl CalculateTimeslice bl FlagSchEvaluationIfTaskRequires @no_task_waiting lwz r16, EventGroup.SWI(r31) rlwinm. r17, r16, 0, 27, 27 ; CASE 2: no task waiting. beq @return ; CASE 3: SOFTWARE INTERRUPT lwz r17, KDP.PA_ECB(r1) lwz r26, PSA.PA_BlueTask(r1) lwz r18, ContextBlock.EDPOffsetSWIRelated(r17) lwz r19, ContextBlock.SWIEventGroupID(r17) cmpwi cr1, r18, 0 cmpwi r19, 0 bne cr1, @do_not_save_swi_event_id bne @return lwz r8, EventGroup.LLL + LLL.Freeform(r31) ; contains my ID stw r8, ContextBlock.SWIEventGroupID(r17) b @common_case @do_not_save_swi_event_id ; There is an EDP table of SWI-EventGroup IDs... set ours, cancel if already set lwz r9, KDP.PA_EmulatorData(r1) rlwinm r16, r16, 2, 26, 29 add r18, r18, r9 lwzx r19, r16, r18 cmpwi r19, 0 bne @return ; Set! lwz r8, EventGroup.LLL + LLL.Freeform(r31) ; my ID stwx r8, r16, r18 ; Find the highest interrupt level with a nonzero thing li r19, 7*4 li r9, 4 @loop lwzx r8, r19, r18 cmpwi r8, 0 bne @exit_loop subf. r19, r9, r19 bgt @loop bl panic @exit_loop ; Can I interrupt the current interrupt? cmplw r16, r19 srwi r16, r16, 2 blt @return stw r16, ContextBlock.SWIEventGroupID(r17) @common_case lwz r16, Task.Flags(r26) lbz r19, Task.State(r26) ori r16, r16, (1 << (31 - Task.kFlagSchToInterruptEmu)) stw r16, Task.Flags(r26) ; But what *is* MCR? lwz r17, PSA.MCR(r1) lwz r16, KDP.PostIntMaskInit(r1) lwz r8, KDP.ClearIntMaskInit(r1) and r16, r16, r8 or r17, r17, r16 stw r17, PSA.MCR(r1) cmpwi r19, 0 addi r16, r26, Task.QueueMember bne @task_already_running ; De-fang the blocking timeout RemoveFromList r16, scratch1=r17, scratch2=r18 lbz r17, Task.Timer + Timer.Byte3(r26) cmpwi r17, 1 bne @timer_not_armed_2 addi r8, r26, Task.Timer bl DequeueTimer @timer_not_armed_2 lwz r18, PSA.PA_BlueTask(r1) li r16, Task.kCriticalPriority stb r16, Task.Priority(r26) mr r8, r26 bl SchRdyTaskLater mr r8, r26 bl CalculateTimeslice @task_already_running mr r8, r26 bl FlagSchEvaluationIfTaskRequires @return mtlr r27 blr ######## ####### ######## ## ## ### #### ######## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ####### ####### ###### ## ## ## ## ## ## ## ## ## ## ## ## ## ######### ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ######### ######## ### ### ## ## #### ## DeclareMPCall 52, MPWaitForEvent ; ARG MPEventID r3, Duration r5 ; RET OSStatus r3, MPEventFlags r4 ; called using the FE1F trap by the 68k ROM MPWaitForEvent _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 ; Check that the Event Group ID in r3 is valid. bl LookupID cmpwi r9, EventGroup.kIDClass bne ReleaseAndReturnMPCallInvalidIDErr mr r31, r8 lwz r16, 0x0010(r31) cmpwi r16, 0 beq MPWaitForEvent_field_10_was_zero mr r4, r16 li r16, 0 stw r16, 0x0010(r31) lwz r16, 0x0018(r31) lwz r17, KDP.PA_ECB(r1) rlwinm. r18, r16, 0, 27, 27 rlwinm r16, r16, 2, 26, 29 beq ReleaseAndReturnZeroFromMPCall lwz r18, 0x00c8(r17) lwz r9, 0x0634(r1) cmpwi r18, 0x00 add r18, r18, r9 bne MPWaitForEvent_0x84 lwz r18, 0x00d0(r17) cmpw r18, r3 li r18, 0x00 ; r1 = kdp bne ReleaseAndReturnZeroFromMPCall stw r18, 0x00d0(r17) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall MPWaitForEvent_0x84 lwzx r19, r16, r18 cmpw r19, r3 li r19, 0x00 ; r1 = kdp bne ReleaseAndReturnZeroFromMPCall stwx r19, r16, r18 li r19, 0x1c li r9, 0x04 MPWaitForEvent_0xa0 lwzx r8, r19, r18 cmpwi r8, 0x00 bne MPWaitForEvent_0xb4 subf. r19, r9, r19 bgt MPWaitForEvent_0xa0 MPWaitForEvent_0xb4 srwi r19, r19, 2 stw r19, 0x00d0(r17) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall MPWaitForEvent_field_10_was_zero mfsprg r30, 0 cmpwi r5, 0 lwz r19, EWA.PA_CurTask(r30) beq ReleaseAndTimeoutMPCall ;special case: blue may not block lwz r16, Task.Flags(r19) rlwinm. r16, r16, 0, Task.kFlagBlue, Task.kFlagBlue beq @bot_blue stw r3, PSA.BlueSpinningOn(r1) b ReleaseAndReturnMPCallBlueBlocking @bot_blue ; MOVE TASK OUT OF QUEUE AND INTO EVENT GROUP mr r8, r19 bl SchTaskUnrdy lwz r19, EWA.PA_CurTask(r30) addi r16, r31, EventGroup.LLL addi r17, r19, Task.QueueMember stw r16, LLL.FreeForm(r17) InsertAsPrev r17, r16, scratch=r18 lwz r18, EventGroup.Counter(r31) addi r18, r18, 1 stw r18, EventGroup.Counter(r31) lisori r16, 0x7fffffff ; LONG_MAX addi r30, r19, Task.Timer cmpw r5, r16 li r16, 2 beq @wait_forever ; never trigger max-wait timers stb r16, Timer.Kind(r30) stw r19, Timer.ParentTaskPtr(r30) mr r8, r5 bl TimebaseTicksPerPeriod mr r27, r8 mr r28, r9 bl GetTime mfxer r16 addc r9, r9, r28 adde r8, r8, r27 mtxer r16 stw r8, Timer.Time(r30) stw r9, Timer.Time+4(r30) mr r8, r30 bl EnqueueTimer @wait_forever b BlockMPCall ######## ####### ######## ####### ## ## ######## ######## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #### ####### ####### ###### ## ## ## ## ###### ######## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ####### ######## ##### ## ####### ######## ## ## ## DeclareMPCall 53, MPQueryEvent ; Returns Timeout if no flags are set, otherwise NoErr ; ARG MPEventID r3 ; RET OSStatus r3 MPQueryEvent _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 ; r8 = id bl LookupID cmpwi r9, EventGroup.kIDClass bne ReleaseAndReturnMPCallInvalidIDErr mr r31, r8 lwz r16, 0x0010(r31) cmpwi r16, 0x00 beq ReleaseAndTimeoutMPCall ; r1 = kdp b ReleaseAndReturnZeroFromMPCall ######## ## ######## ###### ######## ######## ###### ## ## #### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ####### ## ## ###### ###### ###### ## ###### ## ## ## ## ## ######### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ## ######## ###### ######## ## ###### ### ### #### DeclareMPCall 54, MPSetSWIEvent ; ARG MPEventID r3, int r4 swi ; called using the FE1F trap by the 68k ROM MPSetSWIEvent _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, EventGroup.kIDClass bne ReleaseAndReturnMPCallInvalidIDErr mr r31, r8 li r17, 1 cmpwi r4, 0 cmplwi cr1, r4, 8 lwz r16, EventGroup.SWI(r31) beq @use_1 bgt cr1, @use_1 mr r17, r4 @use_1 ; r17 = 1 if outside 1-8 (inc) range ori r16, r16, 0x10 rlwimi r16, r17, 0, 28, 31 stw r16, EventGroup.SWI(r31) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall ######## #### ## ## ######## ######## ###### ## ## ### ### ## ## ## ## ## ## ## #### #### ## ## ## ## ## ## ## ### ## ###### ######## ###### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #### ## ## ######## ## ## ###### ## ##### ######## ###### ######## ######## ### ######## ######## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ######## ###### ## ## ## ###### ######### ## ## ## ## ## ## ## ######### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##### ## ###### ## ## ######## ## ## ## ######## DeclareMPCall 40, NKCreateTimer NKCreateTimer ; OUTSIDE REFERER li r8, 0x40 ; r1 = kdp ; r8 = size bl PoolAllocClear ; r8 = ptr mr. r31, r8 beq ScrambleMPCall _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r31 li r9, 0x03 ; r1 = kdp ; r9 = kind bl MakeID cmpwi r8, 0x00 bne NKCreateTimer_0x48 mr r8, r31 bl PoolFree b ReleaseAndScrambleMPCall NKCreateTimer_0x48 mfsprg r30, 0 stw r8, 0x0000(r31) lwz r30, -0x0008(r30) mr r4, r8 lwz r17, 0x0060(r30) stw r17, 0x0010(r31) bl GetTime stw r8, 0x0038(r31) stw r9, 0x003c(r31) lis r17, 0x5449 ori r17, r17, 0x4d45 stw r17, 0x0004(r31) li r17, 0x03 stb r17, 0x0014(r31) li r17, 0x00 stb r17, 0x0016(r31) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall ## ## ######## ######## ######## ## ######## ######## ######## ## ## #### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ## ###### ## ###### ######### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ## ######## ######## ######## ######## ## ######## DeclareMPCall 41, NKDeleteTimer NKDeleteTimer ; OUTSIDE REFERER _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 ; r8 = id bl LookupID cmpwi r9, Timer.kIDClass mr r31, r8 bne ReleaseAndReturnMPCallInvalidIDErr mr r8, r3 bl DeleteID lwz r16, 0x0008(r31) cmpwi r16, 0x00 beq NKDeleteTimer_0x48 mr r8, r31 bl DequeueTimer NKDeleteTimer_0x48 _AssertAndRelease PSA.SchLock, scratch=r16 lwz r8, 0x001c(r31) cmpwi r8, 0x00 bnel PoolFree mr r8, r31 bl PoolFree b ReturnZeroFromMPCall ####### ##### ######## ###### ######## ######## ## ## ####### ######## #### ######## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ## #### ####### ## ## ## ###### ###### ## ## ## ## ## ## ## ## ###### ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ####### ##### ## ###### ######## ## ## ## ####### ## #### ## ## ; ARG TimerID r3, EventGroup/Queue/SemaphoreID r4, long r5, long r6, long r7 ; RET OSStatus r3 DeclareMPCall 30, NKSetTimerNotify NKSetTimerNotify _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, Timer.kIDClass mr r31, r8 bne ReleaseAndReturnMPCallInvalidIDErr lbz r16, Timer.Kind(r31) cmpwi r16, 3 bne ReleaseAndReturnMPCallInvalidIDErr mr r8, r4 bl LookupID cmpwi r9, Semaphore.kIDClass cmpwi cr2, r9, Queue.kIDClass beq @SEMAPHORE cmpwi r9, EventGroup.kIDClass beq cr2, @QUEUE bne ReleaseAndReturnMPCallInvalidIDErr @EVENTGROUP stw r4, Timer.EventGroupID(r31) stw r5, Timer.EventGroupFlags(r31) b ReleaseAndReturnZeroFromMPCall @QUEUE stw r4, Timer.MessageQueueID(r31) lwz r16, ContextBlock.r6(r6) lwz r17, ContextBlock.r7(r6) stw r5, Timer.Message1(r31) ; notifyParam1 stw r16, Timer.Message2(r31) ; notifyParam2 stw r17, Timer.Message3(r31) ; notifyParam3 b ReleaseAndReturnZeroFromMPCall @SEMAPHORE stw r4, Timer.SemaphoreID(r31) b ReleaseAndReturnZeroFromMPCall ####### ## ######## ### ######## ## ## ## ## #### ## ## ## ## ## ### ### ## ## ## ## ## ## ## #### #### ####### ## ## ## ## ######## ## ### ## ## ## ## ######### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ####### ###### ## ## ## ## ## ## ## ; Time can be absolute or delta, and a duration (r4) ; or timebase time (r4/r5). ; ARG TimerID r3, long r4, long r5, OptionBits r6 ; RET OSStatus r3 DeclareMPCall 31, MPArmTimer MPArmTimer _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, Timer.kIDClass mr r31, r8 bne ReleaseAndReturnMPCallInvalidIDErr lbz r16, Timer.Kind(r31) cmpwi r16, Timer.kKind3 bne ReleaseAndReturnMPCallInvalidIDErr ; Disarm if armed lwz r16, Timer.QueueLLL + LLL.Freeform(r31) cmpwi r16, 0 mr r8, r31 beq @no_disarm bl DequeueTimer @no_disarm ; Ah... reserve a note if a message is to be sent lwz r9, Timer.ReservedMessage(r31) lwz r8, Timer.MessageQueueID(r31) cmpwi r9, 0 cmpwi cr1, r8, 0 bne @already_got_note beq cr1, @no_queue bl LookupID cmpwi r9, Queue.kIDClass bne @no_queue lwz r9, Queue.ReserveCount(r8) li r8, Message.Size cmpwi r9, 0 bne @already_got_notr bl PoolAllocClear mr. r30, r8 beq ReleaseAndScrambleMPCall lisori r8, 'note' stw r8, Message.LLL + LLL.Signature(r30) stw r30, 0x001c(r31) @already_got_note @already_got_notr @no_queue ; Calculate firing solution lwz r16, ContextBlock.r6(r6) rlwinm. r9, r16, 0, kMPTimeIsDurationMask mr r8, r4 beq @not_duration bl TimebaseTicksPerPeriod mr r4, r8 mr r5, r9 @not_duration lwz r16, ContextBlock.r6(r6) rlwinm. r8, r16, 0, kMPTimeIsDeltaMask mfxer r17 beq @not_delta lwz r19, Timer.Time + 4(r31) lwz r18, Timer.Time(r31) addc r5, r5, r19 adde r4, r4, r18 mtxer r17 @not_delta stw r4, Timer.Time(r31) stw r5, Timer.Time + 4(r31) ; Teensy little option: keep after firing? lwz r16, ContextBlock.r6(r6) rlwinm. r16, r16, 0, kMPPreserveTimerIDMask li r17, 0 beq @no_preserve li r17, 1 @no_preserve stb r17, Timer.KeepAfterFiring(r31) mr r8, r31 bl EnqueueTimer b ReleaseAndReturnZeroFromMPCall ####### ####### ######## ###### ### ## ## ###### ######## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## ## #### ## ## ## ## ####### ####### ## ## ## ## ## ## ## ## ###### ## ## ## ## ## ######### ## #### ## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ####### ######### ## ###### ## ## ## ## ###### ######## ######## ; ARG TimerID r3 ; RET OSStatus r3, AbsoluteTime r4/r5 DeclareMPCall 32, MPCancelTimer MPCancelTimer _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, Timer.kIDClass mr r31, r8 bne ReleaseAndReturnMPCallInvalidIDErr lbz r16, Timer.Byte3(r31) cmpwi r16, 1 bne @say_no_time_remained lwz r4, Timer.Time(r31) lwz r5, Timer.Time + 4(r31) bl GetTime mfxer r16 subfc r5, r9, r5 subfe. r4, r8, r4 mtxer r16 bge+ @can_return_time_remaining @say_no_time_remained li r4, 0 li r5, 0 @can_return_time_remaining lwz r16, Timer.QueueLLL + LLL.Freeform(r31) cmpwi r16, 0 mr r8, r31 beq @not_queued bl DequeueTimer @not_queued b ReleaseAndReturnZeroFromMPCall ## ## ####### ######## #### ######## #### ###### ### ######## #### ####### ## ## ###### ### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## #### ## ## ## ## ## ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ## ## ## ## ###### ## ## ## ## ## ## ## ## ## ## ## ###### ## #### ## ## ## ## ## ## ## ######### ## ## ## ## ## #### ## ## ### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ####### ## #### ## #### ###### ## ## ## #### ####### ## ## ###### ####### ## ## ## ###### ######## ######## ### ######## ######## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ## ## ## ## ######## ## ## ## ## ## ## ######## ###### ## ## ## ###### ## ## ######### ## #### ## ## ## ## ######### ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ####### ## ## ## ###### ## ## ######## ## ## ## ######## ; RET OSErr r3, NotificationID r4 DeclareMPCall 64, MPCreateNotification MPCreateNotification li r8, Notification.Size bl PoolAllocClear mr. r31, r8 beq ScrambleMPCall lisori r16, Notification.kSignature stw r16, Notification.Signature(r31) _Lock PSA.SchLock, scratch1=r16, scratch2=r17 li r9, Notification.kIDClass bl MakeID cmpwi r8, 0 bne+ @nofail mr r8, r31 bl PoolFree b ReleaseAndScrambleMPCall @nofail mfsprg r30, 0 lwz r30, EWA.PA_CurTask(r30) stw r8, Notification.TaskPtr(r31) lwz r17, Task.ProcessID(r30) stw r17, Notification.ProcessID(r31) mr r4, r8 b ReleaseAndReturnZeroFromMPCall ####### ######## ## ## ######## ######## ## ######## ######## ######## ## ## ## ### ## ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ## ## ## ######## ####### ## ## ## ## ## ###### ## ###### ## ###### ## ## ## ## #### ## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ####### ###### ## ## ######## ######## ######## ######## ## ######## ; ARG NotificationID r3 ; RET OSErr r3 DeclareMPCall 65, MPDeleteNotification MPDeleteNotification _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, Notification.kIDClass mr r31, r8 bne ReleaseAndReturnMPCallInvalidIDErr mr r8, r31 bl PoolFree mr r8, r3 bl DeleteID b ReleaseAndReturnZeroFromMPCall ####### ######## ## ## ###### ### ## ## ###### ######## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ## ## ## ######## ## ## ## ## ## ## ## ## ## ###### ###### ## ## ## ## #### ## ######### ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ####### ## ## ## ###### ## ## ####### ###### ######## DeclareMPCall 67, MPCauseNotification MPCauseNotification _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID cmpwi r9, Notification.kIDClass mr r30, r8 bne ReleaseAndReturnMPCallInvalidIDErr bl CauseNotification mr r3, r8 b ReleaseAndReturnMPCall ### ## ## ###### ### ## ## ###### ######## ### ## ### ## ## ## ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ###### ## ## ## #### ## ######### ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## ### ## ## ###### ## ## ####### ###### ######## ### ; ARG Notification *r30 ; RET OSStatus r8 CauseNotification mflr r29 lwz r16, 0x000c(r30) lwz r17, 0x0024(r30) cmplwi r16, 0x00 cmplwi cr1, r17, 0x00 bne @0x28 bne cr1, @0x28 lwz r18, 0x001c(r30) cmplwi r18, 0x00 beq @fail_insufficient_resources @0x28 ; SEND MESSAGE TO QUEUE lwz r8, Notification.QueueID(r30) cmplwi r8, 0 beq @NO_QUEUE bl LookupID cmpwi r9, Queue.kIDClass mr r31, r8 bne @fail_invalid_id lwz r16, Queue.ReserveCount(r31) cmpwi r16, 0 lwz r17, Queue.ReservePtr(r31) beq @no_notr ;use notr mr. r8, r17 lwz r17, Message.LLL + LLL.Next(r17) beq @fail_insufficient_resources stw r17, Queue.ReservePtr(r31) b @queue_common @no_notr ; ... allocate message anew li r8, Message.Size bl PoolAlloc cmpwi r8, 0 beq @fail_unknown_err @queue_common lwz r16, Notification.MsgWord1(r30) lwz r17, Notification.MsgWord2(r30) lwz r18, Notification.MsgWord3(r30) stw r16, Message.Word1(r8) stw r17, Message.Word2(r8) stw r18, Message.Word3(r8) bl EnqueueMessage ; Message *r8, Queue *r31 @NO_QUEUE ; SIGNAL SEMAPHORE lwz r8, Notification.SemaphoreID(r30) cmplwi r8, 0 beq @NO_SEMAPHORE bl LookupID cmpwi r9, Semaphore.kIDClass mr r31, r8 bne @fail_invalid_id bl SignalSemaphore @NO_SEMAPHORE ; SET EVENT lwz r8, Notification.EventGroupID(r30) cmplwi r8, 0 beq @NO_EVENT_GROUP bl LookupID cmpwi r9, EventGroup.kIDClass mr r31, r8 bne @fail_invalid_id lwz r8, Notification.EventFlags(r30) bl SetEvent @NO_EVENT_GROUP ; ... fall thru to success @succeed mtlr r29 li r8, 0x00 blr @fail_unknown_err mtlr r29 li r8, -29294 blr @fail_insufficient_resources mtlr r29 li r8, kMPInsufficientResourcesErr blr @fail_invalid_id mtlr r29 li r8, kMPInvalidIDErr blr ####### ####### ## ## ## ## ####### ######## #### ######## ## ## ## ## ## ## ### ## ### ### ## ## ## ## ## ## ## ## ## ## #### ## #### #### ## ## ## ## ## ## #### ######## ######## ## ## ## ## ### ## ## ## ## ## ## ###### ## ## ## ## ## ## #### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ####### ####### ## ## ## ## ####### ######## #### ## ## DeclareMPCall 66, MPModifyNotification MPModifyNotification _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 ; r8 = id bl LookupID cmpwi r9, Notification.kIDClass mr r31, r8 bne ReleaseAndReturnMPCallInvalidIDErr mr r8, r4 ; r8 = id bl LookupID cmpwi r9, Semaphore.kIDClass cmpwi cr2, r9, 0x04 beq MPCall_66_0x74 cmpwi r9, 0x09 beq cr2, MPCall_66_0x58 bne ReleaseAndReturnMPCallInvalidIDErr stw r4, 0x001c(r31) stw r5, 0x0020(r31) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall MPCall_66_0x58 stw r4, 0x000c(r31) lwz r16, ContextBlock.r6(r6) lwz r17, ContextBlock.r7(r6) stw r5, 0x0010(r31) stw r16, 0x0014(r31) stw r17, 0x0018(r31) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall MPCall_66_0x74 stw r4, 0x0024(r31) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall ## ####### ####### ## ## ## ## ####### ######## ######## ### ######## ### ## ## ###### #### ## ## ## ## ### ## ### ### ## ## ## ## ## ## ## ## ## ## ## ## ### ### ## ## ## ## ## ## #### ## #### #### ## ## ## ## ## ## ## ## ## ## ## ## #### #### ## ## ####### ####### ## ## ## ## ### ## ## ## ## ## ######## ## ## ######## ## ## ## ### ## ###### ## ## ## ## ## #### ## ## ## ## ## ## ## ######### ## ## ######### ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ######### ####### ## ## ## ## ####### ######## ## ## ## ## ## ## ## ## ## ###### DeclareMPCall 128, MPCall_128 MPCall_128 ; OUTSIDE REFERER _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 ; r8 = id bl LookupID cmpwi r9, Notification.kIDClass mr r31, r8 bne ReleaseAndReturnMPCallInvalidIDErr cmpwi r4, 0x04 cmpwi cr1, r4, 0x09 beq MPCall_128_0x40 beq cr1, MPCall_128_0x58 b ReleaseAndReturnParamErrFromMPCall MPCall_128_0x40 lwz r16, ContextBlock.r6(r6) lwz r17, ContextBlock.r7(r6) stw r5, 0x0010(r31) stw r16, 0x0014(r31) stw r17, 0x0018(r31) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall MPCall_128_0x58 stw r5, 0x0020(r31) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall ### ######## ## ## ## ## ######## ## ## ## ######## ### ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ## ## ## ## ######## ## ## ## ## ## ######## ## ## ## ###### ## ## ## ## ## ## ## #### ## ## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ### ## ## ####### ## ## ######## ######## ####### ######## ### ; ARG OpaqueID r8 ; MP calls by blue return kMPBlueBlockingErr instead of blocking, ; in order to maintain system responsiveness. Blue might poll these ; calls, e.g. at SysTask time. This function, called when a ; blocking object becomes "available", unblocks blue to give it ; another shot. UnblockBlueIfCouldBePolling lwz r9, PSA.BlueSpinningOn(r1) lwz r19, PSA.PA_BlueTask(r1) cmpw r8, r9 bnelr li r9, -1 mflr r24 stw r9, PSA.BlueSpinningOn(r1) lbz r17, Task.State(r19) cmpwi r17, 0 addi r16, r19, Task.QueueMember bne @blue_already_running RemoveFromList r16, scratch1=r17, scratch2=r18 lbz r17, Task.Timer + Timer.Byte3(r19) cmpwi r17, 1 bne @no_timer_to_dequeue addi r8, r19, Task.Timer bl DequeueTimer lwz r19, PSA.PA_BlueTask(r1) @no_timer_to_dequeue li r16, Task.kLatencyProtectPriority stb r16, Task.Priority(r19) lwz r8, PSA.PA_BlueTask(r1) bl SchRdyTaskNow @blue_already_running lwz r8, PSA.PA_BlueTask(r1) mtlr r24 b FlagSchEvaluationIfTaskRequires ## ####### ##### ######## #### ###### ###### ### ## ## #### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ####### ## ## ######## ## ## #### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ######### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###### ######### ##### ######## #### ###### ###### ## ## ######## ######## DeclareMPCall 120, MPCall_120 MPCall_120 _Lock PSA.SchLock, scratch1=r16, scratch2=r17 mr r8, r3 bl LookupID mr r31, r8 cmpwi r9, Semaphore.kIDClass cmpwi cr1, r9, Queue.kIDClass beq @SEMAPHORE beq cr1, @QUEUE cmpwi r9, EventGroup.kIDClass cmpwi cr1, r9, CriticalRegion.kIDClass beq @EVENT_GROUP beq cr1, @CRITICAL_REGION cmpwi r9, Notification.kIDClass cmpwi cr1, r9, AddressSpace.kIDClass beq @NOTIFICATION beq cr1, @ADDRESS_SPACE b ReleaseAndReturnParamErrFromMPCall @NOTIFICATION lisori r8, Notification.kFirstID cmpw r8, r4 bne ReleaseAndReturnParamErrFromMPCall cmplwi r5, 0 bne @notification_not_0 ; r5 == 0 lisori r16, Notification.kFirstID stw r16, ContextBlock.r6(r6) lwz r16, Notification.ProcessID(r31) stw r16, ContextBlock.r7(r6) lwz r16, Notification.Signature(r31) stw r16, ContextBlock.r8(r6) lwz r16, 0x000c(r31) stw r16, ContextBlock.r9(r6) li r16, 16 stw r16, ContextBlock.r10(r6) b ReleaseAndReturnZeroFromMPCall @notification_not_0 cmplwi r5, 16 bne @notification_not_16 ; r5 == 16 lwz r16, 0x0010(r31) stw r16, ContextBlock.r6(r6) lwz r16, 0x0014(r31) stw r16, ContextBlock.r7(r6) lwz r16, 0x0018(r31) stw r16, ContextBlock.r8(r6) lwz r16, 0x001c(r31) stw r16, ContextBlock.r9(r6) li r16, 16 stw r16, ContextBlock.r10(r6) b ReleaseAndReturnZeroFromMPCall @notification_not_16 cmplwi r5, 32 bne @notification_not_32 ; r5 == 32 lwz r16, 0x0020(r31) stw r16, ContextBlock.r6(r6) lwz r16, 0x0024(r31) stw r16, ContextBlock.r7(r6) li r16, 8 stw r16, ContextBlock.r10(r6) b ReleaseAndReturnZeroFromMPCall @notification_not_32 cmpwi r5, 40 bne ReleaseAndReturnParamErrFromMPCall ; r5 == 40 li r16, 0x00 stw r16, ContextBlock.r10(r6) b ReleaseAndReturnZeroFromMPCall @CRITICAL_REGION lisori r8, 0x00060001 cmpw r8, r4 bne ReleaseAndReturnParamErrFromMPCall cmplwi r5, 0x00 bne @154 lis r16, 0x06 ori r16, r16, 0x01 stw r16, ContextBlock.r6(r6) lwz r16, 0x0010(r31) stw r16, ContextBlock.r7(r6) lwz r16, 0x0004(r31) stw r16, ContextBlock.r8(r6) lwz r16, 0x0020(r31) stw r16, ContextBlock.r9(r6) li r16, 0x10 stw r16, ContextBlock.r10(r6) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall @154 cmplwi r5, 0x10 bne @1a0 addi r17, r31, 0x00 lwz r18, 0x0008(r31) li r16, 0x00 cmpw r17, r18 beq @174 lwz r16, -0x0008(r18) @174 stw r16, ContextBlock.r6(r6) lwz r16, 0x0018(r31) cmpwi r16, 0x00 beq @188 lwz r16, 0x0000(r16) @188 stw r16, ContextBlock.r7(r6) lwz r16, 0x0014(r31) stw r16, ContextBlock.r8(r6) li r16, 0x0c stw r16, ContextBlock.r10(r6) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall @1a0 cmpwi r5, 0x1c bne ReleaseAndReturnParamErrFromMPCall li r16, 0x00 stw r16, ContextBlock.r10(r6) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall @EVENT_GROUP lis r8, 0x09 ori r8, r8, 0x01 cmpw r8, r4 bne ReleaseAndReturnParamErrFromMPCall cmplwi r5, 0x00 bne @1fc lis r16, 0x09 ori r16, r16, 0x01 stw r16, ContextBlock.r6(r6) lwz r16, 0x0014(r31) stw r16, ContextBlock.r7(r6) lwz r16, 0x0004(r31) stw r16, ContextBlock.r8(r6) lwz r16, 0x001c(r31) stw r16, ContextBlock.r9(r6) li r16, 0x10 stw r16, ContextBlock.r10(r6) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall @1fc cmplwi r5, 0x10 bne @234 addi r17, r31, 0x00 lwz r18, 0x0008(r31) li r16, 0x00 cmpw r17, r18 beq @21c lwz r16, -0x0008(r18) @21c stw r16, ContextBlock.r6(r6) lwz r16, 0x0010(r31) stw r16, ContextBlock.r7(r6) li r16, 0x08 stw r16, ContextBlock.r10(r6) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall @234 cmpwi r5, 0x18 bne ReleaseAndReturnParamErrFromMPCall li r16, 0x00 stw r16, ContextBlock.r10(r6) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall @QUEUE lis r8, 0x04 ori r8, r8, 0x01 cmpw r8, r4 bne ReleaseAndReturnParamErrFromMPCall cmplwi r5, 0x00 bne @290 lis r16, 0x04 ori r16, r16, 0x01 stw r16, ContextBlock.r6(r6) lwz r16, 0x0020(r31) stw r16, ContextBlock.r7(r6) lwz r16, 0x0004(r31) stw r16, ContextBlock.r8(r6) lwz r16, 0x002c(r31) stw r16, ContextBlock.r9(r6) li r16, 0x10 stw r16, ContextBlock.r10(r6) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall @290 cmplwi r5, 0x10 bne @2ec addi r17, r31, 0x00 lwz r18, 0x0008(r31) li r16, 0x00 cmpw r17, r18 beq @2b0 lwz r16, -0x0008(r18) @2b0 stw r16, ContextBlock.r6(r6) lwz r16, 0x0030(r31) stw r16, ContextBlock.r7(r6) lwz r16, 0x0024(r31) stw r16, ContextBlock.r8(r6) lwz r18, 0x0018(r31) addi r17, r31, 0x10 li r16, 0x00 cmpw r17, r18 beq @2dc lwz r16, 0x0010(r18) @2dc stw r16, ContextBlock.r9(r6) li r16, 0x10 stw r16, ContextBlock.r10(r6) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall @2ec cmplwi r5, 0x20 bne @328 lwz r18, 0x0018(r31) addi r17, r31, 0x10 li r16, 0x00 cmpw r17, r18 li r17, 0x00 beq @314 lwz r16, 0x0014(r18) lwz r17, 0x0018(r18) @314 stw r16, ContextBlock.r6(r6) stw r17, ContextBlock.r7(r6) li r16, 0x08 stw r16, ContextBlock.r10(r6) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall @328 cmpwi r5, 0x28 bne ReleaseAndReturnParamErrFromMPCall li r16, 0x00 stw r16, ContextBlock.r10(r6) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall @SEMAPHORE lis r8, 0x05 ori r8, r8, 0x01 cmpw r8, r4 bne ReleaseAndReturnParamErrFromMPCall cmplwi r5, 0x00 bne @384 lis r16, 0x05 ori r16, r16, 0x01 stw r16, ContextBlock.r6(r6) lwz r16, 0x0018(r31) stw r16, ContextBlock.r7(r6) lwz r16, 0x0004(r31) stw r16, ContextBlock.r8(r6) lwz r16, 0x001c(r31) stw r16, ContextBlock.r9(r6) li r16, 0x10 stw r16, ContextBlock.r10(r6) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall @384 cmplwi r5, 0x10 bne @3c4 addi r17, r31, 0x00 lwz r18, 0x0008(r31) li r16, 0x00 cmpw r17, r18 beq @3a4 lwz r16, -0x0008(r18) @3a4 stw r16, ContextBlock.r6(r6) lwz r16, 0x0014(r31) stw r16, ContextBlock.r7(r6) lwz r16, 0x0010(r31) stw r16, ContextBlock.r8(r6) li r16, 0x0c stw r16, ContextBlock.r10(r6) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall @3c4 cmpwi r5, 0x1c bne ReleaseAndReturnParamErrFromMPCall li r16, 0x00 stw r16, ContextBlock.r10(r6) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall @ADDRESS_SPACE lisori r8, 0x00080001 cmpw r8, r4 bne ReleaseAndReturnParamErrFromMPCall cmplwi r5, 0x00 bne @420 lisori r16, 0x00080001 stw r16, ContextBlock.r6(r6) lwz r16, 0x0074(r31) stw r16, ContextBlock.r7(r6) lwz r16, 0x0070(r31) stw r16, ContextBlock.r8(r6) lwz r16, 0x000c(r31) stw r16, ContextBlock.r9(r6) li r16, 0x10 stw r16, ContextBlock.r10(r6) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall @420 cmplwi r5, 0x10 bne @454 lwz r16, 0x0030(r31) stw r16, ContextBlock.r6(r6) lwz r16, 0x0034(r31) stw r16, ContextBlock.r7(r6) lwz r16, 0x0038(r31) stw r16, ContextBlock.r8(r6) lwz r16, 0x003c(r31) stw r16, ContextBlock.r9(r6) li r16, 0x10 stw r16, ContextBlock.r10(r6) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall @454 cmplwi r5, 0x20 bne @488 lwz r16, 0x0040(r31) stw r16, ContextBlock.r6(r6) lwz r16, 0x0044(r31) stw r16, ContextBlock.r7(r6) lwz r16, 0x0048(r31) stw r16, ContextBlock.r8(r6) lwz r16, 0x004c(r31) stw r16, ContextBlock.r9(r6) li r16, 0x10 stw r16, ContextBlock.r10(r6) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall @488 cmplwi r5, 0x30 bne @4bc lwz r16, 0x0050(r31) stw r16, ContextBlock.r6(r6) lwz r16, 0x0054(r31) stw r16, ContextBlock.r7(r6) lwz r16, 0x0058(r31) stw r16, ContextBlock.r8(r6) lwz r16, 0x005c(r31) stw r16, ContextBlock.r9(r6) li r16, 0x10 stw r16, ContextBlock.r10(r6) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall @4bc cmplwi r5, 0x40 bne @4f0 lwz r16, 0x0060(r31) stw r16, ContextBlock.r6(r6) lwz r16, 0x0064(r31) stw r16, ContextBlock.r7(r6) lwz r16, 0x0068(r31) stw r16, ContextBlock.r8(r6) lwz r16, 0x006c(r31) stw r16, ContextBlock.r9(r6) li r16, 0x10 stw r16, ContextBlock.r10(r6) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall @4f0 cmpwi r5, 0x50 bne ReleaseAndReturnParamErrFromMPCall li r16, 0x00 stw r16, ContextBlock.r10(r6) ; r1 = kdp b ReleaseAndReturnZeroFromMPCall