Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset 8 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 722

Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset 8 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 722

Warning: preg_match_all(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 700

Warning: Invalid argument supplied for foreach() in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 701

Warning: preg_replace(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 705

Warning: preg_match_all(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 700

Warning: Invalid argument supplied for foreach() in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 701

Warning: preg_replace(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 705

Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset 8 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 722

Warning: preg_match_all(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 700

Warning: Invalid argument supplied for foreach() in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 701

Warning: preg_replace(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 705

Warning: preg_match_all(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 700

Warning: Invalid argument supplied for foreach() in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 701

Warning: preg_replace(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 705

Warning: preg_match_all(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 700

Warning: Invalid argument supplied for foreach() in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 701

Warning: preg_replace(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 705

Warning: preg_match_all(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 700

Warning: Invalid argument supplied for foreach() in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 701

Warning: preg_replace(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 705

Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset 8 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 722

Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset 8 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 722

Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset 8 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 722

Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset 8 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 722

Warning: preg_match_all(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 700

Warning: Invalid argument supplied for foreach() in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 701

Warning: preg_replace(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 705

Warning: preg_match_all(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 700

Warning: Invalid argument supplied for foreach() in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 701

Warning: preg_replace(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 705

Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset 8 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 722

Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset 8 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 722
Introducing the Instruction Set Part 3 - Intellivision Wiki

Introducing the Instruction Set Part 3


Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset 8 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 722
From Intellivision Wiki

Jump to: navigation, search
(Why do we need branches?)
 
Line 46: Line 46:
That runs very fast, but it takes up a ton of ROM.  Also, it clears the screen only once.  What if you want to clear the screen many times throughout your program, perhaps from different places?  You really don't want to copy this same code everywhere you need to clear the screen.  That's where branches come in.<BR/><BR/>
That runs very fast, but it takes up a ton of ROM.  Also, it clears the screen only once.  What if you want to clear the screen many times throughout your program, perhaps from different places?  You really don't want to copy this same code everywhere you need to clear the screen.  That's where branches come in.<BR/><BR/>
-
Branches tell the CPU to start executing at a different location, rather than barreling forward.  Unconditional branches and jumps tell the CPU to always jump to that location.  Conditional branches tell the CPU to jump to a new location <I>if some condition is true.</I>  These let you skip pieces of code, or repeat them a number of times.  Jumps to subroutine tell the CPU "go do this and come back when you're done."  The following sections explore these concepts a little more closely.<BR/><BR/>
+
Branches tell the CPU to start executing at a different location, rather than barreling forward.  Unconditional branches and jumps tell the CPU to always jump to that location.  Conditional branches tell the CPU to jump to a new location <I>if some condition is true.</I>  These let you skip pieces of code, or repeat them a number of times.  Jumps to subroutines (also known as "calls") tell the CPU "go do this and come back when you're done."  The following sections explore these concepts a little more closely.<BR/><BR/>
= Branches and Labels =
= Branches and Labels =
Line 166: Line 166:
</TABLE>
</TABLE>
<BR/>
<BR/>
-
The unsigned comparisons require some additional explanation to be useful.  After comparing two unsigned numbers, the [[BC]] instruction will branch if the second number is greater than or equal to the first.  The [[BC]] instruction will branch if the second number is smaller than the first.  The CP1610 does not offer unsigned equivalents for "branch if greater than" or "branch if less than or equal."  You can get similar effects, though, by combining [[BC]] and [[BNC]] with [[BEQ]] or [[BNEQ]] to separate out the "equals", "greater-than" and "less-than" cases.
+
The unsigned comparisons require some additional explanation to be useful.  After comparing two unsigned numbers, the [[BC]] instruction will branch if the second number is greater than or equal to the first.  The [[BNC]] instruction will branch if the second number is smaller than the first.  The CP1610 does not offer unsigned equivalents for "branch if greater than" or "branch if less than or equal."  You can get similar effects, though, by combining [[BC]] and [[BNC]] with [[BEQ]] or [[BNEQ]] to separate out the "equals", "greater-than" and "less-than" cases.
=== How Unsigned Arithmetic Works With Conditional Branches ===
=== How Unsigned Arithmetic Works With Conditional Branches ===
Line 204: Line 204:
[[Image:If_then.png|center|Block diagram of an if-then statement]]
[[Image:If_then.png|center|Block diagram of an if-then statement]]
-
In this example, the CPU runs the green portion only if R1 is less than R2, as indicated in the blue square.  The other bits of code always run.  The following diagram shows how this looks as assembly language code:
+
In this example, the CPU runs the green portion only if R1 is less than R2, as indicated in the blue square.  The other bits of code always run.  The diagram shows how this looks as assembly language code:
[[Image:If_then_code.png|center|Code example for an if-then statement]]
[[Image:If_then_code.png|center|Code example for an if-then statement]]
Line 475: Line 475:
         ENDP
         ENDP
-
(Note:  For a more compact way of writing <CODE>CLRSCR</CODE> and <CODE>FILLMEM</CODE>, take a look at the [http://sdk-1600.spatula-city.org/examples/library/fillmem.asm optimized implementation in SDK-1600].)
+
(Note:  For a more compact way of writing <CODE>CLRSCR</CODE> and <CODE>FILLMEM</CODE>, take a look at the [[fillmem.asm|optimized implementation in SDK-1600]].)
-
 
+
-
 
+
== Passing Arguments via Return Address ==
== Passing Arguments via Return Address ==
Line 485: Line 483:
Fortunately, the CP1610 makes it easy to pass static arguments as just plain data, without needing a block of <CODE>[[MVII]]</CODE> instructions before each call.  If a particular function is going to get called regularly with certain arguments fixed at the call site as in the example above, then it makes sense to pass arguments via the return address.
Fortunately, the CP1610 makes it easy to pass static arguments as just plain data, without needing a block of <CODE>[[MVII]]</CODE> instructions before each call.  If a particular function is going to get called regularly with certain arguments fixed at the call site as in the example above, then it makes sense to pass arguments via the return address.
<BR/><BR/>
<BR/><BR/>
-
This relies on the fact that <CODE>[[CALL]]</CODE> sets R5 to point to the word just after the <CODE>[[CALL]]</CODE> instruction.  If you put data here, then <CODE>[[MVI@]] R5</CODE> will read that data.  The [http://sdk-1600.spatula-city.org/examples/library/print.asm SDK-1600 PRINT function] uses this technique to great effect.
+
This relies on the fact that <CODE>[[CALL]]</CODE> sets R5 to point to the word just after the <CODE>[[CALL]]</CODE> instruction.  If you put data here, then <CODE>[[MVI@]] R5</CODE> will read that data.  The [[print.asm|SDK-1600 PRINT function]] uses this technique to great effect.
<BR/><BR/>
<BR/><BR/>
The following example shows a different version of <CODE>FILLMEM</CODE> and <CODE>CLRSCR</CODE> that mimic the [[Introducing_the_Instruction_Set_Part_3#Passing_Arguments_to_Functions|example above]].  The difference is that this code passes arguments as data following the <CODE>[[CALL]]</CODE> instruction.
The following example shows a different version of <CODE>FILLMEM</CODE> and <CODE>CLRSCR</CODE> that mimic the [[Introducing_the_Instruction_Set_Part_3#Passing_Arguments_to_Functions|example above]].  The difference is that this code passes arguments as data following the <CODE>[[CALL]]</CODE> instruction.
Line 530: Line 528:
As you can see, this technique provides a great deal of flexibility in how things are called.
As you can see, this technique provides a great deal of flexibility in how things are called.
-
 
-
 
== Call Chaining:  Having One Function Return for Another ==
== Call Chaining:  Having One Function Return for Another ==
Line 581: Line 577:
= Indirect Branches and Jump Tables =
= Indirect Branches and Jump Tables =
-
<BLOCKQUOTE>"It was a 'Jump to Conclusions' mat. You see, it would be this mat that you would put on the floor... and would have different <B>conclusions</B> written on it that you could <B>jump to.</B>" -- Tom Smykowski, Office Space</BLOCKQUOTE>
+
<BLOCKQUOTE><I>"It was a 'Jump to Conclusions' mat. You see, it would be this mat that you would put on the floor... and would have different <B>conclusions</B> written on it that you could <B>jump to.</B>"</I> -- Tom Smykowski, Office Space</BLOCKQUOTE>
Indirect branches are branches whose destination isn't encoded into the instruction itself.  You've seen a special version of this above:  The <CODE>[[JR]] R5</CODE> and <CODE>[[PULR]] PC</CODE> sequences for returning from function calls are both forms of indirect branches.
Indirect branches are branches whose destination isn't encoded into the instruction itself.  You've seen a special version of this above:  The <CODE>[[JR]] R5</CODE> and <CODE>[[PULR]] PC</CODE> sequences for returning from function calls are both forms of indirect branches.
Line 680: Line 676:
         [[SLL]]    R0, 1
         [[SLL]]    R0, 1
-
The "MAGIC_BRANCH" is really just a sequence that adds a register to the program counter based on how many instructions we intend to skip.  Suppose R1 held the shift amount.  The fol
+
The "MAGIC_BRANCH" is really just a sequence that adds a register to the program counter based on how many instructions we intend to skip.  Suppose R1 held the shift amount.  The following example show how to use that to skip some number of SLL instructions based on that:
         [[NEGR]]    R1        ; \_ Subtract R1 from 4 so it's now 3..0
         [[NEGR]]    R1        ; \_ Subtract R1 from 4 so it's now 3..0
Line 714: Line 710:
The example also shows a minor optimization:  The highest numbered case can always be put right at the end of the list of branches, rather than having a branch to it there.
The example also shows a minor optimization:  The highest numbered case can always be put right at the end of the list of branches, rather than having a branch to it there.
-
 
-
 
== Clever (or Silly) Branch Tricks ==
== Clever (or Silly) Branch Tricks ==

Latest revision as of 04:57, 18 November 2011

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox