;********************************************* ;divide.asm --> div16s -> based on a 24-bit by 16 divide scheme from Atmel's 16x16 divide ;Notes: ;remainder does not contain correct value ;does not check for divide by 0 ;does not check for over/underflow ;only checks the dividend for negative sign, does not check divisor ;48 words, 405 cycles, 101.25us @ 4MHz ;uses 7 high registers, 3 low registers ;********************************************* ;***** Subroutine Register Variables .def d16s =r30 ;sign register .def drem16sL=r9 ;remainder low byte .def drem16sH=r11 ;remainder high byte .def drem16s3=r10 .def dres16s2=r16 ;result middle byte .def dres16s1=r18 ;result highest byte .def dres16s3=r17 ;result lowest byte .def dd16s2 =r16 ;dividend middle byte .def dd16s1 =r18 ;dividend high byte .def dd16s3 =r17 ;dividend low byte .def dv16sL =r19 ;divisor low byte .def dv16sH =r20 ;divisor high byte .def dcnt16s =r31 ;loop counter ;***** Code div16s: clr d16s ;clear sign register tst dd16s1 ;if dividend negative, set sign register brge div_0 ser d16s com dd16s1 ; change sign of dividend com dd16s2 subi dd16s2,low(-1) sbci dd16s2,high(-1) div_0: clr drem16sL ;sets remainder to 0 clr drem16sH ldi dcnt16s, 0x18 ;sets counter at 24 div_1: clc rol dres16s3 ;shift dividend left rol dres16s2 rol dres16s1 rol drem16sL ;shift remainder left + carry in from dividend rol drem16sH sub drem16sL, dv16sL ;remainder = remainder - divisor sbc drem16sH, dv16sH brcc div_2 ;negative? add drem16sL, dv16sL ; restore remaidner adc drem16sH, dv16sH rjmp div_3 div_2: ori dres16s3, 0x01 ;positive --> Q0 = 1 div_3: dec dcnt16s ;count-- brne div_1 tst d16s brge div_end com dres16s2 ; change sign of result com dres16s3 subi dres16s3,low(-1) sbci dres16s2,high(-1) div_end: ret