OUT OF RANGE

Discussion in 'Discussion and Q&A Archive' started by hackman, Oct 24, 2015.

  1. hackman

    hackman Newcomer Trialist

    Joined:
    Aug 30, 2015
    Messages:
    6
    Location:
    behind you
    Ok i'm porting the sonic 2 beta sonic's animations,maps pattern load cues,art every thing works but when I try to port the animations I get this

    F:\SONIC HACKING\SONIC1.ASM(25528)  :Error:Branch (32942 bytes) is out of range

    F:\SONIC HACKING\SONIC1.ASM(25530)  :Error:Branch (32932 bytes) is out of range

    I need some help.

    the code is;=============================================================================== 
    ; Sub Routine Sonic_Animate
    ; [ Begin ]                 
    ;===============================================================================          
    Sonic_Animate: ; loc_10AB2:
            lea     (Sonic_AnimateData), a1 ; loc_10CB4
            moveq    #0,d0
            move.b  $1C(a0), d0
            cmp.b   $1D(a0), d0
            beq.s   loc_10ADA
            move.b  d0, $1D(a0)
            move.b  #$00, $1B(a0)
            move.b  #$00, $1E(a0)
            bclr    #$5, $22(a0)
    loc_10ADA:
            add.w   d0,d0
            adda.w  $00(a1,d0), a1
            move.b  (a1), d0
            bmi.s   loc_10B4A
            move.b  $22(a0),d1
            andi.b  #$1,d1
            andi.b  #$FC, $1(a0)
            or.b    d1, $1(a0)
            subq.b  #$1, $1E(a0) 
            bpl.s   loc_10B18
            move.b  d0, $1E(a0)             
    loc_10B00:        
            moveq    #0,d1
            move.b  $1B(a0),d1
            move.b  $1(a1,d1), d0
            cmpi.b  #$F0,d0
            bcc.s   loc_10B1A
    loc_10B10:        
            move.b  d0, $1A(a0)
            addq.b  #$1, $1B(a0)
    loc_10B18:        
            rts
    loc_10B1A:
            addq.b  #$1,d0
            bne.s   loc_10B2A
            move.b  #$00, $1B(a0)
            move.b  $1(a1), d0
            bra.s   loc_10B10
    loc_10B2A:
            addq.b  #$1,d0
            bne.s   loc_10B3E
            move.b  $2(a1,d1), d0
            sub.b   d0, $1B(a0)
            sub.b   d0,d1
            move.b  $1(a1,d1), d0
            bra.s   loc_10B10
    loc_10B3E:
            addq.b  #$1,d0
            bne.s   loc_10B48
            move.b  $2(a1,d1), $1C(a0)
    loc_10B48: 
            rts            
    loc_10B4A: 
            subq.b  #$1, $1E(a0)
            bpl.s   loc_10B18
            addq.b  #$1,d0
            bne     loc_10C3E
            moveq    #0,d0
            move.b  $27(a0), d0
            bne     loc_10BD8
            moveq    #0,d1
            move.b  $26(a0), d0
            move.b  $22(a0),d2
            andi.b  #$1,d2
            bne.s   loc_10B72
            not.b  d0
    loc_10B72:
            addi.b  #$10,d0
            bpl.s   loc_10B7A
            moveq   #$3,d1
    loc_10B7A:
            andi.b  #$FC, $1(a0)
            eor.b   d1,d2
            or.b    d2, $1(a0)
            btst    #$5, $22(a0)
            bne     loc_10C82
            lsr.b   #$4,d0
            andi.b  #$6,d0
            move.w  $14(a0),d2
            bpl.s   loc_10B9E
            neg.w   d2
    loc_10B9E:
            lea     (Sonic_Animate_Run), a1 ; loc_10D00
            cmpi.w  #$600,d2
            bcc.s   loc_10BB0
            lea     (Sonic_Animate_Walk), a1 ; loc_10CF2
    loc_10BB0:
            move.b  d0,d1
            lsr.b   #$1,d1
            add.b   d1,d0
            add.b   d0,d0
            add.b   d0,d0
            move.b  d0,d3
            neg.w   d2
            addi.w  #$800,d2
            bpl.s   loc_10BC6
            moveq    #0,d2
    loc_10BC6:
            lsr.w   #$8,d2
            lsr.w   #$1,d2
            move.b  d2, $1E(a0)
            bsr     loc_10B00
            add.b   d3, $1A(a0)
            rts    
    loc_10BD8:
            move.b  $27(a0), d0
            moveq    #0,d1
            move.b  $22(a0),d2
            andi.b  #$1,d2
            bne.s   loc_10C06
            andi.b  #$FC, $1(a0)
            addi.b  #$B,d0
            divu.w  #$16,d0
            addi.b  #$9B,d0
            move.b  d0, $1A(a0)
            move.b  #$00, $1E(a0)
            rts
    loc_10C06:
            andi.b  #$FC, $1(a0)
            tst.b   $29(a0)
            beq.s   loc_10C1E
            ori.b   #$1, $1(a0)
            addi.b  #$B,d0
            bra.s   loc_10C2A
    loc_10C1E:
            ori.b   #$3, $1(a0)
            neg.b   d0
            addi.b  #$8F,d0
    loc_10C2A:
            divu.w  #$16,d0
            addi.b  #$9B,d0
            move.b  d0, $1A(a0)
            move.b  #$00, $1E(a0)
            rts 
    loc_10C3E:
            addq.b  #$1,d0
            bne.s   loc_10C82
            move.w  $14(a0),d2
            bpl.s   loc_10C4A
            neg.w   d2
    loc_10C4A:
            lea     (Sonic_Animate_Roll2), a1 ; loc_10D18
            cmpi.w  #$600,d2
            bcc.s   loc_10C5C
            lea     (Sonic_Animate_Roll), a1 ; loc_10D0E
    loc_10C5C:
            neg.w   d2
            addi.w  #$400,d2
            bpl.s   loc_10C66
            moveq    #0,d2
    loc_10C66:
            lsr.w   #$8,d2
            move.b  d2, $1E(a0)
            move.b  $22(a0),d1
            andi.b  #$1,d1
            andi.b  #$FC, $1(a0)
            or.b    d1, $1(a0)
            bra     loc_10B00
    loc_10C82:        
            move.w  $14(a0),d2
            bmi.s   loc_10C8A
            neg.w   d2
    loc_10C8A:
            addi.w  #$800,d2
            bpl.s   loc_10C92
            moveq    #0,d2
    loc_10C92:
            lsr.w   #$6,d2
            move.b  d2, $1E(a0)
            lea     (Sonic_Animate_Push), a1 ; loc_10D22
            move.b  $22(a0),d1
            andi.b  #$1,d1
            andi.b  #$FC, $1(a0)
            or.b    d1, $1(a0)
            bra     loc_10B00  

    Sonic_AnimateData: ; loc_10CB4:
            dc.w    Sonic_Animate_Walk-Sonic_AnimateData        ; loc_10CF2
            dc.w    Sonic_Animate_Run-Sonic_AnimateData         ; loc_10D00
            dc.w    Sonic_Animate_Roll-Sonic_AnimateData        ; loc_10D0E
            dc.w    Sonic_Animate_Roll2-Sonic_AnimateData       ; loc_10D18 
            dc.w    Sonic_Animate_Push-Sonic_AnimateData        ; loc_10D22
            dc.w    Sonic_Animate_Wait-Sonic_AnimateData        ; loc_10D30
            dc.w    Sonic_Animate_Balance-Sonic_AnimateData     ; loc_10D59
            dc.w    Sonic_Animate_LookUp-Sonic_AnimateData      ; loc_10D5D
            dc.w    Sonic_Animate_Duck-Sonic_AnimateData        ; loc_10D62
            dc.w    Sonic_Animate_Spindash-Sonic_AnimateData    ; loc_10D67
            dc.w    Sonic_Animate_WallRecoil1-Sonic_AnimateData ; loc_10D74
            dc.w    Sonic_Animate_WallRecoil2-Sonic_AnimateData ; loc_10D77
            dc.w    Sonic_Animate_0x0C-Sonic_AnimateData        ; loc_10D7D
            dc.w    Sonic_Animate_Stop-Sonic_AnimateData        ; loc_10D81
            dc.w    Sonic_Animate_Float1-Sonic_AnimateData      ; loc_10D8C
            dc.w    Sonic_Animate_Float2-Sonic_AnimateData      ; loc_10D90
            dc.w    Sonic_Animate_0x10-Sonic_AnimateData        ; loc_10D97
            dc.w    Sonic_Animate_S1LzHang-Sonic_AnimateData    ; loc_10D9B
            dc.w    Sonic_Animate_Unused_0x12-Sonic_AnimateData ; loc_10D9F
            dc.w    Sonic_Animate_Unused_0x13-Sonic_AnimateData ; loc_10DA5
            dc.w    Sonic_Animate_Unused_0x14-Sonic_AnimateData ; loc_10DAA
            dc.w    Sonic_Animate_Bubble-Sonic_AnimateData      ; loc_10DAD
            dc.w    Sonic_Animate_Death1-Sonic_AnimateData      ; loc_10DB4
            dc.w    Sonic_Animate_Drown-Sonic_AnimateData       ; loc_10DB7
            dc.w    Sonic_Animate_Death2-Sonic_AnimateData      ; loc_10DBA
            dc.w    Sonic_Animate_Unused_0x19-Sonic_AnimateData ; loc_10DBD
            dc.w    Sonic_Animate_Hurt-Sonic_AnimateData        ; loc_10DC6
            dc.w    Sonic_Animate_S1LzSlide-Sonic_AnimateData   ; loc_10DC9
            dc.w    Sonic_Animate_0x1C-Sonic_AnimateData        ; loc_10DCD
            dc.w    Sonic_Animate_Float3-Sonic_AnimateData      ; loc_10DD1
            dc.w    Sonic_Animate_0x1E-Sonic_AnimateData        ; loc_10DD8
    Sonic_Animate_Walk: ; loc_10CF2:
            dc.b    $FF, $10, $11, $12, $13, $14, $15, $16, $17, $C, $D, $E, $F, $FF
    Sonic_Animate_Run: ; loc_10D00:
            dc.b    $FF, $3C, $3D, $3E, $3F, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
    Sonic_Animate_Roll: ; loc_10D0E:
            dc.b    $FE, $6C, $70, $6D, $70, $6E, $70, $6F, $70, $FF
    Sonic_Animate_Roll2: ; loc_10D18:
            dc.b    $FE, $6C, $70, $6D, $70, $6E, $70, $6F, $70, $FF
    Sonic_Animate_Push: ; loc_10D22:
            dc.b    $FD, $77, $78, $79, $7A, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
    Sonic_Animate_Wait: ; loc_10D30:        
            dc.b    $7, $1, $1, $1, $1, $1, $1, $1, $1, $1, $1, $1, $1, $1, $1, $1
            dc.b    $1, $1, $1, $1, $1, $1, $1, $1, $1, $1, $1, $1, $1, $1, $1, $2
            dc.b    $3, $3, $3, $4, $4, $5, $5, $FE, $4
    Sonic_Animate_Balance: ; loc_10D59:         
            dc.b    $7, $89, $8A, $FF
    Sonic_Animate_LookUp: ; loc_10D5D:        
            dc.b    $5, $6, $7, $FE, $1
    Sonic_Animate_Duck: ; loc_10D62:          
            dc.b    $5, $7F, $80, $FE, $1
    Sonic_Animate_Spindash: ; loc_10D67:        
            dc.b    $00, $71, $72, $71, $73, $71, $74, $71, $75, $71, $76, $71, $FF 
    Sonic_Animate_WallRecoil1: ; loc_10D74:        
            dc.b    $3F, $82, $FF
    Sonic_Animate_WallRecoil2: ; loc_10D77:
            dc.b    $7, $8, $8, $9, $FD, $5
    Sonic_Animate_0x0C: ; loc_10D7D:        
            dc.b    $7, $9, $FD, $5
    Sonic_Animate_Stop: ; loc_10D81:         
            dc.b    $3, $81, $82, $83, $84, $85, $86, $87, $88, $FE, $2
    Sonic_Animate_Float1: ; loc_10D8C:         
            dc.b    $7, $94, $96, $FF
    Sonic_Animate_Float2: ; loc_10D90:        
            dc.b    $7, $91, $92, $93, $94, $95, $FF
    Sonic_Animate_0x10: ; loc_10D97:        
            dc.b    $2F, $7E, $FD, $00
    Sonic_Animate_S1LzHang: ; loc_10D9B:        
            dc.b    $5, $8F, $90, $FF
    Sonic_Animate_Unused_0x12: ; loc_10D9F:        
            dc.b    $F, $43, $43, $43, $FE, $1
    Sonic_Animate_Unused_0x13: ; loc_10DA5:        
            dc.b    $F, $43, $44, $FE, $1
    Sonic_Animate_Unused_0x14: ; loc_10DAA:        
            dc.b    $3F, $49, $FF
    Sonic_Animate_Bubble: ; loc_10DAD:         
            dc.b    $B, $97, $97, $12, $13, $FD, $00
    Sonic_Animate_Death1: ; loc_10DB4:         
            dc.b    $20, $9A, $FF
    Sonic_Animate_Drown: ; loc_10DB7:        
            dc.b    $20, $99, $FF
    Sonic_Animate_Death2: ; loc_10DBA:         
            dc.b    $20, $98, $FF
    Sonic_Animate_Unused_0x19: ; loc_10DBD: 
            dc.b    $3, $4E, $4F, $50, $51, $52, $00, $FE, $1
    Sonic_Animate_Hurt: ; loc_10DC6:        
            dc.b    $40, $8D, $FF
    Sonic_Animate_S1LzSlide: ; loc_10DC9:          
            dc.b    $9, $8D, $8E, $FF
    Sonic_Animate_0x1C: ; loc_10DCD:        
            dc.b    $77, $00, $FD, $00
    Sonic_Animate_Float3: ; loc_10DD1:        
            dc.b    $3, $91, $92, $93, $94, $95, $FF
    Sonic_Animate_0x1E: ; loc_10DD8:        
            dc.b    $3, $3C, $FD, $00
    ;=============================================================================== 
    ; Sub Routine Sonic_Animate
    ; [ End ]                 
     
    Last edited by a moderator: Oct 24, 2015
  2. Clownacy

    Clownacy Retired Staff lolololo Member

    Joined:
    Aug 15, 2014
    Messages:
    957
  3. Selbi

    Selbi The Euphonic Mess Member

    Joined:
    Jul 20, 2008
    Messages:
    2,416
    Location:
    Northern Germany
    Out-of-range errors, probably the most common type of error and also one of the most annoying ones.

    Basically, whatever it is you're doing there isn't the direct cause for your compilation failing; it's just that somewhere else the game tried to reach something, but can't do so now because of the newly inserted code being larger than what was there before.

    Simple rules apply to fixing these errors.

    Open the mentioned file, find the mentioned lines, and check what size your branch has. In 9 out of 10 cases you'll find that the line is something like:

    Code:
    	bra.s	SomeLabel
    Simply replace the .s (which stands for "short") with a .w (which stands for "word"). Shorts, as the name implies, only have a small branching range (but are more efficient for short distances, hence their point), whereas words are much, much larger (in numbers, shorts have a total range of a byte; words have a range of, well, a word).

    However, should you find that the errors in question already have a .w, a different way is required to fix them, which is replacing them with so-called "jumps".

    Jumps are essentially the same thing as branches, only that they don't relatively go to another place based on where the branch is executed, but rather work on an absolute basis, meaning they can go from one end of the ROM to the other with ease. The disadvantage is that there are no conditional jumps (so nothing like "beq" or "bne" applies to jumps, although some people have made custom macros to simulate "jeq" and the likes), and jumps are also considerably less efficient. Only use them when you absolutely must! (No pun intended.)

    In case you have a bra.w and that line only, you can simply replace it with jmp. In case you have a bsr.w and that line only, you can simply replace it with jsr.

    If it's any other command than bra or bsr, it's a conditional operation. Fixing those errors can be a little harder to grasp. There are two ways to do this.

    The first one: You need to create a new label somewhere else which jumps to the actual result, and instead go to that via the branch. I think an example is easier to understand:

    This:

    Code:
    	cmpi.b	#$18,($FFFFFFFF).w	; is that RAM address set to $18?
    	bne.w	SomeOutOfRangeLabel	; if not, branch
    Becomes this:

    Code:
    	cmpi.b	#$18,($FFFFFFFF).w		; is that RAM address set to $18?
    	bne.s	JumpTo_SomeOutOfRangeLabel	; if not, branch
    
    	; some other code in between here
    
    JumpTo_SomeOutOfRangeLabel:
    	jmp	SomeOutOfRangeLabel
    The other method (which I've also touched in my old as hell Basic Error Fixing Guide) is negating the instruction and instead making a skip. Negating bne results into beq, negating bgt results into ble and so on.

    As an example (based on the above code):

    Code:
    	cmpi.b	#$18,($FFFFFFFF).w	; is that RAM address set to $18?
    	beq.s	SkipJump		; if YES, branch (changed from bne)
    	jmp	SomeOutOfRangeLabel
    
    SkipJump:
    	...
    I personally prefer this second method, as I don't need to find a place to put the JumpTo branch and instead can keep everything in one place. However, it requires knowledge of the various conditional branch instructions, so you should memorize the table at the bottom of this page.

    Here's hope this made any sense to you. It's really easy to fix these errors and becomes second nature at some point (because you need to prepare to get confronted with them a lot), but they can be confusing and infuriating for beginners.


    LATE EDIT: Fixed IPB's conversion bullshit.
     
    Last edited: Jan 19, 2016
    ⸸ devon ⸸ likes this.
  4. Sonic master

    Sonic master Well-Known Member Member

    Joined:
    Mar 27, 2010
    Messages:
    303
    Actually don't replace the .s with .w, just remove it and let the assembler decide if it should use a byte or a word for the branch. A few years ago I removed all instances of .s and .w in the Sonic One disassembly and enabled branch optimizations (this was with asm68k) and the final size of s1built.bin decreased. This was because some branches that were using a word offset could have used a byte offset.
     
  5. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,870
    The assembler "asm68k", does not run enough passes to ensure the smallest size is used, in fact, I recall asm68k (only running one main pass of optimisation) causes backwards branches to optimise fine, but forward branches to remain at word, despite being able to assemble as short. If you want to get the best result, you will need an assembler than runs multi-passing until no optimisations can be found, I believe the AS assembler is able to do this.

    However, telling people that they should optimise best for size, is wrong, and it's wrong because it depends on circumstance and situation.

    One individual may need the size, therefore, letting the assembler find the best result is the most suited. Another individual may require quick assembly results for fast and immediate testing (i.e. write, assemble, test, write, assemble, test), therefore, size optimisation with minor branch instructions is not suited as it can take precious time, if the code is complex and requires quick actions to be taken to prevent forgetting vital details, fast assembly time is a importance.

    I am not trying to deter people from following your suggestion, I think it is the right suggestion, I just think it's for the wrong reasons. One should not place .s or .w unless it is necessary (e.g. a jump table of branches with specific size), and should assign the assembler to multi-pass, or NOT, depending on the required situation (do they need ROM speed/size, or assembly speed?).
     
  6. LazloPsylus

    LazloPsylus The Railgun Member

    Joined:
    Nov 25, 2009
    Messages:
    Location:
    Academy City
    Optimizations are very context-sensitive, with different situations calling for different types of optimizations. One size does not fit all. Also, would help if you actually indicated which lines are the two indicated by the error. Sure, some of us who know the system well enough could just go through your code and hand-calculate the branches, but we've got better things to do with our lives, to be honest. Really, though, with out-of-range errors, the assembler pretty directly points you to where the problem is, and solutions are pretty straightforward. Selbi covered a reasonable enough approach to correcting it on your own. Really not terribly hard once you get the hang of it.

    On an unrelated but administrative note, topic names in all caps are pretty obnoxious, so please don't do that. Basic English grammar and spelling is all we ask, and we're usually pretty forgiving on both.
     
  7. AURORA☆FIELDS

    AURORA☆FIELDS so uh yes Member

    Joined:
    Oct 7, 2011
    Messages:
    760
    I usually rather to do optimizations by hand, to ensure it is correctly optimized. If it does not matter in the case, I leave it up to the assembler to do whatever.
     
  8. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,970
    Location:
    England
    But really, how much size does it save by going from .w to .b? Like, bugger all? Yeah, yeah, if you did it with every single one and add them all up it could come to save quite a bit. But I think it would be pointles to do it to save space unless your final ROM size came to 513KBs or 1025KBs, etc =P
     
    MarkeyJester likes this.
  9. Selbi

    Selbi The Euphonic Mess Member

    Joined:
    Jul 20, 2008
    Messages:
    2,416
    Location:
    Northern Germany
    Completely unrelated, I just noticed that the code boxes were entirely fucked up in my post. Sigh. IPB is gone and it still haunts me.
     
    Pacca likes this.