I have a few generell questions about some ASM commands/stuffs: addq/subq: They are a quick version of add/sub but can only use -7 to +8. However, are they really that quicker and smarter to use? Unsigned/Signed: Basically, the branches. What is the difference between bge and bcc? I know there was something with $8000 but that's it. bvc/bvs: On the Instruction page it talks about those two commands, but what the hell is the V-bit? rtr/rte: Simalar to rts I guess, though the explainations don't tell me anything. dbt: dbf is the normal loop command I know. What could dbt be then?
According to the User's Manual, ADDQ and SUBQ are faster than ADDI and SUBI. When the right operand is a data register, it's at least twice as fast; when it's an operand in memory, it's 1.67 times as fast. ADDQ and SUBQ also have shorter encodings, which is probably why they execute faster in the first place. That said, your assembler will probably optimize ADD/ADDI to ADDQ and SUB/SUBI to SUBQ when possible, so you don't even need to worry. Also, the range is 1-8, not 0-7, as 0 is not valid for ADDQ/SUBQ (because why would you do such a thing? :specialed: ). To explain the difference between "signed" and "unsigned" comparisons, let's take a concrete example: Code (ASM): move.w #$7FFF,d0 move.w #$8000,d1 cmp.w d0,d1 bgt.s @greater_than_signed ; d1 > d0 bhi.s @greater_than_unsigned ; d1 > d0 The first branch will not be taken, but the second branch will be taken. What's the difference? In a signed comparison, the operands are assumed to be signed, which means that $8000 here is interpreted as -$8000. -$8000 is not greater than $7FFF, therefore it does not branch. On the other hand, the unsigned comparison assumes the operands are unsigned (I.e. the sign bit is not treated specially). $8000 is greater than $7FFF, so the second condition is met and the branch is taken. I personally tend to use unsigned comparisons unless I really mean to use a signed comparison, because the signed comparisons are more complex (see the Programmer's Manual, page 3-19, table 3-19). Also, note that BCC can be written as BHS (branch if higher or same; the Programmer's Manual incorrectly says HI for this though) and BCS can be written as BLO (branch if lower). If you don't know how two's complement works, read up on it, it should clear up some things. The V-bit is the overflow bit. I think this flag indicates signed overflow/underflow, whereas the C-bit (carry) indicates unsigned overflow/underflow. The exact definition of how these flags are defined is in the Programmer's Manual, page 3-18, table 3-18. RTR seems to be useful when you need to keep the value of the condition code register (where the XNZVC flags are stored) after the execution of your subroutine. If I understand the manual correctly, you will have to push 2 bytes to the stack at the beginning of the subroutine that uses RTR instead of RTS. The documentation doesn't really say if the CCR is supposed to be in the first byte or the second byte though; I assume it's in the second byte, but I never used it so I don't know. RTE is only used when you return from an exception/interrupt handler, like Illegal Instruction or VBlank, because when an exception is raised, several values are pushed on the stack, and RTE removes them before returning. DBT is useless because it does nothing. In general, DBcc does 3 things: Test the condition indicated in the mnemonic (e.g. LE in DBLE). If the condition is true, do nothing. If the condition is false, decrement the lower word of the given data register. If the value of the lower word of the data register after decrementing is not -1 ($FFFF), branch. DBF (or its synonym DBRA) makes the condition always false, so it will always decrement, and DBT makes the condition always true, so it will never decrement nor branch. You can also use other condition codes like in DBEQ if you can find a purpose for it. For example, if you have something like this: Code (ASM): @loop: ; ...instructions... dbeq d0,@loop ; ...more instructions...
Wow, that was.... alot of information. I'm not sure if I understood everything yet, but for now, thanks. =) However, some things to the unsigned/signed thing: So basically when it's unsigned it goes from -$8000 to +$7FFF and signed from -$7FFF to +$8000 or do I totally confuse something here?
Is it possible to make a branch in the power of Sonic 1's springs so you go higher when using a certain attack or animation when landing on them?: Code (Text): Obj41_Powers: dc.w -$1000; power of red spring dc.w -$A00; power of yellow spring I've managed to make the code while still maintaining rolling in transitions like S_Tubes, however I'm not quite sure how the timers work so as to add a slight delay in stopping: Code (Text): Duck_Movement: tst.w $14(a0); is Sonic moving? beq.s Duck_Movement_Return; if not, branch move.b #8,$1C(a0); use "ducking" animation move.w #0,$14(a0); stop Sonic moving move.w #0,$10(a0) move.w #0,$12(a0) Duck_Movement_Return: rts Would I add the first coding above #0,$14(a0) and then add a 'countdown' branch below it? (the time delay itself is rather brief and shouldn't really be much longer than a second, just something for a slight 'skid').
Well as you can see here: Code (ASM): loc_DB72: andi.w #$F,d0 move.w Obj41_Powers(pc,d0.w),$30(a0) rts There is a code that uses a (I dunno what it's called)-code (that pc,d0.w one). That gets the values of Obj41_Powers. Right under it you could add your checks, like this: Code (ASM): loc_DB72: andi.w #$F,d0 move.w Obj41_Powers(pc,d0.w),$30(a0) tst.b ($FFFFFFFF).w ; is move XYZ being performed? bne.s Obj41_NoMoveXYZ ; if not, branch move.w #-$1500,$30(a0) ; use greater speed Obj41_NoMoveXYZ: rts If you also want to make alternate speeds for yellow and red speeds, look up a bit: Code (ASM): loc_DB66: btst #1,d0 beq.s loc_DB72 bset #5,2(a0) I don't directly get what the third line is, but I know that the btst and beq.s are checking if the spring is a yellow one and if not, branch. EDIT: For the delay I made this, which is probably not a good solution, but it works (I guess, since I wasn't able to test it): Code (ASM): subq.w #1,d5 ; substract 1 from the delay timer beq.s PerformMove ; is timer empty? if yes, branch bpl.s ContinueDelay ; if it's still going down, branch move.w #10,d5 ; set delay time if the first things got skipped ContinueDelay: rts ; return PerformMove: clr.w $10(a0) ; clear X-speed rts ; return
The spring alteration changes the height of the springs but isn't dependant on the animation or flag, it has the same altered height all the time. The halt one kinda works but the skid is extended for too long (it's really just meant to be this VERY small skid so as her halt in movement isn't so jarring, like how she ducks in Advance). Is it possible to decrease the timer even more?
Ok, So whenever I get the Disassemblies ((As I have Downloaded all Three of Hivebrain's)) it seems I'm Missing the Artunc Folder. WHERE Do I find that or how do I get it? I would like to start my own hack right now but because of the lack of that folder I can't do anything. AND PLEASE don't link me anywhere else, I would like to know WHAT I am doing wrong with the assemblies and WHY I always get this: http://forums.sonicretro.org/index.php?showtopic=19868 whenever I try to open stuff in SonMapEd.
Well then you just need to change the values in Obj41_Powers or do I confuse something now? Code (ASM): move.w #10,d5 ; set delay time if the first things got skipped This line sets the delay. Just put a smaller value in. Maybe 3 would already be enough? I don't know, trial-and-error is your friend. =P The artunc folder isn't in the raw download included. You need to split your ROM first. Open the readme file, it should explain everything well.
As in the spring alteration changes but as in for all situations, not just using a certain animation or attack on it. Changing the value on the branch any way overwrites the normal Power value. Changing that coding doesn't seem to do anything, I even changed it to 1 and it still takes her the same amount of time to grind to a halt, she has zero friction, similar to when she rolls.
Is it really that hard to understand this? You will need a clean Sonic 1 ROM and rename it as s1.bin. Then click split.bat. I can't give you any links due rule 15, but with some searching I'm sure you will find one. Sorry, I might be just stupid, but I don't get what you want to do with the springs at all. For the other thing, maybe you should include your move in Sonic_Roll, but instead make a new bsr.w in Obj01_MdNormal.
Like I said: I did exactly that but NOTHING Happened. I'm not a Dolt. I placed it in the Folder but all that happened was a stupid black window appeared for a millisecond and No other folders appeared. It was still just the Rom and the Split file. What is supposed to happen?
Like for Amy in Advance I want her to get an extra boost on springs when she hammers on them, the added code activates the boost but does not restrict it to when hammering. The new code is the default one. And about the 'split.bat' problem, I have encountered that too before, I split the ROM but only half the necessary folders appeared for some reason. It was solved somehow, but I've forgotten how to do it.
I think I finally got you. You mean when she hammers next to a spring that extreme high boost? That might work using some fakish code. When you perform the move, a flag is being set. On the spring, you first off check if that flag is set (note, in the part BEFORE it checks if you touched the spring normally). Then you compare the X-position with Amy's one and set a limit, maybe 5 pixels. This might work: Code (ASM): tst.w ($FFFFFFFF).w ; is hammer attack being performed? beq.s Obj41_NoHammerAttack ; if not, branch moveq #0,d0 ; clear d0 move.w $8(a0),d0 ; load springs's X-pos to d0 sub.w ($FFFFD008).w,d0 ; substract Amy's X-pos from it (Anything starting from $FFFFD000 Sonic's/Amy's RAM location) bpl.w Obj41_Positive ; if answer is positive, branch neg.w d0 ; otherwise negate d0 Obj41_Positive: cmpi.w #5,d0 ; is Amy within 5 pixels of the spring? bge.w Obj22_End ; if not, branch ; the other stuff for the spring Obj41_NoHammerAttack:
Unsigned basically means all numbers are treated positive, as written. So, unsigned 32-bit integers go from +$0000 to +$FFFF.
This may be a problem as the hammer attack is a somewhat convoluted code that doesn't have a flag listed: Code (Text): Sonic_Hammer: cmp.b #$1F,$1C(a0) bne.s lol7 move.w $14(a0),d0 move.w d0,d1 asr.w #3,d1 sub.w d1,d0 move.w d0,$14(a0) rts lol7: btst #6,($FFFFF603).w; is A button pressed? beq lol ; if not branch move.b #$1F,$1C(a0); show hammer animation move.w $14(a0),d0 btst #0,$22(a0) beq lol8 neg.w d0 lol8: cmp.w #$400,d0 bgt lol move.w #$400,d0 btst #0,$22(a0) beq lol9 neg.w d0 lol9: move.w d0,$14(a0) lol: move.w $10(a0),d0 tst.w d0 bpl label neg.w d0 label: cmpi.w #$600,d0 bgt Sonic_Hammer_Return btst #6,($FFFFF603).w; is A button pressed? beq.b Sonic_Hammer_return; if not, return move.b #$1F,$1C(a0) ; show animation $20 move.w #$BD,d0 jsr (PlaySound_Special).l Sonic_Hammer_return: rts ; End of function Sonic_Hammer I have tried implementing a flag however since it is a ground attack I can't clear it on ResetOnFloor like the others. Can this coding identify the animation number instead? Also I'm not quite positive where to implement this, when you say before the coding to recognise the character jumping on the screen do you mean directly above it above the routine it's in?: Code (Text): Obj41_Up: ; XREF: Obj41_Index move.w #$1B,d1 move.w #8,d2 move.w #$10,d3 move.w 8(a0),d4 bsr.w SolidObject tst.b $25(a0) ; is Sonic on top of the spring? bne.s Obj41_BounceUp; if yes, branch rts ; =========================================================================== Obj41_BounceUp: ; XREF: Obj41_Up addq.b #2,$24(a0) addq.w #8,$C(a1) move.w $30(a0),$12(a1); move Sonic upwards bset #1,$22(a1) bclr #3,$22(a1) move.b #$10,$1C(a1); use "bouncing" animation move.b #2,$24(a1) bclr #3,$22(a0) clr.b $25(a0) move.w #$CC,d0 jsr (PlaySound_Special).l; play spring sound Obj41_AniUp: ; XREF: Obj41_Index lea (Ani_obj41).l,a1 bra.w AnimateSprite My current attempts have either lead to nothing or have the spring go spastic when it's onscreen. Oh, and, um, there is no Obj22_Land. Obj22 is the buzz bomber.
About the thing with the flag, I would do it like this: Code (ASM): tst.b ($FFFFFFFF).w ; was hammer attack flag set? beq.s Obj01_NoHammer ; if not, branch cmpi.b #$XX,$1C(a0) ; is hammer animation still being showed? beq.s Obj01_NoHammer ; if yes, branch clr.b ($FFFFFFFF).w ; clear hammer flag Obj01_NoHammer: Where $XX needs to be changed to the animation ID while Amy is performing the move. Put this in a place where checks are constantly being made, I recommend Sonic_Display. And about that spring thingy, I forgot to tell you that you need to put it right after the label of Obj41_Up. Also: Code (ASM): tst.w ($FFFFFFFF).w ; is hammer attack being performed? beq.s Obj41_NoHammerAttack ; if not, branch moveq #0,d0 ; clear d0 move.w $8(a0),d0 ; load springs's X-pos to d0 sub.w ($FFFFD008).w,d0 ; substract Amy's X-pos from it (Anything starting from $FFFFD000 Sonic's/Amy's RAM location) bpl.w Obj41_Positive ; if answer is positive, branch neg.w d0 ; otherwise negate d0 Obj41_Positive: cmpi.w #5,d0 ; is Amy within 5 pixels of the spring? bge.s Obj41_NoHammerAttack ; if not, branch ; the other stuff for the spring Obj41_NoHammerAttack: Fixed. I got this from a simalar code, which was in Obj22.
That's 16-bit, not 32-bit. Let's not all get confused now, alright? :v: Signed 8-bit: -$80 to +$7F Signed 16-bit: -$8000 to +$7FFF Signed 32-bit: -$80000000 to +$7FFFFFFF Unsigned 8-bit: 0 to $FF Unsigned 16-bit: 0 to $FFFF Unsigned 32-bit: 0 to $FFFFFFFF
You could've saved yourself from writing over 1200 letters by just creating this table. =P Thanks again.