Write a 32-bit addition routine. It should take three parameters, passed on the stack: the addresses of the two operands (pushed first), and then the address of the result. These are all sixteen bit addresses. Your procedure should perform the addition, and correctly set the NZVC condition code bits.
Write a procedure which will multiply two 16-bit operands, generating a 32 bit result. Once again, it should take three parameters from the stack: the addresses of the two operands (pushed first), and then the address of the result. If your procedure requires any extra space (and it almost certainly will) it should allocate this space on the stack.
Hint: It is possible to build this procedure on top of the MUL
instruction. Here's a picture of the basic idea:
***************** PROGRAM 1 ************************ ********************************************************** *Strategy: consider a + b = c. * we do: * 1. copy a into c; * 2. add b to c. * During step 2, we do four one-byte addition * backwards from the last bytes of the operands. * Except the very first one-byte addition, we * use addition instructions which take the carry * bit such as ADCA, ADCB. ********************************************************** org $0000 c rmb 4 org $f800 a fcb $0f,$f9,$f0,$e9 b fcb $f2,$20,$10,$28 * expect c = $02,$1a,$01,$11 main lds #$00ff ldx #a *pass the address of the first operand,a pshx ldx #b *pass the address of the second operand,b pshx ldx #c *pass the address of the result, c pshx jsr add32 *call the subroutine ins *restore the stack ins ins ins ins ins eloop bra eloop add32 * push the current environment pshx *push X pshy *push Y psha *push A pshb *push B * copy the first operand into the result tsx ldy 8,x *get the address of the result into Y ldx 12,x *get the address of the operand a into X ldd 0,x *read the two higher bytes of operand a into D std 0,y *store them to the two higher bytes of result inx inx iny iny ldd 0,x *read the two lower bytes of operand a into D std 0,y *store them to the two lower bytes of result * get ready for one-byte addition from the end of the operands iny *let Y currently index to the last byte of the result tsx ldx 10,x *get the address of the operand b into X inx *let X currently index to the last byte of operand b inx inx * perform the addition byte by byte backwards from the end * current position is the fourth byte ldaa 0,x *get the current byte of operand b adda 0,y *add the current byte of the result (actually operand a) staa 0,y *update the current byte of the result dex dey * current position is the third byte ldaa 0,x *get the current byte of operand b adca 0,y *add the current byte of the result (actually operand a) staa 0,y *update the current byte of the result dex dey * current position is the second byte ldaa 0,x *get the current byte of operand b adca 0,y *add the current byte of the result (actually operand a) staa 0,y *update the current byte of the result dex dey * current position is the first byte ldaa 0,x *get the current byte of operand b adca 0,y *add the current byte of the result (actually operand a) staa 0,y *update the current byte of the result pulb *pop B pula *pop A puly *pop Y pulx *pop X rts end main *********************** PROGRAM 2 *********************** ********************************************************** *Strategy: consider PQ * UV = R. * step 1: initialize R * step 2: compute Q*V and add it appropriately to R * step 3: compute P*V and add it appropriately to R * step 4: compute Q*U and add it appropriately to R * step 5: compute P*U and add it appropriately to R * ********************************************************** org $0000 c rmb 4 org $f800 a fcb $01,$00 * P Q b fcb $01,$00 * U V * expect c = $00,$01,$00,$00 main lds #$00ff ldx #a *pass the address of the first operand,a pshx ldx #b *pass the address of the second operand,b pshx ldx #c *pass the address of the result, c pshx jsr mul16 *call the subroutine ins *restore the stack ins ins ins ins ins eloop bra eloop mul16 * push the current environment pshx *push X pshy *push Y psha *push A pshb *push B *=======step 1: initialize the result with zero tsx ldx 8,x *get the address of the result into X clra staa 0,x staa 1,x staa 2,x staa 3,x *=======step 2: computing and store the effect of Q*V * 1.get Q and V tsx ldx 12,x *get the address of the operand a into X ldaa 1,x *get Q into A tsx ldx 10,x *get the address of the operand b into X ldab 1,x *get V into B * 2.compute Q*V mul *Q*V is now in accumulator D * 3.store Q*V into the result appropriately tsx ldx 8,x *get the address of the result into X std 2,x *=======step 3: computing and store the effect of P*V * 1.get P and V tsx ldx 12,x *get the address of the operand a into X ldaa 0,x *get P into A tsx ldx 10,x *get the address of the operand b into X ldab 1,x *get V into B * 2.compute P*V mul *P*V is now in accumulator D * 3.store P*V into the result appropriately tsx ldx 8,x *get the address of the result into X addb 2,x *add B to the third byte (from left) of result stab 2,x adca 1,x *add A to the second byte of result staa 1,x bcs t1 *if there is a carry,add it to the first byte of result bra qu t1 inc 0,x *=======step 4: computing and store the effect of Q*U qu * 1.get Q and U tsx ldx 12,x *get the address of the operand a into X ldaa 1,x *get Q into A tsx ldx 10,x *get the address of the operand b into X ldab 0,x *get U into B * 2.compute Q*U mul *Q*U is now in accumulator D * 3.store Q*U into the result appropriately tsx ldx 8,x *get the address of the result into X addb 2,x *add B to the third byte (from left) of result stab 2,x adca 1,x *add A to the second byte of result staa 1,x bcs t2 *if there is a carry,add it to the first byte of result bra pu t2 inc 0,x *=======step 5: computing and store the effect of P*U pu * 1.get P and V tsx ldx 12,x *get the address of the operand a into X ldaa 0,x *get P into A tsx ldx 10,x *get the address of the operand b into X ldab 0,x *get U into B * 2.compute Q*U mul *Q*U is now in accumulator D * 3.store P*U into the result appropriately tsx ldx 8,x *get the address of the result into X addb 1,x *add B to the third byte (from left) of result stab 1,x adca 0,x *add A to the second byte of result staa 0,x pulb *pull the saved environment pula puly pulx rts end main