Research / Megadrive Programming / Let's start

Ok, you need some stuff first. You have to download SNASM68k from our downloads section and a Sonic 1 disassembly
(I suggest you download my disasm because I will refer to its labels).
Now open the Sonic 1 disassembly in notepad. Many lines isn't there? =P



Comments are marked by ; or *. The game code starts with label 'Entrypoint:'.



Ok, let's start with the most interesting part of programming, programming XD. Ok, first command, MOVE.
This command moves some data (constants, registers, RAM) into either
another register or RAM location. JohnnyUK nicely called it 'copying'.



Syntax: move source,destination


Exapmles:
move.w #2,($FFFFFE10).w
move (a6),d3
move.b ($FFFFFE12).w,(a5)+




Looks complicated? Don't worry, I'll explain everything =) First, why .w, .b? If you use it, you will specify the data length being copied. If you don't the assembler will probably choose .l. .b is byte, .w is word and .l - longword.



For example:



move.b	#1,($FFFFFE10).w


before - FFFFFE10: 05 06 07 08
after - FFFFFE10: 01 06 07 08

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

before - FFFFFE10: 05 06 07 08
after - FFFFFE10: 00 01 07 08

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

before - FFFFFE10: 05 06 07 08
after - FFFFFE10: 00 00 00 01


I hope you get it =P Now, #x is a immediate value (a number, constant etc =P). Examples:



#5 - decimal 5


#$20 (hex) - decimal 32

#%1001 (binary) - decimal 9

#@777 (octal) - decimal 511

#'SEGA' - ascii text (remember, this can be tricky. 1 letter - use .b, 2 letters - use .w, 4 letters - use .l)



($FFFFFE10).w is an absolute address. Locations in ram HAVE TO be .w. ROM addresses usually are .l. Some programmers (forgot the name of the game...) use .w
for short ROM addresses, but that can cause serious bugs. Remember,
never write anything to a ROM address ;) (real Genesis will crash)



Examples:



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


moves 1 (byte) to $FFFFFE12 in RAM (lives in Sonic 1)

move.l	($12346).l,d0


moves a longword from address $12346 in ROM to data register d0.
move.w	(a0)+,d0


moves a word from the location at A0 to d0, increments a0 by 2 (length of word) after that.


I'll explain the registers now (already told about it before, but let's
revise XD). There are 16 registers - 8 data registers and 8 address
registers. All registers are longwords. Data registers are called d0-d7 and can store any data. Address registers usually store pointers to some location in ROM or RAM, but they can also be used for data. Address registers are a0-a7, but don't use a7 because it's the stack pointer (I'll explain later). Registers are a nice way of storing temporary data. Eg.



move.b	($FFFFFE12).w,d0 ;copy value at $FFFFFE12 to d0 (this is a comment =P)

move.b d0,($FFFFFE13).w ;move d0 to $FFFFFE13


Of course this could be done with:

move.b	($FFFFFE12).w,($FFFFFE13).w


but this is an example =P The biggest reason why use registers is that you can modify them without modifying the source, eg.



move.b	($FFFFFE12),d0	;copy $FFFFFE12 to d0

add.b #2,d0 ;add 2 to d0
;do something with d0


We have a new command, ADD. It adds a number to a register or a place in ram.



Syntax: add source,destination


Examples: add.b #2,($FFFFFE12).w ;increment $FFFFFE12 by 2
add.l (a0),a0 ;increment a0 by value at a0
add d0,d0 ;add d0 to d0 (d0 = d0 * 2)


What is the difference between a0 and (a0)?



a0 is the address, only a number. And (a0) is the value at this address. Have a look at this:


$FFFFFE12: 01	;some value in ram

a0: $FFFFFE12 ;address
(a0): 01 ;value at address $FFFFFE12


You can postincrement or predecreament address registers:


;a0 is incremented by 1 (length of byte) after the instruction

move.b (a0)+,d0

;a0 is decremented by 2 (length of word) before the instruction
move.w -(a0),d0


Exapmle:


move.l	(a0)+,d0


before: a0: $00012345
d0: $00000000
$000012345: $FFFFFFFF

after: a0: $00012349
d0: $FFFFFFFF
$000012345: $FFFFFFFF


Hope you understand =)



Now, the opposite of adding is substracting. You do it using SUB instruction.



Exapmles:


		sub	#5,a0

sub.w (a0),($FFFFFE12).w
sub.b d0,d1


That would be the end of this chapter. In next lesson we'll learn about LEA,
labels, comparing and branching depending on the results (like
if...else). It's about 3 am and I'm a bit tired. If you don't
understand something or you have any questions, ask on the forums =)


Back | Printer friendly
<< 1. Basics | 3. Compares, branches... >>

© 2004, 2005 drx, www.hacking-cult.org. Don't copy without permission yadda yadda yadda.