SCARZIP (SCARZ Information Pane)
Sonic Stadium
Green Hill Zone


THE 10 CULTMANDMENTS | THE IDIOT'S GUIDE TO POSTING AT SCARZ
Sonic Online
Sonic Dimension


Welcome Guest ( Log In | Register )

3 Pages V   1 2 3 >  
Reply to this topicStart new topic
> 68k Assembly Tutorial, since MOD hasnt posted it here yet
Exploding-Man
post Aug 31 2003, 11:04 PM
Post #1


CulT Villain

Group Icon

Group: CulT Member DX
Posts: 3,341
Joined: 21-August 03
Member No.: 70
Gender: Male



I've taken the liberty of posting it here again. Hope MoD doesnt kill me for it:

>> QUOTE
>> 
I originally started posting this at Area51 because they added a 68K/Hex forum. It sort of inspired me to start writing it. I'm going to continue to post it at Area51, but I'd like it to be mirrored elsewhere since this tutorial is for the whole community not just part of it. I'm going to do this for the 1st two parts, but I'd prefer if someone else would do it for the rest of them. Anyway, here you go:

Part I: Data, Instructions, and Memory

Everything the processor can access is in memory.  Memory is just a bunch of sequential locations.  These locations can be RAM or ROM or even a piece of hardware.  Each location is a byte wide and each location has a number or address associated with it.  On the 68K the first address is 0 and the last is $FFFFFF giving it access to 16MB of data.

A location in memory can store data.  Data is just a number.  Technically this number is stored in binary, but binary is inconvenient to work with so usually hex is used instead.  Any kind of data whether it be text, graphics or a web page is made up of numbers.

Instructions are a special kind of data.  They are still numbers, but they serve a special purpose.  They tell the processor what to do.  Instructions are executed in order until a special kind of instruction is executed that tells the processor to start executing instructions somewhere else.

These numbers can be hard to remember, especially since there are a lot of them.  To make things easier for programmers assembly language was invented.  Assembly replaces numbers with easier to remember mnemonics so instead of having to remember $4E75 I can remember RTS instead.  Don't worry about what this instruction does yet.  We'll get to it later.

Part II: Registers and Addressing Modes

All processors have a special kind of RAM called registers.  Like RAM, registers store data.  They are much faster than normal RAM, but you can store a lot less data in you registers than your RAM.  As a general rule, you want to get as much of your work done in your registers without going out to RAM as possible so that you get optimal performance.  The 68K has 16 registers named d0-d7 and a0-a7.  The first 8 are data registers.  Most of your number crunching will be done in these.  The last 8 are address registers.  As you might have guessed these store addresses.  All these registers are 32-bits (4 bytes) wide.

Before I introduce you to the addressing modes on the 68K, I want to teach you an instruction, namely move.  As its name suggests, move is used to move a piece of data from one location to another.  It has the following form:

move. ,

Size, can be either b (byte), w (word, 2bytes), or l (longword, 4 bytes).  As an example,

move.w d0, d1

would move 1 word (2 bytes) of data from register d0 to register d1


Now it's time to get acquainted with the addressing modes on the 68K.  "What is an addressing mode?", you ask.  Simply put, an addressing mode is a kind of thing you can put in either the or field in that move instruction I introduced you to earlier.  I'm not going to introduce every single addressing mode (or at least not all the details of every one).  You can look in the 68K Programmers Guide for that.

Keep in mind that while the 68K uses 32-bit addresses, it only has a 24-bit address space.  The upper 8 bits are ignored so $FF0000 is equivalent to $FFFF0000.

Register Addressing:

The source or destination is a processor register.
Example:
move.w d0, d1
Equivalent:
d1 = d0

Immediate Addressing:

The source is a constant value that becomes part of the instruction.  This is useful if you want to set a register or memory location to a specific value, but you don't need to do any calculations based on it ahead of time.  It also is very useful in simple mathematics calculations.  Oftentimes you'll find that you need to add or subtract 1 to a register.  Rather than eating up another register you can use immediate addressing.  Keep in mind that all immediate values must be prefixed by a #.

Example:
move.w  #1, d0
Equivalent:
d0 = 1

Absolute Addressing:

Here the source or destination is a location in memory.  You give the address of the location you want to use.

Examples:
move.l  $100, d0 (move a longword from memory location $100 to register d0)
move.b  #1, $FF0000 (store the number 1 at memory location $FF0000)

On a Genesis, the first example would move a longword from the header of the cartridge.  That location should contain the ASCII values for the string 'SEGA'.
The second example would store the number 1 in the first byte of Work RAM.

Absolute Near Addressing:

Before I explain this mode I have to tell you a little about sign extension.  Sign extension is a way of putting a smaller value in a place where a longer value belongs.  What happens is that the highest bit of the smaller value is copied into all the extra values in the larger number.  So when $8000 is sign extended from a word value to a longword value it becomes $FFFF8000, but when $7FFF is sign extend it it becomes $00007FFF or $7FFF.  If you don't want to think in binary just remember this: If the highest hex digit is greater than 7 then the extra digits will be filled with 'F's.  If the highest hext digit is less than 8 then the extra digits will be filled with 0s.  Note that when I say the highest digit, I mean the highest digit in the data width.  $80 as  a word value has a highest digit of 0.

Absoute near addressing is similar to absolute addressing except that instead of using a longword for the address a word is used.  This word is sign-extended giving you access to the first and last 32K of the memory space ($0 - $7FFF and $FF8000 - $FFFFFF).
Example:
move.w #1, $8000.w
Equivalent:
Memory Location $FF8000 = 1

Pointer Addressing:

You remember those address registers? Now you get to use them.  Let's say you want to access the same location in memory over and over again.  You could include the address as part of the instruction every time using the absolute addressing mode, but that's kind of slow and innefficient.  Instead, you can put the address in an address register and use that to reference the memory location.  If you want to use or affect the value stored in the address register, just use the name of the register by itself.  If you want to use or affect the memory location pointed to by the adress register, enclose the name of the register in parenthesis.

Examples:
move.l  #$FF0000, a0    ;Store the address $FF0000 in a0
move.w #1, (a0)        ;Store the number 1 at the memory location pointed to by a0 ($FF0000)

Pointer Relative Addressing:

Let's say you've got two values stored in RAM pretty close together, but you don't want to use two address registers and you don't want to use absolute addressing.  You can point an address register at the first, and then use that address register along with an offset to access the second.  An offset is a number from -$8000 to $7FFF that is added to the register to calculate the address that is used.  Note, this addition is not permanent.  It doesn't effect the value stored in the address register.

Example:
move.l  #$FF0000, a0 ;Store address $FF0000 in a0
move.w #1, (a0)          ;store the number 1 at memory location $FF0000
move.w  #1, 2(a0)    ;store the number 1 at memory location $FF0002

PC Relative Addressing:

The program counter (PC) is a special address register that points to the current instruction.  Although you can't treat it like an address register in most respects, you can use it for relative addressing in the same  way that you use it with an address register.  This will be more useful once we get to labels.

Example:
move.w    #1, $100(pc)      ;stores the value 1 at the memory location $100 bytes from the current instruction.

Pointer Addressing with Predecrement/Postincrement:

Let's say you wanted to access a bunch of sequential memory locations. You could use relative addressing to access each location, but there is a better way. With postincrement the value in the address register is incremented by the size of the last operation each time postincrement addressing is used. With postdecrement the value in the address register is decremented by the size of the operation before the operation is completed.

Examples:
move.l #$FF0000, a0 ;store address $FF0000 in a0
move.b #7, (a0)+ ;store 7 at $FF0000 and add 1 to a0, a0 now equals $FF0001
move.b #4, (a0)+ :store 4 at $FF0001 and add 1 to a0
move.w #3, (a0)+ ;store 3 at $FF0002 and add 2 to a0
move.l #9, (a0)+ ;store 9 at $FF0004
;a0 is now equal to $FF0008
move.w #6, -(a0) ;store 7 at $FF0006


Whew, that took longer than I thought it would. I know this was probably a lot of material to absorb in one sitting, but don't worry about mastering this now. Just try to remember the basic concepts and remember where to find the specifics (namely in Part II of this tutorial). If you find any of this confusing just say so and I'll do my best to explain it better.

Part III: Addition, Subtraction, and Two's Complement

You may have wondered how on earth a computer stores negative numbers if all it understands is 1s and 0s (okay you probably weren't wondering this, but I'm covering it anyway).  One solution might be to use the highest bit to represent the sign of the number.  If this bit is set then the number is negative, if it's not set the number is positive.  While that statement is correct, it doesn't represent the whole truth, but before I explain the rest of it you need to understand something else first.

What happens when you add a 1 to 9 (decimal)?  You run out of room in the current digit, so you do a carry into the next digit making the result 10.  The same thing happens when you add 1 to $FF (hex).  All the bits are filled in the first byte, so a carry is done into the first bit of the next byte making the result $100, but what happens if the variable you are storing the result in is only a byte wide?  The upper digit is lost and you are left with $0. 

So in byte arithematic, $FF + 1 = 0.  What other value when added to 1 gives us 0?  x + 1 = 0  With some simple algebra we find that -1 is the answer.  It turns out that the nature of fixed width arithematic gives us an easy way to make negative numbers.  Let me give you another example to make it clearer.  What is the result when you subtract $2 from $100?  You get $FE.  Now if this was byte wide math, then that 1 wouldn't be there and you would borrow from a digit that doesn't exist so $0 - $2 = $FE or -2.  Hopefully you are beginning to see a patern here.  When you count backwards from 0 on a computer, the numbers loop around so -1 = $FF, -2 = $FE, -3 = $FD, etc..  Keep in mind that with a larger datawidth these values change.  For a word, -1  = $FFFF, -2 = $FFFE and so on.

That is why offsets were sign-extended in the last  tutorial section.  If they weren't negative offsets would become positive when they were stretched to fit a longword wide address.  $FFFF is a positive number if it's a longword, but if you copy the highest bit into the extra bits in the longword, it becomes negative again, $FFFFFFFF.

Okay, enough of the theory behind how the computer works.  It's time for some actual processor instructions.

add.    ,

You'll notice that the syntax for add looks just like the syntax for move.  A lot of instructions on the 68K work this way which is convenient because that way you can have some vague idea what is going on even if you don't know the exact function of the instruction.  You'll always know what the source and destination are. It also means you can use all those fancy addressing modes for most instructions.

Examples:
add.w  #2, d0
add.l    d1, d0
Equivalents:
d0 = d0 + 2
d0 = d0 + d1

Those of you familiar with C can think of this as the += operator.  If you don't know C, don't worry about that comparison.  Just look at the Equivalents.

sub.    ,

Pretty much the same idea here, but be careful.  With subtraction it matters what order the operands come in so you have to remember which operand this instruction subtracts from which.  It works like this:  = - .

Examples:
sub.b    #3, d4
sub.w  d0, d1
Equivalents:
d4 = d4 - 3
d1 = d1 - d0

That's it for part III, have fun.


Thats all we have so far of Mask of Destiny's 68k tutorial. Its here again, yay.


--------------------
=)
Go to the top of the page
 
+Quote Post
Overlord
post Sep 3 2003, 12:27 PM
Post #2


I love 1Mb/s DC++ Hubs, I really do

Group Icon

Group: CulT Family
Posts: 3,079
Joined: 21-August 03
From: Coventry, England
Member No.: 122
Gender: Male
Country: United Kingdom



BUMP

Someone pin this. =P


--------------------
Shadowsoft-Games.com



A new style.


From all over the UK and proud of it, bitches. =P


 
 
 
 
 
 
 
 
Mystifying MSN Chats!Overlord: Also, I've discovered something unsettling
Overlord: The Now Playing and Fucking Love/Hate sections on people's sigs
Overlord: Are faded/darked versions of colours
Overlord: Grey is dark white, and the other 2 can be lightened to be red and blue, as they are
NiktheGreek: Yup
Overlord: What flag uses the colour and layout of the setup?
Overlord: RUSSIA
Overlord: IT'S AN INVASION D:
NiktheGreek: XDDDDD

 
 
 
 
 
 
 
 
Go to the top of the page
 
+Quote Post
Hivebrain
post Sep 3 2003, 03:09 PM
Post #3


The Thing

Group Icon

Group: CulT Family
Posts: 618
Joined: 21-August 03
From: Eggmanland
Member No.: 117
Gender: Male
Country: United Kingdom



This guide doesn't explain the meaning of 68k as it appears in a hex editor. I'd like a list of what each word means in hex, like this:

41F9 = whatever
00C0 = something
etc.


--------------------
Go to the top of the page
 
+Quote Post
Mask of Destiny
post Sep 3 2003, 03:17 PM
Post #4

Objective-C == suckage

Group Icon

Group: CulT Family
Posts: 968
Joined: 21-August 03
Member No.: 85
Gender: Male
Country: United States



>> QUOTE(Hivebrain @ Sep 3 2003, 12:09 PM)
>> 
This guide doesn't explain the meaning of 68k as it appears in a hex editor. I'd like a list of what each word means in hex, like this:

41F9 = whatever
00C0 = something
etc.

That would be an incredibly long list and it's really unnecessary unless you are writing an assembler or disassembler. Instead I recommend you use a disassembler. It's a program that takes a binary file and turns it back into mnemonics like I use here. The disassembler I use is called 68kd and it can be found here http://www.trzy.org/ You might also want to check out IRApc.

I will give you a few useful instructions to know

$4E71 = nop (do nothing)
$4E75 = rts (return from subroutine)
$60FE = bra -2 (basically an infinite loop that does nothing)
$4EF9 XXXX XXXX = jmp $XXXXXXXX (jump to absolute address)

Anyway, here comes Part IV of the tutorial

Part IV: Branches, Conditions and Labels

So far you can add, subtract, and shove data around. In and of itself this isn't too useful. The program will always do the exact same thing and has no real way to make decisions based on input. With this lesson that will change.

Remember that in a previous lesson, I said that the Program Counter is a special address register that points to the current instruction and that this register can't be changed directly. Today, I'm going to show you two instructions that can change PC, jmp and bra.

The jmp instruction replaces the value in PC with another address. This can be accomplished using any of the addressing modes except for ordinary PC relative addressing and register direct addressing.

Examples:
jmp $FF0000 ;this would cause a jump to memory address$FF0000

jmp $F000.w ;this would cause a jump to memory address $FFF000

movea.l #$300, a0
jmp (a0) ;this would cause a jump to memory address $300

move.w #$40, d0
jmp $4(d0, PC) ;this would cause a jump to $44 bytes past the current PC

The bra instruction is similar to jmp, except that it only works with simple PC relative addressing.

Examples:
bra #$100 ;branches to $100 bytes past the current pc
bra #$6.b ;brances to $6 bytes past the current pc

Having to calculate memory addresses and offsets are a real pain so assembler authors came up with a simple way around all this nonsense. They're called labels. A label is simply an alphanumeric string without any spaces. It must start with a letter. To define a label simply type it in at the first position on a line and add a colon. Once you've defined a label, you can treat it like a normal address. Also note, that instructions need to have whitespace in front of them, unlike what I've done so far in the tutorial

Example:
Mylabel:
bra Mylabel ;this would stick the processor in a never ending loop

Don't do this:
Mylabel:
bra Mylabel

Now you know how to make programs that don't just go in a straight line, but there is something that makes this even more useful, flags and conditions. The flags are just a bunch of bits in a special register called the Condition Code Register or CCR for short. These bits are effected by most instructions. For this section of the tutorial I'm only going to introduce you to one flag, the zero flag. This flag is set to 1 (true) if the result of the last operation was zero or more accurately if the destination in the last operation was set to zero.

Examples of when the zero flag is set:
move.w #0, d0

move.w #1, d0
sub.w #1, d0

move.b #$FF, d0
add.b #1, d0

Examples of when the zero flag is not set:
move.w #1, d0

move.w #3, d0
sub.w #1, d0

move.b #$FF, d0
add.b #$2, d0

Well that's all well and good, but how do we use these flags once they've been set? Simple, with branch instructions. Remember bra? That stands for BRanch Always. There are a number of variations on bra that only branch when certain flags are set. I'm going to introduce you to two right now, beq and bne.

beq stands for Branch if EQual. What this really means is that the processor will take the branch if the zero flag is set. If not, then execution continues as normal. You may be wondering where the EQual part comes from. It makes sense in subtraction and compare(we haven't touched on compare yet) operations. If both values are equal and you perform one of these operations, then the result will be zero, thus the name of the instruction.

Example of branch getting taken:
move.w #1, d0
sub.w #1, d0 ;1-1 = 0, zero flag set to 1 (true)
beq Skip: ;zero flag is set so the branch is taken

move.w #5, d0 ;this instruction is skipped

Skip: ;executiong jumps to here
addq #3, d0 ;d0 now equals 3

Example of branch not getting taken:
move.w #2, d0
sub.w #1, d0 ;2-1 = 1, zero flag set to 0 (false)
beq Skip: ;branch is not taken

move.w #5, d0 ;this instruction is executed

Skip:
addq #3, d0 ;d0 now equals 8

bne stands for Branch if Not Equal. It's the exact opposite of beq. If the zero flag is zero (false) than the branch is taken otherwise execution continues as normal. I won't do an example, since it should be easy enough to figure out given the examples for beq.


Once again, if you don't undertand anything in this part or any of the previous parts feel free to ask questions. I don't mind answering even the most basic of questions on assembly.

EDIT: Fixed line breaks

This post has been edited by Mask of Destiny: Oct 19 2003, 11:03 PM


--------------------
Do region conversions, dump cartridges, write Sega CD software. All this and more at http://www.retrodev.com/

Currently messing around with Mac OS X Cocoa development on my resurrected B&W G3.
Go to the top of the page
 
+Quote Post
Nemesis
post Sep 3 2003, 06:18 PM
Post #5


There's no such thing as 2

Group Icon

Group: CulT Family
Posts: 957
Joined: 20-August 03
From: Sydney, Australia
Member No.: 4
Gender: Male



>> QUOTE(Hivebrain @ Sep 4 2003, 06:09 AM)
>> 
This guide doesn't explain the meaning of 68k as it appears in a hex editor. I'd like a list of what each word means in hex, like this:

41F9 = whatever
00C0 = something
etc.

The M68K referance docs give that level of information on each command in the 68K command set. May I suggest that for anyone who's seriously attempting to learn 68K ASM that this manual is an invaluble resource. When starting out pretty much all of it will probably be indecipherable, but it'll make more and more sence as you progress, and it helps quite a bit in many cases, especially if you encounter a command that you've never seen before, and you need to know how it operates.


--------------------
Go to the top of the page
 
+Quote Post
Exploding-Man
post Sep 3 2003, 06:30 PM
Post #6


CulT Villain

Group Icon

Group: CulT Member DX
Posts: 3,341
Joined: 21-August 03
Member No.: 70
Gender: Male



Thank you once again MOD :) .


--------------------
=)
Go to the top of the page
 
+Quote Post
Boozer
post Sep 3 2003, 07:45 PM
Post #7

Guests






Kickass. Pinned.
Go to the top of the page
 
+Quote Post
Mask of Destiny
post Sep 3 2003, 07:55 PM
Post #8

Objective-C == suckage

Group Icon

Group: CulT Family
Posts: 968
Joined: 21-August 03
Member No.: 85
Gender: Male
Country: United States



>> QUOTE(Nemesis @ Sep 3 2003, 03:18 PM)
>> 
>> QUOTE(Hivebrain @ Sep 4 2003, 06:09 AM)
>> 
This guide doesn't explain the meaning of 68k as it appears in a hex editor. I'd like a list of what each word means in hex, like this:

41F9 = whatever
00C0 = something
etc.

The M68K referance docs give that level of information on each command in the 68K command set. May I suggest that for anyone who's seriously attempting to learn 68K ASM that this manual is an invaluble resource. When starting out pretty much all of it will probably be indecipherable, but it'll make more and more sence as you progress, and it helps quite a bit in many cases, especially if you encounter a command that you've never seen before, and you need to know how it operates.

Oh yeah, I should have posted a link to that. You can get the PDF here: http://e-www.motorola.com/files/archives/d...l/M68000PRM.pdf

There's another useful reference I sometimes use over at ticalc.org. It's not 100% accurate in one or two places, but it's a lot easier to understand than Motorola's docs. Get it here: http://www.ticalc.org/pub/text/68k/68kguide.txt


--------------------
Do region conversions, dump cartridges, write Sega CD software. All this and more at http://www.retrodev.com/

Currently messing around with Mac OS X Cocoa development on my resurrected B&W G3.
Go to the top of the page
 
+Quote Post
Steganos128
post Sep 13 2003, 07:06 AM
Post #9


Rape is such a harsh term. I prefer "Surprise Sex"

Group Icon

Group: Unwanted
Posts: 599
Joined: 28-August 03
From: STOKO
Member No.: 463
Gender: Male



What's a good Disassembler and Assembler for 68000?


--------------------
CODE
<REIROM> i,m not out the emuscene but going to go to put new tihns in epicenter: hentai yaoi dickgirls manga's anime's
Go to the top of the page
 
+Quote Post
Mask of Destiny
post Sep 13 2003, 10:12 PM
Post #10

Objective-C == suckage

Group Icon

Group: CulT Family
Posts: 968
Joined: 21-August 03
Member No.: 85
Gender: Male
Country: United States



For a disassembler I use 68kd. It doesn't go about things intelligently like IRApc, but I find it's easier to follow it's output.

Get it here: http://www.trzy.org/

For an assembler I use snasm68k. It's probably the best 68K assembler out there.

Get it here: http://cgfm2.emuviews.com/segastuf.php


--------------------
Do region conversions, dump cartridges, write Sega CD software. All this and more at http://www.retrodev.com/

Currently messing around with Mac OS X Cocoa development on my resurrected B&W G3.
Go to the top of the page
 
+Quote Post
Steganos128
post Sep 16 2003, 02:41 PM
Post #11


Rape is such a harsh term. I prefer "Surprise Sex"

Group Icon

Group: Unwanted
Posts: 599
Joined: 28-August 03
From: STOKO
Member No.: 463
Gender: Male



Thanks. I don't know if this will be of any use. I found it on my schools FTP :D
http://www.geocities.com/rampkorv/et63_md68.zip

EDIT: And a pdf file: http://www.geocities.com/rampkorv/md68k-sim.pdf

This post has been edited by Steganos128: Sep 16 2003, 02:49 PM


--------------------
CODE
<REIROM> i,m not out the emuscene but going to go to put new tihns in epicenter: hentai yaoi dickgirls manga's anime's
Go to the top of the page
 
+Quote Post
Mask of Destiny
post Oct 19 2003, 11:00 PM
Post #12

Objective-C == suckage

Group Icon

Group: CulT Family
Posts: 968
Joined: 21-August 03
Member No.: 85
Gender: Male
Country: United States



Part V: Subroutines, Exceptions and the Stack

Once your done with this one, you'll have all the basics of 68k assembly. There's still a lot more to learn, but for that you really need to write some code yourself and get cozy with the M68K manual. So this will probably be the last 68K tutorial for a while; however, do not fear. I will be writing some Sega CD programming tutorials soon so you can get some real world experience. Now, on to the stack.

A stack is a data structure, that means that it's made of a bunch of different values in RAM instead of just one like a byte or word variable. It's very appropriately named since it can be easily likened to a stack of books. With books, you can take one off the top of the stack, and you can put one back on, but you can't easily take a book out from the middle. A stack in the 68K works in much the same way. You can put a pice of data on top of the stack and you can get the piece of data that's on the top of the stack, but getting data from the middle of the stack is a bit trickier.

Typically, a stack occupies a number of sequential address in RAM, and on the 68K most stacks build down. This means that the first item put on the stack has the highest address, the next piece of data would have the next lowest address. So for example if the top address in the stack is $FFFFFE, and that location stores a word, if you were to put another value on the stack, it would be stored at $FFFFC. The next at $FFFFFA, and so on. If you put the numbers 1, 2, and 3 on the stack in that order, it would look like this:

$FFFFFE: 1
$FFFFFC: 2
$FFFFFA: 3

If you were to then pull the numbers back off the stack, you'd get 3, 2 and 1 in that order. For those of you who were paying attention, you would have noticed that the numbers come off the stack in the reverse order that they came. This reveals one of the most basic uses of a stack, to reverse the order of a set of values. However, this is not The most useful task a stack can accomplish. Another use is found in subroutines.

Subroutines are like small programs that can be called again and again by the main program (or by other subroutines). They're incredibly useful because they allow you to write the code for a certain task once,and then call it whenver you need it. This also allows you to make your program smaller since you only need one copy of the code, instead of having one for each time it would be used.

Subroutines work in a similar manner to branches. There are two mnemonics used to call subroutines, bsr and jsr. Like bra, bsr can only use PC relative addressing and like jmp, jsr can use just about any mode except relative addressing. So the following would all be valid, assuming that "MySubRoutine" was a valid label.

bsr MySubRoutine ;jump to the subroutine at MySubRoutine using relative addressing
jsr MySubRoutine ;do the same using absolute addressing
lea MySubRoutine(PC), a0
jsr (a0) ;jump to subroutine using pointer

There is one distinct difference between bsr and jsr, and their branch counterparts. bsr and jsr save the current value of PC so you can easily return to the point you called the function from. This is done with the rts instruction. Here's an example.

bsr MySubRoutine ;branch to MySubRoutine
moveq #0, d0 ;execution resumes here as soon as the subroutine is done

MySubRoutine:
moveq #3, d1
rts ;Go back to where the subroutine was called from

This allows you to use a subroutine multiple places within your program without having to duplicate the code. For instance, look at the following code:

bsr MySubRoutine
... ;do stuff
bsr MySubRoutine
... ;do more stuff
bsr MySubRoutine

This would cause the subroutine to be executed three times with some extra stuff in the middle. You may be wondering what this has to do with stacks. PC is saved onto something called the system stack. You may remember that register a7 is a special address register. It's the "system stack pointer." The system stack, is a stack like the one I described above. What makes it special is that it's used to store the contents of PC when a subroutine call is made. So when such a call is made, the following happens:

a7 is decremented by 4 to make room on the stack, so if a7 was equal to FFFF04 it would then equal FFFF00
PC is put into the memory location pointed to by a7, so in our example PC would be stored at FFFF00
jump to the subroutine

And when the corresponding rts is executed the following happens:

PC is read from the memory location pointed to by a7, in our example this location is FFFF00
a7 is incremented so it points to it's old location
processor jumps to the original location

Now for exceptions. Exceptions on the 68K occur for a variety of reasons. There's one that occurs at startup, there are others that occur when there are errors in processing (illegal instructions, bus errors, etc.), and then there are external interrupts. The latter is incredibly useful for integrating with hardware. Without interrupts, you have to keep reading from a piece of hardware waiting for an event to happen. The time used for this could have been used for some other processing task, but instead you're forced to waste your time waiting for the hardware. Interrupts allow the hardware to interrupt the processor from what it's doing so it can handle hardware access.

This works in a similar way to subroutine calls, PC is pushed onto the stack and the processor jumps to another location in memory. When the interrupt routine is done, it returns to where it left off. Of course, since you don't explicitly call a interrupt handler, the processor obviously can't get the location to jump to in the normal matter. This is where the vector table comes in. The vector table is just a bunch of numbers at the very beginning of the 68K's memory space. It spans from address 0 to address 99h. Each entry contains an address of an exception handler. The section for interrupts starts at 64h with the address of the level 1 interrupt handler. 68h holds the handler for the level 2 interrupt handler and so on. On the Genesis the only interrupts used are 2, 4, and 6 with their entries in the vector table located at 68h, 70h, and 78h respectively.

There is another difference between bsr/jsr and exceptions and that is what's stored on the stack. bsr/jsr just store PC, but when an exception handler is called another piece of information is also stored on the stack and that's the processor flags. I'm not going to explain why this is important, but just keep in mind that it happens and that you have to use a different instruction to return from an exception handler than from a subroutine. That instruction is rte. It pops both the flags and the PC value of the stack when executed.

Well that raps up Part V. I don't think I did a terribly good job with it, so feel free to ask questions if something isn't clear. My first Sega CD tutorial should be done soon. It will cover the basics of how to use the assembler and how to get a simple SLO program up and running.

This post has been edited by Mask of Destiny: Oct 19 2003, 11:01 PM


--------------------
Do region conversions, dump cartridges, write Sega CD software. All this and more at http://www.retrodev.com/

Currently messing around with Mac OS X Cocoa development on my resurrected B&W G3.
Go to the top of the page
 
+Quote Post
Nemesis
post Oct 19 2003, 11:45 PM
Post #13


There's no such thing as 2

Group Icon

Group: CulT Family
Posts: 957
Joined: 20-August 03
From: Sydney, Australia
Member No.: 4
Gender: Male



Good work MoD. That clarified a few points I wasn't too clear on.


--------------------
Go to the top of the page
 
+Quote Post
Mask of Destiny
post Oct 20 2003, 10:19 PM
Post #14

Objective-C == suckage

Group Icon

Group: CulT Family
Posts: 968
Joined: 21-August 03
Member No.: 85
Gender: Male
Country: United States



These tutorials are now available at my website ( http://www.pages.drexel.edu/~mrp29/index.html ) in the Sega CD section. There are some minor formatting issues to deal with, but they should be usable.


--------------------
Do region conversions, dump cartridges, write Sega CD software. All this and more at http://www.retrodev.com/

Currently messing around with Mac OS X Cocoa development on my resurrected B&W G3.
Go to the top of the page
 
+Quote Post
Beta
post Oct 21 2003, 05:38 AM
Post #15


I'm Baaaaaaaaaaack

Group Icon

Group: Admin
Posts: 2,972
Joined: 18-August 03
From: San Diego, CA
Member No.: 2
Gender: Male
Country: United States



>> QUOTE(Mask of Destiny @ Oct 20 2003, 08:19 PM)
>> 
These tutorials are now available at my website ( http://www.pages.drexel.edu/~mrp29/index.html ) in the Sega CD section.  There are some minor formatting issues to deal with, but they should be usable.

BTW, Mod, I can make a Win32 GUI interface for that BuildSCD program of yours. Recent times have had me without much to do. So I guess I'm reaching, I guess.

Just need to get my hands on the code.


--------------------
YOUR NAME LOOKS LIKE SPANDEX
Go to the top of the page
 
+Quote Post
Nemesis
post Oct 21 2003, 06:02 AM
Post #16


There's no such thing as 2

Group Icon

Group: CulT Family
Posts: 957
Joined: 20-August 03
From: Sydney, Australia
Member No.: 4
Gender: Male



The source was on the site wasn't it? I seem to remember looking through it, or was that something else? I can't remember.


--------------------
Go to the top of the page
 
+Quote Post
Beta
post Oct 21 2003, 06:10 AM
Post #17


I'm Baaaaaaaaaaack

Group Icon

Group: Admin
Posts: 2,972
Joined: 18-August 03
From: San Diego, CA
Member No.: 2
Gender: Male
Country: United States



>> QUOTE(Nemesis @ Oct 21 2003, 04:02 AM)
>> 
The source was on the site wasn't it? I seem to remember looking through it, or was that something else? I can't remember.

I didn't see it, I guess I'll have another look aorund.

Edit: Not seeing it. o.o Could just be tired and missing it...

This post has been edited by Beta: Oct 21 2003, 06:49 AM


--------------------
YOUR NAME LOOKS LIKE SPANDEX
Go to the top of the page
 
+Quote Post
Mask of Destiny
post Oct 21 2003, 07:54 AM
Post #18

Objective-C == suckage

Group Icon

Group: CulT Family
Posts: 968
Joined: 21-August 03
Member No.: 85
Gender: Male
Country: United States



I never bothered putting up the source for buildscd, but there's no reason I can't. I was thinking about working on some kind of IDE that would handle building the ISO and running snasm68k for you, but who knows when I'll get to that.

I'll put the code up sometime this week. Hopefully, it's not too much of a mess.


--------------------
Do region conversions, dump cartridges, write Sega CD software. All this and more at http://www.retrodev.com/

Currently messing around with Mac OS X Cocoa development on my resurrected B&W G3.
Go to the top of the page
 
+Quote Post
Jimi Hendrix
post Dec 17 2004, 10:32 PM
Post #19


Group Icon

Group: CulT Member
Posts: 55
Joined: 20-October 03
Member No.: 805
Gender: Male



Is this for all 68k processors or specifically geared towards the MegaDrive? In other words, can TI-89 users use this to make some shiznat?
Go to the top of the page
 
+Quote Post
drx
post Dec 18 2004, 09:09 AM
Post #20


whoa... i'm drunkz0r... o_O...

Group Icon

Group: CulT Family
Posts: 913
Joined: 28-August 03
From: :P
Member No.: 460
Gender: Male
Country: Poland



this should work for 68k...


--------------------


Hacking CulT


Go there now or I'll cut your dick off.
emails:
spam@the-drx.org

thedrx@gmail.com
drx@hacking-cult.org
drx@bluehedgehog.org
drx@shadowsoft-games.com
and the list goes on...

cool people list:
16-Bit Terror, Alpha, AJ 187, Beta, Buddha, Cedar J, choel aka jesus, dcom aka Prince of Persia aka cube aka Superdeluxe aka whatever, dirtster aka raggak, djbrayster, dude2003, Fiz, grap3fruitman, Gunner112k, Hivebrain, InsaneSonikkuFan, JohnnyUK, Nemesis, Nik, NGC, Overlord, Rika Chou, Sonic Hackr 2000, STC-Fan, Stoko, Tweaker, Ultima=P

contact:
aim: drx1337
icq: 202333696

Go to the top of the page
 
+Quote Post

1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:
3 Pages V   1 2 3 >
Start new topic

 

Lo-Fi Version Time is now: 28th June 2017 - 10:55 PM