DataMuseum.dk

Presents historical artifacts from the history of:

CP/M

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about CP/M

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦24d2a14e0⟧ TextFile

    Length: 3584 (0xe00)
    Types: TextFile
    Names: »MPBMUL.MAC«

Derivation

└─⟦01b5c9619⟧ Bits:30005906 Microsoft Multiplan v1.05 og HELP
    └─ ⟦this⟧ »MPBMUL.MAC« 

TextFile

	aseg
	org	200h
	.z80

;
;
;	Title		Multiple-Precision Binary Multiplication
;	Name:		MPBMUL
;
;
;	Purpose:	Multiply 2 arrays of binary bytes
;			Multiplicand = multiplicand * multiplier
;
;	Entry:		Register pair HL = Base address of multiplicand
;			Register pair DE = Base address of multiplier
;			Register B = Lenght of the arrays
;
;			  The arrays are unsigned binary numbers with a
;			  maximum lenght of 255 bytes, ARRAYÆ0Å is the
;			  least significant byte, and ARRAYÆLENGH-1Å
;			  the most significand byte.
;
;	Exit:		Multiplicand := multiplicand * multiplier
;
;	Registers used:	AF,BC,DE,HL
;
;	Time:		Assuming the average number of 1 bits in multi-
;			plicand is 4 * lenght, then the time is approxi-
;			mately
;			  (728 * lengh ^2) + (883 * lenght) + 300 cycles
;
;	Size:		Program 104 bytes
;			Data    261 bytes
;
;
;


MPBMUL:
	;Exit if lenght is zero
	ld	a,b
	and	a		;Is the lenght of arrays = 0 ?
	ret	z		;Yes, exit

	;Make pointers point to end of operands
	ld	c,b		;BC = lenght
	ld	b,0
	add	hl,bc		;End = base + lenght
	ex	de,hl		;DE points to end of multiplicand
	ld	(mlier),hl	;save address of multiplier
	ld	hl,hiprod
	add	hl,bc
	ld	(endhp),hl	;Save address at end of hiprod

	;Set count to number of bits in array plus 1
	; count *= (lengh*8) + 1
	ld	l,c		;Move lenght to HL
	ld	h,b
	add	hl,hl		;Lenght * 8, shift left 3 times
	add	hl,hl
	add	hl,hl
	inc	hl		;add 1
	ld	(count),hl	;Save number of bits to do

	;Zero high product array
zeropd:
	ld	b,c		;B = lenght in bytes
	ld	hl,hiprod	;Get address of hiprod
zerolp:
	ld	(hl),0		;Store 0
	inc	hl
	djnz	zerolp		;Continue until hiprod array is zero

	;Multiply using the shit and add algorithm
	and	a		;Clear carry first time through
loop:
	;Shift carry into hiprod array and least significant
	; bit of hiprod to carry
	ld	b,c		;Get lenght in bytes
	ld	hl,(endhp)	;Get last byte of hiprod + 1
srplp:
	dec	hl		;Back up to next byte
	rr	(hl)
	djnz	srplp		;Continue until index = 0

	;Shift carry (next bit of lower product) into most
	;  significant bit of multiplicand.
	;  this also shifts next bit of multiplicand to carry
	ld	l,e		;HL = address of end of multipliand
	ld	h,d
	ld	b,c		;B = lenght in bytes
sra1lp:
	dec	hl		;Back up to next byte
	rr	(hl)
	djnz	sra1lp		;Continue until done

	;If next bit of multiplicandd is 1 then
	;  add multiplier to hiprod array
	jp	nc,deccnt	;Jump if next bit is zero

	;Add multiplier to hiprod
	push	de		;Save address of multiplicand
	ld	de,(mlier)	;DE = address of multiplier
	ld	hl,hiprod	;HL = address of hiprod
	ld	b,c		;B = lenght in bytes
	and	a		;Clear carry
addlp:
	ld	a,(de)		;Get next multiplier byte
	adc	a,(hl)		;Add to hiprod
	ld	(hl),a		;Store new hiprod
	inc	de
	inc	hl
	djnz	addlp		;Continue until done
	pop	de		;estore address of multiplicand

	;Decrement bit counter, exit if done
	;  does not change carry
deccnt:
	ld	a,(count)
	dec	a
	ld	(count),a
	jp	nz,loop		;Branch if lsb of count not zero
	push	af		;Save carry
	ld	a,(count+1)	;Get high byte of count
	and	a		; is it zero ?
	jr	z,exit		; exit if so
	dec	a		;Decrement high byte of count
	ld	(count+1),a
	pop	af		;restore carry
	jp	loop		;Continue

exit:	pop	af		;Drop psw from stack
	ret			;Return

	;DATA
count:	ds	2		;Temporary for loop counter
endhp:	ds	2		;Address of last byte of hiprod + 1
mlier:	ds	2		;Address of multiplier
hiprod:	ds	255		;High product buffer
«eof»