*************************************** * * * M.L. PART FIVE BY DR. FIRMWARE * * * *************************************** 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. *************************************** * * * CALL THESE BOARDS: * * TESTAMENT: (514)-332-6852 * * GAMMA-LINE: (514)-683-9176 * * TRANSFERS II AE/CAT: 738-1247 * * * *************************************** 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..