81 lines
1.7 KiB
ArmAsm
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
|