http://mirrors.apple2.org.za/ground.ica ... mming/div7
Richard Jackson
Ranando King
Scott Hemphill
Paul Guertin
Code: Select all
; - - - - - - - - - - - - - - - - - - - - - - - - - - -
; 16-bit unsigned division by 40 routine
; TOS /= 40, A = remainder, Y = 0
;
div40:
lda #0 ; remainder
ldy #16 ; loop counter
div40b:
asl TOS ; TOS is gradually replaced
rol TOS+1 ; with the quotient
rol ; A is gradually replaced
; with the remainder
cmp #40 ; partial remainder >= 40?
bcc div40c
sbc #40 ; yes: update partial
; remainder, set low bit
inc TOS ; in partial quotient
div40c:
dey
bne div40b ; loop 16 times
rts
Code: Select all
:f8860000 clc ; zero high word
:24060028 div #40 ; TOS /= 40, c = remainder
Code: Select all
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 16 bit unsigned divide by 40, mod 40
; By Omegamatrix
; 142/143 cycles, 118 bytes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LowQuotientAdjust:
.byte 0,6,12,19,25
; (0 / 40) % 32 = 0
; (256 / 40) % 32 = 6
; (512 / 40) % 32 = 12
; (768 / 40) % 32 = 19
;(1024 / 40) % 32 = 25
;(1280 / 40) % 32 = 0 <--- starts to repeat
Mod40_DivHigh:
.byte 0,16,32,8,24
; 0 % 40 = 0
; 256 % 40 = 16
; 512 % 40 = 32
; 768 % 40 = 8
; 1024 % 40 = 24
; 1280 % 40 = 0 <--- starts to repeat
FortyCountTab:
.byte 0,40,80,120,160,200,240
StartDivide40Mod40:
lda dividendHigh ;3 @3
sta temp ;3 @6
lsr ;2 @8
adc #13 ;2 @10
adc temp ;3 @13
ror ;2 @15
lsr ;2 @17
lsr ;2 @19
adc temp ;3 @22
ror ;2 @24
adc temp ;3 @27
ror ;2 @29
and #$FC ;2 @31
sta temp ;3 @34
lsr ;2 @36
lsr ;2 @38
tay ;2 @40
adc temp ;3 @43
eor #$FF ;2 @45
sec ;2 @47
adc dividendHigh ;3 @50
tax ;2 @52
lda temp ;3 @55
asl ;2 @57
asl ;2 @59
asl ;2 @61
ora LowQuotientAdjust,X ;4 @65
sta quotientLow ;3 @68
tya ;2 @70
lsr ;2 @72
lsr ;2 @74
lsr ;2 @76
sta quotientHigh ;3 @79
lda #0 ;2 @81
ldy dividendLow ;3 @84
cpy #40 ;2 @86
rol ;2 @88
cpy #80 ;2 @90
adc #0 ;2 @92
cpy #120 ;2 @94
adc #0 ;2 @96
cpy #160 ;2 @98
adc #0 ;2 @100
cpy #200 ;2 @102
adc #0 ;2 @104
cpy #240 ;2 @106
adc #0 ;2 @108
sta temp ;3 @111
tya ;2 @113
ldy temp ;3 @116
adc Mod40_DivHigh,X ;4 @120
sec ;2 @122
sbc FortyCountTab,Y ;4 @126
cmp #40 ;2 @128
bcc .storeMod40 ;2³ @130/131
sbc #40 ;2 @132 leaving carry set to increase quotientLow by 1 below...
.storeMod40:
sta remainder ;3 @135
tya ;2 @137
adc quotientLow ;3 @140
sta quotientLow ;3 @143Code: Select all
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 16 bit unsigned divide by 40, mod 40 (Ver 2)
; By Omegamatrix
; 111-131 cycles, 118 bytes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LowQuotientAdjust:
.byte 0,6,12,19,25
; (0 / 40) % 32 = 0
; (256 / 40) % 32 = 6
; (512 / 40) % 32 = 12
; (768 / 40) % 32 = 19
;(1024 / 40) % 32 = 25
;(1280 / 40) % 32 = 0 <--- starts to repeat
Mod40_DivHigh:
.byte 0,16,32,8,24
; 0 % 40 = 0
; 256 % 40 = 16
; 512 % 40 = 32
; 768 % 40 = 8
; 1024 % 40 = 24
; 1280 % 40 = 0 <--- starts to repeat
StartDivide40Mod40:
lda dividendHigh ;3 @3
sta temp ;3 @6
lsr ;2 @8
adc #13 ;2 @10
adc temp ;3 @13
ror ;2 @15
lsr ;2 @17
lsr ;2 @19
adc temp ;3 @22
ror ;2 @24
adc temp ;3 @27
ror ;2 @29
and #$FC ;2 @31
sta temp ;3 @34
lsr ;2 @36
lsr ;2 @38
tay ;2 @40
adc temp ;3 @43
eor #$FF ;2 @45
sec ;2 @47
adc dividendHigh ;3 @50
tax ;2 @52
lda temp ;3 @55
asl ;2 @57
asl ;2 @59
asl ;2 @61
ora LowQuotientAdjust,X ;4 @65
sta quotientLow ;3 @68
tya ;2 @70
lsr ;2 @72
lsr ;2 @74
lsr ;2 @76
sta quotientHigh ;3 @79
lda dividendLow ;3 @82
clc ;2 @84
adc Mod40_DivHigh,X ;4 @88
bcs .moreThan255 ;2³ @90/91
cmp #120 ;2 @92
bcs .more120 ;2³ @94/95
ldx #0-1 ;2 @96
sec ;2 @98
bne .less120 ;3 @101 always branch
.moreThan255:
ldx #6 ;2 @93
adc #255-240 ;2 @95
cmp #40 ;2 @97
bcc .storeMod40 ;2³ @99/100
sbc #40 ;2 @101
bcs .storeMod40 ;3 @104 always branch
.more120:
sbc #120 ;2 @97
ldx #3-1 ;2 @99
.less120:
sbc #40 ;2 @101...103
bcc .add40 ;2³ @105/106
inx ;2 @107
sbc #40 ;2 @109
bcc .add40 ;2³ @111/112
inx ;2 @113
sbc #40 ;2 @115
bcc .add40 ;2³ @117/118
inx ;2 @..117
bcs .storeMod40 ;3 @120 always branch
.add40:
adc #40 ;2 @120
.storeMod40:
sta remainder ;3 @123
txa ;2 @125
adc quotientLow ;3 @128
sta quotientLow ;3 @131 worse case, 111 cycles best caseCode: Select all
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 16 bit unsigned divide by 40, mod 40 (Ver 3)
; By Omegamatrix
; 45-65 cycles, 581 bytes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
StartDivide40Mod40:
ldy dividendHigh ;3 @3
lda HighQuot_Mod40Tab,Y ;4 @7
and #$07 ;2 @9
sta quotientHigh ;3 @12
eor HighQuot_Mod40Tab,Y ;4 @16
clc ;2 @18
adc dividendLow ;3 @21
bcs .moreThan255 ;2³ @23/24
cmp #120 ;2 @25
bcs .more120 ;2³ @27/28
ldx #0-1 ;2 @29
sec ;2 @31
bne .less120 ;3 @34 always branch
.moreThan255:
ldx #6 ;2 @26
adc #255-240 ;2 @28
cmp #40 ;2 @30
bcc .storeMod40 ;2³ @32/33
sbc #40 ;2 @34
bcs .storeMod40 ;3 @37 always branch
.more120:
sbc #120 ;2 @30
ldx #3-1 ;2 @32
.less120:
sbc #40 ;2 @34...36 worse case
bcc .add40 ;2³ @38/39
inx ;2 @40
sbc #40 ;2 @42
bcc .add40 ;2³ @44/45
inx ;2 @46
sbc #40 ;2 @48
bcc .add40 ;2³ @50/51
inx ;2 @..50
bcs .storeMod40 ;3 @53 always branch
.add40:
adc #40 ;2 @53
.storeMod40:
sta remainder ;3 @56
txa ;2 @58
adc LowQuotientTab,Y ;4 @62
sta quotientLow ;3 @65 worse case, 45 best case
HighQuot_Mod40Tab:
.byte $00,$10,$20,$08,$18,$00,$10,$20,$08,$18,$00,$10,$20,$08,$18,$00
.byte $10,$20,$08,$18,$00,$10,$20,$08,$18,$00,$10,$20,$08,$18,$00,$10
.byte $20,$08,$18,$00,$10,$20,$08,$18,$01,$11,$21,$09,$19,$01,$11,$21
.byte $09,$19,$01,$11,$21,$09,$19,$01,$11,$21,$09,$19,$01,$11,$21,$09
.byte $19,$01,$11,$21,$09,$19,$01,$11,$21,$09,$19,$01,$11,$21,$09,$19
.byte $02,$12,$22,$0A,$1A,$02,$12,$22,$0A,$1A,$02,$12,$22,$0A,$1A,$02
.byte $12,$22,$0A,$1A,$02,$12,$22,$0A,$1A,$02,$12,$22,$0A,$1A,$02,$12
.byte $22,$0A,$1A,$02,$12,$22,$0A,$1A,$03,$13,$23,$0B,$1B,$03,$13,$23
.byte $0B,$1B,$03,$13,$23,$0B,$1B,$03,$13,$23,$0B,$1B,$03,$13,$23,$0B
.byte $1B,$03,$13,$23,$0B,$1B,$03,$13,$23,$0B,$1B,$03,$13,$23,$0B,$1B
.byte $04,$14,$24,$0C,$1C,$04,$14,$24,$0C,$1C,$04,$14,$24,$0C,$1C,$04
.byte $14,$24,$0C,$1C,$04,$14,$24,$0C,$1C,$04,$14,$24,$0C,$1C,$04,$14
.byte $24,$0C,$1C,$04,$14,$24,$0C,$1C,$05,$15,$25,$0D,$1D,$05,$15,$25
.byte $0D,$1D,$05,$15,$25,$0D,$1D,$05,$15,$25,$0D,$1D,$05,$15,$25,$0D
.byte $1D,$05,$15,$25,$0D,$1D,$05,$15,$25,$0D,$1D,$05,$15,$25,$0D,$1D
.byte $06,$16,$26,$0E,$1E,$06,$16,$26,$0E,$1E,$06,$16,$26,$0E,$1E,$06
LowQuotientTab
.byte $00,$06,$0C,$13,$19,$20,$26,$2C,$33,$39,$40,$46,$4C,$53,$59,$60
.byte $66,$6C,$73,$79,$80,$86,$8C,$93,$99,$A0,$A6,$AC,$B3,$B9,$C0,$C6
.byte $CC,$D3,$D9,$E0,$E6,$EC,$F3,$F9
.byte $00,$06,$0C,$13,$19,$20,$26,$2C,$33,$39,$40,$46,$4C,$53,$59,$60
.byte $66,$6C,$73,$79,$80,$86,$8C,$93,$99,$A0,$A6,$AC,$B3,$B9,$C0,$C6
.byte $CC,$D3,$D9,$E0,$E6,$EC,$F3,$F9
.byte $00,$06,$0C,$13,$19,$20,$26,$2C,$33,$39,$40,$46,$4C,$53,$59,$60
.byte $66,$6C,$73,$79,$80,$86,$8C,$93,$99,$A0,$A6,$AC,$B3,$B9,$C0,$C6
.byte $CC,$D3,$D9,$E0,$E6,$EC,$F3,$F9
.byte $00,$06,$0C,$13,$19,$20,$26,$2C,$33,$39,$40,$46,$4C,$53,$59,$60
.byte $66,$6C,$73,$79,$80,$86,$8C,$93,$99,$A0,$A6,$AC,$B3,$B9,$C0,$C6
.byte $CC,$D3,$D9,$E0,$E6,$EC,$F3,$F9
.byte $00,$06,$0C,$13,$19,$20,$26,$2C,$33,$39,$40,$46,$4C,$53,$59,$60
.byte $66,$6C,$73,$79,$80,$86,$8C,$93,$99,$A0,$A6,$AC,$B3,$B9,$C0,$C6
.byte $CC,$D3,$D9,$E0,$E6,$EC,$F3,$F9
.byte $00,$06,$0C,$13,$19,$20,$26,$2C,$33,$39,$40,$46,$4C,$53,$59,$60
.byte $66,$6C,$73,$79,$80,$86,$8C,$93,$99,$A0,$A6,$AC,$B3,$B9,$C0,$C6
.byte $CC,$D3,$D9,$E0,$E6,$EC,$F3,$F9
.byte $00,$06,$0C,$13,$19,$20,$26,$2C,$33,$39,$40,$46,$4C,$53,$59,$60
Code: Select all
; - - - - - - - - - - - - - - - - - - - - - - - - - - -
; 16-bit unsigned division by 40 routine
; TOS /= 40, A = remainder, Y = 0
;
div40:
lda #0 ; remainder
ldy #16 ; loop counter
div40b:
cmp #20 ; partial remainder >= 40 (/2)?
bcc div40c
sbc #20 ; yes: update partial
; remainder, set carry
div40c:
rol TOS ; TOS is gradually replaced
rol TOS+1 ; with the quotient
rol ; A is gradually replaced
; with the remainder
dey
bne div40b ; loop 16 times
rts