dos33fsprogs/tfv/tfv_multiply.s

111 lines
2.0 KiB
ArmAsm
Raw Normal View History

2017-09-07 05:32:31 +00:00
; http://www.llx.com/~nparker/a2/mult.html
; MULTIPLY NUM1H:NUM1L * NUM2H:NUM2L
2017-09-07 05:40:00 +00:00
; NUM2 is zeroed out
; result is in RESULT3:RESULT2:RESULT1:RESULT0
2017-09-07 05:32:31 +00:00
NUM1L: .byte 0
NUM1H: .byte 0
NUM2L: .byte 0
NUM2H: .byte 0
RESULT: .byte 0,0,0,0
NEGATE: .byte 0
; If we have 2k to spare we should check out
; http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
multiply:
2017-11-23 04:50:43 +00:00
lda #$0 ; 2
sta NEGATE ; 4
2017-09-07 05:32:31 +00:00
; Handle Signed
2017-11-23 04:50:43 +00:00
lda NUM1H ; 4
bpl check_num2 ; 2nt/3
2017-09-07 05:32:31 +00:00
2017-11-23 04:50:43 +00:00
inc NEGATE ; 4
2017-09-07 05:32:31 +00:00
2017-11-23 04:50:43 +00:00
clc ; 2s-complement NUM1H/NUM1L ; 2
lda NUM1L ; 4
eor #$ff ; 2
adc #$1 ; 2
sta NUM1L ; 4
2017-09-07 05:32:31 +00:00
2017-11-23 04:50:43 +00:00
lda NUM1H ; 4
eor #$ff ; 2
adc #$0 ; 2
sta NUM1H ; 4
2017-09-07 05:32:31 +00:00
check_num2:
2017-11-23 04:50:43 +00:00
lda NUM2H ; 4
bpl unsigned_multiply ; 2nt/3
2017-09-07 05:32:31 +00:00
2017-11-23 04:50:43 +00:00
inc NEGATE ; 4
2017-09-07 05:32:31 +00:00
2017-11-23 04:50:43 +00:00
clc ; 2
lda NUM2L ; 4
eor #$ff ; 2
adc #$1 ; 2
sta NUM2L ; 4
2017-09-07 05:32:31 +00:00
2017-11-23 04:50:43 +00:00
lda NUM2H ; 4
eor #$ff ; 2
adc #$0 ; 2
sta NUM2H ; 4
2017-09-07 05:32:31 +00:00
unsigned_multiply:
2017-11-23 04:50:43 +00:00
lda #0 ; Initialize RESULT to 0 ; 2
sta RESULT+2 ; 4
ldx #16 ; 16x16 multiply ; 2
2017-09-07 05:32:31 +00:00
multiply_mainloop:
2017-11-23 04:50:43 +00:00
lsr NUM2H ; Shift right 16-bit NUM2 ; 6
ror NUM2L ; low bit goes into carry ; 6
bcc shift_output ; 0 or 1? ; 2nt/3
tay ; If 1, add NUM1 (hi byte RESULT in A) ; 2
clc ; 2
lda NUM1L ; 4
adc RESULT+2 ; 4
sta RESULT+2 ; 4
tya ; 2
adc NUM1H ; 4
2017-09-07 05:32:31 +00:00
shift_output:
2017-11-23 04:50:43 +00:00
ror A ; "Stairstep" shift ; 2
ror RESULT+2 ; 6
ror RESULT+1 ; 6
ror RESULT ; 6
dex ; 2
bne multiply_mainloop ; 2nt/3
sta RESULT+3 ; 4
2017-09-07 05:32:31 +00:00
;; Negate if necessary
2017-11-23 04:50:43 +00:00
lda NEGATE ; 4
and #$1 ; 2
beq positive ; 2nt/3
2017-09-07 05:32:31 +00:00
2017-11-23 04:50:43 +00:00
clc ; 2
lda RESULT+0 ; 4
eor #$ff ; 2
adc #$1 ; 2
sta RESULT+0 ; 4
2017-09-07 05:32:31 +00:00
2017-11-23 04:50:43 +00:00
lda RESULT+1 ; 4
eor #$ff ; 2
adc #$0 ; 2
sta RESULT+1 ; 4
2017-09-07 05:32:31 +00:00
2017-11-23 04:50:43 +00:00
lda RESULT+2 ; 4
eor #$ff ; 2
adc #$0 ; 2
sta RESULT+2 ; 4
2017-09-07 05:32:31 +00:00
2017-11-23 04:50:43 +00:00
lda RESULT+3 ; 4
eor #$ff ; 2
adc #$0 ; 2
sta RESULT+3 ; 4
2017-09-07 05:32:31 +00:00
positive:
2017-11-23 04:50:43 +00:00
rts ; 6
2017-09-07 05:32:31 +00:00