Basic Error Fixing Guide

Discussion in 'Tutorials Archive' started by Selbi, Feb 5, 2009.

Thread Status:
Not open for further replies.
  1. Selbi

    Selbi The Euphonic Mess Member

    Joined:
    Jul 20, 2008
    Messages:
    2,416
    Location:
    Northern Germany
    Basic error fixing guide


    This guide will (hopefully) teach you how to fix some common errors when building your ROM, like the out of branch-error (because many people asked for it). Before we can start you need to know how an error is constructed:

    The first thing is of course the location to the ASM file. After then is a number in (). This is the line where this error happened. Then we can see "Error", which means "there is an error" (O RLY?). After that we can see the type of the error. There are different ones. In the example you can see the very common out of range-error. There's a number in () again. This just means how many bytes the line is from it's goal away. But you don't really need to know this.


    Actually we just need to know the line and the type of the error.


    That said, we can start.


    How to fix the "Out of range-Error


    This is a very common error. It happens to everyone who added the Spindash or did any bigger ASM edits. Here is an example:

    Many people don't know to fix this kind of Error. It'll happend, if there is too many coding between a branch and the goal. For example:



    Routine1:
    cmp.w d0,($FFFFFE20).w ; check something


    bne.s Routine2 ; if not, branch


    ... 4000 lines below ...


    Routine2:


    rts ; return



    In Routine1 it checks something. If d0 doesn't match with the RAM-Adress, then he should branch. Well, the branch command can't jump like the jmp-command to every part of the ROM.


    So you will get this error. You'll have to fix it. There are 2 ways, but of course I'm going to start with the easier one:



    bne.s Routine5 ; if not, branch



    Nearly every branch command has something like .s (short) or .w (word). The error mostly happends with .s lines. To fix it, we simply need to change this .s to a .w:



    bne.w Routine5 ; if not, branch



    After that you should be able to compile your game just fine. :downs:


    Case 2


    If you didn't have a bra.s, but for example bne.s, you can first off try to change that to bne.w again. But even though that should crop down the rate of error possibility, it can still happen if there are WAY too much lines between there. You fix the error using a jump. However, as already mentioned, this doesn't work for things like bne.w, because there is nothing like jne. Look at this:


    First off, you have to invert the branch command. Meaning:



    Routine1:
    cmp.w d0,($FFFFFE20).w ; check something


    -> bne.s Routine5 ; if not, branch



    To:



    Routine1:
    cmp.w d0,($FFFFFE20).w ; check something


    beq.s Routine5 ; if yes, branch



    Also, don't branch to Routine5. Branch to Routine2:



    Routine1:
    cmp.w d0,($FFFFFE20).w ; check something


    beq.s Routine2 ; if yes, branch



    Below the branch command, add a jmp-command, wich jumps to your actually goal:



    Routine1:
    cmp.w d0,($FFFFFE20).w ; check something


    beq.s Routine2 ; if yes, branch


    jmp Routine5 ; jump to Routine5



    Now the error should be gone. However, there is another possibility: If there is under the code more coding:



    Routine1:
    cmp.w d0,($FFFFFE20).w ; check something


    bne.s Routine5 ; if not, branch


    move.b #1,($FFFFFE20).w ; move 1 to somewere


    move.b #1,($FFFFFE21).w ; move 1 to somewere


    move.b #1,($FFFFFE22).w ; move 1 to somewere


    move.b #1,($FFFFFE23).w ; move 1 to somewere


    Routine2:


    .


    .


    .



    Then do this: Add the same jmp-command as above. Invert the branch command again. It should look like this:



    Routine1:
    cmp.w d0,($FFFFFE20).w ; check something


    beq.s Routine2 ; if yes, branch


    jmp Routine5 ; jump to Routine5


    move.b #1,($FFFFFE20).w ; move 1 to somewere


    move.b #1,($FFFFFE21).w ; move 1 to somewere


    move.b #1,($FFFFFE22).w ; move 1 to somewere


    move.b #1,($FFFFFE23).w ; move 1 to somewere


    Routine2:


    .


    .


    .



    And now, add a new label under the jmp-command and change the branch command to this Routine:



    Routine1:
    cmp.w d0,($FFFFFE20).w ; check something


    beq.s Routine1_Rest ; if yes, branch


    jmp Routine5 ; jump to Routine5


    Routine1_Rest:


    move.b #1,($FFFFFE20).w ; move 1 to somewere


    move.b #1,($FFFFFE21).w ; move 1 to somewere


    move.b #1,($FFFFFE22).w ; move 1 to somewere


    move.b #1,($FFFFFE23).w ; move 1 to somewere


    Routine2:


    .


    .


    .



    If the check is not equal, then he will jump to Routine5. If it's equal, he will branch to Routine1_Rest.


    Now this error should be gone. :)


    Note: If the command was instead of bne.s, beq.s, then just invert beq.s to bne.s!


    Oh, and for the gay heads, this is the Boundary_Bottom routine fixed (rip it off or read and learn. I don't care):



    Boundary_Bottom:
    move.w ($FFFFF726).w,d0


    move.w ($FFFFF72E).w,d1


    cmp.w d0,d1


    blt.s Boundary_Bottom_locret


    cmpi.w #$501,($FFFFFE10).w ; is level SBZ2 ?


    bne.w KillSonic_JMP ; if not, kill Sonic


    cmpi.w #$2000,($FFFFD008).w


    bcs.w KillSonic_JMP


    clr.b ($FFFFFE30).w ; clear lamppost counter


    move.w #1,($FFFFFE02).w ; restart the level


    move.w #$103,($FFFFFE10).w ; set level to SBZ3 (LZ4)


    Boundary_Bottom_locret:


    rts


    KillSonic_JMP:


    jmp KillSonic



    How to fix the "Illegal Value" Error


    The Illegal Value error looks like this:

    This error is simalar to the Out of range-Error. You can fix it on the same way as it.


    However, that is an usual case, but there are more possibilties. As it's titled, "illegal value", there might be a wrong number on the wrong spot. For example:



    move.b #$100,d0


    There is no way of using values higher than $FF on any .b commands. You need to change it to .w:

    Code:
    		move.w	#$100,d0
    

    But even .w has its limits. You can't have more than a 4-digit value. In this case you need to use .l instead, which is the highest thing and goes up to 8 digits (if you need anything more than this, you are crazy):



    move.w #$10000,d0


    To:
    Code:
    		move.l	#$10000,d0
    

    How to fix the "Line multiply defined" Error

    If you have a brain you could guess what this is actually doing without reading the following stuff. It simply means there is a line (like loc_1AC84) multiple times in your ASM. If you still don't get it, look at this:



    Routine1:
    cmp.w d0,($FFFFFE20).w ; check something


    bne.s Routine5 ; if not, branch


    Routine2:


    move.b #1,($FFFFFE20).w ; move 1 to somewere


    Routine3:


    add.b #1,($FFFFFE21).w ; add 1 to somewere


    Routine4:


    sub.b #1,($FFFFFE20).w ; substract 1 from somewere


    Routine1:


    rts ; return



    As you can see, there is 2 times a Routine1. So what do you have to do? Right, simply change one of those 2 labels to another name. This is so simple, I will not do another ASM box now.


    There is also something that I call "The Illegal multiple defined-Error". It's simply a mix which is happening when you are having the Illegal Value error and the multiple defined error. To fix this simply do everything above.


    So, this it is for the first. I'm not sure how many errors are out there, but if you have more errors I could explain, please suggest along in this thread!


    Credits:


    Me (Selbi) for the Guide, the Examples and the Coding (in other words, everything)
     
    Last edited by a moderator: Apr 9, 2010
  2. Malevolence

    Malevolence Well-Known Member Member

    Joined:
    Jul 29, 2008
    Messages:
    97
    Or you could always just change bne.s to bne.w, saves a lot of time. If the other options are too far out of range to do a branch command (beq, bne, bsr, bra, ect...) you could branch to a routine that jumps:



    cmp.w whatever,whatever
    beq.s jumptonextroutine


    bra.s routineafterjump


    jumptonextroutine:


    jmp Whereyouneedtogoifequal


    routineafterjump:


    continuationofcode...



    Also here is an old guide of mine on error fixing, copied from Sonic Retro:


    Okay, let's say I want to make the Eggman object in Sonic 1 a valid object. I look up the code to see this:



    Obj2E_ChkEggman: ; XREF: Obj2E_Move
    addq.b #2,$24(a0)


    move.w #29,$1E(a0)


    move.b $1C(a0),d0


    cmpi.b #1,d0 ; does monitor contain Eggman?


    bne.s Obj2E_ChkSonic


    rts ; Eggman monitor does nothing



    Now, I'll add this at the end of it which should hurt sonic:



    lea ($FFFFD000).w,a0
    jsr HurtSonic



    Let's say I accidently put HurtSoni instead of HurtSonic. I then go to build, but what, it's only one kb.


    Then we'll go to our command prompt to see what the problem is. In windows command prompt is found in accessories in all programs.


    So, we click on it and it should say right next to where you type c:\Documents and Settings\UserName>_


    What you do is type in cd TheAreaWhereYouClickBuild and then press enter. After that it should have that area as opposed to c:\Documents and Settings\UserName>_


    Now, type in build and press enter. In our case this will come up:



    Code:
    > > >sonic1.asm<12698>&#58; error&#58; symbol undefined<-&#91;K
    
    > > > HurtSoni<-&#91;K
    
    > > >		 jsr	HurtSoni<-&#91;K
    
    > > >sonic1.asm<12689>&#58; warning&#58; address is not properly aligned<-&#91;K
    
    > > > 		 jsr	HurtSoni<-&#91;K
    
    > > >sonic1.asm<12698>&#58; error&#58; addressing mode not allowed here<-&#91;K
    
    > > >		 jsr	HurtSoni<-&#91;K
    Now we know that there is something wrong here, and we should go fix it. In this case, it's obvious that HurtSonic was spelled incorrectly.


    Now go and fix it, and look, 512 KB just as it should be. Now that's not everything needed to make the eggman monitor to work.


    If you wanted to completely restore it (I might as well finish), you just need to put this before the other things you added:



    tst.b ($FFFFFE2D).w ; is Sonic invincible?
    bne.s ChkEggmanNO ; if yes, branch


    tst.w ($FFFFD030).w ; is Sonic invulnerable?


    bne.s ChkEggmanNO ; if yes, branch



    Then add this right underneath the code:



    ChkEggmanNO:
    rts



    If those are not put, sonic will get hurt while invincible or when hurt right before (like the spike bug), and ChkEggmanNO will stop sonic from getting hurt.


    So, in the end your code should be this:



    Obj2E_ChkEggman: ; XREF: Obj2E_Move
    addq.b #2,$24(a0)


    move.w #29,$1E(a0)


    move.b $1C(a0),d0


    cmpi.b #1,d0 ; does monitor contain Eggman?


    bne.s Obj2E_ChkSonic


    tst.b ($FFFFFE2D).w ; is Sonic invincible?


    bne.s ChkEggmanNO ; if yes, branch


    tst.w ($FFFFD030).w ; is Sonic invulnerable?


    bne.s ChkEggmanNO ; if yes, branch


    lea ($FFFFD000).w,a0


    jsr HurtSonic


    ChkEggmanNO:


    rts
     
  3. Selbi

    Selbi The Euphonic Mess Member

    Joined:
    Jul 20, 2008
    Messages:
    2,416
    Location:
    Northern Germany
    2 things:


    1: This is totally off-topic!


    2: There is a much easier way to get invulnerable with the Eggman-Monitor:


    Add this line to Obj2E_ChkEggman (EDIT: and delete the rts (*rolleyes*)):



    bra Obj36_Hurt ; branch to the Spike Hurt Routine



    It should look like this:



    Obj2E_ChkEggman: ; XREF: Obj2E_Move
    addq.b #2,$24(a0)


    move.w #29,$1E(a0)


    move.b $1C(a0),d0


    cmpi.b #1,d0 ; does monitor contain Eggman?


    bne.s Obj2E_ChkSonic


    bra Obj36_Hurt ; branch to the Spike Hurt Routine
     
    Last edited by a moderator: Feb 5, 2009
  4. Malevolence

    Malevolence Well-Known Member Member

    Joined:
    Jul 29, 2008
    Messages:
    97
    It's not off topic it was demonstrating how to locate an error in coding. Also adding bra without specific distance (ie .s .w) will eventually lead to it having to go through the code more times than necessary when building. If it is the spike behavior for sonic one then the monitor would hurt sonic when he was invulnerable therefor not giving the effect wanted anyway. Restoring the monitor was just used while explaining how to look for the error.


    edit: Also, you don't need an rts after you use bra or jmp.
     
    Last edited by a moderator: Feb 5, 2009
  5. Selbi

    Selbi The Euphonic Mess Member

    Joined:
    Jul 20, 2008
    Messages:
    2,416
    Location:
    Northern Germany
    Open your eyes:



    Obj2E_ChkEggman: ; XREF: Obj2E_Move
    addq.b #2,$24(a0)


    move.w #29,$1E(a0)


    move.b $1C(a0),d0


    cmpi.b #1,d0 ; does monitor contain Eggman?


    bne.s Obj2E_ChkSonic


    bra Obj36_Hurt ; branch to the Spike Hurt Routine


    rts ; Eggman monitor does nothing (this line will be ignored)
     
  6. Spanner

    Spanner The Tool Member

    Joined:
    Aug 9, 2007
    Messages:
    2,555
    *facepalm*


    The code was a fucking example. So you don't have to use an rts yet you added it? Why keep it then? Maybe you should learn more opcodes and their functions.


    And won't that cause the monitor to have the s1 spike behavior like Malevolence was pointing out? It's easy to get the Eggman monitor to work anyway.
     
  7. Selbi

    Selbi The Euphonic Mess Member

    Joined:
    Jul 20, 2008
    Messages:
    2,416
    Location:
    Northern Germany
    Man, I know, this rts wasn't needed, but I leaved it, because the Game itself will not be changed with this rts! But I edited it, because I don't want to discuss about unimportant things like that!
     
    Last edited by a moderator: Feb 5, 2009
  8. Irixion

    Irixion Well-Known Member Member

    Joined:
    Aug 11, 2007
    Messages:
    670
    Location:
    Ontario, Canada
    Unimportant? How about, you explain exactly HOW to actually fix things. Not another copy and paste. I know how to fix these errors and I don't get your 'guide'. Sorry, not good for me.


    Try:


    Elaborating, on WHAT IS WRONG with the current code


    then explaining what you're going to replace it with and HOW IT CHANGES THE CODE.


    This just seems like another copy and paste. Don't want to be negative, but you did explain things, but just not well enough for me. More explanation. You do want this to work for newbies, no?
     
  9. Selbi

    Selbi The Euphonic Mess Member

    Joined:
    Jul 20, 2008
    Messages:
    2,416
    Location:
    Northern Germany
    Thanks Irixion. The guide was made in... I guess 5-10 Minutes, so there are many bugs! However, I'll try to make this guide clearlier!
     
  10. Irixion

    Irixion Well-Known Member Member

    Joined:
    Aug 11, 2007
    Messages:
    670
    Location:
    Ontario, Canada
    Yeah, spend a little more time explaining things and WHY...You know the question words. WHEN, WHY, WHERE, HOW, etc. =P
     
  11. Qjimbo

    Qjimbo Well-Known Member Member

    Joined:
    Feb 27, 2008
    Messages:
    850
    Location:
    Vancouver, BC
    Indeed, it's like any assignment... just saying what happened gets you a pass, evaluating and explaining gets you a distinction :downs:
     
  12. Tweaker

    Tweaker OI! MIRON! Member

    Joined:
    Aug 10, 2007
    Messages:
    324
    I'm pretty sure out-of-range errors are explained in pretty much any assembler's documentation files... in any case, they're not too hard to fix if you understand why they occur. :downs:
     
  13. Selbi

    Selbi The Euphonic Mess Member

    Joined:
    Jul 20, 2008
    Messages:
    2,416
    Location:
    Northern Germany
    I know Tweaker, but this Tutorial was made for Newbies! But thanks for the information! ;)
     
  14. Selbi

    Selbi The Euphonic Mess Member

    Joined:
    Jul 20, 2008
    Messages:
    2,416
    Location:
    Northern Germany
    Sorry double post and bump, but as you can see this guide is back, but changed. I thought it would be a good idea to change this guide into a error fixing guide for common errors. All what can you see here was only tested and made in the Sonic 1 ASM68k disassembly so I'm not sure about other ones, but I guess they are the same. Anyway, I hope you can tell me some more errors I could explain here. For now it's only the "Out of range", "Illegal Value" and "Label multiply defined" error.
     
Thread Status:
Not open for further replies.