;********************************************************************* ;vertical_adder ; ; The purpose of this routine is to add two numbers that are ;oriented 'vertically' instead of horizontally. In other ;words, the least significant bit of each variable is in one file register, ;the next bit is in another register, and so on. This method of addition ;makes it possible to perform 8 simultaneous additions. ; ; The arithmetic operation performed given A and B are the two numbers ;being added together and C is the carry is: ; ; sum = A + B + C ; B+ = sum & 1 ;next state of B is the LSB of the sum of the 3 bits ; C+ = sum >> 1 ;The carry out is set if the sum is greater than 1 ; ; The truth table and boolean equations (along with their Karnaugh maps) ;are: ; ; Truth table: \BC \BC ; A \ 00 01 11 10 A \ 00 01 11 10 ; inputs | outputs +---+---+---+---+ +---+---+---+---+ ; A B C | B+ C+ 0 | | 1 | | 1 | 0 | | | 1 | | ; -------+--------- +---+---+---+---+ +---+---+---+---+ ; 0 0 0 | 0 0 1 | 1 | | 1 | | 1 | | 1 | 1 | 1 | ; 0 0 1 | 1 0 +---+---+---+---+ +---+---+---+---+ ; 0 1 0 | 1 0 B+ = A ^ B ^ C C+ = AB | BC | AC ; 0 1 1 | 0 1 ; 1 0 0 | 1 0 ; 1 0 1 | 0 1 ; 1 1 0 | 0 1 ; 1 1 1 | 1 1 ; ; Generating B+ is relatively straight forward. However, the carry out ;is somewhat difficult. The in-line comments describe the boolean equations ;at each step of the program. Though it's probably easier to follow the ;logic with Karnaugh maps. ; ; C+ = (~B+)&A | BC = (~(A^B^C)&A) | BC = AB | BC | AC ; ; \BC \BC \BC ; A \ 00 01 11 10 A \ 00 01 11 10 A \ 00 01 11 10 ; +---+---+---+---+ +---+---+---+---+ +---+---+---+---+ ; 0 | 1 | | 1 | | 0 | | | | | 0 | | | | | ; +---+---+---+---+ AND +---+---+---+---+ = +---+---+---+---+ ; 1 | | 1 | | 1 | 1 | 1 | 1 | 1 | 1 | 1 | | 1 | | 1 | ; +---+---+---+---+ +---+---+---+---+ +---+---+---+---+ ; ;followed by: ; ; ; \BC \BC \BC ; A \ 00 01 11 10 A \ 00 01 11 10 A \ 00 01 11 10 ; +---+---+---+---+ +---+---+---+---+ +---+---+---+---+ ; 0 | | | | | 0 | | | 1 | | 0 | | | 1 | | ; +---+---+---+---+ OR +---+---+---+---+ = +---+---+---+---+ ; 1 | | 1 | | 1 | 1 | | | 1 | | 1 | | 1 | 1 | 1 | ; +---+---+---+---+ +---+---+---+---+ +---+---+---+---+ ; ==================== ; ; INPUTS ; A0 - 8 bits of the first addend ; B0 - 8 bits of the second addend ; CARRY - 8 bits of the carry-in ; ; OUTPUTS: ; B0 - 8 bits of the result ; CARRY - 8 bits of the carry-out ; vertical_adder MOVF CARRY,W ;W = C XORWF A0,W ;W = A ^ C XORWF B0,F ;B+ = A ^ B ^ C XORWF B0,W ;W = (A^B^C) ^ (A^C) = B ANDWF CARRY,F ;C = B&C COMF B0,W ;W = ~(A^B^C) ANDWF A0,W ;W = ~(A^B^C) & A ; = A&~B&C | A&B&~C IORWF CARRY,F ;C = A&~B&C | A&B&~C | B&C ; = A&C | A&B | B&C