 Also available at MoD&#39;s site - <a href='http://www.retrodev.com/' target='_blank'>http://www.retrodev.com/</a><br><br><!--QuoteBegin--></div><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>QUOTE</b> </td></tr><tr><td id='QUOTE'><!--QuoteEBegin-->I originally started posting this at Area51 because they added a 68K/Hex forum. It sort of inspired me to start writing it. I&#39;m going to continue to post it at Area51, but I&#39;d like it to be mirrored elsewhere since this tutorial is for the whole community not just part of it. I&#39;m going to do this for the 1st two parts, but I&#39;d prefer if someone else would do it for the rest of them. Anyway, here you go:<br><br><span style='font-size:14pt;line-height:100%'>Part I: Data, Instructions, and Memory</span><br><br>Everything the processor can access is in memory.&nbsp; Memory is just a bunch of sequential locations.&nbsp; These locations can be RAM or ROM or even a piece of hardware.&nbsp; Each location is a byte wide and each location has a number or address associated with it.&nbsp; On the 68K the first address is 0 and the last is &#036;FFFFFF giving it access to 16MB of data.<br><br>A location in memory can store data.&nbsp; Data is just a number.&nbsp; Technically this number is stored in binary, but binary is inconvenient to work with so usually hex is used instead.&nbsp; Any kind of data whether it be text, graphics or a web page is made up of numbers.<br><br>Instructions are a special kind of data.&nbsp; They are still numbers, but they serve a special purpose.&nbsp; They tell the processor what to do.&nbsp; Instructions are executed in order until a special kind of instruction is executed that tells the processor to start executing instructions somewhere else.<br><br>These numbers can be hard to remember, especially since there are a lot of them.&nbsp; To make things easier for programmers assembly language was invented.&nbsp; Assembly replaces numbers with easier to remember mnemonics so instead of having to remember &#036;4E75 I can remember RTS instead.&nbsp; Don&#39;t worry about what this instruction does yet.&nbsp; We&#39;ll get to it later.<br><br><span style='font-size:14pt;line-height:100%'>Part II: Registers and Addressing Modes</span><br><br>All processors have a special kind of RAM called registers.&nbsp; Like RAM, registers store data.&nbsp; They are much faster than normal RAM, but you can store a lot less data in you registers than your RAM.&nbsp; 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.&nbsp; The 68K has 16 registers named d0-d7 and a0-a7.&nbsp; The first 8 are data registers.&nbsp; Most of your number crunching will be done in these.&nbsp; The last 8 are address registers.&nbsp; As you might have guessed these store addresses.&nbsp; All these registers are 32-bits (4 bytes) wide.<br><br>Before I introduce you to the addressing modes on the 68K, I want to teach you an instruction, namely move.&nbsp; As its name suggests, move is used to move a piece of data from one location to another.&nbsp; It has the following form:<br><br>move.&lt;size&gt;&nbsp;  &lt;source&gt;, &lt;destination&gt;<br><br>Size, can be either b (byte), w (word, 2bytes), or l (longword, 4 bytes).&nbsp; As an example, <br><br>move.w&nbsp;  d0, d1<br><br>would move 1 word (2 bytes) of data from register d0 to register d1<br><br><br>Now it&#39;s time to get acquainted with the addressing modes on the 68K.&nbsp; &quot;What is an addressing mode?&quot;, you ask.&nbsp; Simply put, an addressing mode is a kind of thing you can put in either the &lt;source&gt; or &lt;destination&gt; field in that move instruction I introduced you to earlier.&nbsp; I&#39;m not going to introduce every single addressing mode (or at least not all the details of every one).&nbsp; You can look in the 68K Programmers Guide for that.<br><br>Keep in mind that while the 68K uses 32-bit addresses, it only has a 24-bit address space.&nbsp; The upper 8 bits are ignored so &#036;FF0000 is equivalent to &#036;FFFF0000.<br><br>Register Addressing:<br><br>The source or destination is a processor register. <br>Example:<br>move.w&nbsp;  d0, d1<br>Equivalent:<br>d1 = d0<br><br>Immediate Addressing:<br><br>The source is a constant value that becomes part of the instruction.&nbsp; This is useful if you want to set a register or memory location to a specific value, but you don&#39;t need to do any calculations based on it ahead of time.&nbsp; It also is very useful in simple mathematics calculations.&nbsp; Oftentimes you&#39;ll find that you need to add or subtract 1 to a register.&nbsp; Rather than eating up another register you can use immediate addressing.&nbsp; Keep in mind that all immediate values must be prefixed by a #.<br><br>Example:<br>move.w&nbsp; #1, d0<br>Equivalent:<br>d0 = 1<br><br>Absolute Addressing:<br><br>Here the source or destination is a location in memory.&nbsp; You give the address of the location you want to use.<br><br>Examples:<br>move.l&nbsp; &#036;100, d0 (move a longword from memory location &#036;100 to register d0)<br>move.b&nbsp; #1, &#036;FF0000 (store the number 1 at memory location &#036;FF0000)<br><br>On a Genesis, the first example would move a longword from the header of the cartridge.&nbsp; That location should contain the ASCII values for the string &#39;SEGA&#39;.<br>The second example would store the number 1 in the first byte of Work RAM.<br><br>Absolute Near Addressing:<br><br>Before I explain this mode I have to tell you a little about sign extension.&nbsp; Sign extension is a way of putting a smaller value in a place where a longer value belongs.&nbsp; What happens is that the highest bit of the smaller value is copied into all the extra values in the larger number.&nbsp; So when &#036;8000 is sign extended from a word value to a longword value it becomes &#036;FFFF8000, but when &#036;7FFF is sign extend it it becomes &#036;00007FFF or &#036;7FFF.&nbsp; If you don&#39;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 &#39;F&#39;s.&nbsp; If the highest hext digit is less than 8 then the extra digits will be filled with 0s.&nbsp; Note that when I say the highest digit, I mean the highest digit in the data width.&nbsp; &#036;80 as&nbsp; a word value has a highest digit of 0.<br><br>Absoute near addressing is similar to absolute addressing except that instead of using a longword for the address a word is used.&nbsp; This word is sign-extended giving you access to the first and last 32K of the memory space (&#036;0 - &#036;7FFF and &#036;FF8000 - &#036;FFFFFF).<br>Example:<br>move.w&nbsp;  #1, &#036;8000.w<br>Equivalent:<br>Memory Location &#036;FF8000 = 1<br><br>Pointer Addressing:<br><br>You remember those address registers? Now you get to use them.&nbsp; Let&#39;s say you want to access the same location in memory over and over again.&nbsp; You could include the address as part of the instruction every time using the absolute addressing mode, but that&#39;s kind of slow and innefficient.&nbsp; Instead, you can put the address in an address register and use that to reference the memory location.&nbsp; If you want to use or affect the value stored in the address register, just use the name of the register by itself.&nbsp; If you want to use or affect the memory location pointed to by the adress register, enclose the name of the register in parenthesis.<br><br>Examples:<br>move.l&nbsp; #&#036;FF0000, a0&nbsp; &nbsp; ;Store the address &#036;FF0000 in a0<br>move.w #1, (a0)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  ;Store the number 1 at the memory location pointed to by a0 (&#036;FF0000)<br><br>Pointer Relative Addressing:<br><br>Let&#39;s say you&#39;ve got two values stored in RAM pretty close together, but you don&#39;t want to use two address registers and you don&#39;t want to use absolute addressing.&nbsp; You can point an address register at the first, and then use that address register along with an offset to access the second.&nbsp; An offset is a number from -&#036;8000 to &#036;7FFF that is added to the register to calculate the address that is used.&nbsp; Note, this addition is not permanent.&nbsp; It doesn&#39;t effect the value stored in the address register.<br><br>Example:<br>move.l&nbsp; #&#036;FF0000, a0&nbsp;  ;Store address &#036;FF0000 in a0<br>move.w #1, (a0)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ;store the number 1 at memory location &#036;FF0000<br>move.w&nbsp; #1, 2(a0)&nbsp; &nbsp; &nbsp;  ;store the number 1 at memory location &#036;FF0002<br><br>PC Relative Addressing:<br><br>The program counter (PC) is a special address register that points to the current instruction.&nbsp; Although you can&#39;t treat it like an address register in most respects, you can use it for relative addressing in the same&nbsp; way that you use it with an address register.&nbsp; This will be more useful once we get to labels.<br><br>Example:<br>move.w&nbsp; &nbsp; #1, &#036;100(pc)&nbsp; &nbsp; &nbsp; ;stores the value 1 at the memory location &#036;100 bytes from the current instruction.<br><br>Pointer Addressing with Predecrement/Postincrement:<br><br>Let&#39;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.<br><br>Examples:<br>move.l #&#036;FF0000, a0 ;store address &#036;FF0000 in a0<br>move.b #7, (a0)+ ;store 7 at &#036;FF0000 and add 1 to a0, a0 now equals &#036;FF0001<br>move.b #4, (a0)+ :store 4 at &#036;FF0001 and add 1 to a0<br>move.w #3, (a0)+ ;store 3 at &#036;FF0002 and add 2 to a0<br>move.l #9, (a0)+ ;store 9 at &#036;FF0004<br>;a0 is now equal to &#036;FF0008<br>move.w #6, -(a0) ;store 7 at &#036;FF0006<br><br><br>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&#39;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&#39;ll do my best to explain it better.<br><br><span style='font-size:14pt;line-height:100%'>Part III: Addition, Subtraction, and Two&#39;s Complement </span><br><br>You may have wondered how on earth a computer stores negative numbers if all it understands is 1s and 0s (okay you probably weren&#39;t wondering this, but I&#39;m covering it anyway).&nbsp; One solution might be to use the highest bit to represent the sign of the number.&nbsp; If this bit is set then the number is negative, if it&#39;s not set the number is positive.&nbsp; While that statement is correct, it doesn&#39;t represent the whole truth, but before I explain the rest of it you need to understand something else first.<br><br>What happens when you add a 1 to 9 (decimal)?&nbsp; You run out of room in the current digit, so you do a carry into the next digit making the result 10.&nbsp; The same thing happens when you add 1 to &#036;FF (hex).&nbsp; 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 &#036;100, but what happens if the variable you are storing the result in is only a byte wide?&nbsp; The upper digit is lost and you are left with &#036;0.&nbsp; <br><br>So in byte arithematic, &#036;FF + 1 = 0.&nbsp; What other value when added to 1 gives us 0?&nbsp; x + 1 = 0&nbsp; With some simple algebra we find that -1 is the answer.&nbsp; It turns out that the nature of fixed width arithematic gives us an easy way to make negative numbers.&nbsp; Let me give you another example to make it clearer.&nbsp; What is the result when you subtract &#036;2 from &#036;100?&nbsp; You get &#036;FE.&nbsp; Now if this was byte wide math, then that 1 wouldn&#39;t be there and you would borrow from a digit that doesn&#39;t exist so &#036;0 - &#036;2 = &#036;FE or -2.&nbsp; Hopefully you are beginning to see a patern here.&nbsp; When you count backwards from 0 on a computer, the numbers loop around so -1 = &#036;FF, -2 = &#036;FE, -3 = &#036;FD, etc..&nbsp; Keep in mind that with a larger datawidth these values change.&nbsp; For a word, -1&nbsp; = &#036;FFFF, -2 = &#036;FFFE and so on.<br><br>That is why offsets were sign-extended in the last&nbsp; tutorial section.&nbsp; If they weren&#39;t negative offsets would become positive when they were stretched to fit a longword wide address.&nbsp; &#036;FFFF is a positive number if it&#39;s a longword, but if you copy the highest bit into the extra bits in the longword, it becomes negative again, &#036;FFFFFFFF.<br><br>Okay, enough of the theory behind how the computer works.&nbsp; It&#39;s time for some actual processor instructions.<br><br>add.&lt;size&gt;&nbsp; &nbsp; &lt;source&gt;, &lt;destination&gt;<br><br>You&#39;ll notice that the syntax for add looks just like the syntax for move.&nbsp; 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&#39;t know the exact function of the instruction.&nbsp; You&#39;ll always know what the source and destination are.&nbsp;  It also means you can use all those fancy addressing modes for most instructions.<br><br>Examples:<br>add.w&nbsp; &nbsp;  #2, d0<br>add.l&nbsp; &nbsp; &nbsp;  d1, d0<br>Equivalents:<br>d0 = d0 + 2<br>d0 = d0 + d1<br><br>Those of you familiar with C can think of this as the += operator.&nbsp; If you don&#39;t know C, don&#39;t worry about that comparison.&nbsp; Just look at the Equivalents.<br><br>sub.&lt;size&gt;&nbsp; &nbsp; &lt;source&gt;, &lt;destination&gt;<br><br>Pretty much the same idea here, but be careful.&nbsp; With subtraction it matters what order the operands come in so you have to remember which operand this instruction subtracts from which.&nbsp; It works like this:&nbsp; &lt;destination&gt; = &lt;destination&gt; - &lt;source&gt;.<br><br>Examples:<br>sub.b&nbsp; &nbsp; #3, d4<br>sub.w&nbsp; &nbsp;  d0, d1<br>Equivalents:<br>d4 = d4 - 3<br>d1 = d1 - d0<br><br>That&#39;s it for part III, have fun.<br><br><span style='font-size:14pt;line-height:100%'>Part IV: Branches, Conditions and Labels</span><br><br>So far you can add, subtract, and shove data around.&nbsp; In and of itself this isn&#39;t too useful. The program will always do the exact same thing and has no real way to make decisions based on input.&nbsp; With this lesson that will change.<br><br>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&#39;t be changed directly.&nbsp; Today, I&#39;m going to show you two instructions that can change PC, jmp and bra.<br><br>The jmp instruction replaces the value in PC with another address.&nbsp; This can be accomplished using any of the addressing modes except for ordinary PC relative addressing and register direct addressing.&nbsp; <br><br>Examples:<br>jmp	&#036;FF0000&nbsp; ;this would cause a jump to memory address&#036;FF0000<br><br>jmp	&#036;F000.w&nbsp; ;this would cause a jump to memory address &#036;FFF000<br><br>movea.l #&#036;300, a0<br>jmp	(a0)&nbsp; ;this would cause a jump to memory address &#036;300<br><br>move.w	#&#036;40, d0<br>jmp	&#036;4(d0, PC)	;this would cause a jump to &#036;44 bytes past the current PC<br><br>The bra instruction is similar to jmp, except that it only works with simple PC relative addressing.<br><br>Examples:<br>bra	#&#036;100&nbsp; ;branches to &#036;100 bytes past the current pc<br>bra	#&#036;6.b&nbsp; ;brances to &#036;6 bytes past the current pc<br><br>Having to calculate memory addresses and offsets are a real pain so assembler authors came up with a simple way around all this nonsense.&nbsp; They&#39;re called labels. A label is simply an alphanumeric string without any spaces.&nbsp; It must start with a letter.&nbsp; To define a label simply type it in at the first position on a line and add a colon.&nbsp; Once you&#39;ve defined a label, you can treat it like a normal address.&nbsp; Also note, that instructions need to have whitespace in front of them, unlike what I&#39;ve done so far in the tutorial<br><br>Example:<br>Mylabel:<br>	bra	Mylabel&nbsp; ;this would stick the processor in a never ending loop<br><br>Don&#39;t do this:<br>Mylabel:<br>bra	Mylabel<br><br>Now you know how to make programs that don&#39;t just go in a straight line, but there is something that makes this even more useful, flags and conditions.&nbsp; The flags are just a bunch of bits in a special register called the Condition Code Register or CCR for short.&nbsp; These bits are effected by most instructions.&nbsp; For this section of the tutorial I&#39;m only going to introduce you to one flag, the zero flag.&nbsp; 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.<br><br>Examples of when the zero flag is set:<br>move.w	#0, d0<br><br>move.w	#1, d0<br>sub.w	#1, d0<br><br>move.b	#&#036;FF, d0<br>add.b	#1, d0<br><br>Examples of when the zero flag is not set:<br>move.w	#1, d0<br><br>move.w	#3, d0<br>sub.w	#1, d0<br><br>move.b	#&#036;FF, d0<br>add.b	#&#036;2, d0<br><br>Well that&#39;s all well and good, but how do we use these flags once they&#39;ve been set?&nbsp; Simple, with branch instructions.&nbsp; Remember bra?&nbsp; That stands for BRanch Always.&nbsp; There are a number of variations on bra that only branch when certain flags are set.&nbsp; I&#39;m going to introduce you to two right now, beq and bne.<br><br>beq stands for Branch if EQual. What this really means is that the processor will take the branch if the zero flag is set.&nbsp; If not, then execution continues as normal.&nbsp; You may be wondering where the EQual part comes from.&nbsp; It makes sense in subtraction and compare(we haven&#39;t touched on compare yet) operations.&nbsp; If both values are equal and you perform one of these operations, then the result will be zero, thus the name of the instruction.<br><br>Example of branch getting taken:<br>	move.w	#1, d0<br>	sub.w	#1, d0&nbsp; ;1-1 = 0, zero flag set to 1 (true)<br>	beq	Skip:&nbsp; ;zero flag is set so the branch is taken<br><br>	move.w	#5, d0&nbsp; ;this instruction is skipped<br><br>Skip:&nbsp; &nbsp; ;executiong jumps to here<br>	addq	#3, d0&nbsp; ;d0 now equals 3<br><br>Example of branch not getting taken:<br>	move.w	#2, d0<br>	sub.w	#1, d0&nbsp; ;2-1 = 1, zero flag set to 0 (false)<br>	beq	Skip:&nbsp; ;branch is not taken<br><br>	move.w	#5, d0&nbsp; ;this instruction is executed<br><br>Skip:<br>	addq	#3, d0&nbsp; ;d0 now equals 8<br><br>bne stands for Branch if Not Equal.&nbsp; It&#39;s the exact opposite of beq.&nbsp; If the zero flag is zero (false) than the branch is taken otherwise execution continues as normal.&nbsp; I won&#39;t do an example, since it should be easy enough to figure out given the examples for beq.<br><br><br>Once again, if you don&#39;t undertand anything in this part or any of the previous parts feel free to ask questions.&nbsp; I don&#39;t mind answering even the most basic of questions on assembly.<br><br><span style='font-size:14pt;line-height:100%'>Part V: Subroutines, Exceptions and the Stack</span><br><br>Once your done with this one, you&#39;ll have all the basics of 68k assembly.&nbsp; There&#39;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.&nbsp; I will be writing some Sega CD programming tutorials soon so you can get some real world experience.&nbsp; Now, on to the stack.<br><br> A stack is a data structure, that means that it&#39;s made of a bunch of different values in RAM instead of just one like a byte or word variable.&nbsp; It&#39;s very appropriately named since it can be easily likened to a stack of books.&nbsp; With books, you can take one off the top of the stack, and you can put one back on, but you can&#39;t easily take a book out from the middle.&nbsp; A stack in the 68K works in much the same way.&nbsp; You can put a pice of data on top of the stack and you can get the piece of data that&#39;s on the top of the stack, but getting data from the middle of the stack is a bit trickier.<br><br>Typically, a stack occupies a number of sequential address in RAM, and on the 68K most stacks build down.&nbsp; 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.&nbsp; So for example if the top address in the stack is &#036;FFFFFE, and that location stores a word, if you were to put another value on the stack, it would be stored at &#036;FFFFC.&nbsp; The next at &#036;FFFFFA, and so on.&nbsp; If you put the numbers 1, 2, and 3 on the stack in that order, it would look like this:<br><br>&#036;FFFFFE: 1<br>&#036;FFFFFC: 2<br>&#036;FFFFFA: 3<br><br>If you were to then pull the numbers back off the stack, you&#39;d get 3, 2 and 1 in that order.&nbsp; 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.&nbsp; This reveals one of the most basic uses of a stack, to reverse the order of a set of values.&nbsp; However, this is not The most useful task a stack can accomplish.&nbsp; Another use is found in subroutines.<br><br>Subroutines are like small programs that can be called again and again by the main program (or by other subroutines).&nbsp; They&#39;re incredibly useful because they allow you to write the code for a certain task once,and then call it whenver you need it.&nbsp; 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.<br><br>Subroutines work in a similar manner to branches.&nbsp; There are two mnemonics used to call subroutines, bsr and jsr.&nbsp; Like bra, bsr can only use PC relative addressing and like jmp, jsr can use just about any mode except relative addressing.&nbsp; So the following would all be valid, assuming that &quot;MySubRoutine&quot; was a valid label.<br><br>	bsr	MySubRoutine&nbsp; ;jump to the subroutine at MySubRoutine using relative addressing<br>	jsr	MySubRoutine&nbsp; ;do the same using absolute addressing<br>	lea	MySubRoutine(PC), a0<br>	jsr	(a0)&nbsp; 	;jump to subroutine using pointer<br><br>There is one distinct difference between bsr and jsr, and their branch counterparts.&nbsp; bsr and jsr save the current value of PC so you can easily return to the point you called the function from.&nbsp; This is done with the rts instruction.&nbsp; Here&#39;s an example.<br><br>	bsr	MySubRoutine&nbsp; ;branch to MySubRoutine<br>	moveq	#0, d0&nbsp; 	;execution resumes here as soon as the subroutine is done<br><br>MySubRoutine:<br>	moveq	#3, d1<br>	rts&nbsp; &nbsp; ;Go back to where the subroutine was called from<br><br>This allows you to use a subroutine multiple places within your program without having to duplicate the code.&nbsp; For instance, look at the following code:<br><br>	bsr	MySubRoutine<br>	...	;do stuff<br>	bsr	MySubRoutine<br>	...	;do more stuff<br>	bsr	MySubRoutine<br><br>This would cause the subroutine to be executed three times with some extra stuff in the middle.&nbsp; You may be wondering what this has to do with stacks.&nbsp; PC is saved onto something called the system stack.&nbsp; You may remember that register a7 is a special address register.&nbsp; It&#39;s the &quot;system stack pointer.&quot;&nbsp;  The system stack, is a stack like the one I described above.&nbsp; What makes it special is that it&#39;s used to store the contents of PC when a subroutine call is made.&nbsp; So when such a call is made, the following happens:<br><br>	a7 is decremented by 4 to make room on the stack, so if a7 was equal to FFFF04 it would then equal FFFF00<br>	PC is put into the memory location pointed to by a7, so in our example PC would be stored at FFFF00<br>	jump to the subroutine<br>	<br>And when the corresponding rts is executed the following happens:<br>	<br>	PC is read from the memory location pointed to by a7, in our example this location is FFFF00<br>	a7 is incremented so it points to it&#39;s old location<br>	processor jumps to the original location<br><br>Now for exceptions.&nbsp; Exceptions on the 68K occur for a variety of reasons.&nbsp; There&#39;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.&nbsp; The latter is incredibly useful for integrating with hardware.&nbsp; Without interrupts, you have to keep reading from a piece of hardware waiting for an event to happen.&nbsp; The time used for this could have been used for some other processing task, but instead you&#39;re forced to waste your time waiting for the hardware.&nbsp; Interrupts allow the hardware to interrupt the processor from what it&#39;s doing so it can handle hardware access.<br><br>This works in a similar way to subroutine calls, PC is pushed onto the stack and the processor jumps to another location in memory.&nbsp; When the interrupt routine is done, it returns to where it left off.&nbsp; Of course, since you don&#39;t explicitly call a interrupt handler, the processor obviously can&#39;t get the location to jump to in the normal matter.&nbsp; This is where the vector table comes in.&nbsp; The vector table is just a bunch of numbers at the very beginning of the 68K&#39;s memory space.&nbsp; It spans from address 0 to address 99h.&nbsp; Each entry contains an address of an exception handler.&nbsp; The section for interrupts starts at 64h with the address of the level 1 interrupt handler.&nbsp; 68h holds the handler for the level 2 interrupt handler and so on.&nbsp; 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.<br><br>There is another difference between bsr/jsr and exceptions and that is what&#39;s stored on the stack.&nbsp; bsr/jsr just store PC, but when an exception handler is called another piece of information is also stored on the stack and that&#39;s the processor flags.&nbsp; I&#39;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.&nbsp; That instruction is rte.&nbsp; It pops both the flags and the PC value of the stack when executed.<br><br>Well that raps up Part V.&nbsp; I don&#39;t think I did a terribly good job with it, so feel free to ask questions if something isn&#39;t clear.&nbsp; My first Sega CD tutorial should be done soon.&nbsp; It will cover the basics of how to use the assembler and how to get a simple SLO program up and running.<br><!--QuoteEnd--></td></tr></table><div class='postcolor'><!--QuoteEEnd--><br><br> 