Advertisement
Guest User

Untitled

a guest
Dec 20th, 2014
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.     .NoHeader
  2.  
  3. ;; INSERT THIS AT 0x1000
  4. ;; 3C08B07D lui    t0, 0xB07D
  5. ;; 01006009 jalr   t0, t4
  6. ;; 00000000 nop
  7.  
  8. ;; INSERT BELOW AT 0x7CFFFC
  9. patcher_start:
  10.     dw     0xB07D02C0           ;;! <address of cheat_list>
  11.  
  12. ;; 0x7D0000
  13. ;; Installs general exception handler, router, and code engine
  14. patcher:
  15.     lui    t5, 0xB07D           ;; Start of temporary patcher location
  16.     lui    t6, 0x8000           ;; Start of cached memory
  17.     li     t7, 0x007FFFFF       ;; Address mask
  18.     li     t8, 0x807C5C00       ;; Permanent code engine location
  19.     addiu  t9, t5, -4
  20.     lw     t9, 0x0000(t9)      ;; Get temporary code lists location (stored before patcher)
  21.  
  22. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  23. ;; BOOT-TIME CHEATS
  24. load_next_boot_cheat:
  25.     ;; Apply boot-time cheats
  26.     lw     v0, 0x0000(t9)
  27.     bnez   v0, boot_cheat_type ;; if it's equal to zero, we're done with the pre-boot cheats.
  28.     lw     v1, 0x0004(t9)      ;; t9 = code list location
  29.     beqz   v1, install_geh     ;; Only gets here if first branch doesn't happen (cheat addr = 0)
  30.  
  31. boot_cheat_type:
  32.     addiu  t9, t9, 0x0008     ;; t9 = 2 words after code list location
  33.     srl    t2, v0, 24         ;; t2 = code type
  34.     addiu  at, zero, 0xEE
  35.     beq    t2, at, boot_cheat_ee
  36.     addiu  at, zero, 0xF0
  37.     and    v0, v0, t7
  38.     beq    t2, at, boot_cheat_f0
  39.     or     v0, v0, t6
  40.     addiu  at, zero, 0xF1
  41.     beq    t2, at, boot_cheat_f1
  42.     nop
  43.  
  44.     ;; Fall through, assume FF
  45.     ;; Apply FF code type
  46.     addiu  at, zero, 0xFFFC         ;; Mask address
  47.     b      load_next_boot_cheat
  48.     and    t8, v0, at               ;; Update permanent code engine location
  49.  
  50. boot_cheat_f1:
  51.     ;; Apply F1 code type
  52.     b      load_next_boot_cheat
  53.     sh     v1, 0x0000(v0)
  54.  
  55. boot_cheat_f0:
  56.     ;; Apply F0 code type
  57.     b      load_next_boot_cheat
  58.     sb     v1, 0x0000(v0)
  59.  
  60. boot_cheat_ee:
  61.     ;; Apply EE code type
  62.     lui    v0, 0x0040
  63.     sw     v0, 0x0318(t6)
  64.     b      load_next_boot_cheat
  65.     sw     v0, 0x03F0(t6)
  66.  
  67. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  68. ;; INSTALLATION
  69. install_geh:
  70.     ;; Install General Exception Handler
  71.     srl    at, t8, 2
  72.     and    v0, at, t7
  73.     lui    at, 0x0800
  74.     or     v0, v0, at
  75.                                 ;; Installs a jump to the code engine at 0x80000180
  76.     sw     v0, 0x0180(t6)     ;; v0 = 0x081F1700 -> j 0x807c5c00
  77.     sw     zero, 0x0184(t6)   ;; nop
  78.  
  79.     ;; Install code engine to permanent location
  80.     sw     t8, 0x0188(t6)      ;; Save permanent code engine location
  81.     addiu  at, zero, 0x0000 ;;! <lower addr of patcher>
  82.     addiu  v0, zero, 0x0158 ;;! <lower addr of code_engine_start>
  83.     addiu  v1, zero, 0x02C4 ;;! <lower addr of code_engine_end>
  84.     subu   at, v0, at         ;; at = patcher length
  85.     subu   v1, v1, v0         ;; v1 = code engine length
  86.     addu   v0, t5, at         ;; v0 = temporary code engine location
  87.  
  88. loop_copy_code_engine:  ;; Actually do the copying of the code engine to its permanent locatoin
  89.     lw     at, 0x0000(v0)
  90.     addiu  v1, v1, -4
  91.     sw     at, 0x0000(t8)
  92.     addiu  v0, v0, 4
  93.     dw     0x1C60FFFB         ;; hex for "bgtz v1, 0xFFFB" because our assembler is shit
  94.     addiu  t8, t8, 4
  95.     sw     t8, 0x018C(t6)     ;; Save permanent code list location
  96.                                 ;; comes right after the nop after the jump to the code engine at the GEH
  97.  
  98. loop_copy_code_list:
  99.     ;; Install in-game code list
  100.     lw     v0, 0x0000(t9)     ;; t9 points to temporary code list location for in-game codes
  101.     lw     v1, 0x0004(t9)
  102.     addiu  t9, t9, 8
  103.     sw     v0, 0x0000(t8)     ;; store code list after code engine
  104.     sw     v1, 0x0004(t8)     ;; ^
  105.     bnez   v0, loop_copy_code_list
  106.     addiu  t8, t8, 8
  107.     bnez   v1, loop_copy_code_list
  108.     nop                         ;; only continue if both address and data are zero
  109.  
  110.     ;; Write cache to physical memory and invalidate (GEH)
  111.     ori    t0, t6, 0x0180
  112.     addiu  at, zero, 0x0010
  113.  
  114. loop_cache_invalidate_geh:  ;; Iterates 4 times, so 0180 - 018F get updated
  115.     cache  0x19, 0x0000(t0)     ;; Data cache hit writeback
  116.     cache  0x10, 0x0000(t0)     ;; Instruction cache hit invalidate
  117.     addiu  at, at, -4
  118.     bnez   at, loop_cache_invalidate_geh
  119.     addiu  t0, t0, 4
  120.  
  121.  
  122.     ;; Write cache to physical memory and invalidate (code engine + list)
  123.     lw     t0, 0x0188(t6)
  124.     subu   at, t8, t0
  125. loop_cache_invalidate_code_engine:
  126.     cache  0x19, 0x0000(t0)     ;; Data cache hit writeback
  127.     cache  0x10, 0x0000(t0)     ;; Instruction cache hit invalidate
  128.     addiu  at, at, -4
  129.     bnez   at, loop_cache_invalidate_code_engine
  130.     addiu  t0, t0, 4
  131.  
  132.  
  133.     ;; Protect GEH via WatchLo/WatchHi
  134.     addiu  t0, zero, 0x0181    ;; Watch 0x80000180 for writes
  135.     mtc0   t0, 18              ;; Cp0 WatchLo
  136.     nop
  137.     mtc0   zero, 19            ;; Cp0 WatchHi
  138.  
  139.  
  140.     ;; Start game!
  141.     dw     0x3C088034   ;; replace with instructions we replaced
  142.     dw     0x3C090002   ;; ^^
  143.     jr     t4
  144.     dw     0x2508A580   ;; ^^
  145.  
  146. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  147. ;; CODE ENGINE
  148.  
  149. code_engine_start:
  150.     mfc0   k0, 13              ;; Cp0 Cause
  151.     andi   k1, k0, 0x1000      ;; Pre-NMI
  152.     bnezl  k1, not_nmi         ;; If this is an NMI interrupt... do nothing different? (delay slots)
  153.     mtc0   zero, 18            ;; Cp0 WatchLo
  154.  
  155. not_nmi:
  156.     andi   k0, k0, 0x7C
  157.     addiu  k1, zero, 0x5C      ;; Watchpoint
  158.     bne    k0, k1, run_code_engine
  159.  
  160.     ;; Watch exception; manipulate register contents
  161.     ;; Changes things to be stored at 0x80000120 instead of GEH assuming they
  162.     mfc0   k1, 14              ;; Cp0 EPC
  163.     lw     k1, 0x0000(k1)      ;; Load cause instruction
  164.     lui    k0, 0x03E0
  165.     and    k1, k1, k0         ;; Mask (base) register                    ;; Register holding offset
  166.     srl    k1, k1, 5           ;; Shift it to the "rt" position           ;; Upper half of k1 now contains register number
  167.     lui    k0, 0x3740           ;; Upper half "ori <reg number contained in k1>, k0, 0x0120"    
  168.     or     k1, k1, k0
  169.     ori    k1, k1, 0x0120      ;; Lower half "ori <reg number contained in k1>, k0, 0x0120"
  170.     lui    k0, 0x8000
  171.     lw     k0, 0x0188(k0)      ;; Load permanent code engine location     ;; Stored during installation
  172.     sw     k1, 0x0060(k0)      ;; Self-modifying code FTW!                ;; Place the modified instruction at the placeholder below
  173.     cache  0x19, 0x0060(k0)     ;; Data cache hit writeback                ;; Cache hit our updated instruction below
  174.     cache  0x10, 0x0060(k0)     ;; Instruction cache hit invalidate        ;; ^
  175.     lui    k0, 0x8000
  176.     nop                          ;; Short delay for cache sync
  177.     nop
  178.     nop
  179.     nop                          ;; Placeholder for self-modifying code     ;; Offset reg is changed to 0x80000120 here
  180.     dw     0x42000018            ;; Back to game
  181.  
  182. run_code_engine:
  183.     ;; Run code engine
  184.     lui    k0, 0x8000
  185.     lw     k0, 0x0188(k0)     ;; k0 now contains the address of the code engine
  186.     addiu  k0, k0, -40        ;; We're storing things in the 28 bytes before the code engine (which is safe, I guess...)
  187.     sd     v1, 0x0000(k0)     ;; Back up registers we clobber
  188.     sd     v0, 0x0008(k0)
  189.     sd     t9, 0x0010(k0)
  190.     sd     t8, 0x0018(k0)
  191.     sd     t7, 0x0020(k0)
  192.  
  193.     ;; Handle cheats
  194.     lui    t9, 0x8000
  195.     lw     t9, 0x018C(t9)      ;; Get code list location
  196. load_next_ingame_cheat:
  197.     lw     v0, 0x0000(t9)      ;; Load address
  198.     bnez   v0, address_not_zero
  199.     lw     v1, 0x0004(t9)      ;; Load value
  200.     beqz   v1, both_are_zero
  201.     nop
  202.  
  203.     ;; Address == 0 (TODO)
  204.     b      load_next_ingame_cheat
  205.  
  206. address_not_zero:
  207.     ;; Address != 0
  208.     addiu  t9, t9, 0x0008
  209.     srl    t7, v0, 24
  210.     sltiu  k1, t7, 0xD0        ;; Code type < 0xD0 ?
  211.     sltiu  t8, t7, 0xD4        ;; Code type < 0xD4 ?
  212.     xor    k1, k1, t8         ;; k1 = (0xD0 >= code_type < 0xD4)
  213.     addiu  t8, zero, 0x50
  214.     bne    t7, t8, not_repeater;; Code type != 0x50 ? -> 3
  215.  
  216.     ;; GS Patch/Repeater
  217.     srl    t8, v0, 8
  218.     andi   t8, t8, 0x00FF      ;; Get address count
  219.     andi   t7, v0, 0x00FF      ;; Get address increment
  220.     lw     v0, 0x0000(t9)      ;; Load address
  221.     lw     k1, 0x0004(t9)      ;; Load value
  222.     addiu  t9, t9, 0x0008
  223.  
  224. repeater_write_loop:
  225.     sh     k1, 0x0000(v0)      ;; Repeater/Patch write
  226.     addiu  t8, t8, -1
  227.     addu   v0, v0, t7
  228.     bnez   t8, repeater_write_loop
  229.     addu   k1, k1, v1
  230.     b      load_next_ingame_cheat
  231.  
  232. not_repeater:
  233.     ;; GS RAM write or Conditional
  234.     lui    t7, 0x0300
  235.     and    t7, v0, t7         ;; Test for 8-bit or 16-bit code type
  236.     li     t8, 0xA07FFFFF
  237.     and    v0, v0, t8
  238.     lui    t8, 0x8000
  239.     beqz   k1, gs_ram_write
  240.     or     v0, v0, t8         ;; Mask address
  241.  
  242.     ;; GS Conditional
  243.     sll    k1, t7, 7
  244.     beqzl  k1, skip_word_write1
  245.     lbu    t8, 0x0000(v0)      ;; 8-bit conditional
  246.     lhu    t8, 0x0000(v0)      ;; 16-bit conditional
  247. skip_word_write1:
  248.     srl    t7, t7, 22
  249.     andi   t7, t7, 8           ;; Test for equal-to or not-equal-to
  250.     beql   v1, t8, load_next_ingame_cheat
  251.     add    t9, t9, t7         ;; Add if equal
  252.     xori   t7, t7, 8
  253.     b      load_next_ingame_cheat
  254.     add    t9, t9, t7         ;; Add if not-equal
  255.  
  256. gs_ram_write:
  257.     ;; GS RAM write
  258.     sll    k1, t7, 7
  259.     beqzl  k1, skip_word_write2
  260.     sb     v1, 0x0000(v0)      ;; Constant 8-bit write
  261.     sh     v1, 0x0000(v0)      ;; Constant 16-bit write
  262. skip_word_write2:
  263.     b      load_next_ingame_cheat
  264.  
  265. both_are_zero:
  266.     ;; Restore registers from our temporary stack, and back to the game!
  267.     ld     t7, 0x0020(k0)
  268.     ld     t8, 0x0018(k0)
  269.     ld     t9, 0x0010(k0)
  270.     ld     v0, 0x0008(k0)
  271.     j      0x80000120
  272.     ld     v1, 0x0000(k0)
  273. code_engine_end:
  274. patcher_end:
  275.  
  276. cheat_list:
  277.  
  278.     ;; BEGIN PRE-BOOT CODES
  279.     dw 0x00000000   ;; END OF LIST
  280.     dw 0x0000
  281.  
  282.     ;; BEGIN IN-GAME CODES
  283.     dw 0x8133B4D6   ;; Play as glove in Super Mario 64
  284.     dw 0x3C4C
  285.     dw 0x00000000   ;; END OF LIST
  286.     dw 0x0000
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement