******************************************************************************* * This simple program illustrates the use of the 'abcd' instruction for summing * multiple-precision BCD numbers, dbf, and address manipulation instructions * (the subjects of today's lecture) while reviewing many previous topics. ******************************************************************************* org $3000 START * Tests _add and bcd_to_ascii _main: move.w #N,-(sp) ; add(BCD0, BCD1, N) pea BCD1 pea BCD0 jsr _add adda.l #10,sp cmp.w #-1,d0 ; if rv = -1, print 'overflow' bne ok lea MSG,a1 move.l #13,d0 trap #15 bra done ok lea BCD1,a0 ; else, convert result to ASCII to print lea ASCII,a1 move.w #N,d1 jsr bcd_to_ascii lea ASCII,a1 ; print result move.w #N,d1 lsl.w #1,d1 ; 2*N characters to print move.l #0,d0 trap #15 done move.l #9,d0 ; exit trap #15 ******************************************************************************* * short add(void * bcd0, void * bcd1, short nbytes); * In: bcd0, bcd1 - pointers to two BCD numbers, each of nbytes * nbytes - length of BCD numbers * Out: *bcd1 is updated to the sum of the two input BCD numbers * 0 - if the sum was computed successfully * -1 - if an overflow occurred ******************************************************************************* _add: link a6,#0 ; do standard setup (for review) movem.l d1/a0-a1,-(sp) movea.l 8(a6),a0 ; bcd0 movea.l 12(a6),a1 ; bcd1 move.w 16(a6),d1 ; nbytes adda.w d1,a0 ; point to end of first BCD number adda.w d1,a1 ; point to end of second BCD number clr.w d0 ; no error yet subi.w #1,d1 ; set up for use of dbf move #4,ccr ; Z = 1, X = 0 loop abcd -(a0),-(a1) ; BCD addition (Section 7.5) dbf d1,loop ; loop over all nbytes bcc exit move.w #-1,d0 ; set error (overflow) exit movem.l (sp)+,d1/a0-a1 unlk a6 rts ******************************************************************************* * Convert BCD of length (d1.w) at (a0) to ASCII at (a1). Two BCD numbers * (each 4 bits wide) are packed into each byte. ******************************************************************************* bcd_to_ascii: movem.l d2-d3,-(sp) subi.w #1,d1 ; set up for dbf ba_loop move.b (a0)+,d2 move.b d2,d3 ; two BCD numbers per byte lsr.b #4,d2 ; upper nibble addi.b #$30,d2 move.b d2,(a1)+ ; write ASCII character andi.b #$F,d3 ; lower nibble addi.b #$30,d3 move.b d3,(a1)+ ; write ASCII character dbf d1,ba_loop movem.l (sp)+,d2-d3 rts ******************************** DATA ***************************************** BCD0 dc.b $21,$79,$46 ; first BCD number, i.e., 217946 BCD1 dc.b $00,$30,$19 ; second BCD number, i.e., 3019 (padded with 0s) E_BCD1 N equ E_BCD1-BCD1 ; number of bytes comprising BCD numbers ASCII ds.b 16 ; destination for bcd_to_ascii MSG dc.b 'overflow',0 end START