From: uz Date: Thu, 29 Oct 2009 23:19:00 +0000 (+0000) Subject: Added fixpoint sine and cosine functions. X-Git-Tag: V2.13.1~130 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=7d453f5e117b61a88403b5a52b3cd1012ace43fa;p=cc65 Added fixpoint sine and cosine functions. git-svn-id: svn://svn.cc65.org/cc65/trunk@4399 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/libsrc/common/Makefile b/libsrc/common/Makefile index df3c97277..e912795f7 100644 --- a/libsrc/common/Makefile +++ b/libsrc/common/Makefile @@ -99,6 +99,9 @@ S_OBJS = _cwd.o \ atexit.o \ atoi.o \ calloc.o \ + cc65_cos.o \ + cc65_sin.o \ + cc65_sintab.o \ chdir.o \ copydata.o \ creat.o \ diff --git a/libsrc/common/cc65_cos.s b/libsrc/common/cc65_cos.s new file mode 100644 index 000000000..06a59af35 --- /dev/null +++ b/libsrc/common/cc65_cos.s @@ -0,0 +1,48 @@ +; +; Fixed point cosine 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_cos + + .import _cc65_sin + + + +; --------------------------------------------------------------------------- +; + +.code + +.proc _cc65_cos + +; cos(x) = sin(x+90) + + clc + adc #90 + bcc L1 + inx + +; If x is now larger than 360, we need to subtract 360. + +L1: cpx #>360 + bne L2 + cmp #<360 +L2: bcc L4 + + sbc #<360 + bcs L3 + dex +L3: dex + +L4: jmp _cc65_sin + + +.endproc + + diff --git a/libsrc/common/cc65_sin.s b/libsrc/common/cc65_sin.s new file mode 100644 index 000000000..6d83086cf --- /dev/null +++ b/libsrc/common/cc65_sin.s @@ -0,0 +1,113 @@ +; +; 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 + + diff --git a/libsrc/common/cc65_sintab.s b/libsrc/common/cc65_sintab.s new file mode 100644 index 000000000..88464817a --- /dev/null +++ b/libsrc/common/cc65_sintab.s @@ -0,0 +1,24 @@ +; +; Sinus table +; +; Ullrich von Bassewitz, 2009-10-29 +; + + .export _cc65_sintab + + +; --------------------------------------------------------------------------- +; + +.rodata + +_cc65_sintab: + .byte $00, $04, $09, $0D, $12, $16, $1B, $1F, $24, $28 + .byte $2C, $31, $35, $3A, $3E, $42, $47, $4B, $4F, $53 + .byte $58, $5C, $60, $64, $68, $6C, $70, $74, $78, $7C + .byte $80, $84, $88, $8B, $8F, $93, $96, $9A, $9E, $A1 + .byte $A5, $A8, $AB, $AF, $B2, $B5, $B8, $BB, $BE, $C1 + .byte $C4, $C7, $CA, $CC, $CF, $D2, $D4, $D7, $D9, $DB + .byte $DE, $E0, $E2, $E4, $E6, $E8, $EA, $EC, $ED, $EF + .byte $F1, $F2, $F3, $F5, $F6, $F7, $F8, $F9, $FA, $FB + .byte $FC, $FD, $FE, $FE, $FF, $FF, $FF