mirror of
https://github.com/deater/dos33fsprogs.git
synced 2024-12-25 05:29:34 +00:00
130 lines
2.4 KiB
ArmAsm
130 lines
2.4 KiB
ArmAsm
|
; http://www.llx.com/~nparker/a2/mult.html
|
||
|
; MULTIPLY NUM1H:NUM1L * NUM2H:NUM2L
|
||
|
; NUM2 is zeroed out
|
||
|
; result is in RESULT3:RESULT2:RESULT1:RESULT0
|
||
|
|
||
|
;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:
|
||
|
|
||
|
lda #$0 ; 2
|
||
|
sta NEGATE ; 3
|
||
|
|
||
|
; Handle Signed
|
||
|
lda NUM1H ; 3
|
||
|
bpl check_num2 ; 2nt/3
|
||
|
;==============
|
||
|
; 10
|
||
|
|
||
|
inc NEGATE ; 3
|
||
|
|
||
|
clc ; 2s-complement NUM1H/NUM1L ; 2
|
||
|
lda NUM1L ; 3
|
||
|
eor #$ff ; 2
|
||
|
adc #$1 ; 2
|
||
|
sta NUM1L ; 3
|
||
|
|
||
|
lda NUM1H ; 3
|
||
|
eor #$ff ; 2
|
||
|
adc #$0 ; 2
|
||
|
sta NUM1H ; 3
|
||
|
;===========
|
||
|
; 25
|
||
|
check_num2:
|
||
|
lda NUM2H ; 3
|
||
|
bpl unsigned_multiply ; 2nt/3
|
||
|
;==============
|
||
|
; 6
|
||
|
|
||
|
inc NEGATE ; 3
|
||
|
|
||
|
clc ; 2
|
||
|
lda NUM2L ; 3
|
||
|
eor #$ff ; 2
|
||
|
adc #$1 ; 2
|
||
|
sta NUM2L ; 3
|
||
|
|
||
|
lda NUM2H ; 3
|
||
|
eor #$ff ; 2
|
||
|
adc #$0 ; 2
|
||
|
sta NUM2H ; 3
|
||
|
;=============
|
||
|
; 25
|
||
|
unsigned_multiply:
|
||
|
|
||
|
lda #0 ; Initialize RESULT to 0 ; 2
|
||
|
sta RESULT+2 ; 3
|
||
|
ldx #16 ; 16x16 multiply ; 2
|
||
|
;============
|
||
|
; 7
|
||
|
multiply_mainloop:
|
||
|
lsr NUM2H ; Shift right 16-bit NUM2 ; 5
|
||
|
ror NUM2L ; low bit goes into carry ; 5
|
||
|
bcc shift_output ; 0 or 1? ; 2nt/3
|
||
|
;============
|
||
|
; 13
|
||
|
|
||
|
tay ; If 1, add NUM1 (hi byte RESULT in A) ; 2
|
||
|
clc ; 2
|
||
|
lda NUM1L ; 3
|
||
|
adc RESULT+2 ; 3
|
||
|
sta RESULT+2 ; 3
|
||
|
tya ; 2
|
||
|
adc NUM1H ; 3
|
||
|
;============
|
||
|
; 18
|
||
|
shift_output:
|
||
|
ror A ; "Stairstep" shift ; 2
|
||
|
ror RESULT+2 ; 5
|
||
|
ror RESULT+1 ; 5
|
||
|
ror RESULT ; 5
|
||
|
dex ; 2
|
||
|
bne multiply_mainloop ; 2nt/3
|
||
|
;=============
|
||
|
; 22
|
||
|
|
||
|
sta RESULT+3 ; 3
|
||
|
|
||
|
;; Negate if necessary
|
||
|
|
||
|
lda NEGATE ; 3
|
||
|
and #$1 ; 2
|
||
|
beq positive ; 2nt/3
|
||
|
;==============
|
||
|
; 11
|
||
|
|
||
|
clc ; 2
|
||
|
lda RESULT+0 ; 3
|
||
|
eor #$ff ; 2
|
||
|
adc #$1 ; 2
|
||
|
sta RESULT+0 ; 3
|
||
|
|
||
|
lda RESULT+1 ; 3
|
||
|
eor #$ff ; 2
|
||
|
adc #$0 ; 2
|
||
|
sta RESULT+1 ; 3
|
||
|
|
||
|
lda RESULT+2 ; 3
|
||
|
eor #$ff ; 2
|
||
|
adc #$0 ; 2
|
||
|
sta RESULT+2 ; 3
|
||
|
|
||
|
lda RESULT+3 ; 3
|
||
|
eor #$ff ; 2
|
||
|
adc #$0 ; 2
|
||
|
sta RESULT+3 ; 3
|
||
|
;===========
|
||
|
; 42
|
||
|
positive:
|
||
|
|
||
|
rts ; 6
|
||
|
|