Welcome, Guest
You have to register before you can post on our site.

Username
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 646
» Latest member: Luca1337
» Forum threads: 1,815
» Forum posts: 14,002

Full Statistics

Online Users
There are currently 93 online users.
» 0 Member(s) | 91 Guest(s)
Bing, Google

Latest Threads
MKW Coder/Developer of th...
Forum: Coding & Hacking General Discussion
Last Post: Fifty
4 hours ago
» Replies: 11
» Views: 13,871
Make it to 10,000
Forum: General Discussion
Last Post: Fifty
4 hours ago
» Replies: 7,339
» Views: 5,672,672
Allow Pausing Before Race...
Forum: Offline Non-Item
Last Post: Vega
Yesterday, 07:47 PM
» Replies: 0
» Views: 21
Top 10 Most Influential C...
Forum: Coding & Hacking General Discussion
Last Post: Vega
Yesterday, 03:27 PM
» Replies: 2
» Views: 7,361
Show Ice Cube on Online P...
Forum: Online Non-Item
Last Post: _Ro
Yesterday, 08:23 AM
» Replies: 0
» Views: 37
CPU Control Cycler [Ro]
Forum: Offline Non-Item
Last Post: _Ro
Yesterday, 07:56 AM
» Replies: 7
» Views: 1,021
Thunder Cloud Effect Modi...
Forum: Offline; Item
Last Post: JerryHatrick
01-10-2025, 11:13 PM
» Replies: 11
» Views: 1,099
Miniturbos and Inside Dri...
Forum: Coding & Hacking General Discussion
Last Post: JerryHatrick
01-10-2025, 09:54 AM
» Replies: 1
» Views: 861
Code request???
Forum: Code Support / Help / Requests
Last Post: DrTap
01-09-2025, 06:06 PM
» Replies: 3
» Views: 4,964
CPUs/Online Players Have ...
Forum: Visual & Sound Effects
Last Post: Zeraora
01-09-2025, 02:26 AM
» Replies: 2
» Views: 516

 
  Code Patcher v1.0 [JoshuaMK]
Posted by: JoshuaMK - 10-16-2019, 05:49 AM - Forum: Misc/Other - Replies (12)

Code Patcher v1.0 [JoshuaMK]

NOTE: Currently only working in Dolphin.

This code allows you to actively patch codes into the code list without needing to restart the game after applying said codes. Future versions may include deletion of codes, patching GCT files, scrolling to allow larger codes, and maybe even relocating codes when needed. But until I figure those things out, this is v1.0!

Disclaimer: I am not responsible for any screen burn-in issues caused by this code. If playing on a real Wii on a flatscreen TV, please activate the screen burn-in reduction option in the Wii settings, and only keep this menu up for ~5 mins at a time at most. As long as you deactivate the menu without injecting the code, your code will be saved in memory to continue working on.



(NTSC-U)
C200A3F0 00000007
9421FF80 BC610008
806DA358 80630044
80630000 3D808002
618C23E0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C0000000 00000048
9421FFA0 BD610008
3D808034 618CXXXX
A16C0000 3D808000
886C0198 28030000
41820210 A3EC1906
A3CC190A 57FF801E
7FFFF214 3DC0F000
3DE08000 61EF2FFC
865F0004 7C1F7800
41800010 38600001
986C01C0 480001DC
7C127000 4082FFE4
93EC01A0 280Buuuu
418200BC 280Bdddd
418200F8 280BRRRR
41820104 280BLLLL
41820138 280BUUUU
4182014C 280BDDDD
41820180 280BYESS
40820190 619C0F94
83EC01A0 7E9C84AA
2C150000 40A20014
2C160000 40A2000C
2C170000 4182016C
3BFFFFFC 89CC01A6
39CE0001 99CC01A6
280E000F 41A0015C
39C00000 7F98E378
861C0004 863C0004
961F0004 963F0004
7C1F7800 4181013C
7C107000 4082FFE4
2C110000 40A2FFDC
3BFFFFFC 93EC01A0
619F12FC 96380004
7C18F800 4180FFF8
48000108 3B600000
A24C01A4 A26C01A8
3A520F98 7E529A14
89CC01A6 39CE0001
99CC01A6 280E0004
41A000E8 39C00000
7C6C90AE 281B0001
41820018 38630001
7C6C91AE 480000C4
3B600001 4BFFFFBC
3863FFFF 7C6C91AE
480000B0 3B600000
89CC01A6 39CE0001
99CC01A6 280E0004
41A000A0 39C00000
A24C01A4 281B0001
41820020 3A520001
28120008 4080007C
B24C01A4 48000074
3B600001 4BFFFFC4
2C120000 41820064
3A52FFFF B24C01A4
48000058 3B600000
89CC01A6 39CE0001
99CC01A6 280E0004
41A00048 39C00000
A26C01A8 281B0001
41820020 28130048
40800028 3A730008
B26C01A8 4800001C
3B600001 4BFFFFC4
2C130000 4182000C
3A73FFF8 B26C01A8
39C00000 99CC01A6
B9610008 38210060
4C00012C 4E800020
2834XXXX YYYYZZZZ
C2009640 0000002A
9421FF70 BC610008
3D808000 896C0198
2C0B0000 41820128
896C01C0 280B0001
4182011C 48000035
53656C65 63746564
3A204279 74652C20
2558207C 204C696E
652C2025 580A2558
20202530 38582025
30385800 00000000
7C8802A6 7C9D2378
619E0F98 88AC01A5
A0CC01A8 38E00008
7CC63BD6 38E00000
7CFD3B78 7D1E44AA
61831500 3BE30030
4CC63182 3D808001
618C0ECC 7D8803A6
4E800021 2C030000
4180009C 3B800009
48000015 0A255820
20253038 58202530
38580000 7C8802A6
7FE3FB78 3BDE0008
3BBD0001 7FA5EB78
7CDEA4AA 3BE30015
3D808001 618C0ECC
7D8803A6 4E800021
2C030000 41800050
3B9CFFFF 2C1C0000
4082FFB0 38600009
3880000C 38A00001
7C1C0378 8B9CFFBF
1F9C0015 38DFFFD0
7CDC3050 3D808002
618C1DF0 7D8803A6
4E800021 3D808002
618C1DD0 7D8803A6
4E800021 B8610008
38210090 81830000
60000000 00000000
00000198 00000001
04009628 60000000
0454EECC 60000000
046046A8 60000000
CC000000 00000000
00000198 00000000
0454EECC 4BFFFBE9
046046A8 4BFECF9D
04009628 4E800421
04009640 81830000
E0000000 80008000

(PAL)
C200A430 00000007
9421FF80 BC610008
806DA360 80630044
80630000 3D808002
618C2480 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C0000000 00000048
9421FFA0 BD610008
3D808034 618CXXXX
A16C0000 3D808000
886C0198 28030000
41820210 A3EC1906
A3CC190A 57FF801E
7FFFF214 3DC0F000
3DE08000 61EF2FFC
85BF0004 7C1F7800
41800010 38600001
986C01C0 480001DC
7C0D7000 4082FFE4
93EC01A0 280Buuuu
418200BC 280Bdddd
418200F8 280BRRRR
41820104 280BLLLL
41820138 280BUUUU
4182014C 280BDDDD
41820180 280BYESS
40820190 619C0F94
83EC01A0 7E9C84AA
2C150000 40A20014
2C160000 40A2000C
2C170000 4182016C
3BFFFFFC 89CC01A6
39CE0001 99CC01A6
280E000F 41A0015C
39C00000 7F98E378
861C0004 863C0004
961F0004 963F0004
7C1F7800 4181013C
7C107000 4082FFE4
2C110000 40A2FFDC
3BFFFFFC 93EC01A0
619F12FC 96380004
7C18F800 4180FFF8
48000108 3B600000
A1AC01A4 A26C01A8
39AD0F98 7DAD9A14
89CC01A6 39CE0001
99CC01A6 280E0004
41A000E8 39C00000
7C6C68AE 281B0001
41820018 38630001
7C6C69AE 480000C4
3B600001 4BFFFFBC
3863FFFF 7C6C69AE
480000B0 3B600000
89CC01A6 39CE0001
99CC01A6 280E0004
41A000A0 39C00000
A1AC01A4 281B0001
41820020 39AD0001
280D0008 4080007C
B1AC01A4 48000074
3B600001 4BFFFFC4
2C0D0000 41820064
39ADFFFF B1AC01A4
48000058 3B600000
89CC01A6 39CE0001
99CC01A6 280E0004
41A00048 39C00000
A26C01A8 281B0001
41820020 28130048
40800028 3A730008
B26C01A8 4800001C
3B600001 4BFFFFC4
2C130000 4182000C
3A73FFF8 B26C01A8
39C00000 99CC01A6
B9610008 38210060
4C00012C 4E800020
2834XXXX YYYYZZZZ
C2009680 0000002A
9421FF70 BC610008
3D808000 896C0198
2C0B0000 41820128
896C01C0 280B0001
4182011C 48000035
53656C65 63746564
3A204279 74652C20
2558207C 204C696E
652C2025 580A2558
20202530 38582025
30385800 00000000
7C8802A6 7C9D2378
619E0F98 88AC01A5
A0CC01A8 38E00008
7CC63BD6 38E00000
7CFD3B78 7D1E44AA
61831500 3BE30030
4CC63182 3D808001
618C1A2C 7D8803A6
4E800021 2C030000
4180009C 3B800009
48000015 0A255820
20253038 58202530
38580000 7C8802A6
7FE3FB78 3BDE0008
3BBD0001 7FA5EB78
7CDEA4AA 3BE30015
3D808001 618C1A2C
7D8803A6 4E800021
2C030000 41800050
3B9CFFFF 2C1C0000
4082FFB0 38600009
3880000C 38A00001
7C1C0378 8B9CFFBF
1F9C0015 38DFFFD0
7CDC3050 3D808002
618C1E90 7D8803A6
4E800021 3D808002
618C1E70 7D8803A6
4E800021 B8610008
38210090 81830000
60000000 00000000
00000198 00000001
04009628 60000000
0454EECC 60000000
046046A8 60000000
CC000000 00000000
00000198 00000000
0454EECC 4BFFFBE9
046046A8 4BFECF9D
04009628 4E800421
04009640 81830000
E0000000 80008000

(NTSC-J)
C200A38C 00000007
9421FF80 BC610008
806DA360 80630044
80630000 3D808002
618C23A0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C0000000 00000048
9421FFA0 BD610008
3D808034 618CXXXX
A16C0000 3D808000
886C0198 28030000
41820210 A3EC1906
A3CC190A 57FF801E
7FFFF214 3DC0F000
3DE08000 61EF2FFC
85BF0004 7C1F7800
41800010 38600001
986C01C0 480001DC
7C0D7000 4082FFE4
93EC01A0 280Buuuu
418200BC 280Bdddd
418200F8 280BRRRR
41820104 280BLLLL
41820138 280BUUUU
4182014C 280BDDDD
41820180 280BYESS
40820190 619C0F94
83EC01A0 7E9C84AA
2C150000 40A20014
2C160000 40A2000C
2C170000 4182016C
3BFFFFFC 89CC01A6
39CE0001 99CC01A6
280E000F 41A0015C
39C00000 7F98E378
861C0004 863C0004
961F0004 963F0004
7C1F7800 4181013C
7C107000 4082FFE4
2C110000 40A2FFDC
3BFFFFFC 93EC01A0
619F12FC 96380004
7C18F800 4180FFF8
48000108 3B600000
A1AC01A4 A26C01A8
39AD0F98 7DAD9A14
89CC01A6 39CE0001
99CC01A6 280E0004
41A000E8 39C00000
7C6C68AE 281B0001
41820018 38630001
7C6C69AE 480000C4
3B600001 4BFFFFBC
3863FFFF 7C6C69AE
480000B0 3B600000
89CC01A6 39CE0001
99CC01A6 280E0004
41A000A0 39C00000
A1AC01A4 281B0001
41820020 39AD0001
280D0008 4080007C
B1AC01A4 48000074
3B600001 4BFFFFC4
2C0D0000 41820064
39ADFFFF B1AC01A4
48000058 3B600000
89CC01A6 39CE0001
99CC01A6 280E0004
41A00048 39C00000
A26C01A8 281B0001
41820020 28130048
40800028 3A730008
B26C01A8 4800001C
3B600001 4BFFFFC4
2C130000 4182000C
3A73FFF8 B26C01A8
39C00000 99CC01A6
B9610008 38210060
4C00012C 4E800020
2834XXXX YYYYZZZZ
C20095DC 0000002A
9421FF70 BC610008
3D808000 896C0198
2C0B0000 41820128
896C01C0 280B0001
4182011C 48000035
53656C65 63746564
3A204279 74652C20
2558207C 204C696E
652C2025 580A2558
20202530 38582025
30385800 00000000
7C8802A6 7C9D2378
619E0F98 88AC01A5
A0CC01A8 38E00008
7CC63BD6 38E00000
7CFD3B78 7D1E44AA
61831500 3BE30030
4CC63182 3D808001
618C1950 7D8803A6
4E800021 2C030000
4180009C 3B800009
48000015 0A255820
20253038 58202530
38580000 7C8802A6
7FE3FB78 3BDE0008
3BBD0001 7FA5EB78
7CDEA4AA 3BE30015
3D808001 618C1950
7D8803A6 4E800021
2C030000 41800050
3B9CFFFF 2C1C0000
4082FFB0 38600009
3880000C 38A00001
7C1C0378 8B9CFFBF
1F9C0015 38DFFFD0
7CDC3050 3D808002
618C1DB0 7D8803A6
4E800021 3D808002
618C1D90 7D8803A6
4E800021 B8610008
38210090 81830000
60000000 00000000
00000198 00000001
04009628 60000000
0454EECC 60000000
046046A8 60000000
CC000000 00000000
00000198 00000000
0454EECC 4BFFFBE9
046046A8 4BFECF9D
04009628 4E800421
04009640 81830000
E0000000 80008000

(NTSC-K)
C200A538 00000007
9421FF80 BC610008
806DA380 80630044
80630000 3D808002
618C24E0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C0000000 00000048
9421FFA0 BD610008
3D808033 618CXXXX
A16C0000 3D808000
886C0198 28030000
41820210 A3EC1906
A3CC190A 57FF801E
7FFFF214 3DC0F000
3DE08000 61EF2FFC
85BF0004 7C1F7800
41800010 38600001
986C01C0 480001DC
7C0D7000 4082FFE4
93EC01A0 280Buuuu
418200BC 280Bdddd
418200F8 280BRRRR
41820104 280BLLLL
41820138 280BUUUU
4182014C 280BDDDD
41820180 280BYESS
40820190 619C0F94
83EC01A0 7E9C84AA
2C150000 40A20014
2C160000 40A2000C
2C170000 4182016C
3BFFFFFC 89CC01A6
39CE0001 99CC01A6
280E000F 41A0015C
39C00000 7F98E378
861C0004 863C0004
961F0004 963F0004
7C1F7800 4181013C
7C107000 4082FFE4
2C110000 40A2FFDC
3BFFFFFC 93EC01A0
619F12FC 96380004
7C18F800 4180FFF8
48000108 3B600000
A1AC01A4 A26C01A8
39AD0F98 7DAD9A14
89CC01A6 39CE0001
99CC01A6 280E0004
41A000E8 39C00000
7C6C68AE 281B0001
41820018 38630001
7C6C69AE 480000C4
3B600001 4BFFFFBC
3863FFFF 7C6C69AE
480000B0 3B600000
89CC01A6 39CE0001
99CC01A6 280E0004
41A000A0 39C00000
A1AC01A4 281B0001
41820020 39AD0001
280D0008 4080007C
B1AC01A4 48000074
3B600001 4BFFFFC4
2C0D0000 41820064
39ADFFFF B1AC01A4
48000058 3B600000
89CC01A6 39CE0001
99CC01A6 280E0004
41A00048 39C00000
A26C01A8 281B0001
41820020 28130048
40800028 3A730008
B26C01A8 4800001C
3B600001 4BFFFFC4
2C130000 4182000C
3A73FFF8 B26C01A8
39C00000 99CC01A6
B9610008 38210060
4C00012C 4E800020
2833XXXX YYYYZZZZ
C2009788 0000002A
9421FF70 BC610008
3D808000 896C0198
2C0B0000 41820128
896C01C0 280B0001
4182011C 48000035
53656C65 63746564
3A204279 74652C20
2558207C 204C696E
652C2025 580A2558
20202530 38582025
30385800 00000000
7C8802A6 7C9D2378
619E0F98 88AC01A5
A0CC01A8 38E00008
7CC63BD6 38E00000
7CFD3B78 7D1E44AA
61831500 3BE30030
4CC63182 3D808001
618C1A94 7D8803A6
4E800021 2C030000
4180009C 3B800009
48000015 0A255820
20253038 58202530
38580000 7C8802A6
7FE3FB78 3BDE0008
3BBD0001 7FA5EB78
7CDEA4AA 3BE30015
3D808001 618C1A94
7D8803A6 4E800021
2C030000 41800050
3B9CFFFF 2C1C0000
4082FFB0 38600009
3880000C 38A00001
7C1C0378 8B9CFFBF
1F9C0015 38DFFFD0
7CDC3050 3D808002
618C1EF0 7D8803A6
4E800021 3D808002
618C1ED0 7D8803A6
4E800021 B8610008
38210090 81830000
60000000 00000000
00000198 00000001
04009628 60000000
0454EECC 60000000
046046A8 60000000
CC000000 00000000
00000198 00000000
0454EECC 4BFFFBE9
046046A8 4BFECF9D
04009628 4E800421
04009640 81830000
E0000000 80008000



Guide

Note: This code makes use of user input. See this guide for reference on filling in values: https://mkwii.com/showthread.php?tid=44

XXXX = Controller Address
YYYY = Mask
ZZZZ = Button to Activate/Deactivate Code
uuuu = Increase Value
dddd = Decrease Value
RRRR = Move Right 1 Byte
LLLL = Move Left 1 Byte
UUUU = Move Up 1 Line
DDDD = Move Down 1 Line
YESS = Inject Code Into Game



#~~~~~~#
#C0 Inject#
#~~~~~#

.set region, '' #Fill in E, P, J, or K within the quotes for your region when Compiling! Lowercase letters can also be used.

.macro push_stack
stwu r1, -0x60 (r1)
stmw r11, 0x8 (r1)
.endm

.macro pop_stack
lmw r11, 0x8 (r1)
addi r1, r1, 0x60
.endm

.macro grab_controller_input
lis r12, input_address
ori r12, r12, 0x3E80
lhz r11, 0 (r12)
.endm

.macro code_flag_check
lbz r3, 0x198 (r12)
cmplwi r3, 0
beq the_end
.endm

.macro mega_loop_find_end
lhz r31, 0x1906 (r12) #Grab Address Values
lhz r30, 0x190A (r12)
slwi r31, r31, 16 #Set Upper Address
add r31, r31, r30 #Combine Address Base
lis r14, 0xF000 #Set End of Codes Value
lis r15, 0x8000
ori r15, r15, 0x2FFC #Create a Cap of Mega Loop
mega_loop:
lwzu r18, 0x4 (r31) #Load Value of Address Into r18
cmpw r31, r15
blt continue #If r31's Address is Greater Than Cap, End Code
li r3, 1
stb r3, 0x1C0 (r12)
b the_end
continue:
cmpw r18, r14 #Compare r13 to r14 and Loop if Not Equal
bne mega_loop
stw r31, 0x1A0 (r12) #Store Address Into RAM
.endm

.macro find_movement_type_and_move
cmplwi r11, 0x88
beq increase_one
cmplwi r11, 0x84
beq decrease_one
cmplwi r11, 0x82
beq move_right
cmplwi r11, 0x81
beq move_left
cmplwi r11, 0x94
beq next_line
cmplwi r11, 0x98
beq previous_line
cmplwi r11, 0xF0
bne reset_and_end
ori r28, r12, 0xF94
lwz r31, 0x1A0 (r12) #Grab End Address
lswi r20, r28, 16
cmpwi r21, 0
bne+ valid
cmpwi r22, 0
bne+ valid
cmpwi r23, 0
beq- reset_and_end
valid:
subi r31, r31, 0x4
lbz r14, 0x1A6 (r12)
addi r14, r14, 1
stb r14, 0x1A6 (r12)
cmplwi r14, 0
blt+ the_end
li r14, 0
mr r24, r28
mega_loop_2: #Mega Loop
lwzu r16, 0x4 (r28)
lwzu r17, 0x4 (r28)
stwu r16, 0x4 (r31)
stwu r17, 0x4 (r31)
cmpw r31, r15 #Check for Address Higher Than Cap and End If So
bgt the_end
cmpw r16, r14 #Following checks for F0000000 00000000 and loops if not found
bne+ mega_loop_2
cmpwi r17, 0
bne- mega_loop_2
subi r31, r31, 0x4
stw r31, 0x1A0 (r12) #Subtract 8 from r31, to get new end address, and store to RAM
ori r31, r12, 0x12FC
clear:
stwu r17, 0x4 (r24)
cmpw r24, r31
blt+ clear
b reset_and_end
increase_one:
li r27, 0 #Load Increase Flag
decrease_recycle:
lhz r18, 0x1A4 (r12) #The Following Loads the chosen byte, adds 1 to it and stores.
lhz r19, 0x1A8 (r12)
addi r18, r18, 0xF98
add r18, r18, r19
lbz r14, 0x1A6 (r12)
addi r14, r14, 1
stb r14, 0x1A6 (r12)
cmplwi r14, 4
blt+ the_end
li r14, 0
lbzx r3, r12, r18
cmplwi r27, 1
beq decrease
addi r3, r3, 1
stbx r3, r12, r18
b reset_and_end
decrease_one:
li r27, 1
b decrease_recycle
decrease:
subi r3, r3, 1
stbx r3, r12, r18
b reset_and_end
move_right:
li r27, 0
left:
lbz r14, 0x1A6 (r12)
addi r14, r14, 1
stb r14, 0x1A6 (r12)
cmplwi r14, 6
blt+ the_end
li r14, 0
lhz r18, 0x1A4 (r12)
cmplwi r27, 1
beq left_move
addi r18, r18, 1
cmplwi r18, 0x8
bge reset_and_end
sth r18, 0x1A4 (r12)
b reset_and_end
move_left:
li r27, 1
b left
left_move:
cmpwi r18, 0
beq reset_and_end
subi r18, r18, 1
sth r18, 0x1A4 (r12)
b reset_and_end
next_line:
li r27, 0
line:
lbz r14, 0x1A6 (r12)
addi r14, r14, 1
stb r14, 0x1A6 (r12)
cmplwi r14, 6
blt+ the_end
li r14, 0
lhz r19, 0x1A8 (r12)
cmplwi r27, 1
beq backwards_line
cmplwi r19, 0x48
bge reset_and_end
addi r19, r19, 0x8
sth r19, 0x1A8 (r12)
b reset_and_end
previous_line:
li r27, 1
b line
backwards_line:
cmpwi r19, 0
beq reset_and_end
subi r19, r19, 0x8
sth r19, 0x1A8 (r12)
reset_and_end:
li r14, 0
stb r14, 0x1A6 (r12)
.endm

.if    (region == 'E' || region == 'e') # RMCE
    .set input_address, 0x8034
.elseif (region == 'P' || region == 'p') # RMCP
    .set input_address, 0x8034
.elseif (region == 'J' || region == 'j') # RMCJ
    .set input_address, 0x8034
.elseif (region == 'K' || region == 'k') # RMCK
    .set input_address, 0x8033
.else # Invalid Region
    .err
.endif


#START


push_stack

grab_controller_input

lis r12, 0x8000

code_flag_check

mega_loop_find_end

find_movement_type_and_move

the_end:

pop_stack

isync

#END

=================================================

#Second ASM

#~~~~~~~~~~~~~~~~~~#
#      Register Notes:              #
# No need to backup r0 or LR #
#~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~#
# Macros & Statements #
#~~~~~~~~~~~~~~#

.macro push_stack
stwu r1, -0x80 (r1)
stmw r3, 0x8 (r1)
.endm

.macro pop_stack
lmw r3, 0x8 (r1)
addi r1, r1, 0x80
.endm

.macro call_link address
lis r12, \address@h
ori r12, r12, \address@l
mtlr r12
blrl
.endm

.macro default_instruction
lwz r0, 0x0014 (r1)
.endm

.set region, '' #Must set region value, or else source will not compile

.if (region == 'E' || region == 'e') # RMCE
.set nw4r_db_DirectPrint_SetupFB, 0x800223E0
.elseif (region == 'P' || region == 'p') # RMCP
.set nw4r_db_DirectPrint_SetupFB, 0x80022480
.elseif (region == 'J' || region == 'j') # RMCJ
.set nw4r_db_DirectPrint_SetupFB, 0x800223A0
.elseif (region == 'K' || region == 'k') # RMCK
.set nw4r_db_DirectPrint_SetupFB, 0x800224E0
.else # Invalid Region
.abort
.endif

#~~~~~~~~~~~~~~#
# Start Register Safety #
#~~~~~~~~~~~~~#

push_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Get Render Mode (RKSystem->mpVideo()->pRenderMode) #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

.if (region == 'E' || region == 'e') # RMCE
lwz r3, -0x5CA8(r13)
.elseif (region == 'P' || region == 'p') # RMCP
lwz r3, -0x5CA0(r13)
.elseif (region == 'J' || region == 'j') # RMCJ
lwz r3, -0x5CA0(r13)
.elseif (region == 'K' || region == 'k') # RMCK
lwz r3, -0x5C80(r13)
.endif

lwz r3, 0x0044(r3)
lwz r3, 0x0 (r3)

#~~~~~~~~~~~~~~~~~~~~~~#
# Call nw4r::db: DirectPrint_SetupFB #
#        r3 = Render Mode                 #
#~~~~~~~~~~~~~~~~~~~~~~#

call_link nw4r_db_DirectPrint_SetupFB

#~~~~~~~~~~~~~~~~~~~~~~~~~#
# End Register Safety; Default Instruction #
#~~~~~~~~~~~~~~~~~~~~~~~~~#

pop_stack
default_instruction

==================================================

#Third ASM

#~~~~~~~~~~~~~~~~~~#
#      Register Notes:              #
# No need to backup r0 or LR #
#~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#                                  Mem Address Notes:                                                                     #
#                            0x80001660 Speed Float Word                                                             #
# 0x815F0000 "Status Word" If not zero, Draw Code will execute, auto clears after every race  #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~#
# Macros & Statements #
#~~~~~~~~~~~~~~#

.macro push_stack
stwu r1, -0x90 (r1)
stmw r3, 0x8 (r1)
.endm

.macro pop_stack
lmw r3, 0x8 (r1)
addi r1, r1, 0x90
.endm

.macro call_link address
lis r12, \address@h
ori r12, r12, \address@l
mtlr r12
blrl
.endm

.macro default_instruction
lwz r12, 0x0 (r3)
.endm

.set region, '' #Must set region value, or else source will not compile

.if (region == 'E' || region == 'e') # RMCE

.set sprintf, 0x80010ECC
.set nw4r_db_DirectPrint_Printf, 0x80021DF0
.set nw4r_db_DirectPrint_StoreCache, 0x80021DD0

.elseif (region == 'P' || region == 'p') # RMCP

.set sprintf, 0x80011A2C
.set nw4r_db_DirectPrint_Printf, 0x80021E90
.set nw4r_db_DirectPrint_StoreCache, 0x80021E70

.elseif (region == 'J' || region == 'j') # RMCJ

.set sprintf, 0x80011950
.set nw4r_db_DirectPrint_Printf, 0x80021DB0
.set nw4r_db_DirectPrint_StoreCache, 0x80021D90

.elseif (region == 'K' || region == 'k') # RMCK

.set sprintf, 0x80011A94
.set nw4r_db_DirectPrint_Printf, 0x80021EF0
.set nw4r_db_DirectPrint_StoreCache, 0x80021ED0

.else # Invalid Region
.abort
.endif

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#      Check to See if a Race is Active:                   #
#        Load Status Word from Mem 81                 #
# If not zero, we know to execute the Draw Code #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#


push_stack

lis r12, 0x8000
lbz r11, 0x198 (r12)
cmpwi r11, 0
beq- dont_execute
lbz r11, 0x1C0 (r12)
cmplwi r11, 1
beq- _error

bl the_string #Create the C++ string

#Selected: Byte, %X | Line, %X | Address, %X\n%X  %08X %08X\0\0

.string "Selected: Byte, %X | Line, %X\n%X  %08X %08X\0\0\0\0"

the_string:
mflr r4 #Set 4th Arg of DirectPrint Printf
mr r29, r4

ori r30, r12, 0xF98 #Load Area of Code into r11
lbz r5, 0x1A5 (r12)
lhz r6, 0x1A8 (r12)
li r7, 8
divw r6, r6, r7
li r7, 0
mr r29, r7
lswi r8, r30, 8
ori r3, r12, 0x1500
addi r31, r3, 0x30

crclr 4*cr1+eq

call_link sprintf

cmpwi r3, 0x0
blt- _error

li r28, 9
string_loop:

bl second_string

#.string "\n%X  %08X %08X\n%08X %08X\0\0"

.string "\n%X  %08X %08X\0"

second_string:
mflr r4
mr r3, r31
addi r30, r30, 0x8
addi r29, r29, 1
mr r5, r29
lswi r6, r30, 20
addi r31, r3, 0x15

call_link sprintf

cmpwi r3, 0
blt- _error
subi r28, r28, 1
cmpwi r28, 0
bne+ string_loop

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#              DirectPrint Printf & Store Cache                            #
#                Purpose: Draw on Screen                                  #
#            r3 = X coordinate (starts far left)                            #
#          r4 = Y coordinate (starts at very top)                        #
#                r5 = 0 No Wrap; 1 Wrap                                    #
# r6 = Address Pointer to String that will be Drawn on Screen #
#              r7 thru r10 printf format args                               #
#            f1 thru f13 printf float format args                          #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

li r3, 0x9
li r4, 0xC
li r5, 0x1
mr r28, r0
lbz r28, -0x41 (r28)
mulli r28, r28, 0x15
addi r6, r31, -0x30 #Make r6 have 0x80001500, beginning of entire formatted string
sub r6, r6, r28

call_link nw4r_db_DirectPrint_Printf
call_link nw4r_db_DirectPrint_StoreCache

#~~~~~~~~~~~~~~~~~~~~~~~~~#
# dont_execute label; Default Instruction #
#~~~~~~~~~~~~~~~~~~~~~~~~~#

_error:
dont_execute:
pop_stack
default_instruction







Code Creator: JoshuaMK
Code Contributors: Star & RiiDefi (Draw Text To Screen Code)

Print this item

  USB Gecko/Shuriken USB in 2019?
Posted by: JoshuaMK - 10-14-2019, 05:08 AM - Forum: Coding & Hacking General Discussion - Replies (9)

I am looking to get one in the near future and I understand the eBay has these banned? If that's true where could I find one of these?

I would be willing to pay $100+ so price isn't an issue. Thanks in advance  Smile

Print this item

  Sync, Eieio
Posted by: Vega - 10-10-2019, 08:23 PM - Forum: Code Support / Help / Requests - Replies (3)

I'm writing a HBC program (actually done with it, just trying to make sure it's as optimized as possible) that interacts with an external device. I need strict ordering for my load-store instructions. I'm changing bits in the Hollywood GPIO's, fyi.

Here's a snippet of code from the program

lwz r0, 0 (r11)
sync 0
ori r0, r0, XXXX #Set a bit in the register
stw r0, 0 (r11)
eieio

bl sub_routine

lwz r0, 0 (r11)
sync 0
rlwinm r0, r0, 0, XX, XX #Now remove the bit
stw r0, 0 (r11)
eieio


Sorry for the lack of detail, but I don't want to 'release' to much info before I decide to post my work entirely (it's sort of useless but still...). I essentially have to do a lot of these load-store combos (via various bits) with the GPIO. I was wondering if there is a better way to enforce ordering like 'globally' if that makes any sense... I don't like the idea of having to sync after every load and eieio after every store.

In the Broadway manual, I found this .. "If store gathering is enabled and the stores do not fall under the above categories, an eieio or sync construction must be used to prevent 2 stores from being gathered ... ... ... "

My stores do not fit in the category that was listed above the quote. So wouldn't I be able to simply set bit 24 (store gathering enable) of HID0 to 0, then switch the bit back to 1 once I'm done with messing with the GPIOs?

Print this item

  About the Wii's SEEPROM
Posted by: Vega - 10-08-2019, 09:32 PM - Forum: Coding & Hacking General Discussion - No Replies

About the Wii's SEEPROM



Chapter 1: Introduction

The Wii contains a Serial Electrically Erase-able Programmable Read Only Memory (Serial EEPROM aka SEEPROM) chip. It is (or similar to) an Atmel AT93C56 Model chip. A pdf file detailing everything about the SEEPROM can be found HERE. Reading the Manual can be intimidating (plus some basic beginner information is left out of the manual), therefore I will do my best in this thread to simplify it. It will still be a lot of content of digest.

The SEEPROM uses 16 bits for a word. There is a total of 128 (0x80) 16-bit words. The use of 16-bit words causes 'offsets' to be a bit weird when talking about the location of data in the SEEPROM. For example, if one was to conventionally say the location/offset of 0x86, the offset according to the SEEPROM is 0x43. Offsets range from 0x00 to 0x7F.

For the rest of this thread, we will refer to the 16-bit words as "Atmel-words".

Offset's listed on this thread (excluding Chapter 5) are in Atmel-word form!



Chapter 2: Hollywood GPIO's

You can communicate with the SEEPROM via the Wii's GPIO Pins (bits). For sending info to the SEEPROM, you use the GPIO_OUT register (0xCD8000E0), and for receiving info from the SEEPROM, you use the GPIO_IN register (0xCD8000E8).

Using the GPIO_OUT register, you send data to the SEEPROM via the following 3 bits...
CS (Chip Select) = Bit 21
SK (Clock) = Bit 20
DI (Data from Wii to SEEPROM; for sending SEEPROM Commands) = Bit 19

Using the GPIO_IN register, there's one bit to read data given from the SEEPROM.
DO (Data from SEEPROM to Wii; for reading output values after a READ Command, or to check the busy/read signal) = Bit 18



Chapter 3: SEEPROM Commands

To communicate with the SEEPROM, you have to use what are called 'Commands'. These Commands is the only form of communicatation that the SEEPROM can understand. Here is a list of all Commands.

EWEN
READ
WRITE
ERASE
EWDS
ERAL
WRAL

All Commands are sent via the GPIO_OUT Register utilizing the DI bit (Bit 19) only. Obviously, this causes an issue, since we can't send anything more than a binary value. Thus, to send commands, a stream of unique bits are sent via the DI bit of GPIO_OUT. Once the SEEPROM has received the full stream of unique bits, it will start running the Command.

Every Command has a Start Bit aka SB. All Commands have a SB value of 1. After SB is the OpCode, this varies per every Command. Next is the Address x16 and/or Data x16.

The Start Bit basically lets the SEEPROM know, hey a Command is now being sent. The OpCode tells the SEEPROM the type of Command it is. The Address/Data x16 is additional info that may need to be provided, this depends on which Command is being sent.

Certain Commands will make the SEEPROM output some bit information via the GPIO_IN Register; DO bit (bit 18).

~~~

EWEN (Erase-Write Enable)

SB = 1
OpCode = 00
Address x16 = 11xxxxxx

x = Don't care values, doesn't matter what they are.

This command MUST be executed first before executing any other command (except for READ). The Hex value of this command can vary due to the last 6 bits being don't care values. But for convenience we will say the Hex value of EWEN is 0x4C0 (all don't care values set to 0).

~~~

READ (Read)

SB = 1
OpCode = 10
Address x16 = XXXXXXXX (The SEEPROM's Offset; anything from 0x00 thru 0x7F)

This Command will output a stream of 17 bits of data via the DO bit of the GPIO_IN register. The first bit from the output stream is always a dummy bit (value of 0). Excluding the dummy bit, the READ command will output the Atmel-word contents of the Offset that is supplied by the READ Command.

Hex value for READ command for SEEPROM offset 0x44 = 0x644.

~~~

WRITE (Write)

SB = 1
OpCode = 01
Address x16 = XXXXXXXX (The SEEPROM's Offset; anything from 0x00 thru 0xF)
Data x16 = ZZZZZZZZZZZZZZZZ (The full Atmel-word to write at designated offset)

This Command will allow you to write in a new Atmel-word at the designated offset. You can write anywhere on the SEEPROM, but writing at the wrong spot will result in your Wii becoming a new coffee coaster (more info in Chapter 13).

Hex value for WRITE value (0x1234) at SEEPROM offset 0x50 = 0x5501234

~~~

ERASE (Erase)

SB = 1
OpCode = 11
Address x16 = XXXXXXXX (The SEEPROM's Offset)

Erase means set every bit of the Atmel-word to '1'. It's like a WRITE Command using a Data x16 value of 0xFFFF. ERASE is quicker and simpler to do than WRITE, thus it may be better to execute an ERASE Command if you no longer need certain data on the SEEPROM.

Just like with the command WRITE, executing ERASE at the wrong spot will result in a perma-brick.

Hex value for ERASE at SEEPROM offset 0x02 = 0x702

~~~

EWDS (Erase-Write Disable)

SB = 1
OpCode = 00
Address x16 = 00xxxxxx

x = Don't care values

Whenever you are finished with Erasing/Writing to the SEEPROM, you should always execute this command to prevent further unwanted interaction with the SEEPROM. It's not really necessary as every time power is supplied to the SEEPROM (from the Wii turning on), this command is executed (from Starlet's side) for extra safety.

Hex value for EWDS is 0x400.

~~~

ERAL (Erase All)

SB = 1
OpCode = 00
Address x16 = 10xxxxxx

x = Don't care values.

This command sets every bit of the entire SEEPROM to '1'. Thus every Atmel-word on the SEEPROM becomes 0xFFFF. This will brick your Wii, for more info why, read Chapter 13.

Hex value for ERAL is 0x480

~~~

WRAL (Write All)

SB = 1
OpCode = 00
Address x16 = 01xxxxxx (x = Don't care values)
Data x16 = ZZZZZZZZZZZZZZZZ (The Atmel-word value that will be written at every SEEPROM offset)

This command will write same the Atmel-word value (designated by Data x16) at every offset of the SEEPROM. This will brick your Wii. To find out why, read Chapter 13.

Hex value for WRAL (with value 0x1234) is 0x4401234.

~~~

Fyi: Leaked rvl source uses 0's for the don't care values for the SEEPROM Commands.



Chapter 3: Chip Select & Clocking

Even though (while the Wii is turned on) power is always supplied to the SEERPOM, that doesn't necessarily mean it's "On" per say. The SEEPROM must be "On" in order to receive, digest, and execute any Command. The Chip Select bit in the GPIO_OUT Register is how to turn on/off the SEEPROM. To turn on the SEEPROM, you would simply set the Chip Select (CS) bit high. To turn if off, set it low.

Like all other modern SEEPROM chips, the one on the Wii requires what is called 'clocking' for certain periods before, during, and/or after a Command. To 'clock' the SEEPROM, you would set the Clock (SK) bit of GPIO_OUT high. To 'unclock' the SEEPROM, set the SK bit low.



Chapter 4: Timing

The SEEPROM has certain timing requirements to how a Command is received and executed. These timing requirements must be followed or your Command may not execute correctly or execute at all.

For starters, when you set a bit high (like CS) when it's previous state was low, it's not flipped high instantly. It will take some time and this time is known as 'Setup Time'.

CS Setup Time (tCSS) = 200 Nanosecond Wait
DI Setup Time (tDIS) = 400 Nanosecond Wait

SK (clock, unclock) doesn't have a wait for its setup time.

Once certain bits are high and 'setup', they may need to be kept high (or low) for a certain time. This is known as "Holding".

CS Hold Time (tCSH) = 0
DI Hold Time (tDIH) = 400 Nanosecond Wait
SK High Hold Time (tSKH) = 1000 Nanosecond Wait (1 Microsecond)
SK Low Hold Time (tSKL) = 1000 Nanosecond Wait (1 Microsecond)

Chip Select has an extra requirement where if you bring it low (to bring it high later), it has to be low for a certain time.

CS Minimum Low Time (tCS) = 1000 Nanosecond Wait (Page 6 of the Manual says this is 250ns but the chart on page 4 says the wait can be as high as 1000ns depending on the Voltage. For simplicity, we will just put this as 1000ns)

And finally there is  the Write Cycle Time (tWP). It is a range of time that is takes for the SEEPROM to execute a WRITE, ERASE, WRAL, or ERAL Command.

tWP (MILLIseconds) = 0.1 thru 10 #Typically completes in 3 Milliseconds

Chapter 5. Interrupts

Whenever you are writing data to the SEEPROM, you will want to disable interrupts. It's not required for reading data from the SEEPROM though.

Here's a simple snippet of code to disable interrupts:

Code:
mfmsr rX
rlwinm rY, rX, 0, 17, 15
mtmsr rY

Keep rX safe somewhere, you will need it when you restore interrupts. To restore them, all you need to do is write back the original MSR (this assumes there are no unrelated function calls in your code that may have modified the MSR to an unknown state).

Code:
mtmsr rX



Chapter 6: Wait Subroutine

As mentioned in Chapter 4, certain timing requirements must be followed. We could have special wait subroutines for each specific amount of wait, but that is silly. It's better just to create a single wait subroutine that waits long enough to cover any circumstance. Thus, we need a wait subroutine of 1000 Nanoseconds. You do not want one for tWP (Write cycle time), that will be checked via a Busy/Read signal and is explained more in Chapter 10.

We could write out a Wait Subroutine by just executing some arbitrary nops in a loop. It takes time for Broadway to execute an instruction, but how much time? Well view the following formulae...
  • Bus_Clock = 243,000,000
  • Timer_Clock = (Bus_Clock / 4000)
  • Ticks to Seconds = [(Ticks) / (Timer_Clock * 1000)]
  • Ticks to Milliseconds = [Ticks / Timer_Clock]
  • Ticks to Microseconds = [(Ticks) * 8 / (Timer_Clock / 125)]
  • Ticks to Nanoseconds = [(Ticks) * 8000 / (Timer_Clock / 125)]
  • Seconds to Ticks = [(Secs) * (Timer_Clock * 1000)]
  • Milliseconds to Ticks = [Msecs * Timer_Clock]
  • Microseconds to Ticks = {[(Usecs * (Timer_Clock / 125)]} / 8
  • Nanoseconds to Tricks = {[(Nsecs * (Timer_Clock / 125)]} / 8000

A thousand nanoseconds is just 1 microsecond. So using the second to last formula of this list, we can convert 1 microsecond to its Tick value.
  • {[(1 * (60,750 / 125)]} / 8
  • 60,750 / 125 = 486
  • 1 * 486 = 486
  • 486 / 8 = 60.75

Result is 1 microsecond = 60.75 ticks. (Thus as a future fyi, 1 tick roughly equals 16.461 nanoseconds)

You could write a series of 61 nops for your Wait Subroutine, or make a basic loop, or implement reading Broadway's Time Base. However, we will use the built in timer from Starlet. Starlet's Timer is located at 0xCD800010. Each 'tick' on Starlet's Timer takes exactly 526.7 Nanoseconds to complete.

We just need 2 ticks and we're good. Plus the Starlet Timer will come in handy if you ever happen to mess with the SEEPROM directly from Starlet itself (IOS).

The timer increments up. To start the timer at any time, you just write null to it. Here's a template of basic Wait Subroutine where it assumes r11 is already 0xCD800000 and certain other registers are safe.

Code:
wait:
li r0, 0 #Reset Starlet Timer
stw r0, 0x0010 (r11) #Start the Timer

wait_loop:
lwz r0, 0x0010 (r11) #Check Timer
cmplwi r0, 2 #Check if 2 'tick's (~1000 nanoseconds) has elapsed
blt- wait_loop

blr #End Wait Subroutine



Chapter 7: Prepping the SEEPROM

Let's look at some of the diagrams in the Atmel manual I linked in Chapter 1. Go to Figure to 3 (top of page 8). We will go over the diagram for EWEN as its the most simple Command.

Now remember in order to send a command, you send a stream of bits thru DI (first bit always being '1'). So in the EWEN diagram, we see the stream of bits via the DI bit of GPIO_OUT. In the diagram we see 1,0,0,1,1,X,...,X. The X's are the don't care values and the '...' is simply showing there are more X's in between just the 2 X's shown in the diagram. The '//'s in the diagram present a time cut or else the diagrams would take longer than the width of the page they are shown in.

So what do you notice in the diagram for when the DI bits are being sent? (in fact you will see this pattern on every Command diagram, not just EWEN).

It's that Chip Select is HIGH for the entire time when the Command is executing! Not only that take a closer look, but not at Chip Select.

You may have noticed that SK always starts off as low when the first bit of '1' is sent in the diagram. So we know two things for certain. Before any command we now conclude that CS must be high and SK must be low. We have some issues though, we don't know what CS is beforehand. Therefore, it needs to be set low first in your source.

We will go ahead and set both CS and SK low in the following example snippet of code. The snippet of code is using r11 as 0xCD800000.

Code:
lwz r0, 0x00E0 (r11)
sync
rlwinm r0, r0 0, 22, 19 #Clear bit 20 aka SK, & clear bit 21 aka CS
stw r0, 0x00E0 (r11)
eieio
bl wait

We know that CS needs to be high before any Command is sent. That will be done shortly. Notice the 'bl wait' at the source. It's calling our earlier Wait Subroutine we made from the Chapter 6.

What's the sync and eieio for?
Broadway is an out of order execution CPU. Since we are dealing with timing requirements, we want certain instructions to be forced 'in order'. This is done with the usage of sync and eieio. You want to place a sync after any load (that is from GPIO_OUT or GPIO_IN). Then you need an eieio after any GPIO-related store. You might be able to get away without this, but not worth it especially if you are Writing Data to the SEEPROM.

Anyway, CS and SK is low, turn on CS to enable the SEEPROM!

Code:
lwz r0, 0x00E0 (r11)
sync
ori r0, r0, 0x0400
stw r0, 0x00E0 (r11)
eieio
bl wait

At this point the SEEPROM is 'prepped' and is ready to receive a Command.

Chapter 8: Sending Commands

As mentioned before, Commands are sent via a stream of bits. So we will need a loop of some sort to send the bits one after another. You cannot just send each bit back to back to back, it's not that simple. Remember, we have timing requirements to follow. Not only that, there are clocking requirements.

We will go over sending bits for the EWEN command. Referring back to the EWEN diagram (figure 3; page 8 of manual), you will see that DI was sent high THEN SK was sent high. SK would then be sent back to LOW afterwards. This is because SK MUST be low whenever a Command bit is sent via DI!

Obviously, CS is kept high the entire time for any Command. So basically our loop structure is something like this....
  • Loop:
  • Send bit value via DI
  • Wait #For DI setup time
  • Clock
  • Wait #For SK high hold time
  • Unclock
  • Wait #For SK low hold time
  • Repeat Loop

Because every new DI bit that is sent needs the SEEPROM in the unclocked state, we are required to unclock the SEEPROM after clocking it.



Chapter 9: Reading

Reading data isn't too tough. Requires clocking as well. Data from the READ is available once the SEEPROM has received all your bits from the READ command. Basically once you have clocked and unclocked (in your sending bits subroutine), the data is available.

The issue we will run into is the Dummy bit. A bit value of 0 is always sent out first. On page 6 of the Atmel manual for the READ command it says this....

"Output data changes are synchronized with the rising edges of serial clock SK."

What do this mean? It means that in order to receive the next bit of the data, the SEEPROM must receive a clock (SK high). So all we have to do is clock-unclock another extra time, therefore the dummy bit won't be read.

So here's the structure for reading data from the SEEPROM
  • Clock #To get rid of dummy bit
  • Wait #For SK high hold time
  • Unclock
  • Wait #For SK low hold time
  • Read DO bit (remember to read DO from GPIO_IN!!!)
  • Store the bit somewhere safe to later compile it to a hex value
  • Repeat til all 16 bits are read

Afterwards, you can then write some source to compile the bits to an Atmel-word in hex form. Or better yet, you could compile the bits during the reading itself. Have the bits compile as you read them 1 by 1.



Chapter 10: Writing/Erasing

Don't forget that for the WRITE Command, you also send the bits that will be written to the SEEPROM. The WRITE Command is the longest (in bits) of any Command.

Whenever you execute a WRITE, ERASE, WRAL, or ERAL command, the SEEPROM needs some time to preform the task. This is the tWP that was briefly introduced to you back in Chapter 4. Lucky for us, the SEEPROM comes with the feature of a Busy/Ready signal.

After you have finished sending the bits for WRITE, ERASE, WRAL, or ERAL, you wanna check this Busy/Ready signal. On page 6 of the Atmel Manual, it says this for any Writing or Erasing type Command....

"The DO pin outputs the Ready/Busy status
of the part if CS is brought high after being kept low for a minimum of 250 ns (tCS). A
logic “1” at pin DO indicates that the selected memory location has been erased and the
part is ready for another instruction."

Its straight forward. We need to bring CS low, then back to high. Then we can finally check the busy/read signal. Once the signal is good (value is 1), we can do another Command.

Here's a template for checking the Busy/Ready signal~
  • CS low
  • Wait
  • CS high
  • Wait #Because of CS setup time, this is needed!
  • Loop:
  • Check busy/ready signal
  • Repeat Loop

The busy/ready signal is available on the DO bit of GPIO_IN!!!
0 = Busy
1 = Ready



Chapter 11: Cleaning up the Environment

After any Writing or Erasing type of Command, you want to execute a EWDS command to put the SEEPROM into an read-only state for protection.

Also, once you have done that, be sure you bring both CS and SK low, and do one more final wait. Afterwards you're good to restore interrupts (if it was required) and be on your marry way.



Chapter 12: Structure/Map of SEEPROM

NOTE: The offset values listed in this chapter are of the conventional kind. Divide offset values in half for use in any SEEPROM code execution.

The first 72 (conventional offset 0x0 thru 0x47) bytes of the SEEPROM is deemed 'non-writable' according to the leaked RVL source. It is written to once at the factory with the following contents. Therefore, executing a WRAL or ERAL Command on the SEEPROM will not work (well it technically in theory will work, but you will Brick your Wii).

Some of the following may not be 100% accurate (from what I've seen on various Wii SEEPROMs), this is just taken from the leaked RVL source via one document.

Offset 0x0 - MFR_ID; Size 4 bytes
Offset 0x4 - CA_ID; Size 4 bytes
Offset 0x8 - MFR_DATA; Size 4 bytes
Offset 0xC - MFR_SIGN; Size 60 bytes

Now onto the 'writable' stuff...

Offset 0x48 - Boot 2 Version Info; size 20 bytes - WiiCrusher clears words at offsets 0x48 thru 0x5A; I have no idea wth 'WiiCrusher' is
Offset 0x5C - File System Version info; size 18 bytes
Offset 0x6E - Nintendo lot number; size 4 bytes
Offset 0x72 - Nintendo Wii crusher count; size 2 bytes
Offset 0x74 - Key 2; size 16 bytes (this is where the Korean Key is stored; literally called "Key 2" in leaked rvl source)
Offset 0x84 - Hollywood SS Setting; size 2 bytes
Offset 0x86 - Unused, free to write to; size 114 bytes (57 words of free space, remember words are 16-bits)
Offset 0xF8 - RNG; size 8 bytes (final 8 bytes of the SEEPROM) this value is incremented every time IOS starts. The lower 4 bytes of the value is listed first, then the higher 4 bytes.




Chapter 13: About ERAL and WRAL

I decided to write two HBC apps. 1st app, would execute a ERAL then immediately return to HBC, the 2nd app would execute a WRAL (random 16-bit value) then return back to HBC. These apps were made and tested (ERAL tested on one Wii, WRAL on another) before the RVL source was ever leaked. Thus, at the time, I was unaware of the 'unwriteable' region of the SEEPROM.

Anyway, both apps resulted in both Wiis halting when the app was launched and would not return back to HBC. Needless to say, after force shutdown, the Wiis would not boot after powering them on. Don't worry these Wiis were crappy Bootmii IOS Wiis, no real losses occurred, lol.

According the leaked RVL source, the Wii is capable of running the ERAL and WRAL Commands (proper voltage from the VCC pin) but I couldn't find any info as to why the 'unwriteable' region was physically 'unwriteable' unless the SEEPROM chip the Wii uses is custom made and unique.

The only true way to know is to use something as the ERASE Command, the execute a loop of the ERASE Command on the entire SEEPROM (to mimic ERAL). Make an app of this and have the app return back to HBC automatically. If you return back to HBC without a halt, then it's a mystery as why ERAL (or WRAL) won't work..

If the app halts, then we know that the 'unwriteable' region is physically unwriteable to some degree to where attempting writes on it, damages the SEEPROM physically. I would do all this testing myself, but all the Wiis I own now are Boot2 Wiis, and I don't wanna risk losing those.



Chapter 14: Example Sources

Some developers have already made C code to interact with the SEEPROM. Seeprom_write and Seeprom_read have already been made.

However, nobody has written any source code to utilize the SEEPROM's ERASE Command. I thus went ahead and made and wrote my own source code to do so. It's useless as writing is much better obviously. The Erase source is licensed under GPLv2, notice of the license in included in the source.

seeprom_erase - https://mariokartwii.com/downloads/seepr...om_erase.s

Also I wrote up sources for WRAL and ERAL, but they are essentially useless. Both licensed under GPLv2.

seeprom_wral - https://mariokartwii.com/downloads/seepr...rom_wral.s
seeprom_eral - https://mariokartwii.com/downloads/seepr...rom_eral.s



Chapter 15: Seeprom Viewer HBC App

Here's an app I made that displays all your SEEPROM contents on the TV screen - https://github.com/VegaASM/Seeprom-Viewer

Welp, that's it. Thank you for taking the time to read this all.

Print this item

  Turning Sharpness Modifier [JoshuaMK]
Posted by: JoshuaMK - 10-07-2019, 06:58 PM - Forum: Offline Non-Item - No Replies

Turning Sharpness Modifier [JoshuaMK]

This is the first code that edits the handling AND drifting of ALL vehicles. This code also gets rid of the ballerina issue of other float modifiers, meaning you can turn infinitely sharp without becoming a spinning top.



(NTSC-U)
C2574220 00000004
3D808150 3D60TURN
916C1764 C04C1764
EC6300B2 D07D0158
60000000 00000000
C2574268 00000002
C04C1764 EC000072
EC0000B2 00000000
C25742C0 00000002
C04C1764 EC23082A
EC2100B2 00000000
045742CC 4800001C

(PAL)
C257AA84 00000004
3D808150 3D60TURN
916C1764 C04C1764
EC6300B2 D07D0158
60000000 00000000
C257AACC 00000002
C04C1764 EC000072
EC0000B2 00000000
C257AB24 00000002
C04C1764 EC23082A
EC2100B2 00000000
0457AB30 4800001C

(NTSC-J)
C257A404 00000004
3D808150 3D60TURN
916C1764 C04C1764
EC6300B2 D07D0158
60000000 00000000
C257A44C 00000002
C04C1764 EC000072
EC0000B2 00000000
C257A4A4 00000002
C04C1764 EC23082A
EC2100B2 00000000
0457A4B0 4800001C

(NTSC-K)
C2568ADC 00000004
3D808150 3D60TURN
916C1764 C04C1764
EC6300B2 D07D0158
60000000 00000000
C2568B24 00000002
C04C1764 EC000072
EC0000B2 00000000
C2568B7C 00000002
C04C1764 EC23082A
EC2100B2 00000000
04568B88 4800001C



TURN = Floating Point Value
Normal Value = 3F80

It is recommended to keep it below 0x4000, and above 0x3F00



#ASM

#~~~~~~~~~~~~#
#Inject > 80574220#
#~~~~~~~~~~~#

lis r12, 0x8000
lis r11, 0xTURN
stw r11, 0x1764 (r12)
lfs f2, 0x1764 (r12)
fmuls f3, f3, f2
stfs f3, 0x0158 (r29)

#~~~~~~~~~~~~#
#Inject > 80574268#
#~~~~~~~~~~~#

lfs f2, 0x1764 (r12)
fmuls f0, f0, f1
fmuls f0, f0, f2

#~~~~~~~~~~~~#
#Inject > 805742C0#
#~~~~~~~~~~~#

lfs f2, 0x1764 (r12)
fadds f1, f3, f1
fmuls f1, f1, f2


#~~~~~~~~~~~~~~~#
#RAM Write > 805742CC#
#~~~~~~~~~~~~~~#

b -> +0x001C



Code Creator: JoshuaMK

Print this item

  No Characters [JoshuaMK]
Posted by: JoshuaMK - 09-30-2019, 06:16 AM - Forum: Visual & Sound Effects - No Replies

No Characters [JoshuaMK]

Now works in multiplayer.



(NTSC-U)
00558F98 00000040
00558FA0 00000040
00558FC8 00000040

(PAL)
0055D318 00000040
0055D320 00000040
0055D348 00000040

(NTSC-J)
0055CC98 00000040
0055CCA0 00000040
0055CCC8 00000040

(NTSC-K)
0054B370 00000040
0054B378 00000040
0054B3A0 00000040




Code Creator: JoshuaMK

Print this item

  Hover Kart [JoshuaMK]
Posted by: JoshuaMK - 09-29-2019, 01:54 AM - Forum: Visual & Sound Effects - No Replies

Hover Kart [JoshuaMK]

Gets rid of tires by corrupting the file paths, Therefore making you "hover".



(NTSC-U)
0888D460 00000000
00030008 00000000
0288D49B 00010000

(PAL)
08891978 00000000
00030008 00000000
028919B3 00010000

(NTSC-J)
08890FC8 00000000
00030008 00000000
02891003 00010000

(NTSC-K)
0887FD80 00000000
00030008 00000000
0287FDBB 00010000



Code Creator: JoshuaMK

Print this item

  Max Speed Modifier [JoshuaMK]
Posted by: JoshuaMK - 09-27-2019, 06:35 AM - Forum: Offline Non-Item - Replies (6)

Max Speed Modifier [JoshuaMK]

This version, although longer, actually dynamically edits 2 extra values compared to Volderbeek's version through vanilla code, although I don't know what the effects are.
You can also edit the base speed independently from the max speed. (It's recommended to keep the two values close so the drifting and wheelie-ing don't become impossible)



(NTSC-U)
C2571CA4 00000002
3D00XXXX 91030018
C0230018 00000000
C2571CF4 00000002
3D80YYYY 91891134
C0091134 00000000

(PAL)
C2578508 00000002
3D00XXXX 91030018
C0230018 00000000
C2578558 00000002
3D80YYYY 91891134
C0091134 00000000

(NTSC-J)
C2577E88 00000002
3D00XXXX 91030018
C0230018 00000000
C2577ED8 00000002
3D80YYYY 91891134
C0091134 00000000

(NTSC-K)
C2566560 00000002
3D00XXXX 91030018
C0230018 00000000
C25665B0 00000002
3D80YYYY 91891134
C0091134 00000000



XXXX = BASE SPEED
YYYY = MAX SPEED

Some X Values:
0 km/h = 0000
2 km/h = 4000
5 km/h = 41C8
50 km/h = 4248
75 km/h = 4296
100 km/h = 42C8
150 km/h = 4316
200 km/h = 4348
250 km/h = 437A
300 km/h = 4396
400 km/h = 43C8
500 km/h = 43FA
700 km/h = 442F
1000 km/h = 447A
1200 km/h = 4496
1600 km/h = 44C8
2400 km/h = 4516
4000 km/h = 457A



#ASM

#~~~~~~~~~~~~#
#Inject > 80571CA4#
#~~~~~~~~~~~#

lis r8, 0xBASESPEED
stw r8, 0x0018 (r3)
lfs f1, 0x0018 (r3)

#~~~~~~~~~~~~#
#Inject > 80571CF4#
#~~~~~~~~~~~#

lis r12, 0xMAXSPEED
stw r12, 0x1134 (r9)
lfs f0, 0x1134 (r9)



Code Creator: JoshuaMK
Code Contributors: Volderbeek (Speed Hook)

Print this item

  Wheelie Never Times Out [JoshuaMK]
Posted by: JoshuaMK - 09-27-2019, 01:13 AM - Forum: Offline Non-Item - Replies (2)

Wheelie Never Times Out [JoshuaMK]

This code keeps you from ever needing to re-wheelie. No more need for luck-wheelie BOTs!



(NTSC-U)
04581CD0 60000000

(PAL)
045884F4 60000000

(NTSC-J)
04587E74 60000000

(NTSC-K)
0457653C 60000000



Code Creator: JoshuaMK

Print this item

  Dynamic Gravity (CTGP 200cc) [JoshuaMK]
Posted by: JoshuaMK - 09-26-2019, 09:16 PM - Forum: Incomplete & Outdated Codes - No Replies

Dynamic Gravity (CTGP 200cc) [JoshuaMK]

NOTE: Outdated by 3.0 CTGP version.

A modded Dynamic Gravity code made to work as closely to CTGP's dynamic gravity as possible. Only real difference is with this code, you can't cheese blue shells by abusing the gravity, which in my opinion makes this code superior to the one in CTGP.



(NTSC-U)
C25801FC 00000002
3D808142 D00300F4
D00C0800 00000000
C2590400 00000007
3D608142 3C804078
908B0804 C14B0804
C1AB0800 EDAD02B2
C03F0000 FD400890
EC21682A FF815040
409C0008 FC205090
60000000 00000000

(PAL)
C2586A20 00000002
3D808142 D00300F4
D00C0800 00000000
C2596C24 00000007
3D608142 3C804078
908B0804 C14B0804
C1AB0800 EDAD02B2
C03F0000 FD400890
EC21682A FF815040
409C0008 FC205090
60000000 00000000

(NTSC-J)
C25863A0 00000002
3D808142 D00300F4
D00C0800 00000000
C25965A4 00000007
3D608142 3C804078
908B0804 C14B0804
C1AB0800 EDAD02B2
C03F0000 FD400890
EC21682A FF815040
409C0008 FC205090
60000000 00000000

(NTSC-K)
C2574A78 00000002
3D808142 D00300F4
D00C0800 00000000
C2584C7C 00000007
3D608142 3C804078
908B0804 C14B0804
C1AB0800 EDAD02B2
C03F0000 FD400890
EC21682A FF815040
409C0008 FC205090
60000000 00000000



#ASM

#~~~~~~~~~~~~#
#Inject > 805801FC#
#~~~~~~~~~~~#

lis r12, 0x8142
stfs f0, 0x00F4 (r3)
stfs f0, 0x0800 (r12)

#~~~~~~~~~~~~#
#Inject > 80590400#
#~~~~~~~~~~~#

lis r11, 0x8142
lis r4, 0x4078
stw r4, 0x0804 (r11)
lfs f10, 0x0804 (r11)
lfs f13, 0x0800 (r11)
fmuls f13, f13, f10
lfs f1, 0 (r31)
fmr f10, f1
fadds f1, f1, f13
fcmpo cr7, f1, f10
bge cr7, the_end
fmr f1, f10
the_end:



Code Creator: JoshuaMK
Code Contributors: Hamster35000vr (Gravity Float Address)

Print this item