h09748
s 00132/00000/00000
d D 1.1 83/03/24 15:09:11 lib 1 0
c date and time created 83/03/24 15:09:11 by lib
e
u
4
U
t
T
I 1
;     INTEGER FUNCTION MULDIV (MUL1, MUL2, DIV)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                      ;
;          THIS MATERIAL IS CONFIDENTIAL AND IS FURNISHED UNDER        ;
;          A WRITTEN LICENSE AGREEMENT.  IT MAY NOT BE USED,           ;
;          COPIED OR DISCLOSED TO OTHERS EXCEPT IN ACCORDANCE          ;
;          WITH THE TERMS OF THAT AGREEMENT.                           ;
;                                                                      ;
;          COPYRIGHT (C) 1982 GRAPHIC SOFTWARE SYSTEMS INC.            ;
;          ALL RIGHTS RESERVED.                                        ;
;                                                                      ;
;     FUNCTION: MULTIPLY 2 16-BIT INTEGERS TO PRODUCE A 32-BIT         ;
;               INTERMEDIATE RESULT AND DIVIDE THAT BY A 16-BIT        ;
;               INTEGER TO PRODUCE A 16-BIT QUOTIENT                   ;
;                                                                      ;
;     INPUT PARAMETERS:                                                ;
;            MUL1, MUL2 - TWO 16-BIT INTEGERS TO MULTIPLY              ;
;            DIV        - DIVISOR                                      ;
;                                                                      ;
;     OUTPUT PARAMETERS:                                               ;
;            MULDIV - (MUL1 * MUL2) / DIV                              ;
;                                                                      ;
;     ROUTINES CALLED:                                                 ;
;            NONE                                                      ;
;                                                                      ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	.8080
muldiv: entry   muldiv
	push	b		; save address of divisor
	mov	c,m		; get multiplicand in bc
	inx	h
	mov	b,m		
	xchg			; get multiplier in de
	mov	e,m
	inx	h
	mov	d,m		
	pop	h		; get address of divisor
	mov	a,m		; get divisor
	sta	divs
	inx	h
	mov	a,m
	sta	divs+1		
 
; Multiply 2 16-bit numbers to yield 32 bit result
; Numbers to be multiplied are in BC and DE
; The 32 bit result is in DE HL
 
	lxi	h,0		;initialize partial product
	mvi	a,16		;initialize count
loop:	dad	h		;left shift logical into carry
	xchg			;swap hl and de
	jc	mpy1		;jump if carry out from hl
	dad	h		;no carry-shift multiplier left logical into
				;carry
	jmp	mpy2
mpy1:	dad	h		;carry-shift multiplier left locigal into
	inx	h		;  carry and increment
mpy2:	xchg			;repoint to partial product
	jnc	mpy3		;jump if no add (multiplier bit in carry=0)
	dad	b		;add multiplicand in bc to partial prod in hl
	jnc	mpy3		;jump if no carry out
	inx	d		;increment de to add carry
mpy3:	dcr	a		;decrement count
	jnz	loop		;loop back if not done
	
;	Set up for divide. 32 bit product is in DE and HL.
;	Move HL to BC , DE to HL, and divisor to DE
 
	mov	c,l
	mov	b,h
	lhld	divs		;get divisor
	xchg
 
; Assume 31 bit unsigned integer in HLBC is dividend
;  15 bit unsigned DE is divisor
 
        mvi     a,16            ;Loop count
	sta	count		;Save count
 
; Carry H L B C rotated left by one bit.
 
shift:
	ana	a		;Clear carry
        mov     a,c             ;Shift developing quotient
        ral
        mov     c,a
        mov     a,b
        ral
        mov     b,a
 
        mov     a,l             ;Shift dividend
        ral
        mov     l,a
        mov     a,h
        ral
        mov     h,a
 
sub:	shld	temp		;save dividend
	mov     a,l             ;Get dividend
        sub     e               ;Subtract divisor
        mov     l,a             ;Back to dividend
        mov     a,h             ;High half
        sbb     d               ; of both
        mov     h,a
 
	jc	restore		;dividend >= divisor? - No
	
	inx	b		;yes - increment quotient
	jmp	test
 
restore:
	lhld	temp
 
test:
	lda	count		;Get loop count
        dcr     a               ;Decrement loop count
        sta	count		;Save loop count
        jz      done            ;Jump when 16 bits done
 
        jmp     shift           ;Go shift in quotient bit
 
 
;Quotient is now in BC.  Move it to HL for Fortran function return
done:
	mov	h,b
	mov	l,c
	ret
divs:	ds	2
count:  ds   	1
temp:   ds	2
	end
 
E 1
