--- # Entry point - name: start signature: fn() -> ! desc: Executable start inline_comments: 0x80056280: Zero out ZeroStart .. HeapStart word by word. 0x80056284: ^ 0x80056288: ^ 0x8005628c: ^ 0x800562a8: Initialize stack to (*StackTop - 0x10) | 0x80000000 0x800562f8: "args: (HeapStart + 0x4, (*StackTop - 0x10) - *StackSize - (HeapStart & 0x1fff_ffff))" 0x80056314: "Seems to never be reached, as we get to the title screen before this instruction" 0x80056324: "args: (something1_data2, something1_data2)" labels: 0x80056280: zero_loop start_pos: 0x80056270 end_pos: 0x80056330 kind: Known # Main game loop - name: main_loop signature: fn() -> ! desc: Runs the main loop of the game. Never seems to return. inline_comments: 0x80013e50: The return address is stored, but it seems it's never popped. 0x80013e54: Just sets `something1_executed` to 1. 0x80013e5c: Setup interrupts and DMA and possibly other stuff. 0x80013e6c: "args: (0)" 0x80013e84: "args: (0x140, 0xf0, 0, 0)" labels: 0x80013ef4: "0" 0x80013f04: "1" 0x80013f48: "2" 0x80013f54: "3" 0x80013f6c: "4" 0x80013f8c: "5" start_pos: 0x80013e4c end_pos: 0x80013fa4 kind: Known # ??? - name: something1 signature: fn() desc: If something1_executed is 0, sets it to 1. Also calls `call_func_arr(something1_data2, something1_data2)` if 0, but this seems to be a nop. inline_comments: 0x80056348: If *something1_executed != 0, skip 0x80056350: Else set it to 1. 0x80056368: "args: (something1_data2, something1_data2). Seems like a nop?" labels: 0x80056370: skip start_pos: 0x80056330 end_pos: 0x80056388 kind: Known - name: call_func_arr desc: |- Calls all functions from `start` to `end` (exclusive). Since it's only called from `start` and `something1` with no functions, it seems that this is never used. After running the game for a bit it doesn't seem to be triggered, all the way from the start of a new game to the battle arena fight. signature: "fn(start: *fn(), end: *fn())" inline_comments: 0x800563a0: If `start >= end`, return 0x800563a8: Load the current function 0x800563b0: If it was null, skip the call. 0x800563b8: Else call it 0x800563c0: Go to the next function 0x800563c8: Until we hit `end`, keep going. labels: 0x800563a8: loop 0x800563c0: skip_call 0x800563d0: exit start_pos: 0x80056388 end_pos: 0x800563e4 kind: Known # ? - name: something3 signature: fn() desc: Calls `something5`. inline_comments: 0x80056604: "Loads FuncList1[3]" 0x8005660c: "Calls FuncList1[3] (i.e. something5)" start_pos: 0x800565f4 end_pos: 0x80056624 kind: Known # ? - name: something5 signature: fn() desc: Setups interrupt and DMA. If called again, simply returns. inline_comments: 0x8005679c: Loads *something5_data1 0x800567a4: "If the loaded value is not zero, exit" 0x800567c0: Stop all interrupts by writing 0 to I_MASK 0x800567c4: "Before the write goes through, save the current interrupts (?)" 0x800567cc: Set I_STAT to the previous I_MASK value. 0x800567dc: Set the DMA control registers to 0x33333333 0x800567e0: "args: (something5_data1, 0x33333333), Zero out `something5_data1[..0x33333333]`" 0x800567e8: "Save all registers with `save_registers` and check return value" 0x800567f0: "If the return value isn't 0, call `func_831`. This shouldn't happen, as `save_registers` always returns 0" 0x800567f8: "args: (something5_data1 as *u8 + 0x38, 0x41a)" 0x80056810: "Set the exception exit function as something5_data5 - 1; args: (something5_data5 as *u8 - 0x4)" 0x80056814: Set something5_data5 to 0xfdc labels: 0x80056850: exit 0x80056800: skip_call start_pos: 0x80056788 end_pos: 0x80056860 kind: Known # ? - name: something6 signature: "fn(arg: u32)" desc: "" inline_comments: 0x80056404: Get the gpu status from `GPU_STAT` 0x80056408: Read the horizontal retrace from timer1 0x80056418: Read the horizontal retrace again. 0x80056420: While the horizontal retraces are different, loop. 0x8005642c: "TODO: Check what this load is about, it's 0 at the start of the program. Seems to store the result from the timing" 0x80056438: Get the difference between data_w462 and the current horizontal retrace timer. 0x8005643c: "If arg < 0, return something6_data1, (Note: `main_loop` doesn't supply any arguments)" 0x80056458: If arg == 1, return the difference between data_w462 and the current time & 0xFFFF. 0x80056460: If arg <= 0, $v0 = data_w463, else $v0 = data_w463 + arg - 1 0x80056488: If arg <= 0, $a1 = 0, else $a1 = arg - 1 0x80056494: "args: arg <= 0 ? (data_w463, 0) : (data_w463 + arg - 1, arg - 1)" labels: 0x80056408: timer_loop 0x80056454: skip_exit 0x80056480: 2 0x80056488: 3 0x80056494: 4 0x800564f0: 5 0x80056508: 6 0x80056520: 7 0x80056544: exit_with_s1 0x80056548: exit start_pos: 0x800563e4 end_pos: 0x8005655c kind: Known # ? - name: something7 signature: "fn(a: u32, b: u32)" inline_comments: 0x80056578: If something6_data1 >= a, return 0x8005659c: If (b << 15 - 1) != -1, goto try_again 0x800565dc: If something6_data1 < a, try again, else exit. 0x800565a8: "args: (0x8001311c)" 0x800565b0: "args: (0)" 0x800565bc: "args: (0x3, 0), This call and the above one seem to setup interrupts" labels: 0x80056584: try_start 0x800565cc: try_again 0x800565e4: exit start_pos: 0x8005655c end_pos: 0x800565f4 kind: Known #? - name: something4 signature: fn() labels: 0x80056ac0: "0" 0x80056ae0: "1" 0x80056b04: "2" 0x80056b1c: "3" 0x80056b34: "4" 0x80056b44: "5" 0x80056b54: "6" 0x80056b58: "7" start_pos: 0x80056a30 end_pos: 0x80056b78 kind: Known - name: memset_zero signature: "fn(u32* ptr, u32 size)" desc: "Zeroes out the memory at `ptr` for `size` words.\n" inline_comments: 0x80056c90: "If size == 0, return" 0x80056c94: size-- 0x80056c9c: "*ptr = 0" 0x80056ca0: size-- 0x80056ca4: "While size != -1, continue" 0x80056ca8: ptr++ labels: 0x80056c9c: loop 0x80056cac: exit start_pos: 0x80056c90 end_pos: 0x80056cb4 kind: Known - name: save_registers signature: fn(u32* pos) desc: "Saves the following registers in `pos[0x0 .. 0x30]`.\n$ra, $gp, $sp, $fp,\n$s0, $s1, $s2, $s3,\n$s4, $s5, $s6, $s7,\n" start_pos: 0x8006a674 end_pos: 0x8006a6b0 kind: Known - name: load_registers signature: fn(u32* pos) desc: "Loads the following registers from `pos[0x0 .. 0x30]`.\n$ra, $gp, $sp, $fp,\n$s0, $s1, $s2, $s3,\n$s4, $s5, $s6, $s7,\n" labels: 0x8006a6f4: "0" start_pos: 0x8006a6b0 end_pos: 0x8006a6fc kind: Known - name: prng_next signature: fn() desc: |- Advances the current prng, stored at `cur_prng_value`. Returns `cur_prng_value << 0x10 | 0x7fff`. start_pos: 0x80069124 end_pos: 0x80069154 kind: Known - name: something8 signature: "fn(a: u32, b: u32, c: u32, d: u32)" desc: "" inline_comments: 0x80061910: "args: ($s1, $s0, c & 0xffff, d & 0xffff)" start_pos: 0x800618e4 end_pos: 0x80061954 kind: Known - name: modify_spu_delay1 signature: "fn() -> u32" desc: |- Sets `SPU_DELAY` to `(SPU_DELAY & 0xf0fffff) | 0x2000ffff` and returns the new value inline_comments: 0x8004b434: "$v0 = *SPU_DELAY" 0x8004b44c: "*SPU_DELAY = $v0" start_pos: 0x8004b428 end_pos: 0x8004b450 kind: Known - name: modify_spu_delay2 signature: "fn() -> u32" desc: |- Sets `SPU_DELAY` to `(SPU_DELAY & 0xf0fffff) | 0x2200ffff` and returns the new value inline_comments: 0x8004b45c: "$v0 = *SPU_DELAY" 0x8004b474: "*SPU_DELAY = $v0" start_pos: 0x8004b450 end_pos: 0x8004b478 kind: Known - name: calc_0x890e6fbd signature: "fn() -> u32" desc: |- Simply calculates and returns `0x890e6fbd`. inline_comments: 0x8004b480: "$sp[0x4] = 0xd;" 0x8004b488: "$sp[0x4] = 0x0;" 0x8004b4a4: "$sp[0x4] *= 13;" 0x8004b4b4: "$sp[0x0] += 1;" 0x8004b4c4: "if $sp[0x0] <= 0x3c { goto .loop; }" comments: 0x8004b48c: |- let value = 0xd; for _ in 0..0x3c { value *= 13; } return value; labels: 0x8004b48c: "loop" 0x8004b4b8: "while_condition" start_pos: 0x8004b478 end_pos: 0x8004b4d4 kind: Known - name: something9 start_pos: 0x80013fa4 end_pos: 0x800141b8 kind: Known labels: 0x80013fe4: "0" 0x80014058: "1" 0x80014064: "2" 0x80014094: "3" 0x80014198: "4" 0x8001419c: "5" - name: something10 start_pos: 0x800141b8 end_pos: 0x800142d0 kind: Known labels: 0x800141ec: "0" 0x80014268: "1" 0x800142a4: "2" 0x800142c0: "3" - name: something11 labels: 0x8001431c: "0" 0x80014320: "1" 0x8001434c: "2" start_pos: 0x800142d0 end_pos: 0x80014364 kind: Known - name: something12 labels: 0x8001537c: "0" 0x800153a0: "1" 0x800153b8: "2" 0x80015408: "3" 0x80015420: "4" 0x8001542c: "5" 0x80015510: "6" 0x80015554: "7" 0x80015578: "8" 0x800155a8: "9" 0x800155e8: "10" 0x800155f4: "11" 0x800156a8: "12" start_pos: 0x80015328 end_pos: 0x800157b0 kind: Known - name: something13 labels: 0x80014914: "0" 0x8001494c: "1" 0x80014968: "2" start_pos: 0x800148f8 end_pos: 0x80014970 kind: Known - name: something14 start_pos: 0x80014b94 end_pos: 0x80014c08 kind: Known - name: something15 labels: 0x8002a7f0: "0" 0x8002a800: "1" 0x8002a850: "2" 0x8002a864: "3" 0x8002a870: "4" 0x8002a87c: "5" 0x8002a888: "6" 0x8002a8a8: "7" 0x8002a8bc: "8" 0x8002a918: "9" 0x8002a934: "10" 0x8002a950: "11" 0x8002a970: "12" 0x8002a978: "13" 0x8002a9a0: "14" 0x8002a9b4: "15" 0x8002a9b8: "16" 0x8002aa14: "17" 0x8002aa4c: "18" 0x8002aa74: "19" 0x8002aac4: "20" 0x8002aafc: "21" 0x8002ab14: "22" 0x8002ab28: "23" 0x8002ab4c: "24" 0x8002ab54: "25" start_pos: 0x8002a7cc end_pos: 0x8002ab5c kind: Known - name: something16 labels: 0x8001b3a0: "0" 0x8001b3bc: "1" 0x8001b3fc: "2" start_pos: 0x8001b358 end_pos: 0x8001b438 kind: Known - name: something17 labels: 0x8002c1e0: "0" 0x8002c21c: "1" 0x8002c274: "2" 0x8002c2ac: "3" 0x8002c2b4: "4" 0x8002c2b8: "5" 0x8002c2c8: "6" 0x8002c2cc: "7" 0x8002c384: "8" 0x8002c3d8: "9" 0x8002c408: "10" 0x8002c44c: "11" 0x8002c450: "12" 0x8002c4ac: "13" 0x8002c4c4: "14" 0x8002c520: "15" 0x8002c574: "16" 0x8002c5a0: "17" 0x8002c624: "18" 0x8002c63c: "19" 0x8002c648: "20" 0x8002c650: "21" 0x8002c698: "22" 0x8002c6d4: "23" 0x8002c768: "24" 0x8002c76c: "25" 0x8002c7c4: "26" 0x8002c7dc: "27" 0x8002c820: "28" 0x8002c874: "29" 0x8002c8a0: "30" 0x8002c924: "31" 0x8002c93c: "32" 0x8002c948: "33" 0x8002c950: "34" 0x8002c998: "35" 0x8002c9d4: "36" 0x8002caa8: "37" 0x8002cab0: "38" 0x8002cab4: "39" 0x8002cb30: "40" 0x8002cb54: "41" 0x8002cb7c: "42" 0x8002cbb0: "43" 0x8002cbd4: "44" 0x8002cbf4: "45" 0x8002cbfc: "46" 0x8002cc14: "47" 0x8002cc38: "48" start_pos: 0x8002c1c0 end_pos: 0x8002cc44 kind: Known - name: something18 labels: 0x80015a4c: "0" 0x80015a64: "1" 0x80015a88: "2" 0x80015ab4: "3" 0x80015ac4: "4" 0x80015ac8: "5" start_pos: 0x80015a3c end_pos: 0x80015ad8 kind: Known - name: something19 labels: 0x80016330: "0" 0x80016384: "1" 0x800163a4: "2" 0x800163bc: "3" 0x800163e0: "4" 0x800163ec: "5" 0x80016434: "6" 0x80016458: "7" 0x80016490: "8" 0x800164ac: "9" 0x800164b4: "10" 0x800164e4: "11" 0x80016540: "12" 0x8001658c: "13" 0x800165ac: "14" 0x800165c4: "15" 0x800165e8: "16" 0x800165f4: "17" 0x8001663c: "18" 0x80016660: "19" 0x80016690: "20" 0x800166ac: "21" 0x800166b4: "22" 0x80016708: "23" 0x8001676c: "24" 0x800167a8: "25" 0x800167b0: "26" 0x800167d0: "27" 0x800167fc: "28" 0x80016814: "29" 0x8001683c: "30" 0x80016848: "31" 0x80016868: "32" 0x80016870: "33" start_pos: 0x800162f0 end_pos: 0x80016878 kind: Known - name: something20 labels: 0x80019990: "0" 0x800199c8: "1" 0x80019a6c: "2" 0x80019abc: "3" 0x80019b08: "4" 0x80019b34: "5" 0x80019b74: "6" 0x80019b88: "7" 0x80019bb8: "8" 0x80019be4: "9" 0x80019c04: "10" 0x80019c58: "11" 0x80019c84: "12" 0x80019cd0: "13" 0x80019cfc: "14" 0x80019d34: "15" 0x80019d60: "16" 0x80019d80: "17" 0x80019d88: "18" 0x80019d8c: "19" 0x80019db0: "20" 0x80019e64: "21" start_pos: 0x8001963c end_pos: 0x80019ea4 kind: Known - name: something21 labels: 0x8001a21c: "0" 0x8001a228: "1" 0x8001a27c: "2" 0x8001a2b4: "3" 0x8001a2d8: "4" 0x8001a314: "5" 0x8001a32c: "6" 0x8001a370: "7" 0x8001a37c: "8" 0x8001a380: "9" 0x8001a390: "10" 0x8001a3c4: "11" 0x8001a474: "12" 0x8001a520: "13" 0x8001a5a0: "14" 0x8001a5ec: "15" start_pos: 0x8001a1d8 end_pos: 0x8001a600 kind: Known - name: something22 labels: 0x8001a874: "0" 0x8001a940: "1" 0x8001a970: "2" 0x8001a980: "3" 0x8001a994: "4" 0x8001a998: "5" start_pos: 0x8001a870 end_pos: 0x8001a9b0 kind: Known - name: something23 labels: 0x8001b0bc: "0" 0x8001b0d4: "1" 0x8001b0f4: "2" 0x8001b0f8: "3" start_pos: 0x8001b088 end_pos: 0x8001b10c kind: Known - name: something24 labels: 0x8001b770: "0" 0x8001b7b8: "1" 0x8001b7d8: "2" 0x8001b840: "3" 0x8001b8a8: "4" 0x8001b8e8: "5" start_pos: 0x8001b734 end_pos: 0x8001b90c kind: Known - name: something25 labels: 0x8001bb4c: "0" 0x8001bb60: "1" 0x8001bb68: "2" 0x8001bb80: "3" 0x8001bb8c: "4" start_pos: 0x8001bb44 end_pos: 0x8001bb94 kind: Known - name: something26 labels: 0x8001bc84: "0" start_pos: 0x8001bc38 end_pos: 0x8001bca4 kind: Known - name: something27 labels: 0x8001c124: "0" 0x8001c12c: "1" 0x8001c144: "2" 0x8001c16c: "3" 0x8001c190: "4" 0x8001c1a0: "5" 0x8001c1b0: "6" start_pos: 0x8001c0a8 end_pos: 0x8001c1e0 kind: Known - name: something28 labels: 0x8001c27c: "0" 0x8001c290: "1" 0x8001c29c: "2" 0x8001c2ac: "3" 0x8001c2e0: "4" 0x8001c2e4: "5" 0x8001c394: "6" 0x8001c3dc: "7" 0x8001c3e4: "8" 0x8001c400: "9" 0x8001c434: "10" 0x8001c444: "11" 0x8001c454: "12" 0x8001c46c: "13" 0x8001c4a8: "14" 0x8001c4b8: "15" 0x8001c5b0: "16" 0x8001c5c8: "17" 0x8001c680: "18" 0x8001c724: "19" 0x8001c72c: "20" 0x8001c748: "21" 0x8001c770: "22" 0x8001c798: "23" 0x8001c7a4: "24" 0x8001c890: "25" 0x8001c898: "26" 0x8001c8b4: "27" 0x8001c93c: "28" 0x8001c9c4: "29" 0x8001cacc: "30" 0x8001cad8: "31" 0x8001caf4: "32" 0x8001cb10: "33" 0x8001cb2c: "34" 0x8001cbb4: "35" 0x8001cc3c: "36" 0x8001cc48: "37" 0x8001cd2c: "38" 0x8001cd38: "39" 0x8001cd54: "40" 0x8001cd70: "41" 0x8001cd8c: "42" 0x8001cda8: "43" 0x8001cdd0: "44" 0x8001ce00: "45" 0x8001ce0c: "46" 0x8001ced0: "47" 0x8001ceec: "48" 0x8001cf14: "49" 0x8001cf84: "50" 0x8001cfb0: "51" 0x8001d044: "52" 0x8001d060: "53" 0x8001d07c: "54" 0x8001d098: "55" 0x8001d0b4: "56" 0x8001d0dc: "57" 0x8001d0e8: "58" 0x8001d148: "59" 0x8001d17c: "60" 0x8001d210: "61" 0x8001d22c: "62" 0x8001d248: "63" 0x8001d264: "64" 0x8001d2e0: "65" 0x8001d30c: "66" 0x8001d390: "67" 0x8001d3ac: "68" 0x8001d410: "69" 0x8001d43c: "70" 0x8001d4c0: "71" 0x8001d4dc: "72" 0x8001d4f8: "73" 0x8001d55c: "74" 0x8001d588: "75" 0x8001d608: "76" 0x8001d624: "77" 0x8001d67c: "78" 0x8001d6a8: "79" 0x8001d730: "80" 0x8001d768: "81" 0x8001d7ac: "82" 0x8001d7c8: "83" 0x8001d84c: "84" 0x8001d88c: "85" 0x8001d8d0: "86" 0x8001d8ec: "87" start_pos: 0x8001c220 end_pos: 0x8001d900 kind: Known - name: something29 labels: 0x8001da98: "0" 0x8001dad0: "1" 0x8001db4c: "2" 0x8001db8c: "3" 0x8001dc30: "4" 0x8001dc70: "5" 0x8001dcec: "6" 0x8001dd2c: "7" 0x8001ddac: "8" 0x8001dde4: "9" 0x8001de28: "10" 0x8001de44: "11" 0x8001decc: "12" 0x8001df04: "13" 0x8001df80: "14" 0x8001dfc0: "15" start_pos: 0x8001da24 end_pos: 0x8001dfe0 kind: Known - name: something30 labels: 0x8001e240: "0" 0x8001e280: "1" 0x8001e364: "2" 0x8001e3a4: "3" 0x8001e418: "4" 0x8001e43c: "5" 0x8001e440: "6" 0x8001e45c: "7" 0x8001e474: "8" 0x8001e480: "9" 0x8001e484: "10" 0x8001e4a0: "11" 0x8001e4bc: "12" 0x8001e4cc: "13" 0x8001e4d0: "14" start_pos: 0x8001e180 end_pos: 0x8001e53c kind: Known - name: something31 labels: 0x8001e87c: "0" 0x8001e884: "1" start_pos: 0x8001e850 end_pos: 0x8001e894 kind: Known - name: something32 labels: 0x8001f0d8: "0" 0x8001f0f4: "1" 0x8001f148: "2" 0x8001f170: "3" 0x8001f174: "4" 0x8001f344: "5" 0x8001f394: "6" start_pos: 0x8001f094 end_pos: 0x8001f3c0 kind: Known - name: something33 labels: 0x8001f5f0: "0" start_pos: 0x8001f5cc end_pos: 0x8001f5fc kind: Known - name: something34 labels: 0x8001f654: "0" start_pos: 0x8001f630 end_pos: 0x8001f660 kind: Known - name: something35 labels: 0x8001f708: "0" 0x8001f728: "1" 0x8001f760: "2" start_pos: 0x8001f6c4 end_pos: 0x8001f768 kind: Known - name: something36 labels: 0x8001f7bc: "0" 0x8001f7e4: "1" 0x8001f81c: "2" start_pos: 0x8001f768 end_pos: 0x8001f824 kind: Known - name: something37 labels: 0x8001f85c: "0" 0x8001f870: "1" 0x8001f8a8: "2" start_pos: 0x8001f824 end_pos: 0x8001f8b0 kind: Known - name: something38 labels: 0x8001f8f4: "0" 0x8001f90c: "1" 0x8001f944: "2" start_pos: 0x8001f8b0 end_pos: 0x8001f94c kind: Known - name: something39 labels: 0x8005ab04: "0" 0x8005ab3c: "1" start_pos: 0x8005aa7c end_pos: 0x8005ab4c kind: Known - name: something40 start_pos: 0x8005a7d4 end_pos: 0x8005a808 kind: Known - name: something41 start_pos: 0x80049e80 end_pos: 0x80049ef8 kind: Known - name: something42 labels: 0x8004b320: "0" 0x8004b340: "1" 0x8004b370: "2" 0x8004b378: "3" 0x8004b38c: "4" inline_comments: 0x8004b2f0: "Division by 0" start_pos: 0x8004b2f0 end_pos: 0x8004b394 kind: Known # A functions - name: InitHeap signature: "fn(addr: *u32, size: u32)" desc: Calls A(0x39) inline_comments: 0x8006a738: Register tailcall. Likely to prevent calling in KSEG0 and do it in KUSEG 0x8006a73c: "arg: 0x39" start_pos: 0x8006a734 end_pos: 0x8006a744 kind: Known - name: FlushCache signature: "fn()" desc: Calls A(0x44) start_pos: 0x8006a744 end_pos: 0x8006a754 kind: Known - name: GPU_cw signature: "fn(cmd: u32)" desc: Calls A(0x49) start_pos: 0x8006a754 end_pos: 0x8006a764 kind: Known - name: _bu_init signature: "fn()" desc: Calls A(0x70) start_pos: 0x80068804 end_pos: 0x80068814 kind: Known - name: CdRemove signature: "fn()" desc: Calls A(0x72) start_pos: 0x8006a76c end_pos: 0x8006a77c kind: Known - name: _card_info signature: "fn(port: u32)" desc: Calls A(0xab) start_pos: 0x80068814 end_pos: 0x80068824 kind: Known - name: _card_async_load_directory signature: "fn(port: u32)" desc: Calls A(0xac) start_pos: 0x80068824 end_pos: 0x80068834 kind: Known # B Functions - name: DeliverEvent signature: "fn(class: u32, spec: u32)" desc: Calls B(0x07) start_pos: 0x8006a784 end_pos: 0x8006a794 kind: Known - name: OpenEvent signature: "fn(class: u32, spec: u32, mode: u32, func: u32)" desc: Calls B(0x08) start_pos: 0x8006a794 end_pos: 0x8006a7a4 kind: Known - name: WaitEvent signature: "fn(event: u32)" desc: Calls B(0x0a) start_pos: 0x8006a7a4 end_pos: 0x8006a7b4 kind: Known - name: TestEvent signature: "fn(event: u32)" desc: Calls B(0x0b) start_pos: 0x8006a7b4 end_pos: 0x8006a7c4 kind: Known - name: EnableEvent signature: "fn(event: u32)" desc: Calls B(0x0c) start_pos: 0x8006a7c4 end_pos: 0x8006a7d4 kind: Known - name: InitPad signature: "fn(buf1: *mut u8, size1: u32, buf2: *mut u8, size2: u32)" desc: Calls B(0x12) start_pos: 0x8006af54 end_pos: 0x8006af64 kind: Known - name: StartPad signature: "fn()" desc: Calls B(0x13) start_pos: 0x8006af64 end_pos: 0x8006af74 kind: Known - name: OutdatedPadInitAndStart signature: "fn(type: u32, button_dest: *mut u8, unused1: u32, unused2: u32)" desc: Calls B(0x15) start_pos: 0x8006af74 end_pos: 0x8006af84 kind: Known - name: ReturnFromException signature: "fn()" desc: Calls B(0x17) start_pos: 0x8006a7d4 end_pos: 0x8006a7e4 kind: Known - name: SetDefaultExitFromException signature: "fn()" desc: Calls B(0x18) start_pos: 0x8006a7e4 end_pos: 0x8006a7f4 kind: Known - name: SetCustomExitFromException signature: "fn(addr: fn())" desc: Calls B(0x19) start_pos: 0x8006a7f4 end_pos: 0x8006a804 kind: Known - name: FileOpen signature: "fn(filename: *const str, access_mode: u32)" desc: Calls B(0x32) start_pos: 0x8006a824 end_pos: 0x8006a834 kind: Known - name: FileSeek signature: "fn(fd: u32, offset: u32, seek_type: u32)" desc: Calls B(0x33) start_pos: 0x8006a834 end_pos: 0x8006a844 kind: Known - name: FileRead signature: "fn(fd: u32, dst: *mut u8, length: u32)" desc: Calls B(0x34) start_pos: 0x8006a844 end_pos: 0x8006a854 kind: Known - name: FileWrite signature: "fn(fd: u32, src: *const u8, length: u32)" desc: Calls B(0x35) start_pos: 0x8006a854 end_pos: 0x8006a864 kind: Known - name: FileClose signature: "fn(fd: u32)" desc: Calls B(0x36) start_pos: 0x8006a864 end_pos: 0x8006a874 kind: Known - name: firstfile signature: "fn(filename: *const str, dir_entry: u32)" desc: Calls B(0x42) start_pos: 0x8006acb4 end_pos: 0x8006acc4 kind: Known - name: nextfile signature: "fn(dir_entry: u32)" desc: Calls B(0x43) start_pos: 0x8006a874 end_pos: 0x8006a884 kind: Known - name: InitCard signature: "fn(pad_enable: u32)" desc: Calls B(0x4a) start_pos: 0x80068994 end_pos: 0x800689a4 kind: Known - name: StartCard signature: "fn()" desc: Calls B(0x4b) start_pos: 0x800689a4 end_pos: 0x800689b4 kind: Known - name: StopCard signature: "fn()" desc: Calls B(0x4c) start_pos: 0x800689b4 end_pos: 0x800689c4 kind: Known - name: write_card_sector signature: "fn(port: u32, sector: u32, src: *const u8)" desc: Calls B(0x4e) start_pos: 0x80068874 end_pos: 0x80068884 kind: Known - name: read_card_sector signature: "fn(port: u32, sector: u32, dst: *mut u8)" desc: Calls B(0x4f) start_pos: 0x80069024 end_pos: 0x80069034 kind: Known - name: allow_new_card signature: "fn()" desc: Calls B(0x50) start_pos: 0x80068884 end_pos: 0x80068894 kind: Known - name: ChangeClearPad signature: "fn(pad: u32)" desc: Calls B(0x5b) start_pos: 0x8006a884 end_pos: 0x8006a894 kind: Known - name: get_card_status signature: "fn(slot: u32)" desc: Calls B(0x5c) start_pos: 0x80069034 end_pos: 0x80069044 kind: Known # C Functions - name: SysEnqIntRP signature: "fn(priority: u32, struct: u32)" desc: Calls C(0x02) start_pos: 0x8006af84 end_pos: 0x8006af94 kind: Known - name: SysDeqIntRP signature: "fn(priority: u32, struct: u32)" desc: Calls C(0x03) start_pos: 0x8006af94 end_pos: 0x8006afa4 kind: Known - name: ChangeClearRCnt signature: "fn(t: u32, flag: u32)" desc: Calls C(0x0a) start_pos: 0x8006a894 end_pos: 0x8006a8a0 kind: Known # Std - name: sprintf signature: "fn sprintf(buffer: *char, format: *const char, ...) -> i32" inline_comments: 0x80069d6c: "if *buffer == '\\0' { goto.65; }" 0x80069d84: "if *buffer == '%' { goto .58; }" comments: 0x80069d24: "Save arguments on wasted space." 0x80069d30: |- Reserve stack space and save all additional registers there labels: 0x80069d84: "0" 0x80069db4: "1" 0x80069de8: "2" 0x80069e04: "3" 0x80069e14: "4" 0x80069e30: "5" 0x80069e4c: "6" 0x80069e84: "7" 0x80069e98: "8" 0x80069ed4: "9" 0x80069ee0: "10" 0x80069f34: "11" 0x80069f70: "12" 0x80069f7c: "13" 0x80069f9c: "14" 0x80069fbc: "15" 0x80069fc0: "16" 0x80069fe4: "17" 0x80069ff0: "18" 0x80069FFC: "66" 0x8006a008: "19" 0x8006a028: "20" 0x8006a058: "21" 0x8006a06c: "22" 0x8006a080: "23" 0x8006a0b0: "24" 0x8006a0b4: "25" 0x8006a0f4: "26" 0x8006a108: "27" 0x8006a118: "28" 0x8006a14c: "29" 0x8006a164: "30" 0x8006a180: "31" 0x8006a1a0: "32" 0x8006a1d0: "33" 0x8006a1f4: "34" 0x8006a208: "35" 0x8006a210: "36" 0x8006a22c: "37" 0x8006a268: "38" 0x8006a280: "39" 0x8006a2a0: "40" 0x8006a2b4: "41" 0x8006a2c0: "42" 0x8006a2c8: "43" 0x8006a2f8: "44" 0x8006a328: "45" 0x8006a33c: "46" 0x8006a344: "47" 0x8006a364: "48" 0x8006a380: "49" 0x8006a39c: "50" 0x8006a3cc: "51" 0x8006a3ec: "52" 0x8006a43c: "53" 0x8006a458: "54" 0x8006a478: "55" 0x8006a4a4: "56" 0x8006a4ac: "57" 0x8006a4b8: "58" 0x8006a4c4: "59" 0x8006a4ec: "60" 0x8006a514: "61" 0x8006a518: "62" 0x8006a534: "63" 0x8006a550: "64" 0x8006a570: "65" start_pos: 0x80069d24 end_pos: 0x8006a5a4 kind: Known - name: memcpy_args_reversed signature: "fn(src: *const u8, dst: *mut u8, len: u32) -> *mut u8" desc: |- `memcpy` with the first two arguments swapped. inline_comments: 0x80069044: "if src == NULL { return 0; }" 0x80069048: "" 0x8006904c: "if len <= 0 { return src; }" comments: 0x80069054: |- do { *dst = *src; src += 1; len -= 1; dst += 1; } while (len > 0) labels: 0x80069054: "loop" 0x8006906c: "end" 0x80069070: "on_null" start_pos: 0x80069044 end_pos: 0x80069078 kind: Known - name: mem_zero signature: "fn(dst: *mut u8, len: u32) -> *mut u8" desc: |- Zeroes out `len` bytes of `dst`. If `len <= 0`, returns `NULL`. Otherwise returns `dst`. inline_comments: 0x80069084: "if dst == NULL { return 0; }" 0x80069088: "" 0x8006908c: "" 0x80069090: "if len > 0 { _ret = dst; }" 0x80069094: "if len <= 0 { return 0; }" comments: 0x8006909c: |- do { *dst = 0; len -= 1; dst += 1; } while (len > 0) labels: 0x8006909c: "loop" 0x800690ac: "end" start_pos: 0x80069084 end_pos: 0x800690b4 kind: Known - name: memcpy signature: "fn(dst: *mut u8, src: *const u8, len: u32) -> *mut u8" inline_comments: 0x800690b4: "if ptr == NULL { return 0; }" 0x800690b8: "" 0x800690bc: "if len <= 0 { return 0; }" comments: 0x800690c4: |- do { *dst = *src; src += 1; len -= 1; dst += 1; } while (len > 0) labels: 0x800690c4: "loop" 0x800690dc: "end" 0x800690e0: "on_null" start_pos: 0x800690b4 end_pos: 0x800690e8 kind: Known - name: memset signature: "fn(dst: *mut u8, value: u32, len: u32) -> *mut u8" inline_comments: 0x800690f4: "if ptr == NULL { return 0; }" 0x800690f8: "" 0x800690fc: "" 0x80069100: "if len > 0 { _ret = ptr; }" 0x80069104: "if len <= 0 { return 0; }" comments: 0x8006910c: |- do { *dst = value; len -= 1; ptr += 1; } while (len > 0) labels: 0x8006910c: "loop" 0x8006911c: "end" start_pos: 0x800690f4 end_pos: 0x80069124 kind: Known - name: strcat signature: "fn(dst: *mut u8, src: *const u8) -> *mut u8" desc: "" inline_comments: 0x8006917c: "if dst == NULL { return NULL; }" 0x80069180: "" 0x80069184: "if src == NULL { return NULL; }" 0x8006918c: "let dst_len = strlen(dst);" 0x80069190: "" 0x80069194: "" 0x80069198: "let src_len = strlen(src);" 0x800691a4: "if dst + dst_len == src + src_len { return NULL; }" 0x800691b4: "dst += 1; if *dst == 0 { goto go_back_1_dst; }" 0x800691cc: "dst -= 1;" 0x800691e8: "return dst;" comments: 0x800691ac: |- Skips `dst` until it hits one-past '\\0'. Then backs up one and begins appending `src` 0x800691bc: |- // Note: This causes `dst` to be one-past the null. do { let tmp = *dst; dst += 1; } while tmp != 0 0x800691d0: |- // Note: The null is copied in this loop too. do { let tmp = *src; *dst = src; src += 1; dst += 1; } while tmp != 0 labels: 0x800691bc: "advance_dst_until_past_null" 0x800691cc: "go_back_1_dst" 0x800691d0: "loop" 0x800691ec: "on_null" 0x800691f0: "exit" start_pos: 0x80069164 end_pos: 0x80069208 kind: Known - name: strlen signature: "fn(ptr: *const u8) -> u32" desc: "" inline_comments: 0x800692d8: "if ptr == NULL { return 0; }" labels: 0x800692e8: "increase_len" 0x800692ec: "loop" 0x80069300: "on_null" start_pos: 0x800692d4 end_pos: 0x80069308 kind: Known # TODO: Investigate this more, seems weird - name: strcmp signature: "fn(lhs: *const u8, rhs: *const u8) -> u32" desc: "" inline_comments: 0x80069214: "if lhs == NULL { goto .lhs_null; }" 0x8006921c: "if rhs != NULL { goto .start_cmp; }" 0x80069224: "if lhs == rhs { return 0; } // Same as `rhs == NULL`" 0x80069228: "" 0x8006922c: "if lhs == NULL { return -1; } // Always true?" 0x80069234: "// Dead code?" 0x8006925c: "rhs += 1;" 0x80069248: "lhs += 1;" 0x8006926c: "return lhs[0] - rhs[-1]; // Note: This is because we don't advance `lhs` when we don't take the branch" comments: 0x8006924c: |- // Note: Includes the code from `.2` and `.1` loop { let left = *lhs; let right = *rhs; rhs += 1; if left == right { if *right == 0 { return 0; } } } 0x8006926c: |- // This is because we update `rhs` prematurely in the previous loop. // Note: This returns the lexicographic order by comparing the last character. return lhs[0] - rhs[-1]; labels: 0x80069224: "lhs_null" 0x8006923c: "1" 0x80069244: "2" 0x8006924c: "start_cmp" 0x80069270: "exit" start_pos: 0x80069214 end_pos: 0x80069278 kind: Known - name: strcpy signature: "fn(dst: *mut u8, src: *const u8) -> *mut u8" desc: "" inline_comments: 0x80069284: "if dst == NULL { return NULL; }" 0x80069288: "" 0x8006928c: "if dst == NULL { return NULL; }" 0x800692bc: "// Returns the original `lhs`" comments: 0x80069294: |- let tmp = *rhs; rhs += 1; *lhs = tmp; lhs += 1; if tmp == 0 { return lhs; } 0x800692a8: |- do { let tmp = *rhs; rhs += 1; *lhs = tmp; lhs += 1; if tmp == 0 { return lhs; } } labels: 0x800692a8: "loop" 0x800692bc: "end" 0x800692c0: "on_null" start_pos: 0x80069284 end_pos: 0x800692c8 kind: Known