💾 Archived View for gemini.spam.works › mirrors › textfiles › apple › ml.part.v captured on 2020-10-31 at 20:27:00.

View Raw

More Information

-=-=-=-=-=-=-



This part is going to be about the     
arithmetic and logic unit of the 6502. 
The ALU is what does the addition and  
subtraction and bit operations.        
Presently, we will only cover the math,
leaving the bit operations for later.  

If you read the previous column, you   
will have noticed that the CMP         
'subtracts' two numbers. this          
subraction takes place in the ALU.     

To subtract two numbers, we use the SBC
command. In immediate addressing mode, 
the arguement is subtracted from the   
value currently held in accumulator,   
and the result is then put back into   
the accumulator. It is a fairly simple 
procdure, but this is not all there is 
to it. First of all, negative numbers  
are represented as $100+the number.    
Also, there is the carry flag to deal  
with. This flag was put into the       
formula so that calculations involving 
numbers greater than 255 (that is 1    
byte) could be simplified. Once the    
result of the A - arguement is fonud,  
then the oppisite (techniquely called  
the two's complement, see below) of the
carry (that is, if C=1, then use 0 and 
vice versa) is subtracted from the     
result. (The carry is a one bit flag   
and can only hold 0 or 1, so if it is  
set the wrong way, the answer will be  
off by one.) Since we want to use this 
command to produce right results, we   
must set C=1. This is done by an SEC.  
To subtract 2 numbers, the following   
routine should be used.

SEC
LDA #FIRST NUMBER
SBC #SECOND NUMBER

The SBC command also has absolute,     
indexed X and Y modes.

Adding.

Adding numbers is very similar to      
subtraction. The ADC (add with carry   
not analog to digital converter)       
command adds the value in the          
accumulator to the arguement plus what 
the carry flag is set to. To set the   
carry to 0, we use CLC. Here's the     
routine:

CLC
LDA #FIRST NUMBER
ADC #SECOND NUMBER

And your desired result is in the      
accumulator. As we said earlier, the   
way the carry functions allows us to   
add mutli-byte numbers easily. Suppose 
we have two 3-byte long numbers. We    
will represent these numbers by the    
following method. N1 will be used to   
denote the first number and N2 the     
second. B1 will be used to denote the  
left-most (MSB) of each number and B2  
B3 as the successive bytes. So the     
numbers are N1B1.N1B2.N1B3, and        
N2B1.N2B2.N2B3. We will add the LSB's  
first and then follow with the middle  
bytes and finally the MSB's. For the   
LSB's, we will set the carry to zero.  
This will give us the answer we want   
for the LSB of the result (RB3). After 
storing RB3 in it's proper place, we   
will then add N1B2 and N2B2 together,  
leaving the carry as it is. After an   
addition is made, the carry is set to  
0 if the result is less than 255, and  
set to 1 if it is greater than 255. The
result can range from 0 to 510, which  
can be represented in 9 bits, C+ the   
accumultor. Now if the result is       
greater than 255 for the LSB's, we want
to add one to the next result of the   
middle bytes. This is automaticly done 
by the carry. So, here is the routine:


CLC
LDA #N1B3
ADC #N2B3
STA (THE ADDRESS OF) RB3
LDA #N1B2
ADC #N2B2
STA (THE ADDRESS OF) RB2
LDA #N1B1
ADC #N2B1
STA (THE ADDRESS OF) RB1
RTS

The result is C.RB1.RB2.RB3. The reason
why the carry is at the top is because 
if you add $FFFFFF and $FFFFFF you get 
$1FFFFFE. The one is the carry. It is  
advisable to set up 'registers' in RAM 
so that a generalized addition routine 
can be utilized. What it means is that 
you've set aside nine byte (say $300 to
$308) to be three 3-byte registers. One
from $300-$302, which would be where N1
would be stored, another from $303-$305
, resting place for N2, and the last   
from $306-$308, for the result (R). You
would have to figure out something with
the carry though. To help you with this
there are two branch commands BCC and  
BCS which branch on carry clear (C=0)  
and carry set (C=1), respectively.

Another possibility is to make an      
indexed addition routine using the X   
register as a counter. Though I won't  
give the code here, by examining the   
code given in the previous column and  
the addition routine, it can be worked 
out quite simply.

To subtract multi-byte numbers, we can 
use the same routine as above, except  
replacing the CLC with a SEC and the   
ADC's with SBC's. This works, though   
the result would now be RB1.RB2.RB3    
with the carry telling you whether the 
result is negative or positive. If C=1 
then the result is positive and vice   
versa. However, if the result is       
negative, the number is represented as 
$1000000+result.

Next time round: assemblers, monitor,  
and other fun stuff.



Oh yeah, since you asked, 2's          
complement is gotten by taking the next
highest power of 2, and subtracting one
form it. Then, subtract your number    
from that result and voila. For example
the next highest power of 2 after 1, is
2. Minus one is one and then 1-1=0.

The negative numbers sort of work on   
the same principle, except, the one is 
not subtracted and it is the 256's     
complment.

So long for now..