start service tasks separately in-case platforms need to perform additional set-up...
[AROS.git] / rom / utility / sdivmod32.c
blobb670c824a3b11104eee4bc6937909c74bd095ba1
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: SDivMod32 - Divide two 32 bit numbers.
6 Lang: english
7 */
8 #include "intern.h"
10 /*****************************************************************************
12 NAME */
13 #include <proto/utility.h>
15 AROS_LH2(QUAD, SDivMod32,
17 /* SYNOPSIS */
18 AROS_LHA(LONG, dividend, D0),
19 AROS_LHA(LONG, divisor, D1),
21 /* LOCATION */
22 struct UtilityBase *, UtilityBase, 25, Utility)
24 /* FUNCTION
25 Calculates the 32-bit signed division of dividend by divisor. That
26 is dividend / divisor. Will return both the quotient and the
27 remainder.
29 INPUTS
30 dividend - The number to divide.
31 divisor - The to divide by.
33 RESULT
34 For m68k assembly programmers:
35 D0: quotient
36 D1: remainder
37 Others:
38 The quotient is returned in the high 32 bits of the result.
39 The remainder in the low 32 bits.
41 NOTES
42 The utility.library math functions are unlike all other utility
43 functions in that they don't require the library base to be
44 loaded in register A6, and they also save the values of the
45 address registers A0/A1.
47 This function is mainly to support assembly programers, and is
48 probably of limited use to higher-level language programmers.
50 EXAMPLE
52 BUGS
53 It is very hard for a C programmer to obtain the value of the
54 remainder. In fact, its pretty near impossible.
56 SEE ALSO
57 SMult32(), SMult64(), UDivMod32(), UMult32(), UMult64()
59 INTERNALS
60 This may be handled by code in config/$(KERNEL).
62 HISTORY
63 29-10-95 digulla automatically created from
64 utility_lib.fd and clib/utility_protos.h
66 *****************************************************************************/
68 AROS_LIBFUNC_INIT
70 return dividend / divisor;
72 #if 0
73 #error Sorry, but the SDivMod32() emulation code does NOT work...
75 This does NOT work. Do not even try and use this code...
78 UWORD a,b,c,d;
79 QUAD result;
80 LONG quo, rem;
81 BOOL neg;
83 /* Fix everything up so that -ve signs don't vanish */
84 if(dividend < 0)
86 neg = 1; dividend = -dividend;
88 else
89 neg = 0;
91 if(divisor < 0)
93 neg ^= 1; divisor = -divisor;
96 a = dividend >> 16;
97 b = dividend & 0xFFFF;
98 c = divisor >> 16;
99 d = divisor & 0xFFFF;
101 /* See if the numerator is 32 bits or 16... */
102 if(a == 0)
104 /* 16 bits */
105 if(c != 0)
107 /* 16/32 -> quo = 0; rem = dividend */
108 quo = 0;
109 rem = dividend;
111 else
113 /* 16/16 -> can be done in native div */
114 quo = b / d;
115 rem = b % d;
118 else
120 /* 32 bit numerator */
121 if(c != 0)
123 /* 32 bit denominator, quo ~= a/c */
124 quo = a/c;
126 else
128 /* 16 bit denominator, quo ~= (a/d) * 65536 */
129 quo = (a / d) << 16;
131 /* Get the error */
132 rem = dividend - UMult32(quo,divisor);
134 /* Take the remainder down to zero */
135 while(rem > 0)
137 quo++;
138 rem -= divisor;
141 /* However a -ve remainder is silly,
142 this also catches the case when the remainder is < 0 from the
143 guess
145 while(rem < 0)
147 quo--;
148 rem += divisor;
152 return result;
154 #endif
156 AROS_LIBFUNC_EXIT
157 } /* SDivMod32 */