Change the bsr.w to a jsr and it should work fine - the error message is saying that the offset to the target label (-32798) is too big to fit in a bsr.w.
I thought it was one of those things that jsrs and jmps couldn't solve, and I should just leave it alone. It worked. You are a life saver.
Rule of thumb: bra.s --> bra.w --> jmp bsr.s --> bsr.w --> jsr It doesn't work for conditional branches though, you'd need to mix conditional branching and jumps in such a case. Luckily, that's an oddity and not the rule.
Got it, thanx. Hopefully that will give me enough frames to complete the movelist. Having a problem with getting combo button moves working in Sonic 2 asm now, here's my attempted code: Code (Text): ; --------------------------------------------------------------------------- ; Subroutine to do Jump Dash (code by Vladikcomper) ; --------------------------------------------------------------------------- ; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||||||||||||||||| Sonic_SpinHammer: btst #7,status(a0) ; was Jump Dash flag set? beq.b Sonic_SpinHammer_Rts ; if yes, branch move.b (Ctrl_1_Press_Logical).w,d0 btst #1,(Ctrl_1_Held_Logical).w; is down being pressed? beq.b Sonic_SpinHammer_Rts; if no, return and.b #$40,d0 ; get only button A cmpi.b #$40,d0 ;is A being pressed? beq.w Sonic_SpinHammer_Rts; if not, return move.w #$BC,d0 ; play sound jsr (PlaySound).l bset #7,status(a0) ; set Jump Dash flag move.b #$25,anim(a0) ; use spinning animation move.w #$650,y_vel(a0) ; set Jump Dash speed move.w #0,x_vel(a0) ; clear Y-velocity btst #0,status(a0) ; is sonic facing left? beq.s Sonic_SpinHammer_Rts ; if no, branch neg.w x_vel(a0) ; negate X-velocity Sonic_SpinHammer_Rts: rts ; End of function Sonic_SpinHammer It's based on the Jump Dash code from the SSRG (I've added the necessary coding outside the main branch as well), however I can't get it to work with the two button activation (hold down and A). Oh and another more minor question, what technique do you guys use to edit the text in Sonic 2 for characters (eg. to change who 'Got Through Act 1' or who you select on the options screen)? ASM, Text editor or something?
For the options screen, if you look at byte_97CA you'll see: Code (ASM): byte_97CA: dc.b $10,"* PLAYER SELECT *" byte_97DC: dc.b $E,"SONIC AND MILES" byte_97EC: dc.b $E,"SONIC AND TAILS" byte_97FC: dc.b $E," SONIC ALONE " byte_980C: dc.b $E," MILES ALONE " byte_981C: dc.b $E," TAILS ALONE " As for the end-of-act results... they're sprite mappings, but editing them in SonMapEd removes part of them, crashing the game.
Code (ASM): ; --------------------------------------------------------------------------- ; Subroutine to do Jump Dash (code by Vladikcomper) ; --------------------------------------------------------------------------- ; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||||||||||||||||| Sonic_SpinHammer: btst #7,status(a0) ; was Jump Dash flag set? beq.b Sonic_SpinHammer_Rts ; if yes, branch move.b (Ctrl_1_Press_Logical).w,d0 btst #1,d0; is down being pressed? beq.b Sonic_SpinHammer_Rts; if no, return and.b #$40,d0 ; get only button A cmpi.b #$40,d0 ;is A being pressed? bne.w Sonic_SpinHammer_Rts; if not, return move.w #$BC,d0 ; play sound jsr (PlaySound).l bset #7,status(a0) ; set Jump Dash flag move.b #$25,anim(a0) ; use spinning animation move.w #$650,y_vel(a0) ; set Jump Dash speed move.w #0,x_vel(a0) ; clear X-velocity ;btst #0,status(a0) ; is sonic facing left? ;beq.s Sonic_SpinHammer_Rts ; if no, branch ; those 3 lines aren't necessary because you are not even applying X velocity. ;neg.w x_vel(a0) ; negate X-velocity Sonic_SpinHammer_Rts: rts ; End of function Sonic_SpinHammer Fix'd it for you.
Code (ASM): cmpi.b #$FF,($FFFFCxxx).w bne.s Op_Next This is a check I'm going to use a lot. The only difference between each version, is the xxx, which is always a multiple of $48 + $A00 (basically $48 * X + $A00), while X is between 0 and 5. Is there a way to put that line into a bsr and make it look like this: Code (ASM): cmpi.b #$FF,($FFFFC($A00+($48*d0))).w bne.s Op_Next I know this does not work, but is the a way to do it? Or am I forced to calculate each line myself?
I believe you can do something like this: Code (Text): moveq #$0,d0 *give d0 its value here* mulu.w #$48,d0 addi.l $FFFFCA00,d0 movea.l d0, a6 cmpi.b #$FF,(a6) Not tested, because I'm not at home.
Either I'm too stupid, or that doesn't work. Here's the full code for me: Code (ASM): moveq #0,d2 ; make sure d2 is empty move.w ($FFFFFF9A).w,d2 ; get the number $48 needs to be multiplicated divu.w #2,d2 ; because this number works like 0, 2, 4, 6 etc, it needs to be halved mulu.w #$48,d2 ; multiplicate that number with $48 add.l $FFFFCA00,d2 ; add another $FFFFCA00 to it movea.l d2,a6 ; move the result to a6 cmp.l #$FF,a6 ; is the last byte of the calculated location $FF? beq.s Op_CheckOk ; if yes, branch move.w #1,d2 ; otherwise, set d2 to 1, for something which will be used later Almost forgot, my problem is that d2 always gets set to 1 at the end. My guess was the longword, but since I can't use bytes on address registers, I'm screwed.
Try Code (ASM): move.w ($FFFFFF9A).w,d2 ; get the number $48 needs to be multiplicated mulu.w #$24,d2 ; d2 / 2 * $48 = d2 * $24 add.w $CA00,d2 ; add another $CA00 to it movea.w d2,a6 ; sign extension takes place automatically cmp.b #$FF,(a6) ; is the last byte of the calculated location $FF? beq.s Op_CheckOk ; if yes, branch move.w #1,d2 ; otherwise, set d2 to 1, for something which will be used later
The code looks good, but still no success. Probably a problem on my side. Just to make sure I'm right: Let's say there's #2 in $FFFFFF9A, wouldn't the output (a6) be $FFFFCA48?
Your main problem is that you used cmp.l #$FF,a6 instead of cmpi.b #$FF,(a6) edit: I didn't see you posted at the same time. My bad. You can disregard the content of this post. Also because as I said I'm not at home so I wrote it without any code references in my hand :v:
Yup, the cmp.b #$FF,(a6) will be comparing it with the byte at $FFFFCA48 in that case. EDIT: I forgot an immediate value sign. It's add.w #$CA00, not add.w $CA00. On a similar note, I believe this is the fastest way to multiply by $24 (assuming d2 already contains the number to be multiplied and d3 is a spare register): Code (ASM): add.w d2,d2 ; x = original value of d2 add.w d2,d2 ; d2 = 4x move.w d2,d3 lsl.w #3,d3 ; d3 = $20x add.w d3,d2 ; $20x + 4x = $24x Really though, it's much simpler to just use a multiply instruction unless it's a speed-critical section of the code.
While it doesn't work where it should, it works at another point, so yeah, probably my mistake. Thanks so far. =)
Maybe a6 is used by something else in a certain section of your code. I used it as an example, but you should look at the code surrounding your snippet and if necessary you should attempt to use another address register.
That was not the problem, but I forgot some things. The location had a totally different format (yes, I managed to put together two totally different code without noticing). Just changed it to the correct way and it worked. Thanks again. =)