From 7334ffa373d7aeef31977c2fe39af711d7069809 Mon Sep 17 00:00:00 2001 From: Tharo <17233964+Thar0@users.noreply.github.com> Date: Sun, 1 May 2022 00:03:22 +0100 Subject: [PATCH] Improve the state of handwritten assembly files (#865) * Format all handwritten asm and document some * Use c preprocessor for constants * Fix * Fix PI_STATUS_ERROR, some label improvements * Avoid hi/lo for constants * Some more comments * Properly mark functions as functions and their sizes * Fix merge * Improvements * Review suggestions, rework procedure start/end macros to be more like libreultra * Move IPL3 symbol definitions into ipl3.s * Fix undefined_syms, add include and language guards to asm.h and fix the comment in gbi.h * Consistent hex capitalization, add some MIPS builtin defines to CC_CHECK to behave properly * Add -no-pad-sections assembler option and clean up alignment in gu files and bzero * Further suggestions and improvements * Matrix conversion function clarifications * Fix passing AVOID_UB to gcc * Suggestions * Suggestions, global interrupt mask improvements * Further suggestions, interrupt mask comments * Comments fixes, rdb.h * Switch from # comments to // comments, remove unnecesary .set gp=64 directives * Further review suggestions * Missed one --- Makefile | 19 +- asm/__osDisableInt.s | 41 - asm/__osGetCause.s | 18 +- asm/__osGetFpcCsr.s | 18 +- asm/__osGetSR.s | 18 +- asm/__osProbeTLB.s | 136 ++- asm/__osRestoreInt.s | 19 - asm/__osSetCompare.s | 18 +- asm/__osSetFpcCsr.s | 22 +- asm/__osSetSR.s | 20 +- asm/__osSetWatchLo.s | 20 +- asm/bcmp.s | 173 ++- asm/bcopy.s | 413 +++---- asm/bzero.s | 137 +-- asm/code_800D71F0.s | 92 +- asm/entry.s | 62 +- asm/exceptasm.s | 1536 +++++++++++++++----------- asm/fp.s | 125 ++- asm/guMtxF2L.s | 72 +- asm/guMtxIdent.s | 51 +- asm/guMtxIdentF.s | 51 +- asm/guMtxL2F.s | 70 +- asm/guNormalize.s | 59 +- asm/guScale.s | 95 +- asm/guTranslate.s | 117 +- asm/interrupt.s | 53 + asm/ipl3.s | 6 - asm/libm_vals.s | 10 +- asm/mio0.s | 115 +- asm/osGetCount.s | 20 +- asm/osInvalDCache.s | 143 ++- asm/osInvalICache.s | 86 +- asm/osMapTLBRdb.s | 59 +- asm/osSetIntMask.s | 279 +++-- asm/osUnmapTLBAll.s | 48 +- asm/osWritebackDCache.s | 92 +- asm/osWritebackDCacheAll.s | 34 +- asm/parameters.s | 22 + include/boot.h | 6 + include/functions.h | 3 - include/ultra64/asm.h | 85 ++ include/ultra64/exception.h | 21 +- include/ultra64/message.h | 25 +- include/ultra64/rcp.h | 66 +- include/ultra64/rdb.h | 82 ++ include/ultra64/thread.h | 76 +- include/variables.h | 2 +- include/z64.h | 2 +- spec | 4 +- src/boot/boot_main.c | 3 +- src/code/main.c | 2 +- src/libultra/io/cartrominit.c | 5 +- src/libultra/io/devmgr.c | 6 +- src/libultra/io/driverominit.c | 5 +- src/libultra/io/epirawdma.c | 5 +- src/libultra/io/epirawread.c | 5 +- src/libultra/io/epirawwrite.c | 5 +- src/libultra/io/pirawdma.c | 3 +- src/libultra/os/createthread.c | 3 +- src/libultra/os/initialize.c | 4 +- src/libultra/os/resetglobalintmask.c | 2 +- undefined_syms.txt | 52 - 62 files changed, 2758 insertions(+), 2083 deletions(-) delete mode 100644 asm/__osDisableInt.s delete mode 100644 asm/__osRestoreInt.s create mode 100644 asm/interrupt.s create mode 100644 asm/parameters.s create mode 100644 include/boot.h create mode 100644 include/ultra64/asm.h create mode 100644 include/ultra64/rdb.h diff --git a/Makefile b/Makefile index 8796ed954e..bc09cee215 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,9 @@ MAKEFLAGS += --no-builtin-rules +# Ensure the build fails if a piped command fails +SHELL = /bin/bash +.SHELLFLAGS = -o pipefail -c + # Build options can either be changed by modifying the makefile, or by building with 'make SETTING=value' # If COMPARE is 1, check the output md5sum after building @@ -32,8 +36,8 @@ endif MIPS_BINUTILS_PREFIX ?= mips-linux-gnu- ifeq ($(NON_MATCHING),1) - CFLAGS += -DNON_MATCHING - CPPFLAGS += -DNON_MATCHING + CFLAGS += -DNON_MATCHING -DAVOID_UB + CPPFLAGS += -DNON_MATCHING -DAVOID_UB COMPARE := 0 endif @@ -112,10 +116,10 @@ else OPTFLAGS := -O2 endif -ASFLAGS := -march=vr4300 -32 -Iinclude +ASFLAGS := -march=vr4300 -32 -no-pad-sections -I include ifeq ($(COMPILER),gcc) - CFLAGS += -G 0 -nostdinc $(INC) -DAVOID_UB -march=vr4300 -mfix4300 -mabi=32 -mno-abicalls -mdivide-breaks -fno-zero-initialized-in-bss -fno-toplevel-reorder -ffreestanding -fno-common -fno-merge-constants -mno-explicit-relocs -mno-split-addresses $(CHECK_WARNINGS) -funsigned-char + CFLAGS += -G 0 -nostdinc $(INC) -march=vr4300 -mfix4300 -mabi=32 -mno-abicalls -mdivide-breaks -fno-zero-initialized-in-bss -fno-toplevel-reorder -ffreestanding -fno-common -fno-merge-constants -mno-explicit-relocs -mno-split-addresses $(CHECK_WARNINGS) -funsigned-char MIPS_VERSION := -mips3 else # we support Microsoft extensions such as anonymous structs, which the compiler does support but warns for their usage. Surpress the warnings with -woff. @@ -124,7 +128,9 @@ else endif ifeq ($(COMPILER),ido) - CC_CHECK = gcc -fno-builtin -fsyntax-only -funsigned-char -std=gnu90 -D_LANGUAGE_C -DNON_MATCHING $(INC) $(CHECK_WARNINGS) + # Have CC_CHECK pretend to be a MIPS compiler + MIPS_BUILTIN_DEFS := -D_MIPS_ISA_MIPS2=2 -D_MIPS_ISA=_MIPS_ISA_MIPS2 -D_ABIO32=1 -D_MIPS_SIM=_ABIO32 -D_MIPS_SZINT=32 -D_MIPS_SZLONG=32 -D_MIPS_SZPTR=32 + CC_CHECK = gcc -fno-builtin -fsyntax-only -funsigned-char -std=gnu90 -D_LANGUAGE_C -DNON_MATCHING $(MIPS_BUILTIN_DEFS) $(INC) $(CHECK_WARNINGS) ifeq ($(shell getconf LONG_BIT), 32) # Work around memory allocation bug in QEMU export QEMU_GUEST_BASE := 1 @@ -277,7 +283,6 @@ $(O_FILES): | asset_files .PHONY: o_files asset_files - build/$(SPEC): $(SPEC) $(CPP) $(CPPFLAGS) $< > $@ @@ -291,7 +296,7 @@ build/baserom/%.o: baserom/% $(OBJCOPY) -I binary -O elf32-big $< $@ build/asm/%.o: asm/%.s - $(AS) $(ASFLAGS) $< -o $@ + $(CPP) $(CPPFLAGS) -I include $< | $(AS) $(ASFLAGS) -o $@ build/data/%.o: data/%.s $(AS) $(ASFLAGS) $< -o $@ diff --git a/asm/__osDisableInt.s b/asm/__osDisableInt.s deleted file mode 100644 index b3ec3e6304..0000000000 --- a/asm/__osDisableInt.s +++ /dev/null @@ -1,41 +0,0 @@ -.include "macro.inc" - -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers - -.section .text - -.balign 16 - -glabel __osDisableInt -/* 007E80 80007280 3C0A8001 */ lui $t2, %hi(__OSGlobalIntMask) # $t2, 0x8001 -/* 007E84 80007284 254AAD00 */ addiu $t2, %lo(__OSGlobalIntMask) # addiu $t2, $t2, -0x5300 -/* 007E88 80007288 8D4B0000 */ lw $t3, ($t2) -/* 007E8C 8000728C 316BFF00 */ andi $t3, $t3, 0xff00 -/* 007E90 80007290 40086000 */ mfc0 $t0, $12 -/* 007E94 80007294 2401FFFE */ li $at, -2 -/* 007E98 80007298 01014824 */ and $t1, $t0, $at -/* 007E9C 8000729C 40896000 */ mtc0 $t1, $12 -/* 007EA0 800072A0 31020001 */ andi $v0, $t0, 1 -/* 007EA4 800072A4 8D480000 */ lw $t0, ($t2) -/* 007EA8 800072A8 3108FF00 */ andi $t0, $t0, 0xff00 -/* 007EAC 800072AC 110B000E */ beq $t0, $t3, .L800072E8 -/* 007EB0 800072B0 3C0A8001 */ lui $t2, %hi(__osRunningThread) # $t2, 0x8001 -/* 007EB4 800072B4 254AAD50 */ addiu $t2, %lo(__osRunningThread) # addiu $t2, $t2, -0x52b0 -/* 007EB8 800072B8 8D490118 */ lw $t1, 0x118($t2) -/* 007EBC 800072BC 312AFF00 */ andi $t2, $t1, 0xff00 -/* 007EC0 800072C0 01485024 */ and $t2, $t2, $t0 -/* 007EC4 800072C4 3C01FFFF */ lui $at, (0xFFFF00FF >> 16) # lui $at, 0xffff -/* 007EC8 800072C8 342100FF */ ori $at, (0xFFFF00FF & 0xFFFF) # ori $at, $at, 0xff -/* 007ECC 800072CC 01214824 */ and $t1, $t1, $at -/* 007ED0 800072D0 012A4825 */ or $t1, $t1, $t2 -/* 007ED4 800072D4 2401FFFE */ li $at, -2 -/* 007ED8 800072D8 01214824 */ and $t1, $t1, $at -/* 007EDC 800072DC 40896000 */ mtc0 $t1, $12 -/* 007EE0 800072E0 00000000 */ nop -/* 007EE4 800072E4 00000000 */ nop -.L800072E8: -/* 007EE8 800072E8 03E00008 */ jr $ra -/* 007EEC 800072EC 00000000 */ nop diff --git a/asm/__osGetCause.s b/asm/__osGetCause.s index b09caa0178..46c56d16ef 100644 --- a/asm/__osGetCause.s +++ b/asm/__osGetCause.s @@ -1,15 +1,15 @@ -.include "macro.inc" +#include "ultra64/asm.h" +#include "ultra64/r4300.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 -glabel __osGetCause -/* 008790 80007B90 40026800 */ mfc0 $v0, $13 -/* 008794 80007B94 03E00008 */ jr $ra -/* 008798 80007B98 00000000 */ nop +LEAF(__osGetCause) + mfc0 $v0, C0_CAUSE + jr $ra + nop +END(__osGetCause) diff --git a/asm/__osGetFpcCsr.s b/asm/__osGetFpcCsr.s index f3581d77e6..28ad5cf907 100644 --- a/asm/__osGetFpcCsr.s +++ b/asm/__osGetFpcCsr.s @@ -1,15 +1,15 @@ -.include "macro.inc" +#include "ultra64/asm.h" +#include "ultra64/r4300.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 -glabel __osGetFpcCsr -/* 008680 80007A80 4442F800 */ cfc1 $v0, $31 -/* 008684 80007A84 03E00008 */ jr $ra -/* 008688 80007A88 00000000 */ nop +LEAF(__osGetFpcCsr) + cfc1 $v0, C1_FPCSR + jr $ra + nop +END(__osGetFpcCsr) diff --git a/asm/__osGetSR.s b/asm/__osGetSR.s index 1eb0414250..d47f244404 100644 --- a/asm/__osGetSR.s +++ b/asm/__osGetSR.s @@ -1,15 +1,15 @@ -.include "macro.inc" +#include "ultra64/asm.h" +#include "ultra64/r4300.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 -glabel __osGetSR -/* 0052B0 800046B0 40026000 */ mfc0 $v0, $12 -/* 0052B4 800046B4 03E00008 */ jr $ra -/* 0052B8 800046B8 00000000 */ nop +LEAF(__osGetSR) + mfc0 $v0, C0_SR + jr $ra + nop +END(__osGetSR) diff --git a/asm/__osProbeTLB.s b/asm/__osProbeTLB.s index ea1dc097ff..ce655facaf 100644 --- a/asm/__osProbeTLB.s +++ b/asm/__osProbeTLB.s @@ -1,62 +1,86 @@ -.include "macro.inc" +#include "ultra64/asm.h" +#include "ultra64/r4300.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 -glabel __osProbeTLB -/* 005C40 80005040 40085000 */ mfc0 $t0, $10 -/* 005C44 80005044 310900FF */ andi $t1, $t0, 0xff -/* 005C48 80005048 2401E000 */ li $at, -8192 -/* 005C4C 8000504C 00815024 */ and $t2, $a0, $at -/* 005C50 80005050 012A4825 */ or $t1, $t1, $t2 -/* 005C54 80005054 40895000 */ mtc0 $t1, $10 -/* 005C58 80005058 00000000 */ nop -/* 005C5C 8000505C 00000000 */ nop -/* 005C60 80005060 00000000 */ nop -/* 005C64 80005064 42000008 */ tlbp -/* 005C68 80005068 00000000 */ nop -/* 005C6C 8000506C 00000000 */ nop -/* 005C70 80005070 400B0000 */ mfc0 $t3, $0 -/* 005C74 80005074 3C018000 */ lui $at, 0x8000 -/* 005C78 80005078 01615824 */ and $t3, $t3, $at -/* 005C7C 8000507C 1560001A */ bnez $t3, .L800050E8 -/* 005C80 80005080 00000000 */ nop -/* 005C84 80005084 42000001 */ tlbr -/* 005C88 80005088 00000000 */ nop -/* 005C8C 8000508C 00000000 */ nop -/* 005C90 80005090 00000000 */ nop -/* 005C94 80005094 400B2800 */ mfc0 $t3, $5 -/* 005C98 80005098 216B2000 */ addi $t3, $t3, 0x2000 -/* 005C9C 8000509C 000B5842 */ srl $t3, $t3, 1 -/* 005CA0 800050A0 01646024 */ and $t4, $t3, $a0 -/* 005CA4 800050A4 15800004 */ bnez $t4, .L800050B8 -/* 005CA8 800050A8 216BFFFF */ addi $t3, $t3, -1 -/* 005CAC 800050AC 40021000 */ mfc0 $v0, $2 -/* 005CB0 800050B0 10000002 */ b .L800050BC -/* 005CB4 800050B4 00000000 */ nop -.L800050B8: -/* 005CB8 800050B8 40021800 */ mfc0 $v0, $3 -.L800050BC: -/* 005CBC 800050BC 304D0002 */ andi $t5, $v0, 2 -/* 005CC0 800050C0 11A00009 */ beqz $t5, .L800050E8 -/* 005CC4 800050C4 00000000 */ nop -/* 005CC8 800050C8 3C013FFF */ lui $at, (0x3FFFFFC0 >> 16) # lui $at, 0x3fff -/* 005CCC 800050CC 3421FFC0 */ ori $at, (0x3FFFFFC0 & 0xFFFF) # ori $at, $at, 0xffc0 -/* 005CD0 800050D0 00411024 */ and $v0, $v0, $at -/* 005CD4 800050D4 00021180 */ sll $v0, $v0, 6 -/* 005CD8 800050D8 008B6824 */ and $t5, $a0, $t3 -/* 005CDC 800050DC 004D1020 */ add $v0, $v0, $t5 -/* 005CE0 800050E0 10000002 */ b .L800050EC -/* 005CE4 800050E4 00000000 */ nop -.L800050E8: -/* 005CE8 800050E8 2402FFFF */ li $v0, -1 -.L800050EC: -/* 005CEC 800050EC 40885000 */ mtc0 $t0, $10 -/* 005CF0 800050F0 03E00008 */ jr $ra -/* 005CF4 800050F4 00000000 */ nop +/** + * u32 __osProbeTLB(void* vaddr); + * + * Searches the TLB for the physical address associated with + * the virtual address `vaddr`. + * + * Returns the physical address if found, or -1 if not found. + */ +LEAF(__osProbeTLB) + // Set C0_ENTRYHI based on supplied vaddr + mfc0 $t0, C0_ENTRYHI + andi $t1, $t0, TLBHI_PIDMASK + li $at, TLBHI_VPN2MASK + and $t2, $a0, $at + or $t1, $t1, $t2 + mtc0 $t1, C0_ENTRYHI + nop + nop + nop + // TLB probe, sets C0_INX to a value matching C0_ENTRYHI. + // If no match is found the TLBINX_PROBE bit is set to indicate this. + tlbp + nop + nop + // Read result + mfc0 $t3, C0_INX + li $at, TLBINX_PROBE + and $t3, $t3, $at + // Branch if no match was found + bnez $t3, 3f + nop + // Read TLB, sets C0_ENTRYHI, C0_ENTRYLO0, C0_ENTRYLO1 and C0_PAGEMASK for the TLB + // entry indicated by C0_INX + tlbr + nop + nop + nop + // Calculate page size = (page mask + 0x2000) >> 1 + mfc0 $t3, C0_PAGEMASK + addi $t3, $t3, 0x2000 + srl $t3, $t3, 1 + // & with vaddr + and $t4, $t3, $a0 + // Select C0_ENTRYLO0 or C0_ENTRYLO1 + bnez $t4, 1f + addi $t3, $t3, -1 // make bitmask out of page size + mfc0 $v0, C0_ENTRYLO0 + b 2f + nop +1: + mfc0 $v0, C0_ENTRYLO1 +2: + // Check valid bit and branch if not valid + andi $t5, $v0, TLBLO_V + beqz $t5, 3f + nop + // Extract the Page Frame Number from the entry + li $at, TLBLO_PFNMASK + and $v0, $v0, $at + sll $v0, $v0, TLBLO_PFNSHIFT + // Mask vaddr with page size mask + and $t5, $a0, $t3 + // Add masked vaddr to pfn to obtain the physical address + add $v0, $v0, $t5 + b 4f + nop +3: + // No physical address for the supplied virtual address was found, + // return -1 + li $v0, -1 +4: + // Restore original C0_ENTRYHI value before returning + mtc0 $t0, C0_ENTRYHI + jr $ra + nop +END(__osProbeTLB) diff --git a/asm/__osRestoreInt.s b/asm/__osRestoreInt.s deleted file mode 100644 index 9a08a319f9..0000000000 --- a/asm/__osRestoreInt.s +++ /dev/null @@ -1,19 +0,0 @@ -.include "macro.inc" - -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers - -.section .text - -.balign 16 - -glabel __osRestoreInt -/* 007EF0 800072F0 40086000 */ mfc0 $t0, $12 -/* 007EF4 800072F4 01044025 */ or $t0, $t0, $a0 -/* 007EF8 800072F8 40886000 */ mtc0 $t0, $12 -/* 007EFC 800072FC 00000000 */ nop -/* 007F00 80007300 00000000 */ nop -/* 007F04 80007304 03E00008 */ jr $ra -/* 007F08 80007308 00000000 */ nop diff --git a/asm/__osSetCompare.s b/asm/__osSetCompare.s index aabc65c3ec..f3c5fc18a7 100644 --- a/asm/__osSetCompare.s +++ b/asm/__osSetCompare.s @@ -1,15 +1,15 @@ -.include "macro.inc" +#include "ultra64/asm.h" +#include "ultra64/r4300.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 -glabel __osSetCompare -/* 007B00 80006F00 40845800 */ mtc0 $a0, $11 -/* 007B04 80006F04 03E00008 */ jr $ra -/* 007B08 80006F08 00000000 */ nop +LEAF(__osSetCompare) + mtc0 $a0, C0_COMPARE + jr $ra + nop +END(__osSetCompare) diff --git a/asm/__osSetFpcCsr.s b/asm/__osSetFpcCsr.s index 5f4570a696..ec12e21559 100644 --- a/asm/__osSetFpcCsr.s +++ b/asm/__osSetFpcCsr.s @@ -1,16 +1,16 @@ -.include "macro.inc" +#include "ultra64/asm.h" +#include "ultra64/r4300.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 - -glabel __osSetFpcCsr -/* 008670 80007A70 4442F800 */ cfc1 $v0, $31 -/* 008674 80007A74 44C4F800 */ ctc1 $a0, $31 -/* 008678 80007A78 03E00008 */ jr $ra -/* 00867C 80007A7C 00000000 */ nop + +LEAF(__osSetFpcCsr) + cfc1 $v0, C1_FPCSR + ctc1 $a0, C1_FPCSR + jr $ra + nop +END(__osSetFpcCsr) diff --git a/asm/__osSetSR.s b/asm/__osSetSR.s index 3a5e3e814e..977b661bd8 100644 --- a/asm/__osSetSR.s +++ b/asm/__osSetSR.s @@ -1,16 +1,16 @@ -.include "macro.inc" +#include "ultra64/asm.h" +#include "ultra64/r4300.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 -glabel __osSetSR -/* 0052A0 800046A0 40846000 */ mtc0 $a0, $12 -/* 0052A4 800046A4 00000000 */ nop -/* 0052A8 800046A8 03E00008 */ jr $ra -/* 0052AC 800046AC 00000000 */ nop +LEAF(__osSetSR) + mtc0 $a0, C0_SR + nop + jr $ra + nop +END(__osSetSR) diff --git a/asm/__osSetWatchLo.s b/asm/__osSetWatchLo.s index 5e56598208..0c8752e984 100644 --- a/asm/__osSetWatchLo.s +++ b/asm/__osSetWatchLo.s @@ -1,16 +1,16 @@ -.include "macro.inc" +#include "ultra64/asm.h" +#include "ultra64/r4300.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 -glabel __osSetWatchLo -/* 009F10 80009310 40849000 */ mtc0 $a0, $18 -/* 009F14 80009314 00000000 */ nop -/* 009F18 80009318 03E00008 */ jr $ra -/* 009F1C 8000931C 00000000 */ nop +LEAF(__osSetWatchLo) + mtc0 $a0, C0_WATCHLO + nop + jr $ra + nop +END(__osSetWatchLo) diff --git a/asm/bcmp.s b/asm/bcmp.s index 7e57bdf85c..df6692feb5 100644 --- a/asm/bcmp.s +++ b/asm/bcmp.s @@ -1,94 +1,93 @@ -.include "macro.inc" +#include "ultra64/asm.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 -glabel bcmp -/* 0074C0 800068C0 28C10010 */ slti $at, $a2, 0x10 -/* 0074C4 800068C4 14200037 */ bnez $at, .bytecmp -/* 0074C8 800068C8 00851026 */ xor $v0, $a0, $a1 -/* 0074CC 800068CC 30420003 */ andi $v0, $v0, 3 -/* 0074D0 800068D0 14400019 */ bnez $v0, .unalgncmp -/* 0074D4 800068D4 0004C023 */ negu $t8, $a0 -/* 0074D8 800068D8 33180003 */ andi $t8, $t8, 3 -/* 0074DC 800068DC 13000007 */ beqz $t8, .wordcmp -/* 0074E0 800068E0 00D83023 */ subu $a2, $a2, $t8 -/* 0074E4 800068E4 00601025 */ move $v0, $v1 -/* 0074E8 800068E8 88820000 */ lwl $v0, ($a0) -/* 0074EC 800068EC 88A30000 */ lwl $v1, ($a1) -/* 0074F0 800068F0 00982021 */ addu $a0, $a0, $t8 -/* 0074F4 800068F4 00B82821 */ addu $a1, $a1, $t8 -/* 0074F8 800068F8 14430036 */ bne $v0, $v1, .cmpdone -.wordcmp: -/* 0074FC 800068FC 2401FFFC */ li $at, -4 -/* 007500 80006900 00C13824 */ and $a3, $a2, $at -/* 007504 80006904 10E00027 */ beqz $a3, .bytecmp -/* 007508 80006908 00C73023 */ subu $a2, $a2, $a3 -/* 00750C 8000690C 00E43821 */ addu $a3, $a3, $a0 -/* 007510 80006910 8C820000 */ lw $v0, ($a0) -.L80006914: -/* 007514 80006914 8CA30000 */ lw $v1, ($a1) -/* 007518 80006918 24840004 */ addiu $a0, $a0, 4 -/* 00751C 8000691C 24A50004 */ addiu $a1, $a1, 4 -/* 007520 80006920 1443002C */ bne $v0, $v1, .cmpdone -/* 007524 80006924 00000000 */ nop -/* 007528 80006928 5487FFFA */ bnel $a0, $a3, .L80006914 -/* 00752C 8000692C 8C820000 */ lw $v0, ($a0) -/* 007530 80006930 1000001C */ b .bytecmp -/* 007534 80006934 00000000 */ nop -.unalgncmp: -/* 007538 80006938 00053823 */ negu $a3, $a1 -/* 00753C 8000693C 30E70003 */ andi $a3, $a3, 3 -/* 007540 80006940 10E0000A */ beqz $a3, .partaligncmp -/* 007544 80006944 00C73023 */ subu $a2, $a2, $a3 -/* 007548 80006948 00E43821 */ addu $a3, $a3, $a0 -/* 00754C 8000694C 90820000 */ lbu $v0, ($a0) -.L80006950: -/* 007550 80006950 90A30000 */ lbu $v1, ($a1) -/* 007554 80006954 24840001 */ addiu $a0, $a0, 1 -/* 007558 80006958 24A50001 */ addiu $a1, $a1, 1 -/* 00755C 8000695C 1443001D */ bne $v0, $v1, .cmpdone -/* 007560 80006960 00000000 */ nop -/* 007564 80006964 5487FFFA */ bnel $a0, $a3, .L80006950 -/* 007568 80006968 90820000 */ lbu $v0, ($a0) -.partaligncmp: -/* 00756C 8000696C 2401FFFC */ li $at, -4 -/* 007570 80006970 00C13824 */ and $a3, $a2, $at -/* 007574 80006974 10E0000B */ beqz $a3, .bytecmp -/* 007578 80006978 00C73023 */ subu $a2, $a2, $a3 -/* 00757C 8000697C 00E43821 */ addu $a3, $a3, $a0 -/* 007580 80006980 88820000 */ lwl $v0, ($a0) -.L80006984: -/* 007584 80006984 8CA30000 */ lw $v1, ($a1) -/* 007588 80006988 98820003 */ lwr $v0, 3($a0) -/* 00758C 8000698C 24840004 */ addiu $a0, $a0, 4 -/* 007590 80006990 24A50004 */ addiu $a1, $a1, 4 -/* 007594 80006994 1443000F */ bne $v0, $v1, .cmpdone -/* 007598 80006998 00000000 */ nop -/* 00759C 8000699C 5487FFF9 */ bnel $a0, $a3, .L80006984 -/* 0075A0 800069A0 88820000 */ lwl $v0, ($a0) -.bytecmp: -/* 0075A4 800069A4 18C00009 */ blez $a2, .L800069CC -/* 0075A8 800069A8 00C43821 */ addu $a3, $a2, $a0 -/* 0075AC 800069AC 90820000 */ lbu $v0, ($a0) -.L800069B0: -/* 0075B0 800069B0 90A30000 */ lbu $v1, ($a1) -/* 0075B4 800069B4 24840001 */ addiu $a0, $a0, 1 -/* 0075B8 800069B8 24A50001 */ addiu $a1, $a1, 1 -/* 0075BC 800069BC 14430005 */ bne $v0, $v1, .cmpdone -/* 0075C0 800069C0 00000000 */ nop -/* 0075C4 800069C4 5487FFFA */ bnel $a0, $a3, .L800069B0 -/* 0075C8 800069C8 90820000 */ lbu $v0, ($a0) -.L800069CC: -/* 0075CC 800069CC 03E00008 */ jr $ra -/* 0075D0 800069D0 00001025 */ move $v0, $zero +LEAF(bcmp) + slti $at, $a2, 0x10 + bnez $at, bytecmp + xor $v0, $a0, $a1 + andi $v0, $v0, 3 + bnez $v0, unaligncmp + negu $t8, $a0 + andi $t8, $t8, 3 + beqz $t8, wordcmp + subu $a2, $a2, $t8 + move $v0, $v1 + lwl $v0, ($a0) + lwl $v1, ($a1) + addu $a0, $a0, $t8 + addu $a1, $a1, $t8 + bne $v0, $v1, cmpne +wordcmp: + li $at, ~3 + and $a3, $a2, $at + beqz $a3, bytecmp + subu $a2, $a2, $a3 + addu $a3, $a3, $a0 + lw $v0, ($a0) +1: + lw $v1, ($a1) + addiu $a0, $a0, 4 + addiu $a1, $a1, 4 + bne $v0, $v1, cmpne + nop + bnel $a0, $a3, 1b + lw $v0, ($a0) + b bytecmp + nop +unaligncmp: + negu $a3, $a1 + andi $a3, $a3, 3 + beqz $a3, partaligncmp + subu $a2, $a2, $a3 + addu $a3, $a3, $a0 + lbu $v0, ($a0) +1: + lbu $v1, ($a1) + addiu $a0, $a0, 1 + addiu $a1, $a1, 1 + bne $v0, $v1, cmpne + nop + bnel $a0, $a3, 1b + lbu $v0, ($a0) +partaligncmp: + li $at, ~3 + and $a3, $a2, $at + beqz $a3, bytecmp + subu $a2, $a2, $a3 + addu $a3, $a3, $a0 + lwl $v0, ($a0) +1: + lw $v1, ($a1) + lwr $v0, 3($a0) + addiu $a0, $a0, 4 + addiu $a1, $a1, 4 + bne $v0, $v1, cmpne + nop + bnel $a0, $a3, 1b + lwl $v0, ($a0) +bytecmp: + blez $a2, cmpdone + addu $a3, $a2, $a0 + lbu $v0, ($a0) +1: + lbu $v1, ($a1) + addiu $a0, $a0, 1 + addiu $a1, $a1, 1 + bne $v0, $v1, cmpne + nop + bnel $a0, $a3, 1b + lbu $v0, ($a0) +cmpdone: + jr $ra + move $v0, $zero -.cmpdone: -/* 0075D4 800069D4 03E00008 */ jr $ra -/* 0075D8 800069D8 24020001 */ li $v0, 1 +cmpne: + jr $ra + li $v0, 1 +END(bcmp) diff --git a/asm/bcopy.s b/asm/bcopy.s index 80f29dd5d4..e1240f113a 100644 --- a/asm/bcopy.s +++ b/asm/bcopy.s @@ -1,230 +1,233 @@ -.include "macro.inc" +#include "ultra64/asm.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 -glabel bcopy -/* 007B10 80006F10 10C0001A */ beqz $a2, ret -/* 007B14 80006F14 00A03825 */ move $a3, $a1 -/* 007B18 80006F18 10850018 */ beq $a0, $a1, ret -/* 007B1C 80006F1C 00A4082A */ slt $at, $a1, $a0 -/* 007B20 80006F20 54200008 */ bnezl $at, goforwards -/* 007B24 80006F24 28C10010 */ slti $at, $a2, 0x10 -/* 007B28 80006F28 00861020 */ add $v0, $a0, $a2 -/* 007B2C 80006F2C 00A2082A */ slt $at, $a1, $v0 -/* 007B30 80006F30 50200004 */ beql $at, $zero, goforwards -/* 007B34 80006F34 28C10010 */ slti $at, $a2, 0x10 -/* 007B38 80006F38 1000005B */ b gobackwards -/* 007B3C 80006F3C 28C10010 */ slti $at, $a2, 0x10 -/* 007B40 80006F40 28C10010 */ slti $at, $a2, 0x10 +LEAF(bcopy) + beqz $a2, ret + move $a3, $a1 + beq $a0, $a1, ret + slt $at, $a1, $a0 + bnezl $at, goforwards + slti $at, $a2, 0x10 + add $v0, $a0, $a2 + slt $at, $a1, $v0 + beql $at, $zero, goforwards + slti $at, $a2, 0x10 + b gobackwards + slti $at, $a2, 0x10 + slti $at, $a2, 0x10 goforwards: -/* 007B44 80006F44 14200005 */ bnez $at, forwards_bytecopy -/* 007B48 80006F48 00000000 */ nop -/* 007B4C 80006F4C 30820003 */ andi $v0, $a0, 3 -/* 007B50 80006F50 30A30003 */ andi $v1, $a1, 3 -/* 007B54 80006F54 1043000B */ beq $v0, $v1, forwalignable -/* 007B58 80006F58 00000000 */ nop + bnez $at, forwards_bytecopy + nop + andi $v0, $a0, 3 + andi $v1, $a1, 3 + beq $v0, $v1, forwalignable + nop forwards_bytecopy: -/* 007B5C 80006F5C 10C00007 */ beqz $a2, ret -/* 007B60 80006F60 00000000 */ nop -/* 007B64 80006F64 00861821 */ addu $v1, $a0, $a2 -.L80006F68: -/* 007B68 80006F68 80820000 */ lb $v0, ($a0) -/* 007B6C 80006F6C 24840001 */ addiu $a0, $a0, 1 -/* 007B70 80006F70 24A50001 */ addiu $a1, $a1, 1 -/* 007B74 80006F74 1483FFFC */ bne $a0, $v1, .L80006F68 -/* 007B78 80006F78 A0A2FFFF */ sb $v0, -1($a1) + beqz $a2, ret + nop + addu $v1, $a0, $a2 +99: + lb $v0, ($a0) + addiu $a0, $a0, 1 + addiu $a1, $a1, 1 + bne $a0, $v1, 99b + sb $v0, -1($a1) ret: -/* 007B7C 80006F7C 03E00008 */ jr $ra -/* 007B80 80006F80 00E01025 */ move $v0, $a3 + jr $ra + move $v0, $a3 forwalignable: -/* 007B84 80006F84 10400018 */ beqz $v0, forwards_32 -/* 007B88 80006F88 24010001 */ li $at, 1 -/* 007B8C 80006F8C 1041000F */ beq $v0, $at, forw_copy3 -/* 007B90 80006F90 24010002 */ li $at, 2 -/* 007B94 80006F94 50410008 */ beql $v0, $at, forw_copy2 -/* 007B98 80006F98 84820000 */ lh $v0, ($a0) -/* 007B9C 80006F9C 80820000 */ lb $v0, ($a0) -/* 007BA0 80006FA0 24840001 */ addiu $a0, $a0, 1 -/* 007BA4 80006FA4 24A50001 */ addiu $a1, $a1, 1 -/* 007BA8 80006FA8 24C6FFFF */ addiu $a2, $a2, -1 -/* 007BAC 80006FAC 1000000E */ b forwards_32 -/* 007BB0 80006FB0 A0A2FFFF */ sb $v0, -1($a1) -/* 007BB4 80006FB4 84820000 */ lh $v0, ($a0) + beqz $v0, forwards_32 + li $at, 1 + beq $v0, $at, forw_copy3 + li $at, 2 + beql $v0, $at, forw_copy2 + lh $v0, ($a0) + lb $v0, ($a0) + addiu $a0, $a0, 1 + addiu $a1, $a1, 1 + addiu $a2, $a2, -1 + b forwards_32 + sb $v0, -1($a1) + lh $v0, ($a0) forw_copy2: -/* 007BB8 80006FB8 24840002 */ addiu $a0, $a0, 2 -/* 007BBC 80006FBC 24A50002 */ addiu $a1, $a1, 2 -/* 007BC0 80006FC0 24C6FFFE */ addiu $a2, $a2, -2 -/* 007BC4 80006FC4 10000008 */ b forwards_32 -/* 007BC8 80006FC8 A4A2FFFE */ sh $v0, -2($a1) + addiu $a0, $a0, 2 + addiu $a1, $a1, 2 + addiu $a2, $a2, -2 + b forwards_32 + sh $v0, -2($a1) forw_copy3: -/* 007BCC 80006FCC 80820000 */ lb $v0, ($a0) -/* 007BD0 80006FD0 84830001 */ lh $v1, 1($a0) -/* 007BD4 80006FD4 24840003 */ addiu $a0, $a0, 3 -/* 007BD8 80006FD8 24A50003 */ addiu $a1, $a1, 3 -/* 007BDC 80006FDC 24C6FFFD */ addiu $a2, $a2, -3 -/* 007BE0 80006FE0 A0A2FFFD */ sb $v0, -3($a1) -/* 007BE4 80006FE4 A4A3FFFE */ sh $v1, -2($a1) + lb $v0, ($a0) + lh $v1, 1($a0) + addiu $a0, $a0, 3 + addiu $a1, $a1, 3 + addiu $a2, $a2, -3 + sb $v0, -3($a1) + sh $v1, -2($a1) + +forwards: forwards_32: -/* 007BE8 80006FE8 28C10020 */ slti $at, $a2, 0x20 -/* 007BEC 80006FEC 54200016 */ bnezl $at, .L80007048 -/* 007BF0 80006FF0 28C10010 */ slti $at, $a2, 0x10 -/* 007BF4 80006FF4 8C820000 */ lw $v0, ($a0) -/* 007BF8 80006FF8 8C830004 */ lw $v1, 4($a0) -/* 007BFC 80006FFC 8C880008 */ lw $t0, 8($a0) -/* 007C00 80007000 8C89000C */ lw $t1, 0xc($a0) -/* 007C04 80007004 8C8A0010 */ lw $t2, 0x10($a0) -/* 007C08 80007008 8C8B0014 */ lw $t3, 0x14($a0) -/* 007C0C 8000700C 8C8C0018 */ lw $t4, 0x18($a0) -/* 007C10 80007010 8C8D001C */ lw $t5, 0x1c($a0) -/* 007C14 80007014 24840020 */ addiu $a0, $a0, 0x20 -/* 007C18 80007018 24A50020 */ addiu $a1, $a1, 0x20 -/* 007C1C 8000701C 24C6FFE0 */ addiu $a2, $a2, -0x20 -/* 007C20 80007020 ACA2FFE0 */ sw $v0, -0x20($a1) -/* 007C24 80007024 ACA3FFE4 */ sw $v1, -0x1c($a1) -/* 007C28 80007028 ACA8FFE8 */ sw $t0, -0x18($a1) -/* 007C2C 8000702C ACA9FFEC */ sw $t1, -0x14($a1) -/* 007C30 80007030 ACAAFFF0 */ sw $t2, -0x10($a1) -/* 007C34 80007034 ACABFFF4 */ sw $t3, -0xc($a1) -/* 007C38 80007038 ACACFFF8 */ sw $t4, -8($a1) -/* 007C3C 8000703C 1000FFEA */ b forwards_32 -/* 007C40 80007040 ACADFFFC */ sw $t5, -4($a1) + slti $at, $a2, 0x20 + bnezl $at, forwards_16_ + slti $at, $a2, 0x10 + lw $v0, ($a0) + lw $v1, 4($a0) + lw $t0, 8($a0) + lw $t1, 0xC($a0) + lw $t2, 0x10($a0) + lw $t3, 0x14($a0) + lw $t4, 0x18($a0) + lw $t5, 0x1C($a0) + addiu $a0, $a0, 0x20 + addiu $a1, $a1, 0x20 + addiu $a2, $a2, -0x20 + sw $v0, -0x20($a1) + sw $v1, -0x1C($a1) + sw $t0, -0x18($a1) + sw $t1, -0x14($a1) + sw $t2, -0x10($a1) + sw $t3, -0xC($a1) + sw $t4, -8($a1) + b forwards_32 + sw $t5, -4($a1) forwards_16: -/* 007C44 80007044 28C10010 */ slti $at, $a2, 0x10 -.L80007048: -/* 007C48 80007048 5420000E */ bnezl $at, .L80007084 -/* 007C4C 8000704C 28C10004 */ slti $at, $a2, 4 -/* 007C50 80007050 8C820000 */ lw $v0, ($a0) -/* 007C54 80007054 8C830004 */ lw $v1, 4($a0) -/* 007C58 80007058 8C880008 */ lw $t0, 8($a0) -/* 007C5C 8000705C 8C89000C */ lw $t1, 0xc($a0) -/* 007C60 80007060 24840010 */ addiu $a0, $a0, 0x10 -/* 007C64 80007064 24A50010 */ addiu $a1, $a1, 0x10 -/* 007C68 80007068 24C6FFF0 */ addiu $a2, $a2, -0x10 -/* 007C6C 8000706C ACA2FFF0 */ sw $v0, -0x10($a1) -/* 007C70 80007070 ACA3FFF4 */ sw $v1, -0xc($a1) -/* 007C74 80007074 ACA8FFF8 */ sw $t0, -8($a1) -/* 007C78 80007078 1000FFF2 */ b forwards_16 -/* 007C7C 8000707C ACA9FFFC */ sw $t1, -4($a1) + slti $at, $a2, 0x10 +forwards_16_: // fake label due to branch likely optimization + bnezl $at, forwards_4_ + slti $at, $a2, 4 + lw $v0, ($a0) + lw $v1, 4($a0) + lw $t0, 8($a0) + lw $t1, 0xC($a0) + addiu $a0, $a0, 0x10 + addiu $a1, $a1, 0x10 + addiu $a2, $a2, -0x10 + sw $v0, -0x10($a1) + sw $v1, -0xC($a1) + sw $t0, -8($a1) + b forwards_16 + sw $t1, -4($a1) forwards_4: -/* 007C80 80007080 28C10004 */ slti $at, $a2, 4 -.L80007084: -/* 007C84 80007084 1420FFB5 */ bnez $at, forwards_bytecopy -/* 007C88 80007088 00000000 */ nop -/* 007C8C 8000708C 8C820000 */ lw $v0, ($a0) -/* 007C90 80007090 24840004 */ addiu $a0, $a0, 4 -/* 007C94 80007094 24A50004 */ addiu $a1, $a1, 4 -/* 007C98 80007098 24C6FFFC */ addiu $a2, $a2, -4 -/* 007C9C 8000709C 1000FFF8 */ b forwards_4 -/* 007CA0 800070A0 ACA2FFFC */ sw $v0, -4($a1) -/* 007CA4 800070A4 28C10010 */ slti $at, $a2, 0x10 + slti $at, $a2, 4 +forwards_4_: // fake label due to branch likely optimization + bnez $at, forwards_bytecopy + nop + lw $v0, ($a0) + addiu $a0, $a0, 4 + addiu $a1, $a1, 4 + addiu $a2, $a2, -4 + b forwards_4 + sw $v0, -4($a1) + slti $at, $a2, 0x10 gobackwards: -/* 007CA8 800070A8 00862020 */ add $a0, $a0, $a2 -/* 007CAC 800070AC 14200005 */ bnez $at, backwards_bytecopy -/* 007CB0 800070B0 00A62820 */ add $a1, $a1, $a2 -/* 007CB4 800070B4 30820003 */ andi $v0, $a0, 3 -/* 007CB8 800070B8 30A30003 */ andi $v1, $a1, 3 -/* 007CBC 800070BC 1043000D */ beq $v0, $v1, backalignable -/* 007CC0 800070C0 00000000 */ nop + add $a0, $a0, $a2 + bnez $at, backwards_bytecopy + add $a1, $a1, $a2 + andi $v0, $a0, 3 + andi $v1, $a1, 3 + beq $v0, $v1, backalignable + nop backwards_bytecopy: -/* 007CC4 800070C4 10C0FFAD */ beqz $a2, ret -/* 007CC8 800070C8 00000000 */ nop -/* 007CCC 800070CC 2484FFFF */ addiu $a0, $a0, -1 -/* 007CD0 800070D0 24A5FFFF */ addiu $a1, $a1, -1 -/* 007CD4 800070D4 00861823 */ subu $v1, $a0, $a2 -.L800070D8: -/* 007CD8 800070D8 80820000 */ lb $v0, ($a0) -/* 007CDC 800070DC 2484FFFF */ addiu $a0, $a0, -1 -/* 007CE0 800070E0 24A5FFFF */ addiu $a1, $a1, -1 -/* 007CE4 800070E4 1483FFFC */ bne $a0, $v1, .L800070D8 -/* 007CE8 800070E8 A0A20001 */ sb $v0, 1($a1) -/* 007CEC 800070EC 03E00008 */ jr $ra -/* 007CF0 800070F0 00E01025 */ move $v0, $a3 + beqz $a2, ret + nop + addiu $a0, $a0, -1 + addiu $a1, $a1, -1 + subu $v1, $a0, $a2 +99: + lb $v0, ($a0) + addiu $a0, $a0, -1 + addiu $a1, $a1, -1 + bne $a0, $v1, 99b + sb $v0, 1($a1) + jr $ra + move $v0, $a3 backalignable: -/* 007CF4 800070F4 10400018 */ beqz $v0, backwards_32 -/* 007CF8 800070F8 24010003 */ li $at, 3 -/* 007CFC 800070FC 1041000F */ beq $v0, $at, back_copy3 -/* 007D00 80007100 24010002 */ li $at, 2 -/* 007D04 80007104 50410008 */ beql $v0, $at, back_copy2 -/* 007D08 80007108 8482FFFE */ lh $v0, -2($a0) -/* 007D0C 8000710C 8082FFFF */ lb $v0, -1($a0) -/* 007D10 80007110 2484FFFF */ addiu $a0, $a0, -1 -/* 007D14 80007114 24A5FFFF */ addiu $a1, $a1, -1 -/* 007D18 80007118 24C6FFFF */ addiu $a2, $a2, -1 -/* 007D1C 8000711C 1000000E */ b backwards_32 -/* 007D20 80007120 A0A20000 */ sb $v0, ($a1) -/* 007D24 80007124 8482FFFE */ lh $v0, -2($a0) + beqz $v0, backwards_32 + li $at, 3 + beq $v0, $at, back_copy3 + li $at, 2 + beql $v0, $at, back_copy2 + lh $v0, -2($a0) + lb $v0, -1($a0) + addiu $a0, $a0, -1 + addiu $a1, $a1, -1 + addiu $a2, $a2, -1 + b backwards_32 + sb $v0, ($a1) + lh $v0, -2($a0) back_copy2: -/* 007D28 80007128 2484FFFE */ addiu $a0, $a0, -2 -/* 007D2C 8000712C 24A5FFFE */ addiu $a1, $a1, -2 -/* 007D30 80007130 24C6FFFE */ addiu $a2, $a2, -2 -/* 007D34 80007134 10000008 */ b backwards_32 -/* 007D38 80007138 A4A20000 */ sh $v0, ($a1) + addiu $a0, $a0, -2 + addiu $a1, $a1, -2 + addiu $a2, $a2, -2 + b backwards_32 + sh $v0, ($a1) back_copy3: -/* 007D3C 8000713C 8082FFFF */ lb $v0, -1($a0) -/* 007D40 80007140 8483FFFD */ lh $v1, -3($a0) -/* 007D44 80007144 2484FFFD */ addiu $a0, $a0, -3 -/* 007D48 80007148 24A5FFFD */ addiu $a1, $a1, -3 -/* 007D4C 8000714C 24C6FFFD */ addiu $a2, $a2, -3 -/* 007D50 80007150 A0A20002 */ sb $v0, 2($a1) -/* 007D54 80007154 A4A30000 */ sh $v1, ($a1) + lb $v0, -1($a0) + lh $v1, -3($a0) + addiu $a0, $a0, -3 + addiu $a1, $a1, -3 + addiu $a2, $a2, -3 + sb $v0, 2($a1) + sh $v1, ($a1) + +backwards: backwards_32: -/* 007D58 80007158 28C10020 */ slti $at, $a2, 0x20 -/* 007D5C 8000715C 54200016 */ bnezl $at, .L800071B8 -/* 007D60 80007160 28C10010 */ slti $at, $a2, 0x10 -/* 007D64 80007164 8C82FFFC */ lw $v0, -4($a0) -/* 007D68 80007168 8C83FFF8 */ lw $v1, -8($a0) -/* 007D6C 8000716C 8C88FFF4 */ lw $t0, -0xc($a0) -/* 007D70 80007170 8C89FFF0 */ lw $t1, -0x10($a0) -/* 007D74 80007174 8C8AFFEC */ lw $t2, -0x14($a0) -/* 007D78 80007178 8C8BFFE8 */ lw $t3, -0x18($a0) -/* 007D7C 8000717C 8C8CFFE4 */ lw $t4, -0x1c($a0) -/* 007D80 80007180 8C8DFFE0 */ lw $t5, -0x20($a0) -/* 007D84 80007184 2484FFE0 */ addiu $a0, $a0, -0x20 -/* 007D88 80007188 24A5FFE0 */ addiu $a1, $a1, -0x20 -/* 007D8C 8000718C 24C6FFE0 */ addiu $a2, $a2, -0x20 -/* 007D90 80007190 ACA2001C */ sw $v0, 0x1c($a1) -/* 007D94 80007194 ACA30018 */ sw $v1, 0x18($a1) -/* 007D98 80007198 ACA80014 */ sw $t0, 0x14($a1) -/* 007D9C 8000719C ACA90010 */ sw $t1, 0x10($a1) -/* 007DA0 800071A0 ACAA000C */ sw $t2, 0xc($a1) -/* 007DA4 800071A4 ACAB0008 */ sw $t3, 8($a1) -/* 007DA8 800071A8 ACAC0004 */ sw $t4, 4($a1) -/* 007DAC 800071AC 1000FFEA */ b backwards_32 -/* 007DB0 800071B0 ACAD0000 */ sw $t5, ($a1) + slti $at, $a2, 0x20 + bnezl $at, backwards_16_ + slti $at, $a2, 0x10 + lw $v0, -4($a0) + lw $v1, -8($a0) + lw $t0, -0xc($a0) + lw $t1, -0x10($a0) + lw $t2, -0x14($a0) + lw $t3, -0x18($a0) + lw $t4, -0x1c($a0) + lw $t5, -0x20($a0) + addiu $a0, $a0, -0x20 + addiu $a1, $a1, -0x20 + addiu $a2, $a2, -0x20 + sw $v0, 0x1C($a1) + sw $v1, 0x18($a1) + sw $t0, 0x14($a1) + sw $t1, 0x10($a1) + sw $t2, 0xC($a1) + sw $t3, 8($a1) + sw $t4, 4($a1) + b backwards_32 + sw $t5, ($a1) backwards_16: -/* 007DB4 800071B4 28C10010 */ slti $at, $a2, 0x10 -.L800071B8: -/* 007DB8 800071B8 5420000E */ bnezl $at, .L800071F4 -/* 007DBC 800071BC 28C10004 */ slti $at, $a2, 4 -/* 007DC0 800071C0 8C82FFFC */ lw $v0, -4($a0) -/* 007DC4 800071C4 8C83FFF8 */ lw $v1, -8($a0) -/* 007DC8 800071C8 8C88FFF4 */ lw $t0, -0xc($a0) -/* 007DCC 800071CC 8C89FFF0 */ lw $t1, -0x10($a0) -/* 007DD0 800071D0 2484FFF0 */ addiu $a0, $a0, -0x10 -/* 007DD4 800071D4 24A5FFF0 */ addiu $a1, $a1, -0x10 -/* 007DD8 800071D8 24C6FFF0 */ addiu $a2, $a2, -0x10 -/* 007DDC 800071DC ACA2000C */ sw $v0, 0xc($a1) -/* 007DE0 800071E0 ACA30008 */ sw $v1, 8($a1) -/* 007DE4 800071E4 ACA80004 */ sw $t0, 4($a1) -/* 007DE8 800071E8 1000FFF2 */ b backwards_16 -/* 007DEC 800071EC ACA90000 */ sw $t1, ($a1) + slti $at, $a2, 0x10 +backwards_16_: // fake label due to branch likely optimization + bnezl $at, backwards_4_ + slti $at, $a2, 4 + lw $v0, -4($a0) + lw $v1, -8($a0) + lw $t0, -0xC($a0) + lw $t1, -0x10($a0) + addiu $a0, $a0, -0x10 + addiu $a1, $a1, -0x10 + addiu $a2, $a2, -0x10 + sw $v0, 0xC($a1) + sw $v1, 8($a1) + sw $t0, 4($a1) + b backwards_16 + sw $t1, ($a1) backwards_4: -/* 007DF0 800071F0 28C10004 */ slti $at, $a2, 4 -.L800071F4: -/* 007DF4 800071F4 1420FFB3 */ bnez $at, backwards_bytecopy -/* 007DF8 800071F8 00000000 */ nop -/* 007DFC 800071FC 8C82FFFC */ lw $v0, -4($a0) -/* 007E00 80007200 2484FFFC */ addiu $a0, $a0, -4 -/* 007E04 80007204 24A5FFFC */ addiu $a1, $a1, -4 -/* 007E08 80007208 24C6FFFC */ addiu $a2, $a2, -4 -/* 007E0C 8000720C 1000FFF8 */ b backwards_4 -/* 007E10 80007210 ACA20000 */ sw $v0, ($a1) + slti $at, $a2, 4 +backwards_4_: // fake label due to branch likely optimization + bnez $at, backwards_bytecopy + nop + lw $v0, -4($a0) + addiu $a0, $a0, -4 + addiu $a1, $a1, -4 + addiu $a2, $a2, -4 + b backwards_4 + sw $v0, ($a1) +END(bcopy) diff --git a/asm/bzero.s b/asm/bzero.s index 9f116d49f0..5323a92d7d 100644 --- a/asm/bzero.s +++ b/asm/bzero.s @@ -1,84 +1,65 @@ -.include "macro.inc" +#include "ultra64/asm.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 -glabel bzero -/* 005050 80004450 28A1000C */ slti $at, $a1, 0xc -/* 005054 80004454 1420001D */ bnez $at, .bytezero -/* 005058 80004458 00041823 */ negu $v1, $a0 -/* 00505C 8000445C 30630003 */ andi $v1, $v1, 3 -/* 005060 80004460 10600003 */ beqz $v1, .blkzero -/* 005064 80004464 00A32823 */ subu $a1, $a1, $v1 -/* 005068 80004468 A8800000 */ swl $zero, ($a0) -/* 00506C 8000446C 00832021 */ addu $a0, $a0, $v1 -.blkzero: -/* 005070 80004470 2401FFE0 */ li $at, -32 -/* 005074 80004474 00A13824 */ and $a3, $a1, $at -/* 005078 80004478 10E0000C */ beqz $a3, .wordzero -/* 00507C 8000447C 00A72823 */ subu $a1, $a1, $a3 -/* 005080 80004480 00E43821 */ addu $a3, $a3, $a0 -.L80004484: -/* 005084 80004484 24840020 */ addiu $a0, $a0, 0x20 -/* 005088 80004488 AC80FFE0 */ sw $zero, -0x20($a0) -/* 00508C 8000448C AC80FFE4 */ sw $zero, -0x1c($a0) -/* 005090 80004490 AC80FFE8 */ sw $zero, -0x18($a0) -/* 005094 80004494 AC80FFEC */ sw $zero, -0x14($a0) -/* 005098 80004498 AC80FFF0 */ sw $zero, -0x10($a0) -/* 00509C 8000449C AC80FFF4 */ sw $zero, -0xc($a0) -/* 0050A0 800044A0 AC80FFF8 */ sw $zero, -8($a0) -/* 0050A4 800044A4 1487FFF7 */ bne $a0, $a3, .L80004484 -/* 0050A8 800044A8 AC80FFFC */ sw $zero, -4($a0) -.wordzero: -/* 0050AC 800044AC 2401FFFC */ li $at, -4 -/* 0050B0 800044B0 00A13824 */ and $a3, $a1, $at -/* 0050B4 800044B4 10E00005 */ beqz $a3, .bytezero -/* 0050B8 800044B8 00A72823 */ subu $a1, $a1, $a3 -/* 0050BC 800044BC 00E43821 */ addu $a3, $a3, $a0 -.L800044C0: -/* 0050C0 800044C0 24840004 */ addiu $a0, $a0, 4 -/* 0050C4 800044C4 1487FFFE */ bne $a0, $a3, .L800044C0 -/* 0050C8 800044C8 AC80FFFC */ sw $zero, -4($a0) -.bytezero: -/* 0050CC 800044CC 18A00005 */ blez $a1, .zerodone -/* 0050D0 800044D0 00000000 */ nop -/* 0050D4 800044D4 00A42821 */ addu $a1, $a1, $a0 -.L800044D8: -/* 0050D8 800044D8 24840001 */ addiu $a0, $a0, 1 -/* 0050DC 800044DC 1485FFFE */ bne $a0, $a1, .L800044D8 -/* 0050E0 800044E0 A080FFFF */ sb $zero, -1($a0) -.zerodone: -/* 0050E4 800044E4 03E00008 */ jr $ra -/* 0050E8 800044E8 00000000 */ nop - -/* 0050EC 800044EC 00000000 */ nop -/* 0050F0 800044F0 00000000 */ nop -/* 0050F4 800044F4 00000000 */ nop -/* 0050F8 800044F8 00000000 */ nop -/* 0050FC 800044FC 00000000 */ nop -/* 005100 80004500 00000000 */ nop -/* 005104 80004504 00000000 */ nop -/* 005108 80004508 00000000 */ nop -/* 00510C 8000450C 00000000 */ nop -/* 005110 80004510 00000000 */ nop -/* 005114 80004514 00000000 */ nop -/* 005118 80004518 00000000 */ nop -/* 00511C 8000451C 00000000 */ nop -/* 005120 80004520 00000000 */ nop -/* 005124 80004524 00000000 */ nop -/* 005128 80004528 00000000 */ nop -/* 00512C 8000452C 00000000 */ nop -/* 005130 80004530 00000000 */ nop -/* 005134 80004534 00000000 */ nop -/* 005138 80004538 00000000 */ nop -/* 00513C 8000453C 00000000 */ nop -/* 005140 80004540 00000000 */ nop -/* 005144 80004544 00000000 */ nop -/* 005148 80004548 00000000 */ nop -/* 00514C 8000454C 00000000 */ nop +LEAF(bzero) + slti $at, $a1, 0xC + bnez $at, bytezero + negu $v1, $a0 + andi $v1, $v1, 3 + beqz $v1, blkzero + subu $a1, $a1, $v1 + swl $zero, ($a0) + addu $a0, $a0, $v1 +blkzero: + // align backwards to 0x20 + li $at, ~0x1F + and $a3, $a1, $at + // If the result is zero, the amount to zero is less than 0x20 bytes + beqz $a3, wordzero + subu $a1, $a1, $a3 + // zero in blocks of 0x20 at a time + addu $a3, $a3, $a0 +1: + addiu $a0, $a0, 0x20 + sw $zero, -0x20($a0) + sw $zero, -0x1C($a0) + sw $zero, -0x18($a0) + sw $zero, -0x14($a0) + sw $zero, -0x10($a0) + sw $zero, -0xC($a0) + sw $zero, -8($a0) + bne $a0, $a3, 1b + sw $zero, -4($a0) +wordzero: + // align backwards to 0x4 + li $at, ~3 + and $a3, $a1, $at + // If the result is zero, the amount to zero is less than 0x4 bytes + beqz $a3, bytezero + subu $a1, $a1, $a3 + // zero one word at a time + addu $a3, $a3, $a0 +1: + addiu $a0, $a0, 4 + bne $a0, $a3, 1b + sw $zero, -4($a0) +bytezero: + // test if nothing left to zero + blez $a1, zerodone + nop + // zero one byte at a time + addu $a1, $a1, $a0 +1: + addiu $a0, $a0, 1 + bne $a0, $a1, 1b + sb $zero, -1($a0) +zerodone: + jr $ra + nop +END(bzero) diff --git a/asm/code_800D71F0.s b/asm/code_800D71F0.s index 0f7195f73a..c3bf9d11de 100644 --- a/asm/code_800D71F0.s +++ b/asm/code_800D71F0.s @@ -1,57 +1,57 @@ -.include "macro.inc" +#include "ultra64/asm.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 -glabel func_800D71F0 -/* B4E390 800D71F0 34018800 */ li $at, 34816 -/* B4E394 800D71F4 0081082A */ slt $at, $a0, $at -/* B4E398 800D71F8 14200010 */ bnez $at, .L800D723C -/* B4E39C 800D71FC 240600BC */ li $a2, 188 -/* B4E3A0 800D7200 00042A02 */ srl $a1, $a0, 8 -/* B4E3A4 800D7204 20A5FF78 */ addi $a1, $a1, -0x88 -/* B4E3A8 800D7208 00C50019 */ multu $a2, $a1 -/* B4E3AC 800D720C 308700FF */ andi $a3, $a0, 0xff -/* B4E3B0 800D7210 20E7FFC0 */ addi $a3, $a3, -0x40 -/* B4E3B4 800D7214 28E10040 */ slti $at, $a3, 0x40 -/* B4E3B8 800D7218 00003012 */ mflo $a2 -/* B4E3BC 800D721C 54200003 */ bnezl $at, .L800D722C -/* B4E3C0 800D7220 00003012 */ mflo $a2 -/* B4E3C4 800D7224 20E7FFFF */ addi $a3, $a3, -1 -/* B4E3C8 800D7228 00003012 */ mflo $a2 +LEAF(func_800D71F0) + li $at, 0x8800 + slt $at, $a0, $at + bnez $at, .L800D723C + li $a2, 188 + srl $a1, $a0, 8 + addi $a1, $a1, -0x88 + multu $a2, $a1 + andi $a3, $a0, 0xFF + addi $a3, $a3, -0x40 + slti $at, $a3, 0x40 + mflo $a2 + bnezl $at, .L800D722C + mflo $a2 + addi $a3, $a3, -1 + mflo $a2 .L800D722C: -/* B4E3CC 800D722C 20E7030A */ addi $a3, $a3, 0x30a -/* B4E3D0 800D7230 00E63820 */ add $a3, $a3, $a2 -/* B4E3D4 800D7234 03E00008 */ jr $ra -/* B4E3D8 800D7238 000711C0 */ sll $v0, $a3, 7 + addi $a3, $a3, 0x30A + add $a3, $a3, $a2 + jr $ra + sll $v0, $a3, 7 .L800D723C: -/* B4E3DC 800D723C 00042A02 */ srl $a1, $a0, 8 -/* B4E3E0 800D7240 20A5FF7F */ addi $a1, $a1, -0x81 -/* B4E3E4 800D7244 00C50019 */ multu $a2, $a1 -/* B4E3E8 800D7248 308700FF */ andi $a3, $a0, 0xff -/* B4E3EC 800D724C 20E7FFC0 */ addi $a3, $a3, -0x40 -/* B4E3F0 800D7250 28E10040 */ slti $at, $a3, 0x40 -/* B4E3F4 800D7254 00003012 */ mflo $a2 -/* B4E3F8 800D7258 54200003 */ bnezl $at, .L800D7268 -/* B4E3FC 800D725C 00003012 */ mflo $a2 -/* B4E400 800D7260 20E7FFFF */ addi $a3, $a3, -1 -/* B4E404 800D7264 00003012 */ mflo $a2 + srl $a1, $a0, 8 + addi $a1, $a1, -0x81 + multu $a2, $a1 + andi $a3, $a0, 0xFF + addi $a3, $a3, -0x40 + slti $at, $a3, 0x40 + mflo $a2 + bnezl $at, .L800D7268 + mflo $a2 + addi $a3, $a3, -1 + mflo $a2 .L800D7268: -/* B4E408 800D7268 00E63820 */ add $a3, $a3, $a2 -/* B4E40C 800D726C 3C06800D */ lui $a2, %hi(D_800D7288) # $a2, 0x800d -/* B4E410 800D7270 00073840 */ sll $a3, $a3, 1 -/* B4E414 800D7274 24C67288 */ addiu $a2, %lo(D_800D7288) # addiu $a2, $a2, 0x7288 -/* B4E418 800D7278 00E63820 */ add $a3, $a3, $a2 -/* B4E41C 800D727C 84E60000 */ lh $a2, ($a3) -/* B4E420 800D7280 03E00008 */ jr $ra -/* B4E424 800D7284 000611C0 */ sll $v0, $a2, 7 + add $a3, $a3, $a2 + lui $a2, %hi(D_800D7288) + sll $a3, $a3, 1 + addiu $a2, %lo(D_800D7288) + add $a3, $a3, $a2 + lh $a2, ($a3) + jr $ra + sll $v0, $a2, 7 +END(func_800D71F0) -glabel D_800D7288 -.incbin "baserom.z64", 0xB4E428, 0xB4EE70-0xB4E428 +DATA(D_800D7288) + .incbin "baserom.z64", 0xB4E428, 0xB4EE70 - 0xB4E428 +ENDDATA(D_800D7288) diff --git a/asm/entry.s b/asm/entry.s index a8b7c1fdce..72c18131e1 100644 --- a/asm/entry.s +++ b/asm/entry.s @@ -1,37 +1,35 @@ -.include "macro.inc" +#include "ultra64/asm.h" +#include "boot.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text -.set BOOT_STACK_SIZE, 0x400 +.balign 16 -glabel entrypoint # 0x80000400 - lui $t0, %hi(_bootSegmentBssStart) - addiu $t0, %lo(_bootSegmentBssStart) - li $t1, %lo(_bootSegmentBssSize) -.L8000040C: - addi $t1, $t1, -8 - sw $zero, ($t0) - sw $zero, 4($t0) - bnez $t1, .L8000040C - addi $t0, $t0, 8 - lui $t2, %hi(bootproc) - lui $sp, %hi(sBootThreadStack + BOOT_STACK_SIZE) - addiu $t2, %lo(bootproc) - jr $t2 - addiu $sp, %lo(sBootThreadStack + BOOT_STACK_SIZE) - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop +LEAF(entrypoint) + // Clear boot segment .bss + la $t0, _bootSegmentBssStart +#ifndef AVOID_UB + // UB: li only loads the lower 16 bits of _bootSegmentBssSize when it may be larger than this, + // so not all of bss may be cleared if it is too large + li $t1, _bootSegmentBssSize +#else + la $t1, _bootSegmentBssSize +#endif +.clear_bss: + addi $t1, $t1, -8 + sw $zero, ($t0) + sw $zero, 4($t0) + bnez $t1, .clear_bss + addi $t0, $t0, 8 + // Set up stack and enter program code + lui $t2, %hi(bootproc) + lui $sp, %hi(sBootThreadStack + BOOT_STACK_SIZE) + addiu $t2, %lo(bootproc) + jr $t2 + addiu $sp, %lo(sBootThreadStack + BOOT_STACK_SIZE) +END(entrypoint) + +.fill 0x60 - (. - entrypoint) diff --git a/asm/exceptasm.s b/asm/exceptasm.s index 4bcad4d425..79a6ed1a2b 100644 --- a/asm/exceptasm.s +++ b/asm/exceptasm.s @@ -1,34 +1,44 @@ -.include "macro.inc" +#include "ultra64/asm.h" +#include "ultra64/r4300.h" +#include "ultra64/rcp.h" +#include "ultra64/rsp.h" +#include "ultra64/message.h" +#include "ultra64/thread.h" +#include "ultra64/exception.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder +.set gp=64 .section .data -glabel __osHwIntTable - .word 0, 0 - .word 0, 0 - .word 0, 0 - .word 0, 0 - .word 0, 0 +.balign 16 -glabel __osPiIntTable - .word 0 - .word 0 +DATA(__osHwIntTable) + .word 0, 0 + .word 0, 0 // cart + .word 0, 0 + .word 0, 0 + .word 0, 0 +ENDDATA(__osHwIntTable) + +DATA(__osPiIntTable) + .word 0, 0 +ENDDATA(__osPiIntTable) .section .rodata -glabel __osIntOffTable +.balign 16 + +__osIntOffTable: .byte 0x00 /* redispatch */ .byte 0x14 /* prenmi */ .byte 0x18 /* IP6_Hdlr */ .byte 0x18 /* IP6_Hdlr */ - .byte 0x1c /* IP7_Hdlr */ - .byte 0x1c /* IP7_Hdlr */ - .byte 0x1c /* IP7_Hdlr */ - .byte 0x1c /* IP7_Hdlr */ + .byte 0x1C /* IP7_Hdlr */ + .byte 0x1C /* IP7_Hdlr */ + .byte 0x1C /* IP7_Hdlr */ + .byte 0x1C /* IP7_Hdlr */ .byte 0x20 /* counter */ .byte 0x20 /* counter */ .byte 0x20 /* counter */ @@ -41,10 +51,10 @@ glabel __osIntOffTable .byte 0x04 /* sw1 */ .byte 0x08 /* sw2 */ .byte 0x08 /* sw2 */ - .byte 0x0c /* rcp */ - .byte 0x0c /* rcp */ - .byte 0x0c /* rcp */ - .byte 0x0c /* rcp */ + .byte 0x0C /* rcp */ + .byte 0x0C /* rcp */ + .byte 0x0C /* rcp */ + .byte 0x0C /* rcp */ .byte 0x10 /* cart */ .byte 0x10 /* cart */ .byte 0x10 /* cart */ @@ -54,7 +64,7 @@ glabel __osIntOffTable .byte 0x10 /* cart */ .byte 0x10 /* cart */ -glabel __osIntTable +__osIntTable: .word redispatch .word sw1 .word sw2 @@ -69,646 +79,904 @@ glabel __osIntTable .balign 16 -glabel __osExceptionPreamble -/* 0045D0 800039D0 3C1A8000 */ lui $k0, %hi(__osException) # $k0, 0x8000 -/* 0045D4 800039D4 275A39E0 */ addiu $k0, %lo(__osException) # addiu $k0, $k0, 0x39e0 -/* 0045D8 800039D8 03400008 */ jr $k0 -/* 0045DC 800039DC 00000000 */ nop +/** + * The exception preamble is copied to the exception vectors at + * UT_VEC, XUT_VEC, ECC_VEC, E_VEC, to direct execution to __osException + */ +LEAF(__osExceptionPreamble) + lui $k0, %hi(__osException) + addiu $k0, %lo(__osException) + jr $k0 + nop +END(__osExceptionPreamble) -glabel __osException -/* 0045E0 800039E0 3C1A8001 */ lui $k0, %hi(__osThreadSave) # $k0, 0x8001 -/* 0045E4 800039E4 275A5890 */ addiu $k0, %lo(__osThreadSave) # addiu $k0, $k0, 0x5890 -/* 0045E8 800039E8 FF410020 */ sd $at, 0x20($k0) -/* 0045EC 800039EC 401B6000 */ mfc0 $k1, $12 -/* 0045F0 800039F0 AF5B0118 */ sw $k1, 0x118($k0) -/* 0045F4 800039F4 2401FFFC */ li $at, -4 -/* 0045F8 800039F8 0361D824 */ and $k1, $k1, $at -/* 0045FC 800039FC 409B6000 */ mtc0 $k1, $12 -/* 004600 80003A00 FF480058 */ sd $t0, 0x58($k0) -/* 004604 80003A04 FF490060 */ sd $t1, 0x60($k0) -/* 004608 80003A08 FF4A0068 */ sd $t2, 0x68($k0) -/* 00460C 80003A0C AF400018 */ sw $zero, 0x18($k0) -/* 004610 80003A10 40086800 */ mfc0 $t0, $13 -/* 004614 80003A14 03404025 */ move $t0, $k0 -/* 004618 80003A18 3C1A8001 */ lui $k0, %hi(__osRunningThread) # $k0, 0x8001 -/* 00461C 80003A1C 8F5AAD50 */ lw $k0, %lo(__osRunningThread)($k0) -/* 004620 80003A20 DD090020 */ ld $t1, 0x20($t0) -/* 004624 80003A24 FF490020 */ sd $t1, 0x20($k0) -/* 004628 80003A28 DD090118 */ ld $t1, 0x118($t0) -/* 00462C 80003A2C FF490118 */ sd $t1, 0x118($k0) -/* 004630 80003A30 DD090058 */ ld $t1, 0x58($t0) -/* 004634 80003A34 FF490058 */ sd $t1, 0x58($k0) -/* 004638 80003A38 DD090060 */ ld $t1, 0x60($t0) -/* 00463C 80003A3C FF490060 */ sd $t1, 0x60($k0) -/* 004640 80003A40 DD090068 */ ld $t1, 0x68($t0) -/* 004644 80003A44 FF490068 */ sd $t1, 0x68($k0) -/* 004648 80003A48 8F5B0118 */ lw $k1, 0x118($k0) -/* 00464C 80003A4C 00004012 */ mflo $t0 -/* 004650 80003A50 FF480108 */ sd $t0, 0x108($k0) -/* 004654 80003A54 00004010 */ mfhi $t0 -/* 004658 80003A58 3369FF00 */ andi $t1, $k1, 0xff00 -/* 00465C 80003A5C FF420028 */ sd $v0, 0x28($k0) -/* 004660 80003A60 FF430030 */ sd $v1, 0x30($k0) -/* 004664 80003A64 FF440038 */ sd $a0, 0x38($k0) -/* 004668 80003A68 FF450040 */ sd $a1, 0x40($k0) -/* 00466C 80003A6C FF460048 */ sd $a2, 0x48($k0) -/* 004670 80003A70 FF470050 */ sd $a3, 0x50($k0) -/* 004674 80003A74 FF4B0070 */ sd $t3, 0x70($k0) -/* 004678 80003A78 FF4C0078 */ sd $t4, 0x78($k0) -/* 00467C 80003A7C FF4D0080 */ sd $t5, 0x80($k0) -/* 004680 80003A80 FF4E0088 */ sd $t6, 0x88($k0) -/* 004684 80003A84 FF4F0090 */ sd $t7, 0x90($k0) -/* 004688 80003A88 FF500098 */ sd $s0, 0x98($k0) -/* 00468C 80003A8C FF5100A0 */ sd $s1, 0xa0($k0) -/* 004690 80003A90 FF5200A8 */ sd $s2, 0xa8($k0) -/* 004694 80003A94 FF5300B0 */ sd $s3, 0xb0($k0) -/* 004698 80003A98 FF5400B8 */ sd $s4, 0xb8($k0) -/* 00469C 80003A9C FF5500C0 */ sd $s5, 0xc0($k0) -/* 0046A0 80003AA0 FF5600C8 */ sd $s6, 0xc8($k0) -/* 0046A4 80003AA4 FF5700D0 */ sd $s7, 0xd0($k0) -/* 0046A8 80003AA8 FF5800D8 */ sd $t8, 0xd8($k0) -/* 0046AC 80003AAC FF5900E0 */ sd $t9, 0xe0($k0) -/* 0046B0 80003AB0 FF5C00E8 */ sd $gp, 0xe8($k0) -/* 0046B4 80003AB4 FF5D00F0 */ sd $sp, 0xf0($k0) -/* 0046B8 80003AB8 FF5E00F8 */ sd $fp, 0xf8($k0) -/* 0046BC 80003ABC FF5F0100 */ sd $ra, 0x100($k0) -/* 0046C0 80003AC0 11200011 */ beqz $t1, savercp -/* 0046C4 80003AC4 FF480110 */ sd $t0, 0x110($k0) -/* 0046C8 80003AC8 3C088001 */ lui $t0, %hi(__OSGlobalIntMask) # $t0, 0x8001 -/* 0046CC 80003ACC 2508AD00 */ addiu $t0, %lo(__OSGlobalIntMask) # addiu $t0, $t0, -0x5300 -/* 0046D0 80003AD0 8D080000 */ lw $t0, ($t0) -/* 0046D4 80003AD4 2401FFFF */ li $at, -1 -/* 0046D8 80003AD8 01015026 */ xor $t2, $t0, $at -/* 0046DC 80003ADC 3C01FFFF */ lui $at, (0xFFFF00FF >> 16) # lui $at, 0xffff -/* 0046E0 80003AE0 314AFF00 */ andi $t2, $t2, 0xff00 -/* 0046E4 80003AE4 342100FF */ ori $at, (0xFFFF00FF & 0xFFFF) # ori $at, $at, 0xff -/* 0046E8 80003AE8 012A6025 */ or $t4, $t1, $t2 -/* 0046EC 80003AEC 03615824 */ and $t3, $k1, $at -/* 0046F0 80003AF0 3108FF00 */ andi $t0, $t0, 0xff00 -/* 0046F4 80003AF4 016C5825 */ or $t3, $t3, $t4 -/* 0046F8 80003AF8 01284824 */ and $t1, $t1, $t0 -/* 0046FC 80003AFC 0361D824 */ and $k1, $k1, $at -/* 004700 80003B00 AF4B0118 */ sw $t3, 0x118($k0) -/* 004704 80003B04 0369D825 */ or $k1, $k1, $t1 +LEAF(__osException) + // Load scratch space for thread saving + lui $k0, %hi(__osThreadSave) + addiu $k0, %lo(__osThreadSave) + // Save $at + sd $at, THREAD_AT($k0) + // Save sr + mfc0 $k1, C0_SR + sw $k1, THREAD_SR($k0) + // Disable interrupts + li $at, ~(SR_IE | SR_EXL) + and $k1, $k1, $at + mtc0 $k1, C0_SR + // Save some temp registers for use in the following + sd $t0, THREAD_T0($k0) + sd $t1, THREAD_T1($k0) + sd $t2, THREAD_T2($k0) + // Mark FPU as unused + sw $zero, THREAD_FP($k0) + // Left over from misplaced ifdef, immediately overwritten on next instruction + mfc0 $t0, C0_CAUSE +savecontext: + // Save the previously running thread's context to be restored when it resumes + move $t0, $k0 + lui $k0, %hi(__osRunningThread) + lw $k0, %lo(__osRunningThread)($k0) + ld $t1, THREAD_AT($t0) + sd $t1, THREAD_AT($k0) + ld $t1, THREAD_SR($t0) + sd $t1, THREAD_SR($k0) + ld $t1, THREAD_T0($t0) + sd $t1, THREAD_T0($k0) + ld $t1, THREAD_T1($t0) + sd $t1, THREAD_T1($k0) + ld $t1, THREAD_T2($t0) + sd $t1, THREAD_T2($k0) + lw $k1, THREAD_SR($k0) + mflo $t0 + sd $t0, THREAD_LO($k0) + mfhi $t0 + andi $t1, $k1, SR_IMASK + sd $v0, THREAD_V0($k0) + sd $v1, THREAD_V1($k0) + sd $a0, THREAD_A0($k0) + sd $a1, THREAD_A1($k0) + sd $a2, THREAD_A2($k0) + sd $a3, THREAD_A3($k0) + sd $t3, THREAD_T3($k0) + sd $t4, THREAD_T4($k0) + sd $t5, THREAD_T5($k0) + sd $t6, THREAD_T6($k0) + sd $t7, THREAD_T7($k0) + sd $s0, THREAD_S0($k0) + sd $s1, THREAD_S1($k0) + sd $s2, THREAD_S2($k0) + sd $s3, THREAD_S3($k0) + sd $s4, THREAD_S4($k0) + sd $s5, THREAD_S5($k0) + sd $s6, THREAD_S6($k0) + sd $s7, THREAD_S7($k0) + sd $t8, THREAD_T8($k0) + sd $t9, THREAD_T9($k0) + sd $gp, THREAD_GP($k0) + sd $sp, THREAD_SP($k0) + sd $fp, THREAD_S8($k0) + sd $ra, THREAD_RA($k0) + beqz $t1, savercp + sd $t0, THREAD_HI($k0) + // If any CPU interrupts are enabled in the previous thread's SR, bitwise-OR in the + // disabled CPU interrupts from the global interrupt mask. + // This is an attempt at reverting the effect of masking the thread's SR with the + // global interrupt mask. This is however broken, see comments for osSetIntMask. + lui $t0, %hi(__OSGlobalIntMask) + addiu $t0, %lo(__OSGlobalIntMask) + lw $t0, ($t0) + li $at, ~0 + xor $t2, $t0, $at + lui $at, ((~SR_IMASK) >> 0x10) & 0xFFFF + andi $t2, $t2, SR_IMASK + ori $at, (~SR_IMASK) & 0xFFFF + or $t4, $t1, $t2 + and $t3, $k1, $at + andi $t0, $t0, SR_IMASK + or $t3, $t3, $t4 + and $t1, $t1, $t0 + and $k1, $k1, $at + sw $t3, THREAD_SR($k0) + or $k1, $k1, $t1 savercp: -/* 004708 80003B08 3C09A430 */ lui $t1, %hi(D_A430000C) # $t1, 0xa430 -/* 00470C 80003B0C 8D29000C */ lw $t1, %lo(D_A430000C)($t1) -/* 004710 80003B10 1120000B */ beqz $t1, endrcp -/* 004714 80003B14 00000000 */ nop -/* 004718 80003B18 3C088001 */ lui $t0, %hi(__OSGlobalIntMask) # $t0, 0x8001 -/* 00471C 80003B1C 2508AD00 */ addiu $t0, %lo(__OSGlobalIntMask) # addiu $t0, $t0, -0x5300 -/* 004720 80003B20 8D080000 */ lw $t0, ($t0) -/* 004724 80003B24 8F4C0128 */ lw $t4, 0x128($k0) -/* 004728 80003B28 2401FFFF */ li $at, -1 -/* 00472C 80003B2C 00084402 */ srl $t0, $t0, 0x10 -/* 004730 80003B30 01014026 */ xor $t0, $t0, $at -/* 004734 80003B34 3108003F */ andi $t0, $t0, 0x3f -/* 004738 80003B38 010C4024 */ and $t0, $t0, $t4 -/* 00473C 80003B3C 01284825 */ or $t1, $t1, $t0 + // Save the currently masked RCP interrupts. + lui $t1, %hi(PHYS_TO_K1(MI_INTR_MASK_REG)) + lw $t1, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))($t1) + beqz $t1, endrcp + nop + // Similar to the above comment, but for RCP interrupt enable bits rather than CPU. + // This suffers from the same problem as above. + lui $t0, %hi(__OSGlobalIntMask) + addiu $t0, %lo(__OSGlobalIntMask) + lw $t0, ($t0) + lw $t4, THREAD_RCP($k0) + li $at, ~0 + srl $t0, $t0, RCP_IMASKSHIFT + xor $t0, $t0, $at + andi $t0, $t0, (RCP_IMASK >> RCP_IMASKSHIFT) + and $t0, $t0, $t4 + or $t1, $t1, $t0 endrcp: -/* 004740 80003B40 AF490128 */ sw $t1, 0x128($k0) -/* 004744 80003B44 40087000 */ mfc0 $t0, $14 -/* 004748 80003B48 AF48011C */ sw $t0, 0x11c($k0) -/* 00474C 80003B4C 8F480018 */ lw $t0, 0x18($k0) -/* 004750 80003B50 11000014 */ beqz $t0, no_rdb_mesg -/* 004754 80003B54 00000000 */ nop -/* 004758 80003B58 4448F800 */ cfc1 $t0, $31 -/* 00475C 80003B5C 00000000 */ nop -/* 004760 80003B60 AF48012C */ sw $t0, 0x12c($k0) -/* 004764 80003B64 F7400130 */ sdc1 $f0, 0x130($k0) -/* 004768 80003B68 F7420138 */ sdc1 $f2, 0x138($k0) -/* 00476C 80003B6C F7440140 */ sdc1 $f4, 0x140($k0) -/* 004770 80003B70 F7460148 */ sdc1 $f6, 0x148($k0) -/* 004774 80003B74 F7480150 */ sdc1 $f8, 0x150($k0) -/* 004778 80003B78 F74A0158 */ sdc1 $f10, 0x158($k0) -/* 00477C 80003B7C F74C0160 */ sdc1 $f12, 0x160($k0) -/* 004780 80003B80 F74E0168 */ sdc1 $f14, 0x168($k0) -/* 004784 80003B84 F7500170 */ sdc1 $f16, 0x170($k0) -/* 004788 80003B88 F7520178 */ sdc1 $f18, 0x178($k0) -/* 00478C 80003B8C F7540180 */ sdc1 $f20, 0x180($k0) -/* 004790 80003B90 F7560188 */ sdc1 $f22, 0x188($k0) -/* 004794 80003B94 F7580190 */ sdc1 $f24, 0x190($k0) -/* 004798 80003B98 F75A0198 */ sdc1 $f26, 0x198($k0) -/* 00479C 80003B9C F75C01A0 */ sdc1 $f28, 0x1a0($k0) -/* 0047A0 80003BA0 F75E01A8 */ sdc1 $f30, 0x1a8($k0) -no_rdb_mesg: -/* 0047A4 80003BA4 40086800 */ mfc0 $t0, $13 -/* 0047A8 80003BA8 AF480120 */ sw $t0, 0x120($k0) -/* 0047AC 80003BAC 24090002 */ li $t1, 2 -/* 0047B0 80003BB0 A7490010 */ sh $t1, 0x10($k0) -/* 0047B4 80003BB4 3109007C */ andi $t1, $t0, 0x7c -/* 0047B8 80003BB8 240A0024 */ li $t2, 36 -/* 0047BC 80003BBC 112A00B6 */ beq $t1, $t2, handle_break -/* 0047C0 80003BC0 00000000 */ nop -/* 0047C4 80003BC4 240A002C */ li $t2, 44 -/* 0047C8 80003BC8 112A0105 */ beq $t1, $t2, handle_CpU -/* 0047CC 80003BCC 00000000 */ nop -/* 0047D0 80003BD0 240A0000 */ li $t2, 0 -/* 0047D4 80003BD4 152A00C9 */ bne $t1, $t2, panic -/* 0047D8 80003BD8 00000000 */ nop -/* 0047DC 80003BDC 03688024 */ and $s0, $k1, $t0 + sw $t1, THREAD_RCP($k0) + mfc0 $t0, C0_EPC + sw $t0, THREAD_PC($k0) + lw $t0, THREAD_FP($k0) + beqz $t0, handle_interrupt + nop + // Save FP Registers if FPU was used by the thread + cfc1 $t0, C1_FPCSR + nop + sw $t0, THREAD_FPCSR($k0) + sdc1 $f0, THREAD_FP0($k0) + sdc1 $f2, THREAD_FP2($k0) + sdc1 $f4, THREAD_FP4($k0) + sdc1 $f6, THREAD_FP6($k0) + sdc1 $f8, THREAD_FP8($k0) + sdc1 $f10, THREAD_FP10($k0) + sdc1 $f12, THREAD_FP12($k0) + sdc1 $f14, THREAD_FP14($k0) + sdc1 $f16, THREAD_FP16($k0) + sdc1 $f18, THREAD_FP18($k0) + sdc1 $f20, THREAD_FP20($k0) + sdc1 $f22, THREAD_FP22($k0) + sdc1 $f24, THREAD_FP24($k0) + sdc1 $f26, THREAD_FP26($k0) + sdc1 $f28, THREAD_FP28($k0) + sdc1 $f30, THREAD_FP30($k0) + +handle_interrupt: + // Determine the cause of the exception or interrupt and + // enter appropriate handling routine + mfc0 $t0, C0_CAUSE + sw $t0, THREAD_CAUSE($k0) + li $t1, OS_STATE_RUNNABLE + sh $t1, THREAD_STATE($k0) + andi $t1, $t0, CAUSE_EXCMASK + // Test for break exception + li $t2, EXC_BREAK + beq $t1, $t2, handle_break + nop + // Test for CpU (coprocessor unusable) exception + li $t2, EXC_CPU + beq $t1, $t2, handle_CpU + nop + // Test for interrupt, if it's not an interrupt, panic + li $t2, EXC_INT + bne $t1, $t2, panic + nop + and $s0, $k1, $t0 + next_interrupt: -/* 0047E0 80003BE0 3209FF00 */ andi $t1, $s0, 0xff00 -/* 0047E4 80003BE4 00095302 */ srl $t2, $t1, 0xc -/* 0047E8 80003BE8 15400003 */ bnez $t2, .L80003BF8 -/* 0047EC 80003BEC 00000000 */ nop -/* 0047F0 80003BF0 00095202 */ srl $t2, $t1, 8 -/* 0047F4 80003BF4 214A0010 */ addi $t2, $t2, 0x10 -.L80003BF8: -/* 0047F8 80003BF8 3C018001 */ lui $at, %hi(__osIntOffTable) -/* 0047FC 80003BFC 002A0821 */ addu $at, $at, $t2 -/* 004800 80003C00 902A20F0 */ lbu $t2, %lo(__osIntOffTable)($at) -/* 004804 80003C04 3C018001 */ lui $at, %hi(__osIntTable) -/* 004808 80003C08 002A0821 */ addu $at, $at, $t2 -/* 00480C 80003C0C 8C2A2110 */ lw $t2, %lo(__osIntTable)($at) -/* 004810 80003C10 01400008 */ jr $t2 -/* 004814 80003C14 00000000 */ nop + // Handle external interrupt causes, using a jump table + // to enter into the appropriate handler + andi $t1, $s0, CAUSE_IPMASK + srl $t2, $t1, CAUSE_IPSHIFT + 4 + bnez $t2, 1f + nop + srl $t2, $t1, CAUSE_IPSHIFT + addi $t2, $t2, 0x10 +1: + lui $at, %hi(__osIntOffTable) + addu $at, $at, $t2 + lbu $t2, %lo(__osIntOffTable)($at) + lui $at, %hi(__osIntTable) + addu $at, $at, $t2 + lw $t2, %lo(__osIntTable)($at) + jr $t2 + nop + +/** + * IP6 Interrupt + * Only signalled by development hardware + */ IP6_Hdlr: -/* 004818 80003C18 2401DFFF */ li $at, -8193 -/* 00481C 80003C1C 1000FFF0 */ b next_interrupt -/* 004820 80003C20 02018024 */ and $s0, $s0, $at + // Mask out interrupt and continue + li $at, ~CAUSE_IP6 + b next_interrupt + and $s0, $s0, $at + +/** + * IP7 Interrupt + * Only signalled by development hardware + */ IP7_Hdlr: -/* 004824 80003C24 2401BFFF */ li $at, -16385 -/* 004828 80003C28 1000FFED */ b next_interrupt -/* 00482C 80003C2C 02018024 */ and $s0, $s0, $at + // Mask out interrupt and continue + li $at, ~CAUSE_IP7 + b next_interrupt + and $s0, $s0, $at + +/** + * IP8/Counter Interrupt + * Once the cop0 count register reaches the value of the + * cop0 compare register, this interrupt is triggered + */ counter: -/* 004830 80003C30 40095800 */ mfc0 $t1, $11 -/* 004834 80003C34 40895800 */ mtc0 $t1, $11 -/* 004838 80003C38 0C000FCB */ jal send_mesg -/* 00483C 80003C3C 24040018 */ li $a0, 24 -/* 004840 80003C40 3C01FFFF */ lui $at, (0xFFFF7FFF >> 16) # lui $at, 0xffff -/* 004844 80003C44 34217FFF */ ori $at, (0xFFFF7FFF & 0xFFFF) # ori $at, $at, 0x7fff -/* 004848 80003C48 1000FFE5 */ b next_interrupt -/* 00484C 80003C4C 02018024 */ and $s0, $s0, $at + mfc0 $t1, C0_COMPARE + mtc0 $t1, C0_COMPARE + // Post counter message + jal send_mesg + li $a0, OS_EVENT_COUNTER*8 + // Mask out interrupt and continue + li $at, ~CAUSE_IP8 + b next_interrupt + and $s0, $s0, $at + +/** + * IP4/Cartridge Interrupt + * Signalled by the N64 Disk Drive + */ cart: -/* 004850 80003C50 3C098001 */ lui $t1, %hi(__osHwIntTable) # $t1, 0x8001 -/* 004854 80003C54 2529AD10 */ addiu $t1, %lo(__osHwIntTable) # addiu $t1, $t1, -0x52f0 -/* 004858 80003C58 8D2A0008 */ lw $t2, 8($t1) -/* 00485C 80003C5C 2401F7FF */ li $at, -2049 -/* 004860 80003C60 02018024 */ and $s0, $s0, $at -/* 004864 80003C64 11400007 */ beqz $t2, .L80003C84 -/* 004868 80003C68 21290008 */ addi $t1, $t1, 8 -/* 00486C 80003C6C 0140F809 */ jalr $t2 -/* 004870 80003C70 8D3D0004 */ lw $sp, 4($t1) -/* 004874 80003C74 10400003 */ beqz $v0, .L80003C84 -/* 004878 80003C78 00000000 */ nop -/* 00487C 80003C7C 1000008C */ b redispatch -/* 004880 80003C80 00000000 */ nop -.L80003C84: -/* 004884 80003C84 0C000FCB */ jal send_mesg -/* 004888 80003C88 24040010 */ li $a0, 16 -/* 00488C 80003C8C 1000FFD4 */ b next_interrupt -/* 004890 80003C90 00000000 */ nop + // Load cart callback set by __osSetHWIntrRoutine + lui $t1, %hi(__osHwIntTable) + addiu $t1, %lo(__osHwIntTable) + lw $t2, (OS_INTR_CART*HWINT_SIZE+HWINT_CALLBACK)($t1) + // Mask out interrupt + li $at, ~CAUSE_IP4 + and $s0, $s0, $at + // If the callback is NULL, handling is done + beqz $t2, send_cart_mesg + addi $t1, $t1, (OS_INTR_CART*HWINT_SIZE) + // Set up a stack and run the callback + jalr $t2 + lw $sp, HWINT_SP($t1) + beqz $v0, send_cart_mesg + nop + // Redispatch immediately if the callback returned nonzero + b redispatch + nop +send_cart_mesg: + // Post a cart event message + jal send_mesg + li $a0, OS_EVENT_CART*8 + // Continue + b next_interrupt + nop + +/** + * IP3/RCP Interrupt + * Signalled by the RCP for various reasons, described below + */ rcp: -/* 004894 80003C94 3C088001 */ lui $t0, %hi(__OSGlobalIntMask) # $t0, 0x8001 -/* 004898 80003C98 2508AD00 */ addiu $t0, %lo(__OSGlobalIntMask) # addiu $t0, $t0, -0x5300 -/* 00489C 80003C9C 8D080000 */ lw $t0, ($t0) -/* 0048A0 80003CA0 3C11A430 */ lui $s1, %hi(D_A4300008) # $s1, 0xa430 -/* 0048A4 80003CA4 8E310008 */ lw $s1, %lo(D_A4300008)($s1) -/* 0048A8 80003CA8 00084402 */ srl $t0, $t0, 0x10 -/* 0048AC 80003CAC 02288824 */ and $s1, $s1, $t0 -/* 0048B0 80003CB0 32290001 */ andi $t1, $s1, 1 -/* 0048B4 80003CB4 11200013 */ beqz $t1, vi -/* 0048B8 80003CB8 00000000 */ nop -/* 0048BC 80003CBC 3C0CA404 */ lui $t4, %hi(D_A4040010) # $t4, 0xa404 -/* 0048C0 80003CC0 8D8C0010 */ lw $t4, %lo(D_A4040010)($t4) -/* 0048C4 80003CC4 34098008 */ li $t1, 32776 -/* 0048C8 80003CC8 3C01A404 */ lui $at, %hi(D_A4040010) # $at, 0xa404 -/* 0048CC 80003CCC 318C0300 */ andi $t4, $t4, 0x300 -/* 0048D0 80003CD0 3231003E */ andi $s1, $s1, 0x3e -/* 0048D4 80003CD4 11800007 */ beqz $t4, sp_other_break -/* 0048D8 80003CD8 AC290010 */ sw $t1, %lo(D_A4040010)($at) -/* 0048DC 80003CDC 0C000FCB */ jal send_mesg -/* 0048E0 80003CE0 24040020 */ li $a0, 32 -/* 0048E4 80003CE4 12200042 */ beqz $s1, NoMoreRcpInts -/* 0048E8 80003CE8 00000000 */ nop -/* 0048EC 80003CEC 10000005 */ b vi -/* 0048F0 80003CF0 00000000 */ nop + // Load the MI interrupts and mask with the RCP bits in the global interrupt mask + //! @bug this clobbers the t0 register which is expected to hold the value of the + //! C0_CAUSE register in the sw1 and sw2 handlers. If the sw1 or sw2 handler runs + //! after this, the interrupt will not be cleared properly. + lui $t0, %hi(__OSGlobalIntMask) + addiu $t0, %lo(__OSGlobalIntMask) + lw $t0, ($t0) + lui $s1, %hi(PHYS_TO_K1(MI_INTR_REG)) + lw $s1, %lo(PHYS_TO_K1(MI_INTR_REG))($s1) + srl $t0, $t0, RCP_IMASKSHIFT + and $s1, $s1, $t0 + +/** + * Signal Processor (SP) Interrupt + */ +sp: + // Test for sp interrupt + andi $t1, $s1, MI_INTR_SP + beqz $t1, vi + nop + // Test for yielded or done signals in particular + lui $t4, %hi(PHYS_TO_K1(SP_STATUS_REG)) + lw $t4, %lo(PHYS_TO_K1(SP_STATUS_REG))($t4) + li $t1, (SP_CLR_INTR | SP_CLR_SIG3) + lui $at, %hi(PHYS_TO_K1(SP_STATUS_REG)) + andi $t4, $t4, (SP_STATUS_YIELDED | SP_STATUS_TASKDONE) + // Mask out SP interrupt + andi $s1, $s1, (MI_INTR_SI | MI_INTR_AI | MI_INTR_VI | MI_INTR_PI | MI_INTR_DP) + beqz $t4, sp_other_break + // Clear interrupt and signal 3 + sw $t1, %lo(PHYS_TO_K1(SP_STATUS_REG))($at) + // Post an SP event message + jal send_mesg + li $a0, OS_EVENT_SP*8 + beqz $s1, NoMoreRcpInts + nop + // Step over sp_other_break handler + b vi + nop + sp_other_break: -/* 0048F4 80003CF4 0C000FCB */ jal send_mesg -/* 0048F8 80003CF8 24040058 */ li $a0, 88 -/* 0048FC 80003CFC 1220003C */ beqz $s1, NoMoreRcpInts -/* 004900 80003D00 00000000 */ nop + // An sp signal that is not due to yielding or task completion, such as + // an sp breakpoint. Post a different event message + jal send_mesg + li $a0, OS_EVENT_SP_BREAK*8 + beqz $s1, NoMoreRcpInts + nop + +/** + * Video Interface (VI) Interrupt + */ vi: -/* 004904 80003D04 32290008 */ andi $t1, $s1, 8 -/* 004908 80003D08 11200007 */ beqz $t1, ai -/* 00490C 80003D0C 3C01A440 */ lui $at, %hi(D_A4400010) # $at, 0xa440 -/* 004910 80003D10 32310037 */ andi $s1, $s1, 0x37 -/* 004914 80003D14 AC200010 */ sw $zero, %lo(D_A4400010)($at) -/* 004918 80003D18 0C000FCB */ jal send_mesg -/* 00491C 80003D1C 24040038 */ li $a0, 56 -/* 004920 80003D20 12200033 */ beqz $s1, NoMoreRcpInts -/* 004924 80003D24 00000000 */ nop + // Test for vi interrupt + andi $t1, $s1, MI_INTR_VI + beqz $t1, ai + lui $at, %hi(PHYS_TO_K1(VI_CURRENT_REG)) + // Mask out vi interrupt + andi $s1, $s1, (MI_INTR_SP | MI_INTR_SI | MI_INTR_AI | MI_INTR_PI | MI_INTR_DP) + // Clear interrupt + sw $zero, %lo(PHYS_TO_K1(VI_CURRENT_REG))($at) + // Post vi event message + jal send_mesg + li $a0, OS_EVENT_VI*8 + beqz $s1, NoMoreRcpInts + nop + +/** + * Audio Interface (AI) Interrupt + */ ai: -/* 004928 80003D28 32290004 */ andi $t1, $s1, 4 -/* 00492C 80003D2C 11200009 */ beqz $t1, si -/* 004930 80003D30 00000000 */ nop -/* 004934 80003D34 24090001 */ li $t1, 1 -/* 004938 80003D38 3C01A450 */ lui $at, %hi(D_A450000C) # $at, 0xa450 -/* 00493C 80003D3C 3231003B */ andi $s1, $s1, 0x3b -/* 004940 80003D40 AC29000C */ sw $t1, %lo(D_A450000C)($at) -/* 004944 80003D44 0C000FCB */ jal send_mesg -/* 004948 80003D48 24040030 */ li $a0, 48 -/* 00494C 80003D4C 12200028 */ beqz $s1, NoMoreRcpInts -/* 004950 80003D50 00000000 */ nop + // Test for ai interrupt + andi $t1, $s1, MI_INTR_AI + beqz $t1, si + nop + li $t1, 1 + lui $at, %hi(PHYS_TO_K1(AI_STATUS_REG)) + // Mask out ai interrupt + andi $s1, $s1, (MI_INTR_SP | MI_INTR_SI | MI_INTR_VI | MI_INTR_PI | MI_INTR_DP) + // Clear interrupt + sw $t1, %lo(PHYS_TO_K1(AI_STATUS_REG))($at) + // Post ai event message + jal send_mesg + li $a0, OS_EVENT_AI*8 + beqz $s1, NoMoreRcpInts + nop + +/** + * Serial Interface (SI) Interrupt + */ si: -/* 004954 80003D54 32290002 */ andi $t1, $s1, 2 -/* 004958 80003D58 11200007 */ beqz $t1, pi -/* 00495C 80003D5C 3C01A480 */ lui $at, %hi(D_A4800018) # $at, 0xa480 -/* 004960 80003D60 3231003D */ andi $s1, $s1, 0x3d -/* 004964 80003D64 AC200018 */ sw $zero, %lo(D_A4800018)($at) -/* 004968 80003D68 0C000FCB */ jal send_mesg -/* 00496C 80003D6C 24040028 */ li $a0, 40 -/* 004970 80003D70 1220001F */ beqz $s1, NoMoreRcpInts -/* 004974 80003D74 00000000 */ nop + // Test for si interrupt + andi $t1, $s1, MI_INTR_SI + beqz $t1, pi + lui $at, %hi(PHYS_TO_K1(SI_STATUS_REG)) + // Mask out si interrupt + andi $s1, $s1, (MI_INTR_SP | MI_INTR_AI | MI_INTR_VI | MI_INTR_PI | MI_INTR_DP) + // Clear interrupt + sw $zero, %lo(PHYS_TO_K1(SI_STATUS_REG))($at) + // Post si event message + jal send_mesg + li $a0, OS_EVENT_SI*8 + beqz $s1, NoMoreRcpInts + nop + +/** + * Parallel Interface (PI) Interrupt + */ pi: -/* 004978 80003D78 32290010 */ andi $t1, $s1, 0x10 -/* 00497C 80003D7C 11200013 */ beqz $t1, dp -/* 004980 80003D80 00000000 */ nop -/* 004984 80003D84 24090002 */ li $t1, 2 -/* 004988 80003D88 3C01A460 */ lui $at, %hi(D_A4600010) # $at, 0xa460 -/* 00498C 80003D8C AC290010 */ sw $t1, %lo(D_A4600010)($at) -/* 004990 80003D90 3C098001 */ lui $t1, %hi(__osPiIntTable) # $t1, 0x8001 -/* 004994 80003D94 2529AD38 */ addiu $t1, %lo(__osPiIntTable) # addiu $t1, $t1, -0x52c8 -/* 004998 80003D98 8D2A0000 */ lw $t2, ($t1) -/* 00499C 80003D9C 3231002F */ andi $s1, $s1, 0x2f -/* 0049A0 80003DA0 11400006 */ beqz $t2, .L80003DBC -/* 0049A4 80003DA4 00000000 */ nop -/* 0049A8 80003DA8 8D3D0004 */ lw $sp, 4($t1) -/* 0049AC 80003DAC 0140F809 */ jalr $t2 -/* 0049B0 80003DB0 00402025 */ move $a0, $v0 -/* 0049B4 80003DB4 14400003 */ bnez $v0, .L80003DC4 -/* 0049B8 80003DB8 00000000 */ nop -.L80003DBC: -/* 0049BC 80003DBC 0C000FCB */ jal send_mesg -/* 0049C0 80003DC0 24040040 */ li $a0, 64 -.L80003DC4: -/* 0049C4 80003DC4 1220000A */ beqz $s1, NoMoreRcpInts -/* 0049C8 80003DC8 00000000 */ nop + // Test for pi interrupt + andi $t1, $s1, MI_INTR_PI + beqz $t1, dp + nop + // Clear interrupt + li $t1, PI_STATUS_CLR_INTR + lui $at, %hi(PHYS_TO_K1(PI_STATUS_REG)) + sw $t1, %lo(PHYS_TO_K1(PI_STATUS_REG))($at) + // Load pi callback + lui $t1, %hi(__osPiIntTable) + addiu $t1, %lo(__osPiIntTable) + lw $t2, HWINT_CALLBACK($t1) + // Mask out pi interrupt + andi $s1, $s1, (MI_INTR_SP | MI_INTR_SI | MI_INTR_AI | MI_INTR_VI | MI_INTR_DP) + // Skip callback if NULL + beqz $t2, no_pi_callback + nop + // Set up a stack and run the callback + lw $sp, HWINT_SP($t1) + jalr $t2 + move $a0, $v0 + // If the callback returns non-zero, don't post a pi event message + bnez $v0, skip_pi_mesg + nop +no_pi_callback: + // Post pi event message + jal send_mesg + li $a0, OS_EVENT_PI*8 +skip_pi_mesg: + beqz $s1, NoMoreRcpInts + nop + +/** + * Display Processor (DP) Interrupt + */ dp: -/* 0049CC 80003DCC 32290020 */ andi $t1, $s1, 0x20 -/* 0049D0 80003DD0 11200007 */ beqz $t1, NoMoreRcpInts -/* 0049D4 80003DD4 00000000 */ nop -/* 0049D8 80003DD8 24090800 */ li $t1, 2048 -/* 0049DC 80003DDC 3C01A430 */ lui $at, 0xa430 -/* 0049E0 80003DE0 3231001F */ andi $s1, $s1, 0x1f -/* 0049E4 80003DE4 AC290000 */ sw $t1, ($at) -/* 0049E8 80003DE8 0C000FCB */ jal send_mesg -/* 0049EC 80003DEC 24040048 */ li $a0, 72 + // Test for dp interrupt + andi $t1, $s1, MI_INTR_DP + beqz $t1, NoMoreRcpInts + nop + // Clear dp interrupt + li $t1, MI_CLR_DP_INTR + lui $at, %hi(PHYS_TO_K1(MI_INIT_MODE_REG)) + // Mask out dp interrupt + andi $s1, $s1, (MI_INTR_SP | MI_INTR_SI | MI_INTR_AI | MI_INTR_VI | MI_INTR_PI) + sw $t1, %lo(PHYS_TO_K1(MI_INIT_MODE_REG))($at) + // Post dp event message + jal send_mesg + li $a0, OS_EVENT_DP*8 + NoMoreRcpInts: -/* 0049F0 80003DF0 2401FBFF */ li $at, -1025 -/* 0049F4 80003DF4 1000FF7A */ b next_interrupt -/* 0049F8 80003DF8 02018024 */ and $s0, $s0, $at + // Mask out interrupt and continue + li $at, ~CAUSE_IP3 + b next_interrupt + and $s0, $s0, $at + +/** + * IP5/PreNMI Interrupt + * Reset button has been pressed + */ prenmi: -/* 0049FC 80003DFC 8F5B0118 */ lw $k1, 0x118($k0) -/* 004A00 80003E00 2401EFFF */ li $at, -4097 -/* 004A04 80003E04 3C098001 */ lui $t1, %hi(__osShutdown) # $t1, 0x8001 -/* 004A08 80003E08 0361D824 */ and $k1, $k1, $at -/* 004A0C 80003E0C AF5B0118 */ sw $k1, 0x118($k0) -/* 004A10 80003E10 2529ACFC */ addiu $t1, %lo(__osShutdown) # addiu $t1, $t1, -0x5304 -/* 004A14 80003E14 8D2A0000 */ lw $t2, ($t1) -/* 004A18 80003E18 11400003 */ beqz $t2, firstnmi -/* 004A1C 80003E1C 2401EFFF */ li $at, -4097 -/* 004A20 80003E20 10000023 */ b redispatch -/* 004A24 80003E24 02018024 */ and $s0, $s0, $at + // Disable IP5/PreNMI interrupt for the previously running thread + lw $k1, THREAD_SR($k0) + li $at, ~SR_IBIT5 + lui $t1, %hi(__osShutdown) + and $k1, $k1, $at + sw $k1, THREAD_SR($k0) + addiu $t1, %lo(__osShutdown) + // Test __osShutdown for first PreNMI event + lw $t2, ($t1) + beqz $t2, firstnmi + li $at, ~CAUSE_IP5 + // Mask out interrupt and redispatch immediately + b redispatch + and $s0, $s0, $at + firstnmi: -/* 004A28 80003E28 240A0001 */ li $t2, 1 -/* 004A2C 80003E2C AD2A0000 */ sw $t2, ($t1) -/* 004A30 80003E30 0C000FCB */ jal send_mesg -/* 004A34 80003E34 24040070 */ li $a0, 112 -/* 004A38 80003E38 3C0A8001 */ lui $t2, %hi(__osRunQueue) # $t2, 0x8001 -/* 004A3C 80003E3C 8D4AAD48 */ lw $t2, %lo(__osRunQueue)($t2) -/* 004A40 80003E40 2401EFFF */ li $at, -4097 -/* 004A44 80003E44 02018024 */ and $s0, $s0, $at -/* 004A48 80003E48 8D5B0118 */ lw $k1, 0x118($t2) -/* 004A4C 80003E4C 0361D824 */ and $k1, $k1, $at -/* 004A50 80003E50 10000017 */ b redispatch -/* 004A54 80003E54 AD5B0118 */ sw $k1, 0x118($t2) + // Set __osShutdown + li $t2, 1 + sw $t2, ($t1) + // Post a PreNMI event message + jal send_mesg + li $a0, OS_EVENT_PRENMI*8 + // Mask out and disable IP5/PreNMI interrupt for the highest priority thread + lui $t2, %hi(__osRunQueue) + lw $t2, %lo(__osRunQueue)($t2) + li $at, ~SR_IBIT5 + and $s0, $s0, $at + lw $k1, THREAD_SR($t2) + and $k1, $k1, $at + // Redispatch immediately + b redispatch + sw $k1, THREAD_SR($t2) + sw2: -/* 004A58 80003E58 2401FDFF */ li $at, -513 -/* 004A5C 80003E5C 01014024 */ and $t0, $t0, $at -/* 004A60 80003E60 40886800 */ mtc0 $t0, $13 -/* 004A64 80003E64 0C000FCB */ jal send_mesg -/* 004A68 80003E68 24040008 */ li $a0, 8 -/* 004A6C 80003E6C 2401FDFF */ li $at, -513 -/* 004A70 80003E70 1000FF5B */ b next_interrupt -/* 004A74 80003E74 02018024 */ and $s0, $s0, $at + // Mask out interrupt + li $at, ~CAUSE_SW2 + and $t0, $t0, $at + mtc0 $t0, C0_CAUSE + // Post sw2 event message + jal send_mesg + li $a0, OS_EVENT_SW2*8 + li $at, ~CAUSE_SW2 + // Mask out interrupt and continue + b next_interrupt + and $s0, $s0, $at + sw1: -/* 004A78 80003E78 2401FEFF */ li $at, -257 -/* 004A7C 80003E7C 01014024 */ and $t0, $t0, $at -/* 004A80 80003E80 40886800 */ mtc0 $t0, $13 -/* 004A84 80003E84 0C000FCB */ jal send_mesg -/* 004A88 80003E88 24040000 */ li $a0, 0 -/* 004A8C 80003E8C 2401FEFF */ li $at, -257 -/* 004A90 80003E90 1000FF53 */ b next_interrupt -/* 004A94 80003E94 02018024 */ and $s0, $s0, $at + // Mask out interrupt + li $at, ~CAUSE_SW1 + and $t0, $t0, $at + mtc0 $t0, C0_CAUSE + // Post sw1 event message + jal send_mesg + li $a0, OS_EVENT_SW1*8 + li $at, ~CAUSE_SW1 + // Mask out interrupt and continue + b next_interrupt + and $s0, $s0, $at + handle_break: -/* 004A98 80003E98 24090001 */ li $t1, 1 -/* 004A9C 80003E9C A7490012 */ sh $t1, 0x12($k0) -/* 004AA0 80003EA0 0C000FCB */ jal send_mesg -/* 004AA4 80003EA4 24040050 */ li $a0, 80 -/* 004AA8 80003EA8 10000001 */ b redispatch -/* 004AAC 80003EAC 00000000 */ nop + // Set last thread as having hit a break exception + li $t1, OS_FLAG_CPU_BREAK + sh $t1, THREAD_FLAGS($k0) + // Post a cpu break event message + jal send_mesg + li $a0, OS_EVENT_CPU_BREAK*8 + // Redispatch + b redispatch + nop + redispatch: -/* 004AB0 80003EB0 3C0A8001 */ lui $t2, %hi(__osRunQueue) # $t2, 0x8001 -/* 004AB4 80003EB4 8D4AAD48 */ lw $t2, %lo(__osRunQueue)($t2) -/* 004AB8 80003EB8 8F490004 */ lw $t1, 4($k0) -/* 004ABC 80003EBC 8D4B0004 */ lw $t3, 4($t2) -/* 004AC0 80003EC0 012B082A */ slt $at, $t1, $t3 -/* 004AC4 80003EC4 10200007 */ beqz $at, enqueueRunning -/* 004AC8 80003EC8 00000000 */ nop -/* 004ACC 80003ECC 3C048001 */ lui $a0, %hi(__osRunQueue) # $a0, 0x8001 -/* 004AD0 80003ED0 03402825 */ move $a1, $k0 -/* 004AD4 80003ED4 0C001045 */ jal __osEnqueueThread -/* 004AD8 80003ED8 2484AD48 */ addiu $a0, %lo(__osRunQueue) # addiu $a0, $a0, -0x52b8 -/* 004ADC 80003EDC 0800105D */ j __osDispatchThread -/* 004AE0 80003EE0 00000000 */ nop + lui $t2, %hi(__osRunQueue) + lw $t2, %lo(__osRunQueue)($t2) + // Get priority of previously running thread + lw $t1, THREAD_PRI($k0) + // Get highest priority from waiting threads + lw $t3, THREAD_PRI($t2) + slt $at, $t1, $t3 + beqz $at, enqueueRunning + nop + // The previously running thread is no longer the highest priority, + // enqueue it to the run queue to wait its turn again + lui $a0, %hi(__osRunQueue) + move $a1, $k0 + jal __osEnqueueThread + addiu $a0, $a0, %lo(__osRunQueue) + j __osDispatchThread + nop +/** + * Resume the previously running thread by placing it at the top of + * the run queue and dispatching it + */ enqueueRunning: -/* 004AE4 80003EE4 3C098001 */ lui $t1, %hi(__osRunQueue) # $t1, 0x8001 -/* 004AE8 80003EE8 2529AD48 */ addiu $t1, %lo(__osRunQueue) # addiu $t1, $t1, -0x52b8 -/* 004AEC 80003EEC 8D2A0000 */ lw $t2, ($t1) -/* 004AF0 80003EF0 AF4A0000 */ sw $t2, ($k0) -/* 004AF4 80003EF4 0800105D */ j __osDispatchThread -/* 004AF8 80003EF8 AD3A0000 */ sw $k0, ($t1) + lui $t1, %hi(__osRunQueue) + addiu $t1, $t1, %lo(__osRunQueue) + lw $t2, ($t1) + sw $t2, THREAD_NEXT($k0) + j __osDispatchThread + sw $k0, ($t1) +/** + * Unhandled exceptions & interrupts end up here, + * trap to software by posting a fault message + */ panic: -/* 004AFC 80003EFC 3C018001 */ lui $at, %hi(__osFaultedThread) # $at, 0x8001 -/* 004B00 80003F00 AC3AAD54 */ sw $k0, %lo(__osFaultedThread)($at) -/* 004B04 80003F04 24090001 */ li $t1, 1 -/* 004B08 80003F08 A7490010 */ sh $t1, 0x10($k0) -/* 004B0C 80003F0C 24090002 */ li $t1, 2 -/* 004B10 80003F10 A7490012 */ sh $t1, 0x12($k0) -/* 004B14 80003F14 400A4000 */ mfc0 $t2, $8 -/* 004B18 80003F18 AF4A0124 */ sw $t2, 0x124($k0) -/* 004B1C 80003F1C 0C000FCB */ jal send_mesg -/* 004B20 80003F20 24040060 */ li $a0, 96 -/* 004B24 80003F24 0800105D */ j __osDispatchThread -/* 004B28 80003F28 00000000 */ nop + // Mark the thread as having faulted + lui $at, %hi(__osFaultedThread) + sw $k0, %lo(__osFaultedThread)($at) + li $t1, OS_STATE_STOPPED + sh $t1, THREAD_STATE($k0) + li $t1, OS_FLAG_FAULT + sh $t1, THREAD_FLAGS($k0) + // Save C0_BADVADDR + mfc0 $t2, C0_BADVADDR + sw $t2, THREAD_BADVADDR($k0) + // Post the fault message + jal send_mesg + li $a0, OS_EVENT_FAULT*8 + // Dispatch next thread + j __osDispatchThread + nop -glabel send_mesg -/* 004B2C 80003F2C 3C0A8001 */ lui $t2, %hi(__osEventStateTab) # $t2, 0x8001 -/* 004B30 80003F30 254A5A40 */ addiu $t2, %lo(__osEventStateTab) # addiu $t2, $t2, 0x5a40 -/* 004B34 80003F34 01445021 */ addu $t2, $t2, $a0 -/* 004B38 80003F38 8D490000 */ lw $t1, ($t2) -/* 004B3C 80003F3C 03E09025 */ move $s2, $ra -/* 004B40 80003F40 11200025 */ beqz $t1, send_done -/* 004B44 80003F44 00000000 */ nop -/* 004B48 80003F48 8D2B0008 */ lw $t3, 8($t1) -/* 004B4C 80003F4C 8D2C0010 */ lw $t4, 0x10($t1) -/* 004B50 80003F50 016C082A */ slt $at, $t3, $t4 -/* 004B54 80003F54 10200020 */ beqz $at, send_done -/* 004B58 80003F58 00000000 */ nop -/* 004B5C 80003F5C 8D2D000C */ lw $t5, 0xc($t1) -/* 004B60 80003F60 01AB6821 */ addu $t5, $t5, $t3 -/* 004B64 80003F64 01AC001A */ div $zero, $t5, $t4 -/* 004B68 80003F68 15800002 */ bnez $t4, .L80003F74 -/* 004B6C 80003F6C 00000000 */ nop -/* 004B70 80003F70 0007000D */ break 7 -.L80003F74: -/* 004B74 80003F74 2401FFFF */ li $at, -1 -/* 004B78 80003F78 15810004 */ bne $t4, $at, .L80003F8C -/* 004B7C 80003F7C 3C018000 */ lui $at, 0x8000 -/* 004B80 80003F80 15A10002 */ bne $t5, $at, .L80003F8C -/* 004B84 80003F84 00000000 */ nop -/* 004B88 80003F88 0006000D */ break 6 -.L80003F8C: -/* 004B8C 80003F8C 8D2C0014 */ lw $t4, 0x14($t1) -/* 004B90 80003F90 00006810 */ mfhi $t5 -/* 004B94 80003F94 000D6880 */ sll $t5, $t5, 2 -/* 004B98 80003F98 018D6021 */ addu $t4, $t4, $t5 -/* 004B9C 80003F9C 8D4D0004 */ lw $t5, 4($t2) -/* 004BA0 80003FA0 256A0001 */ addiu $t2, $t3, 1 -/* 004BA4 80003FA4 AD8D0000 */ sw $t5, ($t4) -/* 004BA8 80003FA8 AD2A0008 */ sw $t2, 8($t1) -/* 004BAC 80003FAC 8D2A0000 */ lw $t2, ($t1) -/* 004BB0 80003FB0 8D4B0000 */ lw $t3, ($t2) -/* 004BB4 80003FB4 11600008 */ beqz $t3, send_done -/* 004BB8 80003FB8 00000000 */ nop -/* 004BBC 80003FBC 0C001057 */ jal __osPopThread -/* 004BC0 80003FC0 01202025 */ move $a0, $t1 -/* 004BC4 80003FC4 00405025 */ move $t2, $v0 -/* 004BC8 80003FC8 3C048001 */ lui $a0, %hi(__osRunQueue) # $a0, 0x8001 -/* 004BCC 80003FCC 01402825 */ move $a1, $t2 -/* 004BD0 80003FD0 0C001045 */ jal __osEnqueueThread -/* 004BD4 80003FD4 2484AD48 */ addiu $a0, %lo(__osRunQueue) # addiu $a0, $a0, -0x52b8 +/** + * Handles posting event messages to the listening message queue, if there is one + */ +send_mesg: + // Load pointer to listening message queue + lui $t2, %hi(__osEventStateTab) + addiu $t2, %lo(__osEventStateTab) + addu $t2, $t2, $a0 + lw $t1, ($t2) + // Save return address + move $s2, $ra + // If there is no listening message queue, done + beqz $t1, send_done + nop + // Test if the message queue is full, if so don't post the message + lw $t3, MQ_VALIDCOUNT($t1) + lw $t4, MQ_MSGCOUNT($t1) + slt $at, $t3, $t4 + beqz $at, send_done + nop + // Add validcount to first and modulo with msgcount + lw $t5, MQ_FIRST($t1) + addu $t5, $t5, $t3 + // Modulo + div $zero, $t5, $t4 + bnez $t4, 1f + nop + break 7 // div0 +1: + li $at, -1 + bne $t4, $at, 2f + li $at, -0x80000000 + bne $t5, $at, 2f + nop + break 6 // overflow +2: + // End Modulo + lw $t4, MQ_MSG($t1) + mfhi $t5 + sll $t5, $t5, 2 + addu $t4, $t4, $t5 + // Fetch the message to post + lw $t5, 4($t2) + addiu $t2, $t3, 1 + // Post the message to the message queue + sw $t5, ($t4) + // Increment the validCount + sw $t2, MQ_VALIDCOUNT($t1) + // If there was a thread blocked on this message queue, + // wake it up + lw $t2, MQ_MTQUEUE($t1) + lw $t3, ($t2) + beqz $t3, send_done + nop + jal __osPopThread + move $a0, $t1 + move $t2, $v0 + lui $a0, %hi(__osRunQueue) + move $a1, $t2 + jal __osEnqueueThread + addiu $a0, %lo(__osRunQueue) send_done: -/* 004BD8 80003FD8 02400008 */ jr $s2 -/* 004BDC 80003FDC 00000000 */ nop + jr $s2 + nop + +/** + * Handle coprocessor unusable exception + */ handle_CpU: -/* 004BE0 80003FE0 3C013000 */ lui $at, 0x3000 -/* 004BE4 80003FE4 01014824 */ and $t1, $t0, $at -/* 004BE8 80003FE8 00094F02 */ srl $t1, $t1, 0x1c -/* 004BEC 80003FEC 240A0001 */ li $t2, 1 -/* 004BF0 80003FF0 152AFFC2 */ bne $t1, $t2, panic -/* 004BF4 80003FF4 00000000 */ nop -/* 004BF8 80003FF8 8F5B0118 */ lw $k1, 0x118($k0) -/* 004BFC 80003FFC 3C012000 */ lui $at, 0x2000 -glabel func_80004000 -/* 004C00 80004000 24090001 */ li $t1, 1 -/* 004C04 80004004 0361D825 */ or $k1, $k1, $at -/* 004C08 80004008 AF490018 */ sw $t1, 0x18($k0) -/* 004C0C 8000400C 1000FFB5 */ b enqueueRunning -/* 004C10 80004010 AF5B0118 */ sw $k1, 0x118($k0) -glabel __osEnqueueAndYield -/* 004C14 80004014 3C058001 */ lui $a1, %hi(__osRunningThread) # $a1, 0x8001 -/* 004C18 80004018 8CA5AD50 */ lw $a1, %lo(__osRunningThread)($a1) -/* 004C1C 8000401C 40086000 */ mfc0 $t0, $12 -/* 004C20 80004020 8CBB0018 */ lw $k1, 0x18($a1) -/* 004C24 80004024 35080002 */ ori $t0, $t0, 2 -/* 004C28 80004028 ACA80118 */ sw $t0, 0x118($a1) -/* 004C2C 8000402C FCB00098 */ sd $s0, 0x98($a1) -/* 004C30 80004030 FCB100A0 */ sd $s1, 0xa0($a1) -/* 004C34 80004034 FCB200A8 */ sd $s2, 0xa8($a1) -/* 004C38 80004038 FCB300B0 */ sd $s3, 0xb0($a1) -/* 004C3C 8000403C FCB400B8 */ sd $s4, 0xb8($a1) -/* 004C40 80004040 FCB500C0 */ sd $s5, 0xc0($a1) -/* 004C44 80004044 FCB600C8 */ sd $s6, 0xc8($a1) -/* 004C48 80004048 FCB700D0 */ sd $s7, 0xd0($a1) -/* 004C4C 8000404C FCBC00E8 */ sd $gp, 0xe8($a1) -/* 004C50 80004050 FCBD00F0 */ sd $sp, 0xf0($a1) -/* 004C54 80004054 FCBE00F8 */ sd $fp, 0xf8($a1) -/* 004C58 80004058 FCBF0100 */ sd $ra, 0x100($a1) -/* 004C5C 8000405C 13600009 */ beqz $k1, .L80004084 -/* 004C60 80004060 ACBF011C */ sw $ra, 0x11c($a1) -/* 004C64 80004064 445BF800 */ cfc1 $k1, $31 -/* 004C68 80004068 F4B40180 */ sdc1 $f20, 0x180($a1) -/* 004C6C 8000406C F4B60188 */ sdc1 $f22, 0x188($a1) -/* 004C70 80004070 F4B80190 */ sdc1 $f24, 0x190($a1) -/* 004C74 80004074 F4BA0198 */ sdc1 $f26, 0x198($a1) -/* 004C78 80004078 F4BC01A0 */ sdc1 $f28, 0x1a0($a1) -/* 004C7C 8000407C F4BE01A8 */ sdc1 $f30, 0x1a8($a1) -/* 004C80 80004080 ACBB012C */ sw $k1, 0x12c($a1) -.L80004084: -/* 004C84 80004084 8CBB0118 */ lw $k1, 0x118($a1) -/* 004C88 80004088 3369FF00 */ andi $t1, $k1, 0xff00 -/* 004C8C 8000408C 1120000D */ beqz $t1, .L800040C4 -/* 004C90 80004090 00000000 */ nop -/* 004C94 80004094 3C088001 */ lui $t0, %hi(__OSGlobalIntMask) # $t0, 0x8001 -/* 004C98 80004098 2508AD00 */ addiu $t0, %lo(__OSGlobalIntMask) # addiu $t0, $t0, -0x5300 -/* 004C9C 8000409C 8D080000 */ lw $t0, ($t0) -/* 004CA0 800040A0 2401FFFF */ li $at, -1 -/* 004CA4 800040A4 01014026 */ xor $t0, $t0, $at -/* 004CA8 800040A8 3C01FFFF */ lui $at, (0xFFFF00FF >> 16) # lui $at, 0xffff -/* 004CAC 800040AC 3108FF00 */ andi $t0, $t0, 0xff00 -/* 004CB0 800040B0 342100FF */ ori $at, (0xFFFF00FF & 0xFFFF) # ori $at, $at, 0xff -/* 004CB4 800040B4 01284825 */ or $t1, $t1, $t0 -/* 004CB8 800040B8 0361D824 */ and $k1, $k1, $at -/* 004CBC 800040BC 0369D825 */ or $k1, $k1, $t1 -/* 004CC0 800040C0 ACBB0118 */ sw $k1, 0x118($a1) -.L800040C4: -/* 004CC4 800040C4 3C1BA430 */ lui $k1, %hi(D_A430000C) # $k1, 0xa430 -/* 004CC8 800040C8 8F7B000C */ lw $k1, %lo(D_A430000C)($k1) -/* 004CCC 800040CC 1360000B */ beqz $k1, .L800040FC -/* 004CD0 800040D0 00000000 */ nop -/* 004CD4 800040D4 3C1A8001 */ lui $k0, %hi(__OSGlobalIntMask) # $k0, 0x8001 -/* 004CD8 800040D8 275AAD00 */ addiu $k0, %lo(__OSGlobalIntMask) # addiu $k0, $k0, -0x5300 -/* 004CDC 800040DC 8F5A0000 */ lw $k0, ($k0) -/* 004CE0 800040E0 8CA80128 */ lw $t0, 0x128($a1) -/* 004CE4 800040E4 2401FFFF */ li $at, -1 -/* 004CE8 800040E8 001AD402 */ srl $k0, $k0, 0x10 -/* 004CEC 800040EC 0341D026 */ xor $k0, $k0, $at -/* 004CF0 800040F0 335A003F */ andi $k0, $k0, 0x3f -/* 004CF4 800040F4 0348D024 */ and $k0, $k0, $t0 -/* 004CF8 800040F8 037AD825 */ or $k1, $k1, $k0 -.L800040FC: -/* 004CFC 800040FC 10800003 */ beqz $a0, .L8000410C -/* 004D00 80004100 ACBB0128 */ sw $k1, 0x128($a1) -/* 004D04 80004104 0C001045 */ jal __osEnqueueThread -/* 004D08 80004108 00000000 */ nop -.L8000410C: -/* 004D0C 8000410C 0800105D */ j __osDispatchThread -/* 004D10 80004110 00000000 */ nop + li $at, CAUSE_CEMASK + and $t1, $t0, $at + srl $t1, $t1, CAUSE_CESHIFT + li $t2, 1 // if not coprocessor 1, panic + bne $t1, $t2, panic + nop + // Mark cop1 as usable for previous thread + lw $k1, THREAD_SR($k0) + li $at, SR_CU1 + li $t1, 1 + or $k1, $k1, $at + sw $t1, THREAD_FP($k0) + b enqueueRunning + sw $k1, THREAD_SR($k0) +END(__osException) -glabel __osEnqueueThread -/* 004D14 80004114 8C980000 */ lw $t8, ($a0) -/* 004D18 80004118 8CAF0004 */ lw $t7, 4($a1) -/* 004D1C 8000411C 0080C825 */ move $t9, $a0 -/* 004D20 80004120 8F0E0004 */ lw $t6, 4($t8) -/* 004D24 80004124 01CF082A */ slt $at, $t6, $t7 -/* 004D28 80004128 14200007 */ bnez $at, .L80004148 -/* 004D2C 8000412C 00000000 */ nop -.L80004130: -/* 004D30 80004130 0300C825 */ move $t9, $t8 -/* 004D34 80004134 8F180000 */ lw $t8, ($t8) -/* 004D38 80004138 8F0E0004 */ lw $t6, 4($t8) -/* 004D3C 8000413C 01CF082A */ slt $at, $t6, $t7 -/* 004D40 80004140 1020FFFB */ beqz $at, .L80004130 -/* 004D44 80004144 00000000 */ nop -.L80004148: -/* 004D48 80004148 8F380000 */ lw $t8, ($t9) -/* 004D4C 8000414C ACB80000 */ sw $t8, ($a1) -/* 004D50 80004150 AF250000 */ sw $a1, ($t9) -/* 004D54 80004154 03E00008 */ jr $ra -/* 004D58 80004158 ACA40008 */ sw $a0, 8($a1) +/** + * void __osEnqueueAndYield(OSThread** threadQueue); + * + * Voluntary thread yielding. + * Enqueues the currently running thread to the top of the + * thread queue `threadQueue` and yields to the highest priority + * unblocked runnable thread. + */ +LEAF(__osEnqueueAndYield) + lui $a1, %hi(__osRunningThread) + lw $a1, %lo(__osRunningThread)($a1) + // Save SR + mfc0 $t0, C0_SR + lw $k1, THREAD_FP($a1) + ori $t0, $t0, SR_EXL + sw $t0, THREAD_SR($a1) + // Save callee-saved registers + sd $s0, THREAD_S0($a1) + sd $s1, THREAD_S1($a1) + sd $s2, THREAD_S2($a1) + sd $s3, THREAD_S3($a1) + sd $s4, THREAD_S4($a1) + sd $s5, THREAD_S5($a1) + sd $s6, THREAD_S6($a1) + sd $s7, THREAD_S7($a1) + sd $gp, THREAD_GP($a1) + sd $sp, THREAD_SP($a1) + sd $fp, THREAD_S8($a1) + sd $ra, THREAD_RA($a1) + // Save FPU callee-saved registers if the current thread has used the FPU + beqz $k1, 1f + sw $ra, THREAD_PC($a1) + cfc1 $k1, C1_FPCSR + sdc1 $f20, THREAD_FP20($a1) + sdc1 $f22, THREAD_FP22($a1) + sdc1 $f24, THREAD_FP24($a1) + sdc1 $f26, THREAD_FP26($a1) + sdc1 $f28, THREAD_FP28($a1) + sdc1 $f30, THREAD_FP30($a1) + sw $k1, THREAD_FPCSR($a1) +1: + lw $k1, THREAD_SR($a1) + andi $t1, $k1, SR_IMASK + beqz $t1, 2f + nop + // This code does the same thing as the block just above the `savercp` label. + // See the comment there for more about this. + lui $t0, %hi(__OSGlobalIntMask) + addiu $t0, %lo(__OSGlobalIntMask) + lw $t0, ($t0) + li $at, ~0 + xor $t0, $t0, $at + lui $at, ((~SR_IMASK) >> 0x10) & 0xFFFF + andi $t0, $t0, SR_IMASK + ori $at, (~SR_IMASK) & 0xFFFF + or $t1, $t1, $t0 + and $k1, $k1, $at + or $k1, $k1, $t1 + sw $k1, THREAD_SR($a1) +2: + lui $k1, %hi(PHYS_TO_K1(MI_INTR_MASK_REG)) + lw $k1, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))($k1) + beqz $k1, 3f + nop + // This code does the same thing as the block just below the `savercp` label. + // See the comment there for more about this. + lui $k0, %hi(__OSGlobalIntMask) + addiu $k0, %lo(__OSGlobalIntMask) + lw $k0, ($k0) + lw $t0, THREAD_RCP($a1) + li $at, ~0 + srl $k0, $k0, RCP_IMASKSHIFT + xor $k0, $k0, $at + andi $k0, $k0, (RCP_IMASK >> RCP_IMASKSHIFT) + and $k0, $k0, $t0 + or $k1, $k1, $k0 +3: + // If the specified thread queue is null, skip + // straight to dispatching + beqz $a0, no_enqueue + sw $k1, THREAD_RCP($a1) + jal __osEnqueueThread + nop +no_enqueue: + j __osDispatchThread + nop +END(__osEnqueueAndYield) -glabel __osPopThread -/* 004D5C 8000415C 8C820000 */ lw $v0, ($a0) -/* 004D60 80004160 8C590000 */ lw $t9, ($v0) -/* 004D64 80004164 03E00008 */ jr $ra -/* 004D68 80004168 AC990000 */ sw $t9, ($a0) +/** + * void __osEnqueueThread(OSThread** threadQueue, OSThread* thread); + * + * Enqueues `thread` to the thread queue `threadQueue`, inserted by priority + */ +LEAF(__osEnqueueThread) + lw $t8, ($a0) + lw $t7, THREAD_PRI($a1) + move $t9, $a0 + lw $t6, THREAD_PRI($t8) + slt $at, $t6, $t7 + // If the current highest priority thread is a lower priority than + // the new thread, skip searching the queue + bnez $at, 2f + nop +1: + // Search the queue for the position to insert the thread to maintain + // ordering by priority + move $t9, $t8 + lw $t8, THREAD_NEXT($t8) + lw $t6, THREAD_PRI($t8) + slt $at, $t6, $t7 + beqz $at, 1b + nop +2: + // Insert the thread into the queue + lw $t8, ($t9) + sw $t8, THREAD_NEXT($a1) + sw $a1, ($t9) + jr $ra + sw $a0, THREAD_QUEUE($a1) +END(__osEnqueueThread) -glabel __osNop -/* 004D6C 8000416C 03E00008 */ jr $ra -/* 004D70 80004170 00000000 */ nop +/** + * OSThread* __osPopThread(OSThread** threadQueue); + * + * Pops the highest priority thread from the top of the + * thread queue `threadQueue` and returns it + */ +LEAF(__osPopThread) + lw $v0, ($a0) + lw $t9, THREAD_NEXT($v0) + jr $ra + sw $t9, ($a0) +END(__osPopThread) -glabel __osDispatchThread -/* 004D74 80004174 3C048001 */ lui $a0, %hi(__osRunQueue) # $a0, 0x8001 -/* 004D78 80004178 0C001057 */ jal __osPopThread -/* 004D7C 8000417C 2484AD48 */ addiu $a0, %lo(__osRunQueue) # addiu $a0, $a0, -0x52b8 -/* 004D80 80004180 3C018001 */ lui $at, %hi(__osRunningThread) # $at, 0x8001 -/* 004D84 80004184 AC22AD50 */ sw $v0, %lo(__osRunningThread)($at) -/* 004D88 80004188 24080004 */ li $t0, 4 -/* 004D8C 8000418C A4480010 */ sh $t0, 0x10($v0) -/* 004D90 80004190 0040D025 */ move $k0, $v0 -/* 004D94 80004194 3C088001 */ lui $t0, %hi(__OSGlobalIntMask) # $t0, 0x8001 -/* 004D98 80004198 8F5B0118 */ lw $k1, 0x118($k0) -/* 004D9C 8000419C 2508AD00 */ addiu $t0, %lo(__OSGlobalIntMask) # addiu $t0, $t0, -0x5300 -/* 004DA0 800041A0 8D080000 */ lw $t0, ($t0) -/* 004DA4 800041A4 3C01FFFF */ lui $at, (0xFFFF00FF >> 16) # lui $at, 0xffff -/* 004DA8 800041A8 3369FF00 */ andi $t1, $k1, 0xff00 -/* 004DAC 800041AC 342100FF */ ori $at, (0xFFFF00FF & 0xFFFF) # ori $at, $at, 0xff -/* 004DB0 800041B0 3108FF00 */ andi $t0, $t0, 0xff00 -/* 004DB4 800041B4 01284824 */ and $t1, $t1, $t0 -/* 004DB8 800041B8 0361D824 */ and $k1, $k1, $at -/* 004DBC 800041BC 0369D825 */ or $k1, $k1, $t1 -/* 004DC0 800041C0 409B6000 */ mtc0 $k1, $12 -/* 004DC4 800041C4 DF5B0108 */ ld $k1, 0x108($k0) -/* 004DC8 800041C8 DF410020 */ ld $at, 0x20($k0) -/* 004DCC 800041CC DF420028 */ ld $v0, 0x28($k0) -/* 004DD0 800041D0 03600013 */ mtlo $k1 -/* 004DD4 800041D4 DF5B0110 */ ld $k1, 0x110($k0) -/* 004DD8 800041D8 DF430030 */ ld $v1, 0x30($k0) -/* 004DDC 800041DC DF440038 */ ld $a0, 0x38($k0) -/* 004DE0 800041E0 DF450040 */ ld $a1, 0x40($k0) -/* 004DE4 800041E4 DF460048 */ ld $a2, 0x48($k0) -/* 004DE8 800041E8 DF470050 */ ld $a3, 0x50($k0) -/* 004DEC 800041EC DF480058 */ ld $t0, 0x58($k0) -/* 004DF0 800041F0 DF490060 */ ld $t1, 0x60($k0) -/* 004DF4 800041F4 DF4A0068 */ ld $t2, 0x68($k0) -/* 004DF8 800041F8 DF4B0070 */ ld $t3, 0x70($k0) -/* 004DFC 800041FC DF4C0078 */ ld $t4, 0x78($k0) -/* 004E00 80004200 DF4D0080 */ ld $t5, 0x80($k0) -/* 004E04 80004204 DF4E0088 */ ld $t6, 0x88($k0) -/* 004E08 80004208 DF4F0090 */ ld $t7, 0x90($k0) -/* 004E0C 8000420C DF500098 */ ld $s0, 0x98($k0) -/* 004E10 80004210 DF5100A0 */ ld $s1, 0xa0($k0) -/* 004E14 80004214 DF5200A8 */ ld $s2, 0xa8($k0) -/* 004E18 80004218 DF5300B0 */ ld $s3, 0xb0($k0) -/* 004E1C 8000421C DF5400B8 */ ld $s4, 0xb8($k0) -/* 004E20 80004220 DF5500C0 */ ld $s5, 0xc0($k0) -/* 004E24 80004224 DF5600C8 */ ld $s6, 0xc8($k0) -/* 004E28 80004228 DF5700D0 */ ld $s7, 0xd0($k0) -/* 004E2C 8000422C DF5800D8 */ ld $t8, 0xd8($k0) -/* 004E30 80004230 DF5900E0 */ ld $t9, 0xe0($k0) -/* 004E34 80004234 DF5C00E8 */ ld $gp, 0xe8($k0) -/* 004E38 80004238 03600011 */ mthi $k1 -/* 004E3C 8000423C DF5D00F0 */ ld $sp, 0xf0($k0) -/* 004E40 80004240 DF5E00F8 */ ld $fp, 0xf8($k0) -/* 004E44 80004244 DF5F0100 */ ld $ra, 0x100($k0) -/* 004E48 80004248 8F5B011C */ lw $k1, 0x11c($k0) -/* 004E4C 8000424C 409B7000 */ mtc0 $k1, $14 -/* 004E50 80004250 8F5B0018 */ lw $k1, 0x18($k0) -/* 004E54 80004254 13600013 */ beqz $k1, .L800042A4 -/* 004E58 80004258 00000000 */ nop -/* 004E5C 8000425C 8F5B012C */ lw $k1, 0x12c($k0) -/* 004E60 80004260 44DBF800 */ ctc1 $k1, $31 -/* 004E64 80004264 D7400130 */ ldc1 $f0, 0x130($k0) -/* 004E68 80004268 D7420138 */ ldc1 $f2, 0x138($k0) -/* 004E6C 8000426C D7440140 */ ldc1 $f4, 0x140($k0) -/* 004E70 80004270 D7460148 */ ldc1 $f6, 0x148($k0) -/* 004E74 80004274 D7480150 */ ldc1 $f8, 0x150($k0) -/* 004E78 80004278 D74A0158 */ ldc1 $f10, 0x158($k0) -/* 004E7C 8000427C D74C0160 */ ldc1 $f12, 0x160($k0) -/* 004E80 80004280 D74E0168 */ ldc1 $f14, 0x168($k0) -/* 004E84 80004284 D7500170 */ ldc1 $f16, 0x170($k0) -/* 004E88 80004288 D7520178 */ ldc1 $f18, 0x178($k0) -/* 004E8C 8000428C D7540180 */ ldc1 $f20, 0x180($k0) -/* 004E90 80004290 D7560188 */ ldc1 $f22, 0x188($k0) -/* 004E94 80004294 D7580190 */ ldc1 $f24, 0x190($k0) -/* 004E98 80004298 D75A0198 */ ldc1 $f26, 0x198($k0) -/* 004E9C 8000429C D75C01A0 */ ldc1 $f28, 0x1a0($k0) -/* 004EA0 800042A0 D75E01A8 */ ldc1 $f30, 0x1a8($k0) -.L800042A4: -/* 004EA4 800042A4 8F5B0128 */ lw $k1, 0x128($k0) -/* 004EA8 800042A8 3C1A8001 */ lui $k0, %hi(__OSGlobalIntMask) # $k0, 0x8001 -/* 004EAC 800042AC 275AAD00 */ addiu $k0, %lo(__OSGlobalIntMask) # addiu $k0, $k0, -0x5300 -/* 004EB0 800042B0 8F5A0000 */ lw $k0, ($k0) -/* 004EB4 800042B4 001AD402 */ srl $k0, $k0, 0x10 -/* 004EB8 800042B8 037AD824 */ and $k1, $k1, $k0 -/* 004EBC 800042BC 001BD840 */ sll $k1, $k1, 1 -/* 004EC0 800042C0 3C1A8001 */ lui $k0, %hi(__osRcpImTable) # $k0, 0x8001 -/* 004EC4 800042C4 275A2160 */ addiu $k0, %lo(__osRcpImTable) # addiu $k0, $k0, 0x2160 -/* 004EC8 800042C8 037AD821 */ addu $k1, $k1, $k0 -/* 004ECC 800042CC 977B0000 */ lhu $k1, ($k1) -/* 004ED0 800042D0 3C1AA430 */ lui $k0, %hi(D_A430000C) # $k0, 0xa430 -/* 004ED4 800042D4 275A000C */ addiu $k0, %lo(D_A430000C) # addiu $k0, $k0, 0xc -/* 004ED8 800042D8 AF5B0000 */ sw $k1, ($k0) -/* 004EDC 800042DC 00000000 */ nop -/* 004EE0 800042E0 00000000 */ nop -/* 004EE4 800042E4 00000000 */ nop -/* 004EE8 800042E8 00000000 */ nop -/* 004EEC 800042EC 42000018 */ eret -glabel __osCleanupThread -/* 004EF0 800042F0 0C0010D0 */ jal osDestroyThread -/* 004EF4 800042F4 00002025 */ move $a0, $zero +LEAF(__osNop) + jr $ra + nop +END(__osNop) + +/** + * void __osDispatchThread(void); + * + * Dispatches the next thread to run after restoring the context + */ +LEAF(__osDispatchThread) + // Obtain highest priority thread from the active run queue + lui $a0, %hi(__osRunQueue) + jal __osPopThread + addiu $a0, $a0, %lo(__osRunQueue) + // Set thread as running + lui $at, %hi(__osRunningThread) + sw $v0, %lo(__osRunningThread)($at) + li $t0, OS_STATE_RUNNING + sh $t0, THREAD_STATE($v0) + // Restore SR, masking out any interrupts that are not also + // enabled in the global interrupt mask + move $k0, $v0 + lui $t0, %hi(__OSGlobalIntMask) + lw $k1, THREAD_SR($k0) + addiu $t0, %lo(__OSGlobalIntMask) + lw $t0, ($t0) + lui $at, ((~SR_IMASK) >> 0x10) & 0xFFFF + andi $t1, $k1, SR_IMASK + ori $at, (~SR_IMASK) & 0xFFFF + andi $t0, $t0, SR_IMASK + and $t1, $t1, $t0 + and $k1, $k1, $at + or $k1, $k1, $t1 + mtc0 $k1, C0_SR + // Restore GPRs + ld $k1, THREAD_LO($k0) + ld $at, THREAD_AT($k0) + ld $v0, THREAD_V0($k0) + mtlo $k1 + ld $k1, THREAD_HI($k0) + ld $v1, THREAD_V1($k0) + ld $a0, THREAD_A0($k0) + ld $a1, THREAD_A1($k0) + ld $a2, THREAD_A2($k0) + ld $a3, THREAD_A3($k0) + ld $t0, THREAD_T0($k0) + ld $t1, THREAD_T1($k0) + ld $t2, THREAD_T2($k0) + ld $t3, THREAD_T3($k0) + ld $t4, THREAD_T4($k0) + ld $t5, THREAD_T5($k0) + ld $t6, THREAD_T6($k0) + ld $t7, THREAD_T7($k0) + ld $s0, THREAD_S0($k0) + ld $s1, THREAD_S1($k0) + ld $s2, THREAD_S2($k0) + ld $s3, THREAD_S3($k0) + ld $s4, THREAD_S4($k0) + ld $s5, THREAD_S5($k0) + ld $s6, THREAD_S6($k0) + ld $s7, THREAD_S7($k0) + ld $t8, THREAD_T8($k0) + ld $t9, THREAD_T9($k0) + ld $gp, THREAD_GP($k0) + mthi $k1 + ld $sp, THREAD_SP($k0) + ld $fp, THREAD_S8($k0) + ld $ra, THREAD_RA($k0) + // Move thread pc to EPC so that eret will return execution to where the thread left off + lw $k1, THREAD_PC($k0) + mtc0 $k1, C0_EPC + // Check if the FPU was used by this thread and if so also restore the FPU registers + lw $k1, THREAD_FP($k0) + beqz $k1, 1f + nop + lw $k1, THREAD_FPCSR($k0) + ctc1 $k1, C1_FPCSR + ldc1 $f0, THREAD_FP0($k0) + ldc1 $f2, THREAD_FP2($k0) + ldc1 $f4, THREAD_FP4($k0) + ldc1 $f6, THREAD_FP6($k0) + ldc1 $f8, THREAD_FP8($k0) + ldc1 $f10, THREAD_FP10($k0) + ldc1 $f12, THREAD_FP12($k0) + ldc1 $f14, THREAD_FP14($k0) + ldc1 $f16, THREAD_FP16($k0) + ldc1 $f18, THREAD_FP18($k0) + ldc1 $f20, THREAD_FP20($k0) + ldc1 $f22, THREAD_FP22($k0) + ldc1 $f24, THREAD_FP24($k0) + ldc1 $f26, THREAD_FP26($k0) + ldc1 $f28, THREAD_FP28($k0) + ldc1 $f30, THREAD_FP30($k0) +1: + // Restore RCP interrupt mask, masking out any RCP interrupts that + // are not also enabled in the global interrupt mask + lw $k1, THREAD_RCP($k0) + lui $k0, %hi(__OSGlobalIntMask) + addiu $k0, %lo(__OSGlobalIntMask) + lw $k0, ($k0) + srl $k0, $k0, RCP_IMASKSHIFT + and $k1, $k1, $k0 + sll $k1, $k1, 1 + lui $k0, %hi(__osRcpImTable) + addiu $k0, %lo(__osRcpImTable) + addu $k1, $k1, $k0 + lhu $k1, ($k1) + lui $k0, %hi(PHYS_TO_K1(MI_INTR_MASK_REG)) + addiu $k0, %lo(PHYS_TO_K1(MI_INTR_MASK_REG)) + sw $k1, ($k0) + // Empty pipeline + nop + nop + nop + nop + // Resume thread execution + eret +END(__osDispatchThread) + +/** + * void __osCleanupThread(void); + * + * When a thread entrypoint function returns, it returns to this function. + * This function is responsible for cleaning up the thread, signalling for the + * current thread to be destroyed. + */ +LEAF(__osCleanupThread) + jal osDestroyThread + move $a0, $zero + // Despite being a jal, this function does not return as the thread will have been destroyed +END(__osCleanupThread) diff --git a/asm/fp.s b/asm/fp.s index 4954e8ddc0..431348d897 100644 --- a/asm/fp.s +++ b/asm/fp.s @@ -1,138 +1,165 @@ -.include "macro.inc" +#include "ultra64/asm.h" +.set noreorder -.section .data +.section .data -glabel qNaN0x3FFFFF - .word 0x7FBFFFFF +.balign 16 -glabel qNaN0x10000 - .word 0x7F810000 +DATA(qNaN0x3FFFFF) + .word 0x7FBFFFFF +ENDDATA(qNaN0x3FFFFF) -glabel sNaN0x3FFFFF - .word 0x7FFFFFFF +DATA(qNaN0x10000) + .word 0x7F810000 +ENDDATA(qNaN0x10000) +DATA(sNaN0x3FFFFF) + .word 0x7FFFFFFF +ENDDATA(sNaN0x3FFFFF) -.section .text +.section .text -glabel floorf +.balign 16 + +LEAF(floorf) floor.w.s $f12, $f12 - cvt.s.w $f0, $f12 jr $ra + cvt.s.w $f0, $f12 +END(floorf) -glabel floor +LEAF(floor) floor.w.d $f12, $f12 - cvt.d.w $f0, $f12 jr $ra + cvt.d.w $f0, $f12 +END(floor) -glabel lfloorf +LEAF(lfloorf) floor.w.s $f4, $f12 mfc1 $v0, $f4 - nop jr $ra + nop +END(lfloorf) -glabel lfloor +LEAF(lfloor) floor.w.d $f4, $f12 mfc1 $v0, $f4 - nop jr $ra + nop +END(lfloor) -glabel ceilf +LEAF(ceilf) ceil.w.s $f12, $f12 - cvt.s.w $f0, $f12 jr $ra + cvt.s.w $f0, $f12 +END(ceilf) -glabel ceil +LEAF(ceil) ceil.w.d $f12, $f12 - cvt.d.w $f0, $f12 jr $ra + cvt.d.w $f0, $f12 +END(ceil) -glabel lceilf +LEAF(lceilf) ceil.w.s $f4, $f12 mfc1 $v0, $f4 - nop jr $ra + nop +END(lceilf) -glabel lceil +LEAF(lceil) ceil.w.d $f4, $f12 mfc1 $v0, $f4 - nop jr $ra + nop +END(lceil) -glabel truncf +LEAF(truncf) trunc.w.s $f12, $f12 - cvt.s.w $f0, $f12 jr $ra + cvt.s.w $f0, $f12 +END(truncf) -glabel trunc +LEAF(trunc) trunc.w.d $f12, $f12 - cvt.d.w $f0, $f12 jr $ra + cvt.d.w $f0, $f12 +END(trunc) -glabel ltruncf +LEAF(ltruncf) trunc.w.s $f4, $f12 mfc1 $v0, $f4 - nop jr $ra + nop +END(ltruncf) -glabel ltrunc +LEAF(ltrunc) trunc.w.d $f4, $f12 mfc1 $v0, $f4 - nop jr $ra + nop +END(ltrunc) -glabel nearbyintf +LEAF(nearbyintf) round.w.s $f12, $f12 - cvt.s.w $f0, $f12 jr $ra + cvt.s.w $f0, $f12 +END(nearbyintf) -glabel nearbyint +LEAF(nearbyint) round.w.d $f12, $f12 - cvt.d.w $f0, $f12 jr $ra + cvt.d.w $f0, $f12 +END(nearbyint) -glabel lnearbyintf +LEAF(lnearbyintf) round.w.s $f4, $f12 mfc1 $v0, $f4 - nop jr $ra + nop +END(lnearbyintf) -glabel lnearbyint +LEAF(lnearbyint) round.w.d $f4, $f12 mfc1 $v0, $f4 - nop jr $ra + nop +END(lnearbyint) -glabel roundf +LEAF(roundf) li.s $f4, 0.5 nop add.s $f0, $f12, $f4 floor.w.s $f0, $f0 - cvt.s.w $f0, $f0 jr $ra + cvt.s.w $f0, $f0 +END(roundf) -glabel round +LEAF(round) li.d $f4, 0.5 nop add.d $f0, $f12, $f4 floor.w.d $f0, $f0 - cvt.d.w $f0, $f0 jr $ra + cvt.d.w $f0, $f0 +END(round) -glabel lroundf +LEAF(lroundf) li.s $f4, 0.5 nop add.s $f0, $f12, $f4 floor.w.s $f0, $f0 mfc1 $v0, $f0 - nop jr $ra + nop +END(lroundf) -glabel lround +LEAF(lround) li.d $f4, 0.5 nop add.d $f0, $f12, $f4 floor.w.d $f0, $f0 mfc1 $v0, $f0 - nop jr $ra + nop +END(lround) diff --git a/asm/guMtxF2L.s b/asm/guMtxF2L.s index 1590dbb505..edbb675a8e 100644 --- a/asm/guMtxF2L.s +++ b/asm/guMtxF2L.s @@ -1,42 +1,40 @@ -.include "macro.inc" +#include "ultra64/asm.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text -.balign 16 +.balign 32 -/* B7D670 801064D0 00000000 */ nop -/* B7D674 801064D4 00000000 */ nop -/* B7D678 801064D8 00000000 */ nop -/* B7D67C 801064DC 00000000 */ nop -glabel guMtxF2L -/* B7D680 801064E0 3C014780 */ li $at, 0x47800000 # 0.000000 -/* B7D684 801064E4 44810000 */ mtc1 $at, $f0 -/* B7D688 801064E8 3C19FFFF */ lui $t9, 0xffff -/* B7D68C 801064EC 24B80020 */ addiu $t8, $a1, 0x20 -.L801064F0: -/* B7D690 801064F0 C4840000 */ lwc1 $f4, ($a0) -/* B7D694 801064F4 C48A0004 */ lwc1 $f10, 4($a0) -/* B7D698 801064F8 24A50004 */ addiu $a1, $a1, 4 -/* B7D69C 801064FC 46002182 */ mul.s $f6, $f4, $f0 -/* B7D6A0 80106500 24840008 */ addiu $a0, $a0, 8 -/* B7D6A4 80106504 46005402 */ mul.s $f16, $f10, $f0 -/* B7D6A8 80106508 4600320D */ trunc.w.s $f8, $f6 -/* B7D6AC 8010650C 4600848D */ trunc.w.s $f18, $f16 -/* B7D6B0 80106510 44084000 */ mfc1 $t0, $f8 -/* B7D6B4 80106514 44099000 */ mfc1 $t1, $f18 -/* B7D6B8 80106518 01195024 */ and $t2, $t0, $t9 -/* B7D6BC 8010651C 00086C00 */ sll $t5, $t0, 0x10 -/* B7D6C0 80106520 00095C02 */ srl $t3, $t1, 0x10 -/* B7D6C4 80106524 312EFFFF */ andi $t6, $t1, 0xffff -/* B7D6C8 80106528 014B6025 */ or $t4, $t2, $t3 -/* B7D6CC 8010652C 01AE7825 */ or $t7, $t5, $t6 -/* B7D6D0 80106530 ACACFFFC */ sw $t4, -4($a1) -/* B7D6D4 80106534 14B8FFEE */ bne $a1, $t8, .L801064F0 -/* B7D6D8 80106538 ACAF001C */ sw $t7, 0x1c($a1) -/* B7D6DC 8010653C 03E00008 */ jr $ra -/* B7D6E0 80106540 00000000 */ nop +#define MTX_INTPART 0 +#define MTX_FRACPART 0x20 + +LEAF(guMtxF2L) + li $at, 0x47800000 // 65536.0f + mtc1 $at, $f0 + li $t9, 0xFFFF0000 + addiu $t8, $a1, MTX_FRACPART +1: + lwc1 $f4, ($a0) + lwc1 $f10, 4($a0) + addiu $a1, $a1, 4 + mul.s $f6, $f4, $f0 + addiu $a0, $a0, 8 + mul.s $f16, $f10, $f0 + trunc.w.s $f8, $f6 + trunc.w.s $f18, $f16 + mfc1 $t0, $f8 + mfc1 $t1, $f18 + and $t2, $t0, $t9 + sll $t5, $t0, 0x10 + srl $t3, $t1, 0x10 + andi $t6, $t1, 0xFFFF + or $t4, $t2, $t3 + or $t7, $t5, $t6 + sw $t4, (MTX_INTPART-4)($a1) + bne $a1, $t8, 1b + sw $t7, (MTX_FRACPART-4)($a1) + jr $ra + nop +END(guMtxF2L) diff --git a/asm/guMtxIdent.s b/asm/guMtxIdent.s index ec69b0d39b..e28bf70f1f 100644 --- a/asm/guMtxIdent.s +++ b/asm/guMtxIdent.s @@ -1,31 +1,30 @@ -.include "macro.inc" +#include "ultra64/asm.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text -.balign 16 +.balign 32 -glabel guMtxIdent -/* B7AD00 80103B60 20080001 */ addi $t0, $zero, 1 -/* B7AD04 80103B64 00084C00 */ sll $t1, $t0, 0x10 -/* B7AD08 80103B68 AC890000 */ sw $t1, ($a0) -/* B7AD0C 80103B6C AC800004 */ sw $zero, 4($a0) -/* B7AD10 80103B70 AC880008 */ sw $t0, 8($a0) -/* B7AD14 80103B74 AC80000C */ sw $zero, 0xc($a0) -/* B7AD18 80103B78 AC800010 */ sw $zero, 0x10($a0) -/* B7AD1C 80103B7C AC890014 */ sw $t1, 0x14($a0) -/* B7AD20 80103B80 AC800018 */ sw $zero, 0x18($a0) -/* B7AD24 80103B84 AC88001C */ sw $t0, 0x1c($a0) -/* B7AD28 80103B88 AC800020 */ sw $zero, 0x20($a0) -/* B7AD2C 80103B8C AC800024 */ sw $zero, 0x24($a0) -/* B7AD30 80103B90 AC800028 */ sw $zero, 0x28($a0) -/* B7AD34 80103B94 AC80002C */ sw $zero, 0x2c($a0) -/* B7AD38 80103B98 AC800030 */ sw $zero, 0x30($a0) -/* B7AD3C 80103B9C AC800034 */ sw $zero, 0x34($a0) -/* B7AD40 80103BA0 AC800038 */ sw $zero, 0x38($a0) -/* B7AD44 80103BA4 03E00008 */ jr $ra -/* B7AD48 80103BA8 AC80003C */ sw $zero, 0x3c($a0) +LEAF(guMtxIdent) + addi $t0, $zero, 1 + sll $t1, $t0, 0x10 + sw $t1, ($a0) + sw $zero, 4($a0) + sw $t0, 8($a0) + sw $zero, 0xc($a0) + sw $zero, 0x10($a0) + sw $t1, 0x14($a0) + sw $zero, 0x18($a0) + sw $t0, 0x1C($a0) + sw $zero, 0x20($a0) + sw $zero, 0x24($a0) + sw $zero, 0x28($a0) + sw $zero, 0x2c($a0) + sw $zero, 0x30($a0) + sw $zero, 0x34($a0) + sw $zero, 0x38($a0) + jr $ra + sw $zero, 0x3C($a0) +END(guMtxIdent) diff --git a/asm/guMtxIdentF.s b/asm/guMtxIdentF.s index 5eb2d80109..0a23adf77a 100644 --- a/asm/guMtxIdentF.s +++ b/asm/guMtxIdentF.s @@ -1,32 +1,29 @@ -.include "macro.inc" +#include "ultra64/asm.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text -.balign 16 +.balign 32 -## Handwritten ASM - -glabel guMtxIdentF -/* B78CE0 80101B40 3C083F80 */ lui $t0, 0x3f80 -/* B78CE4 80101B44 AC880000 */ sw $t0, ($a0) -/* B78CE8 80101B48 AC800004 */ sw $zero, 4($a0) -/* B78CEC 80101B4C AC800008 */ sw $zero, 8($a0) -/* B78CF0 80101B50 AC80000C */ sw $zero, 0xc($a0) -/* B78CF4 80101B54 AC800010 */ sw $zero, 0x10($a0) -/* B78CF8 80101B58 AC880014 */ sw $t0, 0x14($a0) -/* B78CFC 80101B5C AC800018 */ sw $zero, 0x18($a0) -/* B78D00 80101B60 AC80001C */ sw $zero, 0x1c($a0) -/* B78D04 80101B64 AC800020 */ sw $zero, 0x20($a0) -/* B78D08 80101B68 AC800024 */ sw $zero, 0x24($a0) -/* B78D0C 80101B6C AC880028 */ sw $t0, 0x28($a0) -/* B78D10 80101B70 AC80002C */ sw $zero, 0x2c($a0) -/* B78D14 80101B74 AC800030 */ sw $zero, 0x30($a0) -/* B78D18 80101B78 AC800034 */ sw $zero, 0x34($a0) -/* B78D1C 80101B7C AC800038 */ sw $zero, 0x38($a0) -/* B78D20 80101B80 03E00008 */ jr $ra -/* B78D24 80101B84 AC88003C */ sw $t0, 0x3c($a0) +LEAF(guMtxIdentF) + li $t0, 0x3F800000 // 1.0f + sw $t0, ($a0) + sw $zero, 4($a0) + sw $zero, 8($a0) + sw $zero, 0xC($a0) + sw $zero, 0x10($a0) + sw $t0, 0x14($a0) + sw $zero, 0x18($a0) + sw $zero, 0x1C($a0) + sw $zero, 0x20($a0) + sw $zero, 0x24($a0) + sw $t0, 0x28($a0) + sw $zero, 0x2C($a0) + sw $zero, 0x30($a0) + sw $zero, 0x34($a0) + sw $zero, 0x38($a0) + jr $ra + sw $t0, 0x3C($a0) +END(guMtxIdentF) diff --git a/asm/guMtxL2F.s b/asm/guMtxL2F.s index 68c4ad253d..9298da37cc 100644 --- a/asm/guMtxL2F.s +++ b/asm/guMtxL2F.s @@ -1,39 +1,41 @@ -.include "macro.inc" +#include "ultra64/asm.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text -.balign 16 +.balign 32 -glabel guMtxL2F -/* B7A140 80102FA0 3C013780 */ li $at, 0x37800000 # 0.000000 -/* B7A144 80102FA4 44810000 */ mtc1 $at, $f0 -/* B7A148 80102FA8 3C19FFFF */ li $t9, 0xFFFF0000 # 0.000000 -/* B7A14C 80102FAC 24B80020 */ addiu $t8, $a1, 0x20 -.L80102FB0: -/* B7A150 80102FB0 8CA80000 */ lw $t0, ($a1) -/* B7A154 80102FB4 8CA90020 */ lw $t1, 0x20($a1) -/* B7A158 80102FB8 24A50004 */ addiu $a1, $a1, 4 -/* B7A15C 80102FBC 01195024 */ and $t2, $t0, $t9 -/* B7A160 80102FC0 00095C02 */ srl $t3, $t1, 0x10 -/* B7A164 80102FC4 014B6025 */ or $t4, $t2, $t3 -/* B7A168 80102FC8 448C2000 */ mtc1 $t4, $f4 -/* B7A16C 80102FCC 00086C00 */ sll $t5, $t0, 0x10 -/* B7A170 80102FD0 312EFFFF */ andi $t6, $t1, 0xffff -/* B7A174 80102FD4 01AE7825 */ or $t7, $t5, $t6 -/* B7A178 80102FD8 468021A0 */ cvt.s.w $f6, $f4 -/* B7A17C 80102FDC 448F5000 */ mtc1 $t7, $f10 -/* B7A180 80102FE0 24840008 */ addiu $a0, $a0, 8 -/* B7A184 80102FE4 46805420 */ cvt.s.w $f16, $f10 -/* B7A188 80102FE8 46003202 */ mul.s $f8, $f6, $f0 -/* B7A18C 80102FEC 00000000 */ nop -/* B7A190 80102FF0 46008482 */ mul.s $f18, $f16, $f0 -/* B7A194 80102FF4 E488FFF8 */ swc1 $f8, -8($a0) -/* B7A198 80102FF8 14B8FFED */ bne $a1, $t8, .L80102FB0 -/* B7A19C 80102FFC E492FFFC */ swc1 $f18, -4($a0) -/* B7A1A0 80103000 03E00008 */ jr $ra -/* B7A1A4 80103004 00000000 */ nop +#define MTX_INTPART 0 +#define MTX_FRACPART 0x20 + +LEAF(guMtxL2F) + li $at, 0x37800000 // 1.0f / 65536.0f + mtc1 $at, $f0 + li $t9, 0xFFFF0000 + addiu $t8, $a1, MTX_FRACPART +1: + lw $t0, MTX_INTPART($a1) + lw $t1, MTX_FRACPART($a1) + addiu $a1, $a1, 4 + and $t2, $t0, $t9 + srl $t3, $t1, 0x10 + or $t4, $t2, $t3 + mtc1 $t4, $f4 + sll $t5, $t0, 0x10 + andi $t6, $t1, 0xFFFF + or $t7, $t5, $t6 + cvt.s.w $f6, $f4 + mtc1 $t7, $f10 + addiu $a0, $a0, 8 + cvt.s.w $f16, $f10 + mul.s $f8, $f6, $f0 + nop + mul.s $f18, $f16, $f0 + swc1 $f8, -8($a0) + bne $a1, $t8, 1b + swc1 $f18, -4($a0) + jr $ra + nop +END(guMtxL2F) diff --git a/asm/guNormalize.s b/asm/guNormalize.s index a2a702ad43..fe7b303b2b 100644 --- a/asm/guNormalize.s +++ b/asm/guNormalize.s @@ -1,37 +1,32 @@ -.include "macro.inc" +#include "ultra64/asm.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text -.balign 16 +.balign 32 -/* B7B2F0 80104150 00000000 */ nop -/* B7B2F4 80104154 00000000 */ nop -/* B7B2F8 80104158 00000000 */ nop -/* B7B2FC 8010415C 00000000 */ nop -glabel guNormalize -/* B7B300 80104160 C4840000 */ lwc1 $f4, ($a0) -/* B7B304 80104164 C4A60000 */ lwc1 $f6, ($a1) -/* B7B308 80104168 C4C80000 */ lwc1 $f8, ($a2) -/* B7B30C 8010416C 46042282 */ mul.s $f10, $f4, $f4 -/* B7B310 80104170 3C083F80 */ li $t0, 0x3F800000 # 0.000000 -/* B7B314 80104174 46063402 */ mul.s $f16, $f6, $f6 -/* B7B318 80104178 46105480 */ add.s $f18, $f10, $f16 -/* B7B31C 8010417C 46084402 */ mul.s $f16, $f8, $f8 -/* B7B320 80104180 46128280 */ add.s $f10, $f16, $f18 -/* B7B324 80104184 44889000 */ mtc1 $t0, $f18 -/* B7B328 80104188 46005404 */ sqrt.s $f16, $f10 -/* B7B32C 8010418C 46109283 */ div.s $f10, $f18, $f16 -/* B7B330 80104190 460A2402 */ mul.s $f16, $f4, $f10 -/* B7B334 80104194 00000000 */ nop -/* B7B338 80104198 460A3482 */ mul.s $f18, $f6, $f10 -/* B7B33C 8010419C 00000000 */ nop -/* B7B340 801041A0 460A4102 */ mul.s $f4, $f8, $f10 -/* B7B344 801041A4 E4900000 */ swc1 $f16, ($a0) -/* B7B348 801041A8 E4B20000 */ swc1 $f18, ($a1) -/* B7B34C 801041AC 03E00008 */ jr $ra -/* B7B350 801041B0 E4C40000 */ swc1 $f4, ($a2) +LEAF(guNormalize) + lwc1 $f4, ($a0) + lwc1 $f6, ($a1) + lwc1 $f8, ($a2) + mul.s $f10, $f4, $f4 + li $t0, 0x3F800000 // 1.0f + mul.s $f16, $f6, $f6 + add.s $f18, $f10, $f16 + mul.s $f16, $f8, $f8 + add.s $f10, $f16, $f18 + mtc1 $t0, $f18 + sqrt.s $f16, $f10 + div.s $f10, $f18, $f16 + mul.s $f16, $f4, $f10 + nop + mul.s $f18, $f6, $f10 + nop + mul.s $f4, $f8, $f10 + swc1 $f16, ($a0) + swc1 $f18, ($a1) + jr $ra + swc1 $f4, ($a2) +END(guNormalize) diff --git a/asm/guScale.s b/asm/guScale.s index 89d1393ee7..80199c0621 100644 --- a/asm/guScale.s +++ b/asm/guScale.s @@ -1,53 +1,52 @@ -.include "macro.inc" +#include "ultra64/asm.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text -.balign 16 +.balign 32 -glabel guScale -/* B77380 801001E0 3C014780 */ li $at, 0x47800000 # 0.000000 -/* B77384 801001E4 44812000 */ mtc1 $at, $f4 -/* B77388 801001E8 44853000 */ mtc1 $a1, $f6 -/* B7738C 801001EC AC800004 */ sw $zero, 4($a0) -/* B77390 801001F0 AC80000C */ sw $zero, 0xc($a0) -/* B77394 801001F4 46043202 */ mul.s $f8, $f6, $f4 -/* B77398 801001F8 44863000 */ mtc1 $a2, $f6 -/* B7739C 801001FC AC800010 */ sw $zero, 0x10($a0) -/* B773A0 80100200 AC800018 */ sw $zero, 0x18($a0) -/* B773A4 80100204 AC800024 */ sw $zero, 0x24($a0) -/* B773A8 80100208 AC80002C */ sw $zero, 0x2c($a0) -/* B773AC 8010020C AC800030 */ sw $zero, 0x30($a0) -/* B773B0 80100210 4600428D */ trunc.w.s $f10, $f8 -/* B773B4 80100214 46043202 */ mul.s $f8, $f6, $f4 -/* B773B8 80100218 44873000 */ mtc1 $a3, $f6 -/* B773BC 8010021C AC800038 */ sw $zero, 0x38($a0) -/* B773C0 80100220 44095000 */ mfc1 $t1, $f10 -/* B773C4 80100224 AC80003C */ sw $zero, 0x3c($a0) -/* B773C8 80100228 00095402 */ srl $t2, $t1, 0x10 -/* B773CC 8010022C 4600428D */ trunc.w.s $f10, $f8 -/* B773D0 80100230 46043202 */ mul.s $f8, $f6, $f4 -/* B773D4 80100234 000A4400 */ sll $t0, $t2, 0x10 -/* B773D8 80100238 00095400 */ sll $t2, $t1, 0x10 -/* B773DC 8010023C 44095000 */ mfc1 $t1, $f10 -/* B773E0 80100240 AC880000 */ sw $t0, ($a0) -/* B773E4 80100244 AC8A0020 */ sw $t2, 0x20($a0) -/* B773E8 80100248 00094402 */ srl $t0, $t1, 0x10 -/* B773EC 8010024C 4600428D */ trunc.w.s $f10, $f8 -/* B773F0 80100250 312AFFFF */ andi $t2, $t1, 0xffff -/* B773F4 80100254 AC8A0028 */ sw $t2, 0x28($a0) -/* B773F8 80100258 AC880008 */ sw $t0, 8($a0) -/* B773FC 8010025C 44095000 */ mfc1 $t1, $f10 -/* B77400 80100260 00000000 */ nop -/* B77404 80100264 00095402 */ srl $t2, $t1, 0x10 -/* B77408 80100268 000A4400 */ sll $t0, $t2, 0x10 -/* B7740C 8010026C AC880014 */ sw $t0, 0x14($a0) -/* B77410 80100270 24080001 */ li $t0, 1 -/* B77414 80100274 00095400 */ sll $t2, $t1, 0x10 -/* B77418 80100278 AC8A0034 */ sw $t2, 0x34($a0) -/* B7741C 8010027C 03E00008 */ jr $ra -/* B77420 80100280 AC88001C */ sw $t0, 0x1c($a0) +LEAF(guScale) + li $at, 0x47800000 // 65536.0f + mtc1 $at, $f4 + mtc1 $a1, $f6 + sw $zero, 4($a0) + sw $zero, 0xC($a0) + mul.s $f8, $f6, $f4 + mtc1 $a2, $f6 + sw $zero, 0x10($a0) + sw $zero, 0x18($a0) + sw $zero, 0x24($a0) + sw $zero, 0x2C($a0) + sw $zero, 0x30($a0) + trunc.w.s $f10, $f8 + mul.s $f8, $f6, $f4 + mtc1 $a3, $f6 + sw $zero, 0x38($a0) + mfc1 $t1, $f10 + sw $zero, 0x3C($a0) + srl $t2, $t1, 0x10 + trunc.w.s $f10, $f8 + mul.s $f8, $f6, $f4 + sll $t0, $t2, 0x10 + sll $t2, $t1, 0x10 + mfc1 $t1, $f10 + sw $t0, ($a0) + sw $t2, 0x20($a0) + srl $t0, $t1, 0x10 + trunc.w.s $f10, $f8 + andi $t2, $t1, 0xFFFF + sw $t2, 0x28($a0) + sw $t0, 8($a0) + mfc1 $t1, $f10 + nop + srl $t2, $t1, 0x10 + sll $t0, $t2, 0x10 + sw $t0, 0x14($a0) + li $t0, 1 + sll $t2, $t1, 0x10 + sw $t2, 0x34($a0) + jr $ra + sw $t0, 0x1C($a0) +END(guScale) diff --git a/asm/guTranslate.s b/asm/guTranslate.s index ef0d103299..d059ad5692 100644 --- a/asm/guTranslate.s +++ b/asm/guTranslate.s @@ -1,66 +1,61 @@ -.include "macro.inc" +#include "ultra64/asm.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text -.balign 16 +.balign 32 -/* B7CDB0 80105C10 00000000 */ nop -/* B7CDB4 80105C14 00000000 */ nop -/* B7CDB8 80105C18 00000000 */ nop -/* B7CDBC 80105C1C 00000000 */ nop -glabel guTranslate -/* B7CDC0 80105C20 3C014780 */ li $at, 0x47800000 # 0.000000 -/* B7CDC4 80105C24 44812000 */ mtc1 $at, $f4 -/* B7CDC8 80105C28 44853000 */ mtc1 $a1, $f6 -/* B7CDCC 80105C2C AC800000 */ sw $zero, ($a0) -/* B7CDD0 80105C30 AC800014 */ sw $zero, 0x14($a0) -/* B7CDD4 80105C34 46043202 */ mul.s $f8, $f6, $f4 -/* B7CDD8 80105C38 44863000 */ mtc1 $a2, $f6 -/* B7CDDC 80105C3C AC800008 */ sw $zero, 8($a0) -/* B7CDE0 80105C40 AC800004 */ sw $zero, 4($a0) -/* B7CDE4 80105C44 AC80000C */ sw $zero, 0xc($a0) -/* B7CDE8 80105C48 AC800010 */ sw $zero, 0x10($a0) -/* B7CDEC 80105C4C AC800020 */ sw $zero, 0x20($a0) -/* B7CDF0 80105C50 4600428D */ trunc.w.s $f10, $f8 -/* B7CDF4 80105C54 46043202 */ mul.s $f8, $f6, $f4 -/* B7CDF8 80105C58 44873000 */ mtc1 $a3, $f6 -/* B7CDFC 80105C5C AC800024 */ sw $zero, 0x24($a0) -/* B7CE00 80105C60 44095000 */ mfc1 $t1, $f10 -/* B7CE04 80105C64 AC800028 */ sw $zero, 0x28($a0) -/* B7CE08 80105C68 AC80002C */ sw $zero, 0x2c($a0) -/* B7CE0C 80105C6C 00095402 */ srl $t2, $t1, 0x10 -/* B7CE10 80105C70 4600428D */ trunc.w.s $f10, $f8 -/* B7CE14 80105C74 46043202 */ mul.s $f8, $f6, $f4 -/* B7CE18 80105C78 000A4400 */ sll $t0, $t2, 0x10 -/* B7CE1C 80105C7C AC800030 */ sw $zero, 0x30($a0) -/* B7CE20 80105C80 440B5000 */ mfc1 $t3, $f10 -/* B7CE24 80105C84 AC800034 */ sw $zero, 0x34($a0) -/* B7CE28 80105C88 000B5402 */ srl $t2, $t3, 0x10 -/* B7CE2C 80105C8C 4600428D */ trunc.w.s $f10, $f8 -/* B7CE30 80105C90 010A4025 */ or $t0, $t0, $t2 -/* B7CE34 80105C94 AC880018 */ sw $t0, 0x18($a0) -/* B7CE38 80105C98 00094400 */ sll $t0, $t1, 0x10 -/* B7CE3C 80105C9C 000B5400 */ sll $t2, $t3, 0x10 -/* B7CE40 80105CA0 44095000 */ mfc1 $t1, $f10 -/* B7CE44 80105CA4 000A5402 */ srl $t2, $t2, 0x10 -/* B7CE48 80105CA8 010A4025 */ or $t0, $t0, $t2 -/* B7CE4C 80105CAC AC880038 */ sw $t0, 0x38($a0) -/* B7CE50 80105CB0 00095402 */ srl $t2, $t1, 0x10 -/* B7CE54 80105CB4 000A4400 */ sll $t0, $t2, 0x10 -/* B7CE58 80105CB8 25080001 */ addiu $t0, $t0, 1 -/* B7CE5C 80105CBC AC88001C */ sw $t0, 0x1c($a0) -/* B7CE60 80105CC0 3C080001 */ lui $t0, 1 -/* B7CE64 80105CC4 35080000 */ ori $t0, $t0, 0 -/* B7CE68 80105CC8 AC880000 */ sw $t0, ($a0) -/* B7CE6C 80105CCC AC880014 */ sw $t0, 0x14($a0) -/* B7CE70 80105CD0 3C080000 */ lui $t0, (0x00000001 >> 16) # lui $t0, 0 -/* B7CE74 80105CD4 35080001 */ ori $t0, (0x00000001 & 0xFFFF) # ori $t0, $t0, 1 -/* B7CE78 80105CD8 00095400 */ sll $t2, $t1, 0x10 -/* B7CE7C 80105CDC AC8A003C */ sw $t2, 0x3c($a0) -/* B7CE80 80105CE0 03E00008 */ jr $ra -/* B7CE84 80105CE4 AC880008 */ sw $t0, 8($a0) +LEAF(guTranslate) + li $at, 0x47800000 // 65536.0f + mtc1 $at, $f4 + mtc1 $a1, $f6 + sw $zero, ($a0) + sw $zero, 0x14($a0) + mul.s $f8, $f6, $f4 + mtc1 $a2, $f6 + sw $zero, 8($a0) + sw $zero, 4($a0) + sw $zero, 0xC($a0) + sw $zero, 0x10($a0) + sw $zero, 0x20($a0) + trunc.w.s $f10, $f8 + mul.s $f8, $f6, $f4 + mtc1 $a3, $f6 + sw $zero, 0x24($a0) + mfc1 $t1, $f10 + sw $zero, 0x28($a0) + sw $zero, 0x2C($a0) + srl $t2, $t1, 0x10 + trunc.w.s $f10, $f8 + mul.s $f8, $f6, $f4 + sll $t0, $t2, 0x10 + sw $zero, 0x30($a0) + mfc1 $t3, $f10 + sw $zero, 0x34($a0) + srl $t2, $t3, 0x10 + trunc.w.s $f10, $f8 + or $t0, $t0, $t2 + sw $t0, 0x18($a0) + sll $t0, $t1, 0x10 + sll $t2, $t3, 0x10 + mfc1 $t1, $f10 + srl $t2, $t2, 0x10 + or $t0, $t0, $t2 + sw $t0, 0x38($a0) + srl $t2, $t1, 0x10 + sll $t0, $t2, 0x10 + addiu $t0, $t0, 1 + sw $t0, 0x1C($a0) + lui $t0, 1 + ori $t0, $t0, 0 + sw $t0, ($a0) + sw $t0, 0x14($a0) + lui $t0, (0x00000001 >> 16) + ori $t0, (0x00000001 & 0xFFFF) + sll $t2, $t1, 0x10 + sw $t2, 0x3C($a0) + jr $ra + sw $t0, 8($a0) +END(guTranslate) diff --git a/asm/interrupt.s b/asm/interrupt.s new file mode 100644 index 0000000000..82090742b7 --- /dev/null +++ b/asm/interrupt.s @@ -0,0 +1,53 @@ +#include "ultra64/asm.h" +#include "ultra64/r4300.h" +#include "ultra64/thread.h" + +.set noat +.set noreorder + +.section .text + +.balign 16 + +LEAF(__osDisableInt) + lui $t2, %hi(__OSGlobalIntMask) + addiu $t2, $t2, %lo(__OSGlobalIntMask) + lw $t3, ($t2) + andi $t3, $t3, SR_IMASK + mfc0 $t0, C0_SR + li $at, ~SR_IE + and $t1, $t0, $at + mtc0 $t1, C0_SR + andi $v0, $t0, SR_IE + lw $t0, ($t2) + andi $t0, $t0, SR_IMASK + beq $t0, $t3, No_Change_Global_Int + lui $t2, %hi(__osRunningThread) + //! @bug this addiu should be lw, it may never come up in practice as to reach this code + //! the CPU bits of __OSGlobalIntMask must have changed while this function is running. + addiu $t2, $t2, %lo(__osRunningThread) + lw $t1, THREAD_SR($t2) + andi $t2, $t1, SR_IMASK + and $t2, $t2, $t0 + li $at, ~SR_IMASK + and $t1, $t1, $at + or $t1, $t1, $t2 + li $at, ~SR_IE + and $t1, $t1, $at + mtc0 $t1, C0_SR + nop + nop +No_Change_Global_Int: + jr $ra + nop +END(__osDisableInt) + +LEAF(__osRestoreInt) + mfc0 $t0, C0_SR + or $t0, $t0, $a0 + mtc0 $t0, C0_SR + nop + nop + jr $ra + nop +END(__osRestoreInt) diff --git a/asm/ipl3.s b/asm/ipl3.s index e864b10879..2efa7b53d8 100644 --- a/asm/ipl3.s +++ b/asm/ipl3.s @@ -1,9 +1,3 @@ -.include "macro.inc" - -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers .section .text diff --git a/asm/libm_vals.s b/asm/libm_vals.s index 3c3686576b..18de1ae4f2 100644 --- a/asm/libm_vals.s +++ b/asm/libm_vals.s @@ -1,13 +1,9 @@ -.include "macro.inc" - -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +#include "ultra64/asm.h" .section .rodata .balign 16 -glabel __libm_qnan_f +DATA(__libm_qnan_f) .word 0x7F810000 +ENDDATA(__libm_qnan_f) diff --git a/asm/mio0.s b/asm/mio0.s index b29482f7ee..bdf57397eb 100644 --- a/asm/mio0.s +++ b/asm/mio0.s @@ -1,62 +1,65 @@ -.include "macro.inc" +#include "ultra64/asm.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 -glabel Mio0_Decompress -/* 0031B0 800025B0 8C870008 */ lw $a3, 8($a0) -/* 0031B4 800025B4 8C99000C */ lw $t9, 0xc($a0) -/* 0031B8 800025B8 8C980004 */ lw $t8, 4($a0) -/* 0031BC 800025BC 00E43820 */ add $a3, $a3, $a0 -/* 0031C0 800025C0 0324C820 */ add $t9, $t9, $a0 -/* 0031C4 800025C4 00003025 */ move $a2, $zero -/* 0031C8 800025C8 20840010 */ addi $a0, $a0, 0x10 -/* 0031CC 800025CC 0305C020 */ add $t8, $t8, $a1 -.L800025D0: -/* 0031D0 800025D0 14C00004 */ bnez $a2, .L800025E4 -/* 0031D4 800025D4 00000000 */ nop -/* 0031D8 800025D8 8C880000 */ lw $t0, ($a0) -/* 0031DC 800025DC 24060020 */ li $a2, 32 -/* 0031E0 800025E0 20840004 */ addi $a0, $a0, 4 -.L800025E4: -/* 0031E4 800025E4 0100482A */ slt $t1, $t0, $zero -/* 0031E8 800025E8 11200006 */ beqz $t1, .L80002604 -/* 0031EC 800025EC 00000000 */ nop -/* 0031F0 800025F0 832A0000 */ lb $t2, ($t9) -/* 0031F4 800025F4 23390001 */ addi $t9, $t9, 1 -/* 0031F8 800025F8 20A50001 */ addi $a1, $a1, 1 -/* 0031FC 800025FC 1000000E */ b .L80002638 -/* 003200 80002600 A0AAFFFF */ sb $t2, -1($a1) -.L80002604: -/* 003204 80002604 94EA0000 */ lhu $t2, ($a3) -/* 003208 80002608 20E70002 */ addi $a3, $a3, 2 -/* 00320C 8000260C 000A5B02 */ srl $t3, $t2, 0xc -/* 003210 80002610 314A0FFF */ andi $t2, $t2, 0xfff -/* 003214 80002614 1160000D */ beqz $t3, .L8000264C -/* 003218 80002618 00AA4822 */ sub $t1, $a1, $t2 -/* 00321C 8000261C 216B0002 */ addi $t3, $t3, 2 -.L80002620: -/* 003220 80002620 812AFFFF */ lb $t2, -1($t1) -/* 003224 80002624 216BFFFF */ addi $t3, $t3, -1 -/* 003228 80002628 21290001 */ addi $t1, $t1, 1 -/* 00322C 8000262C 20A50001 */ addi $a1, $a1, 1 -/* 003230 80002630 1560FFFB */ bnez $t3, .L80002620 -/* 003234 80002634 A0AAFFFF */ sb $t2, -1($a1) -.L80002638: -/* 003238 80002638 00084040 */ sll $t0, $t0, 1 -/* 00323C 8000263C 14B8FFE4 */ bne $a1, $t8, .L800025D0 -/* 003240 80002640 20C6FFFF */ addi $a2, $a2, -1 -/* 003244 80002644 03E00008 */ jr $ra -/* 003248 80002648 00000000 */ nop -.L8000264C: -/* 00324C 8000264C 932B0000 */ lbu $t3, ($t9) -/* 003250 80002650 23390001 */ addi $t9, $t9, 1 -/* 003254 80002654 1000FFF2 */ b .L80002620 -/* 003258 80002658 216B0012 */ addi $t3, $t3, 0x12 -/* 00325C 8000265C 00000000 */ nop +/** + * void Mio0_Decompress(void* src, void* dst); + * + * Decompress Mio0 chunk + */ +LEAF(Mio0_Decompress) + lw $a3, 8($a0) // compressed offset + lw $t9, 0xC($a0) // uncompressed offset + lw $t8, 4($a0) // decompressed length + add $a3, $a3, $a0 // compressed start + add $t9, $t9, $a0 // uncompressed start + move $a2, $zero // 0 + addi $a0, $a0, 0x10 // move past header + add $t8, $t8, $a1 // dst + decompressed length = end +mainloop: + bnez $a2, 1f + nop + lw $t0, ($a0) + li $a2, 32 + addi $a0, $a0, 4 +1: + slt $t1, $t0, $zero + beqz $t1, read_comp + nop + lb $t2, ($t9) // read 1 byte from uncompressed data + addi $t9, $t9, 1 // advance uncompressed start + addi $a1, $a1, 1 + b next_iter + sb $t2, -1($a1) // store uncompressed byte +read_comp: + lhu $t2, ($a3) // read 2 bytes from compressed data + addi $a3, $a3, 2 // advance compressed start + srl $t3, $t2, 0xC + andi $t2, $t2, 0xFFF + beqz $t3, 3f + sub $t1, $a1, $t2 + addi $t3, $t3, 2 +2: + lb $t2, -1($t1) + addi $t3, $t3, -1 + addi $t1, $t1, 1 + addi $a1, $a1, 1 + bnez $t3, 2b + sb $t2, -1($a1) +next_iter: + sll $t0, $t0, 1 + bne $a1, $t8, mainloop // continue until decompressed length is reached + addi $a2, $a2, -1 + jr $ra + nop +3: + lbu $t3, ($t9) + addi $t9, $t9, 1 + b 2b + addi $t3, $t3, 0x12 +END(Mio0_Decompress) diff --git a/asm/osGetCount.s b/asm/osGetCount.s index 1bf90fada3..cd4cc326f6 100644 --- a/asm/osGetCount.s +++ b/asm/osGetCount.s @@ -1,15 +1,15 @@ -.include "macro.inc" +#include "ultra64/asm.h" +#include "ultra64/r4300.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 - -glabel osGetCount -/* 007AA0 80006EA0 40024800 */ mfc0 $v0, $9 -/* 007AA4 80006EA4 03E00008 */ jr $ra -/* 007AA8 80006EA8 00000000 */ nop + +LEAF(osGetCount) + mfc0 $v0, C0_COUNT + jr $ra + nop +END(osGetCount) diff --git a/asm/osInvalDCache.s b/asm/osInvalDCache.s index 5f2e55866a..41799d3188 100644 --- a/asm/osInvalDCache.s +++ b/asm/osInvalDCache.s @@ -1,61 +1,94 @@ -.include "macro.inc" +#include "ultra64/asm.h" +#include "ultra64/r4300.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 - -glabel osInvalDCache -/* 006E00 80006200 18A0001F */ blez $a1, .L80006280 -/* 006E04 80006204 00000000 */ nop -/* 006E08 80006208 240B2000 */ li $t3, 8192 -/* 006E0C 8000620C 00AB082B */ sltu $at, $a1, $t3 -/* 006E10 80006210 1020001D */ beqz $at, .L80006288 -/* 006E14 80006214 00000000 */ nop -/* 006E18 80006218 00804025 */ move $t0, $a0 -/* 006E1C 8000621C 00854821 */ addu $t1, $a0, $a1 -/* 006E20 80006220 0109082B */ sltu $at, $t0, $t1 -/* 006E24 80006224 10200016 */ beqz $at, .L80006280 -/* 006E28 80006228 00000000 */ nop -/* 006E2C 8000622C 310A000F */ andi $t2, $t0, 0xf -/* 006E30 80006230 11400007 */ beqz $t2, .L80006250 -/* 006E34 80006234 2529FFF0 */ addiu $t1, $t1, -0x10 -/* 006E38 80006238 010A4023 */ subu $t0, $t0, $t2 -/* 006E3C 8000623C BD150000 */ cache 0x15, ($t0) -/* 006E40 80006240 0109082B */ sltu $at, $t0, $t1 -/* 006E44 80006244 1020000E */ beqz $at, .L80006280 -/* 006E48 80006248 00000000 */ nop -/* 006E4C 8000624C 25080010 */ addiu $t0, $t0, 0x10 -.L80006250: -/* 006E50 80006250 312A000F */ andi $t2, $t1, 0xf -/* 006E54 80006254 11400006 */ beqz $t2, .L80006270 -/* 006E58 80006258 00000000 */ nop -/* 006E5C 8000625C 012A4823 */ subu $t1, $t1, $t2 -/* 006E60 80006260 BD350010 */ cache 0x15, 0x10($t1) -/* 006E64 80006264 0128082B */ sltu $at, $t1, $t0 -/* 006E68 80006268 14200005 */ bnez $at, .L80006280 -/* 006E6C 8000626C 00000000 */ nop -.L80006270: -/* 006E70 80006270 BD110000 */ cache 0x11, ($t0) -/* 006E74 80006274 0109082B */ sltu $at, $t0, $t1 -/* 006E78 80006278 1420FFFD */ bnez $at, .L80006270 -/* 006E7C 8000627C 25080010 */ addiu $t0, $t0, 0x10 -.L80006280: -/* 006E80 80006280 03E00008 */ jr $ra -/* 006E84 80006284 00000000 */ nop -.L80006288: -/* 006E88 80006288 3C088000 */ lui $t0, 0x8000 -/* 006E8C 8000628C 010B4821 */ addu $t1, $t0, $t3 -/* 006E90 80006290 2529FFF0 */ addiu $t1, $t1, -0x10 -.L80006294: -/* 006E94 80006294 BD010000 */ cache 1, ($t0) -/* 006E98 80006298 0109082B */ sltu $at, $t0, $t1 -/* 006E9C 8000629C 1420FFFD */ bnez $at, .L80006294 -/* 006EA0 800062A0 25080010 */ addiu $t0, 0x10 -/* 006EA4 800062A4 03E00008 */ jr $ra -/* 006EA8 800062A8 00000000 */ nop +/** + * void osInvalDCache(void* vaddr, s32 nbytes); + * + * Invalidates the CPU Data Cache for `nbytes` at `vaddr`. + * The cache is not automatically synced with physical memory, so cache + * lines must be invalidated to ensure old data is not used in place of + * newly available data supplied by an external agent in a DMA operation. + * + * If `vaddr` is not aligned to a cache line boundary, or nbytes is not a + * multiple of the data cache line size (16 bytes) a larger region is + * invalidated. + * + * If the amount to invalidate is at least the data cache size (DCACHE_SIZE), + * the entire data cache is invalidated. + */ +LEAF(osInvalDCache) + // If the amount to invalidate is less than or equal to 0, return immediately + blez $a1, 3f + nop + // If the amount to invalidate is as large as or larger than + // the data cache size, invalidate all + li $t3, DCACHE_SIZE + sltu $at, $a1, $t3 + beqz $at, 4f + nop + // Ensure end address doesn't wrap around and end up smaller + // than the start address + move $t0, $a0 + addu $t1, $a0, $a1 + sltu $at, $t0, $t1 + beqz $at, 3f + nop + // Mask start with cache line + andi $t2, $t0, DCACHE_LINEMASK + // If mask is not zero, the start is not cache aligned + beqz $t2, 1f + addiu $t1, $t1, -DCACHE_LINESIZE + // Subtract mask result to align to cache line + subu $t0, $t0, $t2 + // Hit-Writeback-Invalidate unaligned part + cache (CACH_PD | C_HWBINV), ($t0) + sltu $at, $t0, $t1 + // If that's all there is to do, return early + beqz $at, 3f + nop + addiu $t0, $t0, DCACHE_LINESIZE +1: + // Mask end with cache line + andi $t2, $t1, DCACHE_LINEMASK + // If mask is not zero, the end is not cache aligned + beqz $t2, 1f + nop + // Subtract mask result to align to cache line + subu $t1, $t1, $t2 + // Hit-Writeback-Invalidate unaligned part + cache (CACH_PD | C_HWBINV), DCACHE_LINESIZE($t1) + sltu $at, $t1, $t0 + // If that's all there is to do, return early + bnez $at, 3f + nop + // Invalidate the rest +1: + // Hit-Invalidate + cache (CACH_PD | C_HINV), ($t0) + sltu $at, $t0, $t1 + bnez $at, 1b + addiu $t0, $t0, DCACHE_LINESIZE +3: + jr $ra + nop + +4: + li $t0, K0BASE + addu $t1, $t0, $t3 + addiu $t1, $t1, -DCACHE_LINESIZE +5: + // Index-Writeback-Invalidate + cache (CACH_PD | C_IWBINV), ($t0) + sltu $at, $t0, $t1 + bnez $at, 5b + addiu $t0, DCACHE_LINESIZE + jr $ra + nop +END(osInvalDCache) diff --git a/asm/osInvalICache.s b/asm/osInvalICache.s index da0eade5b2..79d576fba9 100644 --- a/asm/osInvalICache.s +++ b/asm/osInvalICache.s @@ -1,46 +1,52 @@ -.include "macro.inc" +#include "ultra64/asm.h" +#include "ultra64/r4300.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 - -glabel osInvalICache -/* 006D50 80006150 18A00011 */ blez $a1, .L80006198 -/* 006D54 80006154 00000000 */ nop -/* 006D58 80006158 240B4000 */ li $t3, 16384 -/* 006D5C 8000615C 00AB082B */ sltu $at, $a1, $t3 -/* 006D60 80006160 1020000F */ beqz $at, .L800061A0 -/* 006D64 80006164 00000000 */ nop -/* 006D68 80006168 00804025 */ move $t0, $a0 -/* 006D6C 8000616C 00854821 */ addu $t1, $a0, $a1 -/* 006D70 80006170 0109082B */ sltu $at, $t0, $t1 -/* 006D74 80006174 10200008 */ beqz $at, .L80006198 -/* 006D78 80006178 00000000 */ nop -/* 006D7C 8000617C 310A001F */ andi $t2, $t0, 0x1f -/* 006D80 80006180 2529FFE0 */ addiu $t1, $t1, -0x20 -/* 006D84 80006184 010A4023 */ subu $t0, $t0, $t2 -.L80006188: -/* 006D88 80006188 BD100000 */ cache 0x10, ($t0) -/* 006D8C 8000618C 0109082B */ sltu $at, $t0, $t1 -/* 006D90 80006190 1420FFFD */ bnez $at, .L80006188 -/* 006D94 80006194 25080020 */ addiu $t0, $t0, 0x20 -.L80006198: -/* 006D98 80006198 03E00008 */ jr $ra -/* 006D9C 8000619C 00000000 */ nop -.L800061A0: -/* 006DA0 800061A0 3C088000 */ lui $t0, 0x8000 -/* 006DA4 800061A4 010B4821 */ addu $t1, $t0, $t3 -/* 006DA8 800061A8 2529FFE0 */ addiu $t1, $t1, -0x20 -.L800061AC: -/* 006DAC 800061AC BD000000 */ cache 0, ($t0) -/* 006DB0 800061B0 0109082B */ sltu $at, $t0, $t1 -/* 006DB4 800061B4 1420FFFD */ bnez $at, .L800061AC -/* 006DB8 800061B8 25080020 */ addiu $t0, 0x20 -/* 006DBC 800061BC 03E00008 */ jr $ra -/* 006DC0 800061C0 00000000 */ nop +LEAF(osInvalICache) + // If the amount to invalidate is less than or equal to 0, return immediately + blez $a1, 2f + nop + // If the amount to invalidate is as large as or larger than + // the instruction cache size, invalidate all + li $t3, ICACHE_SIZE + sltu $at, $a1, $t3 + beqz $at, 3f + nop + // ensure end address doesn't wrap around and end up smaller + // than the start address + move $t0, $a0 + addu $t1, $a0, $a1 + sltu $at, $t0, $t1 + beqz $at, 2f + nop + // Mask and subtract to align to cache line + andi $t2, $t0, ICACHE_LINEMASK + addiu $t1, $t1, -ICACHE_LINESIZE + subu $t0, $t0, $t2 +1: + cache (CACH_PI | C_HINV), ($t0) + sltu $at, $t0, $t1 + bnez $at, 1b + addiu $t0, $t0, ICACHE_LINESIZE +2: + jr $ra + nop + +3: + li $t0, K0BASE + addu $t1, $t0, $t3 + addiu $t1, $t1, -ICACHE_LINESIZE +4: + cache (CACH_PI | C_IINV), ($t0) + sltu $at, $t0, $t1 + bnez $at, 4b + addiu $t0, ICACHE_LINESIZE + jr $ra + nop +END(osInvalICache) diff --git a/asm/osMapTLBRdb.s b/asm/osMapTLBRdb.s index 5375f7beaa..fdcea87010 100644 --- a/asm/osMapTLBRdb.s +++ b/asm/osMapTLBRdb.s @@ -1,34 +1,37 @@ -.include "macro.inc" +#include "ultra64/asm.h" +#include "ultra64/r4300.h" +#include "ultra64/rdb.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 -glabel osMapTLBRdb -/* 0086E0 80007AE0 40085000 */ mfc0 $t0, $10 -/* 0086E4 80007AE4 2409001F */ li $t1, 31 -/* 0086E8 80007AE8 40890000 */ mtc0 $t1, $0 -/* 0086EC 80007AEC 40802800 */ mtc0 $zero, $5 -/* 0086F0 80007AF0 240A0017 */ li $t2, 23 -/* 0086F4 80007AF4 3C09C000 */ lui $t1, 0xc000 -/* 0086F8 80007AF8 40895000 */ mtc0 $t1, $10 -/* 0086FC 80007AFC 3C098000 */ lui $t1, 0x8000 -/* 008700 80007B00 00095982 */ srl $t3, $t1, 6 -/* 008704 80007B04 016A5825 */ or $t3, $t3, $t2 -/* 008708 80007B08 408B1000 */ mtc0 $t3, $2 -/* 00870C 80007B0C 24090001 */ li $t1, 1 -/* 008710 80007B10 40891800 */ mtc0 $t1, $3 -/* 008714 80007B14 00000000 */ nop -/* 008718 80007B18 42000002 */ tlbwi -/* 00871C 80007B1C 00000000 */ nop -/* 008720 80007B20 00000000 */ nop -/* 008724 80007B24 00000000 */ nop -/* 008728 80007B28 00000000 */ nop -/* 00872C 80007B2C 40885000 */ mtc0 $t0, $10 -/* 008730 80007B30 03E00008 */ jr $ra -/* 008734 80007B34 00000000 */ nop +LEAF(osMapTLBRdb) + mfc0 $t0, C0_ENTRYHI + li $t1, NTLBENTRIES + mtc0 $t1, C0_INX + mtc0 $zero, C0_PAGEMASK + li $t2, (TLBLO_UNCACHED | TLBLO_D | TLBLO_V | TLBLO_G) + li $t1, (RDB_BASE_REG & TLBHI_VPN2MASK) + mtc0 $t1, C0_ENTRYHI + // Possible bug? Virtual address instead of physical address + // set as page frame number + li $t1, RDB_BASE_VIRTUAL_ADDR + srl $t3, $t1, TLBLO_PFNSHIFT + or $t3, $t3, $t2 + mtc0 $t3, C0_ENTRYLO0 + li $t1, TLBLO_G + mtc0 $t1, C0_ENTRYLO1 + nop + tlbwi + nop + nop + nop + nop + mtc0 $t0, C0_ENTRYHI + jr $ra + nop +END(osMapTLBRdb) diff --git a/asm/osSetIntMask.s b/asm/osSetIntMask.s index 05a57b4186..3afadb73a6 100644 --- a/asm/osSetIntMask.s +++ b/asm/osSetIntMask.s @@ -1,123 +1,168 @@ -.include "macro.inc" +#include "ultra64/asm.h" +#include "ultra64/r4300.h" +#include "ultra64/rcp.h" +#include "ultra64/exception.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers - -.section .text - -.balign 16 - -glabel osSetIntMask -/* 005B40 80004F40 400C6000 */ mfc0 $t4, $12 -/* 005B44 80004F44 3182FF01 */ andi $v0, $t4, 0xff01 -/* 005B48 80004F48 3C088001 */ lui $t0, %hi(__OSGlobalIntMask) # $t0, 0x8001 -/* 005B4C 80004F4C 2508AD00 */ addiu $t0, %lo(__OSGlobalIntMask) # addiu $t0, $t0, -0x5300 -/* 005B50 80004F50 8D0B0000 */ lw $t3, ($t0) -/* 005B54 80004F54 2401FFFF */ li $at, -1 -/* 005B58 80004F58 01614026 */ xor $t0, $t3, $at -/* 005B5C 80004F5C 3108FF00 */ andi $t0, $t0, 0xff00 -/* 005B60 80004F60 00481025 */ or $v0, $v0, $t0 -/* 005B64 80004F64 3C0AA430 */ lui $t2, %hi(D_A430000C) # $t2, 0xa430 -/* 005B68 80004F68 8D4A000C */ lw $t2, %lo(D_A430000C)($t2) -/* 005B6C 80004F6C 11400005 */ beqz $t2, .L80004F84 -/* 005B70 80004F70 000B4C02 */ srl $t1, $t3, 0x10 -/* 005B74 80004F74 2401FFFF */ li $at, -1 -/* 005B78 80004F78 01214826 */ xor $t1, $t1, $at -/* 005B7C 80004F7C 3129003F */ andi $t1, $t1, 0x3f -/* 005B80 80004F80 01495025 */ or $t2, $t2, $t1 -.L80004F84: -/* 005B84 80004F84 000A5400 */ sll $t2, $t2, 0x10 -/* 005B88 80004F88 004A1025 */ or $v0, $v0, $t2 -/* 005B8C 80004F8C 3C01003F */ lui $at, 0x3f -/* 005B90 80004F90 00814024 */ and $t0, $a0, $at -/* 005B94 80004F94 010B4024 */ and $t0, $t0, $t3 -/* 005B98 80004F98 000843C2 */ srl $t0, $t0, 0xf -/* 005B9C 80004F9C 3C0A8001 */ lui $t2, %hi(__osRcpImTable) -/* 005BA0 80004FA0 01485021 */ addu $t2, $t2, $t0 -/* 005BA4 80004FA4 954A2160 */ lhu $t2, %lo(__osRcpImTable)($t2) -/* 005BA8 80004FA8 3C01A430 */ lui $at, %hi(D_A430000C) # $at, 0xa430 -/* 005BAC 80004FAC AC2A000C */ sw $t2, %lo(D_A430000C)($at) -/* 005BB0 80004FB0 3088FF01 */ andi $t0, $a0, 0xff01 -/* 005BB4 80004FB4 3169FF00 */ andi $t1, $t3, 0xff00 -/* 005BB8 80004FB8 01094024 */ and $t0, $t0, $t1 -/* 005BBC 80004FBC 3C01FFFF */ lui $at, (0xFFFF00FF >> 16) # lui $at, 0xffff -/* 005BC0 80004FC0 342100FF */ ori $at, (0xFFFF00FF & 0xFFFF) # ori $at, $at, 0xff -/* 005BC4 80004FC4 01816024 */ and $t4, $t4, $at -/* 005BC8 80004FC8 01886025 */ or $t4, $t4, $t0 -/* 005BCC 80004FCC 408C6000 */ mtc0 $t4, $12 -/* 005BD0 80004FD0 00000000 */ nop -/* 005BD4 80004FD4 00000000 */ nop -/* 005BD8 80004FD8 03E00008 */ jr $ra -/* 005BDC 80004FDC 00000000 */ nop +.set noat +.set noreorder .section .rodata .balign 16 -glabel __osRcpImTable - .half 0x0555 - .half 0x0556 - .half 0x0559 - .half 0x055A - .half 0x0565 - .half 0x0566 - .half 0x0569 - .half 0x056A - .half 0x0595 - .half 0x0596 - .half 0x0599 - .half 0x059A - .half 0x05A5 - .half 0x05A6 - .half 0x05A9 - .half 0x05AA - .half 0x0655 - .half 0x0656 - .half 0x0659 - .half 0x065A - .half 0x0665 - .half 0x0666 - .half 0x0669 - .half 0x066A - .half 0x0695 - .half 0x0696 - .half 0x0699 - .half 0x069A - .half 0x06A5 - .half 0x06A6 - .half 0x06A9 - .half 0x06AA - .half 0x0955 - .half 0x0956 - .half 0x0959 - .half 0x095A - .half 0x0965 - .half 0x0966 - .half 0x0969 - .half 0x096A - .half 0x0995 - .half 0x0996 - .half 0x0999 - .half 0x099A - .half 0x09A5 - .half 0x09A6 - .half 0x09A9 - .half 0x09AA - .half 0x0A55 - .half 0x0A56 - .half 0x0A59 - .half 0x0A5A - .half 0x0A65 - .half 0x0A66 - .half 0x0A69 - .half 0x0A6A - .half 0x0A95 - .half 0x0A96 - .half 0x0A99 - .half 0x0A9A - .half 0x0AA5 - .half 0x0AA6 - .half 0x0AA9 - .half 0x0AAA +/** + * LUT to convert between an interrupt mask value and a value for MI_INTR_MASK_REG. + * The interrupt mask value is a single bit 0 = disabled, 1 = enabled, while writes to MI_INTR_MASK_REG has two distinct non-zero + * values for set and clear, hence the need for a conversion step. + */ +DATA(__osRcpImTable) + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_CLR_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_CLR_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_CLR_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_CLR_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_CLR_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_CLR_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP + .half MI_INTR_MASK_SET_SP | MI_INTR_MASK_SET_SI | MI_INTR_MASK_SET_AI | MI_INTR_MASK_SET_VI | MI_INTR_MASK_SET_PI | MI_INTR_MASK_SET_DP +ENDDATA(__osRcpImTable) + +.section .text + +.balign 16 + +/** + * OSIntMask osSetIntMask(OSIntMask); + * + * Sets the interrupt enable mask for the current thread. External interrupts + * originating either in the CPU or the RCP may be "masked out" so that they + * are not handled. This is sometimes important for critical code sections + * that must not be interrupted. + * Interrupts that are not enabled in the global interrupt mask __OSGlobalIntMask + * cannot be set here. The global interrupt mask is OS-internal and is not + * expected to change during runtime. + * The returned value is the previous interrupt enable mask so that it can be + * restored later. + * + * @bug Some usage of the global interrupt mask is broken both in here and in the + * exception handler routines. + * While a thread is running, the C0_SR interrupt enable bits contain the + * interrupt enable bits for the current thread masked by the global + * interrupt mask. There is an attempt to recover only the original interrupt + * enable bits belonging to the thread itself using the operation + * (SR | ~__OSGlobalIntMask). + * However, this does not work as intended and can cause interrupts to end + * up enabled when not intended to be. The same issue is present for the + * RCP interrupt enable bits in MI_INTR_MASK_REG. + * This does not cause issues in practice as __OSGlobalIntMask is almost always + * OS_IM_ALL, so the operation is usually simply (SR | 0). + */ +LEAF(osSetIntMask) + // Extract interrupt enable bits from current SR + mfc0 $t4, C0_SR + andi $v0, $t4, (SR_IMASK | SR_IE) + // Get value of __OSGlobalIntMask + lui $t0, %hi(__OSGlobalIntMask) + addiu $t0, %lo(__OSGlobalIntMask) + lw $t3, ($t0) + // Bitwise-OR in the disabled CPU bits of __OSGlobalIntMask + li $at, ~0 + xor $t0, $t3, $at + andi $t0, $t0, SR_IMASK + or $v0, $v0, $t0 + // Fetch MI_INTR_MASK_REG + lui $t2, %hi(PHYS_TO_K1(MI_INTR_MASK_REG)) + lw $t2, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))($t2) + // If there are RCP interrupts masked + beqz $t2, 1f + srl $t1, $t3, RCP_IMASKSHIFT + // Bitwise-OR in the disabled RCP bits of __OSGlobalIntMask + li $at, ~0 + xor $t1, $t1, $at + andi $t1, $t1, (RCP_IMASK >> RCP_IMASKSHIFT) + or $t2, $t2, $t1 +1: + // Shift the RCP bits to not conflict with the CPU bits + sll $t2, $t2, RCP_IMASKSHIFT + // OR the CPU and RCP bits together + or $v0, $v0, $t2 + // Extract RCP interrupt enable bits from requested mask and mask with __OSGlobalIntMask + li $at, RCP_IMASK + and $t0, $a0, $at + and $t0, $t0, $t3 + // Convert to a value for MI_INTR_MASK_REG and set it + srl $t0, $t0, (RCP_IMASKSHIFT-1) + lui $t2, %hi(__osRcpImTable) + addu $t2, $t2, $t0 + lhu $t2, %lo(__osRcpImTable)($t2) + lui $at, %hi(PHYS_TO_K1(MI_INTR_MASK_REG)) + sw $t2, %lo(PHYS_TO_K1(MI_INTR_MASK_REG))($at) + // Extract CPU interrupt enable bits from requested mask and mask with __OSGlobalIntMask + andi $t0, $a0, OS_IM_CPU + andi $t1, $t3, SR_IMASK + and $t0, $t0, $t1 + li $at, ~SR_IMASK + and $t4, $t4, $at + // Bitwise OR in the remaining bits of SR and set new SR + or $t4, $t4, $t0 + mtc0 $t4, C0_SR + nop + nop + jr $ra + nop +END(osSetIntMask) diff --git a/asm/osUnmapTLBAll.s b/asm/osUnmapTLBAll.s index 3a216642a8..ef75432df5 100644 --- a/asm/osUnmapTLBAll.s +++ b/asm/osUnmapTLBAll.s @@ -1,30 +1,30 @@ -.include "macro.inc" +#include "ultra64/asm.h" +#include "ultra64/r4300.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 -glabel osUnmapTLBAll -/* 006BC0 80005FC0 40085000 */ mfc0 $t0, $10 -/* 006BC4 80005FC4 2409001E */ li $t1, 30 -/* 006BC8 80005FC8 3C0A8000 */ lui $t2, 0x8000 -/* 006BCC 80005FCC 408A5000 */ mtc0 $t2, $10 -/* 006BD0 80005FD0 40801000 */ mtc0 $zero, $2 -/* 006BD4 80005FD4 40801800 */ mtc0 $zero, $3 -.L80005FD8: -/* 006BD8 80005FD8 40890000 */ mtc0 $t1, $0 -/* 006BDC 80005FDC 00000000 */ nop -/* 006BE0 80005FE0 42000002 */ tlbwi -/* 006BE4 80005FE4 00000000 */ nop -/* 006BE8 80005FE8 00000000 */ nop -/* 006BEC 80005FEC 2129FFFF */ addi $t1, $t1, -1 -/* 006BF0 80005FF0 0521FFF9 */ bgez $t1, .L80005FD8 -/* 006BF4 80005FF4 00000000 */ nop -/* 006BF8 80005FF8 40885000 */ mtc0 $t0, $10 -/* 006BFC 80005FFC 03E00008 */ jr $ra -/* 006C00 80006000 00000000 */ nop +LEAF(osUnmapTLBAll) + mfc0 $t0, C0_ENTRYHI + li $t1, (NTLBENTRIES - 1) + li $t2, (K0BASE & TLBHI_VPN2MASK) + mtc0 $t2, C0_ENTRYHI + mtc0 $zero, C0_ENTRYLO0 + mtc0 $zero, C0_ENTRYLO1 +1: + mtc0 $t1, C0_INX + nop + tlbwi + nop + nop + addi $t1, $t1, -1 + bgez $t1, 1b + nop + mtc0 $t0, C0_ENTRYHI + jr $ra + nop +END(osUnmapTLBAll) diff --git a/asm/osWritebackDCache.s b/asm/osWritebackDCache.s index 820fd696bf..4eea0d83a3 100644 --- a/asm/osWritebackDCache.s +++ b/asm/osWritebackDCache.s @@ -1,46 +1,60 @@ -.include "macro.inc" +#include "ultra64/asm.h" +#include "ultra64/r4300.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 -glabel osWritebackDCache -/* 0052C0 800046C0 18A00011 */ blez $a1, .L80004708 -/* 0052C4 800046C4 00000000 */ nop -/* 0052C8 800046C8 240B2000 */ li $t3, 8192 -/* 0052CC 800046CC 00AB082B */ sltu $at, $a1, $t3 -/* 0052D0 800046D0 1020000F */ beqz $at, .L80004710 -/* 0052D4 800046D4 00000000 */ nop -/* 0052D8 800046D8 00804025 */ move $t0, $a0 -/* 0052DC 800046DC 00854821 */ addu $t1, $a0, $a1 -/* 0052E0 800046E0 0109082B */ sltu $at, $t0, $t1 -/* 0052E4 800046E4 10200008 */ beqz $at, .L80004708 -/* 0052E8 800046E8 00000000 */ nop -/* 0052EC 800046EC 310A000F */ andi $t2, $t0, 0xf -/* 0052F0 800046F0 2529FFF0 */ addiu $t1, $t1, -0x10 -/* 0052F4 800046F4 010A4023 */ subu $t0, $t0, $t2 -.L800046F8: -/* 0052F8 800046F8 BD190000 */ cache 0x19, ($t0) -/* 0052FC 800046FC 0109082B */ sltu $at, $t0, $t1 -/* 005300 80004700 1420FFFD */ bnez $at, .L800046F8 -/* 005304 80004704 25080010 */ addiu $t0, $t0, 0x10 -.L80004708: -/* 005308 80004708 03E00008 */ jr $ra -/* 00530C 8000470C 00000000 */ nop +/** + * void osWritebackDCache(void* vaddr, s32 nbytes); + * + * Writes back the contents of the data cache to main memory for `nbytes` at `vaddr`. + * If `nbytes` is as large as or larger than the data cache size, the entire cache is + * written back. + */ +LEAF(osWritebackDCache) + // If the amount to write back is less than or equal to 0, return immediately + blez $a1, .ret + nop + // If the amount to write back is as large as or larger than + // the data cache size, write back all + li $t3, DCACHE_SIZE + sltu $at, $a1, $t3 + beqz $at, .all + nop + // ensure end address doesn't wrap around and end up smaller + // than the start address + move $t0, $a0 + addu $t1, $a0, $a1 + sltu $at, $t0, $t1 + beqz $at, .ret + nop + // Mask and subtract to align to cache line + andi $t2, $t0, DCACHE_LINEMASK + addiu $t1, $t1, -DCACHE_LINESIZE + subu $t0, $t0, $t2 +1: + cache (CACH_PD | C_HWB), ($t0) + sltu $at, $t0, $t1 + bnez $at, 1b + addiu $t0, $t0, DCACHE_LINESIZE +.ret: + jr $ra + nop -.L80004710: -/* 005310 80004710 3C088000 */ lui $t0, 0x8000 -/* 005314 80004714 010B4821 */ addu $t1, $t0, $t3 -/* 005318 80004718 2529FFF0 */ addiu $t1, $t1, -0x10 -.L8000471C: -/* 00531C 8000471C BD010000 */ cache 1, ($t0) -/* 005320 80004720 0109082B */ sltu $at, $t0, $t1 -/* 005324 80004724 1420FFFD */ bnez $at, .L8000471C -/* 005328 80004728 25080010 */ addiu $t0, 0x10 -/* 00532C 8000472C 03E00008 */ jr $ra -/* 005330 80004730 00000000 */ nop +// same as osWritebackDCacheAll in operation +.all: + li $t0, K0BASE + addu $t1, $t0, $t3 + addiu $t1, $t1, -DCACHE_LINESIZE +1: + cache (CACH_PD | C_IWBINV), ($t0) + sltu $at, $t0, $t1 + bnez $at, 1b + addiu $t0, DCACHE_LINESIZE + jr $ra + nop +END(osWritebackDCache) diff --git a/asm/osWritebackDCacheAll.s b/asm/osWritebackDCacheAll.s index 065f400557..837495c761 100644 --- a/asm/osWritebackDCacheAll.s +++ b/asm/osWritebackDCacheAll.s @@ -1,23 +1,23 @@ -.include "macro.inc" +#include "ultra64/asm.h" +#include "ultra64/r4300.h" -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 # allow use of 64-bit general purpose registers +.set noat +.set noreorder .section .text .balign 16 -glabel osWritebackDCacheAll -/* B7D630 80106490 3C088000 */ lui $t0, 0x8000 -/* B7D634 80106494 240A2000 */ li $t2, 8192 -/* B7D638 80106498 010A4821 */ addu $t1, $t0, $t2 -/* B7D63C 8010649C 2529FFF0 */ addiu $t1, $t1, -0x10 -.L801064A0: -/* B7D640 801064A0 BD010000 */ cache 1, ($t0) -/* B7D644 801064A4 0109082B */ sltu $at, $t0, $t1 -/* B7D648 801064A8 1420FFFD */ bnez $at, .L801064A0 -/* B7D64C 801064AC 25080010 */ addiu $t0, 0x10 -/* B7D650 801064B0 03E00008 */ jr $ra -/* B7D654 801064B4 00000000 */ nop +LEAF(osWritebackDCacheAll) + li $t0, K0BASE + li $t2, DCACHE_SIZE + addu $t1, $t0, $t2 + addiu $t1, $t1, -DCACHE_LINESIZE +1: + cache (CACH_PD | C_IWBINV), ($t0) + sltu $at, $t0, $t1 + bnez $at, 1b + addiu $t0, DCACHE_LINESIZE + jr $ra + nop +END(osWritebackDCacheAll) diff --git a/asm/parameters.s b/asm/parameters.s new file mode 100644 index 0000000000..c0020ddbed --- /dev/null +++ b/asm/parameters.s @@ -0,0 +1,22 @@ +#include "ultra64/asm.h" + +.section .text + +.macro IPL_SYMBOL name, address, size + .global \name + .set \name, \address + .type \name, @object + .size \name, \size +.endm + +IPL_SYMBOL leoBootID, 0x800001A0, 4 +IPL_SYMBOL osTvType, 0x80000300, 4 +IPL_SYMBOL osRomType, 0x80000304, 4 +IPL_SYMBOL osRomBase, 0x80000308, 4 +IPL_SYMBOL osResetType, 0x8000030C, 4 +IPL_SYMBOL osCicId, 0x80000310, 4 +IPL_SYMBOL osVersion, 0x80000314, 4 +IPL_SYMBOL osMemSize, 0x80000318, 4 +IPL_SYMBOL osAppNMIBuffer, 0x8000031C, 0x40 + +.fill 0x60 diff --git a/include/boot.h b/include/boot.h new file mode 100644 index 0000000000..b0c1a50f03 --- /dev/null +++ b/include/boot.h @@ -0,0 +1,6 @@ +#ifndef BOOT_H +#define BOOT_H + +#define BOOT_STACK_SIZE 0x400 + +#endif diff --git a/include/functions.h b/include/functions.h index 71da96eb20..7387e3b70c 100644 --- a/include/functions.h +++ b/include/functions.h @@ -85,12 +85,9 @@ void osViExtendVStart(u32 arg0); s32 osRecvMesg(OSMesgQueue* mq, OSMesg* msg, s32 flag); void __osInitialize_common(void); void __osInitialize_autodetect(void); -void __osExceptionPreamble(void); -// ? __osException(?); void __osEnqueueAndYield(OSThread**); void __osEnqueueThread(OSThread**, OSThread*); OSThread* __osPopThread(OSThread**); -// ? __osNop(?); void __osDispatchThread(void); void __osCleanupThread(void); void __osDequeueThread(OSThread** queue, OSThread* thread); diff --git a/include/ultra64/asm.h b/include/ultra64/asm.h new file mode 100644 index 0000000000..2a2536bdaa --- /dev/null +++ b/include/ultra64/asm.h @@ -0,0 +1,85 @@ +#ifndef ASM_H +#define ASM_H + +#ifdef __sgi +#define _MIPS_ISA_MIPS1 1 +#define _MIPS_ISA_MIPS2 2 +#define _MIPS_ISA_MIPS3 3 +#define _MIPS_ISA_MIPS4 4 +#endif + +#ifndef _LANGUAGE_C + +#define LEAF(x) \ + .balign 4 ;\ + .globl x ;\ + .type x, @function ;\ + x: ;\ + .ent x, 0 ;\ + .frame $sp, 0, $ra + +#define XLEAF(x) \ + .balign 4 ;\ + .globl x ;\ + .type x, @function ;\ + x: ;\ + .aent x, 0 + +#define NESTED(x, fsize, ra) \ + .globl x ;\ + x: ;\ + .ent x, 0 ;\ + .frame $sp, fsize, ra + +#define XNESTED(x) \ + .globl x ;\ + x: ;\ + .aent x, 0 + +#define END(x) \ + .size x, . - x ;\ + .end x + +#define IMPORT(x, size) \ + .extern x, size + +#define EXPORT(x) \ + .globl x ;\ + x: + +#define DATA(x) \ + .balign 4 ;\ + .globl x ;\ + .type x, @object ;\ + x: + +#define ENDDATA(x) \ + .size x, . - x + +#endif + +/** + * Stack Alignment + */ +#if (_MIPS_SIM == _ABIO32) +#define NARGSAVE 4 // space for 4 args must be allocated +#define ALSZ (8-1) +#define ALMASK ~(8-1) +#elif (_MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64) +#define NARGSAVE 0 // no caller responsibilities +#define ALSZ (16-1) +#define ALMASK ~(16-1) +#endif + +#define FRAMESZ(size) (((size) + ALSZ) & ALMASK) + +/** + * Register Size + */ +#if (_MIPS_ISA == _MIPS_ISA_MIPS1 || _MIPS_ISA == _MIPS_ISA_MIPS2) +#define SZREG 4 +#elif (_MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4) +#define SZREG 8 +#endif + +#endif diff --git a/include/ultra64/exception.h b/include/ultra64/exception.h index 43a700f34b..d03de3657e 100644 --- a/include/ultra64/exception.h +++ b/include/ultra64/exception.h @@ -1,10 +1,9 @@ #ifndef ULTRA64_EXCEPTION_H #define ULTRA64_EXCEPTION_H -#include "types.h" - // Interrupt masks #define OS_IM_NONE 0x00000001 +#define OS_IM_RCP 0x00000401 #define OS_IM_SW1 0x00000501 #define OS_IM_SW2 0x00000601 #define OS_IM_CART 0x00000C01 @@ -24,6 +23,13 @@ #define RCP_IMASK 0x003F0000 #define RCP_IMASKSHIFT 16 +// OSHWIntr values +#define OS_INTR_CART 1 + +#ifdef _LANGUAGE_C + +#include "types.h" + typedef u32 OSIntMask; typedef u32 OSHWIntr; @@ -42,4 +48,15 @@ void __osResetGlobalIntMask(OSHWIntr mask); extern __osHwInt __osHwIntTable[]; +#else + +// __osHwInt struct member offsets +#define HWINT_CALLBACK 0x00 +#define HWINT_SP 0x04 + +// __osHwInt struct size +#define HWINT_SIZE 0x8 + +#endif + #endif diff --git a/include/ultra64/message.h b/include/ultra64/message.h index 6c6966a20b..bf93c524c9 100644 --- a/include/ultra64/message.h +++ b/include/ultra64/message.h @@ -1,14 +1,9 @@ #ifndef ULTRA64_MESSAGE_H #define ULTRA64_MESSAGE_H -#include "thread.h" - #define OS_MESG_NOBLOCK 0 #define OS_MESG_BLOCK 1 -typedef void* OSMesg; -typedef u32 OSEvent; - #define OS_NUM_EVENTS 15 #define OS_EVENT_SW1 0 /* CPU SW1 interrupt */ @@ -27,6 +22,13 @@ typedef u32 OSEvent; #define OS_EVENT_THREADSTATUS 13 /* CPU thread status: used by rmon */ #define OS_EVENT_PRENMI 14 /* Pre NMI interrupt */ +#ifdef _LANGUAGE_C + +#include "thread.h" + +typedef void* OSMesg; +typedef u32 OSEvent; + typedef struct OSMesgQueue { /* 0x00 */ OSThread* mtqueue; /* 0x04 */ OSThread* fullqueue; @@ -43,4 +45,17 @@ typedef struct OSMesgQueue { #define MQ_IS_EMPTY(mq) (MQ_GET_COUNT(mq) == 0) #define MQ_IS_FULL(mq) (MQ_GET_COUNT(mq) >= (mq)->msgCount) +#else + +// OSMesgQueue struct member offsets + +#define MQ_MTQUEUE 0x00 +#define MQ_FULLQUEUE 0x04 +#define MQ_VALIDCOUNT 0x08 +#define MQ_FIRST 0x0C +#define MQ_MSGCOUNT 0x10 +#define MQ_MSG 0x14 + +#endif + #endif diff --git a/include/ultra64/rcp.h b/include/ultra64/rcp.h index c68232fa0e..d92b743c63 100644 --- a/include/ultra64/rcp.h +++ b/include/ultra64/rcp.h @@ -1,7 +1,9 @@ #ifndef ULTRA64_RCP_H #define ULTRA64_RCP_H +#ifdef _LANGUAGE_C #define HW_REG(reg, type) *(volatile type*)((reg) | 0xA0000000) +#endif #define AI_DRAM_ADDR_REG 0x04500000 #define AI_LEN_REG 0x04500004 @@ -10,8 +12,8 @@ #define AI_DACRATE_REG 0x04500010 #define AI_BITRATE_REG 0x04500014 -#define AI_STATUS_AI_FULL (1 << 31) -#define AI_STATUS_AI_BUSY (1 << 30) +#define AI_STATUS_AI_FULL (1 << 31) +#define AI_STATUS_AI_BUSY (1 << 30) #define VI_STATUS_REG 0x04400000 #define VI_CONTROL_REG VI_STATUS_REG @@ -20,7 +22,7 @@ #define VI_WIDTH_REG 0x04400008 #define VI_H_WIDTH_REG VI_WIDTH_REG #define VI_INTR_REG 0x0440000C -#define VI_V_INTER_REG VI_H_WIDTH_REG +#define VI_V_INTER_REG VI_INTR_REG #define VI_CURRENT_REG 0x04400010 #define VI_V_CURRENT_LINE_REG VI_CURRENT_REG #define VI_BURST_REG 0x04400014 @@ -63,21 +65,24 @@ #define PI_BSD_DOM2_PGS_REG 0x0460002C //PI dom2 page size #define PI_BSD_DOM2_RLS_REG 0x04600030 //PI dom2 release -#define PI_STATUS_BUSY 0x1 -#define PI_STATUS_IOBUSY 0x2 -#define PI_STATUS_ERROR 0x4 +// PI_STATUS (read) bits +#define PI_STATUS_BUSY (1 << 0) +#define PI_STATUS_IOBUSY (1 << 1) +#define PI_STATUS_ERROR (1 << 2) -#define PI_STATUS_RESET_CONTROLLER 0x1 -#define PI_STATUS_CLEAR_INTR 0x2 +// PI_STATUS (write) bits +#define PI_STATUS_RESET (1 << 0) +#define PI_STATUS_CLR_INTR (1 << 1) #define SI_DRAM_ADDR_REG 0x04800000 #define SI_PIF_ADDR_RD64B_REG 0x04800004 #define SI_PIF_ADDR_WR64B_REG 0x04800010 #define SI_STATUS_REG 0x04800018 -#define SI_STATUS_DMA_BUSY 0x1 -#define SI_STATUS_IO_READ_BUSY 0x2 -#define SI_STATUS_DMA_ERROR 0x8 +// SI_STATUS (read) bits +#define SI_STATUS_DMA_BUSY (1 << 0) +#define SI_STATUS_IO_READ_BUSY (1 << 1) +#define SI_STATUS_DMA_ERROR (1 << 3) #define SI_STATUS_INTERRUPT (1 << 12) #define PIF_RAM_START 0x1FC007C0 @@ -88,6 +93,45 @@ #define MI_INTR_REG 0x04300008 #define MI_INTR_MASK_REG 0x0430000C +// MI_INIT_MODE_REG bits (write) +#define MI_CLR_INIT (1 << 7) +#define MI_SET_INIT (1 << 8) +#define MI_CLR_EBUS (1 << 9) +#define MI_SET_EBUS (1 << 10) +#define MI_CLR_DP_INTR (1 << 11) +#define MI_CLR_RDRAM (1 << 12) +#define MI_SET_RDRAM (1 << 13) + +// MI_INTR_REG bits +#define MI_INTR_SP (1 << 0) +#define MI_INTR_SI (1 << 1) +#define MI_INTR_AI (1 << 2) +#define MI_INTR_VI (1 << 3) +#define MI_INTR_PI (1 << 4) +#define MI_INTR_DP (1 << 5) + +// MI_INTR_MASK_REG masks (read) +#define MI_INTR_MASK_SP 0x01 +#define MI_INTR_MASK_SI 0x02 +#define MI_INTR_MASK_AI 0x04 +#define MI_INTR_MASK_VI 0x08 +#define MI_INTR_MASK_PI 0x10 +#define MI_INTR_MASK_DP 0x20 + +// MI_INTR_MASK_REG masks (write) +#define MI_INTR_MASK_CLR_SP 0x0001 +#define MI_INTR_MASK_SET_SP 0x0002 +#define MI_INTR_MASK_CLR_SI 0x0004 +#define MI_INTR_MASK_SET_SI 0x0008 +#define MI_INTR_MASK_CLR_AI 0x0010 +#define MI_INTR_MASK_SET_AI 0x0020 +#define MI_INTR_MASK_CLR_VI 0x0040 +#define MI_INTR_MASK_SET_VI 0x0080 +#define MI_INTR_MASK_CLR_PI 0x0100 +#define MI_INTR_MASK_SET_PI 0x0200 +#define MI_INTR_MASK_CLR_DP 0x0400 +#define MI_INTR_MASK_SET_DP 0x0800 + #define VI_NTSC_CLOCK 48681812 /* Hz = 48.681812 MHz */ #define VI_PAL_CLOCK 49656530 /* Hz = 49.656530 MHz */ #define VI_MPAL_CLOCK 48628316 /* Hz = 48.628316 MHz */ diff --git a/include/ultra64/rdb.h b/include/ultra64/rdb.h new file mode 100644 index 0000000000..b9e6a52816 --- /dev/null +++ b/include/ultra64/rdb.h @@ -0,0 +1,82 @@ +#ifndef ULTRA64_RDB_H +#define ULTRA64_RDB_H + +/* U64 side address */ +#define RDB_BASE_REG 0xC0000000 +#define RDB_WRITE_INTR_REG (RDB_BASE_REG + 0x8) +#define RDB_READ_INTR_REG (RDB_BASE_REG + 0xC) +#define RDB_BASE_VIRTUAL_ADDR 0x80000000 + +/* packet type Have six bits, so can have up to 63 types */ +#define RDB_TYPE_INVALID 0 +#define RDB_TYPE_GtoH_PRINT 1 +#define RDB_TYPE_GtoH_FAULT 2 +#define RDB_TYPE_GtoH_LOG_CT 3 +#define RDB_TYPE_GtoH_LOG 4 +#define RDB_TYPE_GtoH_READY_FOR_DATA 5 +#define RDB_TYPE_GtoH_DATA_CT 6 +#define RDB_TYPE_GtoH_DATA 7 +#define RDB_TYPE_GtoH_DEBUG 8 +#define RDB_TYPE_GtoH_RAMROM 9 +#define RDB_TYPE_GtoH_DEBUG_DONE 10 +#define RDB_TYPE_GtoH_DEBUG_READY 11 +#define RDB_TYPE_GtoH_KDEBUG 12 +#define RDB_TYPE_GtoH_PROF_DATA 22 + + +#define RDB_TYPE_HtoG_LOG_DONE 13 +#define RDB_TYPE_HtoG_DEBUG 14 +#define RDB_TYPE_HtoG_DEBUG_CT 15 +#define RDB_TYPE_HtoG_DATA 16 +#define RDB_TYPE_HtoG_DATA_DONE 17 +#define RDB_TYPE_HtoG_REQ_RAMROM 18 +#define RDB_TYPE_HtoG_FREE_RAMROM 19 +#define RDB_TYPE_HtoG_KDEBUG 20 +#define RDB_TYPE_HtoG_PROF_SIGNAL 21 + + +#define RDB_PROF_ACK_SIG 1 +#define RDB_PROF_FLUSH_SIG 2 +#define PROF_BLOCK_SIZE 2048 + +#define RDB_LOG_MAX_BLOCK_SIZE 0x8000 +#define RDB_DATA_MAX_BLOCK_SIZE 0x8000 + +/* GIO side address */ +#define GIO_RDB_BASE_REG 0xBF480000 +#define GIO_RDB_WRITE_INTR_REG (GIO_RDB_BASE_REG + 0x8) +#define GIO_RDB_READ_INTR_REG (GIO_RDB_BASE_REG + 0xC) + +/* minor device number */ +#define GIO_RDB_PRINT_MINOR 1 +#define GIO_RDB_DEBUG_MINOR 2 + +/* interrupt bit */ +#define GIO_RDB_WRITE_INTR_BIT 0x80000000 +#define GIO_RDB_READ_INTR_BIT 0x40000000 + +/* debug command */ +#define DEBUG_COMMAND_NULL 0 +#define DEBUG_COMMAND_MEMORY 1 +#define DEBUG_COMMAND_REGISTER 2 +#define DEBUG_COMMAND_INVALID 255 + +/* debug state */ +#define DEBUG_STATE_NULL 0 +#define DEBUG_STATE_RECEIVE 1 +#define DEBUG_STATE_INVALID 255 + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +#include "types.h" + +/* Structure for debug port */ +typedef struct { + u32 type : 6; /* 0: invalid, 1: print, 2: debug */ + u32 length : 2; /* 1, 2, or 3 */ + char buf[3]; /* character buffer */ +} rdbPacket; + +#endif + +#endif diff --git a/include/ultra64/thread.h b/include/ultra64/thread.h index 4c8146c0bc..5adb689dd9 100644 --- a/include/ultra64/thread.h +++ b/include/ultra64/thread.h @@ -1,8 +1,6 @@ #ifndef ULTRA64_THREAD_H #define ULTRA64_THREAD_H -#include "types.h" - #define OS_PRIORITY_MAX 255 #define OS_PRIORITY_VIMGR 254 #define OS_PRIORITY_RMON 250 @@ -22,6 +20,10 @@ #define OS_FLAG_CPU_BREAK 1 #define OS_FLAG_FAULT 2 +#ifdef _LANGUAGE_C + +#include "types.h" + typedef s32 OSPri; typedef s32 OSId; @@ -69,4 +71,74 @@ typedef struct { OSPri priority; } __OSThreadTail; // size = 0x8 +#else + +// OSThread struct member offsets + +#define THREAD_NEXT 0x00 +#define THREAD_PRI 0x04 +#define THREAD_QUEUE 0x08 +#define THREAD_TLNEXT 0x0C +#define THREAD_STATE 0x10 +#define THREAD_FLAGS 0x12 +#define THREAD_ID 0x14 +#define THREAD_FP 0x18 +#define THREAD_PROFILE 0x1C +#define THREAD_CONTEXT 0x20 +#define THREAD_AT (THREAD_CONTEXT + 0x000) +#define THREAD_V0 (THREAD_CONTEXT + 0x008) +#define THREAD_V1 (THREAD_CONTEXT + 0x010) +#define THREAD_A0 (THREAD_CONTEXT + 0x018) +#define THREAD_A1 (THREAD_CONTEXT + 0x020) +#define THREAD_A2 (THREAD_CONTEXT + 0x028) +#define THREAD_A3 (THREAD_CONTEXT + 0x030) +#define THREAD_T0 (THREAD_CONTEXT + 0x038) +#define THREAD_T1 (THREAD_CONTEXT + 0x040) +#define THREAD_T2 (THREAD_CONTEXT + 0x048) +#define THREAD_T3 (THREAD_CONTEXT + 0x050) +#define THREAD_T4 (THREAD_CONTEXT + 0x058) +#define THREAD_T5 (THREAD_CONTEXT + 0x060) +#define THREAD_T6 (THREAD_CONTEXT + 0x068) +#define THREAD_T7 (THREAD_CONTEXT + 0x070) +#define THREAD_S0 (THREAD_CONTEXT + 0x078) +#define THREAD_S1 (THREAD_CONTEXT + 0x080) +#define THREAD_S2 (THREAD_CONTEXT + 0x088) +#define THREAD_S3 (THREAD_CONTEXT + 0x090) +#define THREAD_S4 (THREAD_CONTEXT + 0x098) +#define THREAD_S5 (THREAD_CONTEXT + 0x0A0) +#define THREAD_S6 (THREAD_CONTEXT + 0x0A8) +#define THREAD_S7 (THREAD_CONTEXT + 0x0B0) +#define THREAD_T8 (THREAD_CONTEXT + 0x0B8) +#define THREAD_T9 (THREAD_CONTEXT + 0x0C0) +#define THREAD_GP (THREAD_CONTEXT + 0x0C8) +#define THREAD_SP (THREAD_CONTEXT + 0x0D0) +#define THREAD_S8 (THREAD_CONTEXT + 0x0D8) +#define THREAD_RA (THREAD_CONTEXT + 0x0E0) +#define THREAD_LO (THREAD_CONTEXT + 0x0E8) +#define THREAD_HI (THREAD_CONTEXT + 0x0F0) +#define THREAD_SR (THREAD_CONTEXT + 0x0F8) +#define THREAD_PC (THREAD_CONTEXT + 0x0FC) +#define THREAD_CAUSE (THREAD_CONTEXT + 0x100) +#define THREAD_BADVADDR (THREAD_CONTEXT + 0x104) +#define THREAD_RCP (THREAD_CONTEXT + 0x108) +#define THREAD_FPCSR (THREAD_CONTEXT + 0x10C) +#define THREAD_FP0 (THREAD_CONTEXT + 0x110) +#define THREAD_FP2 (THREAD_CONTEXT + 0x118) +#define THREAD_FP4 (THREAD_CONTEXT + 0x120) +#define THREAD_FP6 (THREAD_CONTEXT + 0x128) +#define THREAD_FP8 (THREAD_CONTEXT + 0x130) +#define THREAD_FP10 (THREAD_CONTEXT + 0x138) +#define THREAD_FP12 (THREAD_CONTEXT + 0x140) +#define THREAD_FP14 (THREAD_CONTEXT + 0x148) +#define THREAD_FP16 (THREAD_CONTEXT + 0x150) +#define THREAD_FP18 (THREAD_CONTEXT + 0x158) +#define THREAD_FP20 (THREAD_CONTEXT + 0x160) +#define THREAD_FP22 (THREAD_CONTEXT + 0x168) +#define THREAD_FP24 (THREAD_CONTEXT + 0x170) +#define THREAD_FP26 (THREAD_CONTEXT + 0x178) +#define THREAD_FP28 (THREAD_CONTEXT + 0x180) +#define THREAD_FP30 (THREAD_CONTEXT + 0x188) + +#endif + #endif diff --git a/include/variables.h b/include/variables.h index 07714bb0f6..2461b0500f 100644 --- a/include/variables.h +++ b/include/variables.h @@ -10,7 +10,7 @@ extern u32 osTvType; extern u32 osRomBase; extern u32 osResetType; extern u32 osMemSize; -extern u8 osAppNmiBuffer[0x40]; +extern u8 osAppNMIBuffer[0x40]; extern u8 D_80009320[]; extern u8 D_800093F0[]; diff --git a/include/z64.h b/include/z64.h index fe909a2c9b..407a7e8be9 100644 --- a/include/z64.h +++ b/include/z64.h @@ -1748,7 +1748,7 @@ typedef struct { /* 0x04 */ u32 resetCount; /* 0x08 */ OSTime duration; /* 0x10 */ OSTime resetTime; -} PreNmiBuff; // size = 0x18 (actually osAppNmiBuffer is 0x40 bytes large but the rest is unused) +} PreNmiBuff; // size = 0x18 (actually osAppNMIBuffer is 0x40 bytes large but the rest is unused) typedef struct { /* 0x00 */ s16 unk_00; diff --git a/spec b/spec index 85c79d43a8..a136ce2e41 100644 --- a/spec +++ b/spec @@ -38,6 +38,7 @@ beginseg include "build/src/libultra/os/dequeuethread.o" include "build/src/libultra/os/destroythread.o" include "build/asm/bzero.o" + include "build/asm/parameters.o" include "build/src/libultra/os/createthread.o" include "build/asm/__osSetSR.o" include "build/asm/__osGetSR.o" @@ -77,8 +78,7 @@ beginseg include "build/asm/__osSetCompare.o" include "build/asm/bcopy.o" include "build/src/libultra/os/resetglobalintmask.o" - include "build/asm/__osDisableInt.o" - include "build/asm/__osRestoreInt.o" + include "build/asm/interrupt.o" include "build/src/libultra/io/vimodentsclan1.o" include "build/src/libultra/io/vimodempallan1.o" include "build/src/libultra/io/vi.o" diff --git a/src/boot/boot_main.c b/src/boot/boot_main.c index 9d8631b57a..fdba964e80 100644 --- a/src/boot/boot_main.c +++ b/src/boot/boot_main.c @@ -1,10 +1,11 @@ #include "global.h" +#include "boot.h" StackEntry sBootThreadInfo; OSThread sIdleThread; STACK(sIdleThreadStack, 0x400); StackEntry sIdleThreadInfo; -STACK(sBootThreadStack, 0x400); +STACK(sBootThreadStack, BOOT_STACK_SIZE); void cleararena(void) { bzero(_dmadataSegmentStart, osMemSize - OS_K0_TO_PHYSICAL(_dmadataSegmentStart)); diff --git a/src/code/main.c b/src/code/main.c index 9794054c75..f2a1340f64 100644 --- a/src/code/main.c +++ b/src/code/main.c @@ -46,7 +46,7 @@ void Main(void* arg) { osSyncPrintf("mainproc 実行開始\n"); // "Start running" gScreenWidth = SCREEN_WIDTH; gScreenHeight = SCREEN_HEIGHT; - gAppNmiBufferPtr = (PreNmiBuff*)osAppNmiBuffer; + gAppNmiBufferPtr = (PreNmiBuff*)osAppNMIBuffer; PreNmiBuff_Init(gAppNmiBufferPtr); Fault_Init(); SysCfb_Init(0); diff --git a/src/libultra/io/cartrominit.c b/src/libultra/io/cartrominit.c index d7e9aef4fa..231b007680 100644 --- a/src/libultra/io/cartrominit.c +++ b/src/libultra/io/cartrominit.c @@ -27,8 +27,9 @@ OSPiHandle* osCartRomInit(void) { __CartRomHandle.speed = 0; bzero(&__CartRomHandle.transferInfo, sizeof(__OSTranxInfo)); - while (status = HW_REG(PI_STATUS_REG, u32), status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) { - ; + status = HW_REG(PI_STATUS_REG, u32); + while (status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) { + status = HW_REG(PI_STATUS_REG, u32); } lastLatency = HW_REG(PI_BSD_DOM1_LAT_REG, u32); diff --git a/src/libultra/io/devmgr.c b/src/libultra/io/devmgr.c index 9380902c6b..e8581d821e 100644 --- a/src/libultra/io/devmgr.c +++ b/src/libultra/io/devmgr.c @@ -28,7 +28,7 @@ void __osDevMgrMain(void* arg) { phi_s2 = ((transfer->transferMode == 2) && (ioMesg->piHandle->transferInfo.cmdType == 0)) ? 1 : 0; osRecvMesg(arg0->acccessQueue, &sp6C, OS_MESG_BLOCK); - __osResetGlobalIntMask(0x00100401); + __osResetGlobalIntMask(OS_IM_PI); __osEPiRawWriteIo(ioMesg->piHandle, 0x05000510, transfer->bmCtlShadow | 0x80000000); while (true) { @@ -43,8 +43,8 @@ void __osDevMgrMain(void* arg) { __osEPiRawWriteIo(ioMesg->piHandle, 0x05000510, transfer->bmCtlShadow | 0x1000000); } block->errStatus = 4; - HW_REG(PI_STATUS_REG, u32) = PI_STATUS_CLEAR_INTR; - __osSetGlobalIntMask(0x00100C01); + HW_REG(PI_STATUS_REG, u32) = PI_STATUS_CLR_INTR; + __osSetGlobalIntMask(OS_IM_CART | OS_IM_PI); } osSendMesg(ioMesg->hdr.retQueue, (OSMesg)ioMesg, OS_MESG_NOBLOCK); diff --git a/src/libultra/io/driverominit.c b/src/libultra/io/driverominit.c index 672b60ea65..d6247298ae 100644 --- a/src/libultra/io/driverominit.c +++ b/src/libultra/io/driverominit.c @@ -22,8 +22,9 @@ OSPiHandle* osDriveRomInit(void) { __DriveRomHandle.speed = 0; bzero(&__DriveRomHandle.transferInfo, sizeof(__OSTranxInfo)); - while (status = HW_REG(PI_STATUS_REG, u32), status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) { - ; + status = HW_REG(PI_STATUS_REG, u32); + while (status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) { + status = HW_REG(PI_STATUS_REG, u32); } HW_REG(PI_BSD_DOM1_LAT_REG, u32) = 0xFF; diff --git a/src/libultra/io/epirawdma.c b/src/libultra/io/epirawdma.c index c8f4de5fda..ccc23f7085 100644 --- a/src/libultra/io/epirawdma.c +++ b/src/libultra/io/epirawdma.c @@ -4,8 +4,9 @@ s32 __osEPiRawStartDma(OSPiHandle* handle, s32 direction, u32 cartAddr, void* dr s32 status; OSPiHandle* curHandle; - while (status = HW_REG(PI_STATUS_REG, u32), status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) { - ; + status = HW_REG(PI_STATUS_REG, u32); + while (status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) { + status = HW_REG(PI_STATUS_REG, u32); } if (__osCurrentHandle[handle->domain]->type != handle->type) { diff --git a/src/libultra/io/epirawread.c b/src/libultra/io/epirawread.c index 513a246ee4..5a3109364b 100644 --- a/src/libultra/io/epirawread.c +++ b/src/libultra/io/epirawread.c @@ -4,8 +4,9 @@ s32 __osEPiRawReadIo(OSPiHandle* handle, u32 devAddr, u32* data) { s32 status; OSPiHandle* curHandle; - while (status = HW_REG(PI_STATUS_REG, u32), status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) { - ; + status = HW_REG(PI_STATUS_REG, u32); + while (status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) { + status = HW_REG(PI_STATUS_REG, u32); } if (__osCurrentHandle[handle->domain]->type != handle->type) { diff --git a/src/libultra/io/epirawwrite.c b/src/libultra/io/epirawwrite.c index dc169ecf71..2c24c5e254 100644 --- a/src/libultra/io/epirawwrite.c +++ b/src/libultra/io/epirawwrite.c @@ -4,8 +4,9 @@ s32 __osEPiRawWriteIo(OSPiHandle* handle, u32 devAddr, u32 data) { s32 status; OSPiHandle* curHandle; - while (status = HW_REG(PI_STATUS_REG, u32), status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) { - ; + status = HW_REG(PI_STATUS_REG, u32); + while (status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) { + status = HW_REG(PI_STATUS_REG, u32); } if (__osCurrentHandle[handle->domain]->type != handle->type) { diff --git a/src/libultra/io/pirawdma.c b/src/libultra/io/pirawdma.c index b642b508fc..d3dda984cd 100644 --- a/src/libultra/io/pirawdma.c +++ b/src/libultra/io/pirawdma.c @@ -1,8 +1,9 @@ #include "global.h" s32 __osPiRawStartDma(s32 dir, u32 cartAddr, void* dramAddr, size_t size) { - register s32 status = HW_REG(PI_STATUS_REG, u32); + s32 status; + status = HW_REG(PI_STATUS_REG, u32); while (status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) { status = HW_REG(PI_STATUS_REG, u32); } diff --git a/src/libultra/os/createthread.c b/src/libultra/os/createthread.c index 90c0251602..2af6ed0b90 100644 --- a/src/libultra/os/createthread.c +++ b/src/libultra/os/createthread.c @@ -1,4 +1,5 @@ #include "global.h" +#include "ultra64/asm.h" __OSThreadTail __osThreadTail = { NULL, OS_PRIORITY_THREADTAIL }; OSThread* __osRunQueue = (OSThread*)&__osThreadTail; @@ -16,7 +17,7 @@ void osCreateThread(OSThread* thread, OSId id, void (*entry)(void*), void* arg, thread->queue = NULL; thread->context.pc = (u32)entry; thread->context.a0 = arg; - thread->context.sp = (u64)(s32)sp - 16; + thread->context.sp = (u64)(s32)sp - FRAMESZ(SZREG * NARGSAVE); thread->context.ra = __osCleanupThread; mask = OS_IM_ALL; diff --git a/src/libultra/os/initialize.c b/src/libultra/os/initialize.c index fb6202612d..d292248a52 100644 --- a/src/libultra/os/initialize.c +++ b/src/libultra/os/initialize.c @@ -7,6 +7,8 @@ typedef struct { u32 ins_0C; // nop } struct_exceptionPreamble; +void __osExceptionPreamble(void); + u64 osClockRate = OS_CLOCK_RATE; s32 osViClock = VI_NTSC_CLOCK; u32 __osShutdown = 0; @@ -58,7 +60,7 @@ void __osInitialize_common(void) { osClockRate = (u64)((osClockRate * 3ll) / 4ull); if (!osResetType) { - bzero(osAppNmiBuffer, sizeof(osAppNmiBuffer)); + bzero(osAppNMIBuffer, sizeof(osAppNMIBuffer)); } if (osTvType == OS_TV_PAL) { diff --git a/src/libultra/os/resetglobalintmask.c b/src/libultra/os/resetglobalintmask.c index 3744ed848c..c418731838 100644 --- a/src/libultra/os/resetglobalintmask.c +++ b/src/libultra/os/resetglobalintmask.c @@ -3,6 +3,6 @@ void __osResetGlobalIntMask(OSHWIntr mask) { register u32 prevInt = __osDisableInt(); - __OSGlobalIntMask &= ~(mask & ~0x401); + __OSGlobalIntMask &= ~(mask & ~OS_IM_RCP); __osRestoreInt(prevInt); } diff --git a/undefined_syms.txt b/undefined_syms.txt index 8f48e9e1bc..62c6cbaa60 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -1,55 +1,3 @@ -// libultra OS symbols -osTvType = 0x80000300; -osRomBase = 0x80000308; -osResetType = 0x8000030C; -osMemSize = 0x80000318; -osAppNmiBuffer = 0x8000031C; - -// OS hardware registers -D_A4040004 = 0xA4040004; -D_A4040008 = 0xA4040008; -D_A404000C = 0xA404000C; -D_A4040010 = 0xA4040010; -D_A4300008 = 0xA4300008; -D_A430000C = 0xA430000C; -D_A4400004 = 0xA4400004; -D_A4400008 = 0xA4400008; -D_A440000C = 0xA440000C; -D_A4400010 = 0xA4400010; -D_A4400014 = 0xA4400014; -D_A4400018 = 0xA4400018; -D_A440001C = 0xA440001C; -D_A4400020 = 0xA4400020; -D_A4400024 = 0xA4400024; -D_A4400028 = 0xA4400028; -D_A440002C = 0xA440002C; -D_A4400030 = 0xA4400030; -D_A4400034 = 0xA4400034; -D_A4500004 = 0xA4500004; -D_A4500008 = 0xA4500008; -D_A450000C = 0xA450000C; -D_A4500010 = 0xA4500010; -D_A4500014 = 0xA4500014; -D_A4600004 = 0xA4600004; -D_A4600005 = 0xA4600005; -D_A4600006 = 0xA4600006; -D_A4600007 = 0xA4600007; -D_A4600008 = 0xA4600008; -D_A460000C = 0xA460000C; -D_A4600010 = 0xA4600010; -D_A4600014 = 0xA4600014; -D_A4600018 = 0xA4600018; -D_A460001C = 0xA460001C; -D_A4600020 = 0xA4600020; -D_A4600024 = 0xA4600024; -D_A4600028 = 0xA4600028; -D_A460002C = 0xA460002C; -D_A4600030 = 0xA4600030; -D_A4800000 = 0xA4800000; // SI_DRAM_ADDR_REG -D_A4800004 = 0xA4800004; // SI_PIF_ADDR_RD64B_REG -D_A4800010 = 0xA4800010; // SI_PIF_ADDR_WR64B_REG -D_A4800018 = 0xA4800018; // SI_STATUS_REG - // z_kankyo, z_demo_kankyo, z_en_viewer, z_object_kankyo, z_eff_ss_dead_dd D_01000000 = 0x01000000;