[General] Beginner ASM guide

Discussion in 'Approved' started by redhotsonic, Aug 27, 2007.

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

    redhotsonic Also known as RHS Retired Staff

    Joined:
    Aug 10, 2007
    Messages:
    2,967
    Location:
    England
    ASM guide update: How to work with the Motorola 68000 assembly (Basic ASM guide)

    If for some bizarre reason you want to read the old guide, it is here spoilered:

    I revived my ASM guide. I'm still currently looking for my palette rotation guide and Lost levels guide. I believe that will never be recovered, but this one is the main thing anyway.

    Please: If you find any bugs in this guide or do not understand anything, please say so here (or if topic is older than a month), on MSN Messenger (address found on my profile).

    ==================================================

    Introduction

    Welcome, to my ASM guide. Now, before we start, I am still learning ASM fully myself, so, there may be some bugs still in this guide. So, it is important to ALWAYS back-up your hack-work before making changes. Plus, I'm using Sonic 2 disassembly, so this guide is based on Sonic 2. If you're hacking Sonic 1 or something else, you can read on, but the activities will be different.

    In this guide, I'll teach you

    - What ASM means

    - The basics of ASM

    - Learning how ASM works

    - Editing some basics with ASM

    - Making a special ring for entering special stages

    This guide is for people who know a little ASM or none at all. I've learnt my ASM skills from drx's ASM guide, and from SMTP, Stephen and Ultima.

    Getting started

    Ok, you need all the basics. Here, from the help of Stephen, is everything packed that you'll need. I will be using Nemesis ASM build, so all references will be from his. If you wish to use a different build, you may do so, but not everything may be correct here. The pack I've given contains Nemesis build from drx's site. You'll also need SonED2 (contained in the pack).

    (Downloads will be here in guide later)

    If you get the build and SonED2 separately, firstly, extract everything from the build into a folder. Put your Sonic 2 ROM file in the same folder (must be a clean S2 ROM) and rename it to S2.BIN. Double click on split.bat and a load of folders will be created. Then, extract all the contents from SonED2 into the same folder into the build (say yes to anything it wants to over-write).

    Once you have everything, we'll start learning.

    What is ASM?

    ASM stands for ASseMbly. It helps build your ROM. Basically, ASM is instead of Hex (Machine Code); it uses words instead of numbers. That's why people use ASM more than Machine Code.

    The basics commands of ASM

    Okay, in your folder, look for the S2.asm file and open it with a word editor (I use Notepad). Look at that, there's so much to it, but we can learn it. Close the file down for now, and let's get learning. I'll teach you some ASM commands. Let's go to the first one.

    The MOVE command:



    move.w #2,($FFFFFEB8).w


    Let's look at the bit where it says move.w. Move, literally means move. It moves whatever you want to move to a certain point. But what's the .w mean? Well, this means word. You can get .b (byte) and .l (longword). A byte is two nibbles (00), a word is 4 nibbles (0000), and a longword is 8 nibbles (00000000). The $FFFFFEB8 is a RAM address; these store bytes that you want and can change. You can consider it as a memory. When moving something to a RAM address, it must always be a word (I highlighted it blue, in case you do not know what I mean). You see the text in RED saying 'The MOVE command: '? This is called a label, helping branches (that will be explained later). So, this command, what is it doing?



    move.w #2,($FFFFFEB8).w


    Well, let's go through it, move.w means it's moving a word. #2 is the byte we want to move, and must always put # in front of the number, so Genesis knows it is a byte. And the $FFFFFEB8 is the address we want it to go and you must always put a $ in front of the address, so Genesis knows it's an address.. Let's say that at address $FFFFFEB8 it is 00 00. After the command above, it'll become 00 02.

    Do you see how it works? No? Let's do another example.

    Pretend $FFFFFEB8 is: 00 02

    Let's say we want that 02 to be an 08, we do this:



    move.w #8,($FFFFFEB8).w


    Now, $FFFFFEB8 is: 00 08.

    It works.

    Here's a longword example. It works the exact same way.

    Pretend $FFFFFE10 is: 00 00 00 00



    move.l #6,($FFFFFE10).w


    Now, $FFFFFE10 is: 00 00 00 06

    Let's make things slightly more difficult. Let's say that $FFFFFFE6 is 02 03 04 05. What would this become if we did this command?



    move.w #4,($FFFFFFE6).w


    Well, $FFFFFFE6 will become 00 04 04 05. The 00 04 in RED is what you just did. Remembering that .w is a word (4 nibbles, 00 00), and there is 8 nibbles to this address, it only does the first four nibbles. If we did:



    move.b #4,($FFFFFFE6).w


    $FFFFFFE6 would become 04 03 04 06, as the 04 in RED is what you just did.

    NOTE: It is not recommended to pick any old RAM address, as it may be being used elsewhere. For a list of addresses, look here.

    All commands can have comments (it doesn't HAVE to have a comment). This is if you want to remember what this command does. For example:



    move.b #4,($FFFFFFE6).w ; moves the byte 04 to the address shown


    If you want to add comments after a command, you MUST put the Semicolon symbol ( ; ) after the command, then put whatever you want.

    There are more MOVE commands, but I wouldn't worry about them for now. Here they are if you ever look back here:

    MOVE

    MOVE

    MOVEQ

    MOVE Quick

    MOVEM

    MOVE Multiple

    MOVEA

    MOVE Address

    The ADD command



    add.b #2,($FFFFFEB8).w


    This is pretty much the same as the command MOVE, but it adds instead. Example, let's say $FFFFFEB8 is 01 01 01 01 and then we did this command above, it'll become 03 01 01 01. Do you see how it works? One more example.



    add.w #4,($FFFFFEB8).w ; going to add the word 04 to $FFFFFEB8


    $FFFFFEB8 is now 03 05 01 01.

    Here is an extra command:

    ADD

    ADD

    ADDQ

    ADD Quick

    The SUB command:



    sub.b #3,($FFFFFEB8).w


    This is nearly the same as the add command, except we're going the other way. Instead of adding, we're subtracting. I'll only give one example here, as this is pretty straight forward.

    Pretend $FFFFFEB8 is: 09 09 09 09



    sub.b #3,($FFFFFEB8).w ; going to take the byte 03 from $FFFFFEB8


    Now $FFFFFEB8 is: 06 09 09 09

    Here is an extra command:

    SUB

    SUBtract

    SUBQ

    SUBtract Quick

    Data and address registers

    Data registers are temporarily data holders (like memory again). It will remember a byte you told it to remember. All data registers are long words, and these types of registers exist from d0-d7. Example.

    d0: 00 00 00 00



    move.b #3,d0 ; going to move 03 to the data register 0


    d0: 03 00 00 00

    Until you tell it to change, that'll stay like that. Like said, it doesn't necessarily have to be d0, it can be... I don't know, d4. You can make d0 go to other places too.



    move.b #d0,($FFFFFEB8) ; going to move the data from d0 to $FFFFFEB8


    d0 will still be 03 00 00 00, but $FFFFFEB8 will also be 03 00 00 00.

    Address registers are also data holders, but these normally hold pointers, but can store data. These exist from a0 to a7, but avoid using a7 as it is a stack holder. Stack is a reserved data of the RAM for temporary things and I'm not quite sure what, so to be on the safe side, don't use it.

    More ASM commands

    The CMP command:



    cmp.w #3,($FFFFFEB8).w


    Ah, the COMPARE command. This just compares the byte you've put to the address. In this case, the word 03 to $FFFFFEB8. If $FFFFFEB8 is 00 03 07 08, this equals the word 00 03. If $FFFFFEB8 was 05 03 00 00, it would not equal the word 00 03.

    The BRA commands

    This, is the BRANCH command. There are many branch commands, but we're going to take it one step at a time. The command BRA stands for BRanch Anyway. This is what you want Genesis to branch (or go) to when you use this command. What do I mean? Well, take a look at this.

    The CMP:



    move.w #3,($FFFFFEB8).wadd.w #3,($FFFFFF10).w

    bra Morecodinghere

    sub.w #3,($FFFFFEB8).w

    Morecodinghere:

    move.w #3,($FFFFFEB8).w

    rts



    You're probably thinking, 'What the hell?' Do not panic. Let's go through this. First, it's saying it's moving the word 00 03 to $FFFFFEB8. Then it's adding the word 00 03 to $FFFFFF10. Here is when our new command, BRA, comes in. It's saying to branch (go to) 'Morecodinghere'. As you can see, there is a label called Morecodinghere. So, when it sees this, it goes to this label. So, the next thing it does, it is moving 00 03 to $FFFFFEB8.

    The sub.w command was ignored. This is because it got branched. If you took the BRA command out, it would do that SUB command.

    In the Morecodinghere label, you can see underneath its MOVE command, is a new command:

    The RTS command

    This means 'Return To Subroutine'. So, in that code, it's telling to go back to the label, 'The CMP:'. It is important to put RTS. If you do not, it will carry on.



    Morecodinghere:move.w #3,($FFFFFEB8).w

    rts

    Sumrandomcode:

    add.w #3,($FFFFFEB8).w



    Because of that RTS command, the label 'Sumrandomcode' is being ignored. If the RTS command was not there, the 'Sumrandomcode' label would take place.

    Here's two new branch commands

    The BEQ and BNE commands

    BEQ stands for Branch if EQual. BNE stands for Branch if Not Equal. This is where the compare command comes into use. Take a look at this.



    BEQlabel:cmp.w #3,($FFFFFEB8).w

    beq Itequaled

    sub.b #2,($FFFFFEB8).w

    Itequaled:

    add.b #2,($FFFFFEB8).w

    rts



    Let's go through this. First we're comparing if $FFFFFEB8 equals 00 03. Then we've got our BEQ command. Basically, it is saying if $FFFFFEB8 DID equal 00 03, then branch to the label 'Itequaled'. Now, because it branched, the sub.b command is ignored and it goes to the label 'Itequaled'. If $FFFFFEB8 did NOT equal 00 03, it will carry on and do the sub.b command.



    BNElabel:cmp.w #3,($FFFFFEB8).w

    bne Itequaled

    sub.b #2,($FFFFFEB8).w

    Itequaled:

    add.b #2,($FFFFFEB8).w

    rts



    Now, look at this. If $FFFFFEB8 did NOT equal 00 03, it WILL branch, as we've used the BNE command. However, if it DID equal 00 03, it will carry on and do the sub.b command. I hope you understand this. Here is a test. For this test, pretend that $FFFFFF10 equals 00 00 00 00.



    New label:move.w #3,($FFFFFF10).w

    add.w #3,($FFFFFF10).w

    cmp.w #6,($FFFFFF10).w

    bra Morecodinghere

    sub.w #3,($FFFFFF10).w

    Morecodinghere:

    move.w #3,($FFFFFF10).w

    rts



    Here's the question; In 'New Label', does it branch to 'Morecodinghere'? The answer, is yes. I'm not going to explain why it does; study it. If you still do not know why, go back to revise.

    There are more BRANCH commands. Here they are, but I'm not going to explain, as you should get the idea.

    BRA

    BRanch Anyway

    BSR

    Branch to SubRoutine

    BEQ

    Branch if EQual

    BNE

    Branch if Not Equal

    BGE

    Branch if Greater or Equal

    BGT

    Branch if Greater Than

    BLE

    Branch if Less or Equal

    BLT

    Branch if Less Than

    I hope this makes sense. There are more branches, but I do not understand them myself.

    The JMP command

    JMP stands for JuMP. It does exactly the same as BRA, but it can jump to any area in the ROM. You see, Branch can't go anywhere, but it is still more common than JMP. Even though JMP can go anywhere, there is no such thing as 'Jump if equal' or 'Jump if not equal' etc. Only JMP, and JSR (Jump to SubRoutine), which is pretty much the same.

    The LEA command

    I've never used this, but I know what it means. LEA stands for Load Effective Address. You can load an address to somewhere else. Example:



    lea ($FFFFFF10).w,a4


    Imagine at $FFFFFF10 was 00 02 00 04 and a4 was 00 00 00 00. After this command, a4 will now be 00 02 00 04. Apparently, this works in the exact same way as MOVEA does, but don't take me word for it.

    The NOP command

    This command is apparently illegal. This stands for No OPeration. It does nothing, literally. So, what is it used for, I do not know, to slow down the process of where it is? It's been explained that it waits for all processes to finish, whether it's true, I have no idea.

    The DC command

    This is to store data in the ROM. What does DC stand for? I'm not actually sure, but you can see this anywhere. Here's an example.



    dc.b 0, 1,$F8, 5, 0, 0, 0, 0,$FF,$F8


    This is part of the ring's mappings. Looks weird, eh? As it is dc.b, its adding bytes, so here, it is adding 00 01 F8 05 00 00 00 00 FF F8. As you can see, there are $ signs there. This just means that there is more than one nibble being inputted it. Why a $ instead of a # sign, I don't know. When you get a number on its own, like 1, when the ROM gets built, a 0 appears in front. So 1 equals 01. Example:



    dc.b 0, $11, 1 = Correctdc.b 0, 11, 1 = Incorrect

    dc.b 0, $11, 01 = Incorrect



    You can also have dc.w dc.l. If that was dc.w, it'll be putting into the ROM 00 00 00 01 00 F8 00 05 00 00 00 00 00 00 00 00 00 FF 00 F8.

    DC can be used for palettes, mappings, pretty much anything.

    The CLR command

    This means CLeaR. This can clear data (obviously) to any RAM address you want. Let's do an example. Pretend that $FFFFFF10 is 05 05 05 05.



    clr.b ($FFFFFF10).w ; Clear the byte from $FFFFFF10


    Now, $FFFFFF10 is 00 05 05 05.


    Code:
    clr.w ($FFFFFF10).w ; Clear the word from $FFFFFF10
    
    Now, $FFFFFF10 is 00 00 05 05.


    Code:
    clr.l ($FFFFFF10).w ; Clear the longword from $FFFFFF10
    
    Now, $FFFFFF10 is 00 00 00 00.
    Quick Homework

    $FFFFFEB8 is 00 00 00 00 and $FFFFFF10 is 01 01 01 01. What will these two address show after this process?



    Code:add.w #4,($FFFFFEB8).w

    add.b #3,($FFFFFF10).w

    cmp.w #3,($FFFFFEB8).w

    beq Codetwo

    move.l #9,($FFFFFF10).w

    sub.w #3,($FFFFFEB8).w

    Codetwo:

    clr.l #4,($FFFFFF10).w

    rts



    Answer: $FFFFFEB8 is 00 01 00 00 and $FFFFFF10 is 00 00 00 09. Did you get that? If you didn't, try looking at it again, or go back to more commands for help.

    Editing the basics

    Editing the basic is pimp-squeak. You literally do not need any ASM knowledge at all. If you ever want to edit palettes, mappings, text, arrays, start positions, etc, you can search for them. Open up the file s2.asm and go on Edit > Find. Type "array" (without the quotation marks). Keep looking until you come to Level size array. Underneath, you'll see this:



    word_C054: dc.w 0,$29A0, 0, $320; 0


    This, is the level size array for Emerald Hill Act 1. They go down in order of Level ID. If you remember what I told you about the command DC, you should know this is 00 00 29 A0 00 00 03 20. The very last 0 is a comment as ; is before it. It's a weird comment. Change the array to what you want. But remember, if you going to change them 0's into two or more nibbles, put a $ in front. Example:



    word_C054: dc.w 0,$29A0, 22, $320; 0 = Wrongword_C054: dc.w 0,$29A0, $22, $320; 0 = Right



    If you ever want to change things like this, search for it using the Find tool. Example, you want to edit Sonic's start position. Edit > Find > type "start" (without the quotation marks) and keep finding until you come to Character start location array. Edit away.

    Some things can't be done in ASM, like Sonic's palette. ASM tells to load a file. If you go to the folder ART/PALETTES, you'll find a file in there called something like 'Sonic's palette'. You edit that using a hex editor. So if you can't find the stuff you want to edit in ASM, look for the file, if you can't find that, contact me.

    Making the special ring object

    Ok, things are going to get complicated here, but if you follow this thoroughly without missing bits, you'll be fine, and it'll be a breeze. Okay, first of all, open up your s2.asm file. Edit > Find > Type "SprPoint:" (without the quotation marks). Here, is the list object. These are pointers on where the code is. The comments are the object number, but not in HEX format. Here's a little guide on the object list.

    Sprite_1637C is an empty coding. So, object 4C is empty. We can use this. Find:



    dc.l Sprite_1637C ; 76


    Name it to:



    dc.l Sprite_Specialring ; 76


    Now, it'll be going to the Specialring pointer, except it doesn't exist. But we can sort that. Find "Red" (without the quotation marks) and the second find should display this:



    ; ----------------------------------------------------------------------------; Sprite

    ;

    ; Red spring

    ; ----------------------------------------------------------------------------

    Just before the first line before the word Sprite, insert all this:

    ; ----------------------------------------------------------------------------

    ; Sprite

    ;

    ; Special Ring

    ; ----------------------------------------------------------------------------

    Sprite_Specialring: ;This is when the pointer we changed comes to.

    moveq #0,d0

    move.b $24(a0),d0

    move.w off_SpecialringIndex(pc,d0.w),d1

    jmp off_SpecialringIndex(pc,d1.w) ;moves us to the next bit of the code (look down)

    ;****************************************************************************

    off_SpecialringIndex:

    dc.w loc_Specialring_Init-off_SpecialringIndex

    dc.w loc_Specialring_Frame-off_SpecialringIndex

    dc.w loc_Specialring_Collision-off_SpecialringIndex

    dc.w loc_Specialring_Delete-off_SpecialringIndex

    ;****************************************************************************

    loc_Specialring_Init: ;graphics and such are set up here

    addq.b #2,$24(a0)

    move.w 8(a0),$32(a0)

    move.l #MapUnc_12382,4(a0)

    move.w #$26BC,2(a0)

    jsr sub_16D6E

    move.b #4,1(a0)

    move.b #2,$18(a0)

    move.b #$47,$20(a0)

    move.b #8,$19(a0)

    loc_Specialring_Frame: ;executed every frame - for animation/drawing

    move.b #0,$1A(a0)

    move.w $32(a0),d0

    jsr loc_1640A

    rts

    loc_Specialring_Collision: ;executed upon collision with sonic

    loc_Specialring_Delete: ;delete the object

    rts

    ;****************************************************************************



    Oh, my. This looks complicated eh? There are comments there to help explain what which part does. This is what Ultima gave me, as my new object code sucked. Always use this when making new objects, and just change to name Specialring to whatever, but in this case, leave it. The loc_Specialring_Collision: part is where we are going to add our brand new code.



    loc_Specialring_Collision: ;executed upon collision with sonicmove.w #1,($FFFFFEB9).w ;add one word to $FFFFFEB9



    This is all we need at the collision, seriously. Now, we need to find the bit when the level fades to go to the next level. Save the ASM file, the go on EDIT > Find > loc_1429C: and you should find this:



    loc_1429C: ; CODE XREF: ROM:00014292 jmove.w d0,($FFFFFE10).w

    clr.b ($FFFFFE30).w

    clr.b ($FFFFFEE0).w

    move.w #1,($FFFFFE02).w

    rts



    Change it to:



    loc_1429C: ; CODE XREF: ROM:00014292jclr.b ($FFFFFE30).w

    clr.b ($FFFFFEE0).w

    cmpi.w #1,($FFFFFEB9).w ; Does $FFFFFEB9 equal 00 01?

    bne.s nextlevel ; Branch if not

    move.b #$10,($FFFFF600).w ; set game mode to Special Stage

    clr.w ($FFFFFEB9).w

    rts

    nextlevel:

    move.w #1,($FFFFFE02).w ; Set level reset

    clr.b ($FFFFFEB9).w



    Ok, the line in blue has been deleted. The lines in RED is what you've added, and the line in green is what you've shifted. Now what happens is just before the level fades, if $FFFFFEB9 equals 00 01, it will go to the special stage instead of the next level. If it does not equal, it will go to the next level. When you go to the special stage or next level, $FFFFFEB9 also gets cleared, so it's ready for the next level when you put another ring in there.

    Now, Find > Edit > "loc_1428C: " (without the quotation marks) and you'll find this:



    loc_1428C: ; CODE XREF: ROM:00014286jmove.w (a1,d0.w),d0

    tst.w d0

    bpl.s loc_1429C

    move.b #0,(Mstr_Lvl_Trigger).w

    rts

    Change to:

    loc_1428C: ; CODE XREF: ROM:00014286j

    move.w (a1,d0.w),d0

    move.w d0,($FFFFFE10).w

    tst.w d0

    bpl.s loc_1429C

    move.b #0,($FFFFF600).w

    rts



    The lines in green is what you add/edit. This supports the ROM to go to the next level after the special stage. If followed correctly, this should now work. Save your ASM file, and put an object in EHZ act 1 to test it. Put 4D 00 08 as the object. To build, double-click build.bat and after, S2BUILT.BIN will appear. You may need to fix the checksum before playing. Now test away.

    ==================================================
     
    Last edited by a moderator: May 24, 2013
  2. Irixion

    Irixion Well-Known Member Member

    Joined:
    Aug 11, 2007
    Messages:
    670
    Location:
    Ontario, Canada
    Holy shit...Thank you =D. This actually makes sense to me...You've made my day.
     
  3. Sephiroth

    Sephiroth WHY SO CURIOUS?!? Member

    Joined:
    Aug 11, 2007
    Messages:
    507
    Location:
    Qatar, M.E.
    I don't understand it very well. I just don't get what the commands DO like I know that MOVE moves bytes but how does it affect the ROM? If someone could explain that to me I would be grateful.
     
  4. redhotsonic

    redhotsonic Also known as RHS Retired Staff

    Joined:
    Aug 10, 2007
    Messages:
    2,967
    Location:
    England
    Yes, it does, but only what you've told it to do.


    For example, $FE12 is the number of lives. When you start the game, it is set to #3. If you added this command:


    move.w #1,($FFFFFE12).w


    The lives will get set at one. It shouldn't affect anything else in the ROM.
     
  5. Sephiroth

    Sephiroth WHY SO CURIOUS?!? Member

    Joined:
    Aug 11, 2007
    Messages:
    507
    Location:
    Qatar, M.E.
    That sees plausible, but is it basically just hex in a different format? Like for example there are multiple characters and you wanted some with different live amounts you could ue the BRA command, right? This would be impossible in hex but easy to do in ASM.
     
    Last edited by a moderator: Aug 27, 2007
  6. redhotsonic

    redhotsonic Also known as RHS Retired Staff

    Joined:
    Aug 10, 2007
    Messages:
    2,967
    Location:
    England
    ASM is another format, yes.


    ASM explains and builds the hack with words and commands. Hex explains and builds the hack with numbers.


    The BRA command can be involved with what you said.
     
  7. PsychoSk8r

    PsychoSk8r HighKnights Member

    Joined:
    Aug 9, 2007
    Messages:
    267
    Location:
    Birmingham, UK
    Absolutely Brilliant!


    I have been figuring out ASM bit by bit, not knowing exactly what it means, but by looking at similar commands and modifying them to my need. This explains perfectly. Thank You! =P
     
    Last edited by a moderator: Aug 28, 2007
  8. hitaxas

    hitaxas I can has super speed? Member

    Joined:
    Aug 13, 2007
    Messages:
    152
    Very nice, it clears some things i had yet to learn.
     
  9. shobiz

    shobiz Well-Known Member Member

    Joined:
    Aug 11, 2007
    Messages:
    198
    Location:
    Karachi, Pakistan
    Some idiot over at the Glowing Bridge copy-pasted your lost levels guide and tried to claim it as his own. He got banned for it of course. The link is http://www.glowingbridge.org/forums/showthread.php?tid=162, but you'll need to be a member to access it.

    Not meaning to sound rude, but why are you using Nemesis' disassembly? Aurochs' disassembly targets a far superior assembler, is better labeled, builds in 5 seconds instead of 150, is compatible out-of-the-box with SonED2 and has quite a few useful comments in certain places. It also does away with s2comb.asm, making debugging much easier. The only problem with it is that SonED2 project files aren't publicly available, so you'll have to make your own, but that's a five minute job and is a pretty small price to pay for the extra descriptiveness. Just be sure to read http://www.glowingbridge.org/forums/showth...id=1952#pid1952 for three small bugfixes.

    Well, technically speaking, RAM addresses from $FFFF0000 to $FFFF7FFF have to be accessed as longwords, but now I'm being nit-picky :p

    You really should give a bit of information about the different addressing modes that can be used with address registers, since that's pretty vital to understanding the game's code. A stack is a special data structure based on the principle of Last In First Out (LIFO), that is, the last thing you put into it is the first thing you can access. Stack can be used within a subroutine to either backup registers in case you want to modify them but are afraid they may contain some important value, or to store a few variables. However, the stack is also used by the 68000 to store the Program Counter (PC) so that it knows which address to return to when it encounters an rts, and for this reason, it's kinda hard to use it to store variables which have to be used by different subroutines.


    As an example,



    Code:
    movem.l	d0-d7,-(sp)
    stores (pushes) data registers d0 to d7 on to the stack, and





    Code:
    movem.l	(sp)+,d0-d7
    restores (pops) the registers.



    Once again, I'm going to be nit-picky :p. Firstly, the exact limitations of Bcc instructions are 127 bytes forward/128 bytes back for byte-long branches, and 32767 bytes forward/32768 bytes back for word-long branches. Secondly, IMO it's a good coding practice to always specify a size for any branch so that branch instructions don't occupy unnecessary space. Thirdly, the difference between bra and bsr (or jmp and jsr) is actually pretty important. Bra/Jmp don't push the value of the Program Counter onto the stack, while Bsr/Jsr do. That is, you can't use an rts to return from code called with Bra/Bcc/Jmp. As an example:





    Code:
    Foo:
    
    	bsr.s	Bar
    
    
    
    Bar:
    
    	bra.s	Baz
    
    
    
    Baz:
    
    	rts
    The rts command will cause program execution to resume at Foo, not Bar, since the bra didn't push the current PC onto the stack for rts to be able to retrieve. (That's a pretty stupid example I've given, but meh)

    Being nit-picky is fun :p. a4 won't be 00 02 00 04, it'll be $FFFFFF10 (that is the address you just loaded). (a4) will be 00 02 00 04. The difference might seem trivial but it's important.

    Umm, no it doesn't, it means a hex literal is being inputted. Similarly, a % sign represents a binary literal and a @ sign represents an octal literal.


    As a beginner's guide, this is excellent. However, there are a lot of things not explained at all, such as the different types of move, sub, and add, addressing modes, stack, the condition code register, certain Bcc commands (most notably BCS and BCC), etc. Perhaps you should add a note at the end saying that for more details, one should read Drx's ASM guide and/or the Motorola 68000 Programmer's Reference Manual
     
    Last edited by a moderator: Aug 28, 2007
  10. Sephiroth

    Sephiroth WHY SO CURIOUS?!? Member

    Joined:
    Aug 11, 2007
    Messages:
    507
    Location:
    Qatar, M.E.
    I think Im starting to understad how it all works. One thing: If we have done the coding for the special ring, wheres the sprites? I'm guessing we have to make them using TLP or something. Hmmm. I think I am getting this. Thanks. This is definately going in my favourites. I might even save a copy so I don't have to use the internet.
     
  11. redhotsonic

    redhotsonic Also known as RHS Retired Staff

    Joined:
    Aug 10, 2007
    Messages:
    2,967
    Location:
    England
    @shobiz: Like I said, if you point out anything, it will be very helpful so I'm glad your nit-picking.


    As for the nemesis dissassembly, I made this guide when the others were not available (from what I know).


    Plus, I tried using the 2006 disassembly, but it didn't work well. I changed the SonED2 file so it would load and it did. But when I clicked save, it stopped responding. I rechecked the level and it did save. But then when I clicked build, it did nothing, literally. No errors to display either, so I gave up.


    @Sephiroth: I'm still to figure out how to do sprites, I haven't leant how, only to change the mappings.
     
  12. shobiz

    shobiz Well-Known Member Member

    Joined:
    Aug 11, 2007
    Messages:
    198
    Location:
    Karachi, Pakistan
    Hmm, that's really weird. Are you sure you applied the bugfixes? They don't really cause the build process to mess up, but that's the only thing I can think of. Otherwise, it's probably a SonED2 bug. I've used Aurochs' disassembly and it's not messed up for me yet, but I haven't tried using it with SonED2 yet, so I really don't know what could be the cause of the problem.


    EDIT: When I was starting out, the thing that took me the longest to understand was what all the $24(a0), $1C(a0) etc stuff was. They're actually object status table variables, and for more information on them, read http://info.sonicretro.org/SCHG:Sonic_2/RA...us_Table_Format.
     
    Last edited by a moderator: Aug 28, 2007
  13. redhotsonic

    redhotsonic Also known as RHS Retired Staff

    Joined:
    Aug 10, 2007
    Messages:
    2,967
    Location:
    England
    I don't think I did apply the bug fixes actually. Will re-look soon.
     
  14. Sephiroth

    Sephiroth WHY SO CURIOUS?!? Member

    Joined:
    Aug 11, 2007
    Messages:
    507
    Location:
    Qatar, M.E.
    ARGH!!! *screams*


    I read through your guide again and tried the Special Ring thingy. I followed the coding down to the letter and every time it builds it gets to when it says Finished in blah seconds then a whole load of error messages pop up on the Command Prompt Screen and then it closes before I can see the error.


    Any suggestions on how to fix this?


    EDIT: Fixed it because the lines weren't tabbed twice inwards. What a stupid error.


    Another Problem: Now that I got it in there and the ROM Built, The object does nothing at all. It just stops Sonics Automatic running that happens a few seconds after the end sign has been hit. There is no sprite either ( I think I asked about that before and I think I need to make it, but how would one know how to insert it in the right place so that it is added?
     
    Last edited by a moderator: Sep 1, 2007
  15. redhotsonic

    redhotsonic Also known as RHS Retired Staff

    Joined:
    Aug 10, 2007
    Messages:
    2,967
    Location:
    England
    It shouldn't of effected the sign. Are you using nemesis dis? It was designed for that, whether it makes a difference, I do not know.
     
  16. Sephiroth

    Sephiroth WHY SO CURIOUS?!? Member

    Joined:
    Aug 11, 2007
    Messages:
    507
    Location:
    Qatar, M.E.
    I'm using the Nemesis one, yes. I placed it right next to the sigin (after of course) for testing reasons but it doesn't seem to do anything now.
     
  17. redhotsonic

    redhotsonic Also known as RHS Retired Staff

    Joined:
    Aug 10, 2007
    Messages:
    2,967
    Location:
    England
    Send me your ASM and I'll take a look.
     
  18. Sephiroth

    Sephiroth WHY SO CURIOUS?!? Member

    Joined:
    Aug 11, 2007
    Messages:
    507
    Location:
    Qatar, M.E.
    I got your email RHS, sorry I didn;t reply, I left my MSN on when I went out. Anyway, I had a look at the file and it was pretty organized and I tried building the rom to see if it would work but no dice. I just can't figure out why it doesn't work. I'll have a re-check to see if there are any errors but if not then I don't know.
     
  19. redhotsonic

    redhotsonic Also known as RHS Retired Staff

    Joined:
    Aug 10, 2007
    Messages:
    2,967
    Location:
    England
    Ok, the guide had little mistakes that Sephiroth and I found. I have edited the guide with a red-bold colour.


    The special thing now works with him.
     
  20. Sephiroth

    Sephiroth WHY SO CURIOUS?!? Member

    Joined:
    Aug 11, 2007
    Messages:
    507
    Location:
    Qatar, M.E.
    Thanks for all the help, RHS.

    EDIT!!! Ack! You forgot a fix! That clr.b is screaming for a clr.w to replace him!
     
    Last edited by a moderator: Sep 5, 2007
Thread Status:
Not open for further replies.