55
66void __osBbVideoPllInit (s32 tvType );
77void osBbPowerOff (void );
8-
9- void func_80003A28 (void * );
10-
11- void func_80002248 (void * );
12- void func_8000234C (void * );
13-
14- void func_80003094 (void );
8+ void osBbUsbInit (void );
9+ u32 osBbUsbGetResetCount (s32 which );
10+ void osBbSetErrorLed (s32 );
11+ void __osDisableInt (void );
12+ s32 osBbUsbSetCtlrModes (s32 which , u32 mask );
13+
14+ void fbInit (u32 );
15+ void fbSetBg (u16 );
16+ void fbClear (void );
17+
18+ void sa1InitRDP (void );
19+ void sa1ConfigureVI (void * );
20+ void sa1IdleThread (void * );
21+ void sa1MainThread (void * );
22+ s32 sa1CheckIdSys (void );
23+ void sa1BootSA2 (void (* entrypoint )(u32 ), u32 arg );
24+ void * sa1AuthenticateAndLoadSA2 (void );
25+ s32 sa1DisplayImage (void * , size_t );
26+ void sa1CommandLoop (void );
1527
1628extern u8 framebuffer [];
17- extern u32 D_8001AF40 ;
18- extern u32 D_800163A0 ;
19- extern u32 D_80016398 ;
20- extern u8 D_8001B0F8 [0x8000 ];
21- extern u8 D_800232A8 [0x8000 ];
22- extern OSThread D_8001AF48 ;
2329extern OSMesg prenmiMesgBuf [1 ];
2430extern OSMesgQueue prenmiMesgQueue ;
25- extern OSThread D_800230F8 ;
2631extern OSMesgQueue piMesgQueue ;
2732extern OSMesgQueue siMesgQueue ;
2833extern OSMesgQueue siMesgQueue ;
@@ -31,61 +36,68 @@ extern OSMesg viMesgBuf[1];
3136extern OSMesg piMesgBuf [200 ];
3237extern OSMesg siMesgBuf [200 ];
3338extern OSMesg viRetraceMesg ;
34- extern OSThread D_8002B2A8 ;
35- extern u8 D_8002B458 [0x8000 ];
36- extern u32 D_80016390 ;
37- extern u32 D_80016394 ;
38- extern u32 D_80016398 ;
39- extern u32 D_8001639C ;
40- extern s32 D_80016490 ;
41- extern s32 D_800164A0 ;
42- extern s32 D_800178A0 ;
43- extern s32 D_800178B0 ;
44-
39+ extern OSThread idleThread ;
40+ extern u8 idleThreadStack [0x8000 ];
41+ extern OSThread mainThread ;
42+ extern u8 mainThreadStack [0x8000 ];
43+ extern OSThread eventThread ;
44+ extern u8 eventThreadStack [0x8000 ];
45+
46+ extern u32 skBootValue ;
47+ extern u32 powerBtnPressed ;
48+ extern u32 usbNum ;
49+ extern u32 usbTypeA ;
50+ extern u32 usbLineUnstable ;
51+ extern u32 usbNotConnected ;
52+ extern s32 sa1Image1Size ;
53+ extern s32 sa1Image1Data ;
54+ extern s32 sa1Image2Size ;
55+ extern s32 sa1Image2Data ;
4556typedef struct {
4657 u8 data [0x100 ];
4758} Struct_Unk ;
59+ extern Struct_Unk appSavedState ;
4860
49- extern Struct_Unk D_80033458 ;
50-
51- void func_80002050 (u32 arg0 ) {
52- D_80033458 = * (Struct_Unk * )PHYS_TO_K1 (0x04A80100 );
53- func_80003094 ();
61+ void sa1Setup (u32 arg0 ) {
62+ appSavedState = * (Struct_Unk * )PHYS_TO_K1 (0x04A80100 );
63+ sa1CheckIdSys ();
5464}
5565
56- void func_80002114 ( s32 arg0 ) {
57- D_8001AF40 = arg0 ;
66+ void sa1Entrypoint ( u32 arg ) {
67+ skBootValue = arg ;
5868
5969 IO_WRITE (MI_3C_REG , 0x01000000 );
6070
61- if (!(arg0 & 0x4C )) {
71+ if (!(arg & 0x4C )) {
72+ // Cold boot
6273 __osBbVideoPllInit (OS_TV_NTSC );
63- func_80003A28 (framebuffer );
74+ sa1ConfigureVI (framebuffer );
6475 } else {
76+ // Warm boot
6577 IO_WRITE (VI_H_VIDEO_REG , 0 );
6678 }
6779 osInitialize ();
68- osCreateThread (& D_8001AF48 , 1 , func_80002248 , 0 , D_8001B0F8 + sizeof (D_8001B0F8 ), 0x14 );
69- osStartThread (& D_8001AF48 );
80+ osCreateThread (& idleThread , 1 , sa1IdleThread , 0 , idleThreadStack + sizeof (idleThreadStack ), 0x14 );
81+ osStartThread (& idleThread );
7082}
7183
72- void func_800021C8 (void ) {
73- if (D_800163A0 != 0 ) {
84+ void sa1Event (void ) {
85+ if (powerBtnPressed ) {
7486 if (osRecvMesg (& prenmiMesgQueue , NULL , OS_MESG_NOBLOCK ) == 0 ) {
7587 osBbPowerOff ();
7688 }
7789 } else if (!(IO_READ (MI_38_REG ) & 0x01000000 )) {
7890 IO_WRITE (MI_3C_REG , 0x02000000 );
79- D_800163A0 = 1 ;
91+ powerBtnPressed = TRUE ;
8092 }
8193}
8294
83- void func_80002248 (void * arg0 ) {
84- osCreatePiManager (0x96 , & piMesgQueue , piMesgBuf , ARRLEN (piMesgBuf ));
95+ void sa1IdleThread (void * arg ) {
96+ osCreatePiManager (OS_PRIORITY_PIMGR , & piMesgQueue , piMesgBuf , ARRLEN (piMesgBuf ));
8597 osCreateMesgQueue (& siMesgQueue , siMesgBuf , ARRLEN (siMesgBuf ));
8698 osSetEventMesg (OS_EVENT_SI , & siMesgQueue , (OSMesg )200 );
87- osCreateThread (& D_800230F8 , 3 , func_8000234C , arg0 , D_800232A8 + sizeof (D_800232A8 ), 0x12 );
88- osStartThread (& D_800230F8 );
99+ osCreateThread (& mainThread , 3 , sa1MainThread , arg , mainThreadStack + sizeof (mainThreadStack ), 0x12 );
100+ osStartThread (& mainThread );
89101 osCreateMesgQueue (& prenmiMesgQueue , prenmiMesgBuf , ARRLEN (prenmiMesgBuf ));
90102 osSetEventMesg (OS_EVENT_PRENMI , & prenmiMesgQueue , (OSMesg )1 );
91103 osSetThreadPri (NULL , 0 );
@@ -95,83 +107,96 @@ void func_80002248(void* arg0) {
95107 }
96108}
97109
98- void func_80002320 (void ) {
110+ void sa1EventThread (void * arg ) {
99111 while (TRUE) {
100112 osRecvMesg (& viMesgQueue , NULL , OS_MESG_BLOCK );
101- func_800021C8 ();
113+ sa1Event ();
102114 }
103115}
104116
105117#ifdef NON_MATCHING
106118// Needs data imported
107- void func_8000234C (void * arg0 ) {
108- s32 temp_s3 ;
109- u64 temp_s0 ;
110- u32 temp_s2 ;
119+ void sa1MainThread (void * arg ) {
120+ void * sa2Entrypoint ;
121+ OSTime thresholdTime ;
122+ u32 usbResetCount ;
111123
112- osCreateViManager (0xFE );
124+ osCreateViManager (OS_PRIORITY_VIMGR );
113125 fbInit (0 );
114126 osCreateMesgQueue (& viMesgQueue , viMesgBuf , 1 );
115127 osViSetEvent (& viMesgQueue , viRetraceMesg , 1 );
116- osViBlack (1 );
128+ osViBlack (TRUE );
117129 osViSwapBuffer (framebuffer );
118130 fbSetBg (0 );
119131 fbClear ();
120- osViBlack (0 );
132+ osViBlack (FALSE );
121133 osWritebackDCacheAll ();
122134 osViSwapBuffer (framebuffer );
123135 fbClear ();
124- func_80003C20 ();
125- func_80002050 (D_8001AF40 );
126- osCreateThread (& D_8002B2A8 , 5 , func_80002320 , arg0 , D_8002B458 + sizeof (D_8002B458 ), 0xF );
127- osStartThread (& D_8002B2A8 );
128- D_80016398 = 1 ;
129- osBbUsbSetCtlrModes (D_80016398 ^ 1 , 0 );
130- osBbUsbSetCtlrModes (D_80016398 ^ 0 , 2 );
136+ sa1InitRDP ();
137+ sa1Setup (skBootValue );
138+ osCreateThread (& eventThread , 5 , sa1EventThread , arg , eventThreadStack + sizeof (eventThreadStack ), 0xF );
139+ osStartThread (& eventThread );
140+
141+ // Start with USB1
142+ usbNum = 1 ;
143+ osBbUsbSetCtlrModes (usbNum ^ 1 , 0 );
144+ osBbUsbSetCtlrModes (usbNum ^ 0 , 2 );
131145 osBbUsbInit ();
132- temp_s3 = func_80002DCC ();
133146
134- D_80016390 = (D_80016398 == 0 ) ? !(IO_READ (0x04900018 ) & (1 << 7 )) : 0 ;
147+ sa2Entrypoint = sa1AuthenticateAndLoadSA2 ();
148+
149+ // No ID pin on USB1, always assume Type B / Unconnected
150+ usbTypeA = (usbNum == 0 ) ? !(IO_READ (0x04900018 ) & (1 << 7 )) : 0 ;
151+ // Line state is unstable
152+ usbLineUnstable = !(IO_READ ((usbNum == 0 ) ? 0x04900018 : 0x04A00018 ) & (1 << 5 ));
135153
136- D_80016394 = !(IO_READ ((D_80016398 == 0 ) ? 0x04900018 : 0x04A00018 ) & (1 << 5 ));
154+ if (!usbLineUnstable ) {
155+ // If USB1 line state stable, it isn't connected?
137156
138- if ( D_80016394 == 0 ) {
139- D_80016398 = ~D_80016398 & 1 ;
140- osBbUsbSetCtlrModes (D_80016398 ^ 1 , 0 );
141- osBbUsbSetCtlrModes (D_80016398 ^ 0 , 2 );
157+ // Flip to USB0
158+ usbNum = ~usbNum & 1 ;
159+ osBbUsbSetCtlrModes (usbNum ^ 1 , 0 );
160+ osBbUsbSetCtlrModes (usbNum ^ 0 , 2 );
142161 osBbUsbInit ();
143162
144- D_80016390 = (D_80016398 == 0 ) ? !(IO_READ (0x04900018 ) & (1 << 7 )) : 0 ;
145- D_80016394 = 0 ;
146- temp_s2 = osBbUsbGetResetCount (D_80016398 );
147- temp_s0 = OS_CYCLES_TO_USEC (osGetCount ()) + 2000000 ;
148- while (OS_CYCLES_TO_USEC (osGetCount ()) < temp_s0 ) {
149- if (temp_s2 < osBbUsbGetResetCount (D_80016398 )) {
150- D_80016394 = 1 ;
163+ // USB0 has ID pin detection, use it to differentiate Type A or Type B / Unconnected
164+ usbTypeA = (usbNum == 0 ) ? !(IO_READ (0x04900018 ) & (1 << 7 )) : 0 ;
165+ // Determine line stability by reset count over the next 2 seconds
166+ usbLineUnstable = 0 ;
167+ usbResetCount = osBbUsbGetResetCount (usbNum );
168+ thresholdTime = OS_CYCLES_TO_USEC (osGetCount ()) + 2000000 ; // +2 seconds
169+ while (OS_CYCLES_TO_USEC (osGetCount ()) < thresholdTime ) {
170+ if (osBbUsbGetResetCount (usbNum ) > usbResetCount ) {
171+ usbLineUnstable = 1 ;
151172 break ;
152173 }
153174 }
154175 }
155176
156- D_8001639C = (D_80016390 != 0 ) || (D_80016394 == 0 );
177+ // Type A or stable
178+ usbNotConnected = usbTypeA || !usbLineUnstable ;
157179 osBbSetErrorLed (0 );
158- if (D_8001639C != 0 ) {
159- if (temp_s3 != 0 ) {
180+ if (usbNotConnected ) {
181+ if (sa2Entrypoint != NULL ) {
182+ // No USB, SA2
160183 __osDisableInt ();
161184
162- * (Struct_Unk * )PHYS_TO_K1 (0x04A80100 ) = D_80033458 ;
185+ * (Struct_Unk * )PHYS_TO_K1 (0x04A80100 ) = appSavedState ;
163186
164- func_80002D94 ( temp_s3 , D_8001AF40 );
187+ sa1BootSA2 ( sa2Entrypoint , skBootValue );
165188 } else {
166- func_80004390 (& D_800178B0 , D_800178A0 );
167- func_800033CC ();
189+ // No USB, no SA2
190+ sa1DisplayImage (& sa1Image2Data , sa1Image2Size );
191+ sa1CommandLoop ();
168192 }
169193 } else {
170- func_80004390 (& D_800164A0 , D_80016490 );
171- func_800033CC ();
194+ // USB
195+ sa1DisplayImage (& sa1Image1Data , sa1Image1Size );
196+ sa1CommandLoop ();
172197 }
173198 osBbPowerOff ();
174199}
175200#else
176- INCLUDE_ASM ("asm/nonmatchings/sa1/1050" , func_8000234C );
201+ INCLUDE_ASM ("asm/nonmatchings/sa1/1050" , sa1MainThread );
177202#endif
0 commit comments