├── BUGS.txt ├── COMPILING.txt ├── DEBUG.txt ├── DV-Source ├── a │ ├── asm_engine.s │ ├── assemble.s │ ├── bin2txt.s │ ├── branchlabelparser.s │ ├── finalize_assembled_bin.s │ ├── fix_neg_hex.s │ ├── gencodebinsize.s │ ├── simm_length_checker.s │ └── source_parser.s ├── b │ ├── DCStoreRange.s │ ├── ICInvalidateRange.s │ ├── add_header.s │ ├── get_geckoheadertype.s │ ├── newline_fixer.s │ └── saveANDoverwrite_geckoheader.s ├── d │ ├── codetxt2bin.s │ ├── codetxtparser.s │ ├── codetxtpostparsersize.s │ ├── dasm_engine.s │ ├── disassemble.s │ ├── fixwaltress_nulls.s │ └── prep_waltress_dbin.s └── main.S ├── DV └── main ├── Examples ├── 04codetype │ ├── code.txt │ └── source.s ├── 06codetype │ ├── code.txt │ └── source.s ├── C0codetype │ ├── code.txt │ └── source.s └── C2codetype │ ├── code.txt │ └── source.s ├── HBC-Source ├── Makefile ├── build │ ├── add_header.s │ ├── asm_engine.s │ ├── assemble.s │ ├── bin2txt.s │ ├── branchlabelparser.s │ ├── codetxt2bin.s │ ├── codetxtparser.s │ ├── codetxtpostparsersize.s │ ├── dasm_engine.s │ ├── disassemble.s │ ├── finalize_assembled_bin.s │ ├── fix_neg_hex.s │ ├── fixwaltress_nulls.s │ ├── gencodebinsize.s │ ├── get_geckoheadertype.s │ ├── main.s │ ├── newline_fixer.s │ ├── prep_waltress_dbin.s │ ├── saveANDoverwrite_geckoheader.s │ ├── simm_length_checker.s │ └── source_parser.s └── source │ ├── add_header.c │ ├── asm_engine.c │ ├── assemble.c │ ├── bin2txt.c │ ├── branchlabelparser.c │ ├── codetxt2bin.c │ ├── codetxtparser.c │ ├── codetxtpostparsersize.c │ ├── dasm_engine.c │ ├── disassemble.c │ ├── finalize_assembled_bin.c │ ├── fix_neg_hex.c │ ├── fixwaltress_nulls.c │ ├── gencodebinsize.c │ ├── get_geckoheadertype.c │ ├── main.c │ ├── newline_fixer.c │ ├── prep_waltress_dbin.c │ ├── saveANDoverwrite_geckoheader.c │ ├── simm_length_checker.c │ └── source_parser.c ├── HBC-Waltress ├── boot.dol ├── icon.png └── meta.xml ├── HISTORY.txt ├── LICENSE ├── NOTES.txt ├── README ├── script.sh └── test_source.s /BUGS.txt: -------------------------------------------------------------------------------- 1 | Bug003: The very first instruction of any source *CANNOT* be a branch that uses a branch label. Its label will not be converted to a SIMM. Then Waltress will try to assemble the branch instruction as a regular instruction, which will result in a sscanf failure (invalid instruction). 2 | Bug004: The checks to make sure Branch Labels use Capital Letters and/or Underscores fails. Then Waltress will try to assemble the branch instruction as a regular instruction, which will result in a sscanf failure (invalid instruction). 3 | Bug007: Branch SIMMs must be in unsigned form or else certain conditional branches will have the wrong bit hint value assembled. 4 | -------------------------------------------------------------------------------- /COMPILING.txt: -------------------------------------------------------------------------------- 1 | How to compile HBC App Source (Linux) 2 | 3 | Requirements: You must already have DevkitPPC installed and its environment set. 4 | 5 | Step 1: Make script.sh executable 6 | chmod +x ./script.sh 7 | 8 | Step 2: Execute the script 9 | ./script.sh 10 | 11 | Step 3: Delete old boot.dol located at /HBC-Waltress, and replace with new boot.dol that's located at /HBC-Source. Congratz. 12 | 13 | ========== 14 | 15 | How to compile Desktop App Source (Linux) 16 | 17 | Step 1. Install PowerPC Linux Compiler & QEMU 18 | sudo apt-get update 19 | sudo apt-get install gcc-powerpc-linux-gnu build-essential binutils-powerpc-linux-gnu binutils-powerpc-linux-gnu-dbg qemu-user qemu-user-static 20 | 21 | Step 3: Build from Source Code 22 | cd DV-Source 23 | powerpc-linux-gnu-gcc -Wa,-mregnames -ggdb3 -o main -static main.S 24 | 25 | Step 4: Make file executable 26 | chmod +x ./main 27 | 28 | Step 5: Delete old main 29 | cd DV 30 | rm main 31 | 32 | Step 6: Final step 33 | Move newly compiled main file into DV folder. Congratz. 34 | -------------------------------------------------------------------------------- /DEBUG.txt: -------------------------------------------------------------------------------- 1 | How to Debug the Desktop App if desired. Linux Guide only. 2 | 3 | Step 1: Install QEMU and GDB 4 | sudo apt-get update 5 | sudo apt-get install qemu-user qemu-user-static gdb-multiarch build-essential 6 | 7 | Step 2: Run Waltress-DV with QEMU (process will stall, this is normal) 8 | cd DV 9 | qemu-ppc -g 1234 ./main 10 | 11 | Step 3: While leaving Step 2's Terminal intact, open a different terminal in same directory and run this GDB command: 12 | gdb-multiarch -q --nh \ 13 | -ex 'set architecture ppc' \ 14 | -ex 'file main' \ 15 | -ex 'target remote localhost:1234' \ 16 | -ex 'break main' \ 17 | -ex continue \ 18 | -ex 'layout split' \ 19 | -ex 'layout regs' 20 | 21 | Now you are ready to use GDB to step thru and debug Waltress-DV. Registers may not be available. If this is the case, issue 1 stepi command. You will now see the registers. 22 | 23 | GDB quick guide (use Google for help with other commands): 24 | stepi = step instruction 25 | break *0xX = breakpoint at address, X = address (i.e. break *0x100008FC) 26 | del X = delete breakpoint via its assigned number. whenever you set or hit a bp, GDB will show the BP's assigned number 27 | continue = run program after hitting break point 28 | quit = exits GDB and properly ends the QEMU emulation. Be sure to always quit GDB first before closing the qemu terminal 29 | 30 | -------------------------------------------------------------------------------- /DV-Source/a/assemble.s: -------------------------------------------------------------------------------- 1 | #Assemble Func (void) 2 | #r3 returns 0 for success, any negative number is error 3 | 4 | #Open code.txt to make sure one doesn't exist 5 | #Open abin.bin, get size, alloc mem, dump, close 6 | #Open sourse.s, get size, alloc mem, dump, close 7 | #Count 0xA ascii bytes present to estimate needed size sourse's generated code.txt 8 | #Mem alloc for estimated size 9 | #Update cache for abin.bin since we will execute on it 10 | #Run waltress abin.bin 11 | #Create code.text, write to it, close, success 12 | 13 | #r31 = fd, then code.txt pointer 14 | #VOID NOW r30 = abin.bin size 15 | #VOID NOW r29 = abin.bin pointer 16 | #r28 = sourse.s size 17 | #r27 = sourse.s pointer 18 | #r26 = C2, C0, 04, 06, RAW flag 19 | 20 | #Directives 21 | asources: 22 | .asciz "source.s" 23 | acodetxt: 24 | .asciz "code.txt" 25 | arb: 26 | .asciz "rb" 27 | awb: 28 | .asciz "wb" 29 | afopencodetxtEC: 30 | .asciz "\n\nError! Code.txt already exists. Delete it and try again.\n\n" 31 | afopensourceEC: 32 | .asciz "\n\nError! Can't find source.s. This file needs to be present for assembling. Is the file named incorrectly?\n\n" 33 | afseeksourceEC: 34 | .asciz "\n\nError! fseek failure on source.s.\n\n" 35 | amemalignsourceEC: 36 | .asciz "\n\nError! Can't allocate memory for source.s.\n\n" 37 | afreadsourceEC: 38 | .asciz "\n\nError! Unable to dump source.s to memory.\n\n" 39 | afclosesourceEC: 40 | .asciz "\n\nError! Can't close source.s.\n\n" 41 | ageckoheaderEC: 42 | .asciz "\n\nError! The Gecko Header is not the correct format or an unsupported Header type is being used.\n\n" 43 | asavestripmallocEC: 44 | .asciz "\n\nError! Can't allocate memory within the Save and Strip Gecko Header subroutine.\n\n" 45 | amemalignTOBEcodebinEC: 46 | .asciz "\n\nError! Can't allocate memory for temporary code.bin.\n\n" 47 | awaltressSscanfFailureEC: 48 | .asciz "\n\nError! A sscanf failure occurred when Waltress tried assembling the above instruction. Please note that all spaces are stripped out, this is normal. Did you typo the instruction name? Did you forget a comma? Did you forget to prepend a Hex value with 0x? Did you forget to prepend a GPR with the letter r? Did you forget to prepend a FPR with the letter f? If the above instruction is andi/andis, did you forget to add a period after the instruction name?\n\n" 49 | awaltressBadParamEC: 50 | .asciz "\n\nError! The above instruction was interpreted by Waltress to be valid, but an invalid parameter (register value, imm value, etc) was used. Please note that all spaces are stripped out, this is normal. Did you exceed the SIMM-16 range? Did you exceed the UIMM-16 range? Are you following the IMM Format rules? Did you exceed the SIMM-12 range for a psq load/store? Are you using a crF number higher than 7?\n\n" 51 | amemaligncodetxtEC: 52 | .asciz "\n\nError! Can't allocate memory for code.txt.\n\n" 53 | afcreatecodetxtEC: 54 | .asciz "\n\nError! Can't create new code.txt. If you are using the Desktop Version, make sure the DV folder has user permissions enabled.\n\n" 55 | afwritecodetxtEC: 56 | .asciz "\n\nError! Can't write content to newly created code.txt.\n\n" 57 | afclosecodetxtEC: 58 | .asciz "\n\nError! Can't close new code.txt.\n\n" 59 | 60 | .align 2 61 | 62 | #Prologue 63 | .globl assemble 64 | assemble: 65 | stwu sp, -0x0030 (sp) 66 | mflr r0 67 | stw r22, 0x8 (sp) 68 | stw r23, 0xC (sp) 69 | stw r24, 0x10 (sp) 70 | stw r25, 0x14 (sp) 71 | stw r26, 0x18 (sp) 72 | stw r27, 0x1C (sp) 73 | stw r28, 0x20 (sp) 74 | stw r29, 0x24 (sp) 75 | stw r30, 0x28 (sp) 76 | stw r31, 0x2C (sp) 77 | stw r0, 0x0034 (sp) 78 | 79 | #Open code.txt, one shouldn't exist 80 | lis r3, acodetxt@h 81 | lis r4, arb@h 82 | ori r3, r3, acodetxt@l 83 | ori r4, r4, arb@l 84 | bl fopen 85 | cmpwi r3, 0 86 | lis r3, afopencodetxtEC@h 87 | ori r3, r3, afopencodetxtEC@l 88 | bne- assembleerror #YES this is bne! We don't want file to exist 89 | 90 | #Open source.s 91 | lis r3, asources@h 92 | lis r4, arb@h 93 | ori r3, r3, asources@l 94 | ori r4, r4, arb@l 95 | bl fopen 96 | mr. r31, r3 97 | lis r3, afopensourceEC@h 98 | ori r3, r3, afopensourceEC@l 99 | beq- assembleerror 100 | 101 | #Get size of source.s 102 | mr r3, r31 103 | li r4, 0 104 | li r5, 2 #Seek end 105 | bl fseek 106 | cmpwi r3, 0 107 | lis r3, afseeksourceEC@h 108 | ori r3, r3, afseeksourceEC@l 109 | bne- assembleerror 110 | mr r3, r31 111 | bl ftell #No error check for this 112 | 113 | #Rewind file stream position 114 | #Alloc mem for source.s 115 | #*NOTE* We have source.s filesize but future custom subfuncs require the file ends in a null byte, therefore add 1 to the file size before calling memalign. 116 | #*NOTE* Also, the gencodebinsize.s function further below requires source.s end in 0xA (enter), therefore we have to add 1 to the file for that as well (total of 2 bytes added) 117 | addi r28, r3, 2 118 | mr r3, r31 119 | bl rewind 120 | li r3, 32 121 | mr r4, r28 122 | bl memalign 123 | mr. r27, r3 124 | lis r3, amemalignsourceEC@h 125 | ori r3, r3, amemalignsourceEC@l 126 | beq- assembleerror 127 | 128 | #Dump source.s, close 129 | mr r3, r27 130 | li r4, 1 131 | subi r5, r28, 2 #This is because we added 2 fake bytes from earlier!!! 132 | mr r6, r31 133 | bl fread 134 | subi r0, r28, 2 135 | cmpw r3, r0 136 | lis r3, afreadsourceEC@h 137 | ori r3, r3, afreadsourceEC@l 138 | bne- assembleerror 139 | mr r3, r31 140 | bl fclose 141 | cmpwi r3, 0 142 | lis r3, afclosesourceEC@h 143 | ori r3, r3, afclosesourceEC@l 144 | bne- assembleerror 145 | 146 | #Append an 0x0A00 to file (last halfword of allocated block), because we allocated 2 extra bytes and future funcs require the file to end in 0x0A00 (enter new line then null) 147 | subi r3, r28, 2 148 | li r4, 0x0A00 149 | sthx r4, r3, r27 150 | 151 | #Patch carriages 152 | mr r3, r27 153 | bl newline_fixer 154 | 155 | #Get the Gecko Header type from source.s 156 | #-1 = Invalid 157 | #0 = Raw 158 | #1 = C2 159 | #2 = 04 160 | #3 = 06 161 | #4 = C0 162 | mr r3, r27 163 | bl get_geckoheadertype 164 | mr. r24, r3 165 | lis r3, ageckoheaderEC@h 166 | ori r3, r3, ageckoheaderEC@l 167 | blt- assembleerror 168 | beq- skipstrip 169 | 170 | #Call func that saves gecko header then overwrites it with spaces 171 | #r3 returns malloced space where header is saved at 172 | #r3 arg = gecko header type 173 | #r4 arg = source.s ptr, source.s must end in null byte 174 | mr r3, r24 175 | mr r4, r27 176 | bl saveANDoverwrite_geckoheader 177 | mr. r23, r3 178 | lis r3, asavestripmallocEC@h 179 | ori r3, r3, asavestripmallocEC@l 180 | beq- assembleerror 181 | 182 | #Call the source.s parser to remove any double+ enters, spaces, tabs, and comments 183 | #r3 = pointer to source.s, must end in null byte 184 | #r4 = size of source.s plus null byte 185 | skipstrip: 186 | mr r3, r27 187 | mr r4, r28 #TODO fix me, r28 is incorrect (needs to be decremented) but it actually doesn't matter, func will still work correctly cuz null byte ender. THIS MUST BE fixed in the save and stripper function 188 | bl source_parser #No error check for this 189 | cmpwi r3, 0 190 | bne- assembleerror #If not 0, r3 will hold memory address to return to main.S to print to console 191 | 192 | #Check all SIMM lengths/widths 193 | mr r3, r27 194 | bl simm_length_checker 195 | cmpwi r3, 0 196 | bne- assembleerror #If not 0, r3 will hold memory address to return to main.S to print to console 197 | 198 | #Now change all negative hex SIMMs to their unsigned equivalents 199 | mr r3, r27 200 | bl fix_neg_hex 201 | cmpwi r3, 0 202 | bne- assembleerror #If not 0, r3 will hold memory address to return to main.S to print to console 203 | 204 | #Now remove all branch labels and branch label landing spots 205 | mr r3, r27 206 | bl branchlabelparser 207 | cmpwi r3, 0 208 | bne- assembleerror #If not 0, r3 will hold memory address to return to main.S to print to console 209 | 210 | #Call custom subfunc to generate a temp code.bin's upper bound size, if gecko code, this will be incremented right before running Waltress 211 | #r3 = pointer to source.s 212 | #r3 returns byte size, will never return an error 213 | mr r3, r27 214 | bl gencodebinsize #TODO in this func add checks for gecko type (and arg) because we need to allocate more shit to memalign if so 215 | mr r26, r3 216 | 217 | #Alloc mem for to-be-genned temp code.bin and place its pointer in r31 218 | addi r4, r26, 16 #Highest possible incrementation needed is C0 end that requires a whole end appended,no need to checs, mights as well just increase it across the board for any situation 219 | li r3, 32 220 | bl memalign 221 | mr. r31, r3 222 | lis r3, amemalignTOBEcodebinEC@h 223 | ori r3, r3, amemalignTOBEcodebinEC@l 224 | beq- assembleerror 225 | 226 | #Adjust r30 use based on codetype 227 | cmpwi r24, 0 228 | beq- raw_setup_abin 229 | cmpwi r24, 2 230 | bne- add_eight 231 | 232 | #Increase r30 by 4 cuz 04 codetype 233 | addi r30, r31, 4 234 | b minusOner27 235 | 236 | #Increase r30 by 8 cuz c2/06/c0 codetype 237 | add_eight: 238 | addi r30, r31, 8 239 | b minusOner27 240 | 241 | #Prep for Engine 242 | raw_setup_abin: 243 | mr r30, r31 244 | minusOner27: 245 | addi r27, r27, -1 246 | 247 | main_abinDV_loop: 248 | mr r5, r27 249 | 250 | #Loop 251 | #Check for null byte, if so stop 252 | #Write temp null at 0xA 253 | #Send each source instruction to engine 254 | asm_engine_loop: 255 | lbzu r0, 0x1 (r5) 256 | cmpwi r0, 0 257 | beq- asm_engine_completed 258 | cmpwi r0, 0xA 259 | bne+ asm_engine_loop 260 | 261 | overwrite_enter: 262 | li r0, 0 263 | stb r0, 0 (r5) 264 | 265 | #Give waltress's arg, then update r27 before running engine 266 | addi r3, r27, 1 267 | addi r22, r27, 1 #Save current asm instruction string in r22. If an error occurs after running Waltress, we know the culprit. 268 | mr r4, r30 269 | mr r27, r5 270 | 271 | #RUN WALTRESS ASM (abin.bin) ENGINE 272 | #r27 = r3 = source.s line input addr (must end in null) 273 | #r31 = r4 = code.bin*** output addr (where binary assembled instruction gets written at) 274 | bl asm_engine # :) 275 | cmpwi r3, 0 276 | beq- waltress_loves_us 277 | 278 | cmpwi r3, -3 279 | beq- waltress_sscanf_failure 280 | 281 | #Bad format/parameter error 282 | mr r3, r22 283 | crxor 6,6,6 284 | bl printf #print the culprit 285 | lis r3, awaltressBadParamEC@h #Set new string for next printf 286 | ori r3, r3, awaltressBadParamEC@l 287 | b assembleerror 288 | 289 | #sscanf failure 290 | waltress_sscanf_failure: 291 | mr r3, r22 292 | crxor 6,6,6 293 | bl printf #print the culprit, DON'T use puts 294 | lis r3, awaltressSscanfFailureEC@h #Set new string for next printf 295 | ori r3, r3, awaltressSscanfFailureEC@l 296 | b assembleerror 297 | 298 | #Update r30 (code.bin pointer) & r28 (amount of times engine ran) 299 | waltress_loves_us: 300 | addi r30, r30, 4 301 | b main_abinDV_loop 302 | 303 | asm_engine_completed: 304 | #r3 = code.bin raw size calc (this div'd by 4 = amount of instructions) 305 | #r4 = code.bin pointer 306 | #r5 = codetype 307 | #r6 = gecko header pointer 308 | #r3 returns net code.bin size value 309 | cmpwi r24, 0 310 | beq- mulli_crap 311 | mr r3, r26 312 | mr r4, r31 313 | mr r5, r24 314 | mr r6, r23 315 | bl finalize_assembled_bin 316 | mr r26, r3 317 | 318 | #Multiply saved code.bin size by 3 for code.txt's needed memory 319 | #TODO this allocates too much memory for the job, fix later 320 | mulli_crap: 321 | mulli r4, r26, 3 322 | li r3, 32 323 | mr r25, r4 #Need this for later for memset 324 | bl memalign 325 | mr. r30, r3 #r30 we can use now btw 326 | lis r3, amemaligncodetxtEC@h 327 | ori r3, r3, amemaligncodetxtEC@l 328 | beq- assembleerror 329 | 330 | #Memset it w/ null. Needed because we will eventually count the content size 331 | mr r3, r30 332 | li r4, 0 333 | mr r5, r25 334 | bl memset 335 | 336 | #Change code.bin to code.txt 337 | #Call Hex2ASCII 338 | #r3 = source pointer 339 | #r4 = dest pointer 340 | #r5 = code bin word size (byte / 4) 341 | mr r3, r31 342 | mr r4, r30 343 | srawi r5, r26, 2 #TODO needs adjustment after running finalizeassembled func 344 | bl bin2txt 345 | 346 | #Get length of current code.txt (EXclude null byte ender) 347 | addi r3, r30, -1 348 | li r28, 0 #We don't have any more need for r28, free to use now 349 | lbzu r0, 0x1 (r3) 350 | cmpwi r0, 0 351 | beq- 0xC 352 | addi r28, r28, 1 353 | b -0x10 354 | 355 | #Add in saved gecko header to code.txt 356 | cmpwi r24, 0 #If Raw, skip ofc 357 | beq- create_codetxt 358 | 359 | #r3 = pointer to code.txt 360 | #r4 = code.txt size EXcluding null 361 | #r5 = pointer to gecko header 362 | #r6 = gecko header type 363 | #r3 returns updated size that EXcludes null 364 | mr r3, r30 365 | mr r4, r28 366 | mr r5, r23 367 | mr r6, r24 368 | bl add_header 369 | mr r28, r3 370 | 371 | #Create finished code.txt 372 | create_codetxt: 373 | lis r3, acodetxt@h 374 | lis r4, awb@h 375 | ori r3, r3, acodetxt@l 376 | ori r4, r4, awb@l 377 | bl fopen 378 | mr. r29, r3 379 | lis r3, afcreatecodetxtEC@h 380 | ori r3, r3, afcreatecodetxtEC@l 381 | beq- assembleerror 382 | li r4, 1 383 | mr r3, r30 384 | mr r5, r28 #Count (real size) 385 | mr r6, r29 386 | bl fwrite 387 | cmpw r3, r28 388 | lis r3, afwritecodetxtEC@h 389 | ori r3, r3, afwritecodetxtEC@l 390 | bne- assembleerror 391 | mr r3, r29 392 | bl fclose 393 | cmpwi r3, 0 394 | lis r3, afclosecodetxtEC@h 395 | ori r3, r3, afclosecodetxtEC@l 396 | bne- assembleerror 397 | 398 | #TODO add in code to free up allocated blocks of mem 399 | 400 | #Success! 401 | li r3, 0 402 | 403 | assembleerror: 404 | lwz r0, 0x0034 (sp) 405 | lwz r31, 0x2C (sp) 406 | lwz r30, 0x28 (sp) 407 | lwz r29, 0x24 (sp) 408 | lwz r28, 0x20 (sp) 409 | lwz r27, 0x1C (sp) 410 | lwz r26, 0x18 (sp) 411 | lwz r25, 0x14 (sp) 412 | lwz r24, 0x10 (sp) 413 | lwz r23, 0xC (sp) 414 | lwz r22, 0x8 (sp) 415 | mtlr r0 416 | addi sp, sp, 0x0030 417 | blr 418 | -------------------------------------------------------------------------------- /DV-Source/a/bin2txt.s: -------------------------------------------------------------------------------- 1 | #r3 = source pointer 2 | #r4 = dest pointer 3 | #r5 = code.bin byte size / 4 4 | 5 | .globl bin2txt 6 | bin2txt: 7 | stwu sp, -0x0020 (sp) 8 | mflr r0 9 | stw r26, 0x8 (sp) 10 | stw r27, 0xC (sp) 11 | stw r28, 0x10 (sp) 12 | stw r29, 0x14 (sp) 13 | stw r30, 0x18 (sp) 14 | stw r31, 0x1C (sp) 15 | stw r0, 0x0024 (sp) 16 | 17 | #Save args 18 | addi r31, r3, -4 19 | addi r30, r4, -1 20 | 21 | #Set Loop Amount 22 | mtctr r5 23 | 24 | #Set space vs enter flag 25 | li r26, -1 26 | 27 | #Loop 28 | bin2txtloop: 29 | lwzu r0, 0x4 (r31) 30 | rlwinm r6, r0, 4, 0x0000000F #srwi r6, r5, 28 31 | rlwinm r7, r0, 8, 0x0000000F 32 | rlwinm r8, r0, 12, 0x0000000F 33 | rlwinm r9, r0, 16, 0x0000000F 34 | rlwinm r10, r0, 20, 0x0000000F 35 | rlwinm r29, r0, 24, 0x0000000F 36 | rlwinm r4, r0, 28, 0x0000000F 37 | rlwinm r5, r0, 0, 0x0000000F #clrlwi r5, r5, 28 38 | 39 | mr r3, r6 40 | bl hex2ascii 41 | rlwimi r27, r3, 24, 0xFFFFFFFF #Needed to not use any junk data thats residing in r27 42 | 43 | mr r3, r7 44 | bl hex2ascii 45 | rlwimi r27, r3, 16, 0x00FF0000 46 | 47 | mr r3, r8 48 | bl hex2ascii 49 | rlwimi r27, r3, 8, 0x0000FF00 50 | 51 | mr r3, r9 52 | bl hex2ascii 53 | rlwimi r27, r3, 0, 0x000000FF 54 | 55 | mr r3, r10 56 | bl hex2ascii 57 | rlwimi r28, r3, 24, 0xFFFFFFFF #Needed to not use any junk data thats residing in r27 58 | 59 | mr r3, r29 60 | bl hex2ascii 61 | rlwimi r28, r3, 16, 0x00FF0000 62 | 63 | mr r3, r4 64 | bl hex2ascii 65 | rlwimi r28, r3, 8, 0x0000FF00 66 | 67 | mr r3, r5 68 | bl hex2ascii 69 | rlwimi r28, r3, 0, 0x000000FF 70 | 71 | #Check space vs enter flag, also store r27 and r28 to give time for branch prediction 72 | not. r26, r26 73 | stw r27, 0x1 (r30) 74 | stw r28, 0x5 (r30) 75 | bne- 0xC 76 | #Write space 0x20 77 | li r3, 0x20 78 | b 0x8 79 | #Write enter 0xA 80 | li r3, 0xA 81 | stbu r3, 0x9 (r30) 82 | bdnz+ bin2txtloop 83 | 84 | #Write null byte over final space/enter 85 | li r0, 0 86 | stb r0, 0x0 (r30) 87 | 88 | #End func 89 | lwz r0, 0x0024 (sp) 90 | lwz r31, 0x1C (sp) 91 | lwz r30, 0x18 (sp) 92 | lwz r29, 0x14 (sp) 93 | lwz r28, 0x10 (sp) 94 | lwz r27, 0xC (sp) 95 | lwz r26, 0x8 (sp) 96 | mtlr r0 97 | addi sp, sp, 0x0020 98 | blr 99 | 100 | hex2ascii: 101 | cmplwi r3, 9 102 | bgt- 0xC #less likely branch because A-F is less possible outcomes than 0-9 103 | ori r3, r3, 0x30 104 | blr 105 | addi r3, r3, 0x37 106 | blr 107 | -------------------------------------------------------------------------------- /DV-Source/a/branchlabelparser.s: -------------------------------------------------------------------------------- 1 | #This gets immediately called AFTER source.s parser 2 | no_landing_spot_text: 3 | .asciz "\n\nError! The above instruction's branch label doesn't have a landing spot.\n\n" 4 | too_small_text: 5 | .asciz "\n\nError! The above instruction's branch label is not at least 3 characters in length.\n\n" 6 | too_much_text: 7 | .asciz "\n\nError! The above instruction's branch label exceeds 31 characters in length.\n\n" 8 | invalid_char_text: 9 | .asciz "\n\nError! The above instruction's branch label uses an invalid character.\n\n" 10 | too_far_jump_condi_text: 11 | .asciz "\n\nError! The above instruction's branch label (conditional) has a jump that exceeds 0x7FFC.\n\n" 12 | too_far_jump_uncondi_text: 13 | .asciz "\n\nError! The above instruction's branch label (unconditional) has a jump that exceeds 0x01FFFFFC.\n\n" 14 | duplicate_spots: 15 | .asciz "\n\nError! The above instruction's branch label has at least 2 different landing spots.\n\n" 16 | malloc_text: 17 | .asciz "\n\nError! For whatever reason, memory couldn't be allocated when needing to expand source.s due to a label-to-simm conversion.\n\n" 18 | .align 2 19 | 20 | .globl branchlabelparser 21 | branchlabelparser: 22 | 23 | #Func processes branch labels 24 | #Branch instructions receive their SIMMs 25 | #Landing labels gets removed 26 | 27 | #Args 28 | #r3 = source.s ptr (MUST END IN NULL or else overflow occurs) 29 | #Return Values 30 | #r3 = 0 (success) 31 | #r3 = Pointer to ASCII error message if not success 32 | 33 | /* 34 | r31 = source.s 35 | r30 = branch label ptr 36 | r29 = simm max 37 | r28 = length of branch label 38 | r27 = branch lebal landing ptr 39 | r26 = source.s size 40 | r25 = brand new source.s ptr (will replace assemble.s's r27 if used) 41 | */ 42 | 43 | #Symbols 44 | .set branch_ident, 0x0A62 #/nb 45 | .set underscore, 0x5F #_ 46 | .set colon, 0x3A #: 47 | 48 | #Prologue 49 | stwu sp, -0x0030 (sp) 50 | mflr r0 51 | stw r25, 0x14 (sp) #0x8 thru 0x13 is buffer 52 | stw r26, 0x18 (sp) 53 | stw r27, 0x1C (sp) 54 | stw r28, 0x20 (sp) 55 | stw r29, 0x24 (sp) 56 | stw r30, 0x28 (sp) 57 | stw r31, 0x2C (sp) 58 | stw r0, 0x0034 (sp) 59 | 60 | #Save arg 61 | mr r31, r3 62 | 63 | #Search for 0x0A62 (/nb) 64 | subi r30, r31, 1 65 | ROOTLOOP: 66 | lhzu r0, 0x1 (r30) 67 | srwi. r4, r0, 8 #Check for EoF null byteROOTLOOP 68 | beq- erase_landing_spots 69 | cmpwi r0, branch_ident 70 | bne+ ROOTLOOP 71 | 72 | #Possible branch found, check character after b 73 | #lf capital letter or underscore, its a label for uncondi branch 74 | lbzu r0, 0x2 (r30) 75 | cmpwi r0, 0x6C #l 76 | beq- condibranch 77 | cmpwi r0, 0x67 #g 78 | beq- condibranch 79 | cmpwi r0, 0x65 #e 80 | beq- condibranch 81 | cmpwi r0, 0x73 #s 82 | beq- condibranch 83 | cmpwi r0, 0x6E #n 84 | beq- condibranch 85 | cmpwi r0, 0x64 #d 86 | beq- condibranch 87 | cmpwi r0, underscore 88 | beq- uncondibranch 89 | cmplwi r0, 0x41 #A 90 | blt- ROOTLOOP 91 | cmplwi r0, 0x5A #Z 92 | bgt- ROOTLOOP 93 | 94 | #Uncondi branch possibly found, set one-way SIMM max value 95 | uncondibranch: 96 | #Check for "0x" 97 | lhz r0, 0 (r30) 98 | cmpwi r0, 0x3078 99 | beq- ROOTLOOP #SIMM used, not label, skip branch! 100 | lis r29, 0x01FF 101 | ori r29, r29, 0xFFFC 102 | b get_label_length 103 | 104 | #Condi branch possibly found, set one-way SIMM value max 105 | #Atm, r30 is at the char right after (b). Every conditional branch is bxx or greater, so add one to r30 then start doing update-type loop,load, and check 106 | condibranch: 107 | addi r30, r30, 1 108 | condibranch_loop: 109 | lbzu r0, 0x1 (r30) 110 | cmpwi r0, 0 111 | beq- erase_landing_spots 112 | cmpwi r0, 0xA 113 | beq- ROOTLOOP 114 | cmpwi r0, 0x30 #check for 0 out of possible 0x 115 | bne- 0x10 116 | lbz r0, 0x1 (r30) 117 | cmpwi r0, 0x78 #check for x out of possible 0x 118 | beq- ROOTLOOP #SIMM found instead of branch label, skip this branch!!! 119 | cmpwi r0, underscore 120 | li r29, 0x7FFC 121 | beq- get_label_length 122 | cmplwi r0, 0x41 #A 123 | blt- condibranch_loop 124 | cmplwi r0, 0x5A #Z 125 | bgt- condibranch_loop 126 | 127 | #r30 (Branch label ptr/cursor) is fully adjusted, now get length of label 128 | #Must be *in* between 3 and 32 129 | get_label_length: 130 | mr r3, r30 #Keep GVR intact for later 131 | lbzu r0, 0x1 (r3) 132 | cmpwi r0, 0xA 133 | bne+ -0x8 134 | sub r28, r3, r30 135 | cmplwi r28, 3 136 | blt- too_short 137 | cmplwi r28, 31 138 | bgt- too_long 139 | 140 | #Branch labels can ONLY contain capital letters and underscores 141 | subi r3, r30, 1 142 | char_validator: 143 | lbzu r0, 0x1 (r3) 144 | cmpwi r0, 0xA 145 | beq- search_for_landing_spot 146 | cmplwi r0, 0x41 147 | blt- invalid_branch_char 148 | cmpwi r0, 0x5F 149 | beq- char_validator 150 | cmplwi r0, 0x5A 151 | ble- char_validator 152 | b invalid_branch_char 153 | 154 | #Now search the file for the label's "landing spot" respective label 155 | search_for_landing_spot: 156 | subi r27, r31, 1 157 | compare_labels: 158 | lbzu r0, 0x1 (r27) 159 | cmpwi r0, 0 160 | beq- missing_landing_spot 161 | #r30 = label ptr 162 | #r27 = landing label ptr 163 | #r28 = byte count 164 | mr r3, r30 165 | mr r4, r27 166 | mr r5, r28 167 | bl memcmp 168 | cmpwi r3, 0 169 | bne+ compare_labels 170 | 171 | #Either we found the branch label landing-spot or we just ran into the branch label again 172 | #Colon should be next char 173 | lbzx r0, r27, r28 174 | cmpwi r0, colon 175 | bne- compare_labels 176 | 177 | #Now search rest of file if 2nd+ landing spot exist which it shouldn't 178 | make_sure_no_duplicate_landing_spot_exists: 179 | mr r26, r27 180 | make_sure_no_duplicate_landing_spot_exists_LOOP: 181 | lbzu r0, 0x1 (r26) 182 | cmpwi r0, 0 183 | beq- found_it_for_sure 184 | mr r3, r27 185 | mr r4, r26 186 | addi r5, r28, 1 #Include the colon in count 187 | bl memcmp 188 | cmpwi r3, 0 189 | beq- duplicate_error 190 | b make_sure_no_duplicate_landing_spot_exists_LOOP 191 | 192 | #Now we've found it! 193 | #Make copy of r30 & r27 194 | found_it_for_sure: 195 | mr r3, r30 196 | mr r4, r27 197 | 198 | #First we need to differentiate if the branch SIMM is positive or negative 199 | #lf r30 ptr is less than r27 then its a positive branch 200 | #lf r30 ptr is greater than r27, then its a negative branch 201 | cmplw cr7, r30, r27 #Use cr7 because we need to branch on this conditonal later on!! 202 | blt- cr7, 0x10 #Skip register swap 203 | 204 | #SIMM is negative (backwards branch) Swap r30 (now r3) and r27 (now r4), thank you PPC compiler writer's guide 205 | xor r3, r3, r4 206 | xor r4, r4, r3 207 | xor r3, r3, r4 208 | 209 | #Count amount of 0xA's (enter's) in between the labels 210 | subi r3, r3, 1 211 | li r5, 0 212 | lbzu r0, 0x1 (r3) 213 | cmpw r3, r4 214 | beq- calc_branchlabel_simm 215 | cmpwi r0, 0xA 216 | bne+ -0x10 217 | lbz r0, -0x1 (r3) #Check for : from unrelated branch landing spot, we do NOT want to count that enter 218 | cmpwi r0, colon 219 | beq- -0x1C 220 | addi r5, r5, 1 221 | b -0x24 222 | 223 | #Now we have amount of enters (instruction count), mulli by 4 to get SIMM, then check vs Upper Bound One-way SIMM 224 | calc_branchlabel_simm: 225 | slwi r3, r5, 2 226 | cmplw r3, r29 227 | bgt- exceed_simm 228 | 229 | #Convert SIMM from hex to ascii, store to buffer 230 | blt- cr7, 0x8 #If SIMM (r30 vs r27) is positive, this branch is taken 231 | neg r3, r3 #Negative SIMM needs to be Negative ofc 232 | addi r4, sp, 0x8 233 | bl hex2asciiBParser #Keeping this in a subfunc to not clobber stuff up here 234 | 235 | #SIMM digit length will be hardcoded to 0xXXXXXXXX (10 chars) 236 | #Do Label digits minus SIMM digits, we need this for later, plus it will also decide if we expand, contract, or keep file size same 237 | #0 = do simm write only 238 | #>0 = must contract file then simm write 239 | #<0 = must expand file, adjust key GVRs, then simm write 240 | subic. r3, r28, 10 241 | beq- do_simm_write 242 | 243 | #At this point no matter what, we need to know the current length of source.s (INcluding null byte) 244 | #NOTE Keep cr0 & r3 intact! 245 | subi r4, r31, 1 246 | lbzu r0, 0x1 (r4) 247 | cmpwi cr7, r0, 0 248 | bne+ cr7, -0x8 249 | sub r4, r4, r31 250 | addi r26, r4, 1 #Account for null byte 251 | 252 | #Okay r26 holds length of source.s plus null byte, now branch based on expanding vs contracting file 253 | bgt- must_contract_file 254 | 255 | #Alloc new buffer for filesize + r3 from above subic(.) instruction 256 | sub r3, r26, r3 #r3 (delta) is negative, so a subtraction will yield an addition 257 | bl malloc 258 | mr. r25, r3 259 | beq- malloc_branchparser_error_label 260 | #Transfer from original space to new malloced space 261 | mr r4, r31 262 | mr r5, r26 263 | bl memcpy 264 | 265 | #NOTE: Yes the following is hardcoded, yuck! Edit GVR!!!! 266 | #Source.s is now at a new spot, we need to manually fix r27 267 | stw r25, 0x1C (sp) #Replace caller-saved r27 with callee-made r25 268 | #Fix r30 (label ptr) 269 | sub r3, r30, r31 270 | add r30, r25, r3 271 | #Fix this func's r31 (source.s ptr) 272 | mr r31, r25 273 | #Now we can just memmove it, hooray 274 | 275 | must_contract_file: 276 | #File size needs cut down! Branch label digit length exceeds 10 digits 277 | #memmove 278 | #r3 = dest 279 | #r4 = src 280 | #r5 = length of block 281 | add r4, r30, r28 #Label Ptr + Label Size will result as Src ptr (point at the 0xA right after branch label) 282 | addi r3, r30, 10 #okay to hardcode since all gen'd SIMMs are 0xXXXXXXXX ;r3 NOW set 283 | add r5, r31, r26 #r5 at this moment = one byte PAST null byte ptr 284 | sub r5, r5, r4 #One-past-Null byte ptr - Src ptr = amount to move exactly! 285 | bl memmove 286 | #Only thing left to do is transfer the SIMM ascii to source.s 287 | 288 | #No expanding nor contracting needed, just plug in SIMM ascii! 289 | do_simm_write: 290 | #Transfer from stack buffer to source.s 291 | li r0, 5 292 | addi r3, sp, 6 293 | mtctr r0 294 | subi r4, r30, 2 295 | lhzu r0, 0x2 (r3) 296 | sthu r0, 0x2 (r4) 297 | bdnz+ -0x8 298 | 299 | #Sweet! We did it. Move onto next possible branch label 300 | b ROOTLOOP 301 | 302 | #A branch label has 2 more more landing spots 303 | duplicate_error: 304 | #Null out enter AFTER branch label 305 | mr r3, r30 306 | bl null_post_enter 307 | #Move cursor to previous enter or SoF-1 (start of file minus 1) 308 | mr r3, r30 309 | bl move_cursor_back 310 | #Print the culprit 311 | crxor 6, 6, 6 312 | bl printf 313 | #Return error string to Parent 314 | lis r3, duplicate_spots@h 315 | ori r3, r3, duplicate_spots@l 316 | b branchlabelepilogue 317 | 318 | #A branch label's landing spot is missing 319 | missing_landing_spot: 320 | #Null out enter AFTER branch label 321 | mr r3, r30 322 | bl null_post_enter 323 | #Move cursor to previous enter or SoF-1 (start of file minus 1) 324 | mr r3, r30 325 | bl move_cursor_back 326 | #Print the culprit 327 | crxor 6, 6, 6 328 | bl printf 329 | #Return error string to Parent 330 | lis r3, no_landing_spot_text@h 331 | ori r3, r3, no_landing_spot_text@l 332 | b branchlabelepilogue 333 | 334 | #Branch min violation 335 | too_short: 336 | #Null out enter AFTER branch label 337 | mr r3, r30 338 | bl null_post_enter 339 | #Move cursor to previous enter or SoF-1 (start of file minus 1) 340 | mr r3, r30 341 | bl move_cursor_back 342 | #Print the culprit 343 | crxor 6, 6, 6 344 | bl printf 345 | #Return error string to Parent 346 | lis r3, too_small_text@h 347 | ori r3, r3, too_small_text@l 348 | b branchlabelepilogue 349 | 350 | #Branch max violation 351 | too_long: 352 | #Null out enter AFTER branch label 353 | mr r3, r30 354 | bl null_post_enter 355 | #Move cursor to previous enter or SoF-1 (start of file minus 1) 356 | mr r3, r30 357 | bl move_cursor_back 358 | #Print the culprit 359 | crxor 6, 6, 6 360 | bl printf 361 | #Return error string to Parent 362 | lis r3, too_much_text@h 363 | ori r3, r3, too_much_text@l 364 | b branchlabelepilogue 365 | 366 | #Branch invalid char violation 367 | invalid_branch_char: 368 | #Null out enter AFTER branch label 369 | mr r3, r30 370 | bl null_post_enter 371 | #Move cursor to previous enter or SoF-1 (start of file minus 1) 372 | mr r3, r30 373 | bl move_cursor_back 374 | #Print the culprit 375 | crxor 6, 6, 6 376 | bl printf 377 | #Return error string to Parent 378 | lis r3, invalid_char_text@h 379 | ori r3, r3, invalid_char_text@l 380 | b branchlabelepilogue 381 | 382 | #Bad SIMM 383 | exceed_simm: 384 | #Null out enter AFTER branch label 385 | mr r3, r30 386 | bl null_post_enter 387 | #Move cursor to previous enter or SoF-1 (start of file minus 1) 388 | mr r3, r30 389 | bl move_cursor_back 390 | #Print the culprit 391 | crxor 6, 6, 6 392 | bl printf 393 | #Depending on SIMM used, send appropriate error message back to parent 394 | cmpwi r29, 0x7FFC 395 | bne- 0x10 396 | lis r3, too_far_jump_condi_text@h 397 | ori r3, r3, too_far_jump_condi_text@l 398 | b branchlabelepilogue 399 | lis r3, too_far_jump_uncondi_text@h 400 | ori r3, r3, too_far_jump_uncondi_text@l 401 | b branchlabelepilogue 402 | 403 | #Malloc failure 404 | malloc_branchparser_error_label: 405 | lis r3, malloc_text@h 406 | ori r3, r3, malloc_text@l 407 | b branchlabelepilogue 408 | 409 | #Done! Only thing left is to remove all branch landing labels (example:) 410 | erase_landing_spots: 411 | #Search for colon 412 | subi r30, r31, 1 413 | erase_landing_spots_loop: 414 | lbzu r0, 0x1 (r30) 415 | cmpwi r0, 0 416 | beq- finally_done 417 | cmpwi r0, colon 418 | bne+ -0x10 419 | 420 | #Get size of source.s's null byte ptr, we have to do this because its possible this function never executed to make an r26 value to use from earlier 421 | mr r5, r30 #No need to restart at beginning of file again 422 | lbzu r0, 0x1 (r5) 423 | cmpwi r0, 0 424 | bne+ -0x8 425 | #r5 now = null byte ptr 426 | 427 | #Found colon 428 | #For the case that if the user has a branch label at the very very very start of file, we first check 429 | #backwards til we see that the current working ptr matches r31 (source.s) ptr 430 | #For NOT the case above, we then check backwards to see once we hit ASCII enter (0xA) 431 | mr r3, r30 432 | lbzu r0, -0x1 (r3) 433 | cmpw r3, r31 434 | beq- 0xC 435 | cmpwi r0, 0xA 436 | bne+ -0x10 437 | #*DON'T* add one to r3 because we need one of the enters gone, or else we will have back to back enters 438 | addi r4, r30, 1 #Src; must be at char right AFTER : 439 | sub r5, r5, r4 #(Null byte ptr - Src ptr) + 1) = amount to move 440 | addi r5, r5, 1 441 | #Before calling memmove make r30 the dest src, needs to be updated before we loop again 442 | mr r30, r3 443 | #Remove the landing label! 444 | bl memmove 445 | b erase_landing_spots_loop 446 | 447 | finally_done: 448 | #ALMOST THERE, if a branch landing label was at very very start of file then the file will start with 0xA which will jack up 449 | #future subroutines and cause crash 450 | lbz r0, 0x0 (r31) 451 | cmpwi r0, 0xA 452 | bne+ actually_done_lol 453 | 454 | #Get null byte ptr; so hacky we need to fix all of this in the future lol 455 | subi r5, r31, 1 456 | lbzu r0, 0x1 (r5) 457 | cmpwi r0, 0 458 | bne+ -0x8 459 | 460 | #r5 now = null byte ptr, set up args for memmove and call it 461 | mr r3, r31 #Dest 462 | addi r4, r31, 1 #Src 463 | sub r5, r5, r4 #(Null byte ptr - Src ptr) + 1) = amount to move 464 | addi r5, r5, 1 465 | bl memmove 466 | 467 | actually_done_lol: 468 | li r3, 0 469 | 470 | branchlabelepilogue: 471 | lwz r0, 0x0034 (sp) 472 | lwz r31, 0x2C (sp) 473 | lwz r30, 0x28 (sp) 474 | lwz r29, 0x24 (sp) 475 | lwz r28, 0x20 (sp) 476 | lwz r27, 0x1C (sp) 477 | lwz r26, 0x18 (sp) 478 | lwz r25, 0x14 (sp) 479 | mtlr r0 480 | addi sp, sp, 0x0030 481 | blr 482 | 483 | hex2asciiBParser: 484 | #First store "0x" to buffer space 485 | li r0, 0x3078 486 | sth r0, 0 (r4) 487 | #Set loop amount 488 | li r0, 8 489 | mtctr r0 490 | #Set initial shiftor amount 491 | li r5, 32 492 | #Adjust r4 for when we stbu the ascii byte 493 | addi r4, r4, 1 494 | #Loop 495 | hex2asciiBParser_loop: 496 | #Update shiftor amount 497 | subi r5, r5, 4 498 | #Extract digit 499 | srw r0, r3, r5 500 | clrlwi r6, r0, 28 501 | #Convert from digit hex to byte ascii 502 | cmplwi r6, 9 503 | bgt- 0xC 504 | ori r7, r6, 0x30 505 | b 0x8 506 | addi r7, r6, 0x37 507 | #Store converted byte to buffer 508 | stbu r7, 0x1 (r4) 509 | #Decrement loop 510 | bdnz+ hex2asciiBParser_loop 511 | #End func 512 | blr 513 | 514 | null_post_enter: 515 | lbzu r0, 0x1 (r3) 516 | cmpwi r0, 0xA 517 | bne+ -0x8 518 | li r0, 0 519 | stb r0, 0 (r3) 520 | blr 521 | 522 | move_cursor_back: 523 | lbzu r0, -0x1 (r3) 524 | cmplw r3, r31 525 | blt- 0xC 526 | cmpwi r0, 0xA 527 | bne+ -0x10 528 | addi r3, r3, 1 529 | blr 530 | -------------------------------------------------------------------------------- /DV-Source/a/finalize_assembled_bin.s: -------------------------------------------------------------------------------- 1 | #Func (right after waltress abin completes) 2 | 3 | #r3 = code.bin raw size calc (this div'd by 4 = amount of instructions) 4 | #r4 = code.bin pointer 5 | #r5 = codetype 6 | #r6 = gecko header pointer 7 | #r3 returns new code.bin size 8 | 9 | #NOTE net instruction amount = total word amount of final code.bin, includes headers, footers etc 10 | #raw size anything = without any gecko shit 11 | 12 | .globl finalize_assembled_bin 13 | finalize_assembled_bin: 14 | #For the case that if somehow this func gets called with RAW, If r5 = 0, simple end func 15 | cmpwi r5, 0 16 | beqlr- 17 | 18 | #Look for C0 next, cuz it needs no stack shit 19 | cmpwi r5, 4 20 | bne- this_is_gonna_suck 21 | 22 | #C0 codetype found 23 | #Write header 24 | Cohohoh: 25 | lis r0, 0xC000 26 | stw r0, 0 (r4) 27 | #If byte size end in 0x0 or 0x8, we need to add whole new line (blr + null word) 28 | #If byte size end in 0x4 or 0xC, we need to add just blr to current last line 29 | andi. r0, r3, 0x4 30 | lis r0, 0x4E80 31 | ori r0, r0, 0x0020 32 | addi r3, r3, 8 #No matter what add 8 to byte amount cuz C0 header and lineamount word holder 33 | stwx r0, r3, r4 #No matter what write the blr 34 | bne- add_four_for_blr 35 | li r0, 0 36 | addi r3, r3, 4 #Add 4 for byte amount for null 37 | stwx r0, r3, r4 38 | add_four_for_blr: 39 | addi r3, r3, 4 #Add 4 for byte amount for blr 40 | #Write in line amount [(current net byte amount - 8) / 8] 41 | subi r5, r3, 8 42 | srawi r0, r5, 3 43 | stw r0, 0x4 (r4) 44 | #r3 ready to return 45 | blr 46 | 47 | #C2/04/06 found, great... lol 48 | this_is_gonna_suck: 49 | stwu sp, -0x0020 (sp) 50 | mflr r0 51 | stw r28, 0x10 (sp) 52 | stw r29, 0x14 (sp) 53 | stw r30, 0x18 (sp) 54 | stw r31, 0x1C (sp) 55 | stw r0, 0x0020 (sp) 56 | 57 | #Backup args 58 | mr r31, r3 59 | mr r30, r4 60 | mr r29, r5 61 | mr r28, r6 62 | 63 | #First change header to binary and store 64 | #Sub func 65 | #r3 = pointer to header 66 | #r3 returns header word in hex 67 | mr r3, r6 68 | bl ascii2hexPARENT #Making this a func so its not cluttered in my way and shit 69 | stw r3, 0 (r30) 70 | 71 | #check codetypes again 72 | cmpwi r29, 1 73 | beq- Ctwotwotwo 74 | cmpwi r29, 2 75 | li r3, 8 76 | beq- finalassemepipen #nothing left to do if 04 codetype 77 | 78 | #06 codetype found 79 | #If byte size end in 0x0 or 0x8, do nothing 80 | #If byte size end in 0x4 or 0xC, we need to add just null word to current last line 81 | andi. r0, r31, 0x4 82 | stw r31, 0x4 (r30) #No matter what write net byte amount in 06byteamount holder 83 | addi r31, r31, 8 #No matter what add 8 to byte amount cuz 06 header and byteamount word holder 84 | beq- just_move_r31 85 | li r0, 0 86 | stwx r0, r31, r30 #Write the null 87 | addi r3, r31, 4 #Add 4 to byte amount cuz null word, return in r3 88 | b finalassemepipen 89 | just_move_r31: 90 | mr r3, r31 #Do NOT add 4 to byte amount. we DONT have added null word. Copy r31 to r3 and return 91 | b finalassemepipen 92 | 93 | #C2 codetype found 94 | #Write header 95 | #r5 = instruction amount that gets updated over time, at end we will mulli by 4 to get net code.bin size 96 | Ctwotwotwo: 97 | #If byte size end in 0x0 or 0x8, we need to add whole new line (nop + null word) 98 | #If byte size end in 0x4 or 0xC, we need to add just null word to current last line 99 | andi. r0, r31, 0x4 100 | li r4, 0 #r4 will write the null word 101 | addi r31, r31, 8 #No matter what add 8 to byte amount cuz C2 header and lineamount word holder 102 | bne- add_c2nullender 103 | lis r0, 0x6000 104 | stwx r0, r31, r30 105 | addi r31, r31, 4 #Add 4 to byte amount cuz nop was needed 106 | add_c2nullender: 107 | stwx r4, r31, r30 108 | addi r31, r31, 4 #Add 4 to byte amount cuz null word no matter what 109 | #Write in line amount [(current net byte amount - 8) / 8] 110 | subi r5, r31, 8 111 | srawi r0, r5, 3 112 | stw r0, 0x4 (r30) 113 | #move r31 to r3 114 | mr r3, r31 115 | 116 | #Epilogue for when codetype is C2/04/06 117 | finalassemepipen: 118 | lwz r0, 0x0020 (sp) 119 | lwz r31, 0x1C (sp) 120 | lwz r30, 0x18 (sp) 121 | lwz r29, 0x14 (sp) 122 | lwz r28, 0x10 (sp) 123 | mtlr r0 124 | addi sp, sp, 0x0020 125 | blr 126 | 127 | #Parent routine for converting header from ascii to hex 128 | #r3 arg = ptr to gecko header 129 | #r3 returns gecko header in hex (word) 130 | ascii2hexPARENT: 131 | li r0, 8 132 | li r4, 28 #Amount to shift left by 133 | li r5, 0 #Clear out register for shift+save usage 134 | mtctr r0 135 | as2hexloop: 136 | lbzu r6, 0x1 (r3) 137 | ## 138 | ascii2hex: 139 | cmplwi r6, 0x3A 140 | blt- cleartodigit 141 | cmplwi r6, 0x60 142 | bgt- sub0x57 143 | #sub 0x37 144 | subi r6, r6, 0x37 145 | b shifty_shift 146 | sub0x57: 147 | subi r6, r6, 0x57 148 | b shifty_shift 149 | cleartodigit: 150 | andi. r6, r6, 0xF 151 | ## 152 | shifty_shift: 153 | slw r6, r6, r4 154 | or r5, r6, r5 155 | subi r4, r4, 4 #Decrement shift-left amount 156 | bdnz+ as2hexloop 157 | mr r3, r5 158 | blr 159 | 160 | -------------------------------------------------------------------------------- /DV-Source/a/fix_neg_hex.s: -------------------------------------------------------------------------------- 1 | fixneghexEC: 2 | .asciz "\n\nError! For whatever reason, the malloc function failed within the fix_neg_hex.s subroutine." 3 | .align 2 4 | 5 | #r3 = Ptr to source.s 6 | #r3 returns 0 for success or addr to return a message for printing back to parent 7 | 8 | .globl fix_neg_hex 9 | fix_neg_hex: 10 | #Prologue 11 | stwu sp, -0x0030 (sp) 12 | mflr r0 13 | stw r27, 0x1C (sp) #0x8 thru 0x11 is buffer space (10 bytes) 14 | stw r28, 0x20 (sp) 15 | stw r29, 0x24 (sp) 16 | stw r30, 0x28 (sp) 17 | stw r31, 0x2C (sp) 18 | stw r0, 0x0034 (sp) 19 | 20 | #Save arg 21 | mr r31, r3 22 | 23 | #Pre decrement loading addr 24 | subi r30, r3, 1 25 | 26 | #ROOT LOOP 27 | fix_neg_hex_ROOT_loop: 28 | lwzu r0, 0x1 (r30) 29 | srwi. r3, r0, 24 #Check for null byte by removing 3 far side right bytes 30 | beq- fix_neg_hex_success 31 | 32 | #Set constant to compare to 33 | lis r3, 0x002D 34 | ori r3, r3, 0x3078 35 | 36 | #Verify against constant 37 | srwi r4, r0, 8 38 | cmpw r3, r4 39 | bne+ fix_neg_hex_ROOT_loop 40 | 41 | #Found negative hex SIMM! 42 | #NOTE First make sure we *SKIP* condi branches 43 | #Make copy of cursor and go back to first enter before current instruction, or SoF-1 (start of file minus 1) 44 | mr r3, r30 45 | lbzu r0, -0x1 (r3) 46 | cmplw r3, r31 47 | blt- 0x10 48 | cmpwi r0, 0xA 49 | beq- 0x8 50 | b -0x14 51 | #Okay we are at \n or at SoF-1, now check if next line instruction was a condi branch 52 | lhz r0, 0x1 (r3) 53 | cmpwi r0, 0x6267 #bg 54 | beq- fix_neg_hex_ROOT_loop 55 | cmpwi r0, 0x6265 #be 56 | beq- fix_neg_hex_ROOT_loop 57 | cmpwi r0, 0x626E #bn 58 | beq- fix_neg_hex_ROOT_loop 59 | cmpwi r0, 0x6264 #bd 60 | beq- fix_neg_hex_ROOT_loop 61 | cmpwi r0, 0x626C #bl 62 | beq- check_for_t_or_e 63 | cmpwi r0, 0x6273 64 | bne+ not_a_condi_branch 65 | #bs found, if char after bs is o, then abort. its a condi branch 66 | lbz r0, 0x3 (r3) 67 | cmpwi r0, 0x6F #o 68 | beq- fix_neg_hex_ROOT_loop 69 | b not_a_condi_branch 70 | check_for_t_or_e: 71 | lbz r0, 0x3 (r3) 72 | cmpwi r0, 0x74 #t 73 | beq- fix_neg_hex_ROOT_loop 74 | cmpwi r0, 0x65 #e 75 | beq- fix_neg_hex_ROOT_loop 76 | 77 | #Okay perfect negative SIMM is *NOT* for a condi branch, good to proceed. 78 | #Count the amount of hexanumerical ascii digits til non-hexanumerical 79 | not_a_condi_branch: 80 | addi r3, r30, 2 #Point to "x" so first load is the first SIMM digit 81 | digit_width_loop: 82 | lbzu r0, 0x1 (r3) 83 | cmplwi r0, 0x2F #0; look for gt 84 | cmplwi cr1, r0, 0x3A #9; look for lt 85 | cmplwi cr4, r0, 0x40 #A; look for gt 86 | cmplwi cr5, r0, 0x47 #F; look for lt 87 | cmplwi cr6, r0, 0x60 #a; look for gt 88 | cmplwi cr7, r0, 0x67 #f; look for lt 89 | #. IF byte (> 2F && < 3A) || (> 40 && < 47) || (> 60 && < 67), then its a hex byte 90 | crand 4*cr0+eq, 4*cr0+gt, 4*cr1+lt #Don't want a crap ton of branch routes, yes this is SLOW 91 | crand 4*cr4+eq, 4*cr4+gt, 4*cr5+lt 92 | crand 4*cr6+eq, 4*cr6+gt, 4*cr7+lt 93 | cror 4*cr0+eq, 4*cr0+eq, 4*cr4+eq 94 | cror 4*cr0+eq, 4*cr0+eq, 4*cr6+eq 95 | beq+ digit_width_loop 96 | 97 | #Get count 98 | sub r29, r3, r30 99 | 100 | #Change negative ascii to temp positive 101 | #Change temp pos ascii to temp pos hex int 102 | #Flip pos hex int to neg (unsigned eqiv) 103 | #Change neg int to final unsigned ascii 104 | addi r3, r30, 3 105 | subi r4, r29, 3 #Discount the "-0x" portion 106 | bl fixneghex_ascii2hex #r3 = src addr, r4 = amount of digits to convert, r3 returns hex word 107 | #Neg it! 108 | neg r3, r3 109 | #Flip back to ascii 110 | addi r4, sp, 8 111 | bl fixneghex_hex2ascii 112 | 113 | #Do Size minus 10 114 | subic. r3, r29, 10 115 | beq- transfer_the_new_simm 116 | 117 | #No matter what, we need source.s plus Null byte length 118 | #Keep cr0 and r3 intact 119 | subi r4, r31, 1 120 | lbzu r0, 0x1 (r4) 121 | cmpwi cr7, r0, 0 122 | bne+ cr7, -0x8 123 | sub r4, r4, r31 124 | addi r28, r4, 1 #Count null byte and save size to r28 125 | 126 | #Now branch (cr7) on whether or not we malloc 127 | bgt- we_DONT_need_malloc 128 | 129 | #Call malloc, and adjust global r27 register (global source.s ptr) 130 | sub r3, r28, r3 #r3 (delta) is negative, so a subtraction will yield an addition 131 | bl malloc 132 | mr. r27, r3 133 | beq- fix_neg_hex_malloc_ec_string_lock 134 | #Memcpy source.s to malloc'd space 135 | mr r4, r31 136 | mr r5, r28 137 | bl memcpy 138 | 139 | #Change GLOBAL r27 with local r27. THIS IS A GLOBAL CHANGE! 140 | stw r27, 0x1C (sp) 141 | #Fix r30 (-0xXXX... ptr) 142 | sub r3, r30, r31 143 | add r30, r27, r3 144 | #Fix this func's r31 (source.s ptr) 145 | mr r31, r27 146 | #Now we can memmove, yay 147 | 148 | we_DONT_need_malloc: 149 | #Memmove portion of file to right to free up inner space to insert 0x00000000 over -0xX... 150 | #r3 = dest; 151 | #r4 = src; where the comma is located (r30) 152 | #r5 = amt (null byte ptr minus src ptr) + 1 153 | add r4, r30, r29 #-0xXX ptr + SIMM width size = src ptr 154 | addi r3, r30, 10 #Okay to hardcode since all newly gen'd SIMMs with be 10 digits in width 155 | add r5, r31, r28 #r5 at this moment = one past PAST null byte ptr 156 | sub r5, r5, r4 #One-past-Null byte ptr - Src ptr = amount to move 157 | bl memmove 158 | 159 | #Transfer newly gen'd SIMM from stack buffer to its spot in updated source.s 160 | #r3 needs to be setup before this section is executed 161 | transfer_the_new_simm: 162 | li r0, 5 #5 halfwords to transfer 163 | addi r3, sp, 6 #r4 is same no matter circumstance 164 | mtctr r0 165 | subi r4, r30, 2 166 | lhzu r0, 0x2 (r3) 167 | sthu r0, 0x2 (r4) 168 | bdnz+ -0x8 169 | b fix_neg_hex_ROOT_loop 170 | 171 | fix_neg_hex_malloc_ec_string_lock: 172 | lis r3, fixneghexEC@h 173 | ori r3, r3, fixneghexEC@l 174 | b 0x8 175 | 176 | #Return 177 | fix_neg_hex_success: 178 | li r3, 0 179 | lwz r0, 0x0034 (sp) 180 | lwz r31, 0x2C (sp) 181 | lwz r30, 0x28 (sp) 182 | lwz r29, 0x24 (sp) 183 | lwz r28, 0x20 (sp) 184 | lwz r27, 0x1C (sp) 185 | mtlr r0 186 | addi sp, sp, 0x0030 187 | blr 188 | 189 | fixneghex_hex2ascii: 190 | #Write "0x" 191 | li r0, 0x3078 192 | sth r0, 0 (r4) 193 | #Set loop amount 194 | li r0, 8 195 | mtctr r0 196 | #Set initial shiftor amount 197 | li r5, 32 198 | #Adjust r4 for when we stbu the ascii byte 199 | addi r4, r4, 1 200 | #Loop 201 | fixneghex_hex2ascii_loop: 202 | #Update shiftor amount 203 | subi r5, r5, 4 204 | #Extract digit 205 | srw r0, r3, r5 206 | clrlwi r6, r0, 28 207 | #Convert from digit hex to byte ascii 208 | cmplwi r6, 9 209 | bgt- 0xC 210 | ori r7, r6, 0x30 211 | b 0x8 212 | addi r7, r6, 0x37 213 | #Store converted byte to buffer 214 | stbu r7, 0x1 (r4) 215 | #Decrement loop 216 | bdnz+ fixneghex_hex2ascii_loop 217 | #End func 218 | blr 219 | 220 | fixneghex_ascii2hex: #r3 = src addr of SIMM hex word, r4 = digit length 221 | mtctr r4 222 | slwi r5, r4, 2 #r4 x 4 = start-off slw shiftor amount (r5) 223 | subi r4, r3, 1 224 | li r3, 0 #Register used to "compile" word 225 | fixneghex_ascii2hex_looppp: 226 | lbzu r6, 0x1 (r4) 227 | cmplwi r6, 0x39 228 | subi r5, r5, 4 #update shiftor amount 229 | bgt- 0xC 230 | clrlwi r6, r6, 28 #change 0x30 thru 0x39 to 0x0 thru 0x9 231 | b place_hex_digit_to_proper_slot 232 | cmplwi r6, 0x46 233 | bgt- 0xC 234 | subi r6, r6, 0x37 #Change 0x61 thru 0x66 to 0xA thru 0xF 235 | b place_hex_digit_to_proper_slot 236 | subi r6, r6, 0x57 #Change 0x41 thru 0x46 to 0xA thru 0xF 237 | place_hex_digit_to_proper_slot: 238 | slw r6, r6, r5 #Place hex digit into its proper slot 239 | or r3, r3, r6 #"compile" hexword 240 | bdnz+ fixneghex_ascii2hex_looppp 241 | blr 242 | -------------------------------------------------------------------------------- /DV-Source/a/gencodebinsize.s: -------------------------------------------------------------------------------- 1 | #Function will return the size of to-be-genned code.bin using source.s's amount of Enters 2 | #r3 arg = pointer to source.s 3 | #r3 returns code.bin size 4 | 5 | .globl gencodebinsize 6 | gencodebinsize: 7 | addi r4, r3, -1 8 | li r3, 0 9 | gencodebinsizeloop: 10 | lbzu r0, 0x1 (r4) 11 | cmpwi r0, 0 12 | beqlr- 13 | cmpwi r0, 0xA 14 | bne+ gencodebinsizeloop 15 | addi r3, r3, 4 16 | b gencodebinsizeloop 17 | -------------------------------------------------------------------------------- /DV-Source/a/simm_length_checker.s: -------------------------------------------------------------------------------- 1 | 2 | #Small func that will prevent segmentations faults if there is an IMM that exceeds 8 ascii bytes in width 3 | simm_length_ec: 4 | .asciz "\n\nError! The above instruction has an IMM value that exceeds 8 digits in width. Please note that all spaces are stripped out. This is normal. Assembling has been rejected to prevent a segmentation fault. The 8 digit count includes leading zeroes. So be sure to remove those if that is the reason for this Error." 5 | .align 2 6 | 7 | .globl simm_length_checker 8 | simm_length_checker: 9 | stwu sp, -0x0010 (sp) 10 | mflr r0 11 | stw r0, 0x0014 (sp) 12 | 13 | #Save arg, no need for GVR since theres no function calls 14 | mr r10, r3 15 | 16 | #Prep r3 for loop 17 | subi r3, r3, 1 18 | 19 | #Test whole file 20 | simm_length_checker_ROOTLOOP: 21 | lhzu r0, 0x1 (r3) 22 | srwi. r4, r0, 8 23 | beq- simm_length_checker_success #EoF reached 24 | 25 | #Check against constant (0x) 26 | li r5, 0x3078 27 | cmpw r0, r5 28 | bne+ simm_length_checker_ROOTLOOP 29 | 30 | #Found an instance of "0x" 31 | #Count IMM digits 32 | addi r4, r3, 1 33 | lbzu r0, 0x1 (r4) 34 | cmplwi r0, 0x39 35 | bgt- -0x8 36 | cmplwi r0, 0x30 37 | bge- -0x10 38 | sub r5, r4, r3 39 | cmplwi r5, 10 #8 digit max plus the 2 digits for "0x" 40 | ble- simm_length_checker_ROOTLOOP 41 | 42 | #UH OH, IMM exceeds 8 digits in width, print the instruction thats faulty 43 | #Null out instruction's enter 44 | mr r4, r3 45 | lbzu r0, 0x1 (r4) 46 | cmpwi r0, 0xA 47 | bne+ -0x8 48 | li r0, 0 49 | stb r0, 0 (r4) 50 | #Now go backwards til hit first enter or til we hit SoF-1 51 | lbzu r0, -0x1 (r3) 52 | cmplw r3, r10 53 | blt- 0xC #If SoF, we want cursor at SoF-1 54 | cmpwi r0, 0xA 55 | bne+ -0x10 56 | #Increment cursor by 1, and instruction is ready to print 57 | addi r3, r3, 1 58 | crxor 6, 6, 6 59 | bl printf #DONT use puts 60 | #Bad instruction printed, now return back with new string for parent to print 61 | lis r3, simm_length_ec@h 62 | ori r3, r3, simm_length_ec@l 63 | b end_this_crappp 64 | 65 | simm_length_checker_success: 66 | li r3, 0 67 | 68 | end_this_crappp: 69 | lwz r0, 0x0014 (sp) 70 | mtlr r0 71 | addi sp, sp, 0x0010 72 | blr 73 | -------------------------------------------------------------------------------- /DV-Source/a/source_parser.s: -------------------------------------------------------------------------------- 1 | #This function accepts source.s and removes the following.. 2 | #Double+ Enters, *not* single enters 3 | #Spaces 4 | #Tabs 5 | #Comments 6 | #This is needed because Waltress ASM Engine needs everything stripped 7 | #r3 source.s must end in enter then null byte! 8 | 9 | #r3 = pointer to source.s that ends in Enter then Null 10 | #r4 = byte size *plus* null 11 | 12 | #TODO show condi branch in puts message 13 | 14 | wtf_lmao: #TODO remove this error line/check from the branch label parser since its here 15 | .asciz "\n\nError! At least 1 branch label does not have a landing spot." 16 | .align 2 17 | 18 | #Symbols 19 | .set space, 0x20 20 | .set enter, 0x0A 21 | .set tab, 0x09 22 | .set comment, 0x23 23 | .set slash, 0x2F 24 | .set asterisk, 0x2A 25 | 26 | #Prologue 27 | .globl source_parser 28 | source_parser: 29 | stwu sp, -0x0020 (sp) 30 | mflr r0 31 | stw r26, 0x8 (sp) 32 | stw r27, 0xC (sp) 33 | stw r28, 0x10 (sp) 34 | stw r29, 0x14 (sp) 35 | stw r30, 0x18 (sp) 36 | stw r31, 0x1C (sp) 37 | stw r0, 0x0024 (sp) 38 | 39 | #Save Args 40 | mr r31, r3 41 | mr r30, r4 42 | 43 | #Change all comments and chars within comments to spaces 44 | #We'll make a dedicated comment handler in a future version 45 | #Pre decrement ptr/cursor and place space symbol in r4 46 | addi r3, r3, -1 47 | li r4, space 48 | 49 | change_comments_to_spaces: 50 | lbzu r0, 0x1 (r3) 51 | cmpwi r0, 0 52 | beq- remove_double_enters #If null, stop doing this ofc 53 | cmpwi r0, comment #Check for 1st comment symbol of line 54 | beq- handle_hashtagged_comment 55 | cmpwi r0, slash 56 | bne+ change_comments_to_spaces 57 | #At this point, we may be in a chain-type comment 58 | lbz r0, 0x1 (r3) 59 | cmpwi r0, asterisk 60 | bne- change_comments_to_spaces 61 | 62 | #Now we are on a chain comment 63 | #Write over slash asterisk first 64 | stb r4, 0 (r3) 65 | stbu r4, 0x1 (r3) 66 | lbzu r0, 0x1 (r3) 67 | cmpwi r0, asterisk #if asterisk is hit we may be at end of chain comment 68 | stb r4, 0 (r3) #No matter what, this must be done. Overwrite current char with space 69 | bne+ -0xC 70 | lbz r0, 0x1 (r3) #asterisk was current char, very next char must be the slash 71 | cmpwi r0, slash 72 | bne+ -0x18 73 | stbu r4, 0x1 (r3) #Overwrite slash and update cursor to comply with loop 74 | b change_comments_to_spaces 75 | 76 | #Now we are on a hashtag-type comment 77 | #Write over comment symbol first 78 | handle_hashtagged_comment: 79 | stb r4, 0 (r3) 80 | #Now check for enter, once we hit enter go back to prev loop 81 | lbzu r0, 0x1 (r3) 82 | cmpwi r0, enter 83 | beq- change_comments_to_spaces 84 | #Enter not found yet, overwrite char/symbol with space 85 | stb r4, 0 (r3) 86 | b -0x10 #Go back to checking for enter again 87 | 88 | #All comment and chars within comments are now spaces 89 | #Now remove all double+ enters 90 | remove_double_enters: 91 | addi r3, r31, -1 #Reset cursor 92 | remove_double_enters_loop: 93 | lbzu r0, 0x1 (r3) 94 | cmpwi r0, 0 95 | beq- almost_there 96 | cmpwi r0, enter 97 | bne+ remove_double_enters_loop 98 | mr r4, r3 99 | lbzu r0, 0x1 (r4) 100 | cmpwi r0, space 101 | beq- -0x8 102 | cmpwi r0, tab 103 | beq- -0x10 104 | cmpwi r0, enter #TODO fix to move cursor (update r3 is bne route is taken) forward, not needed technically but should be done 105 | bne+ remove_double_enters_loop 106 | li r5, space 107 | stb r5, 0 (r4) 108 | b -0x24 109 | 110 | #There may be a newline (0xA) char at the very start of file, remove it 111 | almost_there: 112 | lbz r0, 0x0 (r31) 113 | cmpwi r0, enter 114 | bne- start_standard_parser 115 | li r0, space 116 | stb r0, 0x0 (r31) 117 | 118 | ##################### 119 | ##################### 120 | #Set counter to know how much to subtract from r30 which will be used as setup for memmove r4 arg 121 | start_standard_parser: 122 | li r6, 0 123 | 124 | #Setup r31 for loop 125 | addi r31, r31, -1 126 | 127 | #Loop 128 | standard_parser_loop: 129 | lbzu r0, 0x1 (r31) 130 | addi r6, r6, 1 131 | cmpwi r0, 0 132 | beq- source_parser_epilogue 133 | cmpwi r0, space 134 | beq- setup_memmoves 135 | cmpwi r0, tab 136 | bne+ standard_parser_loop 137 | 138 | #Memmove 139 | #r3 = Destination Addr 140 | #r4 = Source Addr 141 | #r5 = Size in bytes 142 | setup_memmoves: 143 | mr r3, r31 144 | addi r4, r31, 1 145 | sub r30, r30, r6 146 | mr r5, r30 147 | bl memmove 148 | li r6, 0 #Reset r6 149 | subi r31, r31, 1 #Update cursor to correct spot now that contents have shifted left 1 byte 150 | b standard_parser_loop 151 | 152 | wtf_lol: 153 | lis r3, wtf_lmao@h 154 | ori r3, r3, wtf_lmao@l 155 | b source_parser_further_epilogue 156 | 157 | #Epilogue 158 | source_parser_epilogue: 159 | li r3, 0 160 | source_parser_further_epilogue: 161 | lwz r31, 0x1C (sp) 162 | lwz r30, 0x18 (sp) 163 | lwz r29, 0x14 (sp) 164 | lwz r28, 0x10 (sp) 165 | lwz r27, 0xC (sp) 166 | lwz r26, 0x8 (sp) 167 | lwz r0, 0x0024 (sp) 168 | mtlr r0 169 | addi sp, sp, 0x0020 170 | blr 171 | -------------------------------------------------------------------------------- /DV-Source/b/DCStoreRange.s: -------------------------------------------------------------------------------- 1 | 2 | .globl DCStoreRange 3 | DCStoreRange: 4 | #Make sure we actually have a size 5 | cmplwi r4, 0 6 | blelr- 7 | 8 | #If address isn't 32-byte aligned, add 32 bytes to r4 9 | clrlwi. r5, r3, 27 10 | beq- 0x8 11 | addi r4, r4, 0x20 12 | 13 | #Now calculate CTR amount 14 | addi r4, r4, 0x1F 15 | srwi r4, r4, 5 16 | mtctr r4 17 | 18 | #DCBST loop 19 | dcbst_loop: 20 | dcbst 0, r3 21 | addi r3, r3, 0x20 22 | bdnz+ dcbst_loop 23 | sync 24 | blr 25 | -------------------------------------------------------------------------------- /DV-Source/b/ICInvalidateRange.s: -------------------------------------------------------------------------------- 1 | 2 | .globl ICInvalidateRange 3 | ICInvalidateRange: 4 | #Make sure we actually have a size 5 | cmplwi r4, 0 6 | blelr- 7 | 8 | #If address isn't 32-byte aligned, add 32 bytes to r4 9 | clrlwi. r5, r3, 27 10 | beq- 0x8 11 | addi r4, r4, 0x20 12 | 13 | #Now calculate CTR amount 14 | addi r4, r4, 0x1F 15 | srwi r4, r4, 5 16 | mtctr r4 17 | 18 | #ICBI loop 19 | icbi_loop: 20 | icbi 0, r3 21 | addi r3, r3, 0x20 22 | bdnz+ icbi_loop 23 | isync 24 | blr 25 | 26 | -------------------------------------------------------------------------------- /DV-Source/b/add_header.s: -------------------------------------------------------------------------------- 1 | 2 | #r3 = pointer to source.s/code.txt 3 | #r4 = source.s/code.txt size EXcluding null 4 | #r5 = pointer to gecko header 5 | #r6 = gecko header type 6 | 7 | #r3 returns new size INCLUDING NULL 8 | 9 | #0 = Raw 10 | #1 = C2 11 | #2 = 04 12 | #3 = 06 13 | #4 = C0 14 | 15 | .globl add_header 16 | add_header: 17 | stwu sp, -0x0020 (sp) 18 | mflr r0 19 | stw r29, 0x14 (sp) 20 | stw r30, 0x18 (sp) 21 | stw r31, 0x1C (sp) 22 | stw r0, 0x0024 (sp) 23 | 24 | #Save r3 r4 r5 arg 25 | mr r31, r3 26 | mr r30, r4 27 | mr r29, r5 28 | 29 | #Now include null byte to size (r4 arg) 30 | #We want to move the appending null byte to always ensure source.s final string ends in null, sanity to stop overflows 31 | #NOTE this is important 32 | addi r4, r4, 1 33 | 34 | cmpwi r6, 4 35 | beq- jimmyrakestrawC0 36 | 37 | #C2/04/06 found, memmove source.s forward by 10 bytes 38 | mr r5, r4 #Size 39 | mr r4, r3 #Source 40 | addi r3, r3, 10 #Dest, move forward 41 | bl memmove 42 | li r7, 9 43 | b transferheader_to_source 44 | 45 | #C0 found, memmove source.s/code.txt forward by 4 bytes 46 | jimmyrakestrawC0: 47 | mr r5, r4 #Size 48 | mr r4, r3 #Source 49 | addi r3, r3, 4 #Dest, move forward 50 | bl memmove 51 | li r7, 3 52 | 53 | transferheader_to_source: 54 | mtctr r7 55 | addi r4, r29, -1 56 | addi r3, r31, -1 57 | lbzu r0, 0x1 (r4) 58 | stbu r0, 0x1 (r3) 59 | bdnz+ -0x8 60 | 61 | #Now store an enter inbetween header and rest of source.s/code.txt 62 | li r0, 0xA 63 | stb r0, 0x1 (r3) 64 | 65 | #Now calc new source.s length and EXCLUDE null to return to parent func 66 | add r3, r7, r30 #Header + source.s/code.txt(w/ null) 67 | addi r3, r3, 1 #Account for 0xA byte in between header and source.s/code.txt 68 | 69 | #Epilogue 70 | lwz r0, 0x0024 (sp) 71 | lwz r31, 0x1C (sp) 72 | lwz r30, 0x18 (sp) 73 | lwz r29, 0x14 (sp) 74 | mtlr r0 75 | addi sp, sp, 0x0020 76 | blr 77 | -------------------------------------------------------------------------------- /DV-Source/b/get_geckoheadertype.s: -------------------------------------------------------------------------------- 1 | #Func returns Gecko Header type 2 | #r3 arg = pointer to code.txt/source.s 3 | #r3 returns.. 4 | #-1 = some header found, but invalid 5 | #0 = raw (no header) 6 | #1 = C2 7 | #2 = 04 8 | #3 = 06 9 | #4 = C0 10 | 11 | .globl get_geckoheadertype 12 | get_geckoheadertype: 13 | #Get thru any possible spaces, tabs, and enters beforehand 14 | subi r4, r3, 1 15 | lbzu r0, 0x1 (r4) 16 | cmpwi r0, 0x20 17 | beq -0x8 18 | cmpwi r0, 0x0A 19 | beq- -0x10 20 | cmpwi r0, 0x09 21 | beq- -0x18 22 | 23 | #Went thru all possible junk beforehand, now Check for Valid Header 24 | cmpwi r0, 0x21 #Check for exclamation point 25 | li r3, 0 #Raw ASM, no header 26 | bnelr- 27 | 28 | #Some header was found, is it valid? 29 | lhz r0, 0x1 (r4) 30 | li r5, 0x4332 31 | cmpw r0, r5 32 | li r3, 1 33 | beq- c20406headerfound 34 | li r6, 0x3034 35 | cmpw r0, r6 36 | li r3, 2 37 | beq- c20406headerfound 38 | li r7, 0x3036 39 | cmpw r0, r7 40 | li r3, 3 41 | beq- c20406headerfound 42 | li r8, 0x4330 43 | cmpw r0, r8 44 | li r3, -1 #Set error 45 | bnelr- #Branch to LR in invalid header with r3 -1 46 | 47 | #C0 found 48 | li r3, 4 49 | blr 50 | 51 | #Header cannot have non ascii numbers & letters within address ascii field 52 | c20406headerfound: 53 | li r6, 6 54 | mr r7, r3 #temp backup r3 55 | addi r5, r4, 2 56 | li r3, -1 #preset error 57 | mtctr r6 58 | 59 | silly_loop: 60 | lbzu r0, 0x1 (r5) 61 | cmplwi r0, 0x30 62 | bltlr- 63 | cmplwi r0, 0x66 64 | bgtlr- 65 | cmplwi r0, 0x3A 66 | blt- valid_ascii 67 | cmplwi r0, 0x60 68 | bgt- valid_ascii 69 | cmplwi r0, 0x41 70 | bltlr- 71 | cmplwi r0, 0x46 72 | bgtlr- 73 | valid_ascii: 74 | bdnz+ silly_loop 75 | 76 | #End func, recover r3 77 | mr r3, r7 78 | blr 79 | -------------------------------------------------------------------------------- /DV-Source/b/newline_fixer.s: -------------------------------------------------------------------------------- 1 | #Quick hacky patch to change all Carriages to Newlines, and Carriage+Newline combos (eww Windows) to Newlines 2 | #r3 = pointer to code.txt/source.s (must end in null byte) 3 | 4 | .globl newline_fixer 5 | newline_fixer: 6 | subi r3, r3, 1 7 | li r4, 0xA 8 | lbzu r0, 0x1 (r3) 9 | cmpwi r0, 0 10 | beqlr- 11 | cmpwi r0, 0xD 12 | bne+ -0x10 13 | stb r4, 0 (r3) 14 | b -0x18 15 | 16 | 17 | -------------------------------------------------------------------------------- /DV-Source/b/saveANDoverwrite_geckoheader.s: -------------------------------------------------------------------------------- 1 | #Func does... 2 | #Save header to new malloc space 3 | #Strips out Header from code.txt/source.s and memmoves accordingly 4 | #Returns back malloc pointer 5 | 6 | #r3 arg = gecko header type 7 | #r4 arg = pointer to code.txt/source.s 8 | #r3 returns pointer 9 | #r3 returns 0 if malloc failed, allow parent func to handle error! 10 | 11 | .globl saveANDoverwrite_geckoheader 12 | saveANDoverwrite_geckoheader: 13 | 14 | #For the case this somehow gets called with no header.... 15 | cmpwi r3, 0 16 | beqlr- 17 | 18 | #Prologue 19 | stwu sp, -0x0020 (sp) 20 | mflr r0 21 | stw r28, 0x10 (sp) 22 | stw r29, 0x14 (sp) 23 | stw r30, 0x18 (sp) 24 | stw r31, 0x1C (sp) 25 | stw r0, 0x0024 (sp) 26 | 27 | #Update r4 (& backup to r30) cursor just in case there are spaces, tabs, and centers before gecko header 28 | subi r30, r4, 1 29 | lbzu r0, 0x1 (r30) 30 | cmpwi r0, 0x20 31 | beq -0x8 32 | cmpwi r0, 0x0A 33 | beq- -0x10 34 | cmpwi r0, 0x09 35 | beq- -0x18 36 | 37 | #Check for C0 type 38 | cmpwi r3, 4 39 | li r3, 3 40 | beq- 0x8 #C0's header type number matches malloc arg, lucky for us 41 | 42 | #C2/04/06 header found 43 | li r3, 9 44 | 45 | #Save malloc's r3 arg (length of Gecko header, 3 for C0, 9 for 04/06/C2) 46 | mr r31, r3 47 | 48 | #Malloc, malloc enough for header plus extra byte afterwards 49 | bl malloc 50 | mr. r28, r3 #Save malloc's return value 51 | beq- epipen #Skip saving and memmove if malloc failed 52 | 53 | #Save header to malloc'd space 54 | addi r4, r30, -1 55 | addi r5, r3, -1 56 | mtctr r31 57 | lbzu r0, 0x1 (r4) 58 | stbu r0, 0x1 (r5) 59 | bdnz+ -0x8 60 | 61 | #Now replace header with spaces, ye we could "cut" it out via memmove, but it's bother faster and shorter just to space fill it 62 | mtctr r31 63 | addi r3, r30, -1 64 | li r0, 0x20 65 | stbu r0, 0x1 (r3) 66 | bdnz+ -0x4 67 | 68 | #Recover malloc return value 69 | epipen: 70 | mr r3, r28 71 | 72 | #Return malloc return value back to parent 73 | lwz r0, 0x0024 (sp) 74 | lwz r31, 0x1C (sp) 75 | lwz r30, 0x18 (sp) 76 | lwz r29, 0x14 (sp) 77 | lwz r28, 0x10 (sp) 78 | mtlr r0 79 | addi sp, sp, 0x0020 80 | blr 81 | -------------------------------------------------------------------------------- /DV-Source/d/codetxt2bin.s: -------------------------------------------------------------------------------- 1 | #Func changes fully parsed code.txt to a bare bones code.bin via a series of sscanf calls 2 | #r3 = pointer to code.txt 3 | #r4 = size of code.txt excluding null byte (we need this to make this func short) 4 | #r3 return 0 for success, negative for failure 5 | string1_codetxt2bin: 6 | .asciz "%08X" 7 | string2_codetxt2bin: 8 | .asciz "%08x" 9 | .align 2 10 | 11 | .globl codetxt2bin 12 | codetxt2bin: 13 | #Make sure r4 is divisible by 8, just in case..... 14 | mr r5, r3 15 | andi. r0, r4, 0x7 #3 LSB's need to get null 16 | li r3, -999 17 | bnelr- 18 | mr r3, r5 19 | 20 | #Prologue 21 | stwu sp, -0x0030 (sp) 22 | mflr r0 23 | stw r29, 0x24 (sp) #0x8 thru 0x23 is buffer space for sprintf 24 | stw r30, 0x28 (sp) 25 | stw r31, 0x2C (sp) 26 | stw r0, 0x0034 (sp) 27 | 28 | #Set main loop count in r29 (size divided by 8) 29 | #Set buffer sp dump spot 30 | srwi r29, r4, 3 31 | addi r30, r3, -4 32 | addi r31, r3, -8 33 | 34 | #sscanf 35 | #r3 = pointer to formatted (ascii) shit 36 | #r4 = pointer to %08X/x 37 | #r5 = where to dump real hex word value (converted *from* ascii) 38 | 39 | codetxt2bin_loop: 40 | addi r31, r31, 8 #Every ASCII instruction is 8 bytes (double-word) long 41 | lis r4, string1_codetxt2bin@h 42 | addi r5, sp, 8 43 | ori r4, r4, string1_codetxt2bin@l 44 | mr r3, r31 45 | bl sscanf 46 | cmpwi r3, 1 47 | beq- storebuffer_and_decrement 48 | #Try again but with lowercase hex char string 49 | lis r4, string2_codetxt2bin@h 50 | addi r5, sp, 8 51 | ori r4, r4, string2_codetxt2bin@l 52 | mr r3, r31 53 | bl sscanf 54 | cmpwi r3, 1 55 | li r3, -999 56 | bne- codetxt2bin_error 57 | storebuffer_and_decrement: 58 | subic. r29, r29, 1 59 | lwz r0, 0x8 (sp) 60 | stwu r0, 0x4 (r30) 61 | bne+ codetxt2bin_loop 62 | 63 | #Success 64 | li r3, 0 65 | 66 | codetxt2bin_error: 67 | lwz r0, 0x0034 (sp) 68 | lwz r31, 0x2C (sp) 69 | lwz r30, 0x28 (sp) 70 | lwz r29, 0x24 (sp) 71 | mtlr r0 72 | addi sp, sp, 0x0030 73 | blr 74 | -------------------------------------------------------------------------------- /DV-Source/d/codetxtparser.s: -------------------------------------------------------------------------------- 1 | #This function accepts code.txt and removes the following.. 2 | #Spaces 3 | #Tabs 4 | #Enters 5 | #Comments 6 | #This is needed because Waltress DASM Engine needs everything stripped 7 | #r3 code.txt must end in null byte! 8 | 9 | #r3 = pointer to code.txt that ends in null 10 | #r4 = byte size *plus* null 11 | 12 | .set cspace, 0x20 13 | .set center, 0x0A 14 | .set ctab, 0x09 15 | .set ccomment, 0x23 16 | .set cslash, 0x2F 17 | .set casterisk, 0x2A 18 | 19 | #Prologue 20 | .globl codetxtparser 21 | codetxtparser: 22 | stwu sp, -0x0010 (sp) 23 | mflr r0 24 | stw r30, 0x8 (sp) 25 | stw r31, 0xC (sp) 26 | stw r0, 0x0014 (sp) 27 | 28 | #Save Args 29 | mr r31, r3 30 | mr r30, r4 31 | 32 | #Change all comments and chars within comments to spaces 33 | #We'll make a dedicated comment handler in a future version 34 | #Pre decrement ptr and place space symbol in r4 35 | addi r3, r3, -1 36 | li r4, cspace 37 | 38 | codetxtchange_comments_to_spaces: 39 | lbzu r0, 0x1 (r3) 40 | cmpwi r0, 0 41 | beq- d_start_parser #If null, stop doing this ofc 42 | cmpwi r0, ccomment #Check for 1st comment symbol of line 43 | beq- codetxthandle_hashtagged_comment 44 | cmpwi r0, cslash 45 | bne+ codetxtchange_comments_to_spaces 46 | #At this point, we may be in a chain-type comment 47 | lbz r0, 0x1 (r3) 48 | cmpwi r0, casterisk 49 | bne- codetxtchange_comments_to_spaces 50 | 51 | #Now we are on a chain comment 52 | #Write over slash asterisk first 53 | stb r4, 0 (r3) 54 | stbu r4, 0x1 (r3) 55 | lbzu r0, 0x1 (r3) 56 | cmpwi r0, casterisk #if asterisk is hit we may be at end of chain comment 57 | stb r4, 0 (r3) #No matter what, this must be done. Overwrite current char with space 58 | bne+ -0xC 59 | lbz r0, 0x1 (r3) #asterisk was current char, very next char must be the slash 60 | cmpwi r0, cslash 61 | bne+ -0x18 62 | stbu r4, 0x1 (r3) #Overwrite slash and update cursor to comply with loop 63 | b codetxtchange_comments_to_spaces 64 | 65 | #Now we are on a hashtag-type comment 66 | #Write over comment symbol first 67 | codetxthandle_hashtagged_comment: 68 | stb r4, 0 (r3) 69 | #Now check for enter, once we hit enter go back to prev loop 70 | lbzu r0, 0x1 (r3) 71 | cmpwi r0, center 72 | beq- codetxtchange_comments_to_spaces 73 | #Enter not found yet, overwrite char/symbol with space 74 | stb r4, 0 (r3) 75 | b -0x10 #Go back to checking for enter again 76 | 77 | #Set counter to know how much to subtract from r29 which will be used as setup for memmove r4 arg 78 | d_start_parser: 79 | li r6, 0 80 | 81 | #Setup r31 for loop 82 | addi r31, r31, -1 83 | 84 | #Loop2 85 | codetxtparser_loop: 86 | lbzu r0, 0x1 (r31) 87 | addi r6, r6, 1 88 | cmpwi r0, 0 89 | beq- codetxtparser_epilogue 90 | cmpwi r0, cspace 91 | beq- codetxtparser_setup_memmove 92 | cmpwi r0, center 93 | beq- codetxtparser_setup_memmove 94 | cmpwi r0, ctab 95 | bne+ codetxtparser_loop 96 | 97 | #Memmove 98 | #r3 = Destination Addr 99 | #r4 = Source Addr 100 | #r5 = Size in bytes 101 | codetxtparser_setup_memmove: 102 | mr r3, r31 103 | addi r4, r31, 1 104 | sub r30, r30, r6 105 | mr r5, r30 106 | bl memmove 107 | li r6, 0 #Reset r6 108 | subi r31, r31, 1 #Update cursor to correct spot now that contents have shifted left 1 byte 109 | b codetxtparser_loop 110 | 111 | #Epilogue 112 | codetxtparser_epilogue: 113 | lwz r30, 0x8 (sp) 114 | lwz r31, 0xC (sp) 115 | lwz r0, 0x0014 (sp) 116 | mtlr r0 117 | addi sp, sp, 0x0010 118 | blr 119 | -------------------------------------------------------------------------------- /DV-Source/d/codetxtpostparsersize.s: -------------------------------------------------------------------------------- 1 | #Simple func to calculate file size, EXcluding null byte 2 | #r3 = pointer to code.txt 3 | #r3 returns byte size 4 | 5 | .globl codetxtpostparsersize 6 | codetxtpostparsersize: 7 | addi r4, r3, -1 8 | lbzu r0, 0x1 (r4) 9 | cmpwi r0, 0 10 | bne+ -0x8 11 | sub r3, r4, r3 12 | blr 13 | -------------------------------------------------------------------------------- /DV-Source/d/disassemble.s: -------------------------------------------------------------------------------- 1 | #Disassemble Func (void) 2 | #r3 returns 0 for success, any negative number is error 3 | 4 | #Open source.s to make sure one doesn't exist 5 | #Open dbin.bin, get size, alloc mem, dump, close 6 | #Open code.txt, get size, alloc mem, dump, close 7 | #Multiply code.txt's size by 13 for estimated size of to-be-generated source.s 8 | #Mem alloc for estimated size 9 | #Update cache for dbin.bin since we will execute it 10 | #Run waltress dbin.bin 11 | #Create source.s, write to it, close, success 12 | 13 | #r31 = fp, then source.s pointer 14 | #VOID NOW r30 = dbin.bin size 15 | #VOID NOW r29 = dbin.bin pointer 16 | #r28 = code.txt size 17 | #r27 = code.txt pointer 18 | #r26 = Header flag, 0 = raw, 1 = 04,06,C2, 2 = C0 19 | #r23 thru r25 = Gecko Header (ASCII) 20 | #r22 = r31 (net; factoring in gecko header) 21 | 22 | #Directives 23 | sources: 24 | .asciz "source.s" 25 | codetxt: 26 | .asciz "code.txt" 27 | rb: 28 | .asciz "rb" 29 | wb: 30 | .asciz "wb" 31 | dfopensourceEC: 32 | .asciz "\n\nError! Source.s already exists. Delete it and try again.\n\n" 33 | dfopencodetxtEC: 34 | .asciz "\n\nError! Can't find code.txt. This file needs to be present for disassembling. Is the file named incorrectly?\n\n" 35 | dfseekcodetxtEC: 36 | .asciz "\n\nError! fseek failure on code.txt.\n\n" 37 | dmemaligncodetxtEC: 38 | .asciz "\n\nError! Can't allocate memory for code.txt.\n\n" 39 | dfreadcodetxtEC: 40 | .asciz "\n\nError! Unable to dump code.txt to memory.\n\n" 41 | dfclosecodetxtEC: 42 | .asciz "\n\nError! Can't close code.txt.\n\n" 43 | dgeckoheaderEC: 44 | .asciz "\n\nError! The Gecko Header is not the correct format or an unsupported Header type is being used.\n\n" 45 | dsavestripmallocEC: 46 | .asciz "\n\nError! Can't allocate memory within the Save and Strip Gecko Header subroutine.\n\n" 47 | dcodetxt2binEC: 48 | .asciz "\n\nError! Either a sscanf failure occurred within the codetxt2bin subroutine, or somehow code.txt (after the codetxtpostparsersize subroutine) has a size that isn't divisible by 4. Please report this Error at MarioKartWii.com!\n\n" 49 | dmemalignTOBEsourceEC: 50 | .asciz "\n\nError! Can't allocate memory for future source.s.\n\n" 51 | dprepwaltressdbinEC: 52 | .asciz "\n\nError! One the following scenarios has occurred. The 06 line amount designator byte is an incorrect value, the C0 line amount designator byte is an incorrect value, or the C2 line amount designator byte is an incorrect value.\n\n" 53 | dwaltressSprintfFailureEC: 54 | .asciz "\n\nError! A sprintf failure occurred when Waltress tried disassembling one of the instruction(s). This should never occur. Please report this Error at MarioKartWii.com!\n\n" 55 | dfcreatesourceEC: 56 | .asciz "\n\nError! Can't create new source.s. If you are using the Desktop Version, make sure the DV folder has user permissions enabled.\n\n" 57 | dfwritesourceEC: 58 | .asciz "\n\nError! Can't write content to newly created source.s.\n\n" 59 | dfclosesourceEC: 60 | .asciz "\n\nError! Can't close new source.s.\n\n" 61 | 62 | .align 2 63 | 64 | #Prologue 65 | .globl disassemble 66 | disassemble: 67 | stwu sp, -0x0040 (sp) 68 | mflr r0 69 | stmw r20, 0x10 (sp) 70 | stw r0, 0x0044 (sp) 71 | 72 | #Open source.s, one shouldn't exist 73 | lis r3, sources@h 74 | lis r4, rb@h 75 | ori r3, r3, sources@l 76 | ori r4, r4, rb@l 77 | bl fopen 78 | cmpwi r3, 0 79 | lis r3, dfopensourceEC@h 80 | ori r3, r3, dfopensourceEC@l 81 | bne- disassemble_error #YES this is bne! We don't want file to exist 82 | 83 | #Open code.txt 84 | lis r3, codetxt@h 85 | lis r4, rb@h 86 | ori r3, r3, codetxt@l 87 | ori r4, r4, rb@l 88 | bl fopen 89 | mr. r31, r3 90 | lis r3, dfopencodetxtEC@h 91 | ori r3, r3, dfopencodetxtEC@l 92 | beq- disassemble_error 93 | 94 | #Get size of code.txt 95 | mr r3, r31 96 | li r4, 0 97 | li r5, 2 #Seek end 98 | bl fseek 99 | cmpwi r3, 0 100 | lis r3, dfseekcodetxtEC@h 101 | ori r3, r3, dfseekcodetxtEC@l 102 | bne- disassemble_error 103 | mr r3, r31 104 | bl ftell #No error check for this 105 | 106 | #Rewind file stream position 107 | #Alloc mem for code.txt 108 | #*NOTE* We have code.txt filesize but future custom subfuncs require the file ends in a null byte, therefore add 1 to the file size before calling memalign. 109 | addi r28, r3, 1 110 | mr r3, r31 111 | bl rewind #No error check for this 112 | li r3, 32 113 | mr r4, r28 114 | bl memalign 115 | mr. r27, r3 116 | lis r3, dmemaligncodetxtEC@h 117 | ori r3, r3, dmemaligncodetxtEC@l 118 | beq- disassemble_error 119 | 120 | #Dump code.txt, close 121 | mr r3, r27 122 | li r4, 1 123 | subi r5, r28, 1 #This is because we added 1 fake byte from earlier!!! 124 | mr r6, r31 125 | bl fread 126 | subi r0, r28, 1 127 | cmpw r3, r0 128 | lis r3, dfreadcodetxtEC@h 129 | ori r3, r3, dfreadcodetxtEC@l 130 | bne- disassemble_error 131 | mr r3, r31 132 | bl fclose 133 | cmpwi r3, 0 134 | lis r3, dfclosecodetxtEC@h 135 | ori r3, r3, dfclosecodetxtEC@l 136 | bne- disassemble_error 137 | 138 | #Append null byte to end of file, this is needed for future funcs 139 | subi r3, r28, 1 140 | li r4, 0 141 | stbx r4, r3, r27 142 | 143 | #Patch carriages 144 | mr r3, r27 145 | bl newline_fixer 146 | 147 | #Get the Gecko Header type from code.txt 148 | #-1 = Invalid 149 | #0 = Raw 150 | #1 = C2 151 | #2 = 04 152 | #3 = 06 153 | #4 = C0 154 | mr r3, r27 155 | bl get_geckoheadertype 156 | mr. r22, r3 157 | lis r3, dgeckoheaderEC@h 158 | ori r3, r3, dgeckoheaderEC@l 159 | blt- disassemble_error 160 | beq- skip_codetxt_geckostripper 161 | 162 | #Call func that saves gecko header then overwrites it with spaces 163 | #r3 returns malloced space where header is saved at 164 | #r3 arg = gecko header type 165 | #r4 arg = code.txt ptr, code.txt must end in null byte 166 | mr r3, r22 167 | mr r4, r27 168 | bl saveANDoverwrite_geckoheader 169 | mr. r20, r3 170 | lis r3, dsavestripmallocEC@h 171 | ori r3, r3, dsavestripmallocEC@l 172 | beq- disassemble_error 173 | 174 | #Call the code.txt parser to remove all spaces, enters, tabs, and comments 175 | #r3 = pointer to code.txt, must end in null 176 | #r4 = size of code.txt plus null byte 177 | skip_codetxt_geckostripper: 178 | mr r3, r27 179 | mr r4, r28 #TODO fix me, r28 is incorrect (needs to be decremented) but it actually doesn't matter, func will still work correctly 180 | bl codetxtparser #No error check for this 181 | 182 | #Gen post parser code.txt size (EXclude null byte on count) 183 | mr r3, r27 184 | bl codetxtpostparsersize 185 | mr r25, r3 #Save in r25, no error check for this func 186 | 187 | #Transform code.txt to a temporary code.bin, yuck 188 | #r3 = code.txt pointer 189 | #r4 = code.txt post-parsed size excluding null byte (must exclude because r4 needs to be divisible by 8) 190 | mr r3, r27 191 | mr r4, r25 192 | bl codetxt2bin 193 | cmpwi r3, 0 194 | lis r3, dcodetxt2binEC@h 195 | ori r3, r3, dcodetxt2binEC@l 196 | bne- disassemble_error #Carry return error from codetxt2bin to parent func 197 | 198 | #Using code.txt post parser size, use that to generate safe upper bound range 199 | #for memalign size for to-be-genned source.s 200 | #Longest possible line is 36 bytes 201 | #36 / 8 = 4.5 202 | #Take code.txt post parser size times 5. Then finally add 10 bytes for possible Header 203 | mulli r5, r25, 5 #Yuck 204 | addi r4, r5, 10 205 | li r3, 32 206 | bl memalign 207 | mr. r31, r3 208 | lis r3, dmemalignTOBEsourceEC@h 209 | ori r3, r3, dmemalignTOBEsourceEC@l 210 | beq- disassemble_error 211 | 212 | #Prep for Engine. 213 | #r3 = code.bin pointer 214 | #r4 = code.TXT size (***NOT** .bin size, it hasn't yet been calc'd) 215 | #r5 = gecko type 216 | #Func returns... 217 | #r3 = new code.bin pointer 218 | #r4 = loop/instruction amount for 219 | mr r3, r27 220 | mr r4, r25 221 | mr r5, r22 222 | bl prep_waltress_dbin 223 | cmpwi r3, 0 #r3 == 0 is only possible if 06 byte amount is *not* divisible by 4 224 | addi r24, r3, -4 #Decrement for waltress din bin loop 225 | lis r3, dprepwaltressdbinEC@h 226 | ori r3, r3, dprepwaltressdbinEC@l 227 | beq- disassemble_error 228 | mr r25, r4 #Loop counter GVR 229 | mr r21, r4 #Need instruction amount for later, save again in diff GVR 230 | mr r23, r31 #Make copy of source.s pointer 231 | 232 | #RUN WALTRESS DASM ENGINE 233 | #r3 = source.s ptr (output addr) 234 | #r4 = instruction (input value) 235 | 236 | run_waltress_dbin_bin: 237 | lwzu r4, 0x4 (r24) 238 | mr r3, r23 239 | bl dasm_engine # :) 240 | cmpwi r3, 0 241 | beq+ its_the_waltress 242 | 243 | lis r3, dwaltressSprintfFailureEC@h 244 | ori r3, r3, dwaltressSprintfFailureEC@l 245 | b disassemble_error 246 | 247 | its_the_waltress: 248 | subic. r25, r25, 1 249 | #Find null on newly printed source line at source.s, so we know how much to increment r23 for next go around 250 | lbzu r0, 0x1 (r23) 251 | cmpwi cr7, r0, 0 252 | bne+ cr7, -0x8 253 | #r23 needs to be incremented by 1 254 | addi r23, r23, 1 255 | bne+ run_waltress_dbin_bin 256 | 257 | #Fyi waltress stores null byte to every output string 258 | #Now we just need to replace all null bytes (except last one) with spaces and enters 259 | #Spaces are for odd instructions, enters for even, null byte at very end 260 | mr r3, r31 261 | mr r4, r21 262 | bl fixwaltress_nulls #No error check 263 | 264 | #Get length of new source.s (EXclude null byte ender) 265 | addi r3, r31, -1 266 | li r28, 0 #We don't have any more need for r28, free to use now 267 | lbzu r0, 0x1 (r3) 268 | cmpwi r0, 0 269 | beq- 0xC 270 | addi r28, r28, 1 271 | b -0x10 272 | 273 | #Now add back in gecko header carried over from code.txt 274 | cmpwi r22, 0 #If Raw, skip ofc 275 | beq- create_sources 276 | 277 | #r3 = pointer to source.s 278 | #r4 = source.s size EXcluding null 279 | #r5 = pointer to gecko header 280 | #r6 = gecko header type 281 | #r3 returns updated size that EXcludes null 282 | mr r3, r31 283 | mr r4, r28 284 | mr r5, r20 285 | mr r6, r22 286 | bl add_header 287 | mr r28, r3 288 | 289 | #Create finished source.s 290 | #r28 contains size EXcluding null byte 291 | create_sources: 292 | lis r3, sources@h 293 | lis r4, wb@h 294 | ori r3, r3, sources@l 295 | ori r4, r4, wb@l 296 | bl fopen 297 | mr. r29, r3 298 | lis r3, dfcreatesourceEC@h 299 | ori r3, r3, dfcreatesourceEC@l 300 | beq- disassemble_error 301 | li r4, 1 302 | mr r3, r31 303 | mr r5, r28 #Count (real size) 304 | mr r6, r29 305 | bl fwrite 306 | cmpw r3, r28 307 | lis r3, dfwritesourceEC@h 308 | ori r3, r3, dfwritesourceEC@l 309 | bne- disassemble_error 310 | mr r3, r29 311 | bl fclose 312 | cmpwi r3, 0 313 | lis r3, dfclosesourceEC@h 314 | ori r3, r3, dfclosesourceEC@l 315 | bne- disassemble_error 316 | 317 | #TODO add in code to free up allocated blocks of mem 318 | 319 | #Success! 320 | li r3, 0 321 | 322 | disassemble_error: 323 | lwz r0, 0x0044 (sp) 324 | lmw r20, 0x10 (sp) 325 | mtlr r0 326 | addi sp, sp, 0x0040 327 | blr 328 | -------------------------------------------------------------------------------- /DV-Source/d/fixwaltress_nulls.s: -------------------------------------------------------------------------------- 1 | #Func is meant to fix source.s after dbin.bin 2 | #Replace all gen'd null bytes with 0x20 and 0xA. end in final null 3 | #r3 = Pointer to newly gen source.s 4 | #r4 = number of instructions 5 | 6 | #TODO maybe write in code to check if r4 = 1 then simply blr back! 7 | 8 | .globl fixwaltress_nulls 9 | fixwaltress_nulls: 10 | li r5, 0xA 11 | li r6, 0 12 | mtctr r4 13 | 14 | #Find the next null byte, once found decrement CTR, if CTR zero, skip 'fix', we are eof 15 | fixwaltress_nulls_loop: 16 | lbzu r0, 0x1 (r3) #No need to pre-decrement, no source.s line is a byte long 17 | cmpwi r0, 0 18 | bne+ fixwaltress_nulls_loop 19 | 20 | #Found Waltress-created null byte, apply "enter" 21 | stb r5, 0 (r3) 22 | 23 | #Decrement 24 | bdnz+ fixwaltress_nulls_loop 25 | li r0, 0 #Store final final null byte, overwrites most recent newly written 0xA ofc. *NOTE* this is important as it ensures final string is terminated, sanity for overflow 26 | stb r0, 0 (r3) 27 | blr 28 | -------------------------------------------------------------------------------- /DV-Source/d/prep_waltress_dbin.s: -------------------------------------------------------------------------------- 1 | #Func will properly prep the engine to where all the parent func has to do is typical pre-decrement of 2 | #r3 = code.bin pointer 3 | #r4 = code.TXT size (***NOT** .bin size, it hasn't yet been calc'd) 4 | #r5 = gecko type 5 | 6 | #Func returns 7 | #r3 = new code.bin pointer 8 | #r4 = loop/instruction amount for waltress dasm engine 9 | 10 | #(code.txt post excluding null byte parsed size / 2) = code.bin size 11 | #code.bin size / 4 = Amount of Instruction 12 | #Raw = do nothing afterwards 13 | #!04 = lower by 1 afterwards, skip decrement of r27 14 | #!06 = read 06-specific byte count, divide by 4, increment r27 by 4 15 | #!C2 = increment r27 by 4, read C2 line count, mulli by 2. Subtract 1 for 00000000. Then read line count again, if odd and 2nd to last word is nop, subtract 1 again for GVR 16 | #!C0 = increment r27 by 4, read C0 line count, mulli by 2. Subtract 1 afterwards. Then read line count again. If odd and final final instruction is 00000000, then skip blr (2nd to last instruction), and subtract 1 again to compensate 17 | 18 | #0 = Raw 19 | #1 = C2 20 | #2 = 04 21 | #3 = 06 22 | #4 = C0 23 | 24 | .globl prep_waltress_dbin 25 | prep_waltress_dbin: 26 | cmpwi r5, 0 27 | srawi r4, r4, 3 #Divide code.TXT! size by 8 to get raw instruction amount 28 | beqlr- 29 | 30 | #Check for C2 31 | cmpwi r5, 1 32 | bne- try04 33 | 34 | #C2 codetype found 35 | #Make sure C2 line amount matches {(rawinstructionamount - 2) / 2} 36 | lwz r6, 0x4 (r3) 37 | subi r7, r4, 2 38 | srawi r7, r7, 1 39 | cmpw r7, r6 40 | mr r5, r3 #temp save r3 41 | li r3, 0 42 | bnelr- 43 | #Good to go 44 | subi r4, r4, 3 #Take away C2 header C2 line amount, and final null word 45 | addi r3, r5, 8 #Go past header past C2 line amount 46 | #Check if C2's byte amount matches r4 genned amount 47 | 48 | #If 2nd to last word is nop, subtract r4 by one more 49 | lis r0, 0x6000 #Nop 50 | slwi r6, r4, 2 #r6 = instruction amount x 4 = (byte amount of source + possible nop) 51 | subi r6, r6, 4 52 | lwzx r6, r6, r3 53 | cmpw r0, r6 54 | bnelr- 55 | subi r4, r4, 1 56 | blr 57 | 58 | #Check for 04 59 | try04: 60 | cmpwi r5, 2 61 | bne- tryC0 62 | 63 | #04 codetype found 64 | addi r3, r3, 4 65 | li r4, 1 66 | blr 67 | 68 | #Check for C0 69 | tryC0: 70 | cmpwi r5, 4 71 | bne- found06 72 | 73 | #C0 codetype found 74 | #Make sure C0 line amount matches {(rawinstructionamount - 2) / 2} 75 | lwz r6, 0x4 (r3) 76 | subi r7, r4, 2 77 | srawi r7, r7, 1 78 | cmpw r7, r6 79 | mr r5, r3 #temp save r3 80 | li r3, 0 81 | bnelr- 82 | #Good to go 83 | subi r4, r4, 2 #Take away C0 header C0 line amount 84 | addi r3, r5, 8 #Go past header past C2 line amount 85 | 86 | #If last word is null or blr, subtract one more 87 | lis r0, 0x4E80 #blr 88 | ori r0, r0, 0x0020 89 | slwi r6, r4, 2 #r6 = instruction amount x 4 = (byte amount of source + possible 2ndtolastword) 90 | subi r6, r6, 4 91 | lwzx r7, r6, r3 92 | cmpwi r7, 0 93 | beq- 0xC 94 | cmpw r7, r0 95 | bnelr- #For whatever reason the C0 code in question has an odd setup (custom blr in middle?), *DON*T subtract anymore from r4, end func 96 | #Check if 2nd to last and last word are blr's 97 | #If 2nd to last word is blr, subtract one more again... 98 | subi r4, r4, 1 99 | subi r6, r6, 4 100 | lwzx r7, r6, r3 101 | cmpw r7, r0 102 | bnelr- 103 | subi r4, r4, 1 104 | blr 105 | 106 | #06 codetype found 107 | found06: 108 | lwz r6, 0x4 (r3) 109 | andi. r0, r6, 3 #06 byte amount must be divisible by 4 110 | addi r5, r3, 8 #Go past 06 header 06 byte amount 111 | li r3, 0 112 | bnelr- 113 | subi r4, r4, 2 #Take away 06 header and 06 byte amount line 114 | #If 06 byte amount ends in 0x4 or 0xC, then subtract r4 by 1 and compare vs r6 cuz last word of 06 code is null. If not, skip the subtraction part 115 | andi. r0, r6, 7 116 | beq- 0x8 117 | subi r4, r4, 1 118 | #Byte Amount / 4 should match instruction amount 119 | srawi r6, r6, 2 120 | cmpw r6, r4 121 | bnelr- #r3 still 0 122 | mr r3, r5 #Recover r3 before returning to signal everything is good to go 123 | blr 124 | -------------------------------------------------------------------------------- /DV-Source/main.S: -------------------------------------------------------------------------------- 1 | #include "a/assemble.s" 2 | #include "a/source_parser.s" 3 | #include "a/simm_length_checker.s" 4 | #include "a/fix_neg_hex.s" 5 | #include "a/branchlabelparser.s" 6 | #include "a/gencodebinsize.s" 7 | #include "a/asm_engine.s" 8 | #include "a/bin2txt.s" 9 | #include "a/finalize_assembled_bin.s" 10 | 11 | #include "d/disassemble.s" 12 | #include "d/codetxtparser.s" 13 | #include "d/codetxtpostparsersize.s" 14 | #include "d/codetxt2bin.s" 15 | #include "d/prep_waltress_dbin.s" 16 | #include "d/dasm_engine.s" 17 | #include "d/fixwaltress_nulls.s" 18 | 19 | #include "b/DCStoreRange.s" 20 | #include "b/ICInvalidateRange.s" 21 | #include "b/newline_fixer.s" 22 | #include "b/get_geckoheadertype.s" 23 | #include "b/saveANDoverwrite_geckoheader.s" 24 | #include "b/add_header.s" 25 | 26 | prompt_message: 27 | .asciz "Welcome to Waltress! Version 0.9\n\nCreated by Vega\n\nEnter a for Assembling, enter d for Disassembling. " 28 | 29 | success_message: 30 | .asciz "Success!\n\n" 31 | 32 | fgetsEC: 33 | .asciz "Somehow a fgets error occurred when reading stdin. This should never happen. Please report this Error at MarioKartWii.com!\n\n" 34 | 35 | noad: 36 | .asciz "You've entered an invalid option. Relaunch the program.\n\n" 37 | 38 | .align 2 39 | 40 | .section .text 41 | .globl main 42 | 43 | main: 44 | #Prologue, welcome message 45 | stwu sp, -0x0020 (sp) #0x8 space for char 46 | lis r3, prompt_message@h 47 | mflr r0 48 | ori r3, r3, prompt_message@l 49 | stw r0, 0x0024 (sp) 50 | bl puts 51 | 52 | #Call fgets and check return of fgets 53 | lis r5, stdin@ha 54 | li r4, 100 #FIX ME LATER, we don't need this high of a number 55 | lwz r5, stdin@l (r5) 56 | addi r3, sp, 8 57 | bl fgets 58 | cmpwi r3, 0 59 | lis r3, fgetsEC@h 60 | ori r3, r3, fgetsEC@l 61 | beq- error 62 | 63 | #No error on fgets 64 | lbz r0, 0x8 (sp) 65 | cmpwi r0, 0x61 66 | bne- check_d 67 | bl assemble 68 | b check_for_error 69 | 70 | check_d: 71 | cmpwi r0, 0x64 72 | lis r3, noad@h 73 | ori r3, r3, noad@l 74 | bne- error 75 | bl disassemble 76 | 77 | check_for_error: 78 | cmpwi r3, 0 79 | bne- error 80 | 81 | #Success 82 | lis r3, success_message@h 83 | ori r3, r3, success_message@l 84 | bl puts 85 | b epilogue 86 | 87 | #Error, r3 is already set, simply run puts! 88 | error: 89 | bl puts 90 | 91 | #Epilogue 92 | epilogue: 93 | li r3, 0 #Signal to exit 94 | lwz r0, 0x0024 (sp) 95 | mtlr r0 96 | addi sp, sp, 0x0020 97 | blr 98 | -------------------------------------------------------------------------------- /DV/main: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/DV/main -------------------------------------------------------------------------------- /Examples/04codetype/code.txt: -------------------------------------------------------------------------------- 1 | !0456BA98 2 | 0456BA98 3C358234 -------------------------------------------------------------------------------- /Examples/04codetype/source.s: -------------------------------------------------------------------------------- 1 | !0456BA98 2 | 3 | addis r1, r21, 0xFFFF8234 4 | -------------------------------------------------------------------------------- /Examples/06codetype/code.txt: -------------------------------------------------------------------------------- 1 | !0656BA98 2 | 0656BA98 00000034 3 | 3C358234 40821234 4 | 4DA10021 2A010066 5 | 7D9C8AA6 7FDBFBA6 6 | 60000000 E014D100 7 | 7D54F32E 7C0004AC 8 | 4CE73A42 55EA067F 9 | FEDCBA98 00000000 -------------------------------------------------------------------------------- /Examples/06codetype/source.s: -------------------------------------------------------------------------------- 1 | !0656BA98 2 | 3 | addis r1, r21, 0xFFFF8234 4 | bne- 0x1234 5 | bgtlrl+ 6 | cmplwi cr4, r1, 0x66 7 | mfdbat6u r12 8 | mtictc r30 9 | nop 10 | psq_l f0, 0x100 (r20), 1, 5 11 | sthx r10, r20, r30 12 | sync 13 | crset 7 14 | clrlwi. r10, r15, r25 15 | .long 0xFEDCBA98 16 | -------------------------------------------------------------------------------- /Examples/C0codetype/code.txt: -------------------------------------------------------------------------------- 1 | !C0 2 | C0000000 00000007 3 | 3C358234 40821234 4 | 4DA10021 2A010066 5 | 7D9C8AA6 7FDBFBA6 6 | 60000000 E014D100 7 | 7D54F32E 7C0004AC 8 | 4CE73A42 55EA067F 9 | FEDCBA98 4E800020 -------------------------------------------------------------------------------- /Examples/C0codetype/source.s: -------------------------------------------------------------------------------- 1 | !C0 2 | 3 | addis r1, r21, 0xFFFF8234 4 | bne- 0x1234 5 | bgtlrl+ 6 | cmplwi cr4, r1, 0x66 7 | mfdbat6u r12 8 | mtictc r30 9 | nop 10 | psq_l f0, 0x100 (r20), 1, 5 11 | sthx r10, r20, r30 12 | sync 13 | crset 7 14 | clrlwi. r10, r15, 25 15 | .long 0xFEDCBA98 16 | -------------------------------------------------------------------------------- /Examples/C2codetype/code.txt: -------------------------------------------------------------------------------- 1 | !C256BA98 2 | C256BA98 00000007 3 | 3C358234 40821234 4 | 4DA10021 2A010066 5 | 7D9C8AA6 7FDBFBA6 6 | 60000000 E014D100 7 | 7D54F32E 7C0004AC 8 | 4CE73A42 55EA067F 9 | FEDCBA98 00000000 -------------------------------------------------------------------------------- /Examples/C2codetype/source.s: -------------------------------------------------------------------------------- 1 | !C256BA98 2 | 3 | addis r1, r21, 0xFFFF8234 4 | bne- 0x1234 5 | bgtlrl+ 6 | cmplwi cr4, r1, 0x66 7 | mfdbat6u r12 8 | mtictc r30 9 | nop 10 | psq_l f0, 0x100 (r20), 1, 5 11 | sthx r10, r20, r30 12 | sync 13 | crset 7 14 | clrlwi. r10, r15, 25 15 | .long 0xFEDCBA98 16 | -------------------------------------------------------------------------------- /HBC-Source/Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | # Clear the implicit built in rules 3 | #--------------------------------------------------------------------------------- 4 | .SUFFIXES: 5 | #--------------------------------------------------------------------------------- 6 | ifeq ($(strip $(DEVKITPPC)),) 7 | $(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") 8 | endif 9 | 10 | include $(DEVKITPPC)/wii_rules 11 | 12 | #--------------------------------------------------------------------------------- 13 | # TARGET is the name of the output 14 | # BUILD is the directory where object files & intermediate files will be placed 15 | # SOURCES is a list of directories containing source code 16 | # INCLUDES is a list of directories containing extra header files 17 | #--------------------------------------------------------------------------------- 18 | TARGET := $(notdir $(CURDIR)) 19 | BUILD := build 20 | SOURCES := source 21 | DATA := data 22 | INCLUDES := 23 | 24 | #--------------------------------------------------------------------------------- 25 | # options for code generation 26 | #--------------------------------------------------------------------------------- 27 | 28 | #CFLAGS = -save-temps -Os -Wall $(MACHDEP) $(INCLUDE) 29 | CFLAGS = -g -Os -Wall $(MACHDEP) $(INCLUDE) 30 | CXXFLAGS = $(CFLAGS) 31 | 32 | LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map 33 | 34 | #--------------------------------------------------------------------------------- 35 | # any extra libraries we wish to link with the project 36 | #--------------------------------------------------------------------------------- 37 | LIBS := -lwiiuse -lbte -lfat -logc -lm 38 | 39 | #--------------------------------------------------------------------------------- 40 | # list of directories containing libraries, this must be the top level containing 41 | # include and lib 42 | #--------------------------------------------------------------------------------- 43 | LIBDIRS := 44 | 45 | #--------------------------------------------------------------------------------- 46 | # no real need to edit anything past this point unless you need to add additional 47 | # rules for different file extensions 48 | #--------------------------------------------------------------------------------- 49 | ifneq ($(BUILD),$(notdir $(CURDIR))) 50 | #--------------------------------------------------------------------------------- 51 | 52 | export OUTPUT := $(CURDIR)/$(TARGET) 53 | 54 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 55 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) 56 | 57 | export DEPSDIR := $(CURDIR)/$(BUILD) 58 | 59 | #--------------------------------------------------------------------------------- 60 | # automatically build a list of object files for our project 61 | #--------------------------------------------------------------------------------- 62 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 63 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 64 | sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 65 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) 66 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 67 | 68 | #--------------------------------------------------------------------------------- 69 | # use CXX for linking C++ projects, CC for standard C 70 | #--------------------------------------------------------------------------------- 71 | ifeq ($(strip $(CPPFILES)),) 72 | export LD := $(CC) 73 | else 74 | export LD := $(CXX) 75 | endif 76 | 77 | export OFILES_BIN := $(addsuffix .o,$(BINFILES)) 78 | export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(sFILES:.s=.o) $(SFILES:.S=.o) 79 | export OFILES := $(OFILES_BIN) $(OFILES_SOURCES) 80 | 81 | export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES))) 82 | 83 | #--------------------------------------------------------------------------------- 84 | # build a list of include paths 85 | #--------------------------------------------------------------------------------- 86 | export INCLUDE := $(foreach dir,$(INCLUDES), -iquote $(CURDIR)/$(dir)) \ 87 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 88 | -I$(CURDIR)/$(BUILD) \ 89 | -I$(LIBOGC_INC) 90 | 91 | #--------------------------------------------------------------------------------- 92 | # build a list of library paths 93 | #--------------------------------------------------------------------------------- 94 | export LIBPATHS := -L$(LIBOGC_LIB) $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 95 | 96 | export OUTPUT := $(CURDIR)/$(TARGET) 97 | .PHONY: $(BUILD) clean 98 | 99 | #--------------------------------------------------------------------------------- 100 | $(BUILD): 101 | @[ -d $@ ] || mkdir -p $@ 102 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 103 | 104 | #--------------------------------------------------------------------------------- 105 | clean: 106 | @echo clean ... 107 | @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol 108 | 109 | #--------------------------------------------------------------------------------- 110 | run: 111 | wiiload $(TARGET).dol 112 | 113 | 114 | #--------------------------------------------------------------------------------- 115 | else 116 | 117 | DEPENDS := $(OFILES:.o=.d) 118 | 119 | #--------------------------------------------------------------------------------- 120 | # main targets 121 | #--------------------------------------------------------------------------------- 122 | $(OUTPUT).dol: $(OUTPUT).elf 123 | $(OUTPUT).elf: $(OFILES) 124 | 125 | $(OFILES_SOURCES) : $(HFILES) 126 | 127 | #--------------------------------------------------------------------------------- 128 | # This rule links in binary data with the .jpg extension 129 | #--------------------------------------------------------------------------------- 130 | %.jpg.o %_jpg.h : %.jpg 131 | #--------------------------------------------------------------------------------- 132 | @echo $(notdir $<) 133 | $(bin2o) 134 | 135 | -include $(DEPENDS) 136 | 137 | #--------------------------------------------------------------------------------- 138 | endif 139 | #--------------------------------------------------------------------------------- 140 | -------------------------------------------------------------------------------- /HBC-Source/build/add_header.s: -------------------------------------------------------------------------------- 1 | .file "add_header.c" 2 | .machine ppc 3 | .section ".text" 4 | .ident "GCC: (devkitPPC release 44.2) 13.2.0" 5 | 6 | #r3 = pointer to source.s/code.txt 7 | #r4 = source.s/code.txt size EXcluding null 8 | #r5 = pointer to gecko header 9 | #r6 = gecko header type 10 | 11 | #r3 returns new size INCLUDING NULL 12 | 13 | #0 = Raw 14 | #1 = C2 15 | #2 = 04 16 | #3 = 06 17 | #4 = C0 18 | 19 | .globl add_header 20 | add_header: 21 | stwu sp, -0x0020 (sp) 22 | mflr r0 23 | stw r29, 0x14 (sp) 24 | stw r30, 0x18 (sp) 25 | stw r31, 0x1C (sp) 26 | stw r0, 0x0024 (sp) 27 | 28 | #Save r3 r4 r5 arg 29 | mr r31, r3 30 | mr r30, r4 31 | mr r29, r5 32 | 33 | #Now include null byte to size (r4 arg) 34 | #We want to move the appending null byte to always ensure source.s final string ends in null, sanity to stop overflows 35 | #NOTE this is important 36 | addi r4, r4, 1 37 | 38 | cmpwi r6, 4 39 | beq- jimmyrakestrawC0 40 | 41 | #C2/04/06 found, memmove source.s forward by 10 bytes 42 | mr r5, r4 #Size 43 | mr r4, r3 #Source 44 | addi r3, r3, 10 #Dest, move forward 45 | bl memmove 46 | li r7, 9 47 | b transferheader_to_source 48 | 49 | #C0 found, memmove source.s/code.txt forward by 4 bytes 50 | jimmyrakestrawC0: 51 | mr r5, r4 #Size 52 | mr r4, r3 #Source 53 | addi r3, r3, 4 #Dest, move forward 54 | bl memmove 55 | li r7, 3 56 | 57 | transferheader_to_source: 58 | mtctr r7 59 | addi r4, r29, -1 60 | addi r3, r31, -1 61 | lbzu r0, 0x1 (r4) 62 | stbu r0, 0x1 (r3) 63 | bdnz+ -0x8 64 | 65 | #Now store an enter inbetween header and rest of source.s/code.txt 66 | li r0, 0xA 67 | stb r0, 0x1 (r3) 68 | 69 | #Now calc new source.s length and EXCLUDE null to return to parent func 70 | add r3, r7, r30 #Header + source.s/code.txt(w/ null) 71 | addi r3, r3, 1 #Account for 0xA byte in between header and source.s/code.txt 72 | 73 | #Epilogue 74 | lwz r0, 0x0024 (sp) 75 | lwz r31, 0x1C (sp) 76 | lwz r30, 0x18 (sp) 77 | lwz r29, 0x14 (sp) 78 | mtlr r0 79 | addi sp, sp, 0x0020 80 | blr 81 | -------------------------------------------------------------------------------- /HBC-Source/build/assemble.s: -------------------------------------------------------------------------------- 1 | .file "assemble.c" 2 | .machine ppc 3 | .section ".text" 4 | .ident "GCC: (devkitPPC release 44.2) 13.2.0" 5 | 6 | #Assemble Func (void) 7 | #r3 returns 0 for success, any negative number is error 8 | 9 | #Open code.txt to make sure one doesn't exist 10 | #Open abin.bin, get size, alloc mem, dump, close 11 | #Open sourse.s, get size, alloc mem, dump, close 12 | #Count 0xA ascii bytes present to estimate needed size sourse's generated code.txt 13 | #Mem alloc for estimated size 14 | #Update cache for abin.bin since we will execute on it 15 | #Run waltress abin.bin 16 | #Create code.text, write to it, close, success 17 | 18 | #r31 = fd, then code.txt pointer 19 | #VOID NOW r30 = abin.bin size 20 | #VOID NOW r29 = abin.bin pointer 21 | #r28 = sourse.s size 22 | #r27 = sourse.s pointer 23 | #r26 = C2, C0, 04, 06, RAW flag 24 | 25 | #Directives 26 | asources: 27 | .asciz "source.s" 28 | acodetxt: 29 | .asciz "code.txt" 30 | arb: 31 | .asciz "rb" 32 | awb: 33 | .asciz "wb" 34 | afopencodetxtEC: 35 | .asciz "\n\nError! Code.txt already exists. Delete it and try again.\n\n" 36 | afopensourceEC: 37 | .asciz "\n\nError! Can't find source.s. This file needs to be present for assembling. Is the file named incorrectly?\n\n" 38 | afseeksourceEC: 39 | .asciz "\n\nError! fseek failure on source.s.\n\n" 40 | amemalignsourceEC: 41 | .asciz "\n\nError! Can't allocate memory for source.s.\n\n" 42 | afreadsourceEC: 43 | .asciz "\n\nError! Unable to dump source.s to memory.\n\n" 44 | afclosesourceEC: 45 | .asciz "\n\nError! Can't close source.s.\n\n" 46 | ageckoheaderEC: 47 | .asciz "\n\nError! The Gecko Header is not the correct format or an unsupported Header type is being used.\n\n" 48 | asavestripmallocEC: 49 | .asciz "\n\nError! Can't allocate memory within the Save and Strip Gecko Header subroutine.\n\n" 50 | amemalignTOBEcodebinEC: 51 | .asciz "\n\nError! Can't allocate memory for temporary code.bin.\n\n" 52 | awaltressSscanfFailureEC: 53 | .asciz "\n\nError! A sscanf failure occurred when Waltress tried assembling the above instruction. Please note that all spaces are stripped out, this is normal. Did you typo the instruction name? Did you forget a comma? Did you forget to prepend a Hex value with 0x? Did you forget to prepend a GPR with the letter r? Did you forget to prepend a FPR with the letter f? If the above instruction is andi/andis, did you forget to add a period after the instruction name?\n\n" 54 | awaltressBadParamEC: 55 | .asciz "\n\nError! The above instruction was interpreted by Waltress to be valid, but an invalid parameter (register value, imm value, etc) was used. Please note that all spaces are stripped out, this is normal. Did you exceed the SIMM-16 range? Did you exceed the UIMM-16 range? Are you following the IMM Format rules? Did you exceed the SIMM-12 range for a psq load/store? Are you using a crF number higher than 7?\n\n" 56 | amemaligncodetxtEC: 57 | .asciz "\n\nError! Can't allocate memory for code.txt.\n\n" 58 | afcreatecodetxtEC: 59 | .asciz "\n\nError! Can't create new code.txt. If you are using the Desktop Version, make sure the DV folder has user permissions enabled.\n\n" 60 | afwritecodetxtEC: 61 | .asciz "\n\nError! Can't write content to newly created code.txt.\n\n" 62 | afclosecodetxtEC: 63 | .asciz "\n\nError! Can't close new code.txt.\n\n" 64 | 65 | .align 2 66 | 67 | #Prologue 68 | .globl assemble 69 | assemble: 70 | stwu sp, -0x0030 (sp) 71 | mflr r0 72 | stw r22, 0x8 (sp) 73 | stw r23, 0xC (sp) 74 | stw r24, 0x10 (sp) 75 | stw r25, 0x14 (sp) 76 | stw r26, 0x18 (sp) 77 | stw r27, 0x1C (sp) 78 | stw r28, 0x20 (sp) 79 | stw r29, 0x24 (sp) 80 | stw r30, 0x28 (sp) 81 | stw r31, 0x2C (sp) 82 | stw r0, 0x0034 (sp) 83 | 84 | #Open code.txt, one shouldn't exist 85 | lis r3, acodetxt@h 86 | lis r4, arb@h 87 | ori r3, r3, acodetxt@l 88 | ori r4, r4, arb@l 89 | bl fopen 90 | cmpwi r3, 0 91 | lis r3, afopencodetxtEC@h 92 | ori r3, r3, afopencodetxtEC@l 93 | bne- assembleerror #YES this is bne! We don't want file to exist 94 | 95 | #Open source.s 96 | lis r3, asources@h 97 | lis r4, arb@h 98 | ori r3, r3, asources@l 99 | ori r4, r4, arb@l 100 | bl fopen 101 | mr. r31, r3 102 | lis r3, afopensourceEC@h 103 | ori r3, r3, afopensourceEC@l 104 | beq- assembleerror 105 | 106 | #Get size of source.s 107 | mr r3, r31 108 | li r4, 0 109 | li r5, 2 #Seek end 110 | bl fseek 111 | cmpwi r3, 0 112 | lis r3, afseeksourceEC@h 113 | ori r3, r3, afseeksourceEC@l 114 | bne- assembleerror 115 | mr r3, r31 116 | bl ftell #No error check for this 117 | 118 | #Rewind file stream position 119 | #Alloc mem for source.s 120 | #*NOTE* We have source.s filesize but future custom subfuncs require the file ends in a null byte, therefore add 1 to the file size before calling memalign. 121 | #*NOTE* Also, the gencodebinsize.s function further below requires source.s end in 0xA (enter), therefore we have to add 1 to the file for that as well (total of 2 bytes added) 122 | addi r28, r3, 2 123 | mr r3, r31 124 | bl rewind 125 | li r3, 32 126 | mr r4, r28 127 | bl memalign 128 | mr. r27, r3 129 | lis r3, amemalignsourceEC@h 130 | ori r3, r3, amemalignsourceEC@l 131 | beq- assembleerror 132 | 133 | #Dump source.s, close 134 | mr r3, r27 135 | li r4, 1 136 | subi r5, r28, 2 #This is because we added 2 fake bytes from earlier!!! 137 | mr r6, r31 138 | bl fread 139 | subi r0, r28, 2 140 | cmpw r3, r0 141 | lis r3, afreadsourceEC@h 142 | ori r3, r3, afreadsourceEC@l 143 | bne- assembleerror 144 | mr r3, r31 145 | bl fclose 146 | cmpwi r3, 0 147 | lis r3, afclosesourceEC@h 148 | ori r3, r3, afclosesourceEC@l 149 | bne- assembleerror 150 | 151 | #Append an 0x0A00 to file (last halfword of allocated block), because we allocated 2 extra bytes and future funcs require the file to end in 0x0A00 (enter new line then null) 152 | subi r3, r28, 2 153 | li r4, 0x0A00 154 | sthx r4, r3, r27 155 | 156 | #Patch carriages 157 | mr r3, r27 158 | bl newline_fixer 159 | 160 | #Get the Gecko Header type from source.s 161 | #-1 = Invalid 162 | #0 = Raw 163 | #1 = C2 164 | #2 = 04 165 | #3 = 06 166 | #4 = C0 167 | mr r3, r27 168 | bl get_geckoheadertype 169 | mr. r24, r3 170 | lis r3, ageckoheaderEC@h 171 | ori r3, r3, ageckoheaderEC@l 172 | blt- assembleerror 173 | beq- skipstrip 174 | 175 | #Call func that saves gecko header then overwrites it with spaces 176 | #r3 returns malloced space where header is saved at 177 | #r3 arg = gecko header type 178 | #r4 arg = source.s ptr, source.s must end in null byte 179 | mr r3, r24 180 | mr r4, r27 181 | bl saveANDoverwrite_geckoheader 182 | mr. r23, r3 183 | lis r3, asavestripmallocEC@h 184 | ori r3, r3, asavestripmallocEC@l 185 | beq- assembleerror 186 | 187 | #Call the source.s parser to remove any double+ enters, spaces, tabs, and comments 188 | #r3 = pointer to source.s, must end in null byte 189 | #r4 = size of source.s plus null byte 190 | skipstrip: 191 | mr r3, r27 192 | mr r4, r28 #TODO fix me, r28 is incorrect (needs to be decremented) but it actually doesn't matter, func will still work correctly cuz null byte ender. THIS MUST BE fixed in the save and stripper function 193 | bl source_parser #No error check for this 194 | cmpwi r3, 0 195 | bne- assembleerror #If not 0, r3 will hold memory address to return to main.S to print to console 196 | 197 | #Check all SIMM lengths/widths 198 | mr r3, r27 199 | bl simm_length_checker 200 | cmpwi r3, 0 201 | bne- assembleerror #If not 0, r3 will hold memory address to return to main.S to print to console 202 | 203 | #Now change all negative hex SIMMs to their unsigned equivalents 204 | mr r3, r27 205 | bl fix_neg_hex 206 | cmpwi r3, 0 207 | bne- assembleerror #If not 0, r3 will hold memory address to return to main.S to print to console 208 | 209 | #Now remove all branch labels and branch label landing spots 210 | mr r3, r27 211 | bl branchlabelparser 212 | cmpwi r3, 0 213 | bne- assembleerror #If not 0, r3 will hold memory address to return to main.S to print to console 214 | 215 | #Call custom subfunc to generate a temp code.bin's upper bound size, if gecko code, this will be incremented right before running Waltress 216 | #r3 = pointer to source.s 217 | #r3 returns byte size, will never return an error 218 | mr r3, r27 219 | bl gencodebinsize #TODO in this func add checks for gecko type (and arg) because we need to allocate more shit to memalign if so 220 | mr r26, r3 221 | 222 | #Alloc mem for to-be-genned temp code.bin and place its pointer in r31 223 | addi r4, r26, 16 #Highest possible incrementation needed is C0 end that requires a whole end appended,no need to checs, mights as well just increase it across the board for any situation 224 | li r3, 32 225 | bl memalign 226 | mr. r31, r3 227 | lis r3, amemalignTOBEcodebinEC@h 228 | ori r3, r3, amemalignTOBEcodebinEC@l 229 | beq- assembleerror 230 | 231 | #Adjust r30 use based on codetype 232 | cmpwi r24, 0 233 | beq- raw_setup_abin 234 | cmpwi r24, 2 235 | bne- add_eight 236 | 237 | #Increase r30 by 4 cuz 04 codetype 238 | addi r30, r31, 4 239 | b minusOner27 240 | 241 | #Increase r30 by 8 cuz c2/06/c0 codetype 242 | add_eight: 243 | addi r30, r31, 8 244 | b minusOner27 245 | 246 | #Prep for Engine 247 | raw_setup_abin: 248 | mr r30, r31 249 | minusOner27: 250 | addi r27, r27, -1 251 | 252 | main_abinDV_loop: 253 | mr r5, r27 254 | 255 | #Loop 256 | #Check for null byte, if so stop 257 | #Write temp null at 0xA 258 | #Send each source instruction to engine 259 | asm_engine_loop: 260 | lbzu r0, 0x1 (r5) 261 | cmpwi r0, 0 262 | beq- asm_engine_completed 263 | cmpwi r0, 0xA 264 | bne+ asm_engine_loop 265 | 266 | overwrite_enter: 267 | li r0, 0 268 | stb r0, 0 (r5) 269 | 270 | #Give waltress's arg, then update r27 before running engine 271 | addi r3, r27, 1 272 | addi r22, r27, 1 #Save current asm instruction string in r22. If an error occurs after running Waltress, we know the culprit. 273 | mr r4, r30 274 | mr r27, r5 275 | 276 | #RUN WALTRESS ASM (abin.bin) ENGINE 277 | #r27 = r3 = source.s line input addr (must end in null) 278 | #r31 = r4 = code.bin*** output addr (where binary assembled instruction gets written at) 279 | bl asm_engine # :) 280 | cmpwi r3, 0 281 | beq- waltress_loves_us 282 | 283 | cmpwi r3, -3 284 | beq- waltress_sscanf_failure 285 | 286 | #Bad format/parameter error 287 | mr r3, r22 288 | crxor 6,6,6 289 | bl printf #print the culprit 290 | lis r3, awaltressBadParamEC@h #Set new string for next printf 291 | ori r3, r3, awaltressBadParamEC@l 292 | b assembleerror 293 | 294 | #sscanf failure 295 | waltress_sscanf_failure: 296 | mr r3, r22 297 | crxor 6,6,6 298 | bl printf #print the culprit, DON'T use puts 299 | lis r3, awaltressSscanfFailureEC@h #Set new string for next printf 300 | ori r3, r3, awaltressSscanfFailureEC@l 301 | b assembleerror 302 | 303 | #Update r30 (code.bin pointer) & r28 (amount of times engine ran) 304 | waltress_loves_us: 305 | addi r30, r30, 4 306 | b main_abinDV_loop 307 | 308 | asm_engine_completed: 309 | #r3 = code.bin raw size calc (this div'd by 4 = amount of instructions) 310 | #r4 = code.bin pointer 311 | #r5 = codetype 312 | #r6 = gecko header pointer 313 | #r3 returns net code.bin size value 314 | cmpwi r24, 0 315 | beq- mulli_crap 316 | mr r3, r26 317 | mr r4, r31 318 | mr r5, r24 319 | mr r6, r23 320 | bl finalize_assembled_bin 321 | mr r26, r3 322 | 323 | #Multiply saved code.bin size by 3 for code.txt's needed memory 324 | #TODO this allocates too much memory for the job, fix later 325 | mulli_crap: 326 | mulli r4, r26, 3 327 | li r3, 32 328 | mr r25, r4 #Need this for later for memset 329 | bl memalign 330 | mr. r30, r3 #r30 we can use now btw 331 | lis r3, amemaligncodetxtEC@h 332 | ori r3, r3, amemaligncodetxtEC@l 333 | beq- assembleerror 334 | 335 | #Memset it w/ null. Needed because we will eventually count the content size 336 | mr r3, r30 337 | li r4, 0 338 | mr r5, r25 339 | bl memset 340 | 341 | #Change code.bin to code.txt 342 | #Call Hex2ASCII 343 | #r3 = source pointer 344 | #r4 = dest pointer 345 | #r5 = code bin word size (byte / 4) 346 | mr r3, r31 347 | mr r4, r30 348 | srawi r5, r26, 2 #TODO needs adjustment after running finalizeassembled func 349 | bl bin2txt 350 | 351 | #Get length of current code.txt (EXclude null byte ender) 352 | addi r3, r30, -1 353 | li r28, 0 #We don't have any more need for r28, free to use now 354 | lbzu r0, 0x1 (r3) 355 | cmpwi r0, 0 356 | beq- 0xC 357 | addi r28, r28, 1 358 | b -0x10 359 | 360 | #Add in saved gecko header to code.txt 361 | cmpwi r24, 0 #If Raw, skip ofc 362 | beq- create_codetxt 363 | 364 | #r3 = pointer to code.txt 365 | #r4 = code.txt size EXcluding null 366 | #r5 = pointer to gecko header 367 | #r6 = gecko header type 368 | #r3 returns updated size that EXcludes null 369 | mr r3, r30 370 | mr r4, r28 371 | mr r5, r23 372 | mr r6, r24 373 | bl add_header 374 | mr r28, r3 375 | 376 | #Create finished code.txt 377 | create_codetxt: 378 | lis r3, acodetxt@h 379 | lis r4, awb@h 380 | ori r3, r3, acodetxt@l 381 | ori r4, r4, awb@l 382 | bl fopen 383 | mr. r29, r3 384 | lis r3, afcreatecodetxtEC@h 385 | ori r3, r3, afcreatecodetxtEC@l 386 | beq- assembleerror 387 | li r4, 1 388 | mr r3, r30 389 | mr r5, r28 #Count (real size) 390 | mr r6, r29 391 | bl fwrite 392 | cmpw r3, r28 393 | lis r3, afwritecodetxtEC@h 394 | ori r3, r3, afwritecodetxtEC@l 395 | bne- assembleerror 396 | mr r3, r29 397 | bl fclose 398 | cmpwi r3, 0 399 | lis r3, afclosecodetxtEC@h 400 | ori r3, r3, afclosecodetxtEC@l 401 | bne- assembleerror 402 | 403 | #TODO add in code to free up allocated blocks of mem 404 | 405 | #Success! 406 | li r3, 0 407 | 408 | assembleerror: 409 | lwz r0, 0x0034 (sp) 410 | lwz r31, 0x2C (sp) 411 | lwz r30, 0x28 (sp) 412 | lwz r29, 0x24 (sp) 413 | lwz r28, 0x20 (sp) 414 | lwz r27, 0x1C (sp) 415 | lwz r26, 0x18 (sp) 416 | lwz r25, 0x14 (sp) 417 | lwz r24, 0x10 (sp) 418 | lwz r23, 0xC (sp) 419 | lwz r22, 0x8 (sp) 420 | mtlr r0 421 | addi sp, sp, 0x0030 422 | blr 423 | -------------------------------------------------------------------------------- /HBC-Source/build/bin2txt.s: -------------------------------------------------------------------------------- 1 | .file "bin2txt.c" 2 | .machine ppc 3 | .section ".text" 4 | .ident "GCC: (devkitPPC release 44.2) 13.2.0" 5 | 6 | #r3 = source pointer 7 | #r4 = dest pointer 8 | #r5 = code.bin byte size / 4 9 | 10 | .globl bin2txt 11 | bin2txt: 12 | stwu sp, -0x0020 (sp) 13 | mflr r0 14 | stw r26, 0x8 (sp) 15 | stw r27, 0xC (sp) 16 | stw r28, 0x10 (sp) 17 | stw r29, 0x14 (sp) 18 | stw r30, 0x18 (sp) 19 | stw r31, 0x1C (sp) 20 | stw r0, 0x0024 (sp) 21 | 22 | #Save args 23 | addi r31, r3, -4 24 | addi r30, r4, -1 25 | 26 | #Set Loop Amount 27 | mtctr r5 28 | 29 | #Set space vs enter flag 30 | li r26, -1 31 | 32 | #Loop 33 | bin2txtloop: 34 | lwzu r0, 0x4 (r31) 35 | rlwinm r6, r0, 4, 0x0000000F #srwi r6, r5, 28 36 | rlwinm r7, r0, 8, 0x0000000F 37 | rlwinm r8, r0, 12, 0x0000000F 38 | rlwinm r9, r0, 16, 0x0000000F 39 | rlwinm r10, r0, 20, 0x0000000F 40 | rlwinm r29, r0, 24, 0x0000000F 41 | rlwinm r4, r0, 28, 0x0000000F 42 | rlwinm r5, r0, 0, 0x0000000F #clrlwi r5, r5, 28 43 | 44 | mr r3, r6 45 | bl hex2ascii 46 | rlwimi r27, r3, 24, 0xFFFFFFFF #Needed to not use any junk data thats residing in r27 47 | 48 | mr r3, r7 49 | bl hex2ascii 50 | rlwimi r27, r3, 16, 0x00FF0000 51 | 52 | mr r3, r8 53 | bl hex2ascii 54 | rlwimi r27, r3, 8, 0x0000FF00 55 | 56 | mr r3, r9 57 | bl hex2ascii 58 | rlwimi r27, r3, 0, 0x000000FF 59 | 60 | mr r3, r10 61 | bl hex2ascii 62 | rlwimi r28, r3, 24, 0xFFFFFFFF #Needed to not use any junk data thats residing in r27 63 | 64 | mr r3, r29 65 | bl hex2ascii 66 | rlwimi r28, r3, 16, 0x00FF0000 67 | 68 | mr r3, r4 69 | bl hex2ascii 70 | rlwimi r28, r3, 8, 0x0000FF00 71 | 72 | mr r3, r5 73 | bl hex2ascii 74 | rlwimi r28, r3, 0, 0x000000FF 75 | 76 | #Check space vs enter flag, also store r27 and r28 to give time for branch prediction 77 | not. r26, r26 78 | stw r27, 0x1 (r30) 79 | stw r28, 0x5 (r30) 80 | bne- 0xC 81 | #Write space 0x20 82 | li r3, 0x20 83 | b 0x8 84 | #Write enter 0xA 85 | li r3, 0xA 86 | stbu r3, 0x9 (r30) 87 | bdnz+ bin2txtloop 88 | 89 | #Write null byte over final space/enter 90 | li r0, 0 91 | stb r0, 0x0 (r30) 92 | 93 | #End func 94 | lwz r0, 0x0024 (sp) 95 | lwz r31, 0x1C (sp) 96 | lwz r30, 0x18 (sp) 97 | lwz r29, 0x14 (sp) 98 | lwz r28, 0x10 (sp) 99 | lwz r27, 0xC (sp) 100 | lwz r26, 0x8 (sp) 101 | mtlr r0 102 | addi sp, sp, 0x0020 103 | blr 104 | 105 | hex2ascii: 106 | cmplwi r3, 9 107 | bgt- 0xC #less likely branch because A-F is less possible outcomes than 0-9 108 | ori r3, r3, 0x30 109 | blr 110 | addi r3, r3, 0x37 111 | blr 112 | -------------------------------------------------------------------------------- /HBC-Source/build/branchlabelparser.s: -------------------------------------------------------------------------------- 1 | .file "branchlabelparser.c" 2 | .machine ppc 3 | .section ".text" 4 | .ident "GCC: (devkitPPC release 44.2) 13.2.0" 5 | 6 | #This gets immediately called AFTER source.s parser 7 | no_landing_spot_text: 8 | .asciz "\n\nError! The above instruction's branch label doesn't have a landing spot.\n\n" 9 | too_small_text: 10 | .asciz "\n\nError! The above instruction's branch label is not at least 3 characters in length.\n\n" 11 | too_much_text: 12 | .asciz "\n\nError! The above instruction's branch label exceeds 31 characters in length.\n\n" 13 | invalid_char_text: 14 | .asciz "\n\nError! The above instruction's branch label uses an invalid character.\n\n" 15 | too_far_jump_condi_text: 16 | .asciz "\n\nError! The above instruction's branch label (conditional) has a jump that exceeds 0x7FFC.\n\n" 17 | too_far_jump_uncondi_text: 18 | .asciz "\n\nError! The above instruction's branch label (unconditional) has a jump that exceeds 0x01FFFFFC.\n\n" 19 | duplicate_spots: 20 | .asciz "\n\nError! The above instruction's branch label has at least 2 different landing spots.\n\n" 21 | malloc_text: 22 | .asciz "\n\nError! For whatever reason, memory couldn't be allocated when needing to expand source.s due to a label-to-simm conversion.\n\n" 23 | .align 2 24 | 25 | .globl branchlabelparser 26 | branchlabelparser: 27 | 28 | #Func processes branch labels 29 | #Branch instructions receive their SIMMs 30 | #Landing labels gets removed 31 | 32 | #Args 33 | #r3 = source.s ptr (MUST END IN NULL or else overflow occurs) 34 | #Return Values 35 | #r3 = 0 (success) 36 | #r3 = Pointer to ASCII error message if not success 37 | 38 | /* 39 | r31 = source.s 40 | r30 = branch label ptr 41 | r29 = simm max 42 | r28 = length of branch label 43 | r27 = branch lebal landing ptr 44 | r26 = source.s size 45 | r25 = brand new source.s ptr (will replace assemble.s's r27 if used) 46 | */ 47 | 48 | #Symbols 49 | .set branch_ident, 0x0A62 #/nb 50 | .set underscore, 0x5F #_ 51 | .set colon, 0x3A #: 52 | 53 | #Prologue 54 | stwu sp, -0x0030 (sp) 55 | mflr r0 56 | stw r25, 0x14 (sp) #0x8 thru 0x13 is buffer 57 | stw r26, 0x18 (sp) 58 | stw r27, 0x1C (sp) 59 | stw r28, 0x20 (sp) 60 | stw r29, 0x24 (sp) 61 | stw r30, 0x28 (sp) 62 | stw r31, 0x2C (sp) 63 | stw r0, 0x0034 (sp) 64 | 65 | #Save arg 66 | mr r31, r3 67 | 68 | #Search for 0x0A62 (/nb) 69 | subi r30, r31, 1 70 | ROOTLOOP: 71 | lhzu r0, 0x1 (r30) 72 | srwi. r4, r0, 8 #Check for EoF null byteROOTLOOP 73 | beq- erase_landing_spots 74 | cmpwi r0, branch_ident 75 | bne+ ROOTLOOP 76 | 77 | #Possible branch found, check character after b 78 | #lf capital letter or underscore, its a label for uncondi branch 79 | lbzu r0, 0x2 (r30) 80 | cmpwi r0, 0x6C #l 81 | beq- condibranch 82 | cmpwi r0, 0x67 #g 83 | beq- condibranch 84 | cmpwi r0, 0x65 #e 85 | beq- condibranch 86 | cmpwi r0, 0x73 #s 87 | beq- condibranch 88 | cmpwi r0, 0x6E #n 89 | beq- condibranch 90 | cmpwi r0, 0x64 #d 91 | beq- condibranch 92 | cmpwi r0, underscore 93 | beq- uncondibranch 94 | cmplwi r0, 0x41 #A 95 | blt- ROOTLOOP 96 | cmplwi r0, 0x5A #Z 97 | bgt- ROOTLOOP 98 | 99 | #Uncondi branch possibly found, set one-way SIMM max value 100 | uncondibranch: 101 | #Check for "0x" 102 | lhz r0, 0 (r30) 103 | cmpwi r0, 0x3078 104 | beq- ROOTLOOP #SIMM used, not label, skip branch! 105 | lis r29, 0x01FF 106 | ori r29, r29, 0xFFFC 107 | b get_label_length 108 | 109 | #Condi branch possibly found, set one-way SIMM value max 110 | #Atm, r30 is at the char right after (b). Every conditional branch is bxx or greater, so add one to r30 then start doing update-type loop,load, and check 111 | condibranch: 112 | addi r30, r30, 1 113 | condibranch_loop: 114 | lbzu r0, 0x1 (r30) 115 | cmpwi r0, 0 116 | beq- erase_landing_spots 117 | cmpwi r0, 0xA 118 | beq- ROOTLOOP 119 | cmpwi r0, 0x30 #check for 0 out of possible 0x 120 | bne- 0x10 121 | lbz r0, 0x1 (r30) 122 | cmpwi r0, 0x78 #check for x out of possible 0x 123 | beq- ROOTLOOP #SIMM found instead of branch label, skip this branch!!! 124 | cmpwi r0, underscore 125 | li r29, 0x7FFC 126 | beq- get_label_length 127 | cmplwi r0, 0x41 #A 128 | blt- condibranch_loop 129 | cmplwi r0, 0x5A #Z 130 | bgt- condibranch_loop 131 | 132 | #r30 (Branch label ptr/cursor) is fully adjusted, now get length of label 133 | #Must be *in* between 3 and 32 134 | get_label_length: 135 | mr r3, r30 #Keep GVR intact for later 136 | lbzu r0, 0x1 (r3) 137 | cmpwi r0, 0xA 138 | bne+ -0x8 139 | sub r28, r3, r30 140 | cmplwi r28, 3 141 | blt- too_short 142 | cmplwi r28, 31 143 | bgt- too_long 144 | 145 | #Branch labels can ONLY contain capital letters and underscores 146 | subi r3, r30, 1 147 | char_validator: 148 | lbzu r0, 0x1 (r3) 149 | cmpwi r0, 0xA 150 | beq- search_for_landing_spot 151 | cmplwi r0, 0x41 152 | blt- invalid_branch_char 153 | cmpwi r0, 0x5F 154 | beq- char_validator 155 | cmplwi r0, 0x5A 156 | ble- char_validator 157 | b invalid_branch_char 158 | 159 | #Now search the file for the label's "landing spot" respective label 160 | search_for_landing_spot: 161 | subi r27, r31, 1 162 | compare_labels: 163 | lbzu r0, 0x1 (r27) 164 | cmpwi r0, 0 165 | beq- missing_landing_spot 166 | #r30 = label ptr 167 | #r27 = landing label ptr 168 | #r28 = byte count 169 | mr r3, r30 170 | mr r4, r27 171 | mr r5, r28 172 | bl memcmp 173 | cmpwi r3, 0 174 | bne+ compare_labels 175 | 176 | #Either we found the branch label landing-spot or we just ran into the branch label again 177 | #Colon should be next char 178 | lbzx r0, r27, r28 179 | cmpwi r0, colon 180 | bne- compare_labels 181 | 182 | #Now search rest of file if 2nd+ landing spot exist which it shouldn't 183 | make_sure_no_duplicate_landing_spot_exists: 184 | mr r26, r27 185 | make_sure_no_duplicate_landing_spot_exists_LOOP: 186 | lbzu r0, 0x1 (r26) 187 | cmpwi r0, 0 188 | beq- found_it_for_sure 189 | mr r3, r27 190 | mr r4, r26 191 | addi r5, r28, 1 #Include the colon in count 192 | bl memcmp 193 | cmpwi r3, 0 194 | beq- duplicate_error 195 | b make_sure_no_duplicate_landing_spot_exists_LOOP 196 | 197 | #Now we've found it! 198 | #Make copy of r30 & r27 199 | found_it_for_sure: 200 | mr r3, r30 201 | mr r4, r27 202 | 203 | #First we need to differentiate if the branch SIMM is positive or negative 204 | #lf r30 ptr is less than r27 then its a positive branch 205 | #lf r30 ptr is greater than r27, then its a negative branch 206 | cmplw cr7, r30, r27 #Use cr7 because we need to branch on this conditonal later on!! 207 | blt- cr7, 0x10 #Skip register swap 208 | 209 | #SIMM is negative (backwards branch) Swap r30 (now r3) and r27 (now r4), thank you PPC compiler writer's guide 210 | xor r3, r3, r4 211 | xor r4, r4, r3 212 | xor r3, r3, r4 213 | 214 | #Count amount of 0xA's (enter's) in between the labels 215 | subi r3, r3, 1 216 | li r5, 0 217 | lbzu r0, 0x1 (r3) 218 | cmpw r3, r4 219 | beq- calc_branchlabel_simm 220 | cmpwi r0, 0xA 221 | bne+ -0x10 222 | lbz r0, -0x1 (r3) #Check for : from unrelated branch landing spot, we do NOT want to count that enter 223 | cmpwi r0, colon 224 | beq- -0x1C 225 | addi r5, r5, 1 226 | b -0x24 227 | 228 | #Now we have amount of enters (instruction count), mulli by 4 to get SIMM, then check vs Upper Bound One-way SIMM 229 | calc_branchlabel_simm: 230 | slwi r3, r5, 2 231 | cmplw r3, r29 232 | bgt- exceed_simm 233 | 234 | #Convert SIMM from hex to ascii, store to buffer 235 | blt- cr7, 0x8 #If SIMM (r30 vs r27) is positive, this branch is taken 236 | neg r3, r3 #Negative SIMM needs to be Negative ofc 237 | addi r4, sp, 0x8 238 | bl hex2asciiBParser #Keeping this in a subfunc to not clobber stuff up here 239 | 240 | #SIMM digit length will be hardcoded to 0xXXXXXXXX (10 chars) 241 | #Do Label digits minus SIMM digits, we need this for later, plus it will also decide if we expand, contract, or keep file size same 242 | #0 = do simm write only 243 | #>0 = must contract file then simm write 244 | #<0 = must expand file, adjust key GVRs, then simm write 245 | subic. r3, r28, 10 246 | beq- do_simm_write 247 | 248 | #At this point no matter what, we need to know the current length of source.s (INcluding null byte) 249 | #NOTE Keep cr0 & r3 intact! 250 | subi r4, r31, 1 251 | lbzu r0, 0x1 (r4) 252 | cmpwi cr7, r0, 0 253 | bne+ cr7, -0x8 254 | sub r4, r4, r31 255 | addi r26, r4, 1 #Account for null byte 256 | 257 | #Okay r26 holds length of source.s plus null byte, now branch based on expanding vs contracting file 258 | bgt- must_contract_file 259 | 260 | #Alloc new buffer for filesize + r3 from above subic(.) instruction 261 | sub r3, r26, r3 #r3 (delta) is negative, so a subtraction will yield an addition 262 | bl malloc 263 | mr. r25, r3 264 | beq- malloc_branchparser_error_label 265 | #Transfer from original space to new malloced space 266 | mr r4, r31 267 | mr r5, r26 268 | bl memcpy 269 | 270 | #NOTE: Yes the following is hardcoded, yuck! Edit GVR!!!! 271 | #Source.s is now at a new spot, we need to manually fix r27 272 | stw r25, 0x1C (sp) #Replace caller-saved r27 with callee-made r25 273 | #Fix r30 (label ptr) 274 | sub r3, r30, r31 275 | add r30, r25, r3 276 | #Fix this func's r31 (source.s ptr) 277 | mr r31, r25 278 | #Now we can just memmove it, hooray 279 | 280 | must_contract_file: 281 | #File size needs cut down! Branch label digit length exceeds 10 digits 282 | #memmove 283 | #r3 = dest 284 | #r4 = src 285 | #r5 = length of block 286 | add r4, r30, r28 #Label Ptr + Label Size will result as Src ptr (point at the 0xA right after branch label) 287 | addi r3, r30, 10 #okay to hardcode since all gen'd SIMMs are 0xXXXXXXXX ;r3 NOW set 288 | add r5, r31, r26 #r5 at this moment = one byte PAST null byte ptr 289 | sub r5, r5, r4 #One-past-Null byte ptr - Src ptr = amount to move exactly! 290 | bl memmove 291 | #Only thing left to do is transfer the SIMM ascii to source.s 292 | 293 | #No expanding nor contracting needed, just plug in SIMM ascii! 294 | do_simm_write: 295 | #Transfer from stack buffer to source.s 296 | li r0, 5 297 | addi r3, sp, 6 298 | mtctr r0 299 | subi r4, r30, 2 300 | lhzu r0, 0x2 (r3) 301 | sthu r0, 0x2 (r4) 302 | bdnz+ -0x8 303 | 304 | #Sweet! We did it. Move onto next possible branch label 305 | b ROOTLOOP 306 | 307 | #A branch label has 2 more more landing spots 308 | duplicate_error: 309 | #Null out enter AFTER branch label 310 | mr r3, r30 311 | bl null_post_enter 312 | #Move cursor to previous enter or SoF-1 (start of file minus 1) 313 | mr r3, r30 314 | bl move_cursor_back 315 | #Print the culprit 316 | crxor 6, 6, 6 317 | bl printf 318 | #Return error string to Parent 319 | lis r3, duplicate_spots@h 320 | ori r3, r3, duplicate_spots@l 321 | b branchlabelepilogue 322 | 323 | #A branch label's landing spot is missing 324 | missing_landing_spot: 325 | #Null out enter AFTER branch label 326 | mr r3, r30 327 | bl null_post_enter 328 | #Move cursor to previous enter or SoF-1 (start of file minus 1) 329 | mr r3, r30 330 | bl move_cursor_back 331 | #Print the culprit 332 | crxor 6, 6, 6 333 | bl printf 334 | #Return error string to Parent 335 | lis r3, no_landing_spot_text@h 336 | ori r3, r3, no_landing_spot_text@l 337 | b branchlabelepilogue 338 | 339 | #Branch min violation 340 | too_short: 341 | #Null out enter AFTER branch label 342 | mr r3, r30 343 | bl null_post_enter 344 | #Move cursor to previous enter or SoF-1 (start of file minus 1) 345 | mr r3, r30 346 | bl move_cursor_back 347 | #Print the culprit 348 | crxor 6, 6, 6 349 | bl printf 350 | #Return error string to Parent 351 | lis r3, too_small_text@h 352 | ori r3, r3, too_small_text@l 353 | b branchlabelepilogue 354 | 355 | #Branch max violation 356 | too_long: 357 | #Null out enter AFTER branch label 358 | mr r3, r30 359 | bl null_post_enter 360 | #Move cursor to previous enter or SoF-1 (start of file minus 1) 361 | mr r3, r30 362 | bl move_cursor_back 363 | #Print the culprit 364 | crxor 6, 6, 6 365 | bl printf 366 | #Return error string to Parent 367 | lis r3, too_much_text@h 368 | ori r3, r3, too_much_text@l 369 | b branchlabelepilogue 370 | 371 | #Branch invalid char violation 372 | invalid_branch_char: 373 | #Null out enter AFTER branch label 374 | mr r3, r30 375 | bl null_post_enter 376 | #Move cursor to previous enter or SoF-1 (start of file minus 1) 377 | mr r3, r30 378 | bl move_cursor_back 379 | #Print the culprit 380 | crxor 6, 6, 6 381 | bl printf 382 | #Return error string to Parent 383 | lis r3, invalid_char_text@h 384 | ori r3, r3, invalid_char_text@l 385 | b branchlabelepilogue 386 | 387 | #Bad SIMM 388 | exceed_simm: 389 | #Null out enter AFTER branch label 390 | mr r3, r30 391 | bl null_post_enter 392 | #Move cursor to previous enter or SoF-1 (start of file minus 1) 393 | mr r3, r30 394 | bl move_cursor_back 395 | #Print the culprit 396 | crxor 6, 6, 6 397 | bl printf 398 | #Depending on SIMM used, send appropriate error message back to parent 399 | cmpwi r29, 0x7FFC 400 | bne- 0x10 401 | lis r3, too_far_jump_condi_text@h 402 | ori r3, r3, too_far_jump_condi_text@l 403 | b branchlabelepilogue 404 | lis r3, too_far_jump_uncondi_text@h 405 | ori r3, r3, too_far_jump_uncondi_text@l 406 | b branchlabelepilogue 407 | 408 | #Malloc failure 409 | malloc_branchparser_error_label: 410 | lis r3, malloc_text@h 411 | ori r3, r3, malloc_text@l 412 | b branchlabelepilogue 413 | 414 | #Done! Only thing left is to remove all branch landing labels (example:) 415 | erase_landing_spots: 416 | #Search for colon 417 | subi r30, r31, 1 418 | erase_landing_spots_loop: 419 | lbzu r0, 0x1 (r30) 420 | cmpwi r0, 0 421 | beq- finally_done 422 | cmpwi r0, colon 423 | bne+ -0x10 424 | 425 | #Get size of source.s's null byte ptr, we have to do this because its possible this function never executed to make an r26 value to use from earlier 426 | mr r5, r30 #No need to restart at beginning of file again 427 | lbzu r0, 0x1 (r5) 428 | cmpwi r0, 0 429 | bne+ -0x8 430 | #r5 now = null byte ptr 431 | 432 | #Found colon 433 | #For the case that if the user has a branch label at the very very very start of file, we first check 434 | #backwards til we see that the current working ptr matches r31 (source.s) ptr 435 | #For NOT the case above, we then check backwards to see once we hit ASCII enter (0xA) 436 | mr r3, r30 437 | lbzu r0, -0x1 (r3) 438 | cmpw r3, r31 439 | beq- 0xC 440 | cmpwi r0, 0xA 441 | bne+ -0x10 442 | #*DON'T* add one to r3 because we need one of the enters gone, or else we will have back to back enters 443 | addi r4, r30, 1 #Src; must be at char right AFTER : 444 | sub r5, r5, r4 #(Null byte ptr - Src ptr) + 1) = amount to move 445 | addi r5, r5, 1 446 | #Before calling memmove make r30 the dest src, needs to be updated before we loop again 447 | mr r30, r3 448 | #Remove the landing label! 449 | bl memmove 450 | b erase_landing_spots_loop 451 | 452 | finally_done: 453 | #ALMOST THERE, if a branch landing label was at very very start of file then the file will start with 0xA which will jack up 454 | #future subroutines and cause crash 455 | lbz r0, 0x0 (r31) 456 | cmpwi r0, 0xA 457 | bne+ actually_done_lol 458 | 459 | #Get null byte ptr; so hacky we need to fix all of this in the future lol 460 | subi r5, r31, 1 461 | lbzu r0, 0x1 (r5) 462 | cmpwi r0, 0 463 | bne+ -0x8 464 | 465 | #r5 now = null byte ptr, set up args for memmove and call it 466 | mr r3, r31 #Dest 467 | addi r4, r31, 1 #Src 468 | sub r5, r5, r4 #(Null byte ptr - Src ptr) + 1) = amount to move 469 | addi r5, r5, 1 470 | bl memmove 471 | 472 | actually_done_lol: 473 | li r3, 0 474 | 475 | branchlabelepilogue: 476 | lwz r0, 0x0034 (sp) 477 | lwz r31, 0x2C (sp) 478 | lwz r30, 0x28 (sp) 479 | lwz r29, 0x24 (sp) 480 | lwz r28, 0x20 (sp) 481 | lwz r27, 0x1C (sp) 482 | lwz r26, 0x18 (sp) 483 | lwz r25, 0x14 (sp) 484 | mtlr r0 485 | addi sp, sp, 0x0030 486 | blr 487 | 488 | hex2asciiBParser: 489 | #First store "0x" to buffer space 490 | li r0, 0x3078 491 | sth r0, 0 (r4) 492 | #Set loop amount 493 | li r0, 8 494 | mtctr r0 495 | #Set initial shiftor amount 496 | li r5, 32 497 | #Adjust r4 for when we stbu the ascii byte 498 | addi r4, r4, 1 499 | #Loop 500 | hex2asciiBParser_loop: 501 | #Update shiftor amount 502 | subi r5, r5, 4 503 | #Extract digit 504 | srw r0, r3, r5 505 | clrlwi r6, r0, 28 506 | #Convert from digit hex to byte ascii 507 | cmplwi r6, 9 508 | bgt- 0xC 509 | ori r7, r6, 0x30 510 | b 0x8 511 | addi r7, r6, 0x37 512 | #Store converted byte to buffer 513 | stbu r7, 0x1 (r4) 514 | #Decrement loop 515 | bdnz+ hex2asciiBParser_loop 516 | #End func 517 | blr 518 | 519 | null_post_enter: 520 | lbzu r0, 0x1 (r3) 521 | cmpwi r0, 0xA 522 | bne+ -0x8 523 | li r0, 0 524 | stb r0, 0 (r3) 525 | blr 526 | 527 | move_cursor_back: 528 | lbzu r0, -0x1 (r3) 529 | cmplw r3, r31 530 | blt- 0xC 531 | cmpwi r0, 0xA 532 | bne+ -0x10 533 | addi r3, r3, 1 534 | blr 535 | -------------------------------------------------------------------------------- /HBC-Source/build/codetxt2bin.s: -------------------------------------------------------------------------------- 1 | .file "codetxt2bin.c" 2 | .machine ppc 3 | .section ".text" 4 | .ident "GCC: (devkitPPC release 44.2) 13.2.0" 5 | 6 | #Func changes fully parsed code.txt to a bare bones code.bin via a series of sscanf calls 7 | #r3 = pointer to code.txt 8 | #r4 = size of code.txt excluding null byte (we need this to make this func short) 9 | #r3 return 0 for success, negative for failure 10 | string1_codetxt2bin: 11 | .asciz "%08X" 12 | string2_codetxt2bin: 13 | .asciz "%08x" 14 | .align 2 15 | 16 | .globl codetxt2bin 17 | codetxt2bin: 18 | #Make sure r4 is divisible by 8, just in case..... 19 | mr r5, r3 20 | andi. r0, r4, 0x7 #3 LSB's need to get null 21 | li r3, -999 22 | bnelr- 23 | mr r3, r5 24 | 25 | #Prologue 26 | stwu sp, -0x0030 (sp) 27 | mflr r0 28 | stw r29, 0x24 (sp) #0x8 thru 0x23 is buffer space for sprintf 29 | stw r30, 0x28 (sp) 30 | stw r31, 0x2C (sp) 31 | stw r0, 0x0034 (sp) 32 | 33 | #Set main loop count in r29 (size divided by 8) 34 | #Set buffer sp dump spot 35 | srwi r29, r4, 3 36 | addi r30, r3, -4 37 | addi r31, r3, -8 38 | 39 | #sscanf 40 | #r3 = pointer to formatted (ascii) shit 41 | #r4 = pointer to %08X/x 42 | #r5 = where to dump real hex word value (converted *from* ascii) 43 | 44 | codetxt2bin_loop: 45 | addi r31, r31, 8 #Every ASCII instruction is 8 bytes (double-word) long 46 | lis r4, string1_codetxt2bin@h 47 | addi r5, sp, 8 48 | ori r4, r4, string1_codetxt2bin@l 49 | mr r3, r31 50 | bl sscanf 51 | cmpwi r3, 1 52 | beq- storebuffer_and_decrement 53 | #Try again but with lowercase hex char string 54 | lis r4, string2_codetxt2bin@h 55 | addi r5, sp, 8 56 | ori r4, r4, string2_codetxt2bin@l 57 | mr r3, r31 58 | bl sscanf 59 | cmpwi r3, 1 60 | li r3, -999 61 | bne- codetxt2bin_error 62 | storebuffer_and_decrement: 63 | subic. r29, r29, 1 64 | lwz r0, 0x8 (sp) 65 | stwu r0, 0x4 (r30) 66 | bne+ codetxt2bin_loop 67 | 68 | #Success 69 | li r3, 0 70 | 71 | codetxt2bin_error: 72 | lwz r0, 0x0034 (sp) 73 | lwz r31, 0x2C (sp) 74 | lwz r30, 0x28 (sp) 75 | lwz r29, 0x24 (sp) 76 | mtlr r0 77 | addi sp, sp, 0x0030 78 | blr 79 | -------------------------------------------------------------------------------- /HBC-Source/build/codetxtparser.s: -------------------------------------------------------------------------------- 1 | .file "codetxtparser.c" 2 | .machine ppc 3 | .section ".text" 4 | .ident "GCC: (devkitPPC release 44.2) 13.2.0" 5 | 6 | #This function accepts code.txt and removes the following.. 7 | #Spaces 8 | #Tabs 9 | #Enters 10 | #Comments 11 | #This is needed because Waltress DASM Engine needs everything stripped 12 | #r3 code.txt must end in null byte! 13 | 14 | #r3 = pointer to code.txt that ends in null 15 | #r4 = byte size *plus* null 16 | 17 | .set cspace, 0x20 18 | .set center, 0x0A 19 | .set ctab, 0x09 20 | .set ccomment, 0x23 21 | .set cslash, 0x2F 22 | .set casterisk, 0x2A 23 | 24 | #Prologue 25 | .globl codetxtparser 26 | codetxtparser: 27 | stwu sp, -0x0010 (sp) 28 | mflr r0 29 | stw r30, 0x8 (sp) 30 | stw r31, 0xC (sp) 31 | stw r0, 0x0014 (sp) 32 | 33 | #Save Args 34 | mr r31, r3 35 | mr r30, r4 36 | 37 | #Change all comments and chars within comments to spaces 38 | #We'll make a dedicated comment handler in a future version 39 | #Pre decrement ptr and place space symbol in r4 40 | addi r3, r3, -1 41 | li r4, cspace 42 | 43 | codetxtchange_comments_to_spaces: 44 | lbzu r0, 0x1 (r3) 45 | cmpwi r0, 0 46 | beq- d_start_parser #If null, stop doing this ofc 47 | cmpwi r0, ccomment #Check for 1st comment symbol of line 48 | beq- codetxthandle_hashtagged_comment 49 | cmpwi r0, cslash 50 | bne+ codetxtchange_comments_to_spaces 51 | #At this point, we may be in a chain-type comment 52 | lbz r0, 0x1 (r3) 53 | cmpwi r0, casterisk 54 | bne- codetxtchange_comments_to_spaces 55 | 56 | #Now we are on a chain comment 57 | #Write over slash asterisk first 58 | stb r4, 0 (r3) 59 | stbu r4, 0x1 (r3) 60 | lbzu r0, 0x1 (r3) 61 | cmpwi r0, casterisk #if asterisk is hit we may be at end of chain comment 62 | stb r4, 0 (r3) #No matter what, this must be done. Overwrite current char with space 63 | bne+ -0xC 64 | lbz r0, 0x1 (r3) #asterisk was current char, very next char must be the slash 65 | cmpwi r0, cslash 66 | bne+ -0x18 67 | stbu r4, 0x1 (r3) #Overwrite slash and update cursor to comply with loop 68 | b codetxtchange_comments_to_spaces 69 | 70 | #Now we are on a hashtag-type comment 71 | #Write over comment symbol first 72 | codetxthandle_hashtagged_comment: 73 | stb r4, 0 (r3) 74 | #Now check for enter, once we hit enter go back to prev loop 75 | lbzu r0, 0x1 (r3) 76 | cmpwi r0, center 77 | beq- codetxtchange_comments_to_spaces 78 | #Enter not found yet, overwrite char/symbol with space 79 | stb r4, 0 (r3) 80 | b -0x10 #Go back to checking for enter again 81 | 82 | #Set counter to know how much to subtract from r29 which will be used as setup for memmove r4 arg 83 | d_start_parser: 84 | li r6, 0 85 | 86 | #Setup r31 for loop 87 | addi r31, r31, -1 88 | 89 | #Loop2 90 | codetxtparser_loop: 91 | lbzu r0, 0x1 (r31) 92 | addi r6, r6, 1 93 | cmpwi r0, 0 94 | beq- codetxtparser_epilogue 95 | cmpwi r0, cspace 96 | beq- codetxtparser_setup_memmove 97 | cmpwi r0, center 98 | beq- codetxtparser_setup_memmove 99 | cmpwi r0, ctab 100 | bne+ codetxtparser_loop 101 | 102 | #Memmove 103 | #r3 = Destination Addr 104 | #r4 = Source Addr 105 | #r5 = Size in bytes 106 | codetxtparser_setup_memmove: 107 | mr r3, r31 108 | addi r4, r31, 1 109 | sub r30, r30, r6 110 | mr r5, r30 111 | bl memmove 112 | li r6, 0 #Reset r6 113 | subi r31, r31, 1 #Update cursor to correct spot now that contents have shifted left 1 byte 114 | b codetxtparser_loop 115 | 116 | #Epilogue 117 | codetxtparser_epilogue: 118 | lwz r30, 0x8 (sp) 119 | lwz r31, 0xC (sp) 120 | lwz r0, 0x0014 (sp) 121 | mtlr r0 122 | addi sp, sp, 0x0010 123 | blr 124 | -------------------------------------------------------------------------------- /HBC-Source/build/codetxtpostparsersize.s: -------------------------------------------------------------------------------- 1 | .file "codetxtpostparsersize.c" 2 | .machine ppc 3 | .section ".text" 4 | .ident "GCC: (devkitPPC release 44.2) 13.2.0" 5 | 6 | #Simple func to calculate file size, EXcluding null byte 7 | #r3 = pointer to code.txt 8 | #r3 returns byte size 9 | 10 | .globl codetxtpostparsersize 11 | codetxtpostparsersize: 12 | addi r4, r3, -1 13 | lbzu r0, 0x1 (r4) 14 | cmpwi r0, 0 15 | bne+ -0x8 16 | sub r3, r4, r3 17 | blr 18 | -------------------------------------------------------------------------------- /HBC-Source/build/disassemble.s: -------------------------------------------------------------------------------- 1 | .file "disassemble.c" 2 | .machine ppc 3 | .section ".text" 4 | .ident "GCC: (devkitPPC release 44.2) 13.2.0" 5 | 6 | #Disassemble Func (void) 7 | #r3 returns 0 for success, any negative number is error 8 | 9 | #Open source.s to make sure one doesn't exist 10 | #Open dbin.bin, get size, alloc mem, dump, close 11 | #Open code.txt, get size, alloc mem, dump, close 12 | #Multiply code.txt's size by 13 for estimated size of to-be-generated source.s 13 | #Mem alloc for estimated size 14 | #Update cache for dbin.bin since we will execute it 15 | #Run waltress dbin.bin 16 | #Create source.s, write to it, close, success 17 | 18 | #r31 = fp, then source.s pointer 19 | #VOID NOW r30 = dbin.bin size 20 | #VOID NOW r29 = dbin.bin pointer 21 | #r28 = code.txt size 22 | #r27 = code.txt pointer 23 | #r26 = Header flag, 0 = raw, 1 = 04,06,C2, 2 = C0 24 | #r23 thru r25 = Gecko Header (ASCII) 25 | #r22 = r31 (net; factoring in gecko header) 26 | 27 | #Directives 28 | sources: 29 | .asciz "source.s" 30 | codetxt: 31 | .asciz "code.txt" 32 | rb: 33 | .asciz "rb" 34 | wb: 35 | .asciz "wb" 36 | dfopensourceEC: 37 | .asciz "\n\nError! Source.s already exists. Delete it and try again.\n\n" 38 | dfopencodetxtEC: 39 | .asciz "\n\nError! Can't find code.txt. This file needs to be present for disassembling. Is the file named incorrectly?\n\n" 40 | dfseekcodetxtEC: 41 | .asciz "\n\nError! fseek failure on code.txt.\n\n" 42 | dmemaligncodetxtEC: 43 | .asciz "\n\nError! Can't allocate memory for code.txt.\n\n" 44 | dfreadcodetxtEC: 45 | .asciz "\n\nError! Unable to dump code.txt to memory.\n\n" 46 | dfclosecodetxtEC: 47 | .asciz "\n\nError! Can't close code.txt.\n\n" 48 | dgeckoheaderEC: 49 | .asciz "\n\nError! The Gecko Header is not the correct format or an unsupported Header type is being used.\n\n" 50 | dsavestripmallocEC: 51 | .asciz "\n\nError! Can't allocate memory within the Save and Strip Gecko Header subroutine.\n\n" 52 | dcodetxt2binEC: 53 | .asciz "\n\nError! Either a sscanf failure occurred within the codetxt2bin subroutine, or somehow code.txt (after the codetxtpostparsersize subroutine) has a size that isn't divisible by 4. Please report this Error at MarioKartWii.com!\n\n" 54 | dmemalignTOBEsourceEC: 55 | .asciz "\n\nError! Can't allocate memory for future source.s.\n\n" 56 | dprepwaltressdbinEC: 57 | .asciz "\n\nError! One the following scenarios has occurred. The 06 line amount designator byte is an incorrect value, the C0 line amount designator byte is an incorrect value, or the C2 line amount designator byte is an incorrect value.\n\n" 58 | dwaltressSprintfFailureEC: 59 | .asciz "\n\nError! A sprintf failure occurred when Waltress tried disassembling one of the instruction(s). This should never occur. Please report this Error at MarioKartWii.com!\n\n" 60 | dfcreatesourceEC: 61 | .asciz "\n\nError! Can't create new source.s. If you are using the Desktop Version, make sure the DV folder has user permissions enabled.\n\n" 62 | dfwritesourceEC: 63 | .asciz "\n\nError! Can't write content to newly created source.s.\n\n" 64 | dfclosesourceEC: 65 | .asciz "\n\nError! Can't close new source.s.\n\n" 66 | 67 | .align 2 68 | 69 | #Prologue 70 | .globl disassemble 71 | disassemble: 72 | stwu sp, -0x0040 (sp) 73 | mflr r0 74 | stmw r20, 0x10 (sp) 75 | stw r0, 0x0044 (sp) 76 | 77 | #Open source.s, one shouldn't exist 78 | lis r3, sources@h 79 | lis r4, rb@h 80 | ori r3, r3, sources@l 81 | ori r4, r4, rb@l 82 | bl fopen 83 | cmpwi r3, 0 84 | lis r3, dfopensourceEC@h 85 | ori r3, r3, dfopensourceEC@l 86 | bne- disassemble_error #YES this is bne! We don't want file to exist 87 | 88 | #Open code.txt 89 | lis r3, codetxt@h 90 | lis r4, rb@h 91 | ori r3, r3, codetxt@l 92 | ori r4, r4, rb@l 93 | bl fopen 94 | mr. r31, r3 95 | lis r3, dfopencodetxtEC@h 96 | ori r3, r3, dfopencodetxtEC@l 97 | beq- disassemble_error 98 | 99 | #Get size of code.txt 100 | mr r3, r31 101 | li r4, 0 102 | li r5, 2 #Seek end 103 | bl fseek 104 | cmpwi r3, 0 105 | lis r3, dfseekcodetxtEC@h 106 | ori r3, r3, dfseekcodetxtEC@l 107 | bne- disassemble_error 108 | mr r3, r31 109 | bl ftell #No error check for this 110 | 111 | #Rewind file stream position 112 | #Alloc mem for code.txt 113 | #*NOTE* We have code.txt filesize but future custom subfuncs require the file ends in a null byte, therefore add 1 to the file size before calling memalign. 114 | addi r28, r3, 1 115 | mr r3, r31 116 | bl rewind #No error check for this 117 | li r3, 32 118 | mr r4, r28 119 | bl memalign 120 | mr. r27, r3 121 | lis r3, dmemaligncodetxtEC@h 122 | ori r3, r3, dmemaligncodetxtEC@l 123 | beq- disassemble_error 124 | 125 | #Dump code.txt, close 126 | mr r3, r27 127 | li r4, 1 128 | subi r5, r28, 1 #This is because we added 1 fake byte from earlier!!! 129 | mr r6, r31 130 | bl fread 131 | subi r0, r28, 1 132 | cmpw r3, r0 133 | lis r3, dfreadcodetxtEC@h 134 | ori r3, r3, dfreadcodetxtEC@l 135 | bne- disassemble_error 136 | mr r3, r31 137 | bl fclose 138 | cmpwi r3, 0 139 | lis r3, dfclosecodetxtEC@h 140 | ori r3, r3, dfclosecodetxtEC@l 141 | bne- disassemble_error 142 | 143 | #Append null byte to end of file, this is needed for future funcs 144 | subi r3, r28, 1 145 | li r4, 0 146 | stbx r4, r3, r27 147 | 148 | #Patch carriages 149 | mr r3, r27 150 | bl newline_fixer 151 | 152 | #Get the Gecko Header type from code.txt 153 | #-1 = Invalid 154 | #0 = Raw 155 | #1 = C2 156 | #2 = 04 157 | #3 = 06 158 | #4 = C0 159 | mr r3, r27 160 | bl get_geckoheadertype 161 | mr. r22, r3 162 | lis r3, dgeckoheaderEC@h 163 | ori r3, r3, dgeckoheaderEC@l 164 | blt- disassemble_error 165 | beq- skip_codetxt_geckostripper 166 | 167 | #Call func that saves gecko header then overwrites it with spaces 168 | #r3 returns malloced space where header is saved at 169 | #r3 arg = gecko header type 170 | #r4 arg = code.txt ptr, code.txt must end in null byte 171 | mr r3, r22 172 | mr r4, r27 173 | bl saveANDoverwrite_geckoheader 174 | mr. r20, r3 175 | lis r3, dsavestripmallocEC@h 176 | ori r3, r3, dsavestripmallocEC@l 177 | beq- disassemble_error 178 | 179 | #Call the code.txt parser to remove all spaces, enters, tabs, and comments 180 | #r3 = pointer to code.txt, must end in null 181 | #r4 = size of code.txt plus null byte 182 | skip_codetxt_geckostripper: 183 | mr r3, r27 184 | mr r4, r28 #TODO fix me, r28 is incorrect (needs to be decremented) but it actually doesn't matter, func will still work correctly 185 | bl codetxtparser #No error check for this 186 | 187 | #Gen post parser code.txt size (EXclude null byte on count) 188 | mr r3, r27 189 | bl codetxtpostparsersize 190 | mr r25, r3 #Save in r25, no error check for this func 191 | 192 | #Transform code.txt to a temporary code.bin, yuck 193 | #r3 = code.txt pointer 194 | #r4 = code.txt post-parsed size excluding null byte (must exclude because r4 needs to be divisible by 8) 195 | mr r3, r27 196 | mr r4, r25 197 | bl codetxt2bin 198 | cmpwi r3, 0 199 | lis r3, dcodetxt2binEC@h 200 | ori r3, r3, dcodetxt2binEC@l 201 | bne- disassemble_error #Carry return error from codetxt2bin to parent func 202 | 203 | #Using code.txt post parser size, use that to generate safe upper bound range 204 | #for memalign size for to-be-genned source.s 205 | #Longest possible line is 36 bytes 206 | #36 / 8 = 4.5 207 | #Take code.txt post parser size times 5. Then finally add 10 bytes for possible Header 208 | mulli r5, r25, 5 #Yuck 209 | addi r4, r5, 10 210 | li r3, 32 211 | bl memalign 212 | mr. r31, r3 213 | lis r3, dmemalignTOBEsourceEC@h 214 | ori r3, r3, dmemalignTOBEsourceEC@l 215 | beq- disassemble_error 216 | 217 | #Prep for Engine. 218 | #r3 = code.bin pointer 219 | #r4 = code.TXT size (***NOT** .bin size, it hasn't yet been calc'd) 220 | #r5 = gecko type 221 | #Func returns... 222 | #r3 = new code.bin pointer 223 | #r4 = loop/instruction amount for 224 | mr r3, r27 225 | mr r4, r25 226 | mr r5, r22 227 | bl prep_waltress_dbin 228 | cmpwi r3, 0 #r3 == 0 is only possible if 06 byte amount is *not* divisible by 4 229 | addi r24, r3, -4 #Decrement for waltress din bin loop 230 | lis r3, dprepwaltressdbinEC@h 231 | ori r3, r3, dprepwaltressdbinEC@l 232 | beq- disassemble_error 233 | mr r25, r4 #Loop counter GVR 234 | mr r21, r4 #Need instruction amount for later, save again in diff GVR 235 | mr r23, r31 #Make copy of source.s pointer 236 | 237 | #RUN WALTRESS DASM ENGINE 238 | #r3 = source.s ptr (output addr) 239 | #r4 = instruction (input value) 240 | 241 | run_waltress_dbin_bin: 242 | lwzu r4, 0x4 (r24) 243 | mr r3, r23 244 | bl dasm_engine # :) 245 | cmpwi r3, 0 246 | beq+ its_the_waltress 247 | 248 | lis r3, dwaltressSprintfFailureEC@h 249 | ori r3, r3, dwaltressSprintfFailureEC@l 250 | b disassemble_error 251 | 252 | its_the_waltress: 253 | subic. r25, r25, 1 254 | #Find null on newly printed source line at source.s, so we know how much to increment r23 for next go around 255 | lbzu r0, 0x1 (r23) 256 | cmpwi cr7, r0, 0 257 | bne+ cr7, -0x8 258 | #r23 needs to be incremented by 1 259 | addi r23, r23, 1 260 | bne+ run_waltress_dbin_bin 261 | 262 | #Fyi waltress stores null byte to every output string 263 | #Now we just need to replace all null bytes (except last one) with spaces and enters 264 | #Spaces are for odd instructions, enters for even, null byte at very end 265 | mr r3, r31 266 | mr r4, r21 267 | bl fixwaltress_nulls #No error check 268 | 269 | #Get length of new source.s (EXclude null byte ender) 270 | addi r3, r31, -1 271 | li r28, 0 #We don't have any more need for r28, free to use now 272 | lbzu r0, 0x1 (r3) 273 | cmpwi r0, 0 274 | beq- 0xC 275 | addi r28, r28, 1 276 | b -0x10 277 | 278 | #Now add back in gecko header carried over from code.txt 279 | cmpwi r22, 0 #If Raw, skip ofc 280 | beq- create_sources 281 | 282 | #r3 = pointer to source.s 283 | #r4 = source.s size EXcluding null 284 | #r5 = pointer to gecko header 285 | #r6 = gecko header type 286 | #r3 returns updated size that EXcludes null 287 | mr r3, r31 288 | mr r4, r28 289 | mr r5, r20 290 | mr r6, r22 291 | bl add_header 292 | mr r28, r3 293 | 294 | #Create finished source.s 295 | #r28 contains size EXcluding null byte 296 | create_sources: 297 | lis r3, sources@h 298 | lis r4, wb@h 299 | ori r3, r3, sources@l 300 | ori r4, r4, wb@l 301 | bl fopen 302 | mr. r29, r3 303 | lis r3, dfcreatesourceEC@h 304 | ori r3, r3, dfcreatesourceEC@l 305 | beq- disassemble_error 306 | li r4, 1 307 | mr r3, r31 308 | mr r5, r28 #Count (real size) 309 | mr r6, r29 310 | bl fwrite 311 | cmpw r3, r28 312 | lis r3, dfwritesourceEC@h 313 | ori r3, r3, dfwritesourceEC@l 314 | bne- disassemble_error 315 | mr r3, r29 316 | bl fclose 317 | cmpwi r3, 0 318 | lis r3, dfclosesourceEC@h 319 | ori r3, r3, dfclosesourceEC@l 320 | bne- disassemble_error 321 | 322 | #TODO add in code to free up allocated blocks of mem 323 | 324 | #Success! 325 | li r3, 0 326 | 327 | disassemble_error: 328 | lwz r0, 0x0044 (sp) 329 | lmw r20, 0x10 (sp) 330 | mtlr r0 331 | addi sp, sp, 0x0040 332 | blr 333 | -------------------------------------------------------------------------------- /HBC-Source/build/finalize_assembled_bin.s: -------------------------------------------------------------------------------- 1 | .file "finalize_assembled_bin.c" 2 | .machine ppc 3 | .section ".text" 4 | .ident "GCC: (devkitPPC release 44.2) 13.2.0" 5 | 6 | #Func (right after waltress abin completes) 7 | 8 | #r3 = code.bin raw size calc (this div'd by 4 = amount of instructions) 9 | #r4 = code.bin pointer 10 | #r5 = codetype 11 | #r6 = gecko header pointer 12 | #r3 returns new code.bin size 13 | 14 | #NOTE net instruction amount = total word amount of final code.bin, includes headers, footers etc 15 | #raw size anything = without any gecko shit 16 | 17 | .globl finalize_assembled_bin 18 | finalize_assembled_bin: 19 | #For the case that if somehow this func gets called with RAW, If r5 = 0, simple end func 20 | cmpwi r5, 0 21 | beqlr- 22 | 23 | #Look for C0 next, cuz it needs no stack shit 24 | cmpwi r5, 4 25 | bne- this_is_gonna_suck 26 | 27 | #C0 codetype found 28 | #Write header 29 | Cohohoh: 30 | lis r0, 0xC000 31 | stw r0, 0 (r4) 32 | #If byte size end in 0x0 or 0x8, we need to add whole new line (blr + null word) 33 | #If byte size end in 0x4 or 0xC, we need to add just blr to current last line 34 | andi. r0, r3, 0x4 35 | lis r0, 0x4E80 36 | ori r0, r0, 0x0020 37 | addi r3, r3, 8 #No matter what add 8 to byte amount cuz C0 header and lineamount word holder 38 | stwx r0, r3, r4 #No matter what write the blr 39 | bne- add_four_for_blr 40 | li r0, 0 41 | addi r3, r3, 4 #Add 4 for byte amount for null 42 | stwx r0, r3, r4 43 | add_four_for_blr: 44 | addi r3, r3, 4 #Add 4 for byte amount for blr 45 | #Write in line amount [(current net byte amount - 8) / 8] 46 | subi r5, r3, 8 47 | srawi r0, r5, 3 48 | stw r0, 0x4 (r4) 49 | #r3 ready to return 50 | blr 51 | 52 | #C2/04/06 found, great... lol 53 | this_is_gonna_suck: 54 | stwu sp, -0x0020 (sp) 55 | mflr r0 56 | stw r28, 0x10 (sp) 57 | stw r29, 0x14 (sp) 58 | stw r30, 0x18 (sp) 59 | stw r31, 0x1C (sp) 60 | stw r0, 0x0020 (sp) 61 | 62 | #Backup args 63 | mr r31, r3 64 | mr r30, r4 65 | mr r29, r5 66 | mr r28, r6 67 | 68 | #First change header to binary and store 69 | #Sub func 70 | #r3 = pointer to header 71 | #r3 returns header word in hex 72 | mr r3, r6 73 | bl ascii2hexPARENT #Making this a func so its not cluttered in my way and shit 74 | stw r3, 0 (r30) 75 | 76 | #check codetypes again 77 | cmpwi r29, 1 78 | beq- Ctwotwotwo 79 | cmpwi r29, 2 80 | li r3, 8 81 | beq- finalassemepipen #nothing left to do if 04 codetype 82 | 83 | #06 codetype found 84 | #If byte size end in 0x0 or 0x8, do nothing 85 | #If byte size end in 0x4 or 0xC, we need to add just null word to current last line 86 | andi. r0, r31, 0x4 87 | stw r31, 0x4 (r30) #No matter what write net byte amount in 06byteamount holder 88 | addi r31, r31, 8 #No matter what add 8 to byte amount cuz 06 header and byteamount word holder 89 | beq- just_move_r31 90 | li r0, 0 91 | stwx r0, r31, r30 #Write the null 92 | addi r3, r31, 4 #Add 4 to byte amount cuz null word, return in r3 93 | b finalassemepipen 94 | just_move_r31: 95 | mr r3, r31 #Do NOT add 4 to byte amount. we DONT have added null word. Copy r31 to r3 and return 96 | b finalassemepipen 97 | 98 | #C2 codetype found 99 | #Write header 100 | #r5 = instruction amount that gets updated over time, at end we will mulli by 4 to get net code.bin size 101 | Ctwotwotwo: 102 | #If byte size end in 0x0 or 0x8, we need to add whole new line (nop + null word) 103 | #If byte size end in 0x4 or 0xC, we need to add just null word to current last line 104 | andi. r0, r31, 0x4 105 | li r4, 0 #r4 will write the null word 106 | addi r31, r31, 8 #No matter what add 8 to byte amount cuz C2 header and lineamount word holder 107 | bne- add_c2nullender 108 | lis r0, 0x6000 109 | stwx r0, r31, r30 110 | addi r31, r31, 4 #Add 4 to byte amount cuz nop was needed 111 | add_c2nullender: 112 | stwx r4, r31, r30 113 | addi r31, r31, 4 #Add 4 to byte amount cuz null word no matter what 114 | #Write in line amount [(current net byte amount - 8) / 8] 115 | subi r5, r31, 8 116 | srawi r0, r5, 3 117 | stw r0, 0x4 (r30) 118 | #move r31 to r3 119 | mr r3, r31 120 | 121 | #Epilogue for when codetype is C2/04/06 122 | finalassemepipen: 123 | lwz r0, 0x0020 (sp) 124 | lwz r31, 0x1C (sp) 125 | lwz r30, 0x18 (sp) 126 | lwz r29, 0x14 (sp) 127 | lwz r28, 0x10 (sp) 128 | mtlr r0 129 | addi sp, sp, 0x0020 130 | blr 131 | 132 | #Parent routine for converting header from ascii to hex 133 | #r3 arg = ptr to gecko header 134 | #r3 returns gecko header in hex (word) 135 | ascii2hexPARENT: 136 | li r0, 8 137 | li r4, 28 #Amount to shift left by 138 | li r5, 0 #Clear out register for shift+save usage 139 | mtctr r0 140 | as2hexloop: 141 | lbzu r6, 0x1 (r3) 142 | ## 143 | ascii2hex: 144 | cmplwi r6, 0x3A 145 | blt- cleartodigit 146 | cmplwi r6, 0x60 147 | bgt- sub0x57 148 | #sub 0x37 149 | subi r6, r6, 0x37 150 | b shifty_shift 151 | sub0x57: 152 | subi r6, r6, 0x57 153 | b shifty_shift 154 | cleartodigit: 155 | andi. r6, r6, 0xF 156 | ## 157 | shifty_shift: 158 | slw r6, r6, r4 159 | or r5, r6, r5 160 | subi r4, r4, 4 #Decrement shift-left amount 161 | bdnz+ as2hexloop 162 | mr r3, r5 163 | blr 164 | 165 | -------------------------------------------------------------------------------- /HBC-Source/build/fix_neg_hex.s: -------------------------------------------------------------------------------- 1 | .file "fix_neg_hex.c" 2 | .machine ppc 3 | .section ".text" 4 | .ident "GCC: (devkitPPC release 44.2) 13.2.0" 5 | 6 | fixneghexEC: 7 | .asciz "\n\nError! For whatever reason, the malloc function failed within the fix_neg_hex.s subroutine." 8 | .align 2 9 | 10 | #r3 = Ptr to source.s 11 | #r3 returns 0 for success or addr to return a message for printing back to parent 12 | 13 | .globl fix_neg_hex 14 | fix_neg_hex: 15 | #Prologue 16 | stwu sp, -0x0030 (sp) 17 | mflr r0 18 | stw r27, 0x1C (sp) #0x8 thru 0x11 is buffer space (10 bytes) 19 | stw r28, 0x20 (sp) 20 | stw r29, 0x24 (sp) 21 | stw r30, 0x28 (sp) 22 | stw r31, 0x2C (sp) 23 | stw r0, 0x0034 (sp) 24 | 25 | #Save arg 26 | mr r31, r3 27 | 28 | #Pre decrement loading addr 29 | subi r30, r3, 1 30 | 31 | #ROOT LOOP 32 | fix_neg_hex_ROOT_loop: 33 | lwzu r0, 0x1 (r30) 34 | srwi. r3, r0, 24 #Check for null byte by removing 3 far side right bytes 35 | beq- fix_neg_hex_success 36 | 37 | #Set constant to compare to 38 | lis r3, 0x002D 39 | ori r3, r3, 0x3078 40 | 41 | #Verify against constant 42 | srwi r4, r0, 8 43 | cmpw r3, r4 44 | bne+ fix_neg_hex_ROOT_loop 45 | 46 | #Found negative hex SIMM! 47 | #NOTE First make sure we *SKIP* condi branches 48 | #Make copy of cursor and go back to first enter before current instruction, or SoF-1 (start of file minus 1) 49 | mr r3, r30 50 | lbzu r0, -0x1 (r3) 51 | cmplw r3, r31 52 | blt- 0x10 53 | cmpwi r0, 0xA 54 | beq- 0x8 55 | b -0x14 56 | #Okay we are at \n or at SoF-1, now check if next line instruction was a condi branch 57 | lhz r0, 0x1 (r3) 58 | cmpwi r0, 0x6267 #bg 59 | beq- fix_neg_hex_ROOT_loop 60 | cmpwi r0, 0x6265 #be 61 | beq- fix_neg_hex_ROOT_loop 62 | cmpwi r0, 0x626E #bn 63 | beq- fix_neg_hex_ROOT_loop 64 | cmpwi r0, 0x6264 #bd 65 | beq- fix_neg_hex_ROOT_loop 66 | cmpwi r0, 0x626C #bl 67 | beq- check_for_t_or_e 68 | cmpwi r0, 0x6273 69 | bne+ not_a_condi_branch 70 | #bs found, if char after bs is o, then abort. its a condi branch 71 | lbz r0, 0x3 (r3) 72 | cmpwi r0, 0x6F #o 73 | beq- fix_neg_hex_ROOT_loop 74 | b not_a_condi_branch 75 | check_for_t_or_e: 76 | lbz r0, 0x3 (r3) 77 | cmpwi r0, 0x74 #t 78 | beq- fix_neg_hex_ROOT_loop 79 | cmpwi r0, 0x65 #e 80 | beq- fix_neg_hex_ROOT_loop 81 | 82 | #Okay perfect negative SIMM is *NOT* for a condi branch, good to proceed. 83 | #Count the amount of hexanumerical ascii digits til non-hexanumerical 84 | not_a_condi_branch: 85 | addi r3, r30, 2 #Point to "x" so first load is the first SIMM digit 86 | digit_width_loop: 87 | lbzu r0, 0x1 (r3) 88 | cmplwi r0, 0x2F #0; look for gt 89 | cmplwi cr1, r0, 0x3A #9; look for lt 90 | cmplwi cr4, r0, 0x40 #A; look for gt 91 | cmplwi cr5, r0, 0x47 #F; look for lt 92 | cmplwi cr6, r0, 0x60 #a; look for gt 93 | cmplwi cr7, r0, 0x67 #f; look for lt 94 | #. IF byte (> 2F && < 3A) || (> 40 && < 47) || (> 60 && < 67), then its a hex byte 95 | crand 4*cr0+eq, 4*cr0+gt, 4*cr1+lt #Don't want a crap ton of branch routes, yes this is SLOW 96 | crand 4*cr4+eq, 4*cr4+gt, 4*cr5+lt 97 | crand 4*cr6+eq, 4*cr6+gt, 4*cr7+lt 98 | cror 4*cr0+eq, 4*cr0+eq, 4*cr4+eq 99 | cror 4*cr0+eq, 4*cr0+eq, 4*cr6+eq 100 | beq+ digit_width_loop 101 | 102 | #Get count 103 | sub r29, r3, r30 104 | 105 | #Change negative ascii to temp positive 106 | #Change temp pos ascii to temp pos hex int 107 | #Flip pos hex int to neg (unsigned eqiv) 108 | #Change neg int to final unsigned ascii 109 | addi r3, r30, 3 110 | subi r4, r29, 3 #Discount the "-0x" portion 111 | bl fixneghex_ascii2hex #r3 = src addr, r4 = amount of digits to convert, r3 returns hex word 112 | #Neg it! 113 | neg r3, r3 114 | #Flip back to ascii 115 | addi r4, sp, 8 116 | bl fixneghex_hex2ascii 117 | 118 | #Do Size minus 10 119 | subic. r3, r29, 10 120 | beq- transfer_the_new_simm 121 | 122 | #No matter what, we need source.s plus Null byte length 123 | #Keep cr0 and r3 intact 124 | subi r4, r31, 1 125 | lbzu r0, 0x1 (r4) 126 | cmpwi cr7, r0, 0 127 | bne+ cr7, -0x8 128 | sub r4, r4, r31 129 | addi r28, r4, 1 #Count null byte and save size to r28 130 | 131 | #Now branch (cr7) on whether or not we malloc 132 | bgt- we_DONT_need_malloc 133 | 134 | #Call malloc, and adjust global r27 register (global source.s ptr) 135 | sub r3, r28, r3 #r3 (delta) is negative, so a subtraction will yield an addition 136 | bl malloc 137 | mr. r27, r3 138 | beq- fix_neg_hex_malloc_ec_string_lock 139 | #Memcpy source.s to malloc'd space 140 | mr r4, r31 141 | mr r5, r28 142 | bl memcpy 143 | 144 | #Change GLOBAL r27 with local r27. THIS IS A GLOBAL CHANGE! 145 | stw r27, 0x1C (sp) 146 | #Fix r30 (-0xXXX... ptr) 147 | sub r3, r30, r31 148 | add r30, r27, r3 149 | #Fix this func's r31 (source.s ptr) 150 | mr r31, r27 151 | #Now we can memmove, yay 152 | 153 | we_DONT_need_malloc: 154 | #Memmove portion of file to right to free up inner space to insert 0x00000000 over -0xX... 155 | #r3 = dest; 156 | #r4 = src; where the comma is located (r30) 157 | #r5 = amt (null byte ptr minus src ptr) + 1 158 | add r4, r30, r29 #-0xXX ptr + SIMM width size = src ptr 159 | addi r3, r30, 10 #Okay to hardcode since all newly gen'd SIMMs with be 10 digits in width 160 | add r5, r31, r28 #r5 at this moment = one past PAST null byte ptr 161 | sub r5, r5, r4 #One-past-Null byte ptr - Src ptr = amount to move 162 | bl memmove 163 | 164 | #Transfer newly gen'd SIMM from stack buffer to its spot in updated source.s 165 | #r3 needs to be setup before this section is executed 166 | transfer_the_new_simm: 167 | li r0, 5 #5 halfwords to transfer 168 | addi r3, sp, 6 #r4 is same no matter circumstance 169 | mtctr r0 170 | subi r4, r30, 2 171 | lhzu r0, 0x2 (r3) 172 | sthu r0, 0x2 (r4) 173 | bdnz+ -0x8 174 | b fix_neg_hex_ROOT_loop 175 | 176 | fix_neg_hex_malloc_ec_string_lock: 177 | lis r3, fixneghexEC@h 178 | ori r3, r3, fixneghexEC@l 179 | b 0x8 180 | 181 | #Return 182 | fix_neg_hex_success: 183 | li r3, 0 184 | lwz r0, 0x0034 (sp) 185 | lwz r31, 0x2C (sp) 186 | lwz r30, 0x28 (sp) 187 | lwz r29, 0x24 (sp) 188 | lwz r28, 0x20 (sp) 189 | lwz r27, 0x1C (sp) 190 | mtlr r0 191 | addi sp, sp, 0x0030 192 | blr 193 | 194 | fixneghex_hex2ascii: 195 | #Write "0x" 196 | li r0, 0x3078 197 | sth r0, 0 (r4) 198 | #Set loop amount 199 | li r0, 8 200 | mtctr r0 201 | #Set initial shiftor amount 202 | li r5, 32 203 | #Adjust r4 for when we stbu the ascii byte 204 | addi r4, r4, 1 205 | #Loop 206 | fixneghex_hex2ascii_loop: 207 | #Update shiftor amount 208 | subi r5, r5, 4 209 | #Extract digit 210 | srw r0, r3, r5 211 | clrlwi r6, r0, 28 212 | #Convert from digit hex to byte ascii 213 | cmplwi r6, 9 214 | bgt- 0xC 215 | ori r7, r6, 0x30 216 | b 0x8 217 | addi r7, r6, 0x37 218 | #Store converted byte to buffer 219 | stbu r7, 0x1 (r4) 220 | #Decrement loop 221 | bdnz+ fixneghex_hex2ascii_loop 222 | #End func 223 | blr 224 | 225 | fixneghex_ascii2hex: #r3 = src addr of SIMM hex word, r4 = digit length 226 | mtctr r4 227 | slwi r5, r4, 2 #r4 x 4 = start-off slw shiftor amount (r5) 228 | subi r4, r3, 1 229 | li r3, 0 #Register used to "compile" word 230 | fixneghex_ascii2hex_looppp: 231 | lbzu r6, 0x1 (r4) 232 | cmplwi r6, 0x39 233 | subi r5, r5, 4 #update shiftor amount 234 | bgt- 0xC 235 | clrlwi r6, r6, 28 #change 0x30 thru 0x39 to 0x0 thru 0x9 236 | b place_hex_digit_to_proper_slot 237 | cmplwi r6, 0x46 238 | bgt- 0xC 239 | subi r6, r6, 0x37 #Change 0x61 thru 0x66 to 0xA thru 0xF 240 | b place_hex_digit_to_proper_slot 241 | subi r6, r6, 0x57 #Change 0x41 thru 0x46 to 0xA thru 0xF 242 | place_hex_digit_to_proper_slot: 243 | slw r6, r6, r5 #Place hex digit into its proper slot 244 | or r3, r3, r6 #"compile" hexword 245 | bdnz+ fixneghex_ascii2hex_looppp 246 | blr 247 | -------------------------------------------------------------------------------- /HBC-Source/build/fixwaltress_nulls.s: -------------------------------------------------------------------------------- 1 | .file "fixwaltress_nulls.c" 2 | .machine ppc 3 | .section ".text" 4 | .ident "GCC: (devkitPPC release 44.2) 13.2.0" 5 | 6 | #Func is meant to fix source.s after dbin.bin 7 | #Replace all gen'd null bytes with 0x20 and 0xA. end in final null 8 | #r3 = Pointer to newly gen source.s 9 | #r4 = number of instructions 10 | 11 | #TODO maybe write in code to check if r4 = 1 then simply blr back! 12 | 13 | .globl fixwaltress_nulls 14 | fixwaltress_nulls: 15 | li r5, 0xA 16 | li r6, 0 17 | mtctr r4 18 | 19 | #Find the next null byte, once found decrement CTR, if CTR zero, skip 'fix', we are eof 20 | fixwaltress_nulls_loop: 21 | lbzu r0, 0x1 (r3) #No need to pre-decrement, no source.s line is a byte long 22 | cmpwi r0, 0 23 | bne+ fixwaltress_nulls_loop 24 | 25 | #Found Waltress-created null byte, apply "enter" 26 | stb r5, 0 (r3) 27 | 28 | #Decrement 29 | bdnz+ fixwaltress_nulls_loop 30 | li r0, 0 #Store final final null byte, overwrites most recent newly written 0xA ofc. *NOTE* this is important as it ensures final string is terminated, sanity for overflow 31 | stb r0, 0 (r3) 32 | blr 33 | -------------------------------------------------------------------------------- /HBC-Source/build/gencodebinsize.s: -------------------------------------------------------------------------------- 1 | .file "gencodebinsize.c" 2 | .machine ppc 3 | .section ".text" 4 | .ident "GCC: (devkitPPC release 44.2) 13.2.0" 5 | 6 | #Function will return the size of to-be-genned code.bin using source.s's amount of Enters 7 | #r3 arg = pointer to source.s 8 | #r3 returns code.bin size 9 | 10 | .globl gencodebinsize 11 | gencodebinsize: 12 | addi r4, r3, -1 13 | li r3, 0 14 | gencodebinsizeloop: 15 | lbzu r0, 0x1 (r4) 16 | cmpwi r0, 0 17 | beqlr- 18 | cmpwi r0, 0xA 19 | bne+ gencodebinsizeloop 20 | addi r3, r3, 4 21 | b gencodebinsizeloop 22 | -------------------------------------------------------------------------------- /HBC-Source/build/get_geckoheadertype.s: -------------------------------------------------------------------------------- 1 | .file "get_geckoheadertype.c" 2 | .machine ppc 3 | .section ".text" 4 | .ident "GCC: (devkitPPC release 44.2) 13.2.0" 5 | 6 | #Func returns Gecko Header type 7 | #r3 arg = pointer to code.txt/source.s 8 | #r3 returns.. 9 | #-1 = some header found, but invalid 10 | #0 = raw (no header) 11 | #1 = C2 12 | #2 = 04 13 | #3 = 06 14 | #4 = C0 15 | 16 | .globl get_geckoheadertype 17 | get_geckoheadertype: 18 | #Get thru any possible spaces, tabs, and enters beforehand 19 | subi r4, r3, 1 20 | lbzu r0, 0x1 (r4) 21 | cmpwi r0, 0x20 22 | beq -0x8 23 | cmpwi r0, 0x0A 24 | beq- -0x10 25 | cmpwi r0, 0x09 26 | beq- -0x18 27 | 28 | #Went thru all possible junk beforehand, now Check for Valid Header 29 | cmpwi r0, 0x21 #Check for exclamation point 30 | li r3, 0 #Raw ASM, no header 31 | bnelr- 32 | 33 | #Some header was found, is it valid? 34 | lhz r0, 0x1 (r4) 35 | li r5, 0x4332 36 | cmpw r0, r5 37 | li r3, 1 38 | beq- c20406headerfound 39 | li r6, 0x3034 40 | cmpw r0, r6 41 | li r3, 2 42 | beq- c20406headerfound 43 | li r7, 0x3036 44 | cmpw r0, r7 45 | li r3, 3 46 | beq- c20406headerfound 47 | li r8, 0x4330 48 | cmpw r0, r8 49 | li r3, -1 #Set error 50 | bnelr- #Branch to LR in invalid header with r3 -1 51 | 52 | #C0 found 53 | li r3, 4 54 | blr 55 | 56 | #Header cannot have non ascii numbers & letters within address ascii field 57 | c20406headerfound: 58 | li r6, 6 59 | mr r7, r3 #temp backup r3 60 | addi r5, r4, 2 61 | li r3, -1 #preset error 62 | mtctr r6 63 | 64 | silly_loop: 65 | lbzu r0, 0x1 (r5) 66 | cmplwi r0, 0x30 67 | bltlr- 68 | cmplwi r0, 0x66 69 | bgtlr- 70 | cmplwi r0, 0x3A 71 | blt- valid_ascii 72 | cmplwi r0, 0x60 73 | bgt- valid_ascii 74 | cmplwi r0, 0x41 75 | bltlr- 76 | cmplwi r0, 0x46 77 | bgtlr- 78 | valid_ascii: 79 | bdnz+ silly_loop 80 | 81 | #End func, recover r3 82 | mr r3, r7 83 | blr 84 | -------------------------------------------------------------------------------- /HBC-Source/build/main.s: -------------------------------------------------------------------------------- 1 | .file "main.c" 2 | .machine ppc 3 | .section ".text" 4 | .globl __eabi 5 | .section .rodata.str1.1,"aMS",@progbits,1 6 | .LC0: 7 | .asciz "\033[2;0H" 8 | .LC1: 9 | .asciz "\x1b[2J" #Reset Cursor, clear current screen contents 10 | .LC2: 11 | .asciz "\n\n /\\ /\\\n / \\____/ \\\n | |\n | @ @ |\n |___>_**_<___|\n _______======_______\n (______ ______)\n | |\n | | _\n | |_______/ |\n | |________/\n / ______ \\\n / / \\ \\\n /_/ \\_\\\nWelcome to \x1b[43m\x1b[30mWaltress\x1b[40m\x1b[37m! The PPC Assembler that's entirely handwritten in PPC! You can also assemble Gecko Codes! Read the README and NOTES.txt for more info.\n\nPress \x1b[32mA\x1b[37m to Assemble source.s to code.txt. Press \x1b[31mB\x1b[37m to Disassemble code.txt to source.s.\n\nCreated by \x1b[35mVega\x1b[37m. Version: 0.9\nPress Home/Start button to exit back to \x1b[36mHBC\x1b[37m at any time. Visit www.MarioKartWii.com for questions or bug reports." 12 | .LC3: 13 | .asciz "\n\n\x1b[32mSUCCESS!\x1b[37m\n\nPress Home/Start button to exit back to \x1b[36mHBC\x1b[37m." 14 | .LC4: 15 | .asciz "\n\nError!\n\nUnable to initiate the FAT File System.\n\nPress Home/Start button to exit back to \x1b[36mHBC\x1b[37m." 16 | .LC5: 17 | .asciz "\n\nExiting to \x1b[36mHBC\x1b[37m..." 18 | 19 | .section .text.startup,"ax",@progbits 20 | .align 2 21 | .globl main 22 | .type main, @function 23 | main: 24 | .LFB86: 25 | .cfi_startproc 26 | stwu 1,-16(1) 27 | .cfi_def_cfa_offset 16 28 | mflr 0 29 | stw 0,20(1) 30 | stmw 30,8(1) 31 | .cfi_offset 65, 4 32 | .cfi_offset 30, -8 33 | .cfi_offset 31, -4 34 | bl __eabi 35 | bl VIDEO_Init 36 | lis 31,.LANCHOR0@ha 37 | bl WPAD_Init 38 | la 30,.LANCHOR0@l(31) 39 | bl PAD_Init 40 | li 3,0 41 | bl VIDEO_GetPreferredMode 42 | stw 3,.LANCHOR0@l(31) 43 | bl SYS_AllocateFramebuffer 44 | lwz 9,.LANCHOR0@l(31) 45 | li 5,20 46 | li 4,20 47 | addis 3,3,0x4000 48 | lhz 6,4(9) 49 | lhz 7,8(9) 50 | slwi 8,6,1 51 | stw 3,4(30) 52 | bl CON_Init 53 | lwz 3,.LANCHOR0@l(31) 54 | bl VIDEO_Configure 55 | lwz 3,4(30) 56 | bl VIDEO_SetNextFramebuffer 57 | li 3,0 58 | bl VIDEO_SetBlack 59 | bl VIDEO_Flush 60 | bl VIDEO_WaitVSync 61 | lwz 9,.LANCHOR0@l(31) 62 | lwz 9,0(9) 63 | andi. 9,9,0x1 64 | beq+ 0,.L2 65 | bl VIDEO_WaitVSync 66 | .L2: 67 | #Init the Console Cursor 68 | lis 3,.LC0@ha 69 | la 3,.LC0@l(3) 70 | crxor 6,6,6 71 | bl printf 72 | 73 | #Init the FAT System 74 | bl fatInitDefault 75 | cmpwi r3, 0 76 | lis r3, .LC4@h 77 | ori r3, r3, .LC4@l 78 | beq- error_handler 79 | 80 | #Reset Cursor 81 | lis 3,.LC1@ha 82 | la 3,.LC1@l(3) 83 | crxor 6,6,6 84 | bl printf 85 | 86 | #Display the Main Menu Message 87 | lis 3,.LC2@ha 88 | la 3,.LC2@l(3) 89 | crxor 6,6,6 90 | bl printf 91 | 92 | #Main Menu Idle and Read Button Inputs 93 | main_menu: 94 | #Scan Controllers 95 | bl WPAD_ScanPads 96 | li r3, 0 97 | bl WPAD_ButtonsDown 98 | mr r31, r3 99 | bl PAD_ScanPads 100 | li r3, 0 101 | bl PAD_ButtonsDown 102 | 103 | #Check for Start/Home press 104 | andi. r0, r3, 0x1000 #GCN Start 105 | bne- leave_hbc 106 | andi. r0, r31, 0x0080 #Wheel/Chuck Home 107 | bne- leave_hbc 108 | andis. r0, r31, 0x0800 #Classic Home 109 | bne- leave_hbc 110 | #Check for A (assemble press) 111 | andi. r0, r3, 0x0100 #GCN A 112 | bne- init_asm 113 | andi. r0, r31, 0x0008 #Wheel/Chuck A 114 | bne- init_asm 115 | andis. r0, r31, 0x0010 #Classic A 116 | bne- init_asm 117 | #Check for B (disassemble press) 118 | andi. r0, r3, 0x0200 #GCN B 119 | bne- init_dasm 120 | andi. r0, r31, 0x0004 #Wheel/Chuck B 121 | bne- init_dasm 122 | andis. r0, r31, 0x0040 #Classic B 123 | beq+ sync_video 124 | 125 | #Start/Home was pressed. Reset console, send leaving message. Leave to HBC. 126 | leave_hbc: 127 | lis 3,.LC1@ha 128 | la 3,.LC1@l(3) 129 | crxor 6,6,6 130 | bl printf 131 | lis r3, .LC5@h 132 | ori r3, r3, .LC5@l 133 | crxor 6,6,6 134 | bl printf 135 | li r3, 0 136 | bl exit 137 | 138 | #A was pressed, assemble! 139 | init_asm: 140 | #Reset Cursor again and call assemble 141 | lis 3,.LC1@ha 142 | la 3,.LC1@l(3) 143 | crxor 6,6,6 144 | bl printf 145 | bl assemble 146 | cmpwi r3, 0 #r3 returns address w/ string to print if error 147 | blt- error_handler 148 | b success_handler 149 | 150 | #B was pressed, disassemble! 151 | init_dasm: 152 | #Reset Cursor again and call disassemble 153 | lis 3,.LC1@ha 154 | la 3,.LC1@l(3) 155 | crxor 6,6,6 156 | bl printf 157 | bl disassemble 158 | cmpwi r3, 0 #r3 returns address w/ string to print if error 159 | blt- error_handler 160 | 161 | #Success Handler, print success. console has already been reset 162 | success_handler: 163 | lis 3,.LC3@ha 164 | la 3,.LC3@l(3) 165 | crxor 6,6,6 166 | bl printf 167 | 168 | #Custom Wait Idle Loop 169 | custom_wait: 170 | bl VIDEO_WaitVSync 171 | #Scan Controllers 172 | bl WPAD_ScanPads 173 | li r3, 0 174 | bl WPAD_ButtonsDown 175 | mr r31, r3 176 | bl PAD_ScanPads 177 | li r3, 0 178 | bl PAD_ButtonsDown 179 | #Check for Start/Home press 180 | andi. r0, r3, 0x1000 #GCN Start 181 | bne- leave_hbc 182 | andi. r0, r31, 0x0080 #Wheel/Chuck Home 183 | bne- leave_hbc 184 | andis. r0, r31, 0x0800 #Classic Home 185 | bne- leave_hbc 186 | b custom_wait 187 | 188 | #Error Handler 189 | error_handler: 190 | #print r3 returned message. console has already been reset 191 | crxor 6,6,6 192 | bl printf 193 | b custom_wait 194 | 195 | sync_video: 196 | bl VIDEO_WaitVSync 197 | b main_menu 198 | .cfi_endproc 199 | .LFE86: 200 | .size main, .-main 201 | .section ".bss" 202 | .align 2 203 | .set .LANCHOR0,. + 0 204 | .type rmode, @object 205 | .size rmode, 4 206 | rmode: 207 | .zero 4 208 | .type xfb, @object 209 | .size xfb, 4 210 | xfb: 211 | .zero 4 212 | .ident "GCC: (devkitPPC release 44.2) 13.2.0" 213 | -------------------------------------------------------------------------------- /HBC-Source/build/newline_fixer.s: -------------------------------------------------------------------------------- 1 | .file "newline_fixer.c" 2 | .machine ppc 3 | .section ".text" 4 | .ident "GCC: (devkitPPC release 44.2) 13.2.0" 5 | 6 | #Quick hacky patch to change all Carriages to Newlines, and Carriage+Newline combos (eww Windows) to Newlines 7 | #r3 = pointer to code.txt/source.s (must end in null byte) 8 | 9 | .globl newline_fixer 10 | newline_fixer: 11 | subi r3, r3, 1 12 | li r4, 0xA 13 | lbzu r0, 0x1 (r3) 14 | cmpwi r0, 0 15 | beqlr- 16 | cmpwi r0, 0xD 17 | bne+ -0x10 18 | stb r4, 0 (r3) 19 | b -0x18 20 | 21 | 22 | -------------------------------------------------------------------------------- /HBC-Source/build/prep_waltress_dbin.s: -------------------------------------------------------------------------------- 1 | .file "prep_waltress_dbin.c" 2 | .machine ppc 3 | .section ".text" 4 | .ident "GCC: (devkitPPC release 44.2) 13.2.0" 5 | 6 | #Func will properly prep the engine to where all the parent func has to do is typical pre-decrement of 7 | #r3 = code.bin pointer 8 | #r4 = code.TXT size (***NOT** .bin size, it hasn't yet been calc'd) 9 | #r5 = gecko type 10 | 11 | #Func returns 12 | #r3 = new code.bin pointer 13 | #r4 = loop/instruction amount for waltress dasm engine 14 | 15 | #(code.txt post excluding null byte parsed size / 2) = code.bin size 16 | #code.bin size / 4 = Amount of Instruction 17 | #Raw = do nothing afterwards 18 | #!04 = lower by 1 afterwards, skip decrement of r27 19 | #!06 = read 06-specific byte count, divide by 4, increment r27 by 4 20 | #!C2 = increment r27 by 4, read C2 line count, mulli by 2. Subtract 1 for 00000000. Then read line count again, if odd and 2nd to last word is nop, subtract 1 again for GVR 21 | #!C0 = increment r27 by 4, read C0 line count, mulli by 2. Subtract 1 afterwards. Then read line count again. If odd and final final instruction is 00000000, then skip blr (2nd to last instruction), and subtract 1 again to compensate 22 | 23 | #0 = Raw 24 | #1 = C2 25 | #2 = 04 26 | #3 = 06 27 | #4 = C0 28 | 29 | .globl prep_waltress_dbin 30 | prep_waltress_dbin: 31 | cmpwi r5, 0 32 | srawi r4, r4, 3 #Divide code.TXT! size by 8 to get raw instruction amount 33 | beqlr- 34 | 35 | #Check for C2 36 | cmpwi r5, 1 37 | bne- try04 38 | 39 | #C2 codetype found 40 | #Make sure C2 line amount matches {(rawinstructionamount - 2) / 2} 41 | lwz r6, 0x4 (r3) 42 | subi r7, r4, 2 43 | srawi r7, r7, 1 44 | cmpw r7, r6 45 | mr r5, r3 #temp save r3 46 | li r3, 0 47 | bnelr- 48 | #Good to go 49 | subi r4, r4, 3 #Take away C2 header C2 line amount, and final null word 50 | addi r3, r5, 8 #Go past header past C2 line amount 51 | #Check if C2's byte amount matches r4 genned amount 52 | 53 | #If 2nd to last word is nop, subtract r4 by one more 54 | lis r0, 0x6000 #Nop 55 | slwi r6, r4, 2 #r6 = instruction amount x 4 = (byte amount of source + possible nop) 56 | subi r6, r6, 4 57 | lwzx r6, r6, r3 58 | cmpw r0, r6 59 | bnelr- 60 | subi r4, r4, 1 61 | blr 62 | 63 | #Check for 04 64 | try04: 65 | cmpwi r5, 2 66 | bne- tryC0 67 | 68 | #04 codetype found 69 | addi r3, r3, 4 70 | li r4, 1 71 | blr 72 | 73 | #Check for C0 74 | tryC0: 75 | cmpwi r5, 4 76 | bne- found06 77 | 78 | #C0 codetype found 79 | #Make sure C0 line amount matches {(rawinstructionamount - 2) / 2} 80 | lwz r6, 0x4 (r3) 81 | subi r7, r4, 2 82 | srawi r7, r7, 1 83 | cmpw r7, r6 84 | mr r5, r3 #temp save r3 85 | li r3, 0 86 | bnelr- 87 | #Good to go 88 | subi r4, r4, 2 #Take away C0 header C0 line amount 89 | addi r3, r5, 8 #Go past header past C2 line amount 90 | 91 | #If last word is null or blr, subtract one more 92 | lis r0, 0x4E80 #blr 93 | ori r0, r0, 0x0020 94 | slwi r6, r4, 2 #r6 = instruction amount x 4 = (byte amount of source + possible 2ndtolastword) 95 | subi r6, r6, 4 96 | lwzx r7, r6, r3 97 | cmpwi r7, 0 98 | beq- 0xC 99 | cmpw r7, r0 100 | bnelr- #For whatever reason the C0 code in question has an odd setup (custom blr in middle?), *DON*T subtract anymore from r4, end func 101 | #Check if 2nd to last and last word are blr's 102 | #If 2nd to last word is blr, subtract one more again... 103 | subi r4, r4, 1 104 | subi r6, r6, 4 105 | lwzx r7, r6, r3 106 | cmpw r7, r0 107 | bnelr- 108 | subi r4, r4, 1 109 | blr 110 | 111 | #06 codetype found 112 | found06: 113 | lwz r6, 0x4 (r3) 114 | andi. r0, r6, 3 #06 byte amount must be divisible by 4 115 | addi r5, r3, 8 #Go past 06 header 06 byte amount 116 | li r3, 0 117 | bnelr- 118 | subi r4, r4, 2 #Take away 06 header and 06 byte amount line 119 | #If 06 byte amount ends in 0x4 or 0xC, then subtract r4 by 1 and compare vs r6 cuz last word of 06 code is null. If not, skip the subtraction part 120 | andi. r0, r6, 7 121 | beq- 0x8 122 | subi r4, r4, 1 123 | #Byte Amount / 4 should match instruction amount 124 | srawi r6, r6, 2 125 | cmpw r6, r4 126 | bnelr- #r3 still 0 127 | mr r3, r5 #Recover r3 before returning to signal everything is good to go 128 | blr 129 | -------------------------------------------------------------------------------- /HBC-Source/build/saveANDoverwrite_geckoheader.s: -------------------------------------------------------------------------------- 1 | .file "saveANDoverwrite_geckoheader.c" 2 | .machine ppc 3 | .section ".text" 4 | .ident "GCC: (devkitPPC release 44.2) 13.2.0" 5 | 6 | #Func does... 7 | #Save header to new malloc space 8 | #Strips out Header from code.txt/source.s and memmoves accordingly 9 | #Returns back malloc pointer 10 | 11 | #r3 arg = gecko header type 12 | #r4 arg = pointer to code.txt/source.s 13 | #r3 returns pointer 14 | #r3 returns 0 if malloc failed, allow parent func to handle error! 15 | 16 | .globl saveANDoverwrite_geckoheader 17 | saveANDoverwrite_geckoheader: 18 | 19 | #For the case this somehow gets called with no header.... 20 | cmpwi r3, 0 21 | beqlr- 22 | 23 | #Prologue 24 | stwu sp, -0x0020 (sp) 25 | mflr r0 26 | stw r28, 0x10 (sp) 27 | stw r29, 0x14 (sp) 28 | stw r30, 0x18 (sp) 29 | stw r31, 0x1C (sp) 30 | stw r0, 0x0024 (sp) 31 | 32 | #Update r4 (& backup to r30) cursor just in case there are spaces, tabs, and centers before gecko header 33 | subi r30, r4, 1 34 | lbzu r0, 0x1 (r30) 35 | cmpwi r0, 0x20 36 | beq -0x8 37 | cmpwi r0, 0x0A 38 | beq- -0x10 39 | cmpwi r0, 0x09 40 | beq- -0x18 41 | 42 | #Check for C0 type 43 | cmpwi r3, 4 44 | li r3, 3 45 | beq- 0x8 #C0's header type number matches malloc arg, lucky for us 46 | 47 | #C2/04/06 header found 48 | li r3, 9 49 | 50 | #Save malloc's r3 arg (length of Gecko header, 3 for C0, 9 for 04/06/C2) 51 | mr r31, r3 52 | 53 | #Malloc, malloc enough for header plus extra byte afterwards 54 | bl malloc 55 | mr. r28, r3 #Save malloc's return value 56 | beq- epipen #Skip saving and memmove if malloc failed 57 | 58 | #Save header to malloc'd space 59 | addi r4, r30, -1 60 | addi r5, r3, -1 61 | mtctr r31 62 | lbzu r0, 0x1 (r4) 63 | stbu r0, 0x1 (r5) 64 | bdnz+ -0x8 65 | 66 | #Now replace header with spaces, ye we could "cut" it out via memmove, but it's bother faster and shorter just to space fill it 67 | mtctr r31 68 | addi r3, r30, -1 69 | li r0, 0x20 70 | stbu r0, 0x1 (r3) 71 | bdnz+ -0x4 72 | 73 | #Recover malloc return value 74 | epipen: 75 | mr r3, r28 76 | 77 | #Return malloc return value back to parent 78 | lwz r0, 0x0024 (sp) 79 | lwz r31, 0x1C (sp) 80 | lwz r30, 0x18 (sp) 81 | lwz r29, 0x14 (sp) 82 | lwz r28, 0x10 (sp) 83 | mtlr r0 84 | addi sp, sp, 0x0020 85 | blr 86 | -------------------------------------------------------------------------------- /HBC-Source/build/simm_length_checker.s: -------------------------------------------------------------------------------- 1 | .file "simm_length_checker.c" 2 | .machine ppc 3 | .section ".text" 4 | .ident "GCC: (devkitPPC release 44.2) 13.2.0" 5 | 6 | 7 | #Small func that will prevent segmentations faults if there is an IMM that exceeds 8 ascii bytes in width 8 | simm_length_ec: 9 | .asciz "\n\nError! The above instruction has an IMM value that exceeds 8 digits in width. Please note that all spaces are stripped out. This is normal. Assembling has been rejected to prevent a segmentation fault. The 8 digit count includes leading zeroes. So be sure to remove those if that is the reason for this Error." 10 | .align 2 11 | 12 | .globl simm_length_checker 13 | simm_length_checker: 14 | stwu sp, -0x0010 (sp) 15 | mflr r0 16 | stw r0, 0x0014 (sp) 17 | 18 | #Save arg, no need for GVR since theres no function calls 19 | mr r10, r3 20 | 21 | #Prep r3 for loop 22 | subi r3, r3, 1 23 | 24 | #Test whole file 25 | simm_length_checker_ROOTLOOP: 26 | lhzu r0, 0x1 (r3) 27 | srwi. r4, r0, 8 28 | beq- simm_length_checker_success #EoF reached 29 | 30 | #Check against constant (0x) 31 | li r5, 0x3078 32 | cmpw r0, r5 33 | bne+ simm_length_checker_ROOTLOOP 34 | 35 | #Found an instance of "0x" 36 | #Count IMM digits 37 | addi r4, r3, 1 38 | lbzu r0, 0x1 (r4) 39 | cmplwi r0, 0x39 40 | bgt- -0x8 41 | cmplwi r0, 0x30 42 | bge- -0x10 43 | sub r5, r4, r3 44 | cmplwi r5, 10 #8 digit max plus the 2 digits for "0x" 45 | ble- simm_length_checker_ROOTLOOP 46 | 47 | #UH OH, IMM exceeds 8 digits in width, print the instruction thats faulty 48 | #Null out instruction's enter 49 | mr r4, r3 50 | lbzu r0, 0x1 (r4) 51 | cmpwi r0, 0xA 52 | bne+ -0x8 53 | li r0, 0 54 | stb r0, 0 (r4) 55 | #Now go backwards til hit first enter or til we hit SoF-1 56 | lbzu r0, -0x1 (r3) 57 | cmplw r3, r10 58 | blt- 0xC #If SoF, we want cursor at SoF-1 59 | cmpwi r0, 0xA 60 | bne+ -0x10 61 | #Increment cursor by 1, and instruction is ready to print 62 | addi r3, r3, 1 63 | crxor 6, 6, 6 64 | bl printf #DONT use puts 65 | #Bad instruction printed, now return back with new string for parent to print 66 | lis r3, simm_length_ec@h 67 | ori r3, r3, simm_length_ec@l 68 | b end_this_crappp 69 | 70 | simm_length_checker_success: 71 | li r3, 0 72 | 73 | end_this_crappp: 74 | lwz r0, 0x0014 (sp) 75 | mtlr r0 76 | addi sp, sp, 0x0010 77 | blr 78 | -------------------------------------------------------------------------------- /HBC-Source/build/source_parser.s: -------------------------------------------------------------------------------- 1 | .file "source_parser.c" 2 | .machine ppc 3 | .section ".text" 4 | .ident "GCC: (devkitPPC release 44.2) 13.2.0" 5 | 6 | #This function accepts source.s and removes the following.. 7 | #Double+ Enters, *not* single enters 8 | #Spaces 9 | #Tabs 10 | #Comments 11 | #This is needed because Waltress ASM Engine needs everything stripped 12 | #r3 source.s must end in enter then null byte! 13 | 14 | #r3 = pointer to source.s that ends in Enter then Null 15 | #r4 = byte size *plus* null 16 | 17 | #TODO show condi branch in puts message 18 | 19 | wtf_lmao: #TODO remove this error line/check from the branch label parser since its here 20 | .asciz "\n\nError! At least 1 branch label does not have a landing spot." 21 | .align 2 22 | 23 | #Symbols 24 | .set space, 0x20 25 | .set enter, 0x0A 26 | .set tab, 0x09 27 | .set comment, 0x23 28 | .set slash, 0x2F 29 | .set asterisk, 0x2A 30 | 31 | #Prologue 32 | .globl source_parser 33 | source_parser: 34 | stwu sp, -0x0020 (sp) 35 | mflr r0 36 | stw r26, 0x8 (sp) 37 | stw r27, 0xC (sp) 38 | stw r28, 0x10 (sp) 39 | stw r29, 0x14 (sp) 40 | stw r30, 0x18 (sp) 41 | stw r31, 0x1C (sp) 42 | stw r0, 0x0024 (sp) 43 | 44 | #Save Args 45 | mr r31, r3 46 | mr r30, r4 47 | 48 | #Change all comments and chars within comments to spaces 49 | #We'll make a dedicated comment handler in a future version 50 | #Pre decrement ptr/cursor and place space symbol in r4 51 | addi r3, r3, -1 52 | li r4, space 53 | 54 | change_comments_to_spaces: 55 | lbzu r0, 0x1 (r3) 56 | cmpwi r0, 0 57 | beq- remove_double_enters #If null, stop doing this ofc 58 | cmpwi r0, comment #Check for 1st comment symbol of line 59 | beq- handle_hashtagged_comment 60 | cmpwi r0, slash 61 | bne+ change_comments_to_spaces 62 | #At this point, we may be in a chain-type comment 63 | lbz r0, 0x1 (r3) 64 | cmpwi r0, asterisk 65 | bne- change_comments_to_spaces 66 | 67 | #Now we are on a chain comment 68 | #Write over slash asterisk first 69 | stb r4, 0 (r3) 70 | stbu r4, 0x1 (r3) 71 | lbzu r0, 0x1 (r3) 72 | cmpwi r0, asterisk #if asterisk is hit we may be at end of chain comment 73 | stb r4, 0 (r3) #No matter what, this must be done. Overwrite current char with space 74 | bne+ -0xC 75 | lbz r0, 0x1 (r3) #asterisk was current char, very next char must be the slash 76 | cmpwi r0, slash 77 | bne+ -0x18 78 | stbu r4, 0x1 (r3) #Overwrite slash and update cursor to comply with loop 79 | b change_comments_to_spaces 80 | 81 | #Now we are on a hashtag-type comment 82 | #Write over comment symbol first 83 | handle_hashtagged_comment: 84 | stb r4, 0 (r3) 85 | #Now check for enter, once we hit enter go back to prev loop 86 | lbzu r0, 0x1 (r3) 87 | cmpwi r0, enter 88 | beq- change_comments_to_spaces 89 | #Enter not found yet, overwrite char/symbol with space 90 | stb r4, 0 (r3) 91 | b -0x10 #Go back to checking for enter again 92 | 93 | #All comment and chars within comments are now spaces 94 | #Now remove all double+ enters 95 | remove_double_enters: 96 | addi r3, r31, -1 #Reset cursor 97 | remove_double_enters_loop: 98 | lbzu r0, 0x1 (r3) 99 | cmpwi r0, 0 100 | beq- almost_there 101 | cmpwi r0, enter 102 | bne+ remove_double_enters_loop 103 | mr r4, r3 104 | lbzu r0, 0x1 (r4) 105 | cmpwi r0, space 106 | beq- -0x8 107 | cmpwi r0, tab 108 | beq- -0x10 109 | cmpwi r0, enter #TODO fix to move cursor (update r3 is bne route is taken) forward, not needed technically but should be done 110 | bne+ remove_double_enters_loop 111 | li r5, space 112 | stb r5, 0 (r4) 113 | b -0x24 114 | 115 | #There may be a newline (0xA) char at the very start of file, remove it 116 | almost_there: 117 | lbz r0, 0x0 (r31) 118 | cmpwi r0, enter 119 | bne- start_standard_parser 120 | li r0, space 121 | stb r0, 0x0 (r31) 122 | 123 | ##################### 124 | ##################### 125 | #Set counter to know how much to subtract from r30 which will be used as setup for memmove r4 arg 126 | start_standard_parser: 127 | li r6, 0 128 | 129 | #Setup r31 for loop 130 | addi r31, r31, -1 131 | 132 | #Loop 133 | standard_parser_loop: 134 | lbzu r0, 0x1 (r31) 135 | addi r6, r6, 1 136 | cmpwi r0, 0 137 | beq- source_parser_epilogue 138 | cmpwi r0, space 139 | beq- setup_memmoves 140 | cmpwi r0, tab 141 | bne+ standard_parser_loop 142 | 143 | #Memmove 144 | #r3 = Destination Addr 145 | #r4 = Source Addr 146 | #r5 = Size in bytes 147 | setup_memmoves: 148 | mr r3, r31 149 | addi r4, r31, 1 150 | sub r30, r30, r6 151 | mr r5, r30 152 | bl memmove 153 | li r6, 0 #Reset r6 154 | subi r31, r31, 1 #Update cursor to correct spot now that contents have shifted left 1 byte 155 | b standard_parser_loop 156 | 157 | wtf_lol: 158 | lis r3, wtf_lmao@h 159 | ori r3, r3, wtf_lmao@l 160 | b source_parser_further_epilogue 161 | 162 | #Epilogue 163 | source_parser_epilogue: 164 | li r3, 0 165 | source_parser_further_epilogue: 166 | lwz r31, 0x1C (sp) 167 | lwz r30, 0x18 (sp) 168 | lwz r29, 0x14 (sp) 169 | lwz r28, 0x10 (sp) 170 | lwz r27, 0xC (sp) 171 | lwz r26, 0x8 (sp) 172 | lwz r0, 0x0024 (sp) 173 | mtlr r0 174 | addi sp, sp, 0x0020 175 | blr 176 | -------------------------------------------------------------------------------- /HBC-Source/source/add_header.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/add_header.c -------------------------------------------------------------------------------- /HBC-Source/source/asm_engine.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/asm_engine.c -------------------------------------------------------------------------------- /HBC-Source/source/assemble.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/assemble.c -------------------------------------------------------------------------------- /HBC-Source/source/bin2txt.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/bin2txt.c -------------------------------------------------------------------------------- /HBC-Source/source/branchlabelparser.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/branchlabelparser.c -------------------------------------------------------------------------------- /HBC-Source/source/codetxt2bin.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/codetxt2bin.c -------------------------------------------------------------------------------- /HBC-Source/source/codetxtparser.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/codetxtparser.c -------------------------------------------------------------------------------- /HBC-Source/source/codetxtpostparsersize.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/codetxtpostparsersize.c -------------------------------------------------------------------------------- /HBC-Source/source/dasm_engine.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/dasm_engine.c -------------------------------------------------------------------------------- /HBC-Source/source/disassemble.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/disassemble.c -------------------------------------------------------------------------------- /HBC-Source/source/finalize_assembled_bin.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/finalize_assembled_bin.c -------------------------------------------------------------------------------- /HBC-Source/source/fix_neg_hex.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/fix_neg_hex.c -------------------------------------------------------------------------------- /HBC-Source/source/fixwaltress_nulls.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/fixwaltress_nulls.c -------------------------------------------------------------------------------- /HBC-Source/source/gencodebinsize.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/gencodebinsize.c -------------------------------------------------------------------------------- /HBC-Source/source/get_geckoheadertype.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/get_geckoheadertype.c -------------------------------------------------------------------------------- /HBC-Source/source/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | static void *xfb = NULL; 15 | static GXRModeObj *rmode = NULL; 16 | 17 | //--------------------------------------------------------------------------------- 18 | int main(int argc, char **argv) { 19 | //--------------------------------------------------------------------------------- 20 | 21 | // Initialise the video system 22 | VIDEO_Init(); 23 | 24 | // This function initialises the attached controllers 25 | WPAD_Init(); 26 | PAD_Init(); 27 | 28 | // Obtain the preferred video mode from the system 29 | // This will correspond to the settings in the Wii menu 30 | rmode = VIDEO_GetPreferredMode(NULL); 31 | 32 | // Allocate memory for the display in the uncached region 33 | xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); 34 | 35 | // Initialise the console, required for printf 36 | console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ); 37 | 38 | // Set up the video registers with the chosen mode 39 | VIDEO_Configure(rmode); 40 | 41 | // Tell the video hardware where our display memory is 42 | VIDEO_SetNextFramebuffer(xfb); 43 | 44 | // Make the display visible 45 | VIDEO_SetBlack(FALSE); 46 | 47 | // Flush the video register changes to the hardware 48 | VIDEO_Flush(); 49 | 50 | // Wait for Video setup to complete 51 | VIDEO_WaitVSync(); 52 | if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync(); 53 | 54 | 55 | // The console understands VT terminal escape codes 56 | // This positions the cursor on row 2, column 0 57 | // we can use variables for this with format codes too 58 | // e.g. printf ("\x1b[%d;%dH", row, column ); 59 | printf("\x1b[2;0H"); 60 | 61 | 62 | printf("Hello World!"); 63 | 64 | while(1) { 65 | 66 | // Call WPAD_ScanPads each loop, this reads the latest controller states 67 | WPAD_ScanPads(); 68 | 69 | // WPAD_ButtonsDown tells us which buttons were pressed in this loop 70 | // this is a "one shot" state which will not fire again until the button has been released 71 | u32 pressed = WPAD_ButtonsDown(0); 72 | 73 | // We return to the launcher application via exit 74 | if ( pressed & WPAD_BUTTON_HOME ) exit(0); 75 | 76 | // Wait for the next frame 77 | VIDEO_WaitVSync(); 78 | } 79 | 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /HBC-Source/source/newline_fixer.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/newline_fixer.c -------------------------------------------------------------------------------- /HBC-Source/source/prep_waltress_dbin.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/prep_waltress_dbin.c -------------------------------------------------------------------------------- /HBC-Source/source/saveANDoverwrite_geckoheader.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/saveANDoverwrite_geckoheader.c -------------------------------------------------------------------------------- /HBC-Source/source/simm_length_checker.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/simm_length_checker.c -------------------------------------------------------------------------------- /HBC-Source/source/source_parser.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Source/source/source_parser.c -------------------------------------------------------------------------------- /HBC-Waltress/boot.dol: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Waltress/boot.dol -------------------------------------------------------------------------------- /HBC-Waltress/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VegaASM/Waltress/2f78f9c6ad8a87b2f4a5a67118c5b7df34d02361/HBC-Waltress/icon.png -------------------------------------------------------------------------------- /HBC-Waltress/meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Waltress 4 | 0.9 5 | 20240324 6 | Vega 7 | PowerPC Assembler 8 | The first ever PowerPC Assembler written in PowerPC. Can also be used as a Gecko Cheat Code assembler. Not intended for 'mainstream' usage. Use at your own risk. 9 | 10 | Created by Vega 11 | 12 | Visit www.MarioKartWii.com for questions or bug reports. 13 | 14 | 15 | -------------------------------------------------------------------------------- /HISTORY.txt: -------------------------------------------------------------------------------- 1 | 3/24/2024 (v0.9): Still Not There Yet 2 | *Lifted more IMM restrictions off many instructions 3 | *Fixed a tiny bug in the disassembler when it came to deciphering crclr vs crxor instruction 4 | *On previous version, I thought I fixed the "junk name-only" bug. Apparently I didn't, so now it's actually fixed. 5 | 6 | 3/18/2024 (v0.8): Somewhat Useful Now 7 | *Engine files are now standard functions within Source. This prevents faults occurring on certain versions of QEMU 8 | *Some Immediate Value restrictions have been lifted (i.e. can use decimal values for SIMMs/UIMMs of integer instructions, can use negative hex values for most instructions, etc) 9 | *Added in subi, subis, and subic(.) simplified mnemonics. Somehow I forgot those? lol 10 | *Fixed Bug that allowed multiple branch landings spots to have the same name 11 | *Fixed Bug that allowed name-only instructions to have junk appended to it and still be assembled (i.e nopxxxxx being read as nop) 12 | *Fixed Bug that used SIMM range instead of UIMM range for addis when assembling 13 | *Placed in a function to check if any IMM exceeds 8 digits in net width. Therefore an Error Message will be displayed (that shows the faulty instruction) instead of a fault occurring. 14 | 15 | 2/14/2024 (v0.7): Label Slap 16 | *Branch Labels (with some restrictions) can now be used during assembling 17 | *Fixed bug where addis/lis was being disassembled using SIMM instead of UIMM 18 | *Fixed bug that prevented faulty instruction from being displayed on HBC app error message during assembling 19 | 20 | 1/18/2024 (v0.6.1): Note that Down 21 | *Restrictions on location of Comments removed 22 | *Chain comments (/*example*/) now allowed 23 | *Restrictions of having spaces, tabs, & enters before Gecko Header removed 24 | *Fixed bug on interpreting new lines (Enters vs Carriages) 25 | 26 | 10/16/2023 (v0.6): The End of Hibernation 27 | *Both engine sources are completely overhauled. 28 | *When assembling, Waltress will show the instruction that it cannot assemble (first one, not all). 29 | *Quirky SIMM ranges fixed. 30 | *Fixed bug where mfsr was not assembling correctly (SR was always being assembled as 0). 31 | *Fixed bug where any float or ps multiply related instruction refused to assemble if fD was f8 or higher. 32 | *A desktop version is now included (requires QEMU)!! 33 | *All simplified mnemonics (except clrlslwi, la, extlwi, extrwi, inslwi, & insrwi) now supported. Hooray! 34 | *Binary file support removed. File deletion support removed. Super strict formatting removed. 35 | *Files can now have comments albeit it some limitation. Files can now have extra spaces, extra enters, etc. 36 | *Quirky Error Code system is removed and replaced with Error Text Messages. 37 | 38 | 7/30/2022 (v0.5): Yet Another Bump 39 | *Can now disassemble Gecko Cheat Codes. New secondary menu within App allows users to choose the disassembly option. 40 | 41 | 7/26/2022 (v0.4): Hey, it's a Gecko! 42 | *Can now assemble Gecko Cheat Codes. However, proper disassembling is not supported (example: a Gecko Opcode present at the start of code.bin/txt will be disassembled to its PPC instruction equivalent). Therefore, Waltress can still only disassemble in a 'raw style'. Raw assembling still available. 43 | *Gecko Cheat Codes supported (for assembling) are Mem80 32-bit RAM Write (04 Opcode), Mem80 String Write (06 Opcode), Execute ASM (C0 Opcode), and Insert ASM (C2 Opcode). 44 | *C0 assembling will auto add required blr for you. No need to include it in your source.s file. 45 | 46 | 7/11/2022 (v0.3): Growing Pains 47 | *Codes can now be assembled-to/disassembled-from a code.txt file. Binary file option is still available. 48 | *Added more error code returns for both assembler and disassembler engine due to added option of code.txt 49 | *Option added in to delete original input file after a successful assembly/disassembly. 50 | *More typo and code clean up 51 | 52 | 7/5/2022 (v0.2): Still an Infant 53 | *Added in blr(l), bctr(l), sub(./o), and subc(./o) simplified mnemonics 54 | *Re-did the initial process of creating the HBC application, saved a few lines of pre-generated Assembly code for the Inline file 55 | *Got rid of the -33 error code in the HBC app (aka -3 in Assembler engine). If a source line is simply too long, we will let it output the same error as former -34. 56 | *Engine files no longer hardcoded to certain function addr's that were specific to PAL MKWii. Empty reserved spots in lookup table now serve that job. Function addr's are written to reserved spots by software (HBC App) 57 | *Fixed a bunch of typos (lol) 58 | 59 | 7/4/2022 (v0.1): Humble Beginnings 60 | *Initial public release 61 | -------------------------------------------------------------------------------- /NOTES.txt: -------------------------------------------------------------------------------- 1 | First thing's First. Waltress is an alpha-type program. Meaning it's not ready for "production" usage. Bugs and weird errors will most likely occur. Do not rely on Waltress as your main Wii Gecko Code assembler. If Waltress ever reaches version 1.0.0, then it will be considered ready for production use. 2 | 3 | At the moment, the only "nuisance" Waltress possesses is the IMM (Immediate) Value Format rules that must be followed. Be sure to read --IMM-Format-- further below. 4 | 5 | =========== 6 | 7 | Features~ 8 | - Full support for 04, 06, C0, and C2 Gecko codetypes 9 | - Yes, the blr is auto-added for you on C0 codes 10 | - Uses a special header for Gecko codes. There's no need to select an option when assembling/disassembling. Just include the header at the very top of your file. See -Gecko-Header-Format- below for details. 11 | - If there is a faulty instruction when assembling, Waltress will tell you which instruction it is (if multiple, Waltress only lists the top/first one) 12 | - Checks all rA=/=r0 rules for all applicable load/store instructions 13 | - Checks if NB in lswi does not cause rD's loaded bytes to spill into rA 14 | - Checks for all valid SPR's for both mfspr and mtspr, note that the validity is only matched for the Wii Broadway chip 15 | - Includes support for Broadway's rarely known chip ID SPR's 16 | - When disassembling, clrlwi, clrrwi, rotlwi, rotlw, slwi, and srwi are used over their standard mnemonic forms. 17 | - Anything that can be assembled can be disassembled and vice versa. 18 | 19 | ============ 20 | 21 | As mentioned earlier, Waltress is an alpha-type program. Therefore, it does not include some basic features you would expect. Those are... 22 | - Branch labels are indeed supported, but have some restrictions (read -Branch-labels- below) 23 | - Assembler directives not supported 24 | - Immediate Values have some restrictions (read -IMM-format- below) 25 | - Register alias's (i.e. sp, rtoc) not supported. 26 | 27 | The above limitations may be fixed in the future, who knows. 28 | 29 | Waltress supports all simplified mnemonics except for the following... 30 | 31 | inslwi(.) 32 | insrwi(.) 33 | extlwi(.) 34 | extrwi(.) 35 | clrlslwi(.) 36 | rotrwi(.) 37 | la 38 | twlt 39 | twgt 40 | tweq 41 | twge 42 | twle 43 | twne 44 | 45 | ============ 46 | 47 | -Gecko-Header-Format- 48 | 49 | The syntax for the Header is as follows... 50 | 51 | !<24-bit address if applicable> 52 | 53 | Example 04 header 54 | !04565AAC 55 | 56 | Example 06 header 57 | !06565AAC 58 | 59 | Example C2 header 60 | !C2565AAC 61 | 62 | Example C0 header 63 | !C0 64 | 65 | Just add the appropriate header to source.s/code.txt for your Gecko code to be assembled/disassembled correctly. 66 | 67 | IMPORTANT NOTE: Do not place any notes/comments before the Gecko Header. 68 | 69 | ============ 70 | 71 | -IMM-Format- 72 | 73 | Waltress does require some strict Immediate Value Formatting in regards to Hex vs Decimal for certain instructions. Here are all the restrictions~ 74 | 75 | No binary or octal usage. 76 | 77 | All Branch SIMMs, if used, *must* be in Unsigned Capitalized Hex. 78 | 79 | Lowercase Hex *CANNOT* be of negative connotation (i.e. -0xa is prohibited while -0xA is allowed) 80 | 81 | IMM in mtfsfi(.) *must* be in Hex. 82 | 83 | CRM field in mtcrf *must* be in Hex. 84 | 85 | FM field in mtfsf(.) *must* be in Hex. 86 | 87 | SPR field in mfspr/mtspr *must* be in Decimal. 88 | 89 | TBR field in mftb *must* be in Decimal. 90 | 91 | crF field *must* be in Decimal. 92 | 93 | crB field *must* be in Decimal. 94 | 95 | BO & BI in standard mnemonic branch instructions *must* be in Decimal. 96 | 97 | W, I, and GQR fields in paired single instructions *must* be in Decimal. 98 | 99 | TO field in trap instructions *must* be in Decimal. 100 | 101 | SR field in Segment Register instructions *must* be in Decimal. 102 | 103 | SH field in srawi(.) *must* be in Decimal 104 | 105 | n field in rotlwi(.), slwi(.), srwi(.), clrlwi(.), & clrrwi(.) *must* be in Decimal 106 | 107 | ============= 108 | 109 | -Branch-labels- 110 | 111 | Branch labels are allowed as long as they meet the following criteria 112 | 113 | *The very first PPC instruction of your source *CANNOT* be a branch w/ a branch label 114 | *Use capital letters and/or underscores 115 | *No shorter than 3 characters in length 116 | *No longer than 31 characters in length 117 | 118 | Example~ 119 | beq SOMEWHERE 120 | ... 121 | SOMEWHERE: 122 | 123 | ============ 124 | 125 | -Important NOTE regarding mfspr and mtspr simplified mnemonics- 126 | 127 | Any valid SPR in the mfspr/mtspr can be used in the following format.. 128 | mtNAME rX 129 | mfNAME rX 130 | 131 | NAME = the SPR's name ofc 132 | 133 | Example: 134 | mtl2cr r11 #Move r11 contents to L2CR 135 | mfhid0 r30 #Move HID0 contents to r30 136 | 137 | No other PPC assembler can do this for all the SPRs! 138 | 139 | Because this special SPR format is Waltress-unique, you *CANNOT* use the "legacy format" which is valid for some SPRS. For example.... 140 | mtibatu 3, r12 #Move r12 contents to IBAT3u 141 | 142 | The above instruction *WON'T* work in Waltress. Use the new and improved format instead! 143 | mtibat3u r12 #Better format! Hooray! 144 | 145 | ============ 146 | 147 | -Comments- 148 | 149 | Comments are indeed supported. You can use standard hash comments and chain comments. 150 | 151 | Examples: 152 | nop #Standard comment 153 | nop /*Chain comment*/ 154 | /*This 155 | is 156 | a 157 | Chain comment*/ 158 | 159 | ============ 160 | 161 | NOTE ("noobies" can disregard this note): For the following instructions... 162 | 163 | *trap 164 | *bcX with BO of 0b10100 165 | *blr 166 | *blrl 167 | *bctr 168 | *bctrl 169 | *bdnz 170 | *bdz 171 | *bdnzctr 172 | *bdnzctrl 173 | *bdzctr 174 | *bdzctrl 175 | *bdnzlr 176 | *bdnzlrl 177 | *bdzlr 178 | *bdzlrl 179 | 180 | ...may not re-assemble back to their 100% exact original pre-assembled instruction (Hexadecimal word value) after disassembling from an original code.txt file. This is because these simplified mnemonics have fields and/or register values that qualify as "Don't Care Values". Meaning that these fields/values can be anything and the instruction in question still qualifies as being the simplified mnemonic. When Waltress assembles instructions with these "don't care values", they are set to 0. Please note that all other known PPC Assemblers are "plagued" with this. It's impossible to fix without completely getting rid of the simplified mnemonics. 181 | 182 | NOTE: For the bcX, bcctrX, and bclrX instructions, all "don't care" values for the BO field *only* *MUST* be low or else the instruction is treated as illegal (which is what other PPC assemblers do as well). 183 | 184 | If the above 2 notes make zero sense to you, then don't worry. They won't effect you. 185 | 186 | Final NOTE: 187 | 188 | bcX with BO of 0b10100 is an alternative instruction that exactly mimics an unconditional branch. Therefore I've made custom Waltress-unique mnemonics for these 4 rare instructions. 189 | 190 | bcX with BO of 0b10100 = bal 0xXXXX (branch always) 191 | bcX with BO of 0b10100 && aa high = bala 0xXXXX (branch always absolute) 192 | bcX with BO of 0b10100 && lk high = ball 0xXXXX (branch always & link) 193 | bcX with BO of 0b10100 && aa && lk high = balla 0xXXXX (branch always absolute & link) 194 | 195 | ============ 196 | 197 | FINAL Note (to other coders/devs) 198 | 199 | This project (due to its handwritten nature and my lack of fixing code along the way) has a ton of technical debt. Therefore, code optimization may never happen unless someone else is willing to do it. 200 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | *WALTRESS* 2 | 3 | The first ever PowerPC Assembler entirely handwritten in PowerPC! It is 100% Broadway (Wii CPU) compliant. Waltress can also assemble Wii Gecko Codes. 4 | 5 | Why the name Waltress? Waltress is one of Daysha's cats, and she is a shy black+brown long hair cat with a gigantic fluffy tail. Waltress is also the site mascot for MarioKartWii.com. 6 | 7 | Please read over this document to understand the contents of some of the folders and files present in this zip package. 8 | 9 | Created by Vega 10 | 11 | Version 0.9 12 | 13 | Release Date: March 24, 2024 14 | 15 | ========== 16 | 17 | You can run Waltress via 2 different methods. Either on the Wii/Dolphin via the HBC app, or on your Linux Desktop via QEMU. 18 | 19 | General Overview: 20 | 21 | In the root directly, there are the following files and folders... 22 | 23 | README #What you're reading right now, lol 24 | 25 | NOTES.txt #What features and limitations Waltress has. Also contains notes on how to use special formatting/symbols to "tell" Waltress if your source/code is a Gecko code. Be sure to read this! READ THIS!!! READ THIS!!! 26 | 27 | BUGS.txt #Any known bugs that have not been fixed yet. Read this before reporting a bug if you've encounter one. 28 | 29 | COMPILING.txt #This file contains guides for compiling the HBC app from source, and compiling the Desktop App from source. 30 | 31 | DEBUG.txt #This file contains a guide on how to install & run the GNU Debugger to step-by-step the Desktop App if desired. 32 | 33 | script.sh #File used for compiling the HBC app from source. 34 | 35 | test_source.s #This is a source file (contains every PPC instruction) which is used during debugging to verify that Assembling and Disassembling outputs are 100% correct 36 | 37 | /DV #Desktop application 38 | 39 | /DV-Source #Source of the Desktop application 40 | 41 | /HBC-Waltress #This folder contains the files for the HBC app. (icon.png, boot,dol. and meta.xml) 42 | 43 | /HBC-Source #Source of the HBC app's boot.dol. 44 | 45 | /Examples #Contains various Wii Gecko Code examples so you know exactly how to properly label Gecko codes for Waltress 46 | 47 | ========== 48 | 49 | Using Waltress HBC App (real Wii) 50 | 51 | Requirements: HBC (version 1.1.0 or later) installed on your Wii and is running on a clean IOS58. 52 | 53 | 1. Copy-Paste /HBC-Waltress folder into the /apps folder of your SD/USB device 54 | 2a: Waltress expects a source.s file present in /apps/HBC-Waltress for assembling. Place source.s into /apps/HBC-Waltress folder 55 | 2b: Waltress expects a code.txt file present in /apps/HBC-Waltress for disassembling. Place code.txt into /apps/HBC-Waltress folder. 56 | 3: Do NOT have both a source.s and code.txt file present in /apps/HBC-Waltress. 57 | 4: SD/USB device out of computer and into your Wii 58 | 5: Launch HBC. Launch Waltress HBC App. Follow on-screen instructions. 59 | 6: Waltress will display a Success Message or an Error Message after usage. 60 | 61 | Using Waltress HBC App (Dolphin) 62 | 63 | 1. Copy-Paste /HBC-Waltress folder into the /apps folder of the location of your Virtual SD Card on your computer 64 | 2a: Waltress expects a source.s file present in /apps/HBC-Waltress for assembling. Place source.s into /apps/HBC-Waltress folder 65 | 2b: Waltress expects a code.txt or code.bin file present in /apps/HBC-Waltress for disassembling. Place code.txt into /apps/HBC-Waltress folder. 66 | 3: Do NOT have both a source.s and code.txt file present in /apps/HBC-Waltress. 67 | 4: Launch Dolphin. Launch HBC. Launch Waltress HBC App. Follow on-screen instructions. 68 | 5: Waltress will display a Success Message or an Error Message after usage. 69 | 6. Alternatively, you should be able to directly open the boot.dol directly if desired. 70 | 71 | Using Waltress Desktop Application (Linux w/ QEMU-PPC) 72 | 73 | 1. *NOTE* that this has only been confirmed to work on Linux Debian 11 & 12. I do *NOT* own a Windows or Mac machine, so I cannot be of help here. If anybody knows how to get this to work on Windows or Mac, please notify me. 74 | 2. Install QEMU-PPC 75 | sudo apt-get update 76 | sudo apt-get install qemu-user qemu-user-static 77 | 3. Make sure App is executable 78 | cd DV 79 | chmod +x ./main 80 | 4a: Waltress expects a source.s file present in /DV for assembling. Place that file into /DV folder. 81 | 4b: Waltress expects a code.txt file present in /DV for disassembling. Place that file into /DV folder. 82 | 5: Do NOT have both a source.s and code.txt file present in /DV. 83 | 6. Launch the App 84 | ./main 85 | 7. Follow the on-screen instructions. 86 | 8: Waltress will display a Success Message or an Error Message after usage. 87 | -------------------------------------------------------------------------------- /script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Enter directory where devkitpro is installed at. If unsure, this is usually located at /opt" 4 | read devkitloc 5 | 6 | echo "Enter directory where the HBC-Source directory is located at (i.e. /home/Vega/Waltress03242024)" 7 | read walloc 8 | 9 | cd $devkitloc/devkitpro/devkitPPC/bin 10 | 11 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/main.s -o $walloc/HBC-Source/build/main.o 12 | 13 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/assemble.s -o $walloc/HBC-Source/build/assemble.o 14 | 15 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/bin2txt.s -o $walloc/HBC-Source/build/bin2txt.o 16 | 17 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/finalize_assembled_bin.s -o $walloc/HBC-Source/build/finalize_assembled_bin.o 18 | 19 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/gencodebinsize.s -o $walloc/HBC-Source/build/gencodebinsize.o 20 | 21 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/source_parser.s -o $walloc/HBC-Source/build/source_parser.o 22 | 23 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/add_header.s -o $walloc/HBC-Source/build/add_header.o 24 | 25 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/get_geckoheadertype.s -o $walloc/HBC-Source/build/get_geckoheadertype.o 26 | 27 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/saveANDoverwrite_geckoheader.s -o $walloc/HBC-Source/build/saveANDoverwrite_geckoheader.o 28 | 29 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/codetxt2bin.s -o $walloc/HBC-Source/build/codetxt2bin.o 30 | 31 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/codetxtparser.s -o $walloc/HBC-Source/build/codetxtparser.o 32 | 33 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/codetxtpostparsersize.s -o $walloc/HBC-Source/build/codetxtpostparsersize.o 34 | 35 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/disassemble.s -o $walloc/HBC-Source/build/disassemble.o 36 | 37 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/fixwaltress_nulls.s -o $walloc/HBC-Source/build/fixwaltress_nulls.o 38 | 39 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/prep_waltress_dbin.s -o $walloc/HBC-Source/build/prep_waltress_dbin.o 40 | 41 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/newline_fixer.s -o $walloc/HBC-Source/build/newline_fixer.o 42 | 43 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/branchlabelparser.s -o $walloc/HBC-Source/build/branchlabelparser.o 44 | 45 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/simm_length_checker.s -o $walloc/HBC-Source/build/simm_length_checker.o 46 | 47 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/fix_neg_hex.s -o $walloc/HBC-Source/build/fix_neg_hex.o 48 | 49 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/asm_engine.s -o $walloc/HBC-Source/build/asm_engine.o 50 | 51 | ./powerpc-eabi-as -mregnames -mbroadway $walloc/HBC-Source/build/dasm_engine.s -o $walloc/HBC-Source/build/dasm_engine.o 52 | 53 | cd $walloc/HBC-Source 54 | make 55 | rm HBC-Source.elf 56 | mv HBC-Source.dol boot.dol 57 | cd build 58 | rm *.o 59 | rm *.elf.map 60 | 61 | echo "Done! Delete old boot.dol located at /HBC-Waltress, and replace with new boot.dol that's located at /HBC-Source" 62 | 63 | 64 | --------------------------------------------------------------------------------