BFC007E4: device state flags 00080000 S3: osRomType (True boots from IPL, not cartridge) 00040000 S7: osVersion 00020000 S5: osResetType 0000FF00 S6: CIC seed value 000000FF mirror of CIC seed value, unread osTvType is set manually by PIF to S4 BFC00000 PIF bootrom (NTSC) LUI T5,BFC0 LW T0,07FC (T5) ;T0=BFC007FC: PIF status byte ADDIU T5,T5,07C0 ANDI T0,T0,0080 BNEL T0,R0,BFC00004 ;loop until ready (0x80 unset) LUI T5,BFC0 @BFC00018: select cart or IPL source LW T0,0024 (T5) ;T0=@BFC007E4: device state LUI T3,B000 SRL S3,T0,0x13 ANDI S3,S3,0001 ;S3 = True if T0 & 0x80000 else False SRL S7,T0,0x12 BEQ S3,R0,BFC00038 ;If S3 True, use IPL instead of cartridge ANDI S7,S7,0001 ;S7 = True if S7 & 0x40000 else False LUI T3,A600 @BFC00038: SRL S6,T0,0x8 ANDI T2,T0,00FF ;T2 = T0 & 0xFF SRL S5,T0,0x11 LW T0,003C (T5) ;T0= @BFC007FC: PIF status byte ADDIU T1,R0,0010 ANDI S6,S6,00FF ;S6 = (T0 & 0xFF00) >> 8: CIC seed ANDI S5,S5,0001 ;S5 = True if T0 & 0x20000 else False ADDIU S4,R0,0001 ;S4 = 1: NTSC osTvType OR T0,T0,T1 ;PIF.status |= 0x10 @BFC0005C: wait until SI status ready LUI T1,A480 LW T1,0018 (T1) ;T1 = @A4800018: SI.status ANDI T1,T1,0002 BNEL T1,R0,BFC00060 ;loop while SI I/O busy LUI T1,A480 @BFC00070: initialize PI domain 1 settings SW T0,003C (T5) ;update PIF.status LUI T4,A460 ADDIU T0,R0,00FF SW T0,0014 (T4) ;latency: 0xFF SW T0,0018 (T4) ;pulse width: 0xFF ADDIU T0,R0,000F SW T0,001C (T4) ;page size: 0xF ADDIU T0,R0,0003 SW T0,0020 (T4) ;release: 3 @BFC00094: set initial PI domain 1 settings based on ROM header LW T1,0000 (T3) ;T1 = @ROM: initial PI settings in header LUI T5,A410 ADDIU T4,T4,0000 ANDI T0,T1,00FF SW T0,0014 (T4) ;latency: init & 0xFF SRL T0,T1,0x8 SW T0,0018 (T4) ;pulse width: init >> 8 SRL T0,T1,0x10 SW T0,001C (T4) ;page size: init >> 16 SRL T0,T1,0x14 SW T0,0020 (T4) ;release: init >> 20 @BFC000C0: LW T7,000C (T5) ;T7 = @A410000C: DP command status ADDI T0,R0,0FC0 ADDI T3,T3,0040 ;T3 = ROM+40: p->bootstrap code ANDI T7,T7,0001 BEQ T7,R0,BFC000F0 ADDIU T5,T5,000C @BFC000D8: LUI T5,A410 LW T7,000C (T5) ADDIU T5,T5,000C ANDI T7,T7,0020 BNEL T7,R0,BFC000DC LUI T5,A410 @BFC000F0: LUI T5,A400 ADDIU T5,T5,0000 OR A2,R0,T0 ADDI T5,T5,0040 ;T5 = A4000040 @BFC00100: copy 0xFC0 bytes from bootstrap to A4000040 LW T1,0000 (T3) ADDI T0,T0,FFFC ADDI T3,T3,0004 ADDI T5,T5,0004 BNE T0,R0,BFC00100 SW T1,FFFC (T5) @BFC00118: LUI T0,6C07 ORI T0,T0,8965 ;T0 = 6C078965 MULTU T2,T0 MFLO A0 ADDIU A0,A0,0001 ;A0 = 0x6C078965 * (seed & 0xFF) + 1 LUI A1,A400 ADDIU A1,A1,0040 ;A1 = A4000040: copy of bootstrap code BGEZAL R0,BFC00184 NOP @BFC0013C: accepts: A0=value, A1=cur word in bootstrap, A2=count ADDIU SP,SP,FFD0 BNE A1,R0,BFC0014C ;if A1 is 0: A1 = count SW RA,001C (SP) OR A1,A2,R0 @BFC0014C: ADDIU A2,SP,002C BGEZAL R0,BFC00550 ;(A2, A3) = A0 * A1 ADDIU A3,SP,0028 @BFC00158: LW A0,0028 (SP) LW T6,002C (SP) SUBU V0,T6,A0 ;V0 = target.hi - target.lo BNE V0,R0,BFC00170 OR V1,V0,R0 OR V1,A0,R0 ;if not V0: return target.lo @BFC00170: return LW RA,001C (SP) ADDIU SP,SP,0030 OR V0,V1,R0 JR RA NOP BFC00184 calculate checksum for bootstrap accepts: A0=seed * 0x6C078965, A1=p->bootstrap code ADDIU SP,SP,FF20 SW RA,003C (SP) SW S7,0034 (SP) SW S6,0030 (SP) SW S5,002C (SP) SW S4,0028 (SP) SW S3,0024 (SP) SW S2,0020 (SP) SW S1,001C (SP) SW S0,0018 (SP) LW T6,0000 (A1) ;T6 = bootstrap[0] OR V1,R0,R0 ADDIU V1,SP,00B4 ADDIU V0,SP,0074 XOR S0,T6,A0 ;S0 = initial (bootstrap[0] ^ seedword) @BFC001C0: fill SP+74 - SP+B4 with initial ADDIU V0,V0,0010 SW S0,FFF4 (V0) ;SP+78 = initial SW S0,FFF8 (V0) ;SP+7C =initial SW S0,FFFC (V0) ;SP+80 = initial BNE V0,V1,BFC001C0 SW S0,FFF0 (V0) ;SP+74 = initial @BFC001D8 LW S0,0000 (A1) ;S0=bootstrap[0] OR S1,R0,R0 ;S1 = count OR S6,A1,R0 ;S6 = p->bootstrap ADDIU S7,R0,0020 OR S4,S0,R0 ;S4 = bootstrap[0] LW S0,0000 (S6) ADDIU S1,S1,0001 ;count+=1 ADDIU T7,R0,03EF LW S3,0004 (S6) ;S3 = next(bootstrap) ADDIU S6,S6,0004 SUBU A0,T7,S1 ;A0 = 0x3EF - count OR A2,S1,R0 ;A2 = count BGEZAL R0,BFC0013C OR A1,S0,R0 ;A1 = cur @BFC00210 LW V1,0074 (SP) LW A0,0078 (SP) ;A0 = @SP+78: value OR A1,S0,R0 ;A1 = cur ADDU V1,V0,V1 SW V1,0074 (SP) ;SP+74 -= V0 BGEZAL R0,BFC0013C OR A2,S1,R0 ;A2 = count @BFC0022C LW T8,007C (SP) LUI A1,6C07 SW V0,0078 (SP) XOR T9,T8,S0 SW T9,007C (SP) ORI A1,A1,8965 ;A1 = 0x6C078965 ADDIU A0,S0,0005 BGEZAL R0,BFC0013C OR A2,S1,R0 @BFC00250 LW T0,0080 (SP) SLTU AT,S4,S0 ADDU T1,V0,T0 BEQ AT,R0,BFC0027C SW T1,0080 (SP) LW A0,0098 (SP) OR A1,S0,R0 BGEZAL R0,BFC0013C OR A2,S1,R0 @BFC00274 BEQ R0,R0,BFC00288 SW V0,0098 (SP) @BFC0027C LW T2,0098 (SP) ADDU T3,T2,S0 SW T3,0098 (SP) @BFC00288 ANDI V0,S4,001F LW T6,0084 (SP) SUBU V1,S7,V0 SLLV T5,S0,V1 SRLV T4,S0,V0 OR S5,T4,T5 SRLV T9,S0,V1 SLLV T8,S0,V0 ADDU T7,T6,S5 SW T7,0084 (SP) OR A1,T8,T9 LW A0,0090 (SP) BGEZAL R0,BFC0013C OR A2,S1,R0 @BFC002C0 LW V1,008C (SP) SW V0,0090 (SP) SLTU AT,S0,V1 BEQL AT,R0,BFC002F0 LW T3,0084 (SP) LW T0,0080 (SP) ADDU T2,S0,S1 ADDU T1,T0,V1 XOR V1,T1,T2 BEQ R0,R0,BFC002FC SW V1,008C (SP) @BFC002EC LW T3,0084 (SP) ADDU T4,T3,S0 XOR V1,T4,V1 SW V1,008C (SP) @BFC002FC SRL V0,S4,0x1B LW T7,0088 (SP) SUBU V1,S7,V0 SRLV T6,S0,V1 SLLV T5,S0,V0 OR S2,T5,T6 SLLV T0,S0,V1 SRLV T9,S0,V0 ADDU T8,T7,S2 SW T8,0088 (SP) OR A1,T9,T0 LW A0,0094 (SP) BGEZAL R0,BFC0013C OR A2,S1,R0 ADDIU AT,R0,03F0 BEQ S1,AT,BFC00420 SW V0,0094 (SP) LW A0,00B0 (SP) OR A1,S2,R0 BGEZAL R0,BFC0013C OR A2,S1,R0 SRL V1,S0,0x1B SUBU T2,S7,V1 SRLV T3,S3,T2 SLLV T1,S3,V1 OR A1,T1,T3 OR A0,V0,R0 BGEZAL R0,BFC0013C OR A2,S1,R0 SW V0,00B0 (SP) LW A0,00AC (SP) OR A1,S5,R0 BGEZAL R0,BFC0013C OR A2,S1,R0 ANDI S2,S0,001F SUBU S4,S7,S2 SLLV T5,S3,S4 SRLV T4,S3,S2 OR A1,T4,T5 OR A0,V0,R0 BGEZAL R0,BFC0013C OR A2,S1,R0 LW T1,00A8 (SP) ANDI V1,S3,001F SRLV T6,S0,S2 SLLV T7,S0,S4 SUBU T9,S7,V1 OR A3,T6,T7 SLLV T0,S3,T9 SRLV T8,S3,V1 LW T5,009C (SP) OR T2,T8,T0 ADDU T3,T1,A3 ADDU T4,T3,T2 SW V0,00AC (SP) SW T4,00A8 (SP) OR A1,S3,R0 OR A2,S1,R0 BGEZAL R0,BFC0013C ADDU A0,T5,S0 LW T6,00A0 (SP) SW V0,009C (SP) OR A1,S3,R0 OR A2,S1,R0 BGEZAL R0,BFC0013C XOR A0,T6,S0 LW T7,0094 (SP) LW T8,00A4 (SP) SW V0,00A0 (SP) XOR T9,T7,S0 ADDU T0,T9,T8 BEQ R0,R0,BFC001E8 SW T0,00A4 (SP) @BFC00420 LW V1,0074 (SP) OR S1,R0,R0 ADDIU S3,SP,0074 ADDIU S5,R0,0010 ADDIU S4,R0,0001 SW V1,0064 (SP) SW V1,0068 (SP) SW V1,006C (SP) SW V1,0070 (SP) @BFC00444 LW S0,0000 (S3) LW T5,0064 (SP) ANDI V0,S0,001F SUBU T3,S7,V0 SLLV T2,S0,T3 SRLV T1,S0,V0 OR T4,T1,T2 ADDU T6,T5,T4 SLTU AT,S0,T6 BEQ AT,R0,BFC00480 SW T6,0064 (SP) LW T7,0068 (SP) ADDU T9,T7,S0 BEQ R0,R0,BFC00494 SW T9,0068 (SP) @BFC00480 LW A0,0068 (SP) OR A1,S0,R0 BGEZAL R0,BFC0013C OR A2,S1,R0 SW V0,0068 (SP) @BFC00494 ANDI T8,S0,0002 SRL T0,T8,0x1 ANDI S2,S0,0001 BNEL T0,S2,BFC004BC LW A0,006C (SP) LW T3,006C (SP) ADDU T1,T3,S0 BEQ R0,R0,BFC004CC SW T1,006C (SP) @BFC004B8 LW A0,006C (SP) OR A1,S0,R0 BGEZAL R0,BFC0013C OR A2,S1,R0 SW V0,006C (SP) @BFC004CC BNEL S4,S2,BFC004E8 LW A0,0070 (SP) LW T2,0070 (SP) XOR T5,T2,S0 BEQ R0,R0,BFC004F8 SW T5,0070 (SP) @BFC004E4 LW A0,0070 (SP) OR A1,S0,R0 BGEZAL R0,BFC0013C OR A2,S1,R0 SW V0,0070 (SP) @BFC004F8 ADDIU S1,S1,0001 BNE S1,S5,BFC00444 ADDIU S3,S3,0004 LW A0,0064 (SP) LW A1,0068 (SP) BGEZAL R0,BFC0013C OR A2,S1,R0 @BFC00514: pass control to bootstrap LW T4,0070 (SP) LW T6,006C (SP) LW S0,0018 (SP) LW S1,001C (SP) LW S2,0020 (SP) LW S3,0024 (SP) LW S4,0028 (SP) LW S5,002C (SP) LW S6,0030 (SP) LW S7,0034 (SP) LW RA,003C (SP) OR A0,V0,R0 ;A0 = difference in factors ADDIU SP,SP,00E0 BGEZAL R0,BFC0056C XOR A1,T4,T6 ;A1=@SP+70 ^ @SP+6C BFC00550 (A2,A3) = A0 * A1 accepts: A0=value.hi, A1=value.lo, A2=target.hi, A3=target.lo MULTU A0,A1 MFHI T6 SW T6,0000 (A2) MFLO T7 SW T7,0000 (A3) JR RA NOP BFC0056C pass control to bootstrap accepts: A0, A1 LUI T3,BFC0 LW T0,07F0 (T3) LUI T2,FFFF ANDI A0,A0,FFFF AND T0,T0,T2 OR A0,A0,T0 ADDIU T3,T3,07C0 @BFC00588 LUI T1,A480 LW T1,0018 (T1) ANDI T1,T1,0002 BNEL T1,R0,BFC0058C LUI T1,A480 SW A0,0030 (T3) ;BFC007F0 |= A0 NOP NOP NOP NOP NOP @BFC005B4 LUI T1,A480 LW T1,0018 (T1) ANDI T1,T1,0002 BNEL T1,R0,BFC005B8 LUI T1,A480 LW T0,003C (T3) ADDIU T1,R0,0020 SW A1,0034 (T3) OR T0,T0,T1 @BFC005D8 LUI T1,A480 LW T1,0018 (T1) ANDI T1,T1,0002 BNEL T1,R0,BFC005DC LUI T1,A480 SW T0,003C (T3) ;BFC007FC |= 0x20 ADDI T1,R0,0010 @BFC005F4 loop while 0x80 not set in BFC007FC ADDI T1,T1,FFFF BNEL T1,R0,BFC005F8 ADDI T1,T1,FFFF LW T0,003C (T3) ANDI T2,T0,0080 BEQL R0,T2,BFC005F4 ADDI T1,R0,0010 @BFC00610 ADDIU T2,R0,0040 OR T0,T0,T2 LUI T1,A480 LW T1,0018 (T1) ANDI T1,T1,0002 BNEL T1,R0,BFC0061C LUI T1,A480 SW T0,003C (T3) ;BFC007FC |= 0x40 LUI T3,A400 ADDIU T3,T3,0000 ADDI T3,T3,0040 ;Jump and execute bootstrap at A4000040 JR T3 NOP