ack/mach/i80/libem/dvi4.s
1987-01-28 18:57:04 +00:00

151 lines
2.1 KiB
ArmAsm

.define .dvi4
.sect .text
.sect .rom
.sect .data
.sect .bss
.sect .text
! 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