146 lines
2 KiB
ArmAsm
146 lines
2 KiB
ArmAsm
.define .dvi4
|
|
|
|
! 32 bits integer divide and remainder routine
|
|
! Bit 0 of a-reg is set iff quotient has to be delivered
|
|
! Bit 7 of a-reg is set iff the operands are signed, so:
|
|
! Expects in a-reg: 0 if called by rmu 4
|
|
! 1 if called by dvu 4
|
|
! 128 if called by rmi 4
|
|
! 129 if called by dvi 4
|
|
! Expects on stack: divisor
|
|
! dividend
|
|
! Yields on stack: quotient or remainder
|
|
|
|
.dvi4: pop h
|
|
shld .retadr
|
|
mov h,b
|
|
mov l,c
|
|
shld .bcreg
|
|
|
|
sta .areg
|
|
pop h ! store divisor
|
|
shld block3
|
|
xchg
|
|
pop h
|
|
shld block3+2
|
|
dad d
|
|
jc 1f
|
|
mov a,l
|
|
ora h
|
|
cz eidivz ! trap if divisor = 0
|
|
|
|
1: pop h ! store dividend
|
|
shld block1
|
|
pop h
|
|
shld block1+2
|
|
lxi h,0 ! store initial value of remainder
|
|
shld block2
|
|
shld block2+2
|
|
|
|
mvi b,0
|
|
lda .areg
|
|
ral
|
|
jnc 2f ! jump if unsigned
|
|
|
|
lda block1+3
|
|
ral
|
|
jnc 1f
|
|
mvi b,129
|
|
lxi h,block1
|
|
call compl ! dividend is positive now
|
|
|
|
1: lda block3+3
|
|
ral
|
|
jnc 2f
|
|
inr b
|
|
lxi h,block3
|
|
call compl ! divisor is positive now
|
|
|
|
2: push b ! save b-reg
|
|
mvi b,32
|
|
|
|
dv0: lxi h,block1 ! left shift: block2 <- block1 <- 0
|
|
mvi c,8
|
|
xra a
|
|
1: mov a,m
|
|
ral
|
|
mov m,a
|
|
inx h
|
|
dcr c
|
|
jnz 1b
|
|
lxi h,block2+3 ! which is larger: divisor or remainder?
|
|
lxi d,block3+3
|
|
mvi c,4
|
|
1: ldax d
|
|
cmp m
|
|
jz 0f
|
|
jnc 3f
|
|
jmp 4f
|
|
0: dcx d
|
|
dcx h
|
|
dcr c
|
|
jnz 1b
|
|
|
|
4: lxi d,block2 ! remainder is larger or equal: subtract divisor
|
|
lxi h,block3
|
|
mvi c,4
|
|
xra a
|
|
1: ldax d
|
|
sbb m
|
|
stax d
|
|
inx d
|
|
inx h
|
|
dcr c
|
|
jnz 1b
|
|
lxi h,block1
|
|
inr m
|
|
|
|
3: dcr b
|
|
jnz dv0 ! keep looping
|
|
|
|
pop b
|
|
lda .areg ! quotient or remainder?
|
|
rar
|
|
jnc 4f
|
|
|
|
! for dvi 4 and dvu 4 only:
|
|
mov a,b
|
|
rar
|
|
lxi h,block1 ! complement quotient if divisor
|
|
cc compl ! and dividend have different signs
|
|
lhld block1+2 ! push quotient
|
|
push h
|
|
lhld block1
|
|
push h
|
|
jmp 5f
|
|
|
|
! for rmi 4 and rmu 4 only:
|
|
4: mov a,b
|
|
ral
|
|
lxi h,block2
|
|
cc compl ! negate remainder if dividend was negative
|
|
lhld block2+2
|
|
push h
|
|
lhld block2
|
|
push h
|
|
|
|
5: lhld .bcreg
|
|
mov b,h
|
|
mov c,l
|
|
lhld .retadr
|
|
pchl
|
|
|
|
! make 2's complement of 4 bytes pointed to by hl.
|
|
compl: push b
|
|
mvi c,4
|
|
xra a
|
|
1: mvi a,0
|
|
sbb m
|
|
mov m,a
|
|
inx h
|
|
dcr c
|
|
jnz 1b
|
|
pop b
|
|
ret
|
|
|