boot code runs from 0x1000-0x3F000 80040000 0x1000 start of decompressed ROM segment 80040080 0x1080 copies GS boot code into ram LUI T0,B0C0 ORI T0,T0,1000 ;T0=B0C01000: ROM address? LUI T1,8004 LUI T2,0003 ORI T2,T2,F000 ;T2=size of data //80040094: 0x1094 copy GS ROM to dram 80040000 LW T3,0000 (T0) ;T3=word at B0C01000 ADDIU T0,T0,0004 ;next address SW T3,0000 (T1) ;word->80040000 ADDIU T2,T2,FFFC ;count-=4 BNEZ T2,0x1094 ;loop for 0x3F000 bytes ADDIU T1,T1,0004 ;next address //800400AC: 0x10AC LUI T0,8000 ;T0=80000000: start address ADDIU T1,T0,3000 ADDIU T1,T1,FFF0 ;T1=80002FF0: end address //800400B8: 0x10B8 writeback invalidate first 3Kb CACHE T0,D IndexWInvalid ;primary data, Index Writeback Invalidate SLTU AT,T1,T0 BNEZ AT,0x10B8 ADDIU T0,T0,0010 //800400C8: 0x10C8 LUI T0,8000 ;T0=80000000: start address ADDIU T1,T0,6000 ADDIU T1,T1,FFE0 ;T1=80005FE0: end address //800400D4: 0x10D4 invalidate first 6Kb CACHE T0,I IndexInvalid ;primary instruction,Index Invalidate SLTU AT,T0,T1 BNEZ AT,0x10D4 ADDIU T0,T0,0020 //800400E4: 0x10E4 set stack pointer and continue initialization LUI SP,803F ORI SP,SP,FF00 ;SP=803FFF00 J 80040180 ;set up and execute shell NOP 800400F4 0x10F4 set up VI_REGS LUI T0,A440 LUI T1,0001 ORI T1,T1,3002 SW T1,0000 (T0) ;set VI_STATUS attributes (rather generic, actually) LUI T1,8000 SW T1,0004 (T0) ;this has to be the only game in the world that stores its screens at 0 ADDIU T1,R0,0140 SW T1,0008 (T0) ;VI_H_WIDTH LUI T1,03E5 ORI T1,T1,2239 SW T1,0014 (T0) ;VI_TIMING ADDIU T1,R0,020D SW T1,0018 (T0) ;VI_V_SYNC ADDIU T1,R0,0C15 SW T1,001C (T0) ;VI_H_SYNC LUI T1,0C15 ORI T1,T1,0C15 SW T1,0020 (T0) ;VI_H_LEAP LUI T1,006C ORI T1,T1,02EC SW T1,0024 (T0) ;VI_H_VIDEO LUI T1,0025 ORI T1,T1,01FF SW T1,0028 (T0) ;VI_V_VIDEO LUI T1,000E ORI T1,T1,0204 SW T1,002C (T0) ;VI_V_BURST ADDIU T1,R0,0200 SW T1,T0,0030 ;VI_X_SCALE ADDIU T1,R0,0400 SW T1,T0,0034 ;VI_Y_SCALE BGEZ R0, -1 ;infinite loop, possibly waiting for interrupt to kick it out NOP 80040180 0x1180 set up and execute the shell and trainer ADDIU SP,SP,FFE8 SW S0,0010 (SP) ADDU S0,R0,R0 ;S0=0 count LUI A0,0002 ORI A0,A0,57FF ;A0=257FF LUI V1,8030 SW RA,0014 (SP) //8004019C: 0x119C initialize memory 80300000-80396000 SW R0,0000 (V1) ;0->80300000+offset ADDIU S0,S0,0001 ;S0++ count++ SLT V0,A0,S0 BEQ V0,R0,0x119C ;loop from 80300000-80396000 ADDIU V1,V1,0004 ;V1+=4 next word //800401B0: 0x11B0 set up dynamic memory allocation table JAL 80042488 ;set 0x8 in PIFram RESERVED reg ADDU S0,R0,R0 ;S0=0 count LUI A0,8018 ;A0=80180000: p->start JAL 80042100 ;set dynamic memory table from A0 to A1 LUI A1,8020 ;A1=80200000: p->end JAL 800402D8 ;draw boot screen and logo NOP JAL 80042584 ;display A0 to LCD screen ADDIU A0,R0,0035 ;A0='5' //800401D4: 0x11D4 wait for vsync JAL 800424C0 ;waits for VI refresh ADDIU S0,S0,0001 ;S0++ SLTI V0,S0,003C BNEZ V0,0x11D4 ;repeat 60 times NOP //800401E8: 0x11E8 tick down count on LCD screen JAL 80042584 ;display A0 to LCD screen ADDIU A0,R0,0034 ;A0='4' ADDU S0,R0,R0 ;S0=0: count //800401F4: 0x11F4 wait for vsync JAL 800424C0 ;waits for VI refresh ADDIU S0,S0,0001 ;S0++ SLTI V0,S0,003C BNEZ V0,0x11F4 ;repeat 60 times NOP //80040208: 0x1208 load shell JAL 80042584 ;display A0 to LCD screen ADDIU A0,R0,0033 ;A0='3' LUI S0,8020 ;S0=80200000 ORI A0,A0,0400 ;A0=should be 80200400 maybe I accidentally altered line above? LUI A1,8004 JAL 80041FCC ;decompress filename A1 to A0 ADDIU A1,A1,29C0 ;A1=800429C0: "shell.bin" //80040224: 0x1224 load trainer JAL 80042584 ;display A0 to LCD screen ADDIU A0,R0,0032 ;A0='2' LUI A0,8078 ORI A0,A0,0800 ;A0=80780800: p->target LUI A1,8004 JAL 80041FCC ;decompress filename A1 to A0 ADDIU A1,A1,29CC ;A1=800429CC: "trainer.bin" //80040240: 0x1240 tick down count on LCD screen JAL 80042584 ;display A0 to LCD screen ADDIU A0,R0,0031 ;A0='1' ADDU S0,R0,R0 //8004024C: 0x124C wait for vsync JAL 800424C0 ;waits for VI refresh ADDIU S0,S0,0001 SLTI V0,S0,003C BNE R0,V0 -4 ;loop 60 times LUI A0,8020 //80040260: 0x1260: jump to the shell JAL 80042330 ;JAL A0 ORI A0,A0,0400 ;A0=80200400 //80040268: 0x1268 return LW RA,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0018 80040278 0x1278 ADDIU SP,SP,FFE0 LUI A0,B200 SW S1,0014 (SP) LUI S1,8004 LUI V0,0060 SW RA,0018 (SP) SW S0,0010 (SP) JAL 80040600 SW V0,2AA0 (S1) ;80042AA0=600000 //0x129C oddly, directly pulls a bit of rom... LUI S0,B2C0 LW S0,0000 (S0) ;this either pulls mirrored cart rom or first word of GS rom JAL 80040600 LUI A0,BE00 //0x12AC LUI V1,8037 ORI V1,V1,1240 ;V1=80371240 LW RA,0018 (SP) LUI V0,0040 SW V0,2AA0 (S1) LW S1,0014 (SP) XOR S0,S0,V1 SLTIU V0,S0,0001 LW S0,0010 (SP) JR RA ADDIU SP,SP,0020 800402D8 0x12D8 draw boot screen and logo ADDIU SP,SP,FFD8 SW RA,0020 (SP) SW S3,001C (SP) SW S2,0018 (SP) SW S1,0014 (SP) JAL 8004043C ;loads and copies "tile1.tg~" to video buffer SW S0,0010 (SP) //800402F4: 0x12F4 load gs logo palettes LUI S3,8028 ADDU A0,S3,R0 ;A0=S3: 80280000 p->target LUI A1,8004 JAL 80041FCC ;decompress filename A1 to A0 ADDIU A1,A1,29D8 ;A1=800429D8: "gslogo3.pal" //80040308: 0x1308 load gslogo image ADDU S0,S3,R0 ORI S0,S0,1001 ;S0=80281001 ADDU A0,S3,R0 ORI A0,A0,1000 ;A0=80281000: p->target LUI A1,8004 JAL 80041FCC ;decompress filename A1 to A0 ADDIU A1,A1,29E4 ;A1=800429E4: "gslogo3.bin" //80040324: 0x1324 ADDIU S2,R0,0028 ;S2=40 (0x28) LUI S1,8030 ORI S1,S1,6400 ;S1=80306400 //80040330: 0x1330 JAL 800422C0 ;set cache for first 6Kb NOP //80040338: 0x1338 load pixels from binary, look up index, and save to video memory ADDIU T0,R0,0019 ADDIU A3,S1,0032 ;A3=80306432: target for logo in video memory LBU V0,0000 (S0) ;V0=80281001: index from bin SLL V1,V0,0001 ADDU V1,V1,V0 ;V1=index*3: offset in palette ADDU V1,S3,V1 ;V1+=S3: pal+offset LBU A0,0000 (V1) ;A0=pal+0: red LBU A1,0001 (V1) ;A1=pal+1: green LBU A2,0002 (V1) ;A2=pal+2: blue ADDU V0,A1,A0 ADDU V0,A2,V0 ;V0=r+g+b: test each was set and pulled validly BLEZ V0 +7 ADDIU S0,S0,0001 ;S0++ count.pal++ SLL V0,A0,0011 ;V0=red*20000: what they really wanted was 1<<0xB SLL V1,A1,0006 ;V1=green*40: mask 07C0 OR V0,V0,V1 SLL V1,A2,0001 ;V1=blue*2: mask 003E OR V0,V0,V1 ;V0|=V1: (r)|g|b SH V0,0000 (A3) ;V0->A3+offset: save to video memory //80040384: loop for entire row ADDIU T0,T0,0001 SLTI V0,T0,0129 BNE R0,V0 -14 ADDIU A3,A3,0002 ;A3+=2 next pixel in target //80040394: 0x1394 loop for each row ADDIU S2,S2,0001 ;S2++ count.row++ SLTI V0,S2,00B8 BNE R0,V0 -1C ;loop for each row ADDIU S1,S1,0280 ;S1+=280: next row //800403A4: 0x13A4 set up video LUI V1,0001 ORI V1,V1,3002 ;V1=00013002 LUI A0,03E5 ORI A0,A0,2239 ;A0=03E52239 LUI T0,0C15 ORI T0,T0,0C15 ;T0=0C150C15 LUI A3,006C ORI A3,A3,02EC ;A3=006C02EC LUI A2,0025 ORI A2,A2,01FF ;A2=002501FF LUI A1,000E ORI A1,A1,0204 ;A1=000E0204 LUI V0,A440 SW V1,0000 (V0) ;00013002->VI_STATUS LUI V1,8030 SW V1,0004 (V0) ;80300000->VI_DRAM ADDIU V1,R0,0140 SW V1,0008 (V0) ;140->VI_H_WIDTH ADDIU V1,R0,020D SW V1,0018 (V0) ;20D->VI_V_SYNC ADDIU V1,R0,0C15 SW V1,001C (V0) ;C15->VI_H_SYNC ADDIU V1,R0,0200 SW V1,0030 (V0) ;200->VI_X_SCALE ADDIU V1,R0,0400 SW A0,0014 (V0) ;03E52239->VI_TIMING SW T0,0020 (V0) ;0C150C15->VI_H_SYNC SW A3,0024 (V0) ;006C02EC->VI_H_VIDEO SW A2,0028 (V0) ;002501FF->VI_V_VIDEO SW A1,002C (V0) ;000E0204->VI_V_BURST SW V1,0034 (V0) ;400->VI_Y_SCALE LW RA,0020 (SP) LW S3,001C (SP) LW S2,0018 (SP) LW S1,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0028 8004043C 0x143C loads and copies "tile1.tg~" to video buffer ADDIU SP,SP,FFE0 SW S2,0018 (SP) LUI S2,8021 ADDU A0,S2,R0 ;A0=S2: 80210000 LUI A1,8004 ADDIU A1,A1,29F0 ;A1=800429F0: "tile1.tg~" SW RA,001C (SP) SW S1,0014 (SP) JAL 80041FCC ;decompress filename A1 to A0 SW S0,0010 (SP) //80040464: do an odd colour conversion on pixels ADDU A0,S2,R0 ;A0=80210000: p->tile1 ADDU S1,R0,R0 ;S1=0 ADDU S0,R0,R0 ;S0=0 //80040470: flip and mask each pixel in row LHU V0,0000 (A0) ;V0=pixel ADDIU S0,S0,0001 ;S0++ count.pixel++ SRL V1,V0,0x7 ;V1=V0>>7 masks V0&FF80 ANDI V0,V0,007F ;V0&=7F SLL V0,V0,0x9 ;V0*=200: V0->red (FE00) OR V1,V1,V0 ;V1|=V0: SRL V1,V1,0x1 ;V1/=2: remove alpha ANDI V1,V1,7BDE ;V1&=7BDE: darken to 4bit, remove alpha (bitwise, 0111101111011110) SH V1,0000 (A0) ;V1->pixel SLTI V0,S0,0040 BNE V0,R0,-11 ;loop for 64 pixels ADDIU A0,A0,0002 ;A0+=2: next pixel //800404A0: loop for each row ADDIU S1,S1,0001 ;S1++ count.row++ SLTI V0,S1,0030 BNE V0,R0,-15 ;loop for 48 rows ADDU S0,R0,R0 ;S0=0 ADDU S1,R0,R0 ;S1=0 //800404B4: copy image to 80300000 video buffer ADDU A0,S0,R0 ;A0=S0: xpos ADDU A1,S1,R0 ;A1=S1: ypos JAL 800404FC ;copy image A2 to output {A0,A1} ADDU A2,S2,R0 ;A2=S2: p->tile1 ADDIU S0,S0,0040 ;S0+=40 SLTI V0,S0,0140 ;TRUE if S0 < scanline BNE V0,R0,-6 ;loop for scanline (5x) ADDU A0,S0,R0 ;A0=S0: ADDIU S1,S1,0030 ;S1+=30 SLTI V0,S1,00F0 ;TRUE if S1 < #scanlines BNE V0,R0,-11 ;loop for each row (to end of image) ADDU S0,R0,R0 ;S0=0 //800404E4: return LW RA,001C (SP) LW S2,0018 (SP) LW S1,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0020 800404FC 0x14FC copy image A2 to output {A0,A1}; draws 1/5 screen accepts: A0=xpos, A1=ypos, A2=p->image ADDU A3,R0,R0 ;A3=0 init.count.row SLL V0,A1,0x2 ADDU V0,V0,A1 SLL V0,V0,0x7 ;V0=A1*280: ypos * 2 * 140 (#pixels per row) SLL A0,A0,0x1 ;A0*=2: offset to pixel in row LUI V1,8030 ADDU A0,A0,V1 ;A0+=80300000: base + pixel offset ADDU A1,V0,A0 ;A1=A0+V0: base + pixel + row //8004051C: copy 1/5 screen from source to given position in output ADDU A0,R0,R0 ;A0=0 init.count.pixel ADDU V1,A1,R0 ;V1=A1: p->pixel at {A0,A1} //80040524: loop and copy pixel data for row LHU V0,0000 (A2) ;V0=pixel in image ADDIU A2,A2,0002 ;A2+=2: next pixel in source ADDIU A0,A0,0001 ;A0++ count.pixel SH V0,0000 (V1) ;V0->V1+offset: save pixel to base{A0,A1} SLTI V0,A0,0040 BNE V0,R0,-6 ;fill a row ADDIU V1,V1,0002 ;V1+=2: next pixel in target //80040540: loop for 48 rows ADDIU A3,A3,0001 ;A3++ SLTI V0,A3,0030 BNE V0,R0,-12 ;loop 48 times ADDIU A1,A1,0280 ;A1+=280: next row //80040550: return JR RA NOP 80040558 0x1558 likely data ;ANDI V0,V0,0003 ;BNE V0,R0,-3 80040560 0x1560 wait until PI Status clear LUI V1,A460 LW V0,0010 (V1) ;V0=A4600010: PI Status ANDI V0,V0,0003 BNE V0,R0,-3 ;loop until status clear NOP JR RA NOP 8004057C 0x157C accepts: A0=offset SW S0,0010 (SP) ADDIU SP,SP,FFE8 LUI V0,8004 LUI V1,8004 SW S0,0010 (SP) LW S0,2AA4 (V0) ;S0=80042AA4: hardware bank LW V0,2AA0 (V1) ;V0=80042AA0: hardware address range SW RA,0014 (SP) OR S0,S0,V0 JAL 80040560 ;wait until PI Status clear OR S0,S0,A0 LW V0,0000 (S0) LW RA,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0018 800405BC 0x15BC save A1 to cur.hardware + offset A0 ADDIU SP,SP,FFE8 ANDI A1,A1,FFFF SLL V1,A1,0x10 LUI V0,8004 LUI A2,8004 LW V0,2AA4 (V0) LW A2,2AA0 (A2) OR V1,V1,A1 SW RA,0010 (SP) OR V0,V0,A2 OR V0,V0,A0 SW V1,0000 (V0) JAL 80040560 ;wait until PI Status clear NOP LW RA,0010 (SP) JR RA ADDIU SP,SP,0018 80040600 0x1600 ADDIU SP,SP,FFE8 LUI V0,0F00 SW S0,0010 (SP) AND S0,A0,V0 ;S0=A0 & 0F000000: retain the lower nibble of hardware address range LUI V0,1000 OR S0,S0,V0 ;S0|=10000000: S0->hardware address ADDIU A0,R0,0400 ;A0=400 SW RA,0014 (SP) JAL 800405BC ;save A1 to cur.hardware + offset A0 SRL A1,S0,0x18 ;A1=hardware range (first byte of address) //80040628: LUI V1,8004 LUI V0,B000 LW RA,0014 (SP) OR S0,S0,V0 ;S0|=B0000000: S0->virtual hardware addy SW S0,2AA4 (V1) ;S0->80042AA4: hardware bank LW S0,0010 (SP) JR RA ADDIU SP,SP,0018 80040648 0x1648 ADDIU SP,SP,FFE8 LUI A1,007F ORI A1,A1,F7FF ;A1=007FF7FF SW RA,0010 (SP) JAL 800405BC ;save A1 to cur.hardware + offset A0 ADDIU A0,R0,0600 ;A0=600 LW RA,0010 (SP) JR RA ADDIU SP,SP,0018 8004066C 0x166C accepts: A0=??? ADDIU SP,SP,FFD8 SW S3,001C (SP) ADDU S3,A0,R0 SW RA,0020 (SP) SW S2,0018 (SP) SW S1,0014 (SP) JAL 80040648 SW S0,0010 (SP) ADDIU S1,R0,0001 LUI S2,0200 ORI S2,S2,0200 ;S2=02000200 AND V0,S3,S1 //8004069C: BEQ V0,R0,800406AC ADDU S0,R0,R0 ;S0=0 LUI S0,0100 ORI S0,S0,0100 ;S0=01000100 //800406AC: ADDIU A0,R0,0800 ;A0=800 JAL 800405BC ;save A1 to cur.hardware + offset A0 ADDU A1,S0,R0 ;A1=S0: ADDIU A0,R0,0800 ;A0=800 JAL 800405BC ;save A1 to cur.hardware + offset A0 OR A1,S0,S2 ;A1=S0 | 02000200 ADDIU A0,R0,0800 ;A0=800 JAL 800405BC ;save A1 to cur.hardware + offset A0 ADDU A1,S0,R0 ;A1=S0 SLL S1,S1,0x1 SLTI V0,S1,0100 BNEL V0,R0,8004069C AND V0,S3,S1 //800406E0: return LW RA,0020 (SP) LW S3,001C (SP) LW S2,0018 (SP) LW S1,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0028 800406FC 0x16FC V0=TRUE if entry A0 found and loaded and whatnot accepts: A0=??? (byte) ADDIU SP,SP,FFD0 LUI V0,8004 ADDU V1,R0,R0 ;V1=0 count ADDIU A1,SP,0010 ;A1=SP+10: p->buffer ANDI A0,A0,00FF SW RA,0028 (SP) ADDIU T1,V0,2A00 ;T1=80042A00: table of lookups and values LWL A2,0000 (T1) LWR A2,0003 (T1) LWL A3,0004 (T1) LWR A3,0007 (T1) LWL T0,0008 (T1) LWR T0,000B (T1) SWL A2,0010 (SP) SWR A2,0013 (SP) SWL A3,0014 (SP) SWR A3,0017 (SP) SWL T0,0018 (SP) SWR T0,001B (SP) LWL A2,000C (T1) LWR A2,000F (T1) LWL A3,0010 (T1) LWR A3,0013 (T1) LB T0,0014 (T1) SWL A2,001C (SP) SWR A2,001F (SP) SWL A3,0020 (SP) SWR A3,0023 (SP) SB T0,0024 (SP) LB A2,0015 (T1) SB A2,0025 (SP) ;copy table to stack //80040778: look for an entry matching A0 ADDU V0,A1,V1 ;V0=p->buffer+count LBU V0,0000 (V0) ;V0=number BNEL V0,A0,+7 ;loop if doesn't match A0 ADDIU V1,V1,0002 ;V1+=2 offset to next entry ADDU V0,V1,A1 ;V0=p->buffer+count LBU A0,0001 (V0) ;A0=sample JAL 8004066C NOP J 800407B0 ;return ADDIU V0,R0,0001 ;V0=TRUE //800407A0: 0x17A0 SLTIU V0,V1,0016 BNE V0,R0,-11 ADDU V0,A1,V1 ADDU V0,R0,R0 ;V0=FALSE //800407B0: 0x17B0 return LW RA,0028 (SP) JR RA ADDIU SP,SP,0030 800407BC 0x17BC SW RA,0018 (SP) JR RA NOP 800407C8 0x17C8 ADDIU SP,SP,FFE0 SW RA,0018 (SP) SW S1,0014 (SP) BEQ A0,R0,+7 SW S0,0010 (SP) LUI A0,8004 LUI V1,8004 LW V0,2A58 (A0) LW V1,2A44 (V1) OR V0,V0,V1 SW V0,2A58 (A0) LUI S0,8004 LW V0,2A44 (S0) SRL V0,V0,0x1 BNE V0,R0,+27 SW V0,2A44 (S0) LUI A1,8004 LUI V0,8004 LUI S1,8004 ADDIU A0,S1,2A58 LW V1,2A70 (A1) LW V0,2A88 (V0) LBU A0,0003 (A0) ADDU V0,V0,V1 SB A0,0000 (V0) LUI V0,8004 LW V0,2A8C (V0) ADDIU V1,V1,0001 SW V1,2A70 (A1) SLT V1,V1,V0 BNE V1,R0,+5 LUI V0,8004 LUI A0,8004 JAL 800407C0 ADDIU A0,A0,2A20 LUI V0,8004 LW V1,2AB4 (V0) ADDIU A0,R0,0080 SW R0,2A58 (S1) SW A0,2A44 (S0) ADDIU V1,V1,0001 SW V1,2AB4 (V0) LW RA,0018 (SP) LW S1,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0020 80040884 0x1884 ADDIU SP,SP,FFE8 SW S0,0010 (SP) ADDU S0,R0,R0 SW RA,0014 (SP) JAL 800407C8 ADDU A0,R0,R0 ADDIU S0,S0,0001 SLTI V0,S0,0007 BNE V0,R0,-5 NOP LW RA,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0018 800408BC 0x18BC grab happy bit LUI A2,8004 LW V0,2A40 (A2) ;V0=80042A40: mask for data control byte SRL V0,V0,0x1 ;V0>>1 pull one bit from value BNEZ V0,0x1900 ;branch if more data SW V0,2A40 (A2) ;update value //800408D0: 0x18D0 feed another byte from source LUI A0,8004 LUI V0,8004 LW V1,2A50 (A0) ;V1=80042A50: inpos LW V0,2A6C (V0) ;V0=80042A6C: p->source ADDU V0,V0,V1 ;V0=p->indata ADDIU V1,V1,0001 ;V1++ LBU A1,0000 (V0) ;A1=next byte of data ADDIU V0,R0,0080 SW V0,2A40 (A2) ;0x80->80042A40: good for next 8 bits, making last bit LUI V0,8004 SW V1,2A50 (A0) ;update inpos SW A1,2A54 (V0) ;data->80042A54: data control byte //80040900: 0x1900 LUI V0,8004 LW V0,2A54 (A2) ;V0=80042A54: data LW V1,2A40 (A2) ;V1=80042A40: mask for last bit in data byte AND V0,V0,V1 ;mask last bit JR RA SLTU V0,R0,V0 ;TRUE if nonzero 80040918 0x1918 ADDIU V1,R0,1001 LUI V0,8004 LW V0,2A84 (V0) ADDIU A1,R0,1000 ADDIU A0,V0,4004 SW A1,0000 (A0) ADDIU V1,V1,0001 SLTI V0,V1,1101 BNE V0,R0,-4 ADDIU A0,A0,0004 ADDIU A0,R0,1000 LUI V0,8004 LW V0,2A68 (V0) ADDIU V1,R0,0FFF ADDIU V0,V0,3FFC SW A0,0000 (V0) ADDIU V1,V1,FFFF BGEZ V1,-3 ADDIU V0,V0,FFFC JR RA NOP 8004096C 196C ADDU T4,A0,R0 ADDIU A2,R0,0001 ADDIU T7,R0,1000 LUI V0,8004 ADDU T6,V0,R0 LUI V0,8004 LUI T5,8004 LUI V1,8004 LW V0,2A84 (V0) LW V1,2A78 (V1) ADDU T3,V0,R0 LUI V0,8004 ADDU T0,V1,R0 ADDU A3,T0,T4 LW V0,2A68 (V0) LBU A1,0000 (A3) SLL A0,T4,0x2 SW R0,2A5C (T6) ADDU T8,A0,V0 LUI V0,8004 LW V0,2A80 (V0) ADDIU T2,A1,1001 ADDU T1,V0,R0 ADDU V1,A0,T1 ADDU V0,T7,R0 ADDU A0,A0,T3 SW V0,0000 (V1) SW V0,0000 (A0) BLTZ A2,+8 SLL V0,T2,0x2 ADDU V0,V0,T3 LW V1,0000 (V0) BNEL V1,T7,+9 ADDU T2,V1,R0 SW T4,0000 (V0) JR RA SW T2,0000 (T8) 80040A00 1A00 ADDU V0,V0,T1 LW V1,0000 (V0) BEQL V1,T7,+74 SW T4,0000 (V0) ADDU T2,V1,R0 ADDIU A0,R0,0001 ADDU V1,A3,A0 ADDU V0,T2,A0 ADDU V0,T0,V0 LBU V1,0000 (V1) LBU V0,0000 (V0) SUBU A2,V1,V0 BNE A2,R0,+6 SLTI V0,A0,0003 ADDIU A0,A0,0001 SLTI V0,A0,003C BNE V0,R0,-10 ADDU V1,A3,A0 SLTI V0,A0,0003 BNE V0,R0,-29 NOP LW V1,2A5C (T6) SLT V0,V1,A0 BEQ V0,R0,+8 SUBU V0,T4,T2 ANDI V0,V0,0FFF SW V0,2A90 (T5) SLTI V0,A0,003C BEQ V0,R0,+12 SW A0,2A5C (T6) J 800409DC NOP //80040A80: 1A80 BNE A0,V1,-42 SUBU V1,T4,T2 LW V0,2A90 (T5) ANDI V1,V1,0FFF SLT V0,V1,V0 BNEL V0,R0,-47 SW V1,2A90 (T5) J 800409DC NOP //80040AA0: 1A00 LUI V0,8004 SLL V1,T4,0x2 SLL A0,T2,0x2 LW A3,2A68 (V0) LUI V0,8004 LW T3,2A80 (V0) ADDU T1,A0,A3 ADDU V0,V1,A3 LW A1,0000 (T1) ADDU T0,A0,T3 SW A1,0000 (V0) LUI V0,8004 LW A2,2A84 (V0) ADDU V0,V1,T3 LW A1,0000 (T0) ADDU A0,A0,A2 SW A1,0000 (V0) LW V0,0000 (A0) ADDU V1,V1,A2 SW V0,0000 (V1) LW V0,0000 (T0) SLL V0,V0,0x2 ADDU V0,V0,A3 SW T4,0000 (V0) LW V0,0000 (A0) SLL V0,V0,0x2 ADDU V0,V0,A3 SW T4,0000 (V0) LW V0,0000 (T1) SLL A0,V0,0x2 ADDU V1,A0,A2 LW V0,0000 (V1) BNE V0,T2,+9 ADDU V0,A0,T3 J 80040B50 SW T4,0000 (V1) //80040B30 1B30 LUI V0,8004 LW V1,2A68 (V0) SLL V0,T4,0x2 ADDU V0,V0,V1 JR RA SW T2,0000 (V0) 80040B48 1B48 SW T4,0000 (V0) LUI V0,8004 LW V1,2A68 (V0) SLL V0,T2,0x2 ADDU V0,V0,V1 ADDIU V1,R0,1000 JR RA SW V1,0000 (V0) 80040B68 1B68 ADDU T2,A0,R0 LUI V0,8004 LW V0,2A68 (V0) SLL A0,T2,0x2 ADDU V0,A0,V0 LW V0,0000 (V0) ADDIU A2,R0,1000 BEQ V0,A2,+98 LUI V0,8004 LW A1,2A84 (V0) ADDU V0,A0,A1 LW V1,0000 (V0) BNE V1,A2,+6 LUI V0,8004 LW V0,2A80 (V0) ADDU V0,A0,V0 LW T1,0000 (V0) J 80040CAC LUI V0,8004 //80040BB4: 1BB4 LW V0,2A80 (V0) ADDU V0,A0,V0 LW V0,0000 (V0) BEQ V0,A2,+56 ADDU T1,V1,R0 ADDU T1,V0,R0 SLL V0,T1,0x2 ADDU V0,V0,A1 LW V0,0000 (V0) BEQ V0,A2,+36 ADDU V1,A1,R0 ADDIU A0,R0,1000 SLL V0,T1,0x2 ADDU V0,V0,V1 LW T1,0000 (V0) SLL A1,T1,0x2 ADDU V0,A1,V1 LW V0,0000 (V0) BNE V0,A0,-6 SLL V0,T1,0x2 LUI V0,8004 LUI A0,8004 LUI V1,8004 LW A2,2A68 (V0) LW T0,2A80 (V1) LW V1,2A84 (A0) ADDU A3,A1,A2 ADDU A1,A1,T0 LW V0,0000 (A3) LW A0,0000 (A1) SLL V0,V0,0x2 ADDU V0,V0,V1 SW A0,0000 (V0) LW V0,0000 (A1) LW V1,0000 (A3) SLL V0,V0,0x2 ADDU V0,V0,A2 SW V1,0000 (V0) SLL V0,T2,0x2 ADDU V0,V0,T0 LW V1,0000 (V0) SW V1,0000 (A1) LW V0,0000 (V0) SLL V0,V0,0x2 ADDU V0,V0,A2 SW T1,0000 (V0) LUI V0,8004 SLL V1,T1,0x2 LW A1,2A84 (V0) SLL V0,T2,0x2 ADDU V0,V0,A1 LW A0,0000 (V0) ADDU V1,V1,A1 SW A0,0000 (V1) LUI V1,8004 LW V0,0000 (V0) LW V1,2A68 (V1) SLL V0,V0,0x2 ADDU V0,V0,V1 SW T1,0000 (V0) LUI V0,8004 SLL V1,T1,0x2 LW A1,2A68 (V0) SLL V0,T2,0x2 ADDU V0,V0,A1 LW A0,0000 (V0) ADDU V1,V1,A1 SW A0,0000 (V1) LUI V1,8004 LW V0,0000 (V0) LW V1,2A84 (V1) SLL A0,V0,0x2 ADDU V1,A0,V1 LW V0,0000 (V1) BNE V0,T2,+3 LUI V0,8004 J 80040CFC SW T1,0000 (V1) //80040BEC: 1BEC LW V0,2A80 (V0) ADDU V0,A0,V0 SW T1,0000 (V0) LUI V0,8004 LW V1,2A68 (V0) SLL V0,T2,0x2 ADDU V0,V0,V1 ADDIU V1,R0,1000 SW V1,0000 (V0) JR RA NOP 80040D1C 0x1D1C ADDIU A1,R0,013A ;A1=0x13A ADDIU T2,R0,0001 LUI V0,8004 LW T1,2A4C (V0) ;T1=80042A4C: data5[04EC] LUI V0,8004 LW T0,2A48 (V0) ;T0=80042A48: data6[04EC] LUI V0,8004 LUI V1,8004 LW V0,2A60 (V0) ;V0=80042A60: data8[4004] LW A3,2A7C (V1) ;A3=80042A7C: data7[04EC] ADDU A2,V0,R0 ;A2=V0: SW R0,04E8 (A2) //80042D4C: 0x1D4C ADDIU A0,A1,FFFF ;A0=A1-1: count SLL V0,A0,0x2 ;V0=count->offset ADDU V0,V0,T1 ;V0+=T1: data5[A0] SLL V1,A1,0x2 ;V1=A1->offset SW A1,0000 (V0) ;A1->data5[A0]: ADDU V0,V1,T0 ;V0=V1+T0: data6[A1] SW A0,0000 (V0) ;A0->data6[A1]: ADDIU V0,V1,A3 ADDU V1,V1,A2 SW T2,0000 (V0) ;1->V0: LW V0,0000 (V1) ADDU A1,A0,R0 ;A1=A0: count ADDIU V0,V0,0001 BGTZ A1,0x1D4C ;loop 0x13A times SW V0,FFFC (V1) //80042D88: 0x1D88 LUI V0,8004 LW V0,2A7C (V0) ;V0=80042A7C: data7[] ADDIU A1,R0,1000 ;A1=1000: initial divisor SW R0,0000 (V0) ;0->data7[0] LUI V0,8004 LW V0,2A64 (V0) ;V0=80042A64: data9[] ADDIU A2,R0,2710 ADDIU A0,V0,4000 ;A0=80044000 SW R0,4000 (V0) ;0->80044000: //80042DAC: 0x1DAC ADDIU V1,A1,00C8 ;V1=A1+C8: +200 DIV A2,V1 BNEZ V1,0x1DC0 NOP BREAK //80042DC0: 0x1DC0 test for negative dividend or divisor ADDIU AT,R0,FFFF BNE V1,AT,0x1DD8 LUI AT,8000 BNE A2,AT,0x1DD8 NOP BREAK //80042DD8: 0x1DD8 MFLO V1 LW V0,0000 (A0) ;V0=80044000: ADDIU A1,A1,FFFF ADDU V0,V0,V1 SW V0,FFFC (A0) BGTZ A1,0x1DAC ADDIU A0,A0,FFFC JR RA NOP 80040DFC 0x1DFC LUI V0,8004 LW V1,2A60 (V0) ;V1=80042A60: data8[] LW V0,0000 (V1) ;V0=data8[0] SLTIU V0,V0,7FFF BNEZ V0,0x1E60 ADDU A3,A0,R0 ADDU A0,R0,R0 ADDIU A2,R0,013A LUI V0,8004 LW V0,2A7C (V0) ADDIU A1,V1,04E8 ADDIU V1,V0,04E8 SW A0,0000 (A1) ADDIU A1,A1,FFFC LW V0,0000 (V1) ADDIU A2,A2,FFFF ADDIU V0,V0,0001 SRL V0,V0,0x1 ADDU A0,A0,V0 SW V0,0000 (V1) BGTZ A2,0x1E2C ADDIU V1,V1,FFFC LUI V0,8004 LW V0,2A60 (V0) SW A0,0000 (V0) ADDU A2,A3,R0 LUI V0,8004 LW V1,2A7C (V0) SLL V0,A2,0x2 ADDU A0,V0,V1 LW V1,0000 (A0) LW V0,FFFC (A0) BNE V1,V0,0x1E9C SLT V0,A2,A3 ADDIU A0,A0,FFFC LW V1,0000 (A0) LW V0,FFFC (A0) BEQ V1,V0,0x1E84 ADDIU A2,A2,FFFF SLT V0,A2,A3 BEQ V0,R0,0x1EE8 LUI V0,8004 SLL A0,A2,0x2 LW V1,2A48 (V0) SLL V0,A3,0x2 ADDU A0,A0,V1 ADDU V0,V0,V1 LW A1,0000 (V0) LW V1,0000 (A0) SW A1,0000 (A0) SW V1,0000 (V0) LUI V0,8004 SLL V1,V1,0x2 LW V0,2A4C (V0) SLL A1,A1,0x2 ADDU V1,V1,V0 ADDU A1,A1,V0 SW A3,0000 (V1) SW A2,0000 (A1) //80042EE8: 0x1EE8 LUI V0,8004 LW V0,2A7C (V0) ;V0=80042A7C: data7[] SLL V1,A2,0x2 ;V1=count->offset ADDU V1,V1,V0 ;V1=data7[]+offset LW V0,0000 (V1) ;V0=data7[A2] ADDIU A2,A2,FFFF :A2-- count-- ADDIU V0,V0,0001 ;V0++ BLTZ A2,0x1F34 ;quit if last entry SW V0,0000 (V1) ;V0->data7[A2]: data7[A2]++ LUI V0,8004 LW V1,2A60 (V0) ;V1=80042A60: data8[] SLL V0,A2,0x2 ;V0=count->offset ADDU V1,V0,V1 ;V1=data8[]+offset //80042F1C: 0x1F1C LW V0,0000 (V1) ;V0=data8[A2] ADDIU A2,A2,FFFF ;A2-- count-- ADDIU V0,V0,0001 ;V0++ SW V0,0000 (V1) ;V0->data8[A2]: data8[A2]++ BGEZ A2,0x1F1C ;loop for count ADDIU V1,V1,FFFC ;V1-=4 previous data8[] //80042F34: 0x1F34 return JR RA NOP 0x1F3C 8004132C 0x232C accepts: A0= ADDIU A1,R0,0001 ADDIU A2,R0,013A LUI V0,8004 LW A3,2A60 (V0) ;A3=80042A60: data8[] ADDU V0,A1,A2 ;V0=13A+1: 13B //80041340: 0x2340 SRL V1,V0,0x1F ;V1=nonzero if negative ADDU V0,V0,V1 ;V0+=V1: correction for negative values SRA V1,V0,0x1 ;V1=V0/2: remove last bit, so words not shorts SLL V0,V1,0x2 ;V0=V1*4: V0->offset ADDU V0,V0,A3 ;V0+=A3: data8[]+offset LW V0,0000 (V0) ;V0=data8[V0] SLTU V0,A0,V0 BEQL V0,R0,0x2368 ;if A0 isn't < data8[V0], A2=V1 ADDU A2,V1,R0 ADDIU A1,V1,0001 ;A1=V1+1 //80041368: 0x2368 SLT V0,A1,A2 BNEZ V0,0x2340 ;loop while A1 < A2 ADDU V0,A1,A2 ;V0=A1+A2 JR RA ADDU V0,A1,R0 8004137C 0x237C accepts: A0= ADDIU A1,R0,0001 ADDIU A2,R0,1000 LUI V0,8004 LW A3,2A64 (V0) ;A3=80042A64: data9[] ADDU V0,A1,A2 ;V0=A1+A2: 1001 //80041390: 0x2390 SRL V1,V0,0x1F ;V1=nonzero if negative ADDU V0,V0,V1 ;V0+=V1: correction for negatives SRA V1,V0,0x1 ;V1=V0/2: remove last bit so word, not short offset SLL V0,V1,0x2 ;V0=V1->offset ADDU V0,V0,A3 ;V0+=A3: data9[]+offset LW V0,0000 (V0) ;V0=data9[V0] SLTU V0,A0,V0 BEQL V0,R0,0x23B8 ;A2=V1 if A0 isn;t < data9[V0] ADDU A2,V1,R0 ADDIU A1,V1,0001 ;A1=V1+1 //800413B8: 0x23B8 SLT V0,A1,A2 BNEZ V0,0x2390 ;loop while A1 < A2 ADDU V0,A1,A2 JR RA ADDIU V0,A1,FFFF 800413CC 0x23CC grab next 16 data control bits ADDIU SP,SP,FFE0 SW S0,0010 (SP) ADDU S0,R0,R0 ;S0=0 count SW S1,0014 (SP) LUI S1,8004 SW RA,0018 (SP) //800413E4: 0x23E4 JAL 800408BC ;V0=bit ADDIU S0,S0,0001 ;S0++ count++ LW V1,2AC4 (S1) ;V1=80042AC4: data control word SLL V1,V1,0x1 ;V1*=2: move one bit ADDU V1,V1,V0 ;V1=V1<<1 | next bit SLTI V0,S0,0011 BNEZ V0,0x23E4 ;loop 0x10 times, making a 16bit value SW V1,2AC4 (S1) ;update value LW RA,0018 (SP) LW S1,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0020 80041418 0x2418 ADDIU SP,SP,FFD0 SW S2,0018 (SP) LUI S2,8004 SW S4,0020 (SP) LUI S4,8004 SW S3,001C (SP) LUI S3,8004 LW A0,2ABC (S2) LW V0,2AC4 (S4) LW V1,2A60 (S3) SW RA,002C (SP) SW S6,0028 (SP) SW S5,0024 (SP) SW S1,0014 (SP) SW S0,0010 (SP) SUBU V0,V0,A0 LW V1,0000 (V1) ADDIU V0,V0,0001 MULT V0,V1 LUI S1,8004 LW S0,2AC0 (S1) MFLO V1 SUBU S0,S0,A0 ADDIU A0,V1,FFFF DIVU A0,S0 BNEZ S0,0x2488 NOP BREAK MFLO A0 JAL 8004132C ORI S6,R0,FFFF ADDU S5,V0,R0 LW A1,2A60 (S3) SLL V1,S5,0x2 ADDU V1,V1,A1 LW V0,FFFC (V1) MULT S0,V0 MFLO A3 LW V0,0000 (A1) NOP DIVU A3,V0 BNEZ V0,0x24C8 NOP BREAK MFLO V0 LW V1,0000 (V1) NOP MULT S0,V1 LW A0,2ABC (S2) MFLO V1 ADDU V0,A0,V0 SW V0,2AC0 (S1) LW V0,0000 (A1) DIVU V1,V0 BNEZ V0,0x24FC NOP BREAK MFLO V0 LUI S3,FFFF ADDIU S0,R0,8000 ADDU A0,A0,V0 SW A0,2ABC (S2) LW V1,2ABC (S2) SLTU V0,S6,V1 BEQ V0,R0,0x2540 ADDU V0,V1,S3 SW V0,2ABC (S2) LW V0,2AC4 (S4) LW V1,2AC0 (S1) ADDU V0,V0,S3 ADDIU V1,V1,S3 SW V0,2AC4 (S4) J 80041594 SW V1,2AC0 (S1) //80041540: 0x2540 ADDIU V0,R0,7FFF SLTU V0,V0,V1 BEQ V0,R0,0x2580 LUI V0,0001 LW A0,2AC0 (S1) ORI V0,V0,8000 SLTU V0,V0,A0 BNEZ V0,0x2580 ADDU V0,V1,S0 LW V1,2AC4 (S4) SW V0,2ABC (S2) ADDU V0,A0,S0 J 80041594 SW V1,2AC4 (S4) //80041580: 0x2580 LW V1,2AC0 (S1) LUI V0,0001 SLTU V0,V0,V1 BNEZ V0,0x25C4 ADDU A0,S5,R0 LW V0,2ABC (S2) LW V1,2AC0 (S1) SLL V0,V0,0x1 SLL V1,V1,0x1 SW V0,2ABC (S2) JAL 800408BC SW V1,2AC0 (S1) LW V1,2AC4 (S4) SLL V1,V1,0x1 ADDU V1,V1,V0 J 80041510 SW V1,2AC4 (S4) //800415C4: 0x25C4 LUI V0,8004 LW V1,2A48 (V0) SLL V0,A0,0x2 ADDU V0,V0,V1 LW S0,0000 (V0) JAL 80040DFC NOP //800415E0: 0x25E0 LW RA,002C (SP) LW S6,0028 (SP) LW S5,0024 (SP) LW S4,0020 (SP) LW S3,001C (SP) LW S2,0018 (SP) LW S1,0014 (SP) ADDU V0,S0,R0 LW S0,0010 (SP) JR RA ADDIU SP,SP,0030 8004160C 0x260C ADDIU SP,SP,FFD0 SW S2,0018 (SP) LUI S2,8004 SW S4,0020 (SP) LUI S4,8004 SW S3,001C (SP) LUI S3,8004 LW A0,2ABC (S2) LW V0,2AC4 (S4) LW V1,2A64 (S3) SW RA,002C (SP) SW S6,0028 (SP) SW S5,0024 (SP) SW S1,0014 (SP) SW S0,0010 (SP) SUBU V0,V0,A0 LW V1,0000 (V1) ADDIU V0,V0,0001 MULT V0,V1 LUI S1,8004 LW S0,2AC0 (S1) MFLO V1 SUBU S0,S0,A0 ADDIU A0,V1,FFFF DIVU A0,S0 BNE S0,R0,+2 NOP BREAK 00001C00 MFLO A0 JAL 8004137C ORI S6,R0,FFFF ADDU S5,V0,R0 LW A1,2A64 (S3) SLL V1,S5,0x2 ADDU V1,V1,A1 LW V0,0000 (V1) MULT S0,V0 MFLO A3 LW V0,0000 (A1) NOP DIVU A3,V0 BNE V0,R0,+2 NOP BREAK 00001C00 MFLO V0 LW V1,0004 (V1) NOP MULT S0,V1 LW A0,2ABC (S2) MFLO V1 ADDU V0,A0,V0 SW V0,2AC0 (S1) LW V0,0000 (A1) DIVU V1,V0 BNE V0,R0,+2 NOP BREAK 00001C00 MFLO V0 LUI S3,FFFF ADDIU S0,R0,8000 ADDU A0,A0,V0 SW A0,2ABC (S2) LW V1,2ABC (S2) SLTU V0,S6,V1 BEQ V0,R0,+9 ADDU V0,V1,S3 SW V0,2ABC (S2) LW V0,2AC4 (S4) LW V1,2AC0 (S1) ADDU V0,V0,S3 ADDU V1,V1,S3 SW V0,2AC4 (S4) J 80041788 SW V1,2AC0 (S1) ADDIU V0,R0,7FFF SLTU V0,V0,V1 BEQ V0,R0,+13 LUI V0,0001 LW A0,2AC0 (S1) ORI V0,V0,8000 SLTU V0,V0,A0 BNE V0,R0,+8 ADDU V0,V1,S0 LW V1,2AC4 (S4) SW V0,2ABC (S2) ADDU V0,A0,S0 SW V0,2AC0 (S1) ADDU V1,V1,S0 J 80041788 SW V1,2AC4 (S4) LW V1,2AC0 (S1) LUI V0,0001 SLTU V0,V0,V1 BNE V0,R0,+13 ADDU V0,S5,R0 LW V0,2ABC (S2) LW V1,2AC0 (S1) SLL V0,V0,0x1 SLL V1,V1,0x1 SW V0,2ABC (S2) JAL 800408BC SW V1,2AC0 (S1) LW V1,2AC4 (S4) SLL V1,V1,0x1 ADDU V1,V1,V0 J 80041704 SW V1,2AC4 (S4) LW RA,002C (SP) LW S6,0028 (SP) LW S5,0024 (SP) LW S4,0020 (SP) LW S3,001C (SP) LW S2,0018 (SP) LW S1,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0030 800417E0 ADDIU SP,SP,FFC8 SW S1,0014 (SP) ADDU S1,A0,R0 SW S2,0018 (SP) ADDU S2,A1,R0 SW S0,0010 (SP) ADDU S0,A2,R0 ADDIU A0,R0,103B SW RA,0034 (SP) SW S8,0030 (SP) SW S7,002C (SP) SW S6,0028 (SP) SW S5,0024 (SP) SW S4,0020 (SP) JAL 80042178 ;calloc(0x103B) SW S3,001C (SP) ADDIU A0,R0,4004 LUI V1,8004 JAL 80042178 ;calloc(0x4004) SW V0,2A78 (V1) ADDIU A0,R0,4404 LUI V1,8004 JAL 80042178 ;calloc(0x4404) SW V0,2A80 (V1) ADDIU A0,R0,4004 LUI V1,8004 JAL 80042178 ;calloc(0x4004) SW V0,2A84 (V1) ADDIU A0,R0,04E8 LUI V1,8004 JAL 80042178 ;calloc(0x4E8) SW V0,2A68 (V1) ADDIU A0,R0,04EC LUI V1,8004 JAL 80042178 ;calloc(0x4EC) SW V0,2A4C (V1) ADDIU A0,R0,04EC LUI V1,8004 JAL 80042178 ;calloc(0x4EC) SW V0,2A48 (V1) ADDIU A0,R0,04EC LUI V1,8004 JAL 80042178 ;calloc(0x4EC) SW V0,2A7C (V1) ADDIU A0,R0,4004 LUI V1,8004 JAL 80042178 ;calloc(0x4004) SW V0,2A60 (V1) ADDU S3,R0,R0 LUI V1,8004 ADDU A2,V1,R0 LUI V1,8004 ADDU T0,V1,R0 LUI V1,8004 ADDU A3,V1,R0 LUI V1,8004 LUI A0,8004 SW V0,2A64 (V1) LUI V0,8004 SW R0,2AB4 (V0) LUI V0,8004 SW R0,2AB8 (V0) LUI V0,8004 LUI V1,8004 SW R0,2A58 (V0) ADDIU V0,R0,0080 SW V0,2A44 (V1) LUI V0,8004 SW R0,2A54 (V0) LUI V0,8004 SW R0,2A40 (V0) LUI V0,8004 LUI V1,8004 SW R0,2ABC (V0) LUI V0,0002 SW V0,2AC0 (V1) LUI V0,8004 SW R0,2AC4 (V0) LUI V0,8004 SW S2,2A6C (V0) LUI V0,8004 SW S0,2A8C (V0) LUI V0,8004 SW R0,2AB0 (A0) SW S1,2A88 (T0) SW S0,2A74 (A3) SW S0,2AB0 (A0) SW R0,2A50 (V0) SW R0,2A70 (A2) SLL A1,S3,0x3 ADDIU S3,S3,0001 LW A0,2A70 (A2) LW V1,2A88 (T0) LW V0,2A74 (A3) ADDU V1,V1,A0 ADDIU A0,A0,0001 SRAV V0,V0,A1 SB V0,0000 (V1) SLTI V0,S3,0004 BNE V0,R0,-11 SW A0,2A70 (A2) LUI V0,8004 LUI A1,8004 LW V1,2AB4 (V0) LW A0,2AB0 (A1) ADDIU V1,V1,0004 BNE A0,R0,+3 SW V1,2AB4 (V0) J 80041C28 ADDU V0,R0,R0 JAL 80040D1C SW R0,2AB0 (A1) JAL 80040918 ADDU S2,R0,R0 ADDIU S1,R0,0FC4 ADDU S3,S2,R0 LUI A0,8004 ADDIU V1,R0,0020 LW V0,2A78 (A0) ADDU V0,V0,S3 ADDIU S3,S3,0001 SB V1,0000 (V0) SLT V0,S3,S1 BNE V0,R0,-6 ADDU S4,R0,R0 LUI A2,8004 LUI T1,8004 LUI T0,8004 LUI A3,8004 LW A1,2A50 (A2) LW V0,2A74 (T1) SLT V0,A1,V0 BEQ V0,R0,+12 ADDU A0,S1,S4 ADDIU S4,S4,0001 LW V0,2A6C (T0) LW V1,2A78 (A3) ADDU V0,V0,A1 LBU S0,0000 (V0) ADDIU V0,A1,0001 ADDU V1,V1,A0 SW V0,2A50 (A2) SLTI V0,S4,003C BNE V0,R0,-15 SB S0,0000 (V1) LUI V0,8004 SW S4,2AB0 (V0) ADDIU S3,R0,0001 JAL 8004096C SUBU A0,S1,S3 ADDIU S3,S3,0001 SLTI V0,S3,003D BNE V0,R0,-5 NOP JAL 8004096C ADDU A0,S1,R0 LUI S6,8004 LUI S7,8004 LUI S8,8004 LW V0,2A5C (S6) SLT V0,S4,V0 BNEL V0,R0,+1 SW S4,2A5C (S6) LW A0,2A5C (S6) SLTI V0,A0,0003 BEQ V0,R0,+9 ADDIU V0,R0,0001 LW V1,2A78 (S7) SW V0,2A5C (S6) ADDU V1,V1,S1 LBU A0,0000 (V1) JAL 80040F90 NOP J 80041AB4 NOP JAL 80040F90 ADDIU A0,A0,00FD LUI V0,8004 LW A0,2A90 (V0) JAL 80041148 ADDIU A0,A0,FFFF LW S5,2A5C (S6) BLEZ S5,+45 ADDU S3,R0,R0 LUI T2,8004 LW V1,2A50 (S8) LW V0,2A74 (T2) SLT V0,V1,V0 BEQ V0,R0,+39 LUI T2,8004 LW V0,2A6C (T2) ADDU A0,S2,R0 ADDU V0,V0,V1 LBU S0,0000 (V0) ADDIU V0,V1,0001 JAL 80040B6C SW V0,2A50 (S8) LW V0,2A78 (S7) ADDU V0,V0,S2 SB S0,0000 (V0) SLTI V0,S2,003B BEQ V0,R0,+5 ADDIU V0,S2,0001 LW V0,2A78 (S7) ADDU V0,S2,V0 SB S0,1000 (V0) ADDIU V0,S2,0001 ANDI S2,V0,0FFF ADDIU V0,S1,0001 ANDI S1,V0,0FFF JAL 8004096C ADDU A0,S1,R0 ADDIU S3,S3,0001 SLT V0,S3,S5 BNE V0,R0,-30 LUI T2,8004 J 80041B74 ADDU V0,S3,R0 JAL 80040B6C ADDU A0,S2,R0 ADDIU V0,S2,0001 ANDI S2,V0,0FFF ADDIU V0,S1,0001 ADDIU S4,S4,FFFF BEQ S4,R0,+3 ANDI S1,V0,0FFF JAL 8004096C ADDU A0,S1,R0 ADDU V0,S3,R0 SLT V0,V0,S5 BNE V0,R0,-13 ADDIU S3,S3,0001 BGTZ S4,-74 NOP JAL 800412DC NOP LUI V0,8004 LW A0,2A64 (V0) JAL 8004224C ;free DM entry A0 NOP LUI V0,8004 LW A0,2A60 (V0) JAL 8004224C ;free DM entry A0 NOP LUI V0,8004 LW A0,2A7C (V0) JAL 8004224C ;free DM entry A0 NOP LUI V0,8004 LW A0,2A48 (V0) JAL 8004224C ;free DM entry A0 NOP LUI V0,8004 LW A0,2A4C (V0) JAL 8004224C ;free DM entry A0 NOP LUI V0,8004 LW A0,2A68 (V0) JAL 8004224C ;free DM entry A0 NOP LUI V0,8004 LW A0,2A84 (V0) JAL 8004224C ;free DM entry A0 NOP LUI V0,8004 LW A0,2A80 (V0) JAL 8004224C ;free DM entry A0 NOP LUI V0,8004 LW A0,2A78 (V0) JAL 8004224C ;free DM entry A0 NOP LUI V0,8004 LW V0,2A70 (V0) LW RA,0034 (SP) LW S8,0030 (SP) LW S7,002C (SP) LW S6,0028 (SP) LW S5,0024 (SP) LW S4,0020 (SP) LW S3,001C (SP) LW S2,0018 (SP) LW S1,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0038 80041C58 0x2C58 V0=size of data A1 decompressed to A0; A1=actual compressed data, as in file+0x10 to get past header accepts: A0=p->target, A1=p->compressed data ADDIU SP,SP,FFD0 SW S1,0014 (SP) ADDU S1,A0,R0 ;S1=A0: target SW S0,0010 (SP) ADDU S0,A1,R0 ;S0=A1: source ADDIU A0,R0,103B ;A0=103B SW RA,0028 (SP) SW S5,0024 (SP) SW S4,0020 (SP) SW S3,001C (SP) JAL 80042178 ;calloc(0x103B) SW S2,0018 (SP) //80041C88: 0x2C88 ADDIU A0,R0,4004 ;A0=4004 LUI V1,8004 JAL 80042178 ;calloc(0x4004) SW V0,2A78 (V1) ;V0->80042A78: data1[103B] //80041C98: 0x2C98 ADDIU A0,R0,4004 ;A0=4004 LUI V1,8004 JAL 80042178 ;calloc(0x4004) SW V0,2A80 (V1) ;V0->80042A80: data2[4004] //80041CA8: 0x2CA8 ADDIU A0,R0,4004 ;A0=4004 LUI V1,8004 JAL 80042178 ;calloc(0x4004) SW V0,2A84 (V1) ;V0->80042A84: data3[4004] //80041CB8: 0x2CB8 ADDIU A0,R0,04E8 ;A0=04E8 LUI V1,8004 JAL 80042178 ;calloc(0x04E8) SW V0,2A68 (V1) ;V0->80042A68: data4[04E8] //80041CC8: 0x2CC8 ADDIU A0,R0,04EC ;A0=04EC LUI V1,8004 JAL 80042178 ;calloc(0x04EC) SW V0,2A4C (V1) ;V0->80042A4C: data5[04EC] //80041CD8: 0x2CD8 ADDIU A0,R0,04EC ;A0=04EC LUI V1,8004 JAL 80042178 ;calloc(0x04EC) SW V0,2A48 (V1) ;V0->80042A48: data6[04EC] //80041CE8: 0x2CE8 ADDIU A0,R0,04EC ;A0=04EC LUI V1,8004 JAL 80042178 ;calloc(0x04EC) SW V0,2A7C (V1) ;V0->80042A7C: data7[04EC] //80041CF8: 0x2CF8 ADDIU A0,R0,4004 ;A0=4004 LUI V1,8004 JAL 80042178 ;calloc(0x4004) SW V0,2A60 (V1) ;V0->80042A60: data8[4004] //80041D08: 0x2D08 ADDU A2,R0,R0 ;A2=0: #bits in sliding window value LUI V1,8004 ADDU A3,V1,R0 ;A3=80040000 LUI V1,8004 ADDU T0,V1,R0 ;T0=80040000 LUI V1,8004 SW V0,2A64 (V1) ;V0->80042A64: data9[4004] LUI V0,8004 SW R0,2AB4 (V0) ; 0->80042AB4: LUI V0,8004 SW R0,2AB8 (V0) ; 0->80042AB8: LUI V0,8004 LUI V1,8004 SW R0,2A58 (V0) ; 0->80042A58: ADDIU V0,R0,0080 SW V0,2A44 (V1) ;0x80->80042A44: LUI V0,8004 SW R0,2A54 (V0) ; 0->80042A54: data control byte LUI V0,8004 SW R0,2A40 (V0) ; 0->80042A40: mask for data control byte LUI V0,8004 LUI V1,8004 SW R0,2ABC (V0) ; 0->80042ABC: LUI V0,0002 SW V0,2AC0 (V1) ;0x2->80042AC0: LUI V0,8004 SW R0,2AC4 (V0) ; 0->80042AC4: data control word LUI V0,8004 SW S1,2A88 (V0) ;target->80042A88: LUI V0,8004 SW S0,2A6C (V0) ;source->80042A6C: LUI V0,8004 SW R0,2AB0 (A3) ; 0->80042AB0: data stream SW R0,2A50 (T0) ; 0->80042A50: current position in source SW R0,2A70 (V0) ; 0->80042A70: current position in output SW R0,2AB0 (A3) ; 0->80042AB0: data stream SLL A1,A2,0x3 ;A1=A2*8: #bits so far //80041D9C: 0x2D9C LW V1,2A50 (T0) ;V1=80042A50: current pos in source ADDIU A2,A2,0001 ;A2++ count++ ADDU V0,S0,V1 ;V0=source+offset: next byte LBU A0,0000 (V0) ;A0=data LW V0,2AB0 (A3) ;V0=80042AB0: data stream ADDIU V1,V1,0001 ;V1++ pos++ SW V1,2A50 (T0) ;updated pos->80042A50 SLLV A0,A0,A1 ;A0=data<<#bits (each byte tacked after previous one) OR V0,V0,A0 ;V0|=(data<<#bits) tack new values on end of previous ones SW V0,2AB0 (A3) ;updated data->data stream SLTI V0,A2,0004 ;TRUE if A2<4: loop until word filled BNEL V0,R0,0x2D9C ;branch if need more bits SLL A1,A2,0x3 //80041DD0: 0x2DD0 LUI V0,8004 LW V1,2AB0 (V0) ;V1=80042AB0: data stream LUI V0,8004 BNEZ V1,0x2DEC ;branch if data in stream SW V1,2A8C (V0) ;stream->80042A8C: working copy J 80041FA8 ;if no data, return ADDU V0,R0,R0 ;V0=0 //80041DEC: 0x2DEC when there's data... JAL 800413CC ;fill data control word NOP JAL 80040D1C NOP ADDU A2,R0,R0 ;A2=0 LUI A0,8004 ADDIU V1,R0,0020 //80041E08: 0x2E08 LW V0,2A78 (A0) ;V0=80042A78: data1[103B] ADDU V0,V0,A2 ;V0+=offset: ADDIU A2,A2,0001 ;A2++ SB V1,0000 (V0) ;0x20->V0: fill with 4036 spaces SLTI V0,A2,0FC4 BNEZ V0,0x2E08 ;loop 4036 times... ADDIU S1,R0,0FC4 ;S1=0FC4: #entries... LUI V0,8004 LW V0,2AB0 (V0) ;V0=80042AB0: data stream BEQ V0,R0,0x2F10 ADDU S2,R0,R0 ;S2=0 //80041E34: 0x2E34 LUI S3,8004 LUI S5,8004 LUI S4,8004 //80041E40: 0x2E40 JAL 80041418 NOP ADDU S0,V0,R0 ;S0=V0: SLTI V0,S0,0100 BEQ V0,R0,0x2E8C ;branch if value >= 0x100 NOP LW V0,2A70 (S3) ;V0=80042A70: pos in output LW V1,2A88 (S5) ;V1=80042A88: target ADDIU S2,S2,0001 ;S2++ ADDU V1,V1,V0 ;V1+=V0: target+offset SB S0,0000 (V1) ;value->next entry in target LW V1,2A78 (S4) ;V1=80042A78: data1[103B] ADDIU V0,V0,0001 ;V0++ SW V0,2A70 (S3) ;update outpos ADDU V1,V1,S1 ;V1+=S1: ADDIU S1,S1,0001 ;S1++ ANDI S1,S1,0FFF ;S1&=0xFFF J 80041EFC SB S0,0000 (V1) ;value-> //80041E8C: 0x2E8C JAL 8004160C NOP SUBU V0,S1,V0 ADDIU V0,V0,FFFF ANDI A2,V0,0FFF ADDIU A3,S0,FF03 BLEZ A3,0x2EFC ADDU A1,R0,R0 ADDIU S2,S2,0001 ADDU V0,A2,A1 ADDIU A1,A1,0001 ANDI V0,V0,0FFF LW V1,2A78 (S4) LW A0,2A70 (S3) ADDU V1,V1,V0 LW V0,2A88 (S5) LBU S0,0000 (V1) ADDU V0,V0,A0 SB S0,0000 (V0) LW V0,2A78 (S4) ADDIU A0,A0,0001 SW A0,2A70 (S3) ADDU V0,V0,S1 ADDIU S1,S1,0001 SB S0,0000 (V0) SLT V0,A1,A3 BNEZ V0,0x2EAC ANDI S1,S1,0FFF //80041EFC: 0x2EFC LUI V0,8004 LW V0,2AB0 (V0) ;V0=80042AB0: data stream SLTU V0,S2,V0 BNEZ V0,0x2E40 ;branch if ??? < data in stream NOP //80041F10: 0x2F10 LUI V0,8004 LW A0,2A64 (V0) ;A0=80042A64: data9[4004] JAL 8004224C ;free DM entry A0 NOP //80041F20: 0x2F20 LUI V0,8004 LW A0,2A60 (V0) ;A0=80042A60: data8[4004] JAL 8004224C ;free DM entry A0 NOP //80041F30: 0x2F30 LUI V0,8004 LW A0,2A7C (V0) ;A0=80042A7C: data7[04EC] JAL 8004224C ;free DM entry A0 NOP //80041F40: 0x2F40 LUI V0,8004 LW A0,2A48 (V0) ;A0=80042A48: data6[04EC] JAL 8004224C ;free DM entry A0 NOP //80041F50: 0x2F50 LUI V0,8004 LW A0,2A4C (V0) ;A0=80042A4C: data5[04EC] JAL 8004224C ;free DM entry A0 NOP //80041F60: 0x2F60 LUI V0,8004 LW A0,2A68 (V0) ;A0=80042A68: data4[04E8] JAL 8004224C ;free DM entry A0 NOP //80041F70: 0x2F70 LUI V0,8004 LW A0,2A84 (V0) ;A0=80042A84: data3[4004] JAL 8004224C ;free DM entry A0 NOP //80041F80: 0x2F80 LUI V0,8004 LW A0,2A80 (V0) ;A0=80042A80: data2[4004] JAL 8004224C ;free DM entry A0 NOP //80041F90: 0x2F90 LUI V0,8004 LW A0,2A78 (V0) ;A0=80042A78: data1[103B] JAL 8004224C ;free DM entry A0 NOP //80041A0: 0x2FA0 LUI V0,8004 LW V0,2A70 (V0) ;V0=80042A70: size of output //80041FA8: 0x2FA8 return LW RA,0028 (SP) LW S5,0024 (SP) LW S4,0020 (SP) LW S3,001C (SP) LW S2,0018 (SP) LW S1,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0030 80041FCC 0x2FCC decompresses filename A1 to A0 accepts: A0=p->target, A1=p->string resource name ADDIU SP,SP,FFE8 SW RA,0010 (SP) ADDU A3,A1,R0 ;A3=A1: p->filename LUI V0,8004 ADDIU A1,V0,2B20 ;A1=80042B20: compressed file "shell.bin" //80041FE0: 0x2FE0 test if string valid LBU V1,0000 (A3) ;V1=A3: ??? BEQ V1,R0,0x3040 ;return if NULL string ADDIU A2,R0,0001 ;A2=1 //80041FEC: 0x2FEC test if string matches ADDU V0,A2,A1 ;V0=80042B20+offset: p->string-3 LBU V0,0003 (V0) ;V0=bin str char BNE V1,V0,0x3008 ;branch if no hit ADDU V0,A3,A2 ;V0=next resource str char LBU V1,0000 (V0) ;V1=res str char BNEZ V1,0x2FEC ;loop until NULL byte ADDIU A2,A2,0001 ;A2++ //80042008: 0x3008 find next resource if a dud match BEQ V1,R0,0x3040 ;pull resource if strings matched (made it to NULL char) NOP LBU V1,0000 (A1) ;V1=filesize[0] LBU V0,0001 (A1) ;V0=filesize[1] SLL A2,V1,0x18 SLL V0,V0,0x10 OR A2,A2,V0 LBU V1,0002 (A1) ;V1=filesize[2] LBU V0,0003 (A1) ;V0=filesize[3] SLL V1,V1,0x8 OR A2,A2,V1 OR A2,A2,V0 ;A2=filesize J 80041FE0 ;keep trying until resource found ADDU A1,A1,A2 ;A1+=filesize //80042040: 0x3040 decompress! JAL 80041C58 ;decompress file A1 to A0 ADDIU A1,A1,0010 ;A1+=10: p->compressed data LW RA,0010 (SP) JR RA 80042054 0x3054 data ;BEQ A2,R0,0x3070 ;ADDU V1,R0,R0 ;SB A1,0000 (A3) 80042060 0x3060 V0=memset(A0,A1,A2) accepts: A0=p->chunk, A1=value, A2=size ADDU A3,A0,R0 ;A3=A0: p->chunk BEQ A2,R0,0x3080 ;branch if no entry? ADDU V1,R0,R0 ;V1=0 count //8004206C: 0x306C save value SB A1,0000 (A3) //80042070: 0x3070 loop for all ADDIU V1,V1,0001 ;V1++ count++ SLTU V0,V1,A2 BNEZ V0,0x306C ;loop for all ADDIU A3,A3,0001 //80042080: 0x3080 return JR RA ADDU V0,A0,R0 ;V0=A0: p->block 80042088 0x3088 V0=p->start dynamic memory buffer [80042A30] LUI V0,8004 LW V0,2A30 (V0) ;V0=80042A30: p->start DM buffer JR RA NOP 80042098 0x3098 V0=p->DM entry prior to entry A0 LW V0,0004 (A0) ;V0=A0+4: p->previous DM entry JR RA NOP 800420A4 0x30A4 V0=p->DM entry following entry A0 accepts: A0=p->DM entry LW V0,0008 (A0) ;V0=A0+8: p->next DM entry JR RA NOP 800420B0 0x30B0 800420F0 0x30F0 V0=size of allocation for entry A0 accepts: A0=p->DM entry LW V0,0004 (A0) ;V0=p->previous DM entry ADDIU V0,V0,FFF0 ;V0-=10: p->end of data JR RA SUBU V0,V0,A0 ;V0-=A0: p->end - p->start 80042100 0x3100 set dynamic memory table from A0 to A1 accepts: A0=p->start, A1=p->end ADDIU SP,SP,FFE8 LUI V0,8004 SW S0,0010 (SP) LUI S0,8004 SW RA,0014 (SP) SW A0,2A30 (V0) ;A0->80042A30: p->start of buffer JAL 80042088 ;V0=80042A30: p->start of buffer SW A1,2A34 (S0) ;A1->80042A34: p->end of buffer //80042120: 0x3120 ADDIU A2,R0,0044 ADDIU A1,R0,004D ADDIU V1,R0,0046 SB A2,0000 (V0) ;A0+0=0x44: "D" SB A1,0001 (V0) ;A0+1=0x4D: "M" SB V1,0002 (V0) ;A0+2=0x46: "F" LW V1,2A34 (S0) ;V1=original [A1] argument ADDU A0,V0,R0 ;A0=V0, which it already should SW R0,0008 (V0) ;A0+8=0 ADDIU V1,V1,FFF0 ;V1-=0x10: SW V1,0004 (V0) ;A0+4=[A1]-0x10 ADDU V0,V1,R0 ;V0=V1 ADDIU V1,R0,0054 SB A2,0000 (V0) ;[A1]+0=0x44 "D" SB A1,0001 (V0) ;[A1]+1=0x4D "M" SB V1,0002 (V0) ;[A1]+2=0x54 "T" SW R0,0004 (V0) ;[A1]+4=0 SW A0,0008 (V0) ;[A1]+8=A0 LW RA,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0018 80042178 0x3178 V0=calloc(A0) accepts: A0=size of data ADDIU SP,SP,FFE0 SW S2,0018 (SP) ADDIU S2,A0,000F ADDIU V0,R0,FFF0 AND S2,S2,V0 ;S2=(A0+0xF)& 0xFFF0: A0 to nearest quad boundry SW RA,001C (SP) SW S1,0014 (SP) JAL 80042088 ;V0=80042A30: p->start DM buffer SW S0,0010 (SP) ADDU S1,V0,R0 ;S1=V0: p->start DM buffer ADDIU S0,R0,0046 //800421A4: 0x31A4 LBU V0,0002 (S1) ;V0=S1+2: DM.entry.type BNE V0,S0,0x31C4 ;branch if not 0x46: "F" free NOP JAL 800420F0 ;V0=size of allocation for entry A0 ADDU A0,S1,R0 ;A0=S1: p->start DM buffer SLT V0,V0,S2 ;TRUE if difference same as passed entry BEQL V0,R0,0x31E0 ;branch if same entry ADDIU S0,S1,0010 ;S0=S1+10: p->DM.entry.data //800421C4: 0x31C4 test if valid pointer to stuff JAL 80042098 ;V0=A0+4: p->previous DM entry ADDU A0,S1,R0 ;A0=S1: p->DM entry ADDU S1,V0,R0 ;S1=V0: p->prev.DM.entry BNEZ S1,0x31A4 ;loop until a hit found ADDIU V0,R0,FFFF ;V0= -1 J 80042234 ;return invalid NOP //800421E0: 0x31E0 ADDU A0,S0,R0 ;A0=S0: p->DM.entry.data ADDIU V0,R0,0052 SB V0,0002 (S1) ;0x52->S1+2: "R" ADDIU V0,S2,0010 ;V0=S2+10: entry+=10, next in list ADDU V0,S1,V0 ;V0=S1+V0: address+entry LW A1,0004 (S1) ;A1=S1+4: p->prev.DM.entry ADDIU V1,R0,0044 SW V0,0004 (S1) ;value->S1+4: set prev.DM.entry SB V1,0000 (V0) ;'D'->header[0] ADDIU V1,R0,004D SB V1,0001 (V0) ;'M'->header[1] ADDIU V1,R0,0046 ADDU A2,S2,R0 ;A2=S2: size of data SW S1,0008 (V0) SB V1,0002 (V0) ;V0+0=0x444D46: "DMF" SW A1,0004 (V0) ;V0+4=A1: p->prev ADDU S1,A1,R0 ;S1=A1: p->prev ADDU A1,R0,R0 ;A1=0 fill character JAL 80042060 ;V0=memset(A0,A1,A2) SW V0,0008 (S1) ;S1+8=V0: set prev.header[8] = p->next entry ADDU V0,S0,R0 ;V0=S0: p->data //80042234: 0x3234 return LW RA,001C (SP) LW S2,0018 (SP) LW S1,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0020 8004224C 0x324C free DM entry A0 accepts: A0=p->DM entry ADDU A2,A0,R0 ADDU A3,A2,R0 ;A3=[A0] LBU V1,FFF0 (A3) ;V1=[A0]-10: ADDIU V0,R0,0044 BEQ V1,V0,0x326C ;branch if equal to 0x44 "D" ADDIU A2,A2,FFF0 ;A2=[A0]-10: //80042264: 0x3264 return invalid JR RA ADDIU V0,R0,FFFF ;V0= -1 //8004226C: 0x326C LBU V1,0001 (A2) ;V1=[A0]-F: ADDIU V0,R0,004D BNE V1,V0,0x3264 ;return -1 if not 0x4D "M" ADDIU V0,R0,0052 LBU V1,0002 (A2) ;V1=[A0]-E: BNE V1,V0,0x32B4 ;return -1 if not 0x52 "R" ADDIU V0,R0,0046 SB V0,0002 (A2) ;replace "R" with "F" LW A0,FFF4 (A3) ;A0=[A0]-C ADDU V0,R0,R0 ;V0=0 LW A1,0004 (A0) ADDIU V1,R0,007E SB V1,0000 (A0) ;0x7E->A0+0: ??? "~" SB V1,0001 (A0) ;0x7E->A0+1: ??? "~" SB V1,0002 (A0) ;0x7E->A0+2: ??? "~" SW A1,FFF4 (A3) ;A0=[A0]-C JR RA SW A2,0008 (A1) ;[A0]-10 -> //800422B4: 0x32B4 return invalid JR RA ADDIU V0,R0,FFFF ;V0= -1 800422C0 0x32BC set cache for first 6Kb SW AT,0018 (SP) ADDIU SP,SP,FFE4 SW T0,0010 (SP) SW T1,0014 (SP) SW AT,0018 (SP) LUI T0,8000 ADDIU T1,T0,3000 ;T1=80003000 ADDIU T1,T1,FFF0 //800422E0: writeback invalidate first 3Kb CACHE 0000 (T0), D, Index Writeback Invalidate SLTU AT,T0,T1 BNE AT,R0,-3 ADDIU T0,T0,0010 LUI T0,8000 ADDIU T1,T0,6000 ADDIU T1,T1,FFE0 //800422FC: invalidate first 6Kb CACHE 0000 (T0), I, Index Invalidate SLTU AT,T0,T1 BNE AT,R0,-3 ADDIU T0,T0,0020 //80042308: return LW T0,0010 (SP) LW T1,0014 (SP) LW AT,0018 (SP) JR RA ADDIU SP,SP,001C 8004231C 0x331C cache address A0 CACHE 0000 (A0), D, Hit Writeback Invalidate JR RA NOP 80042328 0x3328 jump to A0 accepts: A0=p->routine JR A0 NOP 80042330 0x3330 jump and link to A0 accepts: A0=p->routine ADDIU SP,SP,FFEC SW RA,0010 (SP) JALR RA,A0 NOP LW RA,0010 (SP) ADDIU SP,SP,0014 JR RA NOP 80042350 0x3350 V0=COP0 Status MFC0 V0,Status JR RA NOP 8004235C 0x335C A0->COP0 Status MTC0 A0,Status JR RA NOP 80042368 0x3368 V0=COP0 Cause MFC0 V0,Cause JR RA NOP 80042374 0x3374 V0=COP0 ExpectPC MFC0 V0,ExpectPC JR RA NOP 80042380 0x3380 ADDIU SP,SP,FFE4 SW RA,0010 (SP) SW T0,0014 (SP) SW T1,0018 (SP) LUI T0,8004 ADDIU T0,T0,23AC LUI T1,4085 OR T1,T1,A0 SW T1,0000 (T0) JAL 800422C0 ;set cache for first 6Kb NOP MTC0 A1,Index LW T1,0018 (SP) LW T0,0014 (SP) LW RA,0010 (SP) ADDIU SP,SP,001C JR RA NOP 800423C8 0x33C8 ADDIU SP,SP,FFE4 SW RA,0010 (SP) SW T0,0014 (SP) SW T1,0018 (SP) LUI T0,8004 ADDIU T0,T0,23F4 LUI T1,4002 OR T1,T1,A0 SW T1,0000 (T0) JAL 800422C0 ;set cache for first 6Kb NOP MFC0 V0,Index LW T1,0018 (SP) LW T0,0014 (SP) LW RA,0010 (SP) ADDIU SP,SP,001C JR RA NOP 80042410 0x3410 wait until mysterious serial interface reg set LUI V1,A480 LW V0,0014 (V1) ;V0=A4800014: SI reserved reg? ANDI V0,V0,0003 ;sifting for 0x3 set BNEZ V0,0x3414 ;loop until set NOP JR RA NOP 8004242C 0x342C possibly returns V0 as GS hardware state? accepts: A0=PIFram address BFC007FC ADDIU SP,SP,FFE8 SW S0,0010 (SP) SW RA,0014 (SP) JAL 80042410 ;V0=SI reserved reg? ADDU S0,A0,R0 ;S0=A0: LW V0,0000 (S0) ;V0=value at address LW RA,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0018 80042454 0x3454 set new state of mystery PIFram address accepts: A0=PIFram address, A1=new state ADDIU SP,SP,FFE0 SW S1,0014 (SP) ADDU S1,A0,R0 ;S1=A0: PIFram address SW S0,0010 (SP) SW RA,0018 (SP) JAL 80042410 ;wait until mysterious SI reg set ADDU S0,A1,R0 ;S0=A1: state of address SW S0,0000 (S1) ;state->PIFram address LW RA,0018 (SP) LW S1,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0020 80042488 0x3488 set 0x8 in PIFram GS thingy ADDIU SP,SP,FFE8 LUI A0,BFC0 SW RA,0010 (SP) JAL 8004242C ;wait until PIF ready ORI A0,A0,07FC ;A0=BFC007FC: PIFram, after controllers LUI A0,BFC0 ORI A0,A0,07FC ;A0=BFC007FC: PIFram, after controllers JAL 80042454 ;set state ORI A1,V0,0008 ;A1=state | 8 LW RA,0010 (SP) JR RA ADDIU SP,SP,0018 800424B8 0x34B8 data ;ADDIU V1,R0,0002 ;ANDI V0,V0,03FE 800424C0 0x34C0 waits for VI refresh LUI A0,A440 LW V0,0010 (A0) ;V0=A4400010: VI current line register ADDIU V1,R0,0002 ;V1=2 ANDI V0,V0,03FE ;V0=current line & 3FE BEQ V0,V1,0x34EC ;skip next weird section if 2 NOP //800424D8: 0x34D8 wait until =2 LW V0,0010 (A0) ;V0=A4400010: VI current line register ANDI V0,V0,03FE ;V0=current line & 3FE BNE V0,V1,0x34D8 ;loop until 2 NOP ADDIU V1,R0,0002 ;V1=2... //800424EC: 0x34EC wait until not 2 LW V0,0010 (A0) ;V0=A4400010: VI current line register ANDI V0,V0,03FE ;V0=current line & 3FE BEQ V0,V1,0x34EC ;loop if 2 NOP JR RA NOP 80042504 0x3504 save A0 to cur.hardware + 800 accepts: A0=value ADDIU SP,SP,FFE8 ADDU A1,A0,R0 ;A1=A0: value SW RA,0010 (SP) JAL 800405BC ;save A1 to cur.hardware + offset A0 ADDIU A0,R0,0800 ;A0=800 JAL 8004267C ;loop 160 times NOP LW RA,0010 (SP) JR RA ADDIU SP,SP,0018 8004252C 0x352C V0=bitsample for displaying A0 to LCD screen or FF if none found accepts: A0=char LUI V1,8004 LBU V0,2AD0 (V1) ;V0=80042AD0: p->table ADDIU A2,R0,00FF ;A2=FF BEQ V0,A2,+15 ;return FF if V0=FF ADDU A1,R0,R0 ;A1=0 ANDI A0,A0,00FF ;A0->byte ADDU T0,A2,R0 ;T0=A2: FF ADDIU A3,V1,2AD0 ;A3=80042AD0 ADDU V1,A3,R0 ;V1=A3: 80042AD0 LBU V0,0000 (V1) ;V0=byte // BNE V0,A0,+5 ;branch if byte doesn't match search value ADDIU V1,V1,0002 ;V1+=2: next byte ADDU V0,A1,A3 ;V0=A1+A3: 80042AD0+offset LBU A2,0001 (V0) ;A2=value for matching entry JR RA ADDU V0,A2,R0 ;V0=A2: value //8004256C: loop through table LBU V0,0000 (V1) ;V0=byte BNE V0,T0,-8 ;loop until FF found ADDIU A1,A1,0002 ;A1+=2: offset // return if not found ADDU V0,A2,R0 ;V0=A2: FF JR RA NOP 80042584 0x3584 display A0 to LCD screen accepts: A0=char ADDIU SP,SP,FFE0 SW S0,0010 (SP) ADDU S0,A0,R0 ;S0=A0: char ADDIU A0,R0,0600 ;A0=0600: Ack | Busy, maybe? SW RA,001C (SP) SW S2,0018 (SP) JAL 800426D4 ;save A0 to cur.hardware + 600 SW S1,0014 (SP) JAL 8004252C ;V0=bitsample for displaying A0 to LCD screen or FF if none found ANDI A0,S0,00FF ;A0=S0&FF: A0=char LUI V1,0001 OR S1,V0,V1 ;S1=char | 10000: bitpattern SLTI V0,S1,0101 BNE V0,R0,+19 LUI S2,0400 ORI S2,S2,0400 ;S2=04000400 ANDI V0,S1,0001 ;V0=bit // select data to send BEQ V0,R0,+3 ;if bit not set, send 0 ADDU S0,R0,R0 ;S0=0 LUI S0,0200 ORI S0,S0,0200 ;S0=02000200: bit set // send data to LCD controller JAL 80042504 ;save A0 to cur.hardware + 800 ADDU A0,S0,R0 ;A0=S0: data JAL 80042504 ;save A0 to cur.hardware + 800 OR A0,S0,S2 ;A0=data | 04000400 JAL 80042504 ;save A0 to cur.hardware + 800 ADDU A0,S0,R0 ;A0=S0: data SRL V0,S1,0x1F ;V0=nonzero if negative, which I don't think it can be ADDU V0,S1,V0 ;V0+=pattern: increment if negative SRA S1,V0,0x1 ;S1=pattern/2: next bit SLTI V0,S1,0101 BEQ V0,R0,-15 ;loop about 8 times ANDI V0,S1,0001 ;V0=S1&1: bit // return JAL 800426D4 ;save A0 to cur.hardware + 600 ADDIU A0,R0,0200 ;A0=0200 LW RA,001C (SP) LW S2,0018 (SP) LW S1,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0020 80042628 0x3628 redirect to 80042584: A0->1byte ADDIU SP,SP,FFE8 SW RA,0010 (SP) JAL 80042584 ;display A0 to LCD screen ANDI A0,A0,00FF ;A0->1byte LW RA,0010 (SP) JR RA ADDIU SP,SP,0018 80042644 0x3644 SW RA,0010 (SP) JAL 800426C4 ADDIU A0,R0,0200 ADDIU SP,SP,FFE8 SW RA,0010 (SP) JAL 800426D4 ADDIU A0,R0,0200 JAL 80042694 ADDU A0,R0,R0 JAL 80042584 ;display A0 to LCD screen ADDU A0,R0,R0 ;A0=0 LW RA,0010 (SP) JR RA ADDIU SP,SP,0018 8004267C 0x367C loop 160 times ADDIU V0,R0,009F ;V0=0x159 ADDIU V0,V0,FFFF BGEZ V0,-1 ADDIU V0,V0,FFFF JR RA NOP 80042694 0x3694 send byte A0 4 times to comms? accepts: A0=byte fries: AT,V0,V1; A0->1byte ADDIU SP,SP,FFE8 ANDI A0,A0,00FF ;A0->1byte SLL V0,A0,0x18 ;V0=A0*0x1000000 SLL V1,A0,0x10 ;V1=A0*0x0010000 OR V0,V0,V1 SLL V1,A0,0x8 ;V1=A0*0x0000100 OR V0,V0,V1 OR V0,V0,A0 ;V0=A0A0A0A0 SW RA,0010 (SP) LUI AT,BE60 SW V0,FFFC (AT) ;V0->BE5FFFFC: comms transfer register? JAL 8004267C ;loop 160 times NOP LW RA,0010 (SP) JR RA ADDIU SP,SP,0018 800426D4 0x36D4 accepts: A0= ADDIU SP,SP,FFE8 SLL A1,A0,0x10 ADDIU A0,R0,0600 ;A0=600 SW RA,0010 (SP) JAL 800405BC ;save A1 to cur.hardware + offset A0 SRA A1,A1,0x10 LW RA,0010 (SP) JR RA ADDIU SP,SP,0018 800426F8 0x36F8 redirect 80040580: A0=0 ADDIU SP,SP,FFE8 SW RA,0010 (SP) JAL 80040580 ADDU A0,R0,R0 LW RA,0010 (SP) JR RA ADDIU SP,SP,0018 80042714 0x3714 ADDIU SP,SP,FFE0 SW S0,0010 (SP) ADDU S0,A0,R0 SW RA,0018 (SP) JAL 80042350 SW S1,0014 (SP) ADDU S1,V0,R0 ADDIU A0,R0,FFFE JAL 8004235C AND A0,S1,A0 JAL 800426F8 NOP ANDI V0,V0,0010 BEQ V0,R0,-4 NOP JAL 800426F8 NOP ANDI A0,S0,000F ORI A0,A0,0010 JAL 80042694 ANDI S0,V0,000F JAL 800426F8 NOP ANDI V0,V0,0010 BNE V0,R0,-4 NOP JAL 80042694 ADDU A0,R0,R0 JAL 8004235C ADDU A0,S1,R0 ADDU V0,S0,R0 LW RA,0018 (SP) LW S1,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0020 800427A4 0x37A4 ADDIU SP,SP,FFE8 SW S0,0010 (SP) ADDU S0,A0,R0 SW RA,0014 (SP) JAL 80042714 SRA A0,S0,0x4 ADDU A0,S0,R0 JAL 80042714 ADDU S0,V0,R0 SLL S0,S0,0x4 OR V0,S0,V0 LW RA,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0018 800427E0 0x37E0 ADDIU SP,SP,FFE8 SW S0,0010 (SP) ADDU S0,A0,R0 SW RA,0014 (SP) JAL 800427A4 SRA A0,S0,0x8 ADDU A0,S0,R0 JAL 800427A4 ADDU S0,V0,R0 SLL S0,S0,0x8 OR V0,S0,V0 LW RA,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0018 8004281C 0x381C ADDIU SP,SP,FFE8 SW S0,0010 (SP) ADDU S0,A0,R0 SW RA,0014 (SP) JAL 800427E0 SRA A0,S0,0x10 ADDU A0,S0,R0 JAL 800427E0 ADDU S0,V0,R0 SLL S0,S0,0x10 OR V0,S0,V0 LW RA,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0018 80042858 0x3858 ADDIU SP,SP,FFD8 SW S0,0010 (SP) ADDU S0,R0,R0 SW S3,001C (SP) ADDIU S3,R0,000F SW S2,0018 (SP) ADDIU S2,R0,000E SW S1,0014 (SP) ADDIU S1,R0,000A SW RA,0020 (SP) JAL 80042714 ADDU A0,R0,R0 BNE V0,S3,+13 NOP JAL 80042714 ADDIU A0,R0,000F BNE V0,R0,+9 NOP JAL 80042714 ADDIU A0,R0,000A BNE V0,S2,+5 NOP JAL 80042714 ADDIU A0,R0,000E BEQL V0,S1,+1 ADDIU S0,R0,0001 BEQ S0,R0,-17 NOP LW RA,0020 (SP) LW S3,001C (SP) LW S2,0018 (SP) LW S1,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0028 800428E4 0x38E4 ADDIU SP,SP,FFE8 SW S0,0010 (SP) ADDU S0,A0,R0 SW RA,0014 (SP) LBU V0,0000 (S0) BEQ V0,R0,+7 NOP LBU A0,0000 (S0) JAL 800427A4 ADDIU S0,S0,0001 LBU V0,0000 (S0) BNE V0,R0,-5 NOP LW RA,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0018 80042928 0x3928 cycle LCD ticker: B,LL,M,LR ADDIU SP,SP,FFE8 LUI A1,8004 LW V0,2B14 (A1) ;V0=80042B14: LCD timer ADDIU V1,R0,000B SW RA,0014 (SP) SW S0,0010 (SP) ADDIU V0,V0,0001 ;V0++ timer++ BNE V0,V1,+18 ;branch if not 11 SW V0,2B14 (A1) ;V0->80042B14: update LCD timer // increment so LCD display sequence is B,LL,M,LR LUI S0,8004 LBU A0,2B10 (S0) ;A0=80042B10: "a" JAL 80042584 ;display A0 to LCD screen SW R0,2B14 (A1) ;0->80042B14: reset LCD timer LBU V0,2B10 (S0) ;V0=80042B10: "a" ADDIU V1,R0,0064 ADDIU V0,V0,0001 SB V0,2B10 (S0) ;V0->80042B10++ increment through alphabet ANDI V0,V0,00FF BNE V0,V1,+2 ;branch if not "d" ADDIU V0,R0,0067 SB V0,2B10 (S0) ;V0->80042B10: "g" if originally "d" LBU V1,2B10 (S0) ;V1=80042B10: letter ADDIU V0,R0,0068 BNE V1,V0,+2 ;branch if not "h" ADDIU V0,R0,0061 SB V0,2B10 (S0) ;V0->80042B10: "a" // JAL 800426F8 NOP ANDI V0,V0,0010 BEQ V0,R0,+4 ;return if not set ADDU V0,R0,R0 ;V0=0 reset JAL 800426F8 NOP ANDI V0,V0,000F ;V0&=0xF: 1 nibble only // return LW RA,0014 (SP) LW S0,0010 (SP) JR RA ADDIU SP,SP,0018 800429C0 0x39C0 shell.bin 800429CC 0x39CC trainer.bin 800429D8 0x39D8 gslogo3.pal 800429E4 0x39E4 gslogo3.bin 800429F0 0x39F0 tile1.tg~ 800429FA 0x39FA rlogo3 80042A00 0x3A00 table of values, probably for some happy graphical feature 0x0 1 ASCII lookup code (0,1,2,etc...) 0x1 1 value passed to 8004066C... 80042A20 0x3A20 Write Error 80042A30 p->start of dynamic memory buffer 80042A34 p->end of dynamic memory buffer 80042AA0 hardware address range 80042AA4 hardware bank 80042AD0-80042B0A 0x3AD0-0x3B0A LCD screen bitpatterns 0x0 1 ID: final entry FF 0x1 1 bitsample ' ' 00 '.' 7F '0' 84 '1' 9F '2' C8 '3' 8A '4' 93 '5' A2 '6' A0 '7' 8F '8' 80 '9' 82 'E' E0 'F' E1 'H' 91 'L' F4 'O' 84 'P' C1 'R' 81 'a' FE 'b' FD 'c' FB 'd' F7 'e' EF 'f' DF 'g' BF 'z' EA 00 FF FF 00 80042B10 LCD cur. display code 80042B14 LCD timer 80042B20 0x3B20 start of compressed binaries 0x0 4 offset to next file 0x4 C name 0x10 var. data files: 3B20 1BF44 shell.bin 1FA64 129F gslogo3.bin 20D03 234 gslogo3.pal 20F37 6C3 tile1.tg~ 215FA C9C1 trainer.bin 8006CFBB 0x2DFBB 0x1045 fill characters (FF) 8006DF00 0x2EF00 active codelist from trainer 0x100 large; max 40 codes; 80,81,D0,D1,D2,D3 accepted 0x0 4 #codes 0x4 6 GS-format code 8006E000 0x2F000 probably replaces interrupt at 80000180, redirecting to 80000120 I'm guessing this is supposed to catch and handle Watch ADDIU SP,SP,FF98 SW T0,0010 (SP) SW T1,0014 (SP) SW T2,0018 (SP) SW T3,001C (SP) SW T4,0020 (SP) SW T5,0024 (SP) SW T6,0028 (SP) SW T7,002C (SP) SW T8,0030 (SP) SW T9,0034 (SP) SW A0,0038 (SP) SW A1,0038 (SP) SW A2,0040 (SP) SW A3,0044 (SP) SW S0,0048 (SP) SW S1,004C (SP) SW S2,0050 (SP) SW S3,0054 (SP) SW S4,0058 (SP) SW S5,005C (SP) SW S6,0060 (SP) SW S7,0064 (SP) //8006E05C: 0x2F05C ADDU T0,SP,R0 ;T0=SP ADDIU T1,T0,0068 ;T1=SP+68 (original SP) LUI T2,8000 ORI T2,T2,0180 ;T2=80000180 //80006E06C: 0x2F06C test registers for redirection LW T3,0010 (T0) ;T3=SP+10: register's value NOP BEQ T2,T3,0x2F090 ;branch if [T0]=80000180 NOP ADDIU T0,T0,0004 ;T0+=4: next reg BNE T0,T1,0x2F06C ;loop until end of list NOP BGEZ R0,0x2F09C ;return if no hit NOP //8006E090: 0x2F090 redirect register to 80000120 LUI T2,A000 ORI T2,T2,0120 ;T2=A0000120 SW T2,0010 (T0) ;[T0]=A0000120 //8006E09C: 0x2F09C LW T0,0010 (SP) LW T1,0014 (SP) LW T2,0018 (SP) LW T3,001C (SP) LW T4,0020 (SP) LW T5,0024 (SP) LW T6,0028 (SP) LW T7,002C (SP) LW T8,0030 (SP) LW T9,0034 (SP) LW A0,0038 (SP) LW A1,0038 (SP) LW A2,0040 (SP) LW A3,0044 (SP) LW S0,0048 (SP) LW S1,004C (SP) LW S2,0050 (SP) LW S3,0054 (SP) LW S4,0058 (SP) LW S5,005C (SP) LW S6,0060 (SP) LW S7,0064 (SP) ADDIU SP,SP,0068 ERET NOP 8006E100 0x2F100 0xB00 fill characters (FF) 8006EC00 0x2FC00 keycode list format: 0x2C each 0x0 8 checksum correction value 0x8 4 boot address 0xC 0x20 description 8006F000 0x30000 code list see seperate doc for details +_+ (note: you can force Nemu to get to a decompression cycle by skipping 80042600) Stupidly, their other compressed files are compressed +within+ shell.bin. shell.bin loads to 80200400 3FC20 trainer.bin loads to 80780800 19948 tile1.tg~ loads to 80210000 1800 gslogo3.pal loads to 80280000 300 gslogo3.bin loads to 80281000 9A10 8020676C/70 is your port access handler. Accepts V0=mode, I think, and the -6C entry grabs it for you from V1(?). calls 80217C8C: A0=???; 8021763C 802176D8 is a redirect to something that watches the port, I believe 80217F04 used when updating the codelist. Pulls codelist from 8011DF20, pushing to BEE30000. 80217E48 has to do with saving codelist (options?) data to the "eeprom". Pulls BE000000 from 80227D34.