don't click here

Nonsensical Errors when editing Sonic 1 ASM and Recompiling

Discussion in 'Engineering & Reverse Engineering' started by Agent ME, Jan 20, 2007.

Thread Status:
Not open for further replies.
  1. Agent ME

    Agent ME

    Void where prohibited Member
    26
    0
    0
    I recently found a thread here about using SRAM, so I decided I'd try to do some simple incorporations of SRAM into sonic1. My first tests worked well - simple things to make sure it worked - I made it so if you did the level select code once, it would from then on make you start with 17 lives - proved I got the SRAM working right.

    Next I tried to make it at the end of every act (in the Obj3A_NextLevel: section) save what level you were on, the number of lives, and an extra number that was always the same (#117) so when the game tried to load it could check for that number to make sure there was really a save and it didn't try to load nonsense.
    And I also added some code in the PlayLevel: section to check if #117 was in the memory, then it would load the lives and level number into the RAM. (Currently I haven't set up an option to allow choosing of a save-slot, or playing a new-game - I'm just trying to get this to work right now)

    But whenever I try to compile, I get errors such as "s1comb.asm(3547) : Error 15030 : Cannot fit value 88 into signed byte". If I go to that line, it's just in the middle of the sounds part - where there's a lot of incbin commands. Nothing I touched.

    And oddly, if I comment out two or three commands, the thing will compile fine, and work exactly as should (except for whatever I commented out - IE I commented the lines that clear how many emeralds the player has on start).

    The ASM file is at - http://am49.frih.net/sonic/sonic1.asm - it's based from the 2005 S1 Disassembly. All of the changes are in the header (to enable SRAM), under PlayLevel:, and Obj3A_NextLevel:. There are a few comment changes and organization changes also, but nothing else that affects the compiled form.

    Anyone help with my problem?
     
  2. Hivebrain

    Hivebrain

    Administrator
    3,049
    162
    43
    53.4N, 1.5W
    Github
    Are you sure you looked at line 3547 in s1comb.asm, and not sonic1.asm?
     
  3. Agent ME

    Agent ME

    Void where prohibited Member
    26
    0
    0
    Yeah I check s1comb.asm - it's in the middle of a bunch of sound incbin's. Far from any code I've touched.

    Is this compiling fine for you guys?
     
  4. Xenowhirl

    Xenowhirl

    Tech Member
    175
    0
    0
    There's PC-relative addressing to some data, and your code offset the data too much. Happens all the time. I shift things around to fix that sort of error, like moving the data directly in front of the code that uses it to make it close enough. You're not finding the right line for the error, though.

    Code (Text):
    1. ; around line 3547 of s1comb.asm... looks like sound incbins huh?
    2. LevSel_Level_SS:        ; XREF: LevelSelect
    3.         add.w   d0,d0
    4.         move.w  LSelectPointers(pc,d0.w),d0; load level number
    5.         bmi.w   LevelSelect
    You added code between there and LSelectPointers, so just move LSelectPointers closer in sonic1.asm.
     
  5. Agent ME

    Agent ME

    Void where prohibited Member
    26
    0
    0
    I officially hate MS Word now (The computer I was on didn't have any good text editors like Crimson on it, so I used Word whenever I wanted to go to a line number, and it always jumped me to a bunch of sound incbins...).

    I made a change - I moved all the LSelectPointer section to right below the part referencing it and it now works perfectly.

    But while this topic exists - what exactly does this command do?
    Code (Text):
    1. move.w  LSelectPointers(pc,d0.w),d0; load level number
    I'm guessing it's like lea - its putting the LSelectPointers address into d0 - but what's the point of the (pc,d0.w)? How's that work?
     
  6. Xenowhirl

    Xenowhirl

    Tech Member
    175
    0
    0
    You put it after an rts or a bra or a jmp, right?

    It sets d0 = LSelectPointers[d0]. d0 is used to store the index [in bytes] into LSelectPointers, then reused to hold the data taken out of LSelectPointers. The pc is because the start address is pc-relative; I think the assembler puts (LSelectPointers - pc) so it fits in 1 byte.
     
  7. Agent ME

    Agent ME

    Void where prohibited Member
    26
    0
    0
    Yeah, I put it right after an rts.

    Thanks for the help.
     
  8. Hayate

    Hayate

    Tech Member
    The other thing you can do is instead of writing bxx.b, use bxx.w. That makes the relative offset a word-length, giving you much more space to write code in.

    edit: oh snap, I just bumped a 5 month old topic :)
     
Thread Status:
Not open for further replies.