<sect1><tt/cc65.h/<label id="cc65.h"><p>
<itemize>
-<!-- <item><ref id="cc65_cos" name="cc65_cos"> -->
-<!-- <item><ref id="cc65_idiv32by16r16" name="cc65_idiv32by16r16"> -->
-<!-- <item><ref id="cc65_imul16x16r32" name="cc65_imul16x16r32"> -->
-<!-- <item><ref id="cc65_imul8x8r16" name="cc65_imul8x8r16"> -->
-<!-- <item><ref id="cc65_sin" name="cc65_sin"> -->
-<!-- <item><ref id="cc65_udiv32by16r16" name="cc65_udiv32by16r16"> -->
-<!-- <item><ref id="cc65_umul16x16r32" name="cc65_umul16x16r32"> -->
-<!-- <item><ref id="cc65_umul16x8r32" name="cc65_umul16x8r32"> -->
-<!-- <item><ref id="cc65_umul8x8r16" name="cc65_umul8x8r16"> -->
+
+<!-- <item><ref id="cos" name="cos"> -->
+<!-- <item><ref id="idiv32by16r16" name="idiv32by16r16"> -->
+<!-- <item><ref id="imul16x16r32" name="imul16x16r32"> -->
+<!-- <item><ref id="imul8x8r16" name="imul8x8r16"> -->
+<!-- <item><ref id="sin" name="sin"> -->
+<!-- <item><ref id="udiv32by16r16" name="udiv32by16r16"> -->
+<!-- <item><ref id="umul16x16r32" name="umul16x16r32"> -->
+<!-- <item><ref id="umul16x8r32" name="umul16x8r32"> -->
+<!-- <item><ref id="umul8x8r16" name="umul8x8r16"> -->
<item><ref id="doesclrscrafterexit" name="doesclrscrafterexit">
+<item><ref id="mul20" name="mul20">
+<item><ref id="mul40" name="mul40">
</itemize>
(incomplete)
<item><ref id="signal" name="signal">
</itemize>
-<sect1><tt/specialmath.h/<label id="specialmath.h"><p>
-
-<itemize>
-<item><ref id="_mul20" name="_mul20">
-<item><ref id="_mul40" name="_mul40">
-</itemize>
-
<sect1><tt/stdarg.h/<label id="stdarg.h"><p>
(incomplete)
</descrip>
</quote>
-<sect1>_mul20<label id="_mul20"><p>
-
-<quote>
-<descrip>
-<tag/Function/Multiplies argument by 20.
-<tag/Header/<tt/<ref id="specialmath.h" name="specialmath.h">/
-<tag/Declaration/<tt/unsigned int __fastcall__ _mul20(unsigned char value);/
-<tag/Description/Speed optimized function to multiply an 8 bit unsigned value by 20 to get a 16 bit result.
-<tag/Availability/cc65
-</descrip>
-</quote>
-
-<sect1>_mul40<label id="_mul40"><p>
-
-<quote>
-<descrip>
-<tag/Function/Multiplies argument by 40.
-<tag/Header/<tt/<ref id="specialmath.h" name="specialmath.h">/
-<tag/Declaration/<tt/unsigned int __fastcall__ _mul40(unsigned char value);/
-<tag/Description/Speed optimized function to multiply an 8 bit unsigned value by 40 to get a 16 bit result.
-<tag/Availability/cc65
-</descrip>
-</quote>
-
<sect1>_poserror<label id="_poserror"><p>
<quote>
</descrip>
</quote>
+<sect1>mul20<label id="mul20"><p>
+
+<quote>
+<descrip>
+<tag/Function/Multiplies argument by 20.
+<tag/Header/<tt/<ref id="cc65.h" name="cc65.h">/
+<tag/Declaration/<tt/unsigned int __fastcall__ mul20(unsigned char value);/
+<tag/Description/Speed optimized function to multiply an 8 bit unsigned value by 20 to get a 16 bit result.
+<tag/Availability/cc65
+</descrip>
+</quote>
+
+<sect1>mul40<label id="mul40"><p>
+
+<quote>
+<descrip>
+<tag/Function/Multiplies argument by 40.
+<tag/Header/<tt/<ref id="cc65.h" name="cc65.h">/
+<tag/Declaration/<tt/unsigned int __fastcall__ mul40(unsigned char value);/
+<tag/Description/Speed optimized function to multiply an 8 bit unsigned value by 40 to get a 16 bit result.
+<tag/Availability/cc65
+</descrip>
+</quote>
<sect1>offsetof<label id="offsetof"><p>
-long __fastcall__ cc65_idiv32by16r16 (long rhs, int lhs);
+long __fastcall__ idiv32by16r16 (long rhs, int lhs);
/* Divide a 32 bit signed value by a 16 bit signed value yielding a 16
** bit result and a 16 bit remainder. The former is returned in the lower 16
** bit of the result, the latter in the upper. If you don't need the
** remainder, just assign (or cast) to an int.
*/
-unsigned long __fastcall__ cc65_udiv32by16r16 (unsigned long rhs, unsigned lhs);
+unsigned long __fastcall__ udiv32by16r16 (unsigned long rhs, unsigned lhs);
/* Divide a 32 bit unsigned value by a 16 bit unsigned value yielding a 16
** bit result and a 16 bit remainder. The former is returned in the lower 16
** bit of the result, the latter in the upper. If you don't need the
** remainder, just assign (or cast) to an unsigned.
*/
-int __fastcall__ cc65_imul8x8r16 (signed char lhs, signed char rhs);
+int __fastcall__ imul8x8r16 (signed char lhs, signed char rhs);
/* Multiplicate two signed 8 bit to yield an signed 16 bit result */
-long __fastcall__ cc65_imul16x16r32 (int lhs, int rhs);
+long __fastcall__ imul16x16r32 (int lhs, int rhs);
/* Multiplicate two signed 16 bit to yield a signed 32 bit result */
-unsigned __fastcall__ cc65_umul8x8r16 (unsigned char lhs, unsigned char rhs);
+unsigned __fastcall__ umul8x8r16 (unsigned char lhs, unsigned char rhs);
/* Multiplicate two unsigned 8 bit to yield an unsigned 16 bit result */
-unsigned long __fastcall__ cc65_umul16x8r32 (unsigned lhs, unsigned char rhs);
+unsigned long __fastcall__ umul16x8r32 (unsigned lhs, unsigned char rhs);
/* Multiplicate an unsigned 16 bit by an unsigned 8 bit number yielding a 24
** bit unsigned result that is extended to 32 bits for easier handling from C.
*/
-unsigned long __fastcall__ cc65_umul16x16r32 (unsigned lhs, unsigned rhs);
+unsigned long __fastcall__ umul16x16r32 (unsigned lhs, unsigned rhs);
/* Multiplicate two unsigned 16 bit to yield an unsigned 32 bit result */
-int __fastcall__ cc65_sin (unsigned x);
+unsigned int __fastcall__ mul20(unsigned char value);
+/* Multiply an 8 bit unsigned value by 20 and return the 16 bit unsigned
+** result
+*/
+
+unsigned int __fastcall__ mul40(unsigned char value);
+/* Multiply an 8 bit unsigned value by 40 and return the 16 bit unsigned
+** result
+*/
+
+int __fastcall__ sin (unsigned x);
/* Return the sine of the argument, which must be in range 0..360. The result
** is in 8.8 fixed point format, which means that 1.0 = $100 and -1.0 = $FF00.
*/
-int __fastcall__ cc65_cos (unsigned x);
+int __fastcall__ cos (unsigned x);
/* Return the cosine of the argument, which must be in range 0..360. The result
** is in 8.8 fixed point format, which means that 1.0 = $100 and -1.0 = $FF00.
*/
+++ /dev/null
-/*****************************************************************************/
-/* */
-/* specialmath.h */
-/* */
-/* Optimized math routines for special usages */
-/* */
-/* */
-/* */
-/* (C) 2019 Christian 'Irgendwer' Krueger */
-/* */
-/* This software is provided 'as-is', without any expressed or implied */
-/* warranty. In no event will the authors be held liable for any damages */
-/* arising from the use of this software. */
-/* */
-/* Permission is granted to anyone to use this software for any purpose, */
-/* including commercial applications, and to alter it and redistribute it */
-/* freely, subject to the following restrictions: */
-/* */
-/* 1. The origin of this software must not be misrepresented; you must not */
-/* claim that you wrote the original software. If you use this software */
-/* in a product, an acknowledgment in the product documentation would be */
-/* appreciated but is not required. */
-/* 2. Altered source versions must be plainly marked as such, and must not */
-/* be misrepresented as being the original software. */
-/* 3. This notice may not be removed or altered from any source */
-/* distribution. */
-/* */
-/*****************************************************************************/
-
-#ifndef _SPECIALMATH_H
-#define _SPECIALMATH_H
-
-
-/* Multiply an 8 bit unsigned value by 20 and return the 16 bit unsigned result */
-
-unsigned int __fastcall__ _mul20(unsigned char value);
-
-
-/* Multiply an 8 bit unsigned value by 40 and return the 16 bit unsigned result */
-
-unsigned int __fastcall__ _mul40(unsigned char value);
-
-
-
-/* End of specialmath.h */
-#endif
.export _cputcxy, _cputc
.export plot, cputdirect, putchar
- .import gotoxy, __mul40
+ .import gotoxy, _mul40
.importzp tmp4,ptr4
.import _revflag,setcursor
sta (OLDADR),y
lda ROWCRS
- jsr __mul40 ; destroys tmp4, carry is cleared
+ jsr _mul40 ; destroys tmp4, carry is cleared
adc SAVMSC ; add start of screen memory
sta ptr4
txa
.export _mouse_txt_callbacks
.importzp tmp4
- .import __mul40
+ .import _mul40
.importzp mouse_txt_char ; screen code of mouse cursor
.include "atari.inc"
lsr a ; convert y position to character line
lsr a
lsr a
- jsr __mul40 ; carry is cleared by _mul40
+ jsr _mul40 ; carry is cleared by _mul40
adc SAVMSC
sta scrptr
txa
.include "atari.inc"
.importzp tmp1,tmp4,ptr1,ptr2
- .import __mul40,_clrscr
+ .import _mul40,_clrscr
.export __scroll
.proc __scroll
sta ptr2+1
lda tmp1
- jsr __mul40
+ jsr _mul40
sta tmp4
lda ptr2
sec
jmp _clrscr
;multiply by 40 (xsize)
-up_ok: jsr __mul40 ; carry is cleared by __mul40
+up_ok: jsr _mul40 ; carry is cleared by _mul40
adc SAVMSC ; add start of screen mem
sta ptr2
txa
; cursor handling, internal function
.include "atari.inc"
- .import cursor,__mul40
+ .import cursor,_mul40
.export setcursor
.proc setcursor
sta (OLDADR),y
lda ROWCRS
- jsr __mul40 ; function leaves with carry clear!
+ jsr _mul40 ; function leaves with carry clear!
adc SAVMSC ; add start of screen memory
sta OLDADR
txa
.export _cputcxy, _cputc
.export plot, cputdirect, putchar
- .import gotoxy, __mul20
+ .import gotoxy, _mul20
.importzp ptr4
.import setcursor
pha ; save char
lda ROWCRS_5200
- jsr __mul20 ; destroys tmp4, carry is cleared
+ jsr _mul20 ; destroys tmp4, carry is cleared
adc SAVMSC ; add start of screen memory
sta ptr4
txa
+++ /dev/null
-; mul20.s
-;
-; This file is part of
-; cc65 - a freeware C compiler for 6502 based systems
-;
-; https://github.com/cc65/cc65
-;
-; See "LICENSE" file for legal information.
-;
-;
-; unsigned int __fastcall__ _mul20(unsigned char value);
-;
-; REMARKS: Function is defined to return with carry-flag cleared
-
-
- .importzp tmp4
- .export __mul20
-
-.proc __mul20 ; = 30 bytes, 41/46 cycles
-
- sta tmp4 ; remember value for later addition...
- ldx #0 ; clear high-byte
- asl a ; * 2
- bcc mul4 ; high-byte affected?
- ldx #2 ; this will be the 1st high-bit soon...
-
-mul4: asl a ; * 4
- bcc mul5 ; high-byte affected?
- inx ; => yes, apply to 0 high-bit
- clc ; prepare addition
-
-mul5: adc tmp4 ; * 5
- bcc mul10 ; high-byte affected?
- inx ; yes, correct...
-
-mul10: stx tmp4 ; continue with classic shifting...
-
- asl a ; * 10
- rol tmp4
-
- asl a ; * 20
- rol tmp4
-
- ldx tmp4 ; deliver high-byte in X
- rts
-
-.endproc
+++ /dev/null
-; mul40.s
-;
-; This file is part of
-; cc65 - a freeware C compiler for 6502 based systems
-;
-; https://github.com/cc65/cc65
-;
-; See "LICENSE" file for legal information.
-;
-;
-; unsigned int __fastcall__ _mul40(unsigned char value);
-;
-; REMARKS: Function is defined to return with carry-flag cleared
-
-
- .importzp tmp4
- .export __mul40
-
-.proc __mul40 ; = 33 bytes, 48/53 cycles
-
- sta tmp4 ; remember value for later addition...
- ldx #0 ; clear high-byte
- asl a ; * 2
- bcc mul4 ; high-byte affected?
- ldx #2 ; this will be the 1st high-bit soon...
-
-mul4: asl a ; * 4
- bcc mul5 ; high-byte affected?
- inx ; => yes, apply to 0 high-bit
- clc ; prepare addition
-
-mul5: adc tmp4 ; * 5
- bcc mul10 ; high-byte affected?
- inx ; yes, correct...
-
-mul10: stx tmp4 ; continue with classic shifting...
-
- asl a ; * 10
- rol tmp4
-
- asl a ; * 20
- rol tmp4
-
- asl a ; * 40
- rol tmp4
-
- ldx tmp4 ; deliver high-byte in X
- rts
-
-.endproc
+++ /dev/null
-;
-; Ullrich von Bassewitz, 2009-11-04
-;
-; CC65 library: 32by16 => 16 signed division
-;
-
- .export _cc65_idiv32by16r16
- .import idiv32by16r16, incsp4
-
- .include "zeropage.inc"
-
-
-;---------------------------------------------------------------------------
-; 32by16 division.
-
-.proc _cc65_idiv32by16r16
-
- pha ; Save rhs
-
-; Copy from stack to zeropage. This assumes ptr1 and ptr2 are adjacent.
-
- ldy #3
-@L1: lda (sp),y
- sta ptr1,y
- dey
- bpl @L1
-
- lda #4
- clc
- adc sp
- sta sp
- bcc @L2
- inc sp+1
-
-@L2: pla ; Old rhs
- jmp idiv32by16r16
-
-.endproc
-
+++ /dev/null
-;
-; Ullrich von Bassewitz, 2010-11-03
-;
-; CC65 library: 16x16 => 32 signed multiplication
-;
-
- .export _cc65_imul16x16r32
- .import imul16x16r32, popax
-
- .include "zeropage.inc"
-
-
-;---------------------------------------------------------------------------
-; 16x16 => 32 signed multiplication routine.
-
-
-.proc _cc65_imul16x16r32
-
- sta ptr1
- stx ptr1+1
- jsr popax
- jmp imul16x16r32
-
-.endproc
-
+++ /dev/null
-;
-; 2014-03-27, Oliver Schmidt
-; 2014-05-08, Greg King
-;
-; CC65 library: 8x8 => 16 signed multiplication
-;
-
- .export _cc65_imul8x8r16
- .import imul8x8r16, popa, ptr1:zp
-
-
-;---------------------------------------------------------------------------
-; 8x8 => 16 signed multiplication routine.
-
-
-.proc _cc65_imul8x8r16
-
- sta ptr1
- jsr popa
- jmp imul8x8r16
-
-.endproc
+++ /dev/null
-;
-; Fixed point cosine/sine functions.
-;
-; int __fastcall__ cc65_sin (unsigned x);
-; int __fastcall__ cc65_cos (unsigned x);
-;
-; Returns the cosine/sine for the given argument as angular degree.
-; Valid argument range is 0..360 for both functions. They will return
-; garbage if the argument is not in a valid range. Result is in 8.8 fixed
-; point format, so $100 is 1.0 and $FF00 is -1.0.
-;
-;
-; Ullrich von Bassewitz, 2009-10-29
-;
-
- .export _cc65_cos, _cc65_sin
-
-
-; ---------------------------------------------------------------------------
-; Sinus table covering values from 0..86° as 0.8 fixed point values. Values
-; for 87..90° are actually 1.0 (= $100), will therefore not fit in the table
-; and are covered specially in the code below.
-
-.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
-
-
-
-; ---------------------------------------------------------------------------
-; Cosine function. Is actually implemented as cos(x) = sin(x+90)
-
-.code
-
-_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 _cc65_sin
-
- sbc #<360
- bcs @L3
- dex
-@L3: dex
-
-; ---------------------------------------------------------------------------
-; Sine function. Uses
-;
-; table lookup for 0..89°
-; sin(x) = sin(180-x) for 90°..179°
-; sin(x) = -sin(x-180) for 180..360°
-;
-; Plus special handling for the values missing in the table.
-
-_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
-
-
+++ /dev/null
-;
-; Ullrich von Bassewitz, 2009-11-04
-;
-; CC65 library: 32by16 => 16 unsigned division
-;
-
- .export _cc65_udiv32by16r16
- .import udiv32by16r16m, incsp4
-
- .include "zeropage.inc"
-
-
-;---------------------------------------------------------------------------
-; 32by16 division.
-
-.proc _cc65_udiv32by16r16
-
- sta ptr3
- stx ptr3+1 ; Store rhs
-
-; Copy from stack to zeropage. This assumes ptr1 and ptr2 are adjacent.
-
- ldy #3
-@L1: lda (sp),y
- sta ptr1,y
- dey
- bpl @L1
-
- lda #4
- clc
- adc sp
- sta sp
- bcc @L2
- inc sp+1
-
-@L2: jmp udiv32by16r16m
-
-.endproc
-
+++ /dev/null
-;
-; Ullrich von Bassewitz, 2010-11-03
-;
-; CC65 library: 16x16 => 32 unsigned multiplication
-;
-
- .export _cc65_umul16x16r32
- .import umul16x16r32, popax
-
- .include "zeropage.inc"
-
-
-;---------------------------------------------------------------------------
-; 16x16 => 32 unsigned multiplication routine.
-
-.proc _cc65_umul16x16r32
-
- sta ptr1
- stx ptr1+1
- jsr popax
- jmp umul16x16r32
-
-.endproc
-
-
+++ /dev/null
-;
-; Ullrich von Bassewitz, 2011-07-10
-;
-; CC65 library: 16x8 => 32 unsigned multiplication
-;
-
- .export _cc65_umul16x8r32
- .import umul8x16r24, popax
-
- .include "zeropage.inc"
-
-
-;---------------------------------------------------------------------------
-; 16x8 => 32 unsigned multiplication routine. We use 8x16 => 24 and clear
-; the high byte of the result
-
-.proc _cc65_umul16x8r32
-
- sta ptr1
- lda #0
- sta sreg+1 ; Clear high byte of result
- jsr popax
- jmp umul8x16r24
-
-.endproc
-
-
+++ /dev/null
-;
-; Oliver Schmidt, 2014-03-27
-;
-; CC65 library: 8x8 => 16 unsigned multiplication
-;
-
- .export _cc65_umul8x8r16
- .import umul8x8r16, popa, ptr1:zp
-
-
-;---------------------------------------------------------------------------
-; 8x8 => 16 unsigned multiplication routine.
-
-
-.proc _cc65_umul8x8r16
-
- sta ptr1
- jsr popa
- jmp umul8x8r16
-
-.endproc
--- /dev/null
+;
+; Ullrich von Bassewitz, 2009-11-04
+;
+; CC65 library: 32by16 => 16 signed division
+;
+
+ .export _idiv32by16r16
+ .import idiv32by16r16, incsp4
+
+ .include "zeropage.inc"
+
+
+;---------------------------------------------------------------------------
+; 32by16 division.
+
+.proc _idiv32by16r16
+
+ pha ; Save rhs
+
+; Copy from stack to zeropage. This assumes ptr1 and ptr2 are adjacent.
+
+ ldy #3
+@L1: lda (sp),y
+ sta ptr1,y
+ dey
+ bpl @L1
+
+ lda #4
+ clc
+ adc sp
+ sta sp
+ bcc @L2
+ inc sp+1
+
+@L2: pla ; Old rhs
+ jmp idiv32by16r16
+
+.endproc
+
--- /dev/null
+;
+; Ullrich von Bassewitz, 2010-11-03
+;
+; CC65 library: 16x16 => 32 signed multiplication
+;
+
+ .export _imul16x16r32
+ .import imul16x16r32, popax
+
+ .include "zeropage.inc"
+
+
+;---------------------------------------------------------------------------
+; 16x16 => 32 signed multiplication routine.
+
+
+.proc _imul16x16r32
+
+ sta ptr1
+ stx ptr1+1
+ jsr popax
+ jmp imul16x16r32
+
+.endproc
+
--- /dev/null
+;
+; 2014-03-27, Oliver Schmidt
+; 2014-05-08, Greg King
+;
+; CC65 library: 8x8 => 16 signed multiplication
+;
+
+ .export _imul8x8r16
+ .import imul8x8r16, popa, ptr1:zp
+
+
+;---------------------------------------------------------------------------
+; 8x8 => 16 signed multiplication routine.
+
+
+.proc _imul8x8r16
+
+ sta ptr1
+ jsr popa
+ jmp imul8x8r16
+
+.endproc
--- /dev/null
+; mul20.s
+;
+; This file is part of
+; cc65 - a freeware C compiler for 6502 based systems
+;
+; https://github.com/cc65/cc65
+;
+; See "LICENSE" file for legal information.
+;
+;
+; unsigned int __fastcall__ mul20(unsigned char value);
+;
+; REMARKS: Function is defined to return with carry-flag cleared
+
+
+ .importzp tmp4
+ .export _mul20
+
+.proc _mul20 ; = 30 bytes, 41/46 cycles
+
+ sta tmp4 ; remember value for later addition...
+ ldx #0 ; clear high-byte
+ asl a ; * 2
+ bcc mul4 ; high-byte affected?
+ ldx #2 ; this will be the 1st high-bit soon...
+
+mul4: asl a ; * 4
+ bcc mul5 ; high-byte affected?
+ inx ; => yes, apply to 0 high-bit
+ clc ; prepare addition
+
+mul5: adc tmp4 ; * 5
+ bcc mul10 ; high-byte affected?
+ inx ; yes, correct...
+
+mul10: stx tmp4 ; continue with classic shifting...
+
+ asl a ; * 10
+ rol tmp4
+
+ asl a ; * 20
+ rol tmp4
+
+ ldx tmp4 ; deliver high-byte in X
+ rts
+
+.endproc
--- /dev/null
+; mul40.s
+;
+; This file is part of
+; cc65 - a freeware C compiler for 6502 based systems
+;
+; https://github.com/cc65/cc65
+;
+; See "LICENSE" file for legal information.
+;
+;
+; unsigned int __fastcall__ mul40(unsigned char value);
+;
+; REMARKS: Function is defined to return with carry-flag cleared
+
+
+ .importzp tmp4
+ .export _mul40
+
+.proc _mul40 ; = 33 bytes, 48/53 cycles
+
+ sta tmp4 ; remember value for later addition...
+ ldx #0 ; clear high-byte
+ asl a ; * 2
+ bcc mul4 ; high-byte affected?
+ ldx #2 ; this will be the 1st high-bit soon...
+
+mul4: asl a ; * 4
+ bcc mul5 ; high-byte affected?
+ inx ; => yes, apply to 0 high-bit
+ clc ; prepare addition
+
+mul5: adc tmp4 ; * 5
+ bcc mul10 ; high-byte affected?
+ inx ; yes, correct...
+
+mul10: stx tmp4 ; continue with classic shifting...
+
+ asl a ; * 10
+ rol tmp4
+
+ asl a ; * 20
+ rol tmp4
+
+ asl a ; * 40
+ rol tmp4
+
+ ldx tmp4 ; deliver high-byte in X
+ rts
+
+.endproc
--- /dev/null
+;
+; Fixed point cosine/sine functions.
+;
+; int __fastcall__ cc65_sin (unsigned x);
+; int __fastcall__ cc65_cos (unsigned x);
+;
+; Returns the cosine/sine for the given argument as angular degree.
+; Valid argument range is 0..360 for both functions. They will return
+; garbage if the argument is not in a valid range. Result is in 8.8 fixed
+; point format, so $100 is 1.0 and $FF00 is -1.0.
+;
+;
+; Ullrich von Bassewitz, 2009-10-29
+;
+
+ .export _cos, _sin
+
+
+; ---------------------------------------------------------------------------
+; Sinus table covering values from 0..86° as 0.8 fixed point values. Values
+; for 87..90° are actually 1.0 (= $100), will therefore not fit in the table
+; and are covered specially in the code below.
+
+.rodata
+
+_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
+
+
+
+; ---------------------------------------------------------------------------
+; Cosine function. Is actually implemented as cos(x) = sin(x+90)
+
+.code
+
+_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 _sin
+
+ sbc #<360
+ bcs @L3
+ dex
+@L3: dex
+
+; ---------------------------------------------------------------------------
+; Sine function. Uses
+;
+; table lookup for 0..89°
+; sin(x) = sin(180-x) for 90°..179°
+; sin(x) = -sin(x-180) for 180..360°
+;
+; Plus special handling for the values missing in the table.
+
+_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 _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 _sintab,y
+ adc #1
+ bcc L7
+ inx
+L7: rts
+
+
--- /dev/null
+;
+; Ullrich von Bassewitz, 2009-11-04
+;
+; CC65 library: 32by16 => 16 unsigned division
+;
+
+ .export _udiv32by16r16
+ .import udiv32by16r16m, incsp4
+
+ .include "zeropage.inc"
+
+
+;---------------------------------------------------------------------------
+; 32by16 division.
+
+.proc _udiv32by16r16
+
+ sta ptr3
+ stx ptr3+1 ; Store rhs
+
+; Copy from stack to zeropage. This assumes ptr1 and ptr2 are adjacent.
+
+ ldy #3
+@L1: lda (sp),y
+ sta ptr1,y
+ dey
+ bpl @L1
+
+ lda #4
+ clc
+ adc sp
+ sta sp
+ bcc @L2
+ inc sp+1
+
+@L2: jmp udiv32by16r16m
+
+.endproc
+
--- /dev/null
+;
+; Ullrich von Bassewitz, 2010-11-03
+;
+; CC65 library: 16x16 => 32 unsigned multiplication
+;
+
+ .export _umul16x16r32
+ .import umul16x16r32, popax
+
+ .include "zeropage.inc"
+
+
+;---------------------------------------------------------------------------
+; 16x16 => 32 unsigned multiplication routine.
+
+.proc _umul16x16r32
+
+ sta ptr1
+ stx ptr1+1
+ jsr popax
+ jmp umul16x16r32
+
+.endproc
+
+
--- /dev/null
+;
+; Ullrich von Bassewitz, 2011-07-10
+;
+; CC65 library: 16x8 => 32 unsigned multiplication
+;
+
+ .export _umul16x8r32
+ .import umul8x16r24, popax
+
+ .include "zeropage.inc"
+
+
+;---------------------------------------------------------------------------
+; 16x8 => 32 unsigned multiplication routine. We use 8x16 => 24 and clear
+; the high byte of the result
+
+.proc _umul16x8r32
+
+ sta ptr1
+ lda #0
+ sta sreg+1 ; Clear high byte of result
+ jsr popax
+ jmp umul8x16r24
+
+.endproc
+
+
--- /dev/null
+;
+; Oliver Schmidt, 2014-03-27
+;
+; CC65 library: 8x8 => 16 unsigned multiplication
+;
+
+ .export _umul8x8r16
+ .import umul8x8r16, popa, ptr1:zp
+
+
+;---------------------------------------------------------------------------
+; 8x8 => 16 unsigned multiplication routine.
+
+
+.proc _umul8x8r16
+
+ sta ptr1
+ jsr popa
+ jmp umul8x8r16
+
+.endproc
}
/* Calculate the start coords */
- x1 = x + tgi_imulround (rx, cc65_cos (sa));
- y1 = y - tgi_imulround (ry, cc65_sin (sa));
+ x1 = x + tgi_imulround (rx, cos (sa));
+ y1 = y - tgi_imulround (ry, sin (sa));
do {
sa += inc;
if (sa >= ea) {
sa = ea;
done = 1;
}
- x2 = x + tgi_imulround (rx, cc65_cos (sa));
- y2 = y - tgi_imulround (ry, cc65_sin (sa));
+ x2 = x + tgi_imulround (rx, cos (sa));
+ y2 = y - tgi_imulround (ry, sin (sa));
tgi_line (x1, y1, x2, y2);
x1 = x2;
y1 = y2;
tgi_arc (x, y, rx, ry, sa, ea);
/* ... and close it */
- tgi_line (x, y, x + tgi_imulround (rx, cc65_cos (sa)), y - tgi_imulround (ry, cc65_sin (sa)));
- tgi_line (x, y, x + tgi_imulround (rx, cc65_cos (ea)), y - tgi_imulround (ry, cc65_sin (ea)));
+ tgi_line (x, y, x + tgi_imulround (rx, cos (sa)), y - tgi_imulround (ry, sin (sa)));
+ tgi_line (x, y, x + tgi_imulround (rx, cos (ea)), y - tgi_imulround (ry, sin (ea)));
}
-#include <specialmath.h>
+#include <cc65.h>
#include "unittest.h"
TEST
for (i=0; i < 256; ++i)
{
- ASSERT_AreEqual(i*20, _mul20(i), "%u", "Invalid 'mul20(%u)' calculation!" COMMA i);
+ ASSERT_AreEqual(i*20, mul20(i), "%u", "Invalid 'mul20(%u)' calculation!" COMMA i);
}
for (i=0; i < 256; ++i)
{
- ASSERT_AreEqual(i*40, _mul40(i), "%u", "Invalid 'mul40(%u)' calculation!" COMMA i);
+ ASSERT_AreEqual(i*40, mul40(i), "%u", "Invalid 'mul40(%u)' calculation!" COMMA i);
}
}
ENDTEST