Notes:Missing Parts Side A: The Tantei Stories
This page contains notes for the game Missing Parts Side A: The Tantei Stories.
Contents
Encryption
This game's file contents are encrypted. Each archive I believe is encrypted slightly differently. In the below sections is the code in MIPS ASM responsible for decrypting audio in real time from DAT15.BIN. To simply extract from this archive, use the below quickBMS script along with the XOR.TBL file. To play the resulting .AWA audio files, one can use vgmstream.
BMS script:
# DAT15.BIN extractor from Missing Parts Side A (PS2) by bnnm # decryption algorithm by punk7890 open FDSE "DAT15.BIN" 0 open FDSE "XOR.TBL" 1 idstring "Mps2" get FILES long callfunction MEM_DECRYPT_INIT 1 # read XOR get TBL_SIZE asize 1 log MEMORY_FILE8 0x00 TBL_SIZE 1 # decrypt TOC at MEMORY_FILE9 log MEMORY_FILE9 0x00 0x800 0 callfunction TOC_DECRYPT 1 #log "TOC" 0x00 0x800 MEMORY_FILE9 goto 0x18 MEMORY_FILE9 for I = 0 < FILES get OFFSET long MEMORY_FILE9 get SIZE long MEMORY_FILE9 getdstring NAME 0x10 MEMORY_FILE9 #print "%I%: %OFFSET|h%, %SIZE|h%, %NAME%" #if I == 16 #|| I = 8 log MEMORY_FILE8 0 0 log MEMORY_FILE8 OFFSET SIZE #string NAME2 p= "%s.enc" NAME #log NAME2 0x00 SIZE MEMORY_FILE8 callfunction AWA_DECRYPT 1 log NAME 0x00 SIZE MEMORY_FILE8 #endif next I ### startfunction MEM_DECRYPT_INIT set MEMORY_FILE10 string " short get_s16le(unsigned char* p) { return (p[0]) | (p[1]<<8); } unsigned short get_u16le(unsigned char* p) { return (p[0]) | (p[1]<<8); } unsigned int get_u32le(unsigned char* p) { return (p[0]) | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); } void put_u32le(unsigned char* buf, unsigned int v) { buf[0] = (v >> 0) & 0xFF; buf[1] = (v >> 8) & 0xFF; buf[2] = (v >> 16) & 0xFF; buf[3] = (v >> 24) & 0xFF; } void put_u16le(unsigned char* buf, unsigned int v) { buf[0] = (v >> 0) & 0xFF; buf[1] = (v >> 8) & 0xFF; } void decrypt_toc(unsigned char* hdr, unsigned char* tbl, unsigned int tbl_size, int files) { int hdr_o = 0x18; int tbl_o = tbl_size - hdr_o - 0x04; int max_o = 0x18 + files * 0x18; while (hdr_o < max_o) { unsigned int xor, val; xor = get_u32le(tbl + tbl_o); val = get_u32le(hdr + hdr_o); val ^= xor; put_u32le(hdr + hdr_o, val); hdr_o += 0x04; tbl_o -= 0x04; } } void decrypt_awa(unsigned char* buf, unsigned int offset, unsigned int size, char* name) { /* decrypt header + first bytes */ unsigned int seed = offset ^ 0xFFFFFFFF; //NOR unsigned int key = (seed + size) & 0xFFFFFFFF; unsigned int pos = 0x00; while (pos < 0x20) { unsigned int val = get_u32le(buf + pos); //LE val = val ^ key; put_u32le(buf + pos, val); key -= 0x03E5; if (key < 0) key = 0xFFFFFFFF + key; pos += 0x04; } /* decrypt random bytes based on name */ // 0025ba60 for (int i = 0; i < 0x10; i++) { unsigned char letter = name[i]; // toc[name_offset + i]; if (letter == '\0') break; unsigned int key = letter; pos = (key << 3) - key + 0x20; key = (key ^ 0xFFFFFFFF) & 0xFF; //buf[i] = letter; //buf[i+0x10] = pos; buf[pos] ^= key; } /* decrypt body */ unsigned int key_s0, key_t6, key_t7; unsigned int key_v1 = 0x00FF; //fixed unsigned int key_t2 = 0x4F; //volume unsigned int key_a0 = 0x0000; //increases by 0x100 pos = 0x18; while (pos < size) { int val_s2, val_s1, val; //00262bc4 val_s2 = get_s16le(buf + pos); val = (val_s2 ^ 0x7F00); /* original function does decrypt and interpolation+volume with next sample, * but that step is skipped here since it's not part of decoding */ /* if (pos >= size - 0x04) val_s1 = 0; else val_s1 = get_s16le(buf + pos + 0x04); //00262bcc key_t6 = key_a0 & 0x00FF; //always 0x0000? key_t7 = key_v1 - key_t6; //always 0x00FF? //00262bd4 key_s0 = 0x0000; //s0 = existing sample in output buffer (probably for mono?) //00262bd8 val_s2 = (val_s2 ^ 0x7F00); val_s2 = (val_s2 * key_t7); //00262be0 val_s1 = (val_s1 ^ 0x7F00); val_s1 = (val_s1 * key_t6); //mult1: sets acc=1? val = (int)((unsigned)val_s2 + (unsigned)val_s1); //s1 //00262bec val = val >> 8; //val = val * key_t2; //val = val >> 7; val = val + key_s0; //00262bfc if (val > 0x7FFF) val = 0x7FFF; else if (val < -0x8000) val = -0x8000; */ //00262c28 put_u16le(buf + pos, val); //00262c2c //(repeat for R samples, looks the same, uses different pos counter) //00262c64 pos += 0x02; //00262c94 key_a0 += 0x100; } } " endfunction startfunction TOC_DECRYPT # C decryption goto 0 MEMORY_FILE8 goto 0 MEMORY_FILE9 calldll MEMORY_FILE10 "decrypt_toc" "tcc" RET MEMORY_FILE9 MEMORY_FILE8 TBL_SIZE FILES endfunction startfunction AWA_DECRYPT # math OFFSET = MEM_DECRYPT_ARG1 # math SIZE = MEM_DECRYPT_ARG2 # # C decryption goto 0 MEMORY_FILE8 calldll MEMORY_FILE10 "decrypt_awa" "tcc" RET MEMORY_FILE8 OFFSET SIZE NAME endfunction # XOR.TBL # 96300777 2C610EEE BA510999 19C46D07 8FF46A70 35A563E9 A395649E 3288DB0E # A4B8DC79 1EE9D5E0 88D9D297 2B4CB609 BD7CB17E 072DB8E7 911DBF90 6410B71D # F220B06A 4871B9F3 DE41BE84 7DD4DA1A EBE4DD6D 51B5D4F4 C785D383 56986C13 # C0A86B64 7AF962FD ECC9658A 4F5C0114 D96C0663 633D0FFA F50D088D C8206E3B # 5E10694C E44160D5 727167A2 D1E4033C 47D4044B FD850DD2 6BB50AA5 FAA8B535 # 6C98B242 D6C9BBDB 40F9BCAC E36CD832 755CDF45 CF0DD6DC 593DD1AB AC30D926 # 3A00DE51 8051D7C8 1661D0BF B5F4B421 23C4B356 9995BACF 0FA5BDB8 9EB80228 # 0888055F B2D90CC6 24E90BB1 877C6F2F 114C6858 AB1D61C1 3D2D66B6 9041DC76 # 0671DB01 BC20D298 2A10D5EF 8985B171 1FB5B606 A5E4BF9F 33D4B8E8 A2C90778 # 34F9000F 8EA80996 18980EE1 BB0D6A7F 2D3D6D08 976C6491 015C63E6 F4516B6B # 62616C1C D8306585 4E0062F2 ED95066C 7BA5011B C1F40882 57C40FF5 C6D9B065 # 50E9B712 EAB8BE8B 7C88B9FC DF1DDD62 492DDA15 F37CD38C 654CD4FB 5861B24D # CE51B53A 7400BCA3 E230BBD4 41A5DF4A D795D83D 6DC4D1A4 FBF4D6D3 6AE96943 # FCD96E34 468867AD D0B860DA 732D0444 E51D0333 5F4C0AAA C97C0DDD 3C710550 # AA410227 10100BBE 86200CC9 25B56857 B3856F20 09D466B9 9FE461CE 0EF9DE5E # 98C9D929 2298D0B0 B4A8D7C7 173DB359 810DB42E 3B5CBDB7 AD6CBAC0 2083B8ED # B6B3BF9A 0CE2B603 9AD2B174 3947D5EA AF77D29D 1526DB04 8316DC73 120B63E3 # 843B6494 3E6A6D0D A85A6A7A 0BCF0EE4 9DFF0993 27AE000A B19E077D 44930FF0 # D2A30887 68F2011E FEC20669 5D5762F7 CB676580 71366C19 E7066B6E 761BD4FE # E02BD389 5A7ADA10 CC4ADD67 6FDFB9F9 F9EFBE8E 43BEB717 D58EB060 E8A3D6D6 # 7E93D1A1 C4C2D838 52F2DF4F F167BBD1 6757BCA6 DD06B53F 4B36B248 DA2B0DD8 # 4C1B0AAF F64A0336 607A0441 C3EF60DF 55DF67A8 EF8E6E31 79BE6946 8CB361CB # 1A8366BC A0D26F25 36E26852 95770CCC 03470BBB B9160222 2F260555 BE3BBAC5 # 280BBDB2 925AB42B 046AB35C A7FFD7C2 31CFD0B5 8B9ED92C 1DAEDE5B B0C2649B # 26F263EC 9CA36A75 0A936D02 A906099C 3F360EEB 85670772 13570005 824ABF95 # 147AB8E2 AE2BB17B 381BB60C 9B8ED292 0DBED5E5 B7EFDC7C 21DFDB0B D4D2D386 # 42E2D4F1 F8B3DD68 6E83DA1F CD16BE81 5B26B9F6 E177B06F 7747B718 E65A0888 # 706A0FFF CA3B0666 5C0B0111 FF9E658F 69AE62F8 D3FF6B61 45CF6C16 78E20AA0 # EED20DD7 5483044E C2B30339 612667A7 F71660D0 4D476949 DB776E3E 4A6AD1AE # DC5AD6D9 660BDF40 F03BD837 53AEBCA9 C59EBBDE 7FCFB247 E9FFB530 1CF2BDBD # 8AC2BACA 3093B353 A6A3B424 0536D0BA 9306D7CD 2957DE54 BF67D923 2E7A66B3 # B84A61C4 021B685D 942B6F2A 37BE0BB4 A18E0CC3 1BDF055A 8DEF022D
XOR Table
This file below seeks from bottom to top (32-bit seeks) and uses each entry as a form of getting the real values from an encrypted XOR string in archives. If the 4 bytes after "Mps2" in a archive header isn't encrypted, encrypted offsets begin at 0x18. Total number of files at 0x4 (not generally encrypted. But encrypted in Z.DAT. No idea what this is.). This table begins at 0x0027981C in RAM. Save this table to a file called XOR.TBL if you wish to use the BMS script at the top of the page.
XOR.TBL:
96 30 07 77 2C 61 0E EE BA 51 09 99 19 C4 6D 07 8F F4 6A 70 35 A5 63 E9 A3 95 64 9E 32 88 DB 0E A4 B8 DC 79 1E E9 D5 E0 88 D9 D2 97 2B 4C B6 09 BD 7C B1 7E 07 2D B8 E7 91 1D BF 90 64 10 B7 1D F2 20 B0 6A 48 71 B9 F3 DE 41 BE 84 7D D4 DA 1A EB E4 DD 6D 51 B5 D4 F4 C7 85 D3 83 56 98 6C 13 C0 A8 6B 64 7A F9 62 FD EC C9 65 8A 4F 5C 01 14 D9 6C 06 63 63 3D 0F FA F5 0D 08 8D C8 20 6E 3B 5E 10 69 4C E4 41 60 D5 72 71 67 A2 D1 E4 03 3C 47 D4 04 4B FD 85 0D D2 6B B5 0A A5 FA A8 B5 35 6C 98 B2 42 D6 C9 BB DB 40 F9 BC AC E3 6C D8 32 75 5C DF 45 CF 0D D6 DC 59 3D D1 AB AC 30 D9 26 3A 00 DE 51 80 51 D7 C8 16 61 D0 BF B5 F4 B4 21 23 C4 B3 56 99 95 BA CF 0F A5 BD B8 9E B8 02 28 08 88 05 5F B2 D9 0C C6 24 E9 0B B1 87 7C 6F 2F 11 4C 68 58 AB 1D 61 C1 3D 2D 66 B6 90 41 DC 76 06 71 DB 01 BC 20 D2 98 2A 10 D5 EF 89 85 B1 71 1F B5 B6 06 A5 E4 BF 9F 33 D4 B8 E8 A2 C9 07 78 34 F9 00 0F 8E A8 09 96 18 98 0E E1 BB 0D 6A 7F 2D 3D 6D 08 97 6C 64 91 01 5C 63 E6 F4 51 6B 6B 62 61 6C 1C D8 30 65 85 4E 00 62 F2 ED 95 06 6C 7B A5 01 1B C1 F4 08 82 57 C4 0F F5 C6 D9 B0 65 50 E9 B7 12 EA B8 BE 8B 7C 88 B9 FC DF 1D DD 62 49 2D DA 15 F3 7C D3 8C 65 4C D4 FB 58 61 B2 4D CE 51 B5 3A 74 00 BC A3 E2 30 BB D4 41 A5 DF 4A D7 95 D8 3D 6D C4 D1 A4 FB F4 D6 D3 6A E9 69 43 FC D9 6E 34 46 88 67 AD D0 B8 60 DA 73 2D 04 44 E5 1D 03 33 5F 4C 0A AA C9 7C 0D DD 3C 71 05 50 AA 41 02 27 10 10 0B BE 86 20 0C C9 25 B5 68 57 B3 85 6F 20 09 D4 66 B9 9F E4 61 CE 0E F9 DE 5E 98 C9 D9 29 22 98 D0 B0 B4 A8 D7 C7 17 3D B3 59 81 0D B4 2E 3B 5C BD B7 AD 6C BA C0 20 83 B8 ED B6 B3 BF 9A 0C E2 B6 03 9A D2 B1 74 39 47 D5 EA AF 77 D2 9D 15 26 DB 04 83 16 DC 73 12 0B 63 E3 84 3B 64 94 3E 6A 6D 0D A8 5A 6A 7A 0B CF 0E E4 9D FF 09 93 27 AE 00 0A B1 9E 07 7D 44 93 0F F0 D2 A3 08 87 68 F2 01 1E FE C2 06 69 5D 57 62 F7 CB 67 65 80 71 36 6C 19 E7 06 6B 6E 76 1B D4 FE E0 2B D3 89 5A 7A DA 10 CC 4A DD 67 6F DF B9 F9 F9 EF BE 8E 43 BE B7 17 D5 8E B0 60 E8 A3 D6 D6 7E 93 D1 A1 C4 C2 D8 38 52 F2 DF 4F F1 67 BB D1 67 57 BC A6 DD 06 B5 3F 4B 36 B2 48 DA 2B 0D D8 4C 1B 0A AF F6 4A 03 36 60 7A 04 41 C3 EF 60 DF 55 DF 67 A8 EF 8E 6E 31 79 BE 69 46 8C B3 61 CB 1A 83 66 BC A0 D2 6F 25 36 E2 68 52 95 77 0C CC 03 47 0B BB B9 16 02 22 2F 26 05 55 BE 3B BA C5 28 0B BD B2 92 5A B4 2B 04 6A B3 5C A7 FF D7 C2 31 CF D0 B5 8B 9E D9 2C 1D AE DE 5B B0 C2 64 9B 26 F2 63 EC 9C A3 6A 75 0A 93 6D 02 A9 06 09 9C 3F 36 0E EB 85 67 07 72 13 57 00 05 82 4A BF 95 14 7A B8 E2 AE 2B B1 7B 38 1B B6 0C 9B 8E D2 92 0D BE D5 E5 B7 EF DC 7C 21 DF DB 0B D4 D2 D3 86 42 E2 D4 F1 F8 B3 DD 68 6E 83 DA 1F CD 16 BE 81 5B 26 B9 F6 E1 77 B0 6F 77 47 B7 18 E6 5A 08 88 70 6A 0F FF CA 3B 06 66 5C 0B 01 11 FF 9E 65 8F 69 AE 62 F8 D3 FF 6B 61 45 CF 6C 16 78 E2 0A A0 EE D2 0D D7 54 83 04 4E C2 B3 03 39 61 26 67 A7 F7 16 60 D0 4D 47 69 49 DB 77 6E 3E 4A 6A D1 AE DC 5A D6 D9 66 0B DF 40 F0 3B D8 37 53 AE BC A9 C5 9E BB DE 7F CF B2 47 E9 FF B5 30 1C F2 BD BD 8A C2 BA CA 30 93 B3 53 A6 A3 B4 24 05 36 D0 BA 93 06 D7 CD 29 57 DE 54 BF 67 D9 23 2E 7A 66 B3 B8 4A 61 C4 02 1B 68 5D 94 2B 6F 2A 37 BE 0B B4 A1 8E 0C C3 1B DF 05 5A 8D EF 02 2D
DAT15.BIN Decryption
Header
AWA (music files) decryption (header only): Example of "SONG09.AWA" in DAT15.BIN as how the game does decryption. File header length always 0x20.
$value 1 = 0x00
- NOR start offset of start of the file from the Mps2 table entry by 0x0 (0x168AD000 NOR 0x0 = E9752FFF)
- Add NOR'd start offset + file length together (E9752FFF + 01EE1898 = 0xEB634897)
- Get next 0x4 of the header (Start at @0x0 first.)
- Subtract end result of step #2 and add 0x03E5 to $value 1 together to form a new value. (should still be 0xEB634897 on first pass).
- Xor end result of step #4 and current encrypted header string (32 bit string). Should be 0x56415741 on first pass.
- Store resulting string to current offset, then start from step #3.
Random Byte Decryption
This below function decrypts random bytes based on the file name before it does stream body decryption.
spot_0025ba60
__0025ba60: # jal $002201d0 # 0025ba60:0c088074 ^ FNC_002201d0 lb a0, $0008(v0) # 0025ba64:80440008 #a0=Loads song name (in this case, "SONG09.AWA") sll v1, v0, 3 # 0025ba68:000218c0 #shift left logical v0 by 3. v1=00000298 subu v1, v1, v0 # 0025ba6c:00621823 #sub unsigned v0 - v1. v1=00000245 addu a0, s1, v1 # 0025ba70:02232021 #add unsigned v1 + s1 (s1=stream offset 0x003687C4 in RAM). a0=00368A09 nor v0, v0, zero # 0025ba74:00401027 #NOR zero+v0. v0=FFFFFFAC andi v1, v0, $00ff # 0025ba78:304300ff #AND v0. v1=000000AC lbu v0, $0020(a0) # 0025ba7c:90820020 #load from a0 + 0x00368A09 into v0. v0=0000002C (from 0x265 in SONG09) addiu s3, s3, $0001 # 0025ba80:26730001 #add +1 to s3 (0x0). s3=1 xor v0, v0, v1 # 0025ba84:00431026 #XOR v1 + v0. v0=00000080 sb v0, $0020(a0) # 0025ba88:a0820020 #store v0 to a0 (0x00368A09 + 20). nop # 0025ba8c:00000000 __0025ba90: # jal $0021faa8 # 0025ba90:0c087eaa ^ strlen addiu a0, s0, $0008 # 0025ba94:26040008 #SONG09.AWA text location slt v0, s3, v0 # 0025ba98:0262102a #set v0 (0xA) if v0 less than s3 (0x1). v0=0x1 bne v0, zero, $0025ba60 # 0025ba9c:1440fff0 ^ __0025ba60 addu v0, s0, s3 # 0025baa0:02131021 #add unsigned s3 (0x00000001) + s0 (0x0035A050). v0=0035A051
FNC_002201d0
lui a1, $0028 # 002201d0:3c050028 a1=$00280000 addiu v0, a0, $ffe0 # 002201d4:2482ffe0 #minus -0x20 from a0 (0x4F "O" in "SONG".). v0=0x2F addiu a1, a1, $0a19 # 002201d8:24a50a19 #a1=0x00280A19(loc_00280a18.txt) addu a1, a0, a1 # 002201dc:00852821 #add unsigned a1 + a0. a1=0x00280A68 lbu v1, $0000(a1) # 002201e0:90a30000 #load from 0x00280A68. v1=0x00000001 andi v1, v1, $0002 # 002201e4:30630002 #AND v1 by 0x0002. v1=0 jr ra # 002201e8:03e00008 #return movz v0, a0, v1 # 002201ec:0083100a #if v1=0, move a0 into v0. v0=0x4F
loc_00280a18
addi zero, at, $2000 # 00280a18:20202000 addi zero, at, $2020 # 00280a1c:20202020 slti t0, at, $2020 # 00280a20:28282020 addi t0, at, $2828 # 00280a24:20282828 addi zero, at, $2020 # 00280a28:20202020 addi zero, at, $2020 # 00280a2c:20202020 addi zero, at, $2020 # 00280a30:20202020 addi zero, at, $2020 # 00280a34:20202020 beq zero, s0, $00262abc # 00280a38:10108820 beq zero, s0, $00284a80 # 00280a3c:10101010 beq zero, s0, $00284a84 # 00280a40:10101010 beq zero, s0, $00284a88 # 00280a44:10101010 beq zero, a0, $00281a64 # 00280a50:10040404 beq zero, s0, $00284a98 # 00280a54:10101010 (cop0) $01411010 # 00280a58:41411010 (cop0) $01414141 # 00280a5c:41414141 (movci) zero, t0, at # 00280a60:01010101 (movci) zero, t0, at # 00280a64:01010101 (movci) zero, t0, at # 00280a68:01010101 (movci) zero, t0, at # 00280a6c:01010101 (movci) zero, t0, at # 00280a70:01010101 beq zero, s0, $00284ab8 # 00280a74:10101010 (cop0) $02421010 # 00280a78:42421010 (cop0) $02424242 # 00280a7c:42424242 srl zero, v0, 8 # 00280a80:02020202 srl zero, v0, 8 # 00280a84:02020202 srl zero, v0, 8 # 00280a88:02020202 srl zero, v0, 8 # 00280a8c:02020202 srl zero, v0, 8 # 00280a90:02020202 beq zero, s0, $00284ad8 # 00280a94:10101010 add zero, zero, zero # 00280a98:00000020
Stream Decryption
The below process will output a 16-bit Little Endian raw PCM stream.
# First pass of SONG09.AWA stream data decryption # paddub a0, zero, zero # 00262bb0:70002628 a0=0 addiu v1, zero, $00ff # 00262bb4:240300ff v1=# always 0x000000ff __00262bb8: # sra t5, a0, 8 # 00262bb8:00046a03 #RAM offset calculation not needed sll t5, t5, 2 # 00262bbc:000d6880 #RAM offset calculation not needed addu t5, a3, t5 # 00262bc0:00ed6821 #RAM offset calculation not needed lh s2, $0000(t5) # 00262bc4:85b20000 #s2=FFFF80EB (from 0x18 in SONG09.AWA) lh s1, $0004(t5) # 00262bc8:85b10004 #s1=FFFF80F5 (from 0x1C in SONG09.AWA) andi t6, a0, $00ff # 00262bcc:308e00ff #AND a0 by 0x00FF. t6=0x0 subu t7, v1, t6 # 00262bd0:006e7823 #SUB t6 by v1(0x00FF). t7=0xFF lh s0, $0000(a1) # 00262bd4:84b00000 #s0=0x0 (Unknown. Always 0?) xori s2, s2, $7f00 # 00262bd8:3a527f00 #XOR s2 by 0x7F00. s2=FFFFFFEB mult s2, t7, s2 # 00262bdc:01f29018 #multiply t7 & s2. s2=FFFFEB15 xori s1, s1, $7f00 # 00262be0:3a317f00 #XOR s1 by 0x7F00. s1=FFFFFFF5 mult1 s1, t6, s1 # 00262be4:71d18818 #multiply t6 $ s1? (not sure of this op code). s1=0x0 addu s1, s2, s1 # 00262be8:02518821 #add unsigned s1 + s2. s1=0xFFFFEB15 sra s1, s1, 8 # 00262bec:00118a03 #shift right arithmetic s1 by 8. s1=FFFFFFEB mult s1, s1, t2 # 00262bf0:022a8818 #multiply t2 (t2=0x4F) & s1. s1=FFFFF985 sra s1, s1, 7 # 00262bf4:001189c3 #shift right arithmetic s1 by 7. s1=FFFFFFF3 addu s1, s1, s0 # 00262bf8:02308821 #add unsigned s0 + s1. s1=0xFFFFFFF3 slti at, s1, $8000 # 00262bfc:2a218000 #Check if s1 is over 0x7FFF not needed? beq at, zero, $00262c14 # 00262c00:10200004 #always branches to $00262c14 ori at, zero, $8000 # 00262c04:34018000 at=$00008000 beq zero, zero, $00262c28 # 00262c08:10000007 v __00262c28 addiu s1, zero, $8000 # 00262c0c:24118000 s1=$ffff8000 ori at, zero, $8000 # 00262c10:34018000 at=$00008000 __00262c14: # slt at, s1, at # 00262c14:0221082a #not needed? bne at, zero, $00262c28 # 00262c18:14200003 #always branches to $00262c28 nop # 00262c1c:00000000 addiu s1, zero, $7fff # 00262c20:24117fff s1=$00007fff nop # 00262c24:00000000 __00262c28: # sh s1, $0000(a1) # 00262c28:a4b10000 #not needed lh s1, $0002(t5) # 00262c2c:85b10002 #s1=FFFF80F8 (from 0x1A in SONG09.AWA) lh s0, $0006(t5) # 00262c30:85b00006 #s0=FFFF80E7 (from 0x1E in SONG09.AWA) xori s1, s1, $7f00 # 00262c34:3a317f00 #XOR s1 by 0x7F00. s1=FFFFFFF8 mult s1, t7, s1 # 00262c38:01f18818 #multiply t7 (t7=0xFF) & s1. s1=FFFFF808 lh t5, $0000(t4) # 00262c3c:858d0000 #Unknown. Always 0? xori t7, s0, $7f00 # 00262c40:3a0f7f00 #XOR s0 by 0x7F00 and store result into t7. t7=FFFFFFE7 mult1 t6, t6, t7 # 00262c44:71cf7018 #multiply t6 $ t7? (not sure of this op code). t6=0x0 addu t6, s1, t6 # 00262c48:022e7021 #add unsigned t6 + s1 into t6. t6=0xFFFFF808 sra t6, t6, 8 # 00262c4c:000e7203 #shift right arithmetic t6 by 8. FFFFFFF8 mult t6, t6, t1 # 00262c50:01c97018 #multiply t6 & t1 (t1=0x4F). t6=FFFFFD88 sra t6, t6, 7 # 00262c54:000e71c3 #shift right arithmetic t6 by 7. t6=FFFFFFFB addu t6, t6, t5 # 00262c58:01cd7021 #add unsigned t5 + t6. t6=0xFFFFFFFB slti at, t6, $8000 # 00262c5c:29c18000 #Check if t6 is over 0x7FFF not needed? beq at, zero, $00262c70 # 00262c60:10200003 #Go to 00262c70 addiu a1, a1, $0002 # 00262c64:24a50002 beq zero, zero, $00262c88 # 00262c68:10000007 v __00262c88 addiu t6, zero, $8000 # 00262c6c:240e8000 t6=$ffff8000 __00262c70: # ori at, zero, $8000 # 00262c70:34018000 at=$00008000 slt at, t6, at # 00262c74:01c1082a #Check if t6 is less than AT. Not needed? bne at, zero, $00262c88 # 00262c78:14200003 #Always go to 00262c88 nop # 00262c7c:00000000 addiu t6, zero, $7fff # 00262c80:240e7fff t6=$00007fff nop # 00262c84:00000000 __00262c88: # sh t6, $0000(t4) # 00262c88:a58e0000 sltu t5, a1, t3 # 00262c8c:00ab682b #not needed addiu t4, t4, $0002 # 00262c90:258c0002 #not needed bne t5, zero, $00262bb8 # 00262c94:15a0ffc8 ^ __00262bb8 addu a0, a0, t0 # 00262c98:00882021 #Add t0 + a0 into a0. (increment by a0=0x0100 each pass) beq zero, zero, $0026352c # 00262c9c:10000223 #exit lw v1, $0054(a2) # 00262ca0:8cc30054