Register | Login
Views: 19364387
Main | Memberlist | Active users | ACS | Commons | Calendar | Online users
Ranks | FAQ | Color Chart | Photo album | IRC Chat
11-02-05 12:59 PM
0 user currently in Programming. | 3 guests
Acmlm's Board - I2 Archive - Programming - Help with some N64 code | |
Add to favorites | "RSS" Feed | Next newer thread | Next older thread
User Post
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 4935/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 06-12-05 11:46 AM Link | Quote
Alright, so this is a chunk of code I'm trying to hack into Zelda OoT (US V1.2) with a Gameshark:
sw $a0,0000($sp) ;Save $a0 and $a1
sw $a1,0004($sp)
lui $a1,801C
addiu $a1,$zero,8D75 ;Get joypad status
addiu $a0,$zero,0000
lb $a0,0000($a1)
addiu $a1,$zero,0030 ;Value for L+R
and $a0,$a1,$a0 ;L+R pressed?
bne $a0,$a1,.end ;No
nop
lui $a1,8011
addiu $a1,$zero,C089 ;Language addr
addiu $a0,$zero,0000
lb $a0,0000($a1)
addiu $a0,$a0,0001 ;Next
andi $a0,$a0,0001 ;But don't go past 1
sb $a0,0000($a1) ;Store it

.end: ;009344
lw $a1,0004($sp) ;Restore regs
lw $a0,0000($sp)
[original op: lbu $t6,C089($t6)]
jr $ra
[original op: lh $t9,4A56($t0)]


The code is placed at 80009300 in RAM and hooked with the instructions jal 9300 and nop at 803B04C0. What it's supposed to do is this:

1) Read a byte from 801C8D75 (low byte of the joypad input).
2) If bits 4 and 5 aren't set, exit. (Otherwise, L and R are pressed.)
3) Read a byte from 8011C089 (language select).
4) If it's 0, make it 1, and vice-versa.
5) Write it back to 8011C089 and exit.

The problem, according to the game's useful on-board exception handler, is that somehow the wrong address is being accessed, because the first LUI instruction doesn't work. When it gets to lb $a0,0000($a1), $a1 should be 801C8D75, but it's FFFF8D75. I've checked the code against the ASM and tried using $k1 in place of $a1, to no avail. (The exception handler doesn't show $k1, but it does show what appears to be the address that was being accessed, and it's FFFF8D75 just like with $a1.) I can't see any reason why this would be happening...

Here's the actual Gameshark code. It's kinda messy because it's been hacked to use $k1 and thus the parts where $a1 is moved to and from the stack were NOPed out in case that was causing any problems, and other such things.
81009300 AFA4
81009302 0000
81009304 0000
81009306 0000
81009308 3C1B
8100930A 801C
8100930C 241B
8100930E 8D75
81009310 2404
81009312 0000
81009314 8364
81009316 0000
81009318 241B
8100931A 0030
8100931C 0364
8100931E 2024
81009320 149B
81009322 0008
81009324 0000
81009326 0000
81009328 3C1B
8100932A 8011
8100932C 241B
8100932E C089
81009330 2404
81009332 0000
81009334 8364
81009336 0000
81009338 2484
8100933A 0001
8100933C 3084
8100933E 0001
81009340 A364
81009342 0000
81009344 0000
81009346 0000
81009348 8FA4
8100934A 0000
8100934C 91CE
8100934E C089
81009350 03E0
81009352 0008
81009354 8519
81009356 4A56
813B04C0 0C00
813B04C2 24C0
813B04C4 2400


(edited by HyperHacker on 06-11-05 06:48 PM)
Ramsus

Octoballoon
Level: 19

Posts: 92/162
EXP: 34651
For next: 1126

Since: 01-24-05
From: United States

Since last post: 39 days
Last activity: 71 days
Posted on 06-13-05 01:45 AM Link | Quote

lui $a1,801C
addiu $a1,$a1,8D75 ;Get joypad status



(edited by Ramsus on 06-12-05 08:47 AM)
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 4949/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 06-13-05 04:22 AM Link | Quote
Hmm, that makes sense. Wouldn't I have to ensure the lower half of $a1 is zero before I do that though?
Ramsus

Octoballoon
Level: 19

Posts: 95/162
EXP: 34651
For next: 1126

Since: 01-24-05
From: United States

Since last post: 39 days
Last activity: 71 days
Posted on 06-13-05 04:24 AM Link | Quote
I thought the same thing, but the description of lui I found says it zeros the bottom half.
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 4950/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 06-13-05 04:41 AM Link | Quote
Well that fixed the crashing, now I just need to figure out why it isn't doing anything.
Ramsus

Octoballoon
Level: 19

Posts: 96/162
EXP: 34651
For next: 1126

Since: 01-24-05
From: United States

Since last post: 39 days
Last activity: 71 days
Posted on 06-13-05 04:54 AM Link | Quote
Now this makes me want to try some ROM hacking.

And did you update the language address part too? That's about all I can suggest right now, since I don't know jack about N64 hardware or Zelda OoT.


(edited by Ramsus on 06-12-05 11:56 AM)
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 4951/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 06-13-05 07:07 AM Link | Quote
Yeah, I think I just need to find another place to stick the code. It doesn't seem to be getting executed in some places.

[edit] Well I found another place to put the code, tweaked it a bit ($s2 and $s3 aren't used so I don't have to use the stack anymore) and it's once again throwing logic out the window.

lui $s2,801C
addiu $s2,$s2,8D75 ;Get joypad status
addiu $s3,$zero,0000
lb $s3,0000($s2)
addiu $s2,$zero,0030 ;Value for L+R
and $s3,$s3,$s2 ;L+R pressed?
bne $s3,$s2,.end ;No
nop
lui $s2,8011
addiu $s2,$s2,C089 ;Language addr
addiu $s3,$zero,0000
lb $s3,0000($s2)
addiu $s3,$s3,0001 ;Next
andi $s3,$s3,0001 ;But don't go past 1
sb $s3,0000($s2) ;Store it

.end:
[original op: addiu $s3,$zero,0004]
j 0A2EBC
[original op: or $s2,$zero,$zero]


If L and R are pressed, it should be getting the language byte, modifying it, and storing it again. But it's not. If I put an invalid opcode in there, the CPU crashes when I hit the buttons just like it should, but somehow this code is just not doing anything. Also, I can't get the buttons to work right. The way it is now, it activates if L or R are pressed. Removing the 'and' that really doesn't need to be there anyway just disables it entirely.


(edited by HyperHacker on 06-12-05 03:34 PM)
Ramsus

Octoballoon
Level: 19

Posts: 97/162
EXP: 34651
For next: 1126

Since: 01-24-05
From: United States

Since last post: 39 days
Last activity: 71 days
Posted on 06-13-05 11:33 AM Link | Quote
How is the joypad status byte laid out? The L or R bug sounds kind of strange.

And are you sure the language byte is used during the game? Maybe it's checked at the beginning and used to set a function pointer somewhere.

Also, I'm only studying PowerPC and MMIX assembly, but try this:

lui $s2,801C
lbu $s3,8D75($s2) ;Get joypad status
addiu $s2,$zero,0030 ;Value for L+R
bne $s3,$s2,.end ;No
nop
lui $s2,8011
lb $s3,C089($s2) ;Language addr
addiu $s3,$s3,0001 ;Next
andi $s3,$s3,0001 ;But don't go past 1
sb $s3,C089($s2) ;Store it

.end:
[original op: addiu $s3,$zero,0004]
j 0A2EBC
[original op: or $s2,$zero,$zero]


EDIT:

I switched lb to lbu so it wouldn't set the upper 24 bits (or 56 bits if the registers are 64-bit) to whatever the sign bit of the loaded byte was. I think that might have been related to the L+R bug, but 0x30 in binary wouldn't have the sign bit anyway, so I doubt it. Let me know if it works, and if not, add the and instruction back in.



(edited by Ramsus on 06-12-05 06:41 PM)
(edited by Ramsus on 06-12-05 06:42 PM)
(edited by Ramsus on 06-12-05 06:51 PM)
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 4958/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 06-14-05 05:48 AM Link | Quote
I was considering doing C089($s2) instead of setting $s2's lower half, but since it's above 7FFF I figured that might not work right (like 80110000 - 3F77 or something). Using an unsigned byte for the controller layout, though it seems right, doesn't seem to work. Also yes, for some weird reason the game constantly checks its language setting and switches the text and fonts accordingly.
Ramsus

Octoballoon
Level: 19

Posts: 98/162
EXP: 34651
For next: 1126

Since: 01-24-05
From: United States

Since last post: 39 days
Last activity: 71 days
Posted on 06-14-05 06:55 AM Link | Quote
They probably had something rigged for the translation team so they could switch between languages while testing the game. Say there's something missing in English, they could switch it to Japanese.

I don't even know what the size of the instructions are, so follow what the programmers did with the game.

Are there any good debugging tools for N64 emulators? That's about all I can think of trying at this point.
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 4959/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 06-14-05 08:01 AM Link | Quote
There's Nemu if by some miracle I can get it running, and the Gameshark which doesn't help a whole lot without step-by-step execution. All instructions are 4 bytes.
neotransotaku

Baby Mario
戻れたら、
誰も気が付く
Level: 87

Posts: 3199/4016
EXP: 6220548
For next: 172226

Since: 03-15-04
From: Outside of Time/Space

Since last post: 11 hours
Last activity: 1 hour
Posted on 06-14-05 09:23 PM Link | Quote
how are you converting the ASM into Gameshark code?

some things to consider:

(1) have you tried lw? when you use lb/lbu, you have to consider endian issues. with lw, you don't have that problem unless the address you try to load from is not divisible by the size of a word

(2) instead of using that and to do the comparison between $s2 and $s3, why don't you use beq?
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 4979/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 06-15-05 01:52 AM Link | Quote
The AND was so that if you pressed, say, L + R + A it would still activate. I figured there's no point doing that though, so I removed it.

The conversion is a not-very-fun process of typing the ASM into Niew, copying the hex into Textpad, using regular expressions to format it into two-byte chunks and adding addresses. I can easily make simple changes to the code without having to do that though (like NOPing out an instruction or replacing it with an invalid one to see if it's even being executed).
neotransotaku

Baby Mario
戻れたら、
誰も気が付く
Level: 87

Posts: 3209/4016
EXP: 6220548
For next: 172226

Since: 03-15-04
From: Outside of Time/Space

Since last post: 11 hours
Last activity: 1 hour
Posted on 06-15-05 03:14 AM Link | Quote
maybe your branches don't work correctly when branching--other than monitoring registers, i'm not sure what else to help you with
Add to favorites | "RSS" Feed | Next newer thread | Next older thread
Acmlm's Board - I2 Archive - Programming - Help with some N64 code | |


ABII


AcmlmBoard vl.ol (11-01-05)
© 2000-2005 Acmlm, Emuz, et al



Page rendered in 0.019 seconds.