sm64

A Super Mario 64 decompilation
Log | Files | Refs | README | LICENSE

__osExceptionPreamble.s (25700B)


      1 .set noat      // allow manual use of $at
      2 .set noreorder // don't insert nops after branches
      3 
      4 #include "macros.inc"
      5 
      6 #include <PR/R4300.h>
      7 #include <PR/rcp.h>
      8 #include <PR/ique.h>
      9 
     10 #if defined(VERSION_EU) || defined(VERSION_SH)
     11 #define VERSION_EU_SH
     12 #endif
     13 
     14 #if defined(VERSION_EU) || defined(VERSION_SH) || defined(VERSION_CN)
     15 #define VERSION_EU_SH_CN
     16 #endif
     17 
     18 .section .text, "ax"
     19 
     20 #ifdef AVOID_UB
     21 .set __osThreadTail, __osThreadTail_fix
     22 #endif
     23 
     24 glabel __osExceptionPreamble
     25     la    $k0, __osException
     26     jr    $k0
     27      nop
     28 
     29 glabel __osException
     30     la    $k0, __osThreadSave
     31     sd    $at, 0x20($k0)
     32     mfc0  $k1, $12
     33     sw    $k1, 0x118($k0)
     34     li    $at, -4
     35     and   $k1, $k1, $at
     36     mtc0  $k1, $12
     37     sd    $t0, 0x58($k0)
     38     sd    $t1, 0x60($k0)
     39     sd    $t2, 0x68($k0)
     40     sw    $zero, 0x18($k0)
     41     mfc0  $t0, $13
     42 #ifndef VERSION_EU_SH_CN
     43     andi  $t1, $t0, 0x7c
     44     li    $t2, 0
     45     bne   $t1, $t2, .L80326750
     46      nop
     47     and   $t1, $k1, $t0
     48     andi  $t2, $t1, 0x4000
     49     beqz  $t2, .L80326734
     50      nop
     51     li    $t1, 1
     52     lui   $at, %hi(D_80334934)
     53     b     .L80326794
     54      sw    $t1, %lo(D_80334934)($at)
     55 .L80326734:
     56     andi  $t2, $t1, 0x2000
     57     beqz  $t2, .L80326750
     58      nop
     59     li    $t1, 1
     60     lui   $at, %hi(D_80334938)
     61     b     .L80326794
     62      sw    $t1, %lo(D_80334938)($at)
     63 .L80326750:
     64     lui   $at, %hi(D_80334934)
     65     sw    $zero, %lo(D_80334934)($at)
     66     lui   $at, %hi(D_80334938)
     67 #endif
     68     move  $t0, $k0
     69 #ifndef VERSION_EU_SH_CN
     70     sw    $zero, %lo(D_80334938)($at)
     71 #endif
     72     lui   $k0, %hi(__osThreadTail + 0x10)
     73     lw    $k0, %lo(__osThreadTail + 0x10)($k0)
     74     ld    $t1, 0x20($t0)
     75     sd    $t1, 0x20($k0)
     76     ld    $t1, 0x118($t0)
     77     sd    $t1, 0x118($k0)
     78     ld    $t1, 0x58($t0)
     79     sd    $t1, 0x58($k0)
     80     ld    $t1, 0x60($t0)
     81     sd    $t1, 0x60($k0)
     82     ld    $t1, 0x68($t0)
     83     sd    $t1, 0x68($k0)
     84 #ifdef VERSION_EU_SH
     85     lw    $k1, 0x118($k0)
     86 #else
     87 .L80326794:
     88 #endif
     89 #ifndef VERSION_CN
     90     mflo  $t0
     91     sd    $t0, 0x108($k0)
     92     mfhi  $t0
     93 #endif
     94 #ifdef VERSION_EU_SH
     95     andi  $t1, $k1, 0xff00
     96 #endif
     97     sd    $v0, 0x28($k0)
     98     sd    $v1, 0x30($k0)
     99     sd    $a0, 0x38($k0)
    100     sd    $a1, 0x40($k0)
    101     sd    $a2, 0x48($k0)
    102     sd    $a3, 0x50($k0)
    103     sd    $t3, 0x70($k0)
    104     sd    $t4, 0x78($k0)
    105     sd    $t5, 0x80($k0)
    106     sd    $t6, 0x88($k0)
    107     sd    $t7, 0x90($k0)
    108     sd    $s0, 0x98($k0)
    109     sd    $s1, 0xa0($k0)
    110     sd    $s2, 0xa8($k0)
    111     sd    $s3, 0xb0($k0)
    112     sd    $s4, 0xb8($k0)
    113     sd    $s5, 0xc0($k0)
    114     sd    $s6, 0xc8($k0)
    115     sd    $s7, 0xd0($k0)
    116     sd    $t8, 0xd8($k0)
    117     sd    $t9, 0xe0($k0)
    118     sd    $gp, 0xe8($k0)
    119     sd    $sp, 0xf0($k0)
    120     sd    $fp, 0xf8($k0)
    121     sd    $ra, 0x100($k0)
    122 #ifdef VERSION_EU_SH_CN
    123 #ifdef VERSION_CN
    124     mflo  $t0
    125     sd    $t0, 0x108($k0)
    126     mfhi  $t0
    127     sd    $t0, 0x110($k0)
    128     lw    $k1, 0x118($k0)
    129     andi  $t1, $k1, SR_IMASK
    130     beqz  $t1, savercp
    131      nop
    132     la    $t0, __OSGlobalIntMask
    133     lw    $t0, ($t0)
    134     lui   $at, (0xFFFFFFFF >> 16)
    135     ori   $at, (0xFFFFFFFF & 0xFFFF)
    136     xor   $t2, $t0, $at
    137     andi  $t2, $t2, SR_IMASK
    138     or    $t4, $t1, $t2
    139     lui   $at, (~SR_IMASK >> 16) & 0xFFFF
    140     ori   $at, (~SR_IMASK & 0xFFFF)
    141     and   $t3, $k1, $at
    142     or    $t3, $t3, $t4
    143     sw    $t3, 0x118($k0)
    144     andi  $t0, $t0, SR_IMASK
    145     and   $t1, $t1, $t0
    146     lui   $at, (~SR_IMASK >> 16) & 0xFFFF
    147     ori   $at, (~SR_IMASK & 0xFFFF)
    148     and   $k1, $k1, $at
    149     or    $k1, $k1, $t1
    150 #else
    151     beqz  $t1, savercp
    152      sd    $t0, 0x110($k0)
    153     la    $t0, __OSGlobalIntMask
    154     lw    $t0, ($t0)
    155     li    $at, -1
    156 #ifdef VERSION_EU
    157     xor   $t0, $t0, $at
    158 #else
    159     xor   $t2, $t0, $at
    160 #endif
    161     lui   $at, (~SR_IMASK >> 16) & 0xFFFF
    162 #ifdef VERSION_EU
    163     andi  $t0, $t0, SR_IMASK
    164 #else
    165     andi  $t2, $t2, SR_IMASK
    166 #endif
    167     ori   $at, (~SR_IMASK & 0xFFFF)
    168 #ifdef VERSION_EU
    169     or    $t1, $t1, $t0
    170     and   $k1, $k1, $at
    171     or    $k1, $k1, $t1
    172     sw    $k1, 0x118($k0)
    173 #else
    174     or    $t4, $t1, $t2
    175     and   $t3, $k1, $at
    176     andi  $t0, $t0, SR_IMASK
    177     or    $t3, $t3, $t4
    178     and   $t1, $t1, $t0
    179     and   $k1, $k1, $at
    180     sw    $t3, 0x118($k0)
    181     or    $k1, $k1, $t1
    182 #endif
    183 #endif
    184 
    185 savercp:
    186     lui   $t1, %hi(PHYS_TO_K1(MI_INTR_MASK_REG))
    187     lw    $t1, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))($t1)
    188     beqz  $t1, endrcp
    189      nop
    190     la    $t0, __OSGlobalIntMask
    191     lw    $t0, ($t0)
    192 #ifdef VERSION_CN
    193     srl   $t0, $t0, 0x10
    194     li    $at, 0xFFFFFFFF
    195 #else
    196     lw    $t4, 0x128($k0)
    197     li    $at, 0xFFFFFFFF
    198     srl   $t0, $t0, 0x10
    199 #endif
    200     xor   $t0, $t0, $at
    201     andi  $t0, $t0, 0x3f
    202 #ifdef VERSION_CN
    203     lw    $t4, 0x128($k0)
    204 #endif
    205     and   $t0, $t0, $t4
    206     or    $t1, $t1, $t0
    207 endrcp:
    208     sw    $t1, 0x128($k0)
    209 #else
    210     sd    $t0, 0x110($k0)
    211 #endif
    212     mfc0  $t0, C0_EPC
    213     sw    $t0, 0x11c($k0)
    214     lw    $t0, 0x18($k0)
    215     beqz  $t0, .L80326868
    216      nop
    217     cfc1  $t0, $31
    218     nop
    219     sw    $t0, 0x12c($k0)
    220     sdc1  $f0, 0x130($k0)
    221     sdc1  $f2, 0x138($k0)
    222     sdc1  $f4, 0x140($k0)
    223     sdc1  $f6, 0x148($k0)
    224     sdc1  $f8, 0x150($k0)
    225     sdc1  $f10, 0x158($k0)
    226     sdc1  $f12, 0x160($k0)
    227     sdc1  $f14, 0x168($k0)
    228     sdc1  $f16, 0x170($k0)
    229     sdc1  $f18, 0x178($k0)
    230     sdc1  $f20, 0x180($k0)
    231     sdc1  $f22, 0x188($k0)
    232     sdc1  $f24, 0x190($k0)
    233     sdc1  $f26, 0x198($k0)
    234     sdc1  $f28, 0x1a0($k0)
    235     sdc1  $f30, 0x1a8($k0)
    236 .L80326868:
    237     mfc0  $t0, C0_CAUSE
    238     sw    $t0, 0x120($k0)
    239 #ifndef VERSION_EU_SH_CN
    240     lui   $t1, %hi(PHYS_TO_K1(MI_INTR_MASK_REG))
    241     lw    $t1, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))($t1)
    242     sw    $t1, 0x128($k0)
    243 #endif
    244     li    $t1, 2
    245     sh    $t1, 0x10($k0)
    246 #ifndef VERSION_EU_SH_CN
    247     lui   $t1, %hi(D_80334934)
    248     lw    $t1, %lo(D_80334934)($t1)
    249     beqz  $t1, .L803268B4
    250      nop
    251     lui   $t2, %hi(D_C0000008)
    252     sw    $zero, %lo(D_C0000008)($t2)
    253     lui   $a0, %hi(D_C0000000)
    254     addiu $t2, %lo(D_C0000008)
    255     jal   kdebugserver
    256      lw    $a0, %lo(D_C0000000)($a0)
    257     b     .L80326E08
    258      nop
    259 .L803268B4:
    260     lui   $t1, %hi(D_80334938)
    261     lw    $t1, %lo(D_80334938)($t1)
    262     beqz  $t1, .L80326900
    263      nop
    264     lui   $t2, %hi(D_C000000C)
    265     sw    $zero, %lo(D_C000000C)($t2)
    266     lui   $t1, %hi(__osRdbSendMessage)
    267     lw    $t1, %lo(__osRdbSendMessage)($t1)
    268     addiu $t2, %lo(D_C000000C)
    269     beqz  $t1, .L803268E8
    270      nop
    271     jal   send_mesg
    272      li    $a0, 120
    273 .L803268E8:
    274     lui   $t1, %hi(__osRdbWriteOK)
    275     lw    $t1, %lo(__osRdbWriteOK)($t1)
    276     lui   $at, %hi(__osRdbWriteOK)
    277     addi  $t1, $t1, 1
    278     b     .L80326E08
    279      sw    $t1, %lo(__osRdbWriteOK)($at)
    280 .L80326900:
    281 #endif
    282     andi  $t1, $t0, CAUSE_EXCMASK
    283     li    $t2, EXC_BREAK
    284     beq   $t1, $t2, handle_break
    285      nop
    286     li    $t2, EXC_CPU
    287     beq   $t1, $t2, handle_CpU
    288      nop
    289     li    $t2, EXC_INT
    290     bne   $t1, $t2, panic
    291      nop
    292     and   $s0, $k1, $t0
    293 next_interrupt:
    294     andi  $t1, $s0, SR_IMASK
    295     srl   $t2, $t1, 0xc
    296     bnez  $t2, .L80326944
    297      nop
    298     srl   $t2, $t1, 8
    299     addi  $t2, $t2, 0x10
    300 .L80326944:
    301     // TODO: Get rid of noat
    302 .set at
    303     lbu   $t2, __osIntOffTable($t2)
    304     lw    $t2, __osIntTable($t2)
    305 .set noat
    306     jr    $t2
    307      nop
    308 #ifdef VERSION_EU_SH_CN
    309 glabel IP6_Hdlr
    310     li    $at, ~CAUSE_IP6
    311     b     next_interrupt
    312      and   $s0, $s0, $at
    313 glabel IP7_Hdlr
    314     li    $at, ~CAUSE_IP7
    315     b     next_interrupt
    316      and   $s0, $s0, $at
    317 #endif
    318 glabel counter
    319     mfc0  $t1, C0_COMPARE
    320     mtc0  $t1, C0_COMPARE
    321 #ifdef VERSION_CN
    322     li    $a0, 24
    323     jal   send_mesg
    324      nop
    325 #else
    326     jal   send_mesg
    327      li    $a0, 24
    328 #endif
    329     lui   $at, (~CAUSE_IP8 >> 16) & 0xFFFF
    330     ori   $at, (~CAUSE_IP8 & 0xFFFF)
    331     b     next_interrupt
    332      and   $s0, $s0, $at
    333 
    334 glabel cart
    335 #ifdef VERSION_EU_SH_CN
    336     li    $at, ~CAUSE_IP4
    337     and   $s0, $s0, $at
    338 #endif
    339 #ifdef VERSION_CN
    340     la    $t1, __osHwIntTable
    341     addi  $t1, $t1, 4 * 2
    342     lw    $t2, ($t1)
    343     beqz  $t2, .L80307480
    344      nop
    345     jalr  $t2
    346      lw   $sp, 4($t1)
    347     beqz  $v0, .L80307480
    348      nop
    349     b     redispatch
    350      nop
    351 .L80307480:
    352     lui   $s1, %hi(PHYS_TO_K1(MI_HW_INTR_REG))
    353     lw    $s1, %lo(PHYS_TO_K1(MI_HW_INTR_REG))($s1)
    354     andi  $t1, $s1, 0x40
    355     beqz  $t1, .L803074AC
    356      nop
    357     andi  $s1, $s1, 0x3F80
    358     li    $t1, 0
    359     lui   $at, %hi(PHYS_TO_K1(PI_CARD_ADDR_REG))
    360     sw    $t1, %lo(PHYS_TO_K1(PI_CARD_ADDR_REG))($at)
    361     jal   send_mesg
    362      li    $a0, 184
    363 .L803074AC:
    364     andi  $t1, $s1, 0x2000
    365     beqz  $t1, .L803074D0
    366      nop
    367     andi  $s1, $s1, 0x1FC0
    368     li    $t1, 0x2000
    369     lui   $at, %hi(PHYS_TO_K1(MI_HW_INTR_REG))
    370     sw    $t1, %lo(PHYS_TO_K1(MI_HW_INTR_REG))($at)
    371     jal   send_mesg
    372      li    $a0, 240
    373 .L803074D0:
    374     andi  $t1, $s1, 0x80
    375     beqz  $t1, .L803074F4
    376      nop
    377     andi  $s1, $s1, 0x3F40
    378     li    $t1, 0x4000
    379     lui   $at, %hi(PHYS_TO_K1(MI_HW_INTR_MASK_REG))
    380     sw    $t1, %lo(PHYS_TO_K1(MI_HW_INTR_MASK_REG))($at)
    381     jal   send_mesg
    382      li    $a0, 192
    383 .L803074F4:
    384     andi  $t1, $s1, 0x100
    385     beqz  $t1, .L80307518
    386      nop
    387     andi  $s1, $s1, 0x3EC0
    388     lui   $t1, 1
    389     lui   $at, %hi(PHYS_TO_K1(MI_HW_INTR_MASK_REG))
    390     sw    $t1, %lo(PHYS_TO_K1(MI_HW_INTR_MASK_REG))($at)
    391     jal   send_mesg
    392      li    $a0, 200
    393 .L80307518:
    394     andi  $t1, $s1, 0x200
    395     beqz  $t1, .L8030753C
    396      nop
    397     andi  $s1, $s1, 0x3DC0
    398     lui   $t1, 4
    399     lui   $at, %hi(PHYS_TO_K1(MI_HW_INTR_MASK_REG))
    400     sw    $t1, %lo(PHYS_TO_K1(MI_HW_INTR_MASK_REG))($at)
    401     jal   send_mesg
    402      li    $a0, 208
    403 .L8030753C:
    404     andi  $t1, $s1, 0x400
    405     beqz  $t1, .L80307560
    406      nop
    407     andi  $s1, $s1, 0x3BC0
    408     lui   $t1, 0x10
    409     lui   $at, %hi(PHYS_TO_K1(MI_HW_INTR_MASK_REG))
    410     sw    $t1, %lo(PHYS_TO_K1(MI_HW_INTR_MASK_REG))($at)
    411     jal   send_mesg
    412      li    $a0, 216
    413 .L80307560:
    414     andi  $t1, $s1, 0x800
    415     beqz  $t1, .L80307584
    416      nop
    417     andi  $s1, $s1, 0x37C0
    418     lui   $t1, 0x40
    419     lui   $at, %hi(PHYS_TO_K1(MI_HW_INTR_MASK_REG))
    420     sw    $t1, %lo(PHYS_TO_K1(MI_HW_INTR_MASK_REG))($at)
    421     jal   send_mesg
    422      li    $a0, 224
    423 .L80307584:
    424     b     next_interrupt
    425      nop
    426 #else
    427     li    $t2, 4
    428     lui   $at, %hi(__osHwIntTable)
    429     addu  $at, $at, $t2
    430     lw    $t2, %lo(__osHwIntTable)($at)
    431 #ifdef VERSION_EU_SH
    432     la    $sp, leoDiskStack
    433     li    $a0, 16
    434     beqz  $t2, .L803269A4
    435      addiu $sp, $sp, 0xff0
    436 #else
    437     beqz  $t2, .L803269A4
    438      nop
    439 #endif
    440     jalr  $t2
    441      nop
    442 #ifdef VERSION_EU_SH
    443     beqz  $v0, .L803269A4
    444 #ifdef VERSION_SH
    445      li    $a0, 0x10
    446 #else
    447      nop
    448 #endif
    449     b     redispatch
    450      nop
    451 #endif
    452 .L803269A4:
    453     jal   send_mesg
    454 #ifdef VERSION_EU_SH
    455      nop
    456     b     next_interrupt
    457      nop
    458 #else
    459      li    $a0, 16
    460     li    $at, -2049
    461     b     next_interrupt
    462      and   $s0, $s0, $at
    463 #endif
    464 #endif
    465 glabel rcp
    466 #ifdef VERSION_EU_SH
    467     la    $t0, __OSGlobalIntMask
    468     lw    $t0, ($t0)
    469 #endif
    470     lui   $s1, %hi(PHYS_TO_K1(MI_INTR_REG))
    471     lw    $s1, %lo(PHYS_TO_K1(MI_INTR_REG))($s1)
    472 #ifdef VERSION_CN
    473     la    $t0, __OSGlobalIntMask
    474     lw    $t0, ($t0)
    475 #endif
    476 #ifdef VERSION_EU_SH_CN
    477     srl   $t0, $t0, 0x10
    478     and   $s1, $s1, $t0
    479 #else
    480     andi  $s1, $s1, 0x3f
    481 #endif
    482     andi  $t1, $s1, MI_INTR_SP
    483     beqz  $t1, vi
    484      nop
    485 #ifdef VERSION_CN
    486     andi  $s1, $s1, 0x3e
    487 #endif
    488     lui   $t4, %hi(PHYS_TO_K1(SP_STATUS_REG))
    489     lw    $t4, %lo(PHYS_TO_K1(SP_STATUS_REG))($t4)
    490 #ifdef VERSION_CN
    491     li    $t1, SP_CLR_INTR | SP_CLR_SIG3
    492 #else
    493     li    $t1, SP_CLR_INTR
    494 #endif
    495     lui   $at, %hi(PHYS_TO_K1(SP_STATUS_REG))
    496 #ifdef VERSION_CN
    497     sw    $t1, %lo(PHYS_TO_K1(SP_STATUS_REG))($at)
    498     andi  $t4, $t4, 0x300
    499     beqz  $t4, sp_other_break
    500      nop
    501 #else
    502     andi  $t4, $t4, 0x300
    503     andi  $s1, $s1, 0x3e
    504     beqz  $t4, sp_other_break
    505      sw    $t1, %lo(PHYS_TO_K1(SP_STATUS_REG))($at)
    506 #endif
    507     jal   send_mesg
    508      li    $a0, 32
    509     beqz  $s1, no_more_rcp_ints
    510      nop
    511     b     vi
    512      nop
    513 sp_other_break:
    514     jal   send_mesg
    515      li    $a0, 88
    516     beqz  $s1, no_more_rcp_ints
    517      nop
    518 vi:
    519     andi  $t1, $s1, 8
    520     beqz  $t1, ai
    521 #ifdef VERSION_CN
    522      nop
    523     andi  $s1, $s1, 0x37
    524     lui   $at, %hi(PHYS_TO_K1(VI_CURRENT_REG))
    525 #else
    526      lui   $at, %hi(PHYS_TO_K1(VI_CURRENT_REG))
    527     andi  $s1, $s1, 0x37
    528 #endif
    529     sw    $zero, %lo(PHYS_TO_K1(VI_CURRENT_REG))($at)
    530     jal   send_mesg
    531      li    $a0, 56
    532     beqz  $s1, no_more_rcp_ints
    533      nop
    534 ai:
    535     andi  $t1, $s1, 4
    536     beqz  $t1, si
    537      nop
    538 #ifdef VERSION_CN
    539     andi  $s1, $s1, 0x3b
    540 #endif
    541     li    $t1, 1
    542     lui   $at, %hi(PHYS_TO_K1(AI_STATUS_REG))
    543 #ifndef VERSION_CN
    544     andi  $s1, $s1, 0x3b
    545 #endif
    546     sw    $t1, %lo(PHYS_TO_K1(AI_STATUS_REG))($at)
    547     jal   send_mesg
    548      li    $a0, 48
    549     beqz  $s1, no_more_rcp_ints
    550      nop
    551 si:
    552     andi  $t1, $s1, 2
    553     beqz  $t1, pi
    554 #ifdef VERSION_CN
    555     nop
    556 #else
    557      lui   $at, %hi(PHYS_TO_K1(SI_STATUS_REG))
    558 #endif
    559     andi  $s1, $s1, 0x3d
    560 #ifdef VERSION_CN
    561      lui   $at, %hi(PHYS_TO_K1(SI_STATUS_REG))
    562 #endif
    563     sw    $zero, %lo(PHYS_TO_K1(SI_STATUS_REG))($at)
    564     jal   send_mesg
    565      li    $a0, 40
    566     beqz  $s1, no_more_rcp_ints
    567      nop
    568 pi:
    569     andi  $t1, $s1, 0x10
    570     beqz  $t1, dp
    571      nop
    572 #ifdef VERSION_CN
    573     andi  $s1, $s1, 0x2f
    574     li    $t1, 2
    575     lui   $at, %hi(PHYS_TO_K1(PI_STATUS_REG))
    576     sw    $t1, %lo(PHYS_TO_K1(PI_STATUS_REG))($at)
    577     la    $t1, D_CN_80319658
    578     lw    $t2, ($t1)
    579     beqz  $t2, .L803076C0
    580      nop
    581     lw    $sp, 4($t1)
    582     jalr  $t2
    583     move  $a0, $v0
    584     bnez  $v0, .L803076C8
    585      nop
    586 .L803076C0:
    587 #else
    588     li    $t1, 2
    589     lui   $at, %hi(PHYS_TO_K1(PI_STATUS_REG))
    590     andi  $s1, $s1, 0x2f
    591     sw    $t1, %lo(PHYS_TO_K1(PI_STATUS_REG))($at)
    592 #endif
    593     jal   send_mesg
    594      li    $a0, 64
    595 .L803076C8:
    596     beqz  $s1, no_more_rcp_ints
    597      nop
    598 dp:
    599     andi  $t1, $s1, 0x20
    600     beqz  $t1, no_more_rcp_ints
    601      nop
    602 #ifdef VERSION_CN
    603     andi  $s1, $s1, 0x1f
    604 #endif
    605     li    $t1, MI_CLR_DP_INTR
    606     lui   $at, %hi(PHYS_TO_K1(MI_MODE_REG))
    607 #ifndef VERSION_CN
    608     andi  $s1, $s1, 0x1f
    609 #endif
    610     sw    $t1, %lo(PHYS_TO_K1(MI_MODE_REG))($at)
    611     jal   send_mesg
    612      li    $a0, 72
    613 no_more_rcp_ints:
    614     li    $at, -1025
    615     b     next_interrupt
    616      and   $s0, $s0, $at
    617 glabel prenmi
    618     lw    $k1, 0x118($k0)
    619     li    $at, -4097
    620 #ifdef VERSION_CN
    621     and   $k1, $k1, $at
    622     sw    $k1, 0x118($k0)
    623     la    $t1, __osShutdown
    624 #else
    625     lui   $t1, %hi(__osShutdown)
    626     and   $k1, $k1, $at
    627     sw    $k1, 0x118($k0)
    628     addiu $t1, %lo(__osShutdown)
    629 #endif
    630     lw    $t2, ($t1)
    631     beqz  $t2, firstnmi
    632 #ifdef VERSION_CN
    633      nop
    634 #endif
    635      li    $at, -4097
    636     b     redispatch
    637      and   $s0, $s0, $at
    638 firstnmi:
    639     li    $t2, 1
    640     sw    $t2, ($t1)
    641     jal   send_mesg
    642      li    $a0, 112
    643 #ifdef VERSION_CN
    644     li    $at, -4097
    645     and   $s0, $s0, $at
    646 #endif
    647     lui   $t2, %hi(__osThreadTail + 0x8)
    648     lw    $t2, %lo(__osThreadTail + 0x8)($t2)
    649 #ifndef VERSION_CN
    650     li    $at, -4097
    651     and   $s0, $s0, $at
    652 #endif
    653     lw    $k1, 0x118($t2)
    654 #ifdef VERSION_CN
    655     li    $at, -4097
    656 #endif
    657     and   $k1, $k1, $at
    658     b     redispatch
    659      sw    $k1, 0x118($t2)
    660 glabel sw2
    661     li    $at, -513
    662     and   $t0, $t0, $at
    663     mtc0  $t0, $13
    664 #ifdef VERSION_CN
    665     li    $a0, 8
    666     jal   send_mesg
    667      nop
    668 #else
    669     jal   send_mesg
    670      li    $a0, 8
    671 #endif
    672     li    $at, -513
    673     b     next_interrupt
    674      and   $s0, $s0, $at
    675 glabel sw1
    676     li    $at, -257
    677     and   $t0, $t0, $at
    678     mtc0  $t0, $13
    679 #ifdef VERSION_CN
    680     li    $a0, 0
    681     jal   send_mesg
    682      nop
    683 #else
    684     jal   send_mesg
    685      li    $a0, 0
    686 #endif
    687     li    $at, -257
    688     b     next_interrupt
    689      and   $s0, $s0, $at
    690 handle_break:
    691     li    $t1, 1
    692     sh    $t1, 0x12($k0)
    693     jal   send_mesg
    694      li    $a0, 80
    695     b     redispatch
    696      nop
    697 
    698 glabel redispatch
    699 #ifdef VERSION_CN
    700     lw    $t1, 4($k0)
    701     lui   $t2, %hi(__osThreadTail + 0x8)
    702     lw    $t2, %lo(__osThreadTail + 0x8)($t2)
    703     lw    $t3, 4($t2)
    704     slt   $at, $t1, $t3
    705     beqz  $at, enqueue_running
    706      nop
    707     move  $a1, $k0
    708     la    $a0, __osThreadTail + 0x8
    709     jal   __osEnqueueThread
    710      nop
    711 #else
    712     lui   $t2, %hi(__osThreadTail + 0x8)
    713     lw    $t2, %lo(__osThreadTail + 0x8)($t2)
    714     lw    $t1, 4($k0)
    715     lw    $t3, 4($t2)
    716     slt   $at, $t1, $t3
    717     beqz  $at, enqueue_running
    718      nop
    719     lui   $a0, %hi(__osThreadTail + 0x8)
    720     move  $a1, $k0
    721     jal   __osEnqueueThread
    722      addiu $a0, %lo(__osThreadTail + 0x8)
    723 #endif
    724     j     __osDispatchThread
    725      nop
    726 
    727 enqueue_running:
    728     la    $t1, __osThreadTail + 0x8
    729     lw    $t2, ($t1)
    730     sw    $t2, ($k0)
    731     j     __osDispatchThread
    732      sw    $k0, ($t1)
    733 
    734 glabel panic
    735     lui   $at, %hi(__osThreadTail + 0x14)
    736     sw    $k0, %lo(__osThreadTail + 0x14)($at)
    737     li    $t1, 1
    738     sh    $t1, 0x10($k0)
    739     li    $t1, 2
    740     sh    $t1, 0x12($k0)
    741     mfc0  $t2, $8
    742     sw    $t2, 0x124($k0)
    743     jal   send_mesg
    744      li    $a0, 96
    745     j     __osDispatchThread
    746      nop
    747 
    748 glabel send_mesg
    749 #ifdef VERSION_CN
    750     move  $s2, $ra
    751 #endif
    752     la    $t2, __osEventStateTab
    753     addu  $t2, $t2, $a0
    754     lw    $t1, ($t2)
    755 #ifndef VERSION_CN
    756     move  $s2, $ra
    757 #endif
    758     beqz  $t1, .L80326CC4
    759      nop
    760     lw    $t3, 8($t1)
    761     lw    $t4, 0x10($t1)
    762     slt   $at, $t3, $t4
    763     beqz  $at, .L80326CC4
    764      nop
    765     lw    $t5, 0xc($t1)
    766     addu  $t5, $t5, $t3
    767 #ifdef VERSION_CN
    768     bnez  $t4, .L80326C60
    769      div   $zero, $t5, $t4
    770 #else
    771     div   $zero, $t5, $t4
    772     bnez  $t4, .L80326C60
    773      nop
    774 #endif
    775     break 7
    776 .L80326C60:
    777     li    $at, -1
    778     bne   $t4, $at, .L80326C78
    779      lui   $at, 0x8000
    780     bne   $t5, $at, .L80326C78
    781      nop
    782     break 6
    783 .L80326C78:
    784 #ifdef VERSION_CN
    785     mfhi  $t5
    786     lw    $t4, 0x14($t1)
    787     li    $at, 4
    788     mult  $t5, $at
    789     mflo  $t5
    790 #else
    791     lw    $t4, 0x14($t1)
    792     mfhi  $t5
    793     sll   $t5, $t5, 2
    794 #endif
    795     addu  $t4, $t4, $t5
    796     lw    $t5, 4($t2)
    797 #ifdef VERSION_CN
    798     sw    $t5, ($t4)
    799     addiu $t2, $t3, 1
    800 #else
    801     addiu $t2, $t3, 1
    802     sw    $t5, ($t4)
    803 #endif
    804     sw    $t2, 8($t1)
    805     lw    $t2, ($t1)
    806     lw    $t3, ($t2)
    807     beqz  $t3, .L80326CC4
    808      nop
    809     jal   __osPopThread
    810      move  $a0, $t1
    811     move  $t2, $v0
    812 #ifdef VERSION_CN
    813     move  $a1, $t2
    814     la    $a0, __osThreadTail + 0x8
    815     jal   __osEnqueueThread
    816      nop
    817 #else
    818     lui   $a0, %hi(__osThreadTail + 0x8)
    819     move  $a1, $t2
    820     jal   __osEnqueueThread
    821      addiu $a0, %lo(__osThreadTail + 0x8)
    822 #endif
    823 .L80326CC4:
    824     jr    $s2
    825      nop
    826 handle_CpU: // coprocessor error
    827     lui   $at, 0x3000
    828     and   $t1, $t0, $at
    829     srl   $t1, $t1, 0x1c
    830     li    $t2, 1
    831     bne   $t1, $t2, panic
    832      nop
    833 #ifdef VERSION_CN
    834     li    $t1, 1
    835     sw    $t1, 0x18($k0)
    836     lw    $k1, 0x118($k0)
    837     lui   $at, 0x2000
    838     or    $k1, $k1, $at
    839 #else
    840     lw    $k1, 0x118($k0)
    841     lui   $at, 0x2000
    842     li    $t1, 1
    843     or    $k1, $k1, $at
    844     sw    $t1, 0x18($k0)
    845 #endif
    846     b     enqueue_running
    847      sw    $k1, 0x118($k0)
    848 
    849 
    850 glabel __osEnqueueAndYield
    851     lui   $a1, %hi(__osThreadTail + 0x10)
    852     lw    $a1, %lo(__osThreadTail + 0x10)($a1)
    853     mfc0  $t0, $12
    854 #ifndef VERSION_CN
    855     lw    $k1, 0x18($a1)
    856 #endif
    857     ori   $t0, $t0, 2
    858     sw    $t0, 0x118($a1)
    859     sd    $s0, 0x98($a1)
    860     sd    $s1, 0xa0($a1)
    861     sd    $s2, 0xa8($a1)
    862     sd    $s3, 0xb0($a1)
    863     sd    $s4, 0xb8($a1)
    864     sd    $s5, 0xc0($a1)
    865     sd    $s6, 0xc8($a1)
    866     sd    $s7, 0xd0($a1)
    867     sd    $gp, 0xe8($a1)
    868     sd    $sp, 0xf0($a1)
    869     sd    $fp, 0xf8($a1)
    870     sd    $ra, 0x100($a1)
    871 #ifdef VERSION_CN
    872     sw    $ra, 0x11c($a1)
    873     lw    $k1, 0x18($a1)
    874     beqz  $k1, .L80326D70
    875      nop
    876     cfc1  $k1, $31
    877     sw    $k1, 0x12c($a1)
    878 #else
    879     beqz  $k1, .L80326D70
    880      sw    $ra, 0x11c($a1)
    881     cfc1  $k1, $31
    882 #endif
    883     sdc1  $f20, 0x180($a1)
    884     sdc1  $f22, 0x188($a1)
    885     sdc1  $f24, 0x190($a1)
    886     sdc1  $f26, 0x198($a1)
    887     sdc1  $f28, 0x1a0($a1)
    888     sdc1  $f30, 0x1a8($a1)
    889 #ifndef VERSION_CN
    890     sw    $k1, 0x12c($a1)
    891 #endif
    892 
    893 .L80326D70:
    894 #ifdef VERSION_EU_SH_CN
    895     lw    $k1, 0x118($a1)
    896     andi  $t1, $k1, 0xff00
    897     beqz  $t1, .L802F3FBC
    898      nop
    899     la    $t0, __OSGlobalIntMask
    900     lw    $t0, ($t0)
    901     li    $at, 0xFFFFFFFF
    902     xor   $t0, $t0, $at
    903 #ifdef VERSION_CN
    904     andi  $t0, $t0, SR_IMASK
    905     or    $t1, $t1, $t0
    906     li    $at, ~SR_IMASK
    907 #else
    908     lui   $at, (~SR_IMASK >> 16) & 0xFFFF
    909     andi  $t0, $t0, SR_IMASK
    910     ori   $at, (~SR_IMASK & 0xFFFF)
    911     or    $t1, $t1, $t0
    912 #endif
    913     and   $k1, $k1, $at
    914     or    $k1, $k1, $t1
    915     sw    $k1, 0x118($a1)
    916 .L802F3FBC:
    917 #endif
    918     lui   $k1, %hi(PHYS_TO_K1(MI_INTR_MASK_REG))
    919     lw    $k1, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))($k1)
    920 #ifdef VERSION_EU_SH_CN
    921     beqz  $k1, .L802F3FF4
    922      nop
    923     la    $k0, __OSGlobalIntMask
    924     lw    $k0, ($k0)
    925 #ifdef VERSION_CN
    926     srl   $k0, $k0, 0x10
    927     li    $at, 0xFFFFFFFF
    928     xor   $k0, $k0, $at
    929     andi  $k0, $k0, 0x3f
    930     lw    $t0, 0x128($a1)
    931 #else
    932     lw    $t0, 0x128($a1)
    933     li    $at, 0xFFFFFFFF
    934     srl   $k0, $k0, 0x10
    935     xor   $k0, $k0, $at
    936     andi  $k0, $k0, 0x3f
    937 #endif
    938     and   $k0, $k0, $t0
    939     or    $k1, $k1, $k0
    940 .L802F3FF4:
    941 #endif
    942     beqz  $a0, .L80326D88
    943      sw    $k1, 0x128($a1)
    944     jal   __osEnqueueThread
    945      nop
    946 .L80326D88:
    947     j     __osDispatchThread
    948      nop
    949 
    950 // enqueue and pop look like compiled functions?  but there's no easy way to extract them
    951 glabel __osEnqueueThread
    952 #ifdef VERSION_CN
    953     move  $t9, $a0
    954 #endif
    955     lw    $t8, ($a0)
    956     lw    $t7, 4($a1)
    957 #ifndef VERSION_CN
    958     move  $t9, $a0
    959 #endif
    960     lw    $t6, 4($t8)
    961     slt   $at, $t6, $t7
    962     bnez  $at, .L80326DC4
    963      nop
    964 .L80326DAC:
    965     move  $t9, $t8
    966     lw    $t8, ($t8)
    967     lw    $t6, 4($t8)
    968     slt   $at, $t6, $t7
    969     beqz  $at, .L80326DAC
    970      nop
    971 .L80326DC4:
    972     lw    $t8, ($t9)
    973     sw    $t8, ($a1)
    974     sw    $a1, ($t9)
    975     jr    $ra
    976      sw    $a0, 8($a1)
    977 
    978 glabel __osPopThread
    979     lw    $v0, ($a0)
    980     lw    $t9, ($v0)
    981     jr    $ra
    982      sw    $t9, ($a0)
    983 
    984 #ifdef VERSION_CN
    985 func_unused:
    986     jr    $ra
    987      nop
    988 #endif
    989 
    990 glabel __osDispatchThread
    991 #ifdef VERSION_CN
    992     la    $a0, __osThreadTail + 0x8
    993     jal   __osPopThread
    994     nop
    995 #else
    996     lui   $a0, %hi(__osThreadTail + 0x8)
    997     jal   __osPopThread
    998      addiu $a0, %lo(__osThreadTail + 0x8)
    999 #endif
   1000     lui   $at, %hi(__osThreadTail + 0x10)
   1001     sw    $v0, %lo(__osThreadTail + 0x10)($at)
   1002     li    $t0, 4
   1003     sh    $t0, 0x10($v0)
   1004     move  $k0, $v0
   1005 #ifdef VERSION_EU_SH_CN
   1006 #ifdef VERSION_CN
   1007     lw    $k1, 0x118($k0)
   1008     la    $t0, __OSGlobalIntMask
   1009     lw    $t0, ($t0)
   1010     andi  $t0, $t0, SR_IMASK
   1011     andi  $t1, $k1, SR_IMASK
   1012     and   $t1, $t1, $t0
   1013     li    $at, ~SR_IMASK
   1014 #else
   1015     lui   $t0, %hi(__OSGlobalIntMask)
   1016     lw    $k1, 0x118($k0)
   1017     addiu $t0, %lo(__OSGlobalIntMask)
   1018     lw    $t0, ($t0)
   1019     lui   $at, (~SR_IMASK >> 16) & 0xFFFF
   1020     andi  $t1, $k1, SR_IMASK
   1021     ori   $at, (~SR_IMASK & 0xFFFF)
   1022     andi  $t0, $t0, SR_IMASK
   1023     and   $t1, $t1, $t0
   1024 #endif
   1025     and   $k1, $k1, $at
   1026     or    $k1, $k1, $t1
   1027     mtc0  $k1, $12
   1028 #endif
   1029 .L80326E08:
   1030 #ifndef VERSION_CN
   1031     ld    $k1, 0x108($k0)
   1032 #endif
   1033     ld    $at, 0x20($k0)
   1034     ld    $v0, 0x28($k0)
   1035 #ifndef VERSION_CN
   1036     mtlo  $k1
   1037     ld    $k1, 0x110($k0)
   1038 #endif
   1039     ld    $v1, 0x30($k0)
   1040     ld    $a0, 0x38($k0)
   1041     ld    $a1, 0x40($k0)
   1042     ld    $a2, 0x48($k0)
   1043     ld    $a3, 0x50($k0)
   1044     ld    $t0, 0x58($k0)
   1045     ld    $t1, 0x60($k0)
   1046     ld    $t2, 0x68($k0)
   1047     ld    $t3, 0x70($k0)
   1048     ld    $t4, 0x78($k0)
   1049     ld    $t5, 0x80($k0)
   1050     ld    $t6, 0x88($k0)
   1051     ld    $t7, 0x90($k0)
   1052     ld    $s0, 0x98($k0)
   1053     ld    $s1, 0xa0($k0)
   1054     ld    $s2, 0xa8($k0)
   1055     ld    $s3, 0xb0($k0)
   1056     ld    $s4, 0xb8($k0)
   1057     ld    $s5, 0xc0($k0)
   1058     ld    $s6, 0xc8($k0)
   1059     ld    $s7, 0xd0($k0)
   1060     ld    $t8, 0xd8($k0)
   1061     ld    $t9, 0xe0($k0)
   1062     ld    $gp, 0xe8($k0)
   1063 #ifndef VERSION_CN
   1064     mthi  $k1
   1065 #endif
   1066     ld    $sp, 0xf0($k0)
   1067     ld    $fp, 0xf8($k0)
   1068     ld    $ra, 0x100($k0)
   1069 #ifdef VERSION_CN
   1070     ld    $k1, 0x108($k0)
   1071     mtlo  $k1
   1072     ld    $k1, 0x110($k0)
   1073     mthi  $k1
   1074 #endif
   1075     lw    $k1, 0x11c($k0)
   1076     mtc0  $k1, $14
   1077 #ifndef VERSION_EU_SH_CN
   1078     lw    $k1, 0x118($k0)
   1079     mtc0  $k1, $12
   1080 #endif
   1081     lw    $k1, 0x18($k0)
   1082     beqz  $k1, .L80326EF0
   1083      nop
   1084     lw    $k1, 0x12c($k0)
   1085     ctc1  $k1, $31
   1086     ldc1  $f0, 0x130($k0)
   1087     ldc1  $f2, 0x138($k0)
   1088     ldc1  $f4, 0x140($k0)
   1089     ldc1  $f6, 0x148($k0)
   1090     ldc1  $f8, 0x150($k0)
   1091     ldc1  $f10, 0x158($k0)
   1092     ldc1  $f12, 0x160($k0)
   1093     ldc1  $f14, 0x168($k0)
   1094     ldc1  $f16, 0x170($k0)
   1095     ldc1  $f18, 0x178($k0)
   1096     ldc1  $f20, 0x180($k0)
   1097     ldc1  $f22, 0x188($k0)
   1098     ldc1  $f24, 0x190($k0)
   1099     ldc1  $f26, 0x198($k0)
   1100     ldc1  $f28, 0x1a0($k0)
   1101     ldc1  $f30, 0x1a8($k0)
   1102 .L80326EF0:
   1103     lw    $k1, 0x128($k0)
   1104 #ifdef VERSION_EU_SH_CN
   1105     la    $k0, __OSGlobalIntMask
   1106     lw    $k0, ($k0)
   1107     srl   $k0, $k0, 0x10
   1108     and   $k1, $k1, $k0
   1109 #endif
   1110     sll   $k1, $k1, 1
   1111     la    $k0, __osRcpImTable
   1112     addu  $k1, $k1, $k0
   1113     lhu   $k1, ($k1)
   1114 #ifdef VERSION_CN
   1115     li    $k0, PHYS_TO_K1(MI_INTR_MASK_REG)
   1116 #else
   1117     // TODO: is this an la?
   1118     lui   $k0, %hi(PHYS_TO_K1(MI_INTR_MASK_REG))
   1119     addiu $k0, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))
   1120 #endif
   1121     sw    $k1, ($k0)
   1122     nop
   1123     nop
   1124     nop
   1125     nop
   1126     eret
   1127 glabel __osCleanupThread
   1128     jal   osDestroyThread
   1129      move  $a0, $zero
   1130 
   1131 .section .data
   1132 
   1133 glabel __osHwIntTable
   1134     .word 0
   1135     .word 0
   1136     .word 0
   1137     .word 0
   1138     .word 0
   1139 #ifdef VERSION_CN
   1140     // CN: table is now 2 words per entry (handler, sp)
   1141     .word 0
   1142     .word 0
   1143     .word 0
   1144     .word 0
   1145     .word 0
   1146 
   1147 // Is this part of __osHwIntTable?
   1148 glabel D_CN_80319658
   1149     .word 0
   1150 #endif
   1151 
   1152 #ifndef VERSION_EU_SH_CN
   1153 glabel D_80334934
   1154     .word 0
   1155 
   1156 glabel D_80334938
   1157     .word 0
   1158     .word 0
   1159 #endif
   1160 
   1161 .section .rodata
   1162 
   1163 glabel __osIntOffTable
   1164     .byte 0x00,0x14,0x18,0x18,0x1C,0x1C,0x1C,0x1C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x04,0x08,0x08,0x0C,0x0C,0x0C,0x0C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10
   1165 
   1166 glabel __osIntTable
   1167     .word redispatch
   1168     .word sw1
   1169     .word sw2
   1170     .word rcp
   1171     .word cart
   1172     .word prenmi
   1173 #ifdef VERSION_EU_SH_CN
   1174     .word IP6_Hdlr
   1175     .word IP7_Hdlr
   1176 #else
   1177     .word panic
   1178     .word panic
   1179 #endif
   1180     .word counter
   1181     .word 0
   1182     .word 0
   1183     .word 0