Reverse Event Group MP calls

This commit is contained in:
Elliot Nunn 2017-11-19 17:59:35 +08:00
parent c5c5b784cb
commit b27256fbb6
10 changed files with 520 additions and 394 deletions

View File

@ -79,24 +79,11 @@ MysteryByte1 ds.b 1 ; 018 ; CreateTask sets 0 by default (blue = 2)
Priority ds.b 1 ; 019 ; CreateTask sets 2 by default
MysteryHalf ds.w 1 ; 01a
Weight ds.l 1 ; 01c ; default is 100, blue gets 200, idle gets 1
ds.l 1 ; 020
ds.l 1 ; 024
ds.l 1 ; 028
ds.l 1 ; 02c
ds.l 1 ; 030
ds.l 1 ; 034
ds.l 1 ; 038
ds.l 1 ; 03c
ds.l 1 ; 040
ds.l 1 ; 044
ds.l 1 ; 048
ds.l 1 ; 04c
ds.l 1 ; 050
ds.l 1 ; 054
ds.l 1 ; 058
ds.l 1 ; 05c
Timer ds.b 64 ; 020:060
ProcessID ds.l 1 ; 060
ThingThatAlignVecHits ds.l 1 ; 064 ; IntAlignment is interested in bit 9, MPCall 116 in bit 15
ThingThatAlignVecHits ds.l 1 ; 064 ; IntAlignment is interested in bit 9, MPCalls 52/116 in bit 15
ds.l 1 ; 068
OwningProcessPtr ds.l 1 ; 06c
AddressSpacePtr ds.l 1 ; 070 ; borrowed from PROC argument to CreateTask
@ -141,6 +128,7 @@ Size equ *
; ID CLASS 3: TIMER
; (size: 64b, thud command: id -tm)
;
; "Prev" is actually the next timer to fire!
;_______________________________________________________________________
Timer record 0,INCR
@ -152,22 +140,24 @@ kSignature equ 'TIME'
; Fields
;_______________________
ID ds.l 1 ; 00
Signature ds.l 1 ; 04
ds.l 1 ; 08
ds.l 1 ; 0c
ProcessID ds.l 1 ; 10
ds.l 1 ; 14
ds.l 1 ; 18
ds.l 1 ; 1c
ds.l 1 ; 20
ds.l 1 ; 24
ds.l 1 ; 28
ds.l 1 ; 2c
ds.l 1 ; 30
ds.l 1 ; 34
ds.l 1 ; 38
ds.l 1 ; 3c
ID ds.l 1 ; 00 ; task+20
Signature ds.l 1 ; 04 ; task+24
QueueLLL ds.l 1 ; 08 ; task+28 ; overlaps with the below bytefields, as a union?
ds.l 1 ; 0c ; task+2c
ProcessID ds.l 1 ; 10 ; task+30
Byte0 ds.b 1 ; 14 ; task+34 ; InitTMRQs sets to 6, MPCall 55 to 1, MPCall 52 to 2
Byte1 ds.b 1 ; 15 ; task+35
Byte2 ds.b 1 ; 16 ; task+36 ; InitTMRQs sets to 1
Byte3 ds.b 1 ; 17 ; task+37 ; called_by_init_tmrqs sets to 1
ParentTaskPtr ds.l 1 ; 18 ; task+38 ; MPCall 55 sets
ds.l 1 ; 1c ; task+3c
ds.l 1 ; 20 ; task+40
ds.l 1 ; 24 ; task+44
ds.l 1 ; 28 ; task+48
ds.l 1 ; 2c ; task+4c
ds.l 1 ; 30 ; task+50
ds.l 1 ; 34 ; task+54
Time ds.l 2 ; 38 ; task+58 ; set from first two args to MPCall 55
Size equ *
endr
@ -204,8 +194,8 @@ Size equ *
ReadyQueue record 0,INCR
LLL ds.l 4 ; 00:10 ; nothing fancy
Counter ds.l 1 ; 10 ; InitRDYQs sets, TaskReadyAsNext bumps
LLL ds.l 4 ; 00:10 ; nothing fancy, freeform contains priority flag
Counter ds.l 1 ; 10 ; InitRDYQs sets, TaskReadyAsNext bumps, major_0x13e4c decs
TotalWeight ds.l 1 ; 14 ; divide available time by these
Timecake ds.d 1 ; 18 ; period of ~1ms, 8ms, 64ms, 512ms
@ -379,10 +369,10 @@ kSignature equ 'EVNT'
;_______________________
LLL ds.l 4 ; 00:10 ; first field is ID
ds.l 1 ; 10
Flags ds.l 1 ; 10
ProcessID ds.l 1 ; 14
ds.l 1 ; 18 ; contains 1-8 +/- 16
ds.l 1 ; 1c
SWI ds.l 1 ; 18 ; contains 1-8 +/- 16
Counter ds.l 1 ; 1c
Size equ *
endr

View File

@ -147,7 +147,7 @@ NoIdeaR23 ds.l 1 ; -900 ; r23 copies here... replated to RTAS?
PA_BlueTask ds.l 1 ; -8f0 ; set at the same time as the one below
ds.l 1 ; -8ec
ds.l 1 ; -8e8
ds.l 1 ; -8e4
OtherSystemContextPtr ds.l 1 ; -8e4 ; sometimes set to PA_ECB
VectorRegInitWord ds.l 1 ; -8e0 ; task vector regs get inited with this word x 4
SevenFFFDead2 ds.l 1 ; -8dc
SevenFFFDead3 ds.l 1 ; -8d8
@ -172,7 +172,7 @@ SystemAddressSpaceID ds.l 1 ; -424
blueProcessPtr ds.l 1 ; -41c ; physical ptr to first type-1 struct created
ThermalHandlerID ds.l 1 ; -418 ; is a Note struct
PMFHandlerID ds.l 1 ; -414 ; also a Note struct
ds.l 1 ; -410
SomeEvtGrpID ds.l 1 ; -410
ds.l 1 ; -40c
ds.l 1 ; -408
ds.l 1 ; -404
@ -266,7 +266,10 @@ Base ; used when init'ed as part of the enclosing CPU struct
TimeList ds.l 4 ; -320:-310, cpu+020
ds.l 1 ; -310, cpu+030
ds.l 1 ; -30c, cpu+034
ds.b 1 ; -30c, cpu+034
ds.b 1 ; -30b, cpu+035
ds.b 1 ; -30a, cpu+036
GlobalTimeIsValid ds.b 1 ; -309, cpu+037
ds.l 1 ; -308, cpu+038
ds.l 1 ; -304, cpu+03c
ds.l 1 ; -300, cpu+040
@ -275,8 +278,7 @@ TimeList ds.l 4 ; -320:-310, cpu+020
ds.l 1 ; -2f4, cpu+04c
ds.l 1 ; -2f0, cpu+050
ds.l 1 ; -2ec, cpu+054
ds.l 1 ; -2e8, cpu+058
ds.l 1 ; -2e4, cpu+05c
GlobalTime ds.l 2 ; -2e8, cpu+058
ThudSavedR29 ds.l 1 ; -2e0, cpu+060
ThudSavedR30 ds.l 1 ; -2dc, cpu+064
ThudSavedR31 ds.l 1 ; -2d8, cpu+068
@ -391,7 +393,7 @@ SpacesDeferredAreaPtr ds.l 1 ; -26c, cpu+0d4
ds.l 1 ; -124, cpu+21c
ds.l 1 ; -120, cpu+220
ds.l 1 ; -11c, cpu+224
ds.l 1 ; -118, cpu+228
BinaryFlag ds.l 1 ; -118, cpu+228 ; 1 or 0, actually a byte!
ds.l 1 ; -114, cpu+22c
ds.l 1 ; -110, cpu+230
ds.l 1 ; -10c, cpu+234

View File

@ -2189,63 +2189,73 @@ KCSetAreaAccess_0x1e4
; major_0x10cb8
; ARG PTE r16, PTE r17, control r18
; RET PTE r16, PTE r17
; CLOB CR
; Xrefs:
; createarea
; KCSetAreaAccess
major_0x10cb8 ; OUTSIDE REFERER
rlwinm r16, r16, 0, 29, 24
rlwinm r17, r17, 0, 27, 23
rlwinm r16, r16, 0, 0, 29
rlwinm r17, r17, 0, 31, 28
major_0x10cb8
rlwinm r16, r16, 0, 0xFFFFFF87 ; fill these in again...
rlwinm r17, r17, 0, 0xFFFFFF1F ;
rlwinm r16, r16, 0, 0xFFFFFFFC ;
rlwinm r17, r17, 0, 0xFFFFFFF9 ;
; Load control argument into condition register
; Note: this is a pretty expensive operation, not in hot path
mtcr r18
bge- cr6, major_0x10cb8_0x20
ori r17, r17, 0x80
ori r16, r16, 0x08
major_0x10cb8_0x20
ble- cr6, major_0x10cb8_0x2c
ori r16, r16, 0x40
b major_0x10cb8_0x30
major_0x10cb8_0x2c
ori r17, r17, 0x20
bge- cr6, @80_not_set ; if(control & 0x80) {
ori r17, r17, 0x80 ; PTE2 |= 0x80; //set referenced bit
ori r16, r16, 0x08 ; PTE1 |= 0x08; //set guard bit
@80_not_set ; }
major_0x10cb8_0x30
bne- cr6, major_0x10cb8_0x3c
ori r17, r17, 0x40
ori r16, r16, 0x20
major_0x10cb8_0x3c
ble- cr7, major_0x10cb8_0x40
ble- cr6, @40_not_set ; if(control & 0x40) {
ori r16, r16, 0x40 ; PTE1 |= 0x40; //set change bit
b @40_endif ; } else {
@40_not_set
ori r17, r17, 0x20 ; PTE2 |= 0x20; //set W bit
@40_endif ; }
major_0x10cb8_0x40
bge- cr7, major_0x10cb8_0x50
ori r17, r17, 0x06
ori r16, r16, 0x01
b major_0x10cb8_0x78
major_0x10cb8_0x50
bne- cr7, major_0x10cb8_0x60
ori r17, r17, 0x00
ori r16, r16, 0x02
b major_0x10cb8_0x78
bne- cr6, @20_not_set ; if(control & 0x20) {
ori r17, r17, 0x40 ; PTE2 |= 0x40; //set change bit
ori r16, r16, 0x20 ; PTE1 |= 0x20; //set W bit
@20_not_set ; }
major_0x10cb8_0x60
bns- cr7, major_0x10cb8_0x70
ori r17, r17, 0x04
ori r16, r16, 0x03
b major_0x10cb8_0x78
major_0x10cb8_0x70
ori r17, r17, 0x02
ori r16, r16, 0x00
ble- cr7, @04_not_set ; if(control & 0x04) {
@04_not_set ; }
major_0x10cb8_0x78
ori r16, r16, 0x10
blr
bge- cr7, @08_not_set ; if(control & 0x08) {
ori r17, r17, 0x06 ; PTE2 |= 0x06; //set leftmost protection bit and reserved bit
ori r16, r16, 0x01 ; PTE1 |= 0x01; //set rightmost protection bit
b @block_endif ; }
@08_not_set
bne- cr7, @02_not_set ; else if(control & 0x02) {
ori r17, r17, 0x00 ; PTE2 |= 0x00; //useless instruction?
ori r16, r16, 0x02 ; PTE1 |= 0x02; //set second protection bit
b @block_endif ; }
@02_not_set
bns- cr7, @01_not_set ; else if(control & 0x01) {
ori r17, r17, 0x04 ; PTE2 |= 0x04; //set reserved bit.
ori r16, r16, 0x03 ; PTE1 |= 0x03: //set both protection bits
b @block_endif ; }
@01_not_set ; else {
ori r17, r17, 0x02 ; PTE2 |= 0x02; //set second protection bit
ori r16, r16, 0x00 ; PTE1 |= 0x00; //useless instruction?
@block_endif ; }
ori r16, r16, 0x10 ; PTE1 |= 0x10; //set M bit
blr ; return (PTE1, PTE2);

View File

@ -457,7 +457,7 @@ major_0x02ccc_0x2a4 ; OUTSIDE REFERER
_Lock PSA.SchLock, scratch1=r28, scratch2=r29
mr r8, r31
bl major_0x13e4c
bl DequeueTask
lwz r16, 0x0064(r31)
srwi r8, r7, 24
rlwinm. r16, r16, 0, 9, 9
@ -489,7 +489,7 @@ major_0x02ccc_0x310 ; OUTSIDE REFERER
_Lock PSA.SchLock, scratch1=r28, scratch2=r29
mr r8, r31
bl major_0x13e4c
bl DequeueTask
lwz r16, 0x0064(r31)
srwi r8, r7, 24
rlwinm. r16, r16, 0, 9, 9
@ -2520,7 +2520,7 @@ IntExternalYellow ; OUTSIDE REFERER
mfsprg r9, 0
li r8, 0x01
stb r8, -0x0118(r9)
stb r8, EWA.BinaryFlag(r9)
b skeleton_key

View File

@ -1178,7 +1178,7 @@ MPCall_6_0x78 ; OUTSIDE REFERER
MPCall_6_0xb4
mr r8, r31
bl major_0x13e4c
bl DequeueTask
li r16, 0x02
stb r16, 0x0019(r31)
bl TaskReadyAsPrev
@ -1222,7 +1222,7 @@ KCYieldWithHint ; OUTSIDE REFERER
cmpwi r16, 0x02
bge- KCYieldWithHint_0x7c
mr r8, r31
bl major_0x13e4c
bl DequeueTask
li r16, 0x02
stb r16, 0x0019(r31)
bl TaskReadyAsNext
@ -1230,7 +1230,7 @@ KCYieldWithHint ; OUTSIDE REFERER
KCYieldWithHint_0x68
mr r8, r31
bl major_0x13e4c
bl DequeueTask
li r16, 0x02
stb r16, 0x0019(r31)
bl TaskReadyAsPrev
@ -1255,7 +1255,7 @@ KCYieldWithHint_0xa0
DeclareMPCall 33, MPCall_33
MPCall_33 ; OUTSIDE REFERER
rlwinm. r8, r7, 0, 10, 10
rlwinm. r8, r7, 0, 10, 10 ; Contains CpuFlags
bne+ ReturnMPCallBlueBlocking
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
@ -1264,6 +1264,7 @@ MPCall_33 ; OUTSIDE REFERER
; MPCall_55
; Xrefs:
@ -1274,52 +1275,61 @@ MPCall_33 ; OUTSIDE REFERER
MPCall_55 ; OUTSIDE REFERER
rlwinm. r8, r7, 0, 10, 10
lwz r16, 0x0e80(r1)
lwz r16, KDP.NanoKernelInfo + NKNanoKernelInfo.ExternalIntCount(r1)
beq- MPCall_55_0x60
lwz r17, -0x08e4(r1)
lwz r18, 0x0658(r1)
lwz r17, PSA.OtherSystemContextPtr(r1)
lwz r18, KDP.PA_ECB(r1)
cmpw r16, r17
stw r16, -0x08e4(r1)
stw r16, PSA.OtherSystemContextPtr(r1)
bne+ ReturnZeroFromMPCall
lwz r8, 0x00cc(r18)
rlwinm r8, r8, 0, 24, 21
oris r8, r8, 0x8000
stw r8, 0x00cc(r18)
lwz r8, ContextBlock.PriorityShifty(r18)
rlwinm r8, r8, 0, 24, 21
oris r8, r8, 0x8000
stw r8, ContextBlock.PriorityShifty(r18)
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
; if(-0x0410(r1) == -1) {-0x0410(r1) = 0; return 0;}
lwz r16, -0x0410(r1)
cmpwi r16, -0x01
li r16, 0x00
bne- MPCall_55_0x60
stw r16, -0x0410(r1)
; r1 = kdp
b ReleaseAndReturnZeroFromMPCall
MPCall_55_0x60 ; OUTSIDE REFERER
mfsprg r16, 0
li r17, 0x01
lwz r31, -0x0008(r16)
li r17, 1
lwz r31, EWA.PA_CurTask(r16)
addi r16, r31, 0x20
stb r17, 0x0014(r16)
clrlwi r3, r3, 0x01
stw r3, 0x0038(r16)
stw r4, 0x003c(r16)
stw r31, 0x0018(r16)
stb r17, Timer.Byte0(r16)
; High bit is possibly suspect? Or a flag?
clrlwi r3, r3, 1
stw r3, Timer.Time(r16)
stw r4, Timer.Time+4(r16)
stw r31, Timer.ParentTaskPtr(r16)
mr r8, r16
bl called_by_init_tmrqs
bl EnqueueTimer
mr r8, r31
bl major_0x13e4c
addi r16, r1, -0xa44
addi r17, r31, 0x08
stw r16, 0x0000(r17)
stw r16, 0x0008(r17)
lwz r18, 0x000c(r16)
stw r18, 0x000c(r17)
stw r17, 0x0008(r18)
stw r17, 0x000c(r16)
li r3, 0x00
bl DequeueTask
addi r16, r1, PSA.DelayQueue
addi r17, r31, Timer.QueueLLL
stw r16, LLL.Freeform(r17)
InsertAsPrev r17, r16, scratch=r18
li r3, 0
b AlternateMPCallReturnPath
@ -1958,7 +1968,7 @@ KCStopScheduling ; OUTSIDE REFERER
oris r17, r17, 0x80
stw r17, 0x0064(r31)
mr r8, r31
bl major_0x13e4c
bl DequeueTask
li r17, 0x00
stb r17, 0x0019(r31)
mr r8, r31
@ -2364,7 +2374,7 @@ NKSetClockStep_0xec
stw r8, 0x0038(r31)
stw r9, 0x003c(r31)
mr r8, r31
bl called_by_init_tmrqs
bl EnqueueTimer
; r1 = kdp
b ReleaseAndReturnZeroFromMPCall
@ -2439,7 +2449,7 @@ NKSetClockDriftCorrection_0x6c
stw r8, 0x0038(r31)
stw r9, 0x003c(r31)
mr r8, r31
bl called_by_init_tmrqs
bl EnqueueTimer
; r1 = kdp
b ReleaseAndReturnZeroFromMPCall

View File

@ -212,7 +212,7 @@ CommonPIHPath_0x168
CommonPIHPath_0x1d0
mr r8, r31
bl major_0x13e4c
bl DequeueTask
b CommonPIHPath_0x218
CommonPIHPath_0x1dc
@ -232,7 +232,7 @@ CommonPIHPath_0x1dc
CommonPIHPath_0x210
lwz r16, 0x0e80(r1)
stw r16, -0x08e4(r1)
stw r16, PSA.OtherSystemContextPtr(r1)
CommonPIHPath_0x218
li r16, 0x00

View File

@ -366,7 +366,7 @@ MPCall_18_0x9c
MPCall_18_0xc4
mr r8, r19
bl major_0x13e4c
bl DequeueTask
lwz r19, -0x0008(r30)
addi r16, r31, 0x00
addi r17, r19, 0x08
@ -406,7 +406,7 @@ MPCall_18_0xc4
stw r8, 0x0038(r30)
stw r9, 0x003c(r30)
mr r8, r30
bl called_by_init_tmrqs
bl EnqueueTimer
MPCall_18_0x154
b AlternateMPCallReturnPath
@ -517,7 +517,7 @@ MPCall_23_0x44
b ReleaseAndReturnMPCallBlueBlocking
MPCall_23_0x68
bl major_0x13e4c
bl DequeueTask
addi r16, r31, 0x00
addi r17, r8, 0x08
stw r16, 0x0000(r17)
@ -555,7 +555,7 @@ MPCall_23_0x68
stw r8, 0x0038(r30)
stw r9, 0x003c(r30)
mr r8, r30
bl called_by_init_tmrqs
bl EnqueueTimer
MPCall_23_0xec
li r3, 0x00
@ -829,7 +829,7 @@ MPCall_27_0x78
MPCall_27_0xb4
mr r8, r30
bl major_0x13e4c
bl DequeueTask
lis r16, 0x7fff
addi r18, r30, 0x08
ori r16, r16, 0xffff
@ -866,7 +866,7 @@ MPCall_27_0xb4
stw r8, 0x0038(r29)
stw r9, 0x003c(r29)
mr r8, r29
bl called_by_init_tmrqs
bl EnqueueTimer
MPCall_27_0x138
b AlternateMPCallReturnPath
@ -1036,9 +1036,39 @@ MPCall_26_0x98
DeclareMPCall 49, NKCreateEventGroupForThisTask
;_______________________________________________________________________
; EVENT GROUP MP CALLS (49-54)
;
; Corresponding with MPLibrary functions, although signatures differ
;
; 49* MPCreateEvent
; 50 MPDeleteEvent
; 51 MPSetEvent
; 52* MPWaitForEvent
; 53 MPQueryEvent
; 54* MPSetSWIEvent
; * also called using the FE1F trap by the 68k ROM
;
; 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.
;_______________________________________________________________________
NKCreateEventGroupForThisTask
DeclareMPCall 49, MPCreateEvent
; RET OSStatus r3, MPEventID r4
MPCreateEvent
li r8, EventGroup.Size
bl PoolAlloc
@ -1072,9 +1102,12 @@ NKCreateEventGroupForThisTask
DeclareMPCall 50, MPCall_50
DeclareMPCall 50, MPDeleteEvent
MPCall_50 ; OUTSIDE REFERER
; ARG MPEventID r3
; RET OSStatus r3
MPDeleteEvent
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
@ -1083,28 +1116,28 @@ MPCall_50 ; OUTSIDE REFERER
; r8 = id
bl LookupID
cmpwi r9, EventGroup.kIDClass
mr r31, r8
bne+ ReleaseAndReturnMPCallInvalidIDErr
mr r8, r3
bl major_0x0dce8
MPCall_50_0x34
MPDeleteEvent_0x34
addi r30, r31, 0x00
lwz r16, 0x0008(r31)
cmpw r16, r30
addi r8, r16, -0x08
beq- MPCall_50_0x98
beq- MPDeleteEvent_0x98
lwz r17, 0x0088(r8)
li r18, -0x726f
stw r18, 0x011c(r17)
lbz r17, 0x0037(r8)
cmpwi r17, 0x01
bne- MPCall_50_0x68
bne- MPDeleteEvent_0x68
addi r8, r8, 0x20
bl major_0x136c8
MPCall_50_0x68
MPDeleteEvent_0x68
lwz r16, 0x0008(r31)
lwz r17, 0x0008(r16)
lwz r18, 0x000c(r16)
@ -1116,9 +1149,9 @@ MPCall_50_0x68
addi r8, r16, -0x08
bl TaskReadyAsPrev
bl major_0x14af8
b MPCall_50_0x34
b MPDeleteEvent_0x34
MPCall_50_0x98
MPDeleteEvent_0x98
mr r8, r31
bl PoolFree
mr r8, r3
@ -1129,20 +1162,21 @@ MPCall_50_0x98
DeclareMPCall 51, MPCall_51
DeclareMPCall 51, MPSetEvent
MPCall_51 ; OUTSIDE REFERER
; ARG MPEventID r3, MPEventFlags r4
; RET OSStatus r3
MPSetEvent
_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, r4
bl major_0x0d35c
@ -1286,38 +1320,43 @@ major_0x0d35c_0x1a0
DeclareMPCall 52, MPCall_52
DeclareMPCall 52, MPWaitForEvent
MPCall_52 ; OUTSIDE REFERER
; ARG MPEventID r3, Duration r5
; RET OSStatus r3, MPEventFlags r4
MPWaitForEvent
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
mr r8, r3
; r8 = id
bl LookupID
; 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, 0x00
beq- MPCall_52_0xc0
lwz r16, 0x0010(r31)
cmpwi r16, 0
beq- MPWaitForEvent_field_10_was_zero
mr r4, r16
li r16, 0x00
li r16, 0
stw r16, 0x0010(r31)
lwz r16, 0x0018(r31)
lwz r17, 0x0658(r1)
lwz r17, KDP.PA_ECB(r1)
rlwinm. r18, r16, 0, 27, 27
rlwinm r16, r16, 2, 26, 29
; r1 = kdp
beq+ ReleaseAndReturnZeroFromMPCall
lwz r18, 0x00c8(r17)
lwz r9, 0x0634(r1)
cmpwi r18, 0x00
add r18, r18, r9
bne- MPCall_52_0x84
bne- MPWaitForEvent_0x84
lwz r18, 0x00d0(r17)
cmpw r18, r3
li r18, 0x00
@ -1329,7 +1368,7 @@ MPCall_52 ; OUTSIDE REFERER
; r1 = kdp
b ReleaseAndReturnZeroFromMPCall
MPCall_52_0x84
MPWaitForEvent_0x84
lwzx r19, r16, r18
cmpw r19, r3
li r19, 0x00
@ -1340,82 +1379,87 @@ MPCall_52_0x84
li r19, 0x1c
li r9, 0x04
MPCall_52_0xa0
MPWaitForEvent_0xa0
lwzx r8, r19, r18
cmpwi r8, 0x00
bne- MPCall_52_0xb4
bne- MPWaitForEvent_0xb4
subf. r19, r9, r19
bgt+ MPCall_52_0xa0
bgt+ MPWaitForEvent_0xa0
MPCall_52_0xb4
MPWaitForEvent_0xb4
srwi r19, r19, 2
stw r19, 0x00d0(r17)
; r1 = kdp
b ReleaseAndReturnZeroFromMPCall
MPCall_52_0xc0
MPWaitForEvent_field_10_was_zero
mfsprg r30, 0
cmpwi r5, 0x00
lwz r19, -0x0008(r30)
cmpwi r5, 0
lwz r19, EWA.PA_CurTask(r30)
beq+ ReleaseAndTimeoutMPCall
lwz r16, 0x0064(r19)
rlwinm. r16, r16, 0, 15, 15
beq- MPCall_52_0xe4
stw r3, -0x0410(r1)
b ReleaseAndReturnMPCallBlueBlocking
lwz r16, Task.ThingThatAlignVecHits(r19)
rlwinm. r16, r16, 0, 15, 15
MPCall_52_0xe4
beq- @bit_15_was_unset
stw r3, PSA.SomeEvtGrpID(r1)
b ReleaseAndReturnMPCallBlueBlocking
@bit_15_was_unset
; MOVE TASK OUT OF QUEUE AND INTO EVENT GROUP
mr r8, r19
bl major_0x13e4c
lwz r19, -0x0008(r30)
addi r16, r31, 0x00
addi r17, r19, 0x08
stw r16, 0x0000(r17)
stw r16, 0x0008(r17)
lwz r18, 0x000c(r16)
stw r18, 0x000c(r17)
stw r17, 0x0008(r18)
stw r17, 0x000c(r16)
lwz r18, 0x001c(r31)
addi r18, r18, 0x01
stw r18, 0x001c(r31)
lis r16, 0x7fff
ori r16, r16, 0xffff
addi r30, r19, 0x20
bl DequeueTask
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, 0x02
beq- MPCall_52_0x170
stb r16, 0x0014(r30)
stw r19, 0x0018(r30)
li r16, 2
beq- @wait_forever ; never trigger max-wait timers
stb r16, Timer.Byte0(r30)
stw r19, Timer.ParentTaskPtr(r30)
mr r8, r5
; 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(r30)
stw r9, 0x003c(r30)
mr r8, r30
bl called_by_init_tmrqs
MPCall_52_0x170
stw r8, Timer.Time(r30)
stw r9, Timer.Time+4(r30)
mr r8, r30
bl EnqueueTimer
@wait_forever
b AlternateMPCallReturnPath
DeclareMPCall 53, MPCall_53
DeclareMPCall 53, MPQueryEvent
MPCall_53 ; OUTSIDE REFERER
; Returns Timeout if no flags are set, otherwise NoErr
; ARG MPEventID r3
; RET OSStatus r3
MPQueryEvent
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
@ -1424,8 +1468,8 @@ MPCall_53 ; OUTSIDE REFERER
; r8 = id
bl LookupID
cmpwi r9, EventGroup.kIDClass
bne+ ReleaseAndReturnMPCallInvalidIDErr
mr r31, r8
lwz r16, 0x0010(r31)
cmpwi r16, 0x00
@ -1436,16 +1480,17 @@ MPCall_53 ; OUTSIDE REFERER
DeclareMPCall 54, MPCall_54
DeclareMPCall 54, MPSetSWIEvent
MPCall_54 ; OUTSIDE REFERER
; ARG MPEventID r3, int r4 swi
MPSetSWIEvent
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
mr r8, r3
bl LookupID
cmpwi r9, EventGroup.kIDClass
bne+ ReleaseAndReturnMPCallInvalidIDErr
mr r31, r8
@ -1454,7 +1499,7 @@ MPCall_54 ; OUTSIDE REFERER
cmpwi r4, 0
cmplwi cr1, r4, 8
lwz r16, 0x0018(r31)
lwz r16, EventGroup.SWI(r31)
beq- @use_1
bgt- cr1, @use_1
@ -1464,18 +1509,29 @@ MPCall_54 ; OUTSIDE REFERER
; r17 = 1 if outside 1-8 (inc) range
ori r16, r16, 0x10
rlwimi r16, r17, 0, 28, 31
stw r16, 0x0018(r31)
ori r16, r16, 0x10
rlwimi r16, r17, 0, 28, 31
stw r16, EventGroup.SWI(r31)
; r1 = kdp
b ReleaseAndReturnZeroFromMPCall
DeclareMPCall 40, MPCall_40
MPCall_40 ; OUTSIDE REFERER
DeclareMPCall 40, NKCreateTimer
NKCreateTimer ; OUTSIDE REFERER
li r8, 0x40
; r1 = kdp
@ -1495,12 +1551,12 @@ MPCall_40 ; OUTSIDE REFERER
; r9 = kind
bl MakeID
cmpwi r8, 0x00
bne- MPCall_40_0x48
bne- NKCreateTimer_0x48
mr r8, r31
bl PoolFree
b major_0x0af60
MPCall_40_0x48
NKCreateTimer_0x48
mfsprg r30, 0
stw r8, 0x0000(r31)
lwz r30, -0x0008(r30)
@ -1523,9 +1579,9 @@ MPCall_40_0x48
DeclareMPCall 41, MPCall_41
DeclareMPCall 41, NKDeleteTimer
MPCall_41 ; OUTSIDE REFERER
NKDeleteTimer ; OUTSIDE REFERER
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
@ -1541,20 +1597,20 @@ MPCall_41 ; OUTSIDE REFERER
bl DeleteID
lwz r16, 0x0008(r31)
cmpwi r16, 0x00
beq- MPCall_41_0x48
beq- NKDeleteTimer_0x48
mr r8, r31
bl major_0x136c8
MPCall_41_0x48
NKDeleteTimer_0x48
sync
lwz r16, PSA.SchLock + Lock.Count(r1)
cmpwi cr1, r16, 0x00
li r16, 0x00
bne+ cr1, MPCall_41_0x64
bne+ cr1, NKDeleteTimer_0x64
mflr r16
bl panic
MPCall_41_0x64
NKDeleteTimer_0x64
stw r16, PSA.SchLock + Lock.Count(r1)
lwz r8, 0x001c(r31)
cmpwi r8, 0x00
@ -1565,9 +1621,9 @@ MPCall_41_0x64
DeclareMPCall 30, MPCall_30
DeclareMPCall 30, NKSetTimerNotify
MPCall_30 ; OUTSIDE REFERER
NKSetTimerNotify ; OUTSIDE REFERER
_Lock PSA.SchLock, scratch1=r16, scratch2=r17
@ -1589,9 +1645,9 @@ MPCall_30 ; OUTSIDE REFERER
cmpwi r9, Semaphore.kIDClass
cmpwi cr2, r9, 0x04
beq- MPCall_30_0x80
beq- NKSetTimerNotify_0x80
cmpwi r9, 0x09
beq- cr2, MPCall_30_0x64
beq- cr2, NKSetTimerNotify_0x64
bne+ ReleaseAndReturnMPCallInvalidIDErr
stw r4, 0x002c(r31)
stw r5, 0x0030(r31)
@ -1599,7 +1655,7 @@ MPCall_30 ; OUTSIDE REFERER
; r1 = kdp
b ReleaseAndReturnZeroFromMPCall
MPCall_30_0x64
NKSetTimerNotify_0x64
stw r4, 0x0018(r31)
lwz r16, 0x0134(r6)
lwz r17, 0x013c(r6)
@ -1610,7 +1666,7 @@ MPCall_30_0x64
; r1 = kdp
b ReleaseAndReturnZeroFromMPCall
MPCall_30_0x80
NKSetTimerNotify_0x80
stw r4, 0x0034(r31)
; r1 = kdp
@ -1709,7 +1765,7 @@ MPCall_31_0xdc
MPCall_31_0xf8
stb r17, 0x0016(r31)
mr r8, r31
bl called_by_init_tmrqs
bl EnqueueTimer
; r1 = kdp
b ReleaseAndReturnZeroFromMPCall
@ -2050,7 +2106,7 @@ MPCall_128_0x58
; MPCall_21
; MPCall_28
; MPCall_26
; MPCall_50
; MPDeleteEvent
; major_0x0d35c
major_0x0dce8 ; OUTSIDE REFERER

View File

@ -638,43 +638,60 @@ Save_v0_v31_0x1b8
major_0x13e4c
lwz r17, 0x0010( r8)
lbz r18, 0x0018( r8)
addi r16, r8, 0x08
cmpwi cr1, r18, 0x00
cmpwi r17, 0x00
beq+ cr1, Local_Panic
beq- major_0x13e4c_0x74
lwz r17, 0x0008(r16)
lwz r18, 0x000c(r16)
stw r17, 0x0008(r18)
stw r18, 0x000c(r17)
li r17, 0x00
stw r17, 0x0008(r16)
stw r17, 0x000c(r16)
lwz r17, 0x0000(r16)
lwz r16, 0x001c( r8)
lwz r18, 0x0014(r17)
subf r18, r16, r18
stw r18, 0x0014(r17)
lwz r18, 0x0010(r17)
addi r18, r18, -0x01
stw r18, 0x0010(r17)
cmpwi r18, 0x00
lwz r16, -0x0970( r1)
blt+ Local_Panic
bne- major_0x13e4c_0x74
lwz r18, 0x0000(r17)
andc r16, r16, r18
stw r16, -0x0970( r1)
; Remove a task from a queue, cleaning up the queue structures behind me.
; If a queue is empty, unset the priority flag of the queue in
; PSA.PriorityFlags (presumably has no effect with non-ready queues).
; Also set the mysterious EWA.BinaryFlag to 1.
; ARG Task *r8
; CLOB r16, r17, r18
DequeueTask
lwz r17, Task.QueueMember + LLL.Next( r8)
lbz r18, Task.MysteryByte1( r8)
addi r16, r8, Task.QueueMember
; Panic if MysteryByte1==0, return early if this task is not enqueued (i.e. LLL.Next==0)
cmpwi cr1, r18, 0
cmpwi r17, 0
beq+ cr1, Local_Panic
beq- @return_early
RemoveFromList r16, scratch1=r17, scratch2=r18
; The queue of which this task was formerly a member
lwz r17, LLL.Freeform(r16)
; Tidy up by subtracting this tasks weight from the Q weight
lwz r16, Task.Weight(r8)
lwz r18, ReadyQueue.TotalWeight(r17)
subf r18, r16, r18
stw r18, ReadyQueue.TotalWeight(r17)
; Decrement the Q counter
lwz r18, ReadyQueue.Counter(r17)
subi r18, r18, 1
stw r18, ReadyQueue.Counter(r17)
; Optimised below: a bit confusing
cmpwi r18, 0 ; Crash if we popped from an empty queue!
lwz r16, PSA.PriorityFlags(r1)
blt+ Local_Panic
bne- @return_early
lwz r18, ReadyQueue.LLL + LLL.Freeform(r17)
andc r16, r16, r18 ; If this queue is empty then unset the corresponding
stw r16, PSA.PriorityFlags(r1) ; bit in PSA.PriorityFlags
@return_early
li r16, 0
stb r16, Task.MysteryByte1(r8)
major_0x13e4c_0x74
li r16, 0x00
stb r16, 0x0018( r8)
mfsprg r17, 0
li r16, 0x01
stb r16, -0x0118(r17)
li r16, 1
stb r16, EWA.BinaryFlag(r17)
blr
@ -1073,7 +1090,7 @@ SetAddrSpcRegisters_0x314:
; skeleton_key
major_0x142a8 ; OUTSIDE REFERER
lbz r8, -0x0118(r1)
lbz r8, EWA.BinaryFlag(r1)
rlwinm. r9, r7, 0, 16, 16
lwz r1, -0x0004(r1)
cmpwi cr1, r8, 0x00
@ -1119,7 +1136,7 @@ major_0x142a8 ; OUTSIDE REFERER
major_0x142dc ; OUTSIDE REFERER
mfsprg r14, 0
li r8, 0x00
stb r8, -0x0118(r14)
stb r8, EWA.BinaryFlag(r14)
lwz r31, -0x0008(r14)
lwz r1, -0x0004(r14)
lwz r9, 0x0ee4(r1)
@ -1136,7 +1153,7 @@ major_0x142dc_0x38
cmpw r27, r26
mr r8, r31
beq- major_0x142dc_0x58
bl major_0x13e4c
bl DequeueTask
stb r26, 0x0019(r31)
mr r8, r31
bl TaskReadyAsPrev
@ -1387,7 +1404,7 @@ major_0x14548_0x58
major_0x14548_0xd4
mfsprg r19, 0
li r8, 0x00
stb r8, -0x0118(r19)
stb r8, EWA.BinaryFlag(r19)
lhz r8, -0x0116(r19)
lwz r6, 0x0088(r30)
lwz r28, -0x0340(r19)
@ -1667,7 +1684,7 @@ major_0x148ec_0xc8
mtxer r20
li r16, 0x01
stb r16, -0x0309(r21)
b major_0x13060_0xc
b AdjustDecForTMRQGivenCurTime
@ -1903,7 +1920,7 @@ major_0x14af8_0x78
major_0x14af8_0x94
li r16, 0x01
stb r16, -0x0118(r15)
stb r16, EWA.BinaryFlag(r15)
blr
@ -1985,7 +2002,7 @@ major_0x14bcc
mfsprg r14, 0
lwz r31, 0x001c(r3)
li r8, 0x00
stb r8, -0x0118(r14)
stb r8, EWA.BinaryFlag(r14)
lwz r6, 0x0088(r31)
stw r31, -0x0008(r14)
stw r6, -0x0014(r14)
@ -2155,7 +2172,7 @@ StopProcessor
lwz r8, 0x001c(r31)
li r9, 0x00
stw r9, 0x001c(r31)
bl major_0x13e4c
bl DequeueTask
addi r16, r1, -0xa44
addi r17, r8, 0x08
stw r16, 0x0000(r17)

View File

@ -437,7 +437,7 @@ MPCall_9_0xe0
ori r16, r16, 0x02
stw r16, 0x0064(r31)
mr r8, r31
bl major_0x13e4c
bl DequeueTask
MPCall_9_0xf0
lwz r17, 0x009c(r31)
@ -708,7 +708,7 @@ KCThrowException_0x70
stw r4, 0x00f8(r31)
stw r16, 0x0064(r31)
mr r8, r31
bl major_0x13e4c
bl DequeueTask
addi r16, r1, -0xa34
addi r17, r31, 0x08
stw r16, 0x0000(r17)
@ -1536,7 +1536,7 @@ MPCall_114 ; OUTSIDE REFERER
rlwinm. r8, r16, 0, 26, 26
mr r8, r31
bne- MPCall_114_0x90
bl major_0x13e4c
bl DequeueTask
bl TaskReadyAsPrev
MPCall_114_0x90

View File

@ -68,39 +68,46 @@ InitTMRQs_0x7c
mtlr r30
InitTMRQs_0xb4
lwz r30, 0x0630(r1)
lhz r31, 0x0378(r30)
cmplwi r31, 0x101
blt- InitTMRQs_0x140
lwz r31, 0x0388(r30)
clrlwi. r8, r31, 0x1f
beq- InitTMRQs_0x140
lwz r8, 0x0edc(r1)
ori r8, r8, 0x02
stw r8, 0x0edc(r1)
; Activate the NanoDebugger (whatever that is...)
lwz r30, KDP.PA_ConfigInfo(r1)
lhz r31, NKConfigurationInfo.Debug(r30)
cmplwi r31, NKConfigurationInfo.DebugThreshold
blt- @nodebug
lwz r31, NKConfigurationInfo.DebugFlags(r30)
rlwinm. r8, r31, 0, NKConfigurationInfo.NanodbgrFlagBit, NKConfigurationInfo.NanodbgrFlagBit
beq- @nodebug
lwz r8, KDP.NanoKernelInfo + NKNanoKernelInfo.ConfigFlags(r1)
_bset r8, r8, NKNanoKernelInfo.NanodbgrFlagBit
stw r8, KDP.NanoKernelInfo + NKNanoKernelInfo.ConfigFlags(r1)
mflr r30
li r8, 0x40
; r1 = kdp
; r8 = size
bl PoolAlloc
; r8 = ptr
li r8, Timer.Size
bl PoolAlloc ; one of those weird queue structures
mr. r31, r8
beq+ Local_Panic
li r9, 0x06
stb r9, 0x0014(r31)
li r9, 0x01
stb r9, 0x0016(r31)
bl GetTime
stw r8, 0x0038(r31)
stw r9, 0x003c(r31)
mr r8, r31
bl called_by_init_tmrqs
_log 'Nanodebugger activated.^n'
mtlr r30
InitTMRQs_0x140
bl GetTime
stw r8, Timer.Time(r31)
stw r9, Timer.Time+4(r31)
mr r8, r31
bl EnqueueTimer
_log 'Nanodebugger activated.^n'
mtlr r30
@nodebug
blr
@ -234,7 +241,7 @@ TimerDispatch_0x180:
TimerDispatch_0x188
lwz r19, -0x0258(r18)
mtlr r19
b major_0x13060_0x18
b AdjustDecForTMRQGivenCurTimeAndTripTime
@ -259,63 +266,83 @@ StartTimeslicing ; OUTSIDE REFERER
; major_0x13060
; Xrefs:
; TimerDispatch
; StartTimeslicing
; called_by_init_tmrqs
; major_0x136c8
; major_0x148ec
; CLOB r8/r9, r16-r21
AdjustDecForTMRQ
major_0x13060 ; OUTSIDE REFERER
mflr r19
bl GetTime
mtlr r19
major_0x13060_0xc ; OUTSIDE REFERER
lwz r18, -0x0a7c(r1)
lwz r16, 0x0038(r18)
lwz r17, 0x003c(r18)
major_0x13060_0x18 ; OUTSIDE REFERER
; ARG TimeBase r8/r9 curTime
; CLOB r16-r21
AdjustDecForTMRQGivenCurTime
; This should get the most distant time???
lwz r18, PSA.TimerQueue + Queue.LLL + LLL.Next(r1)
lwz r16, Timer.Time(r18)
lwz r17, Timer.Time+4(r18)
; ARG TimeBase r8/r9 curTime, TimeBase r16/r17 TripTime
; CLOB r18-r21
AdjustDecForTMRQGivenCurTimeAndTripTime
mfxer r20
mfsprg r19, 0
lis r21, 0x7fff
lbz r18, -0x0309(r19)
ori r21, r21, 0xffff
cmpwi r18, 0x01
bne- major_0x13060_0x58
lwz r18, -0x02e8(r19)
lwz r19, -0x02e4(r19)
lis r21, 0x7fff
lbz r18, EWA.GlobalTimeIsValid(r19)
ori r21, r21, 0xffff
cmpwi r18, 1
; r16/r17 = soonest(last timer, global PSA time if available)
bne- @global_time_invalid
lwz r18, EWA.GlobalTime(r19)
lwz r19, EWA.GlobalTime+4(r19)
cmpw r16, r18
cmplw cr1, r17, r19
blt- major_0x13060_0x58
bgt- major_0x13060_0x50
ble- cr1, major_0x13060_0x58
major_0x13060_0x50
blt- @last_timer_fires_sooner
bgt- @global_time_sooner
ble- cr1, @last_timer_fires_sooner
@global_time_sooner
mr r17, r19
mr r16, r18
@last_timer_fires_sooner
@global_time_invalid
major_0x13060_0x58
; Subtract the current time (or what we were passed in r8/r9) from that time
subfc r17, r9, r17
subfe. r16, r8, r16
mtxer r20
blt- major_0x13060_0x84
bne- major_0x13060_0x7c
cmplw r16, r21
bgt- major_0x13060_0x7c
blt- @that_time_has_passed ; hi bit of r16 = 1
bne- @that_time_is_in_future ;
cmplw r16, r21 ; typo? should be r17???
bgt- @that_time_is_in_future ; will never be taken...
; When the times are roughly equal?
mtspr dec, r17
blr
major_0x13060_0x7c
@that_time_is_in_future
mtspr dec, r21
blr
major_0x13060_0x84
@that_time_has_passed
mtspr dec, r21
mtspr dec, r16
mtspr dec, r16 ; this makes nearly no sense!
blr
@ -531,7 +558,7 @@ major_0x132e8_0x10 ; OUTSIDE REFERER
mfsprg r28, 0
lwz r29, -0x0008(r28)
mr r8, r29
bl major_0x13e4c
bl DequeueTask
lbz r17, 0x0019(r29)
cmpwi r17, 0x02
bge- major_0x132e8_0x64
@ -639,7 +666,7 @@ major_0x134bc ; OUTSIDE REFERER
stw r17, 0x003c(r30)
mtxer r19
mr r8, r30
bl called_by_init_tmrqs
bl EnqueueTimer
b TimerDispatch_0x144
@ -685,7 +712,7 @@ major_0x13524 ; OUTSIDE REFERER
stw r17, 0x003c(r30)
mtxer r20
mr r8, r30
bl called_by_init_tmrqs
bl EnqueueTimer
major_0x13524_0x1c ; OUTSIDE REFERER
b TimerDispatch_0x144
@ -747,7 +774,7 @@ major_0x135b8_0x4 ; OUTSIDE REFERER
mtxer r20
beq+ cr1, TimerDispatch_0x144
mr r8, r30
bl called_by_init_tmrqs
bl EnqueueTimer
b TimerDispatch_0x144
@ -767,7 +794,7 @@ major_0x135b8_0x4 ; OUTSIDE REFERER
stw r17, 0x003c(r30)
mtxer r19
mr r8, r30
bl called_by_init_tmrqs
bl EnqueueTimer
bl getchar
cmpwi r8, -0x01
beq+ TimerDispatch_0x144
@ -776,7 +803,7 @@ major_0x135b8_0x4 ; OUTSIDE REFERER
; called_by_init_tmrqs
; EnqueueTimer
; Xrefs:
; MPCall_55
@ -789,63 +816,77 @@ major_0x135b8_0x4 ; OUTSIDE REFERER
; MPCall_31
; InitTMRQs
; ARG KernelData *r1, TimerQueueStruct *r8
; ARG Timer *r8
; CLOB r16-r20
called_by_init_tmrqs ; OUTSIDE REFERER
lwz r16, 0x0038(r8)
lwz r17, 0x003c(r8)
EnqueueTimer ; OUTSIDE REFERER
; Keep the trip-time of this timer in r16/r17
lwz r16, Timer.Time(r8)
lwz r17, Timer.Time+4(r8)
; r20 = timer being considered
; r18/r19 = trip-time of timer being condidered
lwz r20, PSA.TimerQueue + TimerQueueStruct.LLL + LLL.Next(r1)
lwz r18, 0x0038(r20)
lwz r19, 0x003c(r20)
lwz r18, Timer.Time(r20)
lwz r19, Timer.Time+4(r20)
; First try to insert at head of global TMRQ
cmpw r16, r18
cmplw cr1, r17, r19
bgt- called_by_init_tmrqs_0x5c
blt- called_by_init_tmrqs_0x28
bge- cr1, called_by_init_tmrqs_0x5c
bgt- @insert_further_ahead
blt- @insert_at_tail
bge- cr1, @insert_further_ahead
called_by_init_tmrqs_0x28
addi r20, r1, -0xa84
li r18, 0x01
stb r18, 0x0017(r8)
lwz r19, 0x0000(r8)
lwz r9, 0x0000(r20)
stw r9, 0x0000(r8)
lwz r9, 0x0008(r20)
stw r9, 0x0008(r8)
stw r20, 0x000c(r8)
stw r8, 0x000c(r9)
stw r8, 0x0008(r20)
stw r19, 0x0000(r8)
b major_0x13060
@insert_at_tail
addi r20, r1, PSA.TimerQueue + TimerQueueStruct.LLL
called_by_init_tmrqs_0x5c
lwz r20, -0x0a78(r1)
li r18, 1
stb r18, Timer.Byte3(r8)
called_by_init_tmrqs_0x60
lwz r18, 0x0038(r20)
lwz r19, 0x003c(r20)
; Insert at the very back of the queue
lwz r19, LLL.Freeform(r8)
lwz r9, LLL.Freeform(r20)
stw r9, LLL.Freeform(r8) ; my freeform = considered freeform
lwz r9, LLL.Next(r20)
stw r9, LLL.Next(r8) ; my next = next of considered
stw r20, LLL.Prev(r8) ; my prev = considered
stw r8, LLL.Prev(r9) ; prev of next of considered = me
stw r8, LLL.Next(r20) ; next of considered = me
stw r19, LLL.Freeform(r8) ; my freeform = my original freeform
b AdjustDecForTMRQ
@insert_further_ahead
lwz r20, PSA.TimerQueue + TimerQueueStruct.LLL + LLL.Prev(r1)
@searchloop
lwz r18, Timer.Time(r20)
lwz r19, Timer.Time+4(r20)
cmpw r16, r18
cmplw cr1, r17, r19
bgt- called_by_init_tmrqs_0x84
blt- called_by_init_tmrqs_0x7c
bge- cr1, called_by_init_tmrqs_0x84
bgt- @insert_after_this_one
blt- @next
bge- cr1, @insert_after_this_one
called_by_init_tmrqs_0x7c
lwz r20, 0x000c(r20)
b called_by_init_tmrqs_0x60
@next
lwz r20, LLL.Prev(r20)
b @searchloop
@insert_after_this_one
li r18, 1
stb r18, Timer.Byte3(r8)
lwz r19, LLL.Freeform(r8)
lwz r9, LLL.Freeform(r20)
stw r9, LLL.Freeform(r8) ; my freeform = considered freeform
lwz r9, LLL.Next(r20)
stw r9, LLL.Next(r8) ; my next = next of considered
stw r20, LLL.Prev(r8) ; my prev = considered
stw r8, LLL.Prev(r9) ; prev of next of considered = me
stw r8, LLL.Next(r20) ; next of considered = me
stw r19, LLL.Freeform(r8) ; my freeform = my original freeform
called_by_init_tmrqs_0x84
li r18, 0x01
stb r18, 0x0017(r8)
lwz r19, 0x0000(r8)
lwz r9, 0x0000(r20)
stw r9, 0x0000(r8)
lwz r9, 0x0008(r20)
stw r9, 0x0008(r8)
stw r20, 0x000c(r8)
stw r8, 0x000c(r9)
stw r8, 0x0008(r20)
stw r19, 0x0000(r8)
blr
@ -889,7 +930,7 @@ major_0x136c8 ; OUTSIDE REFERER
li r16, 0x00
cmpw r18, r8
stb r16, 0x0017(r8)
beq+ major_0x13060
beq+ AdjustDecForTMRQ
blr
@ -948,7 +989,7 @@ TimebaseTicksPerPeriod
; MPCall_32
; CreateTask
; InitTMRQs
; major_0x13060
; AdjustDecForTMRQ
; major_0x142dc
; major_0x14548