org $3000 START * tests each function (data are at end) * macro for printing (d1.l) as long print MACRO move.l #3,d0 ; print long trap #15 move.l #0,d0 ; print newline move.w #0,d1 trap #15 ENDM _main: move.w #N,-(sp) pea V2 pea V1 jsr _vsum adda.w #10,sp ; inspect memory to verify move.w #M,-(sp) pea RTBL jsr _range adda.w #6,sp clr.l d1 move.w d0,d1 print move.w #L,-(sp) pea NAME jsr _parity2 adda.w #6,sp ; inspect memory to verify move.l #9,d0 ; exit trap #15 ******************************************************************************* _vsum: link a6,#0 move.w d2,-(sp) move.l 8(a6),a0 ; v1 move.l 12(a6),a1 ; v2 move.w 16(a6),d1 ; n move.w #-1,d0 ; start with error indicated subi.w #1,d1 loop2 move.w (a0)+,d2 add.w d2,(a1)+ bvs exit2 ; overflow dbf d1,loop2 clr.w d0 ; no error exit2 move.w (sp)+,d2 unlk a6 rts ******************************************************************************* _range: link a6,#0 movem.w d2-d3,-(sp) move.l 8(a6),a0 ; table move.w 12(a6),d3 ; n beq exit0 move.w (a0)+,d0 ; min move.w d0,d1 ; max subi.w #2,d3 ; looked at first element & dbf loop0 move.w (a0)+,d2 ; grab element cmp.w d0,d2 ; min? bcc max move.w d2,d0 ; d2 < d0 dbf d3,loop0 max cmp.w d1,d2 ; max? bcs skip0 move.w d2,d1 ; d2 > d1 skip0 dbf d3,loop0 sub.w d0,d1 ; compute range move.w d1,d0 exit0 movem.w (sp)+,d2-d3 unlk a6 rts ******************************************************************************* _parity: move.l 4(sp),a0 ; data move.w 8(sp),d0 ; n move.l a0,a1 adda.w d0,a1 ; end of data loop1 move.b (a0),d0 ; get byte clr.b d1 ; compute XOR of first seven bits eor.b d0,d1 lsr.b #1,d0 eor.b d0,d1 lsr.b #1,d0 eor.b d0,d1 lsr.b #1,d0 eor.b d0,d1 lsr.b #1,d0 eor.b d0,d1 lsr.b #1,d0 eor.b d0,d1 lsr.b #1,d0 eor.b d0,d1 not.b d1 ; negate result (so odd parity) lsl.b #7,d1 ; OR the result into bit #7 of (a0) move.b (a0),d0 or.b d1,d0 move.b d0,(a0)+ cmpa a0,a1 bne loop1 ; continue while bytes remain rts ******************************************************************************* * An alternate implementation requiring lg 8 = 3 steps per parity calculation. * Notice how for small values like 8, such a "clever" implementation may * actually be slower. But if one were computing the parity of, say, 64 bits, * the clever way would be faster than the linear way used in _parity. _parity2: move.w d2,-(sp) move.l 6(sp),a0 ; data move.w 10(sp),d1 ; n subi.w #1,d1 loop3 move.b (a0),d0 ; get byte move.b d0,d2 lsr.b #4,d2 andi.b #$7,d2 ; 0 out highest bit eor.b d2,d0 ; upper nibble with lower nibble move.b d0,d2 lsr.b #2,d2 eor.b d2,d0 ; upper two bits with lower two bits (of nibble) move.b d0,d2 lsr.b #1,d2 eor.b d2,d0 ; upper bit with lower bit (of two bits) not.b d0 ; negate lsl.b #7,d0 or.b d0,(a0)+ ; or into the character dbf d1,loop3 move.w (sp)+,d2 rts ******************************************************************************* * data for _main V1 dc.w 1,3,9 V2 dc.w -1,3,3 E_V2 N equ (E_V2-V2)/2 RTBL dc.w 1,7,3,9 E_RTBL M equ (E_RTBL-RTBL)/2 NAME dc.b 'aaron' E_NAME L equ E_NAME-NAME end START