ack/mach/z80/libem/mli4.s
1987-02-02 13:30:20 +00:00

81 lines
1.7 KiB
ArmAsm

.define .mli4
.sect .text
.sect .rom
.sect .data
.sect .bss
.sect .text
! 32-bit multiply routine for z80
! parameters:
! on stack
! register utilization:
! ix: least significant 2 bytes of result
! hl: most significant 2 bytes of result
! bc: least significant 2 bytes of multiplicand
! de: most significant 2 bytes of multiplicand
! iy: 2 bytes of multiplier (first most significant,
! later least significant)
! a: bit count
.mli4:
!initialization
pop hl ! return address
pop de
ld (.mplier+2),de! least significant bytes of
! multiplier
pop de
ld (.mplier),de ! most sign. bytes
pop de ! least significant bytes of
! multiplicand
pop bc ! most sign. bytes
push hl ! return address
push iy ! LB
ld ix,0
xor a
ld h,a ! clear result
ld l,a
ld (.flag),a ! indicate that this is
! first pass of main loop
ld iy,(.mplier)
! main loop, done twice, once for each part (2 bytes)
! of multiplier
1:
ld a,16
! sub-loop, done 16 times
2:
add iy,iy ! shift left multiplier
jr nc,3f ! skip if most sign. bit is 0
add ix,de ! 32-bit add
adc hl,bc
3:
dec a
jr z,4f ! done with this part of multiplier
add ix,ix ! 32-bit shift left
adc hl,hl
jr 2b
4:
! see if we have just processed the first part
! of the multiplier (flag = 0) or the second
! part (flag = 1)
ld a,(.flag)
or a
jr nz,5f
inc a ! a := 1
ld (.flag),a ! set flag
ld iy,(.mplier+2)! least significant 2 bytes now in iy
add ix,ix ! 32-bit shift left
adc hl,hl
jr 1b
5:
! clean up
pop iy ! restore LB
ex (sp),hl ! put most sign. 2 bytes of result
! on stack! put return address in hl
push ix ! least sign. 2 bytes of result
jp (hl) ! return
.sect .data
.flag: .data1 0
.mplier: .space 4