Hi,

Does anyone has the assembly code for dividing 32 bit by 16 bit, i.e., unsigned long x, unsigned int?

in Freescale intrinsic_math.asm, there is only 32 bit by 8 bit division, as follows.

Thanks

Ed

;/*****************************************************************************

;*

;* Module: unsigned int udiv32i8to16(unsigned long x, unsigned char y)

;*

;* Description:

;* Unsigned integer dividing 32 bit by 8 bit from 16 bit Uword.

;* The Result is saturated at 0xFFFF if overflow occures.

;*

;* Returns: x/y

;* Returns: Out3:Out2:Out1:Out0 = (x3:x2:x1:x0)/(y0) = x/y

;*

;* Arguments: y (in) L1->5,SP; L2->6,SP;

;* H1->3,SP; H2->4,SP;

;* y (in) A

;*

;* Range Issues: None

;*

;* Special Issues: HCS08S -Cs08 Option backend. The result is saturated

;*

;*****************************************************************************/

udiv32i8to16:

PSHA ;

TAX ; y -> X

TST 4,SP ;

BNE udiv32Sat

LDA 5, SP

PSHA

PULH

LDA 6, SP

DIV ;

BCS udiv32Sat

PSHA

LDA 8, SP

DIV

TAX ;z0 -> X

PULH ;z1 -> H

PULA

RTS

udiv32Sat:

LDHX #0FFFFh

PULA

RTS

Hi Ed,

This is a solution. The routine uses some zero-page ram for Quotient, Divisor and Result (2x 4byte) and some bytes more (3) from stack. It is all noted.

; variables declaration (IntAcc1 & IntAcc2)Quotient:Remainder:IntAcc1: ; 4-bytes integer accum. #1TEMP1 ds 1TEMP2 ds 1Dividend:TEMP3 ds 1TEMP4 ds 1Divisor:IntAcc2: ; 4-bytes integer accum. #2TEMP5 ds 1TEMP6 ds 1TEMP7 ds 1TEMP8 ds 1;**************************************************; 32 x 16 UNSIGNED DIVIDE;; This routine takes the 32-bit dividend stored in; IntAcc1:IntAcc1+3 and divides it by the 16-bit; divisor stored in IntAcc2:IntAcc2+1.; The quotient replaces the dividend and the; remainder replaces the divisor.; Time length: 1720us @ 2MHz BusClock with call;**************************************************UDVD32 pshh ; save H-reg valuepsha ; save accumulatorpshx ; save H-reg valueais #-3 ; reserve three bytes of; temp storagelda #32sta 3,SP ; loop cntr for nr. shiftslda Divisor ; get divisor Msbsta 1,SP ; put divisor Msb in; working storagelda Divisor+1 ; get divisor lsbsta 2,SP ; put divisor lsb in; working storage; Shift all four bytes of dividend 16 bits to the; right and clear both bytes of the temporary; remainder locationmov Dividend+1,Dividend+3 ; shift divid. lsbmov Dividend,Dividend+2 ; shift 2nd byte; of dividendmov Dividend-1,Dividend+1 ; shift 3rd byte; of dividendmov Dividend-2,Dividend ; shift divid. Msbclr Remainder ; zero remain. Msbclr Remainder+1 ; zero remain. lsb; Shift each byte of dividend and remainder one bit; to the leftShftLP lda Remainder ;get remainder Msbrola ;shift remainder Msb into;carryrol Dividend+3 ;shift dividend lsbrol Dividend+2 ;shift 2nd byte of dividendrol Dividend+1 ;shift 3rd byte of dividendrol Dividend ;shift dividend Msbrol Remainder+1 ;shift remainder lsbrol Remainder ;shift remainder Msb; Subtract both bytes of the divisor from remainderlda Remainder+1 ;get remainder lsbsub 2,SP ;subtract divisor lsb from;remainder lsbsta Remainder+1 ;store new remainder lsblda Remainder ;get remainder Msbsbc 1,SP ;subtract divisor Msb from;remainder msbsta Remainder ;store new remainder Msblda Dividend+3 ;get low byte of;dividend/quotientsbc #0 ;dividend low bit holds;subtract carrysta Dividend+3 ;store low byte of;dividend/quotient; Check dividend/quotient lsb. If clear, set lsb of; quotient to indicate successful subraction, else; add both bytes of divisor back to remainderbrclr 0,Dividend+3,SetLsb ;check for a carry;from subtraction and add;divisor to remainder if setlda Remainder+1 ;get remainder lsbadd 2,SP ;add divisor lsb to;remainder lsbsta Remainder+1 ;store remainder lsblda Remainder ;get remainder Msbadc 1,SP ;add divisor Msb to;remainder Msbsta Remainder ;store remainder msblda Dividend+3 ;get low byte of dividendadc #0 ;add carry to low bit of;dividendsta Dividend+3 ;store low byte of dividendbra Decrmt ;do next shift and subtractSetLsb bset 0,Dividend+3 ;set lsb of quotient to;indicate successive; subtractionDecrmt dbnz 3,SP,ShftLP ;decrement loop counter and;do next shift; Move 32-bit dividend into IntAcc1:IntAcc1+3 and put; 16-bit remainder in IntAcc2:IntAcc2+1lda Remainder ;get remainder msbsta 1,SP ;temporarily store;remainder msblda Remainder+1 ;get remainder lsbsta 2,SP ;temporarily store rem.r lsbmov Dividend,Quotientmov Dividend+1,Quotient+1 ;shift all four;bytes of quotientmov Dividend+2,Quotient+2 ;16 bits to the;leftmov Dividend+3,Quotient+3lda 1,SP ;get final remainder Msbsta IntAcc2 ;store final remainder Msblda 2,SP ;get final remainder lsbsta IntAcc2+1 ;store final remainder lsb; Deallocate local storage, restore register values,; and return from subroutineais #3 ;deallocate temporary storagepulx ;restore X-reg valuepula ;restore accumulator valuepulh ;restore X-reg valuertsSorry the editor on the forum made a mess with the original formatting, but it is a minor problem: copy it on a good word editor with fixed character size (courier new). The routine is fully tested and I use it in my programs in assembler. Anyway the original text is attached in asm format.

Good luck,

Salvatore