mirror of
https://github.com/cc65/cc65.git
synced 2024-12-24 11:31:31 +00:00
99 lines
2.4 KiB
ArmAsm
99 lines
2.4 KiB
ArmAsm
;
|
|
; Ullrich von Bassewitz, 17.08.1998
|
|
;
|
|
; CC65 runtime: division for long unsigned ints
|
|
;
|
|
|
|
.export tosudiv0ax, tosudiveax, getlop, udiv32
|
|
.import addysp1
|
|
.importzp sp, sreg, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4
|
|
|
|
tosudiv0ax:
|
|
ldy #$00
|
|
sty sreg
|
|
sty sreg+1
|
|
|
|
tosudiveax:
|
|
jsr getlop ; Get the paramameters
|
|
jsr udiv32 ; Do the division
|
|
lda ptr1 ; Result is in ptr1:sreg
|
|
ldx ptr1+1
|
|
rts
|
|
|
|
; Pop the parameters for the long division and put it into the relevant
|
|
; memory cells. Called from the signed divisions also.
|
|
|
|
getlop: sta ptr3 ; Put right operand in place
|
|
stx ptr3+1
|
|
lda sreg
|
|
sta ptr4
|
|
lda sreg+1
|
|
sta ptr4+1
|
|
|
|
ldy #0 ; Put left operand in place
|
|
lda (sp),y
|
|
sta ptr1
|
|
iny
|
|
lda (sp),y
|
|
sta ptr1+1
|
|
iny
|
|
lda (sp),y
|
|
sta sreg
|
|
iny
|
|
lda (sp),y
|
|
sta sreg+1
|
|
jmp addysp1 ; Drop parameters
|
|
|
|
; Do (ptr1:sreg) / (ptr3:ptr4) --> (ptr1:sreg), remainder in (ptr2:tmp3:tmp4)
|
|
; This is also the entry point for the signed division
|
|
|
|
udiv32: lda #0
|
|
sta ptr2+1
|
|
sta tmp3
|
|
sta tmp4
|
|
; sta ptr1+1
|
|
ldy #32
|
|
L0: asl ptr1
|
|
rol ptr1+1
|
|
rol sreg
|
|
rol sreg+1
|
|
rol a
|
|
rol ptr2+1
|
|
rol tmp3
|
|
rol tmp4
|
|
|
|
; Do a subtraction. we do not have enough space to store the intermediate
|
|
; result, so we may have to do the subtraction twice.
|
|
|
|
pha
|
|
cmp ptr3
|
|
lda ptr2+1
|
|
sbc ptr3+1
|
|
lda tmp3
|
|
sbc ptr4
|
|
lda tmp4
|
|
sbc ptr4+1
|
|
bcc L1
|
|
|
|
; Overflow, do the subtraction again, this time store the result
|
|
|
|
sta tmp4 ; We have the high byte already
|
|
pla
|
|
sbc ptr3 ; byte 0
|
|
pha
|
|
lda ptr2+1
|
|
sbc ptr3+1
|
|
sta ptr2+1 ; byte 1
|
|
lda tmp3
|
|
sbc ptr4
|
|
sta tmp3 ; byte 2
|
|
inc ptr1 ; Set result bit
|
|
|
|
L1: pla
|
|
dey
|
|
bne L0
|
|
sta ptr2
|
|
rts
|
|
|
|
|