]> git.sur5r.net Git - cc65/commitdiff
Optimized mul20 & mul40 and extracted to new library.
authorIrgendwerA8 <c.krueger.b@web.de>
Thu, 21 Mar 2019 14:59:45 +0000 (15:59 +0100)
committerOliver Schmidt <ol.sc@web.de>
Fri, 29 Mar 2019 21:53:04 +0000 (22:53 +0100)
14 files changed:
doc/index.sgml
doc/specialmath.sgml [new file with mode: 0644]
include/specialmath.h [new file with mode: 0644]
libsrc/Makefile
libsrc/atari/cputc.s
libsrc/atari/mcbtxtchar.s
libsrc/atari/mul40.s [deleted file]
libsrc/atari/scroll.s
libsrc/atari/setcursor.s
libsrc/atari5200/cputc.s
libsrc/atari5200/mul20.s [deleted file]
libsrc/specialmath/mul20.s [new file with mode: 0644]
libsrc/specialmath/mul40.s [new file with mode: 0644]
test/val/lib_specialmath_mulxx.c [new file with mode: 0644]

index aecfb7de992f9f12e30270f264f606983818a5bc..55e69f40f74a2441f032f7081e15ee51af305cc3 100644 (file)
@@ -97,6 +97,9 @@
   Describes Christian Kr&uuml;ger's macro package for writing self modifying
   assembler code.
 
   Describes Christian Kr&uuml;ger's macro package for writing self modifying
   assembler code.
 
+  <tag><htmlurl url="specialmath.html" name="specialmath.html"></tag>
+  Library for speed optimized math functions.  
+
   <tag><url name="6502 Binary Relocation Format document"
         url="http://www.6502.org/users/andre/o65/fileformat.html"></tag>
   Describes the o65 file format that is used for dynamically loadable modules
   <tag><url name="6502 Binary Relocation Format document"
         url="http://www.6502.org/users/andre/o65/fileformat.html"></tag>
   Describes the o65 file format that is used for dynamically loadable modules
diff --git a/doc/specialmath.sgml b/doc/specialmath.sgml
new file mode 100644 (file)
index 0000000..18de970
--- /dev/null
@@ -0,0 +1,38 @@
+<!doctype linuxdoc system>
+
+<article>
+<title>Special math functions
+<author>Christian Kr&uuml;ger
+
+<abstract>
+This library provides functions for speed optimized math operations.
+</abstract>
+
+<!-- Table of contents -->
+<toc>
+
+<!-- Begin the document -->
+
+<sect>Multiplication<p>
+
+When accessing screen memory often a multiplication of the vertical position is needed to calculate
+the target address. A quite common horizontal span for 8-bit systems is 20 or 40 bytes (beside e.g. 32 bytes, where the multiplication can be accomplished by shifting 5 times).
+
+<p>
+<tscreen><verb>
+    unsigned int __fastcall__ mul20(unsigned char value);
+</verb></tscreen>
+
+The 8 bit <tt>value</tt> is multiplied by 20 and returned as 16 bit value.
+</p>
+
+<p>
+<tscreen><verb>
+    unsigned int __fastcall__ mul40(unsigned char value);
+</verb></tscreen>
+
+The 8 bit <tt>value</tt> is multiplied by 40 and returned as 16 bit value.
+</p>
+
+
+</article>
diff --git a/include/specialmath.h b/include/specialmath.h
new file mode 100644 (file)
index 0000000..fa2f657
--- /dev/null
@@ -0,0 +1,46 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                              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
index 0ebec46b159a9d41d2990b33be6bed56552ee880..4e1a3520d992e880e25b9a03617d2f63342f24eb 100644 (file)
@@ -181,6 +181,7 @@ SRCDIRS += common   \
            mouse    \
            runtime  \
            serial   \
            mouse    \
            runtime  \
            serial   \
+           specialmath \
            tgi      \
            zlib
 
            tgi      \
            zlib
 
index 7132fdca613a69c0e238310aa1a1dc088ea1955c..cf66fdacf02af2f2c66852098f3181cf42b74828 100644 (file)
@@ -7,7 +7,7 @@
 
         .export         _cputcxy, _cputc
         .export         plot, cputdirect, putchar
 
         .export         _cputcxy, _cputc
         .export         plot, cputdirect, putchar
-        .import         gotoxy, mul40
+        .import         gotoxy, _mul40
         .importzp       tmp4,ptr4
         .import         _revflag,setcursor
 
         .importzp       tmp4,ptr4
         .import         _revflag,setcursor
 
@@ -71,8 +71,7 @@ putchar:
         sta     (OLDADR),y
 
         lda     ROWCRS
         sta     (OLDADR),y
 
         lda     ROWCRS
-        jsr     mul40           ; destroys tmp4
-        clc
+        jsr     _mul40          ; destroys tmp4, carry is cleared
         adc     SAVMSC          ; add start of screen memory
         sta     ptr4
         txa
         adc     SAVMSC          ; add start of screen memory
         sta     ptr4
         txa
index 90a25f673dc8b952a78935bff274e42178fb6a94..4ff79c651d9e0985bd4b1b9116d6e2a128934738 100644 (file)
@@ -12,7 +12,7 @@
 
         .export         _mouse_txt_callbacks
         .importzp       tmp4
 
         .export         _mouse_txt_callbacks
         .importzp       tmp4
-        .import         mul40,loc_tmp
+        .import         _mul40
         .importzp       mouse_txt_char          ; screen code of mouse cursor
 
         .include        "atari.inc"
         .importzp       mouse_txt_char          ; screen code of mouse cursor
 
         .include        "atari.inc"
@@ -104,22 +104,15 @@ movex:
 
 ; Move the mouse cursor y position to the value in A/X.
 movey:
 
 ; Move the mouse cursor y position to the value in A/X.
 movey:
-        tax
-        ldy     tmp4            ; mul40 uses tmp4
-        lda     loc_tmp         ; and this local variable
-        pha
-        txa                     ; get parameter back
+        ldy     tmp4            ; mul40 uses tmp4, save in Y
         lsr     a               ; convert y position to character line
         lsr     a
         lsr     a
         lsr     a               ; convert y position to character line
         lsr     a
         lsr     a
-        jsr     mul40
-        clc
+        jsr     _mul40          ; carry is cleared by _mul40
         adc     SAVMSC
         sta     scrptr
         txa
         adc     SAVMSC+1
         sta     scrptr+1
         adc     SAVMSC
         sta     scrptr
         txa
         adc     SAVMSC+1
         sta     scrptr+1
-        pla
-        sta     loc_tmp
-        sty     tmp4
+        sty     tmp4            ; restore tmp4
         rts
         rts
diff --git a/libsrc/atari/mul40.s b/libsrc/atari/mul40.s
deleted file mode 100644 (file)
index 96235bf..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-;
-; Christian Groessler, June 2000
-;
-; mul40
-; multiplies A by 40 and returns result in AX
-; uses tmp4
-
-        .importzp       tmp4
-        .export         mul40,loc_tmp
-
-.proc   mul40
-
-        ldx     #0
-        stx     tmp4
-        sta     loc_tmp
-        asl     a
-        rol     tmp4
-        asl     a
-        rol     tmp4            ; val * 4
-        adc     loc_tmp
-        bcc     L1
-        inc     tmp4            ; val * 5
-L1:     asl     a
-        rol     tmp4            ; val * 10
-        asl     a
-        rol     tmp4
-        asl     a
-        rol     tmp4            ; val * 40
-        ldx     tmp4
-        rts
-
-.endproc
-
-        .bss
-loc_tmp:.res    1
index 5e8428cc2146eab6cce7e879604afb15900f44ae..4bc0d72edc61a9404ea41e2b431b238b4047a030 100644 (file)
@@ -8,7 +8,7 @@
 
         .include        "atari.inc"
         .importzp       tmp1,tmp4,ptr1,ptr2
 
         .include        "atari.inc"
         .importzp       tmp1,tmp4,ptr1,ptr2
-        .import         mul40,_clrscr
+        .import         _mul40,_clrscr
         .export         __scroll
 
 .proc   __scroll
         .export         __scroll
 
 .proc   __scroll
@@ -40,7 +40,7 @@ down_ok:lda     SAVMSC
         sta     ptr2+1
 
         lda     tmp1
         sta     ptr2+1
 
         lda     tmp1
-        jsr     mul40
+        jsr     _mul40
         sta     tmp4
         lda     ptr2
         sec
         sta     tmp4
         lda     ptr2
         sec
@@ -103,8 +103,7 @@ up:     sta     tmp1            ; # of lines to scroll
         jmp     _clrscr
 
         ;multiply by 40 (xsize)
         jmp     _clrscr
 
         ;multiply by 40 (xsize)
-up_ok:  jsr     mul40
-        clc
+up_ok:  jsr     _mul40          ; carry is cleared by _mul40
         adc     SAVMSC          ; add start of screen mem
         sta     ptr2
         txa
         adc     SAVMSC          ; add start of screen mem
         sta     ptr2
         txa
index cf596d4fea238a3e928e2140975de3372bf833e9..c6d844047fa4ce176e414bb56ac8c40608118d30 100644 (file)
@@ -4,7 +4,7 @@
 ; cursor handling, internal function
 
         .include "atari.inc"
 ; cursor handling, internal function
 
         .include "atari.inc"
-        .import cursor,mul40
+        .import cursor,_mul40
         .export setcursor
 
 .proc   setcursor
         .export setcursor
 
 .proc   setcursor
@@ -14,8 +14,7 @@
         sta     (OLDADR),y
 
         lda     ROWCRS
         sta     (OLDADR),y
 
         lda     ROWCRS
-        jsr     mul40
-        clc
+        jsr     _mul40          ; function leaves with carry clear!
         adc     SAVMSC          ; add start of screen memory
         sta     OLDADR
         txa
         adc     SAVMSC          ; add start of screen memory
         sta     OLDADR
         txa
index 860eea88d253ce9ef9e0ac64a1f47153e8a2c940..185ad8da8ecb7fde1ce52818a3da55e9c2981f49 100644 (file)
@@ -10,7 +10,7 @@
 
         .export         _cputcxy, _cputc
         .export         plot, cputdirect, putchar
 
         .export         _cputcxy, _cputc
         .export         plot, cputdirect, putchar
-        .import         gotoxy, mul20
+        .import         gotoxy, _mul20
         .importzp       ptr4
         .import         setcursor
 
         .importzp       ptr4
         .import         setcursor
 
@@ -75,8 +75,7 @@ putchar:
         pha                     ; save char
 
         lda     ROWCRS_5200
         pha                     ; save char
 
         lda     ROWCRS_5200
-        jsr     mul20           ; destroys tmp4
-        clc
+        jsr     _mul20          ; destroys tmp4, carry is cleared
         adc     SAVMSC          ; add start of screen memory
         sta     ptr4
         txa
         adc     SAVMSC          ; add start of screen memory
         sta     ptr4
         txa
diff --git a/libsrc/atari5200/mul20.s b/libsrc/atari5200/mul20.s
deleted file mode 100644 (file)
index fc67b34..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-;
-; Christian Groessler, April 2014
-;
-; mul20
-; multiplies A by 20 and returns result in AX
-; uses tmp4
-
-        .importzp       tmp4
-        .export         mul20,loc_tmp
-
-.proc   mul20
-
-        ldx     #0
-        stx     tmp4
-        sta     loc_tmp
-        asl     a
-        rol     tmp4
-        asl     a
-        rol     tmp4            ; val * 4
-        adc     loc_tmp
-        bcc     L1
-        inc     tmp4            ; val * 5
-L1:     asl     a
-        rol     tmp4            ; val * 10
-        asl     a
-        rol     tmp4            ; val * 20
-        ldx     tmp4
-        rts
-
-.endproc
-
-        .bss
-loc_tmp:.res    1
diff --git a/libsrc/specialmath/mul20.s b/libsrc/specialmath/mul20.s
new file mode 100644 (file)
index 0000000..3339f7d
--- /dev/null
@@ -0,0 +1,47 @@
+; 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
diff --git a/libsrc/specialmath/mul40.s b/libsrc/specialmath/mul40.s
new file mode 100644 (file)
index 0000000..1103519
--- /dev/null
@@ -0,0 +1,50 @@
+; 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
diff --git a/test/val/lib_specialmath_mulxx.c b/test/val/lib_specialmath_mulxx.c
new file mode 100644 (file)
index 0000000..de7cc1e
--- /dev/null
@@ -0,0 +1,18 @@
+#include <specialmath.h>
+#include "unittest.h"
+
+TEST
+{
+    unsigned i;
+    
+    for (i=0; i < 256; ++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);
+    }
+}
+ENDTEST