1
0
mirror of https://github.com/cc65/cc65.git synced 2024-07-22 12:29:06 +00:00
cc65/libsrc/common/cc65_sin.s

114 lines
2.2 KiB
ArmAsm
Raw Normal View History

;
; Fixed point sine function.
;
; Returns the cosine for the given argument as angular degree.
; Valid argument range is 0..360
;
;
; Ullrich von Bassewitz, 2009-10-29
;
.export _cc65_sin
.import _cc65_sintab
; ---------------------------------------------------------------------------
;
.code
.proc _cc65_sin
; If the high byte is non zero, argument is > 255
cpx #0
bne L3
cmp #180
bcs L4
; 0..179°
cmp #90
bcc L1
; 90..179°. Value is identical to sin(180-val). Carry is set on entry.
;
; 180-val := -val + 180.
; With
; -val := (val ^ $FF) + 1
; we get
; 180-val = (val ^ $FF) + 1 + 180
; Since carry is set, we can drop the "+ 1".
;
eor #$FF
adc #180 ; 180-val
; 0..89°. Values for 87..90° are actually 1.0. Since this format doesn't fit
; into the table, we have to check for it manually.
L1: cmp #87
bcc L2
; The value is 1.0
ldx #>(1 << 8)
lda #<(1 << 8)
rts
; 0..86°. Read the value from the table.
L2: tay
ldx #0
lda _cc65_sintab,y
rts
; 180..360°. sin(x) = -sin(x-180). Since the argument is in range 0..180
; after the subtraction, we don't need to handle the high byte.
L3: sec
L4: sbc #180
cmp #90
bcc L5
; 270..360°. Value is identical to -sin(180-val). Carry is set on entry.
;
; 180-val := -val + 180.
; With
; -val := (val ^ $FF) + 1
; we get
; 180-val = (val ^ $FF) + 1 + 180
; Since carry is set, we can drop the "+ 1".
;
eor #$FF
adc #180 ; 180-val
; 180..269°. Values for 267..269° are actually -1.0. Since this format doesn't
; fit into the table, we have to check for it manually.
L5: ldx #$FF
cmp #87
bcc L6
; The value is -1.0
lda #<(-1 << 8)
rts
; 180..266°. Read the value from the table. Carry is clear on entry.
L6: tay
txa ; A = $FF
eor _cc65_sintab,y
adc #1
bcc L7
inx
L7: rts
.endproc