diff options
-rw-r--r-- | NewerCodehandler.yaml | 34 | ||||
-rw-r--r-- | codehandler.yaml | 8 | ||||
-rwxr-xr-x | makeNewerAllCodehandler | 14 | ||||
-rw-r--r-- | src/bossMegaGoomba.cpp | 141 | ||||
-rw-r--r-- | src/codehandler.o | bin | 0 -> 5772 bytes | |||
-rwxr-xr-x | src/codehandler.real.s | 821 | ||||
-rw-r--r-- | tools/kamek.py | 24 |
7 files changed, 1002 insertions, 40 deletions
diff --git a/NewerCodehandler.yaml b/NewerCodehandler.yaml new file mode 100644 index 0000000..facbc81 --- /dev/null +++ b/NewerCodehandler.yaml @@ -0,0 +1,34 @@ +output_dir: "NewerASM" +code_address: 0x808D9000 +modules: + - processed/prolog.yaml + - processed/bugfixes.yaml + - processed/worldmap.yaml + - processed/levelnames.yaml + - processed/animtiles.yaml + - processed/levelspecial.yaml + - processed/mrsun.yaml + - processed/firelaser.yaml + - processed/bossFuzzyBear.yaml + - processed/spritetex.yaml +# - processed/gakenoko.yaml + - processed/poweruphax.yaml +# - processed/heapbar.yaml + - processed/randtiles.yaml + - processed/tilegod.yaml + - processed/linegod.yaml + - processed/tilesetfixer.yaml + - processed/switchblock.yaml + - processed/eventblock.yaml +# - processed/msgbox.yaml +# - processed/replay.yaml + - processed/growup.yaml + - processed/eventlooper.yaml + - processed/spritespawner.yaml + - processed/spriteswapper.yaml + - processed/compression.yaml +# - processed/crowdclapper.yaml + - processed/blocksnake.yaml +# - processed/classic_controller.yaml + - processed/bossMegaGoomba.yaml + - processed/codehandler.yaml diff --git a/codehandler.yaml b/codehandler.yaml new file mode 100644 index 0000000..cfbeb9e --- /dev/null +++ b/codehandler.yaml @@ -0,0 +1,8 @@ +source_files: [../src/codehandler.o] +hooks: + - name: CodeHandlerHook + type: branch_insn + branch_type: b + src_addr_pal: 0x801bdf78 + target_func: '_start' + diff --git a/makeNewerAllCodehandler b/makeNewerAllCodehandler new file mode 100755 index 0000000..dffb254 --- /dev/null +++ b/makeNewerAllCodehandler @@ -0,0 +1,14 @@ +#!/bin/sh +python2 tools/mapfile_tool.py +python2 tools/kamek.py NewerCodehandler.yaml --no-rels --use-mw --use-wine --gcc-type=/opt/wiidev/bin/powerpc-elf --mw-path=tools +if [ "$?" = "0" ]; then + echo "compile successful" +else + exit 1 +fi + +cp NewerASM/pal_loader.bin ~/Games/Newer/DolphinPatch/NewerRes/SystemEU_1.bin +cp NewerASM/ntsc_loader.bin ~/Games/Newer/DolphinPatch/NewerRes/SystemUS_1.bin +cp NewerASM/ntsc2_loader.bin ~/Games/Newer/DolphinPatch/NewerRes/SystemUS_2.bin +echo Built all! + diff --git a/src/bossMegaGoomba.cpp b/src/bossMegaGoomba.cpp index 65bbdb2..e6c2b0b 100644 --- a/src/bossMegaGoomba.cpp +++ b/src/bossMegaGoomba.cpp @@ -14,7 +14,6 @@ class daMegaGoomba_c : public dEn_c { m3d::mdl_c bodyModel; float timer; - nw4r::ut::Rect Bounding; float dying; HermiteKey keysX[0x10]; @@ -25,6 +24,35 @@ class daMegaGoomba_c : public dEn_c { // unsigned int Zkey_count; char life; + + //TODO use these for MegaGecko testing of params + u32 marker1_start; + nw4r::ut::Rect Bounding; + u32 marker1_end; + u32 marker2_start; + int pickedChoice; + u32 marker2_end; + u32 marker3_start; + float XSpeed; + u32 marker3_end; + u32 marker4_start; + float JumpHeight; + u32 marker4_end; + u32 marker5_start; + float JumpDist; + u32 marker5_end; + u32 marker6_start; + float JumpTime; + u32 marker6_end; + u32 marker7_start; + int playIt; + u32 marker7_end; + u32 marker8_start; + int toPlay; + u32 marker8_end; + u32 marker9_start; + u32 marker9_end; + bool takeHit(char count); void dieFall_Execute(); @@ -192,18 +220,45 @@ int daMegaGoomba_c::onCreate() { this->aPhysics.initWithStruct(this, &HitMeBaby); this->aPhysics.addToList(); - pos.y -= 20.0; + pos.y -= 16.0; pos.z = 3000.0; rot.x = rot.y = rot.z = speed.x = dying = 0.0; direction = 0; life = 3; //TODO 1) allow setting bounding rect with settings //TODO 2) don't use bounding rect. use wall/floor/ceiling detection - Bounding.left = pos.x - 350.0; + Bounding.left = pos.x - 212.0; Bounding.top = pos.y + 500.0; - Bounding.right = pos.x + 350.0; + Bounding.right = pos.x + 212.0; Bounding.bottom = pos.y; + //TODO for tests + this->marker1_start = 0xaabbcc11; + this->marker1_end = 0xaabbff11; + this->marker2_start = 0xaabbcc12; + this->marker2_end = 0xaabbff12; + this->marker3_start = 0xaabbcc13; + this->marker3_end = 0xaabbff13; + this->marker4_start = 0xaabbcc14; + this->marker4_end = 0xaabbff14; + this->marker5_start = 0xaabbcc15; + this->marker5_end = 0xaabbff15; + this->marker6_start = 0xaabbcc16; + this->marker6_end = 0xaabbff16; + this->marker7_start = 0xaabbcc17; + this->marker7_end = 0xaabbff17; + this->marker8_start = 0xaabbcc18; + this->marker8_end = 0xaabbff18; + this->marker9_start = 0xaabbcc19; + this->marker9_end = 0xaabbff19; + this->pickedChoice = -1; + this->XSpeed = 2.0; // GOOD FOR FINAL SPEED? + this->JumpHeight = 48.0; + this->JumpDist = 64.0; + this->JumpTime = 50.0; + this->playIt = 0; + this->toPlay = 0; + OSReport("Setting MegaGoomba's State\n"); doStateChange(&StateID_Grow); @@ -241,21 +296,23 @@ int daMegaGoomba_c::onDraw() { void daMegaGoomba_c::updateModelMatrices() { // Bounds checking // TODO possibly change to a state change - if(this->pos.x < this->Bounding.left) { - this->direction = !this->direction; - this->speed.x = -this->speed.x; - this->pos.x = this->Bounding.left; - } else if (this->pos.x > this->Bounding.right) { - this->direction = !this->direction; - this->speed.x = -this->speed.x; - this->pos.x = this->Bounding.right; - } - if(this->pos.y < this->Bounding.bottom) { - this->speed.y = 0.0; - this->pos.y = this->Bounding.bottom; - } else if (this->pos.y > this->Bounding.top) { - this->speed.y = 0.0; - this->pos.y = this->Bounding.bottom; + if(this->life > 0) { + if(this->pos.x < this->Bounding.left) { + this->direction = !this->direction; + this->speed.x = -this->speed.x; + this->pos.x = this->Bounding.left; + } else if (this->pos.x > this->Bounding.right) { + this->direction = !this->direction; + this->speed.x = -this->speed.x; + this->pos.x = this->Bounding.right; + } + if(this->pos.y < this->Bounding.bottom) { + this->speed.y = 0.0; + this->pos.y = this->Bounding.bottom; + } else if (this->pos.y > this->Bounding.top) { + this->speed.y = 0.0; + this->pos.y = this->Bounding.bottom; + } } // This won't work with wrap because I'm lazy. @@ -345,22 +402,34 @@ void daMegaGoomba_c::executeState_Launch() { this->rot.y = sin(this->timer * 3.14 / 5) * 4000; dStageActor_c *spawner = NULL; - // 120ticks / 40numbers * 2cases = 6avg kuribo - int randChoice = GenerateRandomNumber(40); + // 120ticks / 80numbers * 4cases = 6avg kuribo + int randChoice = GenerateRandomNumber(80); int randChoiceX = GenerateRandomNumber(12); - int randChoiceY = GenerateRandomNumber(12); + int randChoiceY = GenerateRandomNumber(7); switch(randChoice) { case 0: case 1: spawner = CreateActor(EN_KURIBO, 0, this->pos, 0, 0); spawner->speed.x = randChoiceX - 6.0; - spawner->speed.y = randChoiceY * 1.0; + spawner->speed.y = randChoiceY + 3.0; spawner->scale = (Vec){1.0, 1.0, 1.0}; break; case 2: spawner = CreateActor(EN_BEANS_KURIBO, 0, this->pos, 0, 0); - spawner->speed.x = randChoiceX - 12.0; - spawner->speed.y = randChoiceY * 1.0; + spawner->speed.x = randChoiceX - 6.0; + spawner->speed.y = randChoiceY + 3.0; + spawner->scale = (Vec){1.0, 1.0, 1.0}; + break; + case 3: + spawner = CreateActor(EN_PATA_KURIBO, 0, this->pos, 0, 0); + spawner->speed.x = randChoiceX - 6.0; + spawner->speed.y = randChoiceY + 3.0; + spawner->scale = (Vec){1.0, 1.0, 1.0}; + break; + case 4: + spawner = CreateActor(EN_MAME_KURIBO, 0, this->pos, 0, 0); + spawner->speed.x = randChoiceX - 6.0; + spawner->speed.y = randChoiceY + 3.0; spawner->scale = (Vec){1.0, 1.0, 1.0}; break; default: @@ -380,9 +449,9 @@ void daMegaGoomba_c::beginState_Jump() { this->timer = 1.0; //Variables for choosing a curve - float jump_height = 36.0; - float delta = (this->direction) ? -24.0 : 24.0; - float fullTime = 90.0; + float jump_height = this->JumpHeight; + float delta = (this->direction) ? -JumpDist : JumpDist; + float fullTime = this->JumpTime; //Key count Xkey_count = 2; Ykey_count = 3; @@ -404,7 +473,7 @@ void daMegaGoomba_c::executeState_Jump() { this->pos.x = GetHermiteCurveValue(this->timer, this->keysX, Xkey_count); this->pos.y = GetHermiteCurveValue(this->timer, this->keysY, Ykey_count); - float TimerMax = 91.0; + float TimerMax = JumpTime + 1.0; if (this->timer > TimerMax) { doStateChange(&StateID_Walk); } @@ -423,14 +492,24 @@ void daMegaGoomba_c::beginState_Walk() { } void daMegaGoomba_c::executeState_Walk() { - float delta = (this->direction) ? -0.5 : 0.5; + float delta = (this->direction) ? -this->XSpeed : this->XSpeed; this->pos.x += delta; int Choice; float TimerMax = 150.0; if (this->timer > TimerMax) { - Choice = GenerateRandomNumber(4); + if(this->pickedChoice != -1) { + Choice = this->pickedChoice; + /* + if(this->playIt = 1) { + playSound(this->toPlay); + this->playIt = 0; + } + */ + } else { + Choice = GenerateRandomNumber(4); + } switch(Choice) { case 0: doStateChange(&StateID_Jump); diff --git a/src/codehandler.o b/src/codehandler.o Binary files differnew file mode 100644 index 0000000..d14757e --- /dev/null +++ b/src/codehandler.o diff --git a/src/codehandler.real.s b/src/codehandler.real.s new file mode 100755 index 0000000..37d7df5 --- /dev/null +++ b/src/codehandler.real.s @@ -0,0 +1,821 @@ +# initial setup
+# * add exception handling for all cases
+# many breakpoints handling
+# * add breakpoint list with addresses
+# * add breakpoint list with original values
+# allow PPC side searches
+# * u32 with number of matches
+# * list of addresses that match
+# breakpoint conditions
+# * address == foo
+# * &&
+# * r* == bar
+# * r* != bar
+# * r* > bar
+# * r* < bar
+
+.text
+
+.set r0,0; .set r1,1; .set r2,2; .set r3,3; .set r4,4
+.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9
+.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14
+.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19
+.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24
+.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29
+.set r30,30; .set r31,31; .set f0,0; .set f2,2; .set f3,3
+
+.globl _start
+
+gameid:
+.long 0,0
+cheatdata:
+.long frozenvalue
+.space 39*4
+
+_start:
+ stwu r1,-168(r1) # stores sp
+ stw r0,8(r1) # stores r0
+
+ mflr r0
+ stw r0,172(r1) # stores lr
+
+ mfcr r0
+ stw r0,12(r1) # stores cr
+
+ mfctr r0
+ stw r0,16(r1) # stores ctr
+
+ mfxer r0
+ stw r0,20(r1) # stores xer
+
+ stmw r3,24(r1) # saves r3-r31
+
+ mfmsr r25
+ ori r26,r25,0x2000 #enable floating point ?
+ andi. r26,r26,0xF9FF
+ mtmsr r26
+
+ stfd f2,152(r1) # stores f2
+ stfd f3,160(r1) # stores f3
+
+ lis r20, 0xCC00
+ lhz r28, 0x4010(r20)
+ ori r21, r28, 0xFF
+ sth r21, 0x4010(r20) # disable MP3 memory protection
+
+_check_state:
+ lis r31, state@h
+ ori r31, r31, state@l
+ lwz r31, 0(r31)
+ cmpwi r31, 0
+ bne- _setvalues
+
+_init_exceptions:
+ # 4,3,5,17 are trampled
+ lis r4,bphandler@h
+ ori r4,r4,bphandler@l
+ lis r3,0x8000
+ ori r3,r3,0x300 # bprw 0x80000300
+ bl writebranch
+
+ addi r3,r3,0xA00 # trace 0x80000D00
+ bl writebranch
+
+ addi r3,r3,0x600 # bpx 0x80001300
+ bl writebranch
+
+ li r5, 1
+ lis r31, state@h
+ ori r31, r31, state@l
+ stw r5, 0(r31) # set state to 1 (exception handling linked)
+
+_setvalues:
+ li r21,0
+ li r22,0x19
+ li r23,0xD0
+ lis r24,0xCD00
+
+ lis r18, frozenvalue@h
+ ori r18, r18, frozenvalue@l # read buffer just store in lowmem
+ lwz r0,172(r1) # loads lr
+ stw r0,4(r18) # stores lr
+ stw r21, 0x643C(r24) # exi speed up
+
+frozen:
+ bl exireceivebyte
+ beq finish # r3 returns 1 or 0, one for byte received ok
+
+checkcommand:
+
+ cmpwi r29, 0x04 # checks lf 8/1/32 bits write command
+ bge _nextcommand
+ cmpwi r29, 0x01
+ blt finish
+ b writedword #write value to address
+_nextcommand:
+ beq readmem
+ cmpwi r29, 0x06
+ beq freezegame
+ cmpwi r29, 0x07
+ beq unfreezegame
+ cmpwi r29, 0x08
+ beq resumegame
+ cmpwi r29, 0x09
+ beq breakpoints #ibp
+ cmpwi r29, 0x10
+ beq breakpoints #dbp
+ cmpwi r29, 0x2F
+ beq upbpdata
+ cmpwi r29, 0x30
+ beq getbpdata
+ cmpwi r29, 0x38
+ beq cancelbreakpoints
+ cmpwi r29, 0x41
+ beq uploadcode
+ cmpwi r29, 0x44
+ beq breakpoints #step
+ cmpwi r29, 0x50
+ beq pausestatus
+ cmpwi r29, 0x89
+ beq breakpoints #aligned dbp
+ cmpwi r29, 0x99
+ beq versionnumber
+ b finish
+
+#******************************************************************
+# subroutine: getpausestatus:
+# one running, two paused, three on a breakpoint
+#******************************************************************
+
+pausestatus:
+ lwz r3,0(18)
+ bl exisendbyte
+ b finish
+
+
+#******************************************************************
+# subroutine: freezegame:
+# Write a 1 to a memory location to freeze
+#******************************************************************
+
+freezegame:
+ li r4, 1
+ stw r4, 0(r18)
+ b finish
+
+#******************************************************************
+# subroutine: unfreezegame:
+# Write a 0 to a memory location to unfreeze
+#******************************************************************
+
+unfreezegame:
+ stw r21, 0(r18)
+ b resumegame
+
+#******************************************************************
+# subroutine: upload bp data:
+# receive the dp databuffer from the PC
+#******************************************************************
+
+upbpdata:
+ bl exisendbyteAA
+
+ li r16, 40*4 # 42 "registers rN" * 4
+ lis r12, regbuffer@h
+ ori r12, r12, regbuffer@l
+ b upload
+
+#******************************************************************
+# subroutine: getbp data:
+# send the dp databuffer to the PC
+#******************************************************************
+
+getbpdata:
+ li r3, 72*4 # register buffer
+ lis r12, regbuffer@h
+ ori r12, r12, regbuffer@l
+ bl exisendbuffer # send it, less than a packet
+ b finish
+
+
+#******************************************************************
+# subroutine: breakpoints:
+# handles data/instruction address breakpoints
+#******************************************************************
+
+breakpoints:
+
+ cmpwi cr6,r29,0x10 # 0x10=instruction, 0x09/0x89=data
+ cmpwi cr5,r29,0x44 # 0x44=step
+
+ lis r4, bphandler@h
+ ori r4,r4,bphandler@l #used for writebranch (=source address)
+
+ lis r3,0x8000
+ ori r3,r3,0x300 # bprw 0x80000300
+ bl writebranch
+
+ addi r3,r3,0xA00 # trace 0x80000D00
+ bl writebranch
+
+ addi r3,r3,0x600 # bpx 0x80001300
+ bl writebranch
+
+ lis r12, bpbuffer@h
+ ori r12, r12, bpbuffer@l # read buffer just store in lowmem
+
+ stw r21,0(r12) # clears inst bp
+ stw r21,4(r12) # clears data bp
+ stw r21,8(r12) # clears alignement
+
+ lis r4, regbuffer@h
+ ori r4, r4, regbuffer@l
+ lwz r9,0x18(r4)
+
+ lwz r3,0(r18)
+ cmpwi r3,2 # checks if the gecko is on a breakpoint
+ bne +12
+ beq cr5,+12
+ b bp
+ li r3,0
+ stw r3,12(r12) # if not, clears the previous "broken on" address
+
+ bne bp
+
+ bne cr5,bp
+ ori r9,r9,0x400
+ stw r9,0x18(r4)
+ b unfreezegame
+
+bp:
+ rlwinm r9,r9,0,22,20
+ stw r9,0x18(r4)
+ beq cr5,finish
+ beq cr6,+8
+ addi r12,r12,4 # if databp r12=r12+4
+
+ li r3, 4 # 4 bytes
+ bl exireceivebuffer
+
+ ble cr6,noalignement # if not aligned data bp (0x89)
+
+ addi r12,r12,4
+
+ li r3, 4 # 4 bytes
+ bl exireceivebuffer
+
+noalignement:
+ lis r4, bpbuffer@h
+ ori r4, r4, bpbuffer@l # read buffer just store in lowmem
+
+ lwz r3, 0(r4) # inst bp
+ lwz r4, 4(r4) # data bp
+ mtspr 1010, r3 # set IABR
+ mtspr 1013, r4 # set DABR
+ b finish
+
+#******************************************************************
+# subroutine: bphandler
+# Data/Instruction address breakpoint handler, save context and return
+#******************************************************************
+
+#FIXME
+bphandler:
+ mtsprg 2,r1 # sprg2 = r1
+ lis r1, regbuffer@h
+ ori r1, r1, regbuffer@l
+ mtsprg 3,r3 # sprg3 = r3
+ mfsrr1 r3 # r3=srr1
+ rlwinm r3,r3,0,22,20 # clear trace
+ stw r3, 0x18(r1)
+ rlwinm r3,r3,0,24,15
+ ori r3,r3,0x2000
+ mfsrr0 r1 # r1=srr0
+
+# rlwinm r3,r3,0,17,15 # clear hw interrupt
+ mtsrr1 r3 # restore srr1 with hw interrupt & trace cleared
+
+ lis r3,break@h
+ ori r3,r3,break@l
+ mtsrr0 r3
+ rfi
+
+break:
+ lis r3, regbuffer@h
+ ori r3, r3, regbuffer@l
+ stw r1,0x14(r3) #stores srr0
+
+ mr r1,r3
+ mfsprg r3,3
+ stmw r2,0x24(r1) #saves r2-r31
+ mr r4,r1
+ mfsprg r1,2
+
+ stw r0,0x1C(r4)
+ stw r1,0x20(r4)
+
+ mflr r3
+ stw r3, 0x9C(r4) # Store LR
+
+ mfcr r3
+ stw r3, 0x0(r4) # Store CR
+
+ mfxer r3
+ stw r3, 0x4(r4) # Store XER
+
+ mfctr r3
+ stw r3, 0x8(r4) # Store CTR
+
+ mfdsisr r3
+ stw r3, 0xC(r4) # Store DSISR
+
+ mfdar r3
+ stw r3, 0x10(r4) # Store DAR
+
+ li r9,0
+ mtspr 1010,r9 # Clear IABR
+ mtspr 1013,r9 # Clear DABR
+
+ lis r5,floatstore@h
+ ori r5,r5,floatstore@l # Set r5 to instruction address
+ lis r31,0xD004
+ ori r31,r31,0x00A0 # Set r31 to 'stfs f0,0xA0(r4)' (==0xD00400A0)
+floatloop:
+ stw r31,0(r5)
+ dcbst r0,r5
+ sync
+ icbi r0,r5
+ isync
+floatstore:
+ stfs f0,0xA0(r4)
+ addi r31,r31,4 # Advance instruction offset
+ addis r31,r31,0x20 # Advance instruction register
+ rlwinm. r16,r31,0,5,5 # Check for register > 31
+ beq floatloop
+
+skip_floating_point:
+
+ lis r5, bpbuffer@h
+ ori r5,r5,bpbuffer@l
+
+ lwz r16,0(r5) # inst bp
+ lwz r17,4(r5) # data bp
+ lwz r19,12(r5) # counter for alignment
+
+ cmpwi r19,0
+ beq _redobp
+
+ cmpwi r19,2
+ bne +24
+ lwz r9,0x14(r4)
+ addi r9,r19,3
+ stw r9,0(r5) # inst bp
+ stw r9,12(r5) # counter for alignment
+ b _executebp
+
+ cmpw r16,r19
+ beq _step
+
+ cmpw r17,r19
+ beq _step
+
+ add r9,r16,r17
+ stw r9,12(r5) # counter for alignment
+
+
+_alignementcheck:
+ lwz r16,8(r5) # bp alignment check
+ cmpwi r16,0
+ beq _executebp # no alignement = normal break
+
+ lwz r3,0x10(r4)
+ cmpw r16,r3 # we check if address = aligned address
+ bne _step # if no, we need to set a bp on the next instruction
+
+ li r16,0
+ stw r16,8(r5) # if we are on the good address we clear the aligned bp check
+ b _executebp # and we break
+
+_step:
+ li r17,0
+ stw r17,12(r5) # counter for alignment
+ lwz r9,0x18(r4)
+ ori r9,r9,0x400
+ stw r9,0x18(r4)
+ b _skipbp #and we don't break right now
+
+_redobp:
+ mtspr 1010,r16 # we set back the instbp with the original value
+ mtspr 1013,r17 # we set back the databp with the original value
+ li r9,1
+ stw r9,12(r5) # counter for alignment
+ b _skipbp # and we don't break
+
+_executebp:
+ li r5, 2
+ lis r4, frozenvalue@h
+ ori r4, r4, frozenvalue@l # Freeze once returned to let user know there is a breakpoint hit
+ stw r5, 0(r4)
+
+ li r3, 0x11
+ bl exisendbyte # tell the PC a bp has happened (send 0x11)
+
+ bl _start # bl mainloop, so you can set up a new breakpoint.
+
+_skipbp:
+ mfmsr r1
+ rlwinm r1,r1,0,31,29
+ rlwinm r1,r1,0,17,15
+ mtmsr r1 # we disable the interrupt so nothing interfers with the restore
+
+ lis r1, regbuffer@h
+ ori r1, r1, regbuffer@l
+
+ lwz r3,0x0(r1)
+ mtcr r3 # restores CR
+ lwz r3,0x14(r1)
+ mtsrr0 r3 # restores SRR0
+ lwz r3,0x18(r1)
+ mtsrr1 r3 # restores SRR1
+ lwz r3,0x9C(r1)
+ mtlr r3 # restores LR
+
+ lmw r2,0x24(r1) # restores r2-r31
+
+ lwz r0,0x1C(r1) # restores r0
+ lwz r1,0x20(r1) # restores r1
+
+ rfi # back to the game
+
+#******************************************************************
+# subroutine: write dword:
+# Write a long word value to memory sent from PC
+#******************************************************************
+
+writedword:
+ cmpwi cr5,r29,2
+ li r3, 8 # 8 bytes (location 4 / Value 4)
+
+ lis r12, dwordbuffer@h
+ ori r12, r12, dwordbuffer@l # buffer
+ bl exireceivebuffer
+
+ lwz r5, 0(r12)
+ lwz r3, 4(r12) # read the value
+ stb r3, 0(r5) # write to location
+ blt cr5,skipp
+ sth r3, 0(r5) # write to location
+ beq cr5,skipp
+ stw r3, 0(r5) # write to location
+ skipp:
+ dcbf r0, r5 # data cache block flush
+ sync
+ icbi r0, r5
+ isync
+ b finish
+
+#******************************************************************
+# subroutine: Upload :
+# Fill memory with value
+#******************************************************************
+
+uploadcode:
+ bl exisendbyteAA
+
+ li r3, 8 # 8 bytes
+ lis r12, dwordbuffer@h
+ ori r12, r12, dwordbuffer@l # buffer
+
+ bl exireceivebuffer
+
+ lwz r16, 4(r12)
+ lwz r12, 0(r12)
+
+upload:
+ lis r27, rem@h
+ ori r27, r27, rem@l # Remainder of bytes upload code
+ li r17,0xF80
+ bl _packetdivide
+ beq douploadremainder
+
+nextrecpacket:
+ mr r3,r17
+ bl exireceivebuffer # r12 start = start of buffer
+
+uploadwait:
+ bl exisendbyteAA
+ beq uploadwait
+ add r12,r12,r14
+
+ subic. r11, r11, 1 # decrease loop counter
+ bgt nextrecpacket
+
+douploadremainder: # send the remainder bytes
+ lwz r3, 0(r27) # remainder
+ cmpwi r3,0
+ beq finishupload
+ bl exireceivebuffer
+finishupload:
+ dcbf r0, r12 # data cache block flush
+ sync
+ icbi r0, r12 # instruction cache block flush
+ isync
+ b finish
+
+#******************************************************************
+# subroutine: exireceivebyte:
+# Return 1(r3) if byte receive, 0(r3) if no byte
+# Command byte is stored at 0x800027ff
+#******************************************************************
+
+exireceivebyte:
+ mflr r30
+ lis r3, 0xA000 # EXI read command
+
+ bl checkexisend
+
+ andis. r3, r16, 0x800
+ rlwinm r29,r16,16,24,31
+ mtlr r30
+ blr
+
+#******************************************************************
+# subroutine: checkexisend:
+#
+#******************************************************************
+
+checkexisend:
+
+ stw r23, 0x6814(r24) # 32mhz Port B
+ stw r3, 0x6824(r24)
+ stw r22, 0x6820(r24) # 0xCC006820 (Channel 1 Control Register)
+
+exicheckreceivewait:
+ lwz r5, 0x6820(r24)
+ andi. r5, r5, 1
+ bne exicheckreceivewait # while((exi_chan1cr)&1);
+
+ lwz r16, 0x6824(r24)
+ stw r5, 0x6814(r24)
+
+ blr
+
+#******************************************************************
+# subroutine: exireceivebuffer:
+# r3 byte counter, r12 points to buffer, r3 gets copied as gets destroyed
+#******************************************************************
+
+exireceivebuffer:
+ mflr r10 # save link register
+ mtctr r3 # counter
+ li r14,0
+
+bufferloop:
+ bl exicheckreceive
+ bl exicheckreceive
+ bl exireceivebyte
+ beq bufferloop # r3 returns 1 or 0, one for byte received ok
+
+ stbx r29, r14,r12 # store byte into buffer
+
+ addi r14, r14, 1 # increase buffer by 1
+ bdnz bufferloop
+
+ mtlr r10 # retore link register
+ blr # return to command check
+
+#******************************************************************
+# exisendbuffer:
+# r3 byte counter, r12 points to buffer, r3 gets copied as gets destroyed
+#******************************************************************
+
+exisendbuffer:
+ mflr r10 # save link register
+ mtctr r3 # r3->counter
+ li r14,0
+
+sendloop:
+ lbzx r3, r12,r14
+ bl exisendbyte
+ beq sendloop
+
+ addi r14, r14, 1 # increase buffer
+ bdnz sendloop
+ mtlr r10 # restore link register
+ blr
+
+#******************************************************************
+# exisendbyte:12345678
+# r3 byte to send, returns 1 if sent, 0 if fail (!!! called by breakpoint)
+#******************************************************************
+exisendbyteAA:
+ li r3,0xAA
+
+exisendbyte: # r3, send value
+ mflr r30
+ slwi r3, r3, 20 # (sendbyte<<20);
+ oris r3, r3, 0xB000 # 0xB0000000 | (OR)
+ li r22,0x19
+ li r23,0xD0
+ lis r24,0xCD00
+
+ bl checkexisend
+
+ extrwi. r3, r16, 1,5 # returns either 0 or 1, one for byte received ok
+ mtlr r30
+ blr
+
+#******************************************************************
+# subroutine: exicheckrecieve:
+# Return 1(r3) lf byte receive, 0(r3) lf no byte
+#******************************************************************
+
+exicheckreceive:
+ mflr r30
+exicheckreceive2:
+ lis r3, 0xD000 # EXI check status command
+
+ bl checkexisend
+
+ rlwinm. r3,r16,6,31,31 # returns either 0 or 1 for r3
+
+ beq exicheckreceive2
+ mtlr r30
+ blr
+
+#******************************************************************
+# Readmem: (reads a memory range back to PC)
+# r3 byte to send, returns 1 lf sent, 0 lf fail
+#******************************************************************
+
+readmem:
+ bl exisendbyteAA
+
+ li r3, 8 # 8 bytes
+ lis r12, dwordbuffer@h
+ ori r12, r12, dwordbuffer@l # buffer
+
+ bl exireceivebuffer
+
+ lwz r5, 4(r12)
+ lwz r12, 0(r12)
+
+ lis r27, rem@h
+ ori r27, r27, rem@l # place holder for remainder bytes
+
+ ori r17, r21, 0xF800 # 64K packet
+ sub r16, r5, r12 # memrange = (*endlocation - *startlocation)
+
+ bl _packetdivide
+
+nextsendpacket:
+ bgt transfer #compares r11 and 0
+ lwz r17, 0(r27) # remainder
+ cmpwi r17,0
+ beq finish
+transfer:
+ mr r3,r17 # number of bytes
+ bl exisendbuffer
+
+bytewait1:
+ bl exicheckreceive
+ bl exicheckreceive
+ bl exireceivebyte
+ beq bytewait1 # r3 returns 1 or 0, one for byte received ok
+ cmpwi r29, 0xCC # cancel code
+ beq finish
+ cmpwi r29, 0xBB # retry code
+ beq transfer
+ cmpwi r29, 0xAA
+ bne bytewait1
+ add r12,r12,r14
+ subic. r11, r11, 1 # decrease loop counter
+ blt finish
+ b nextsendpacket
+
+#******************************************************************
+# Cancel Breakpoints
+# Clears instruction and data and step breakpoints
+#******************************************************************
+
+cancelbreakpoints:
+ mtspr 1013, r21 # clear the DABR
+ mtspr 1010, r21 # clear the IABR
+ lis r4, regbuffer@h
+ ori r4, r4, regbuffer@l
+ lwz r9,0x18(r4)
+ rlwinm r9,r9,0,22,20
+ stw r9,0x18(r4)
+ b finish
+
+#******************************************************************
+# subroutine: version number
+# Sends back the current gecko version number.
+#******************************************************************
+
+versionnumber:
+ li r3, 0x80 #0x80 = Wii, 0x81 = NGC
+ bl exisendbyte
+ #b finish
+
+#******************************************************************
+# Finish
+# Check if the gecko has been paused. if no return to game
+#******************************************************************
+
+finish:
+ lwz r4, 0(r18)
+ cmpwi r4, 0 # check to see if we have frozen the game
+ bne frozen # loop around if we have
+ # (changed to return for the bp)
+
+resumegame:
+
+ sth r28,0x4010(r20) # restore memory protection value
+
+ lfd f2,152(r1) # loads f2
+ lfd f3,160(r1) # loads f3
+
+ mfmsr r25
+
+ lwz r0,172(r1)
+ mtlr r0 # restores lr
+
+ lwz r0,12(r1)
+ mtcr r0 # restores cr
+
+ lwz r0,16(r1)
+ mtctr r0 # restores ctr
+
+ lwz r0,20(r1)
+ mtxer r0 # restores xer
+
+ lmw r3,24(r1) # restores r3-r31
+
+ lwz r0,8(r1) # loads r0
+
+ addi r1,r1,168
+
+ isync
+
+ blr # return back to game
+
+#******************************************************************
+# Write branch
+# r3 - source (our mastercode location)
+# r4 - destination (lowmem area 0x80001800 address which will branch to
+#******************************************************************
+writebranch:
+
+ subf r17, r3, r4 # subtract r3 from r4 and place in r17
+ lis r5, 0x4800 # 0x48000000
+ rlwimi r5,r17,0,6,29
+ stw r5, 0(r3) # result in r3
+
+ dcbf r0, r3 # data cache block flush
+ sync
+ icbi r0, r3
+ isync
+
+ blr # return
+
+
+#******************************************************************
+# Packet Divide
+# Used by the down/up routines to calculate the number of packet to send
+#******************************************************************
+
+_packetdivide:
+ divw. r11, r16, r17 # fullpackets = memrange / 0xF80 (r11 is full packets)
+ mullw r10, r11, r17
+ subf r10, r10, r16 # r10 holds remainder byte counter
+ stw r10, 0(r27) # store remainder
+ blr
+
+#==================================================================
+
+frozenvalue: #frozen value, then LR
+.long 0,0
+dwordbuffer:
+.long 0,0
+rem:
+.long 0
+bpbuffer:
+.long 0 #inst address to bp on
+.long 0 #data address to bp on
+.long 0 #alignement check
+.long 0 #counter for alignement
+
+regbuffer:
+.space 72*4
+
+state:
+.long 0 # 0=none 1=linked 2=???
+
+.align 3
+
+codelist:
+.space 2*4
+.end
+
+
diff --git a/tools/kamek.py b/tools/kamek.py index f67f049..3f7fb5c 100644 --- a/tools/kamek.py +++ b/tools/kamek.py @@ -306,16 +306,19 @@ class KamekBuilder(object): objfile = os.path.join(self._configTempDir, '%d.o' % generate_unique_id()) sourcefile = os.path.join(m.moduleDir, normal_sourcefile) - # todo: better extension detection - if sourcefile.endswith('.s') or sourcefile.endswith('.S'): - command = as_command + if sourcefile.endswith('.o'): + new_command = ['cp', sourcefile, objfile] else: - command = cc_command - - new_command = command + ['-c', '-o', objfile, sourcefile] - - if 'cc_args' in m.data: - new_command += m.data['cc_args'] + # todo: better extension detection + if sourcefile.endswith('.s') or sourcefile.endswith('.S'): + command = as_command + else: + command = cc_command + + new_command = command + ['-c', '-o', objfile, sourcefile] + + if 'cc_args' in m.data: + new_command += m.data['cc_args'] if show_cmd: print_debug(new_command) @@ -428,6 +431,9 @@ class KamekBuilder(object): def _find_func_by_symbol(self, find_symbol): for sym in self._symbols: + #if show_cmd: + # out = "0x%08x - %s - %s" % (sym[0], sym[1], sym[2]) + # print_debug(out) if sym[2] == find_symbol: return sym[0] |