From 94f12732ab1ca77982cfe2d06de70f44012bef88 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Fri, 27 Oct 2023 22:36:43 +0200 Subject: [PATCH] add math.diff() and math.diffw() --- compiler/res/prog8lib/math.p8 | 39 +++++++++++++++++++++++++++ compiler/res/prog8lib/virtual/math.p8 | 15 +++++++++++ docs/source/libraries.rst | 7 +++++ examples/test.p8 | 31 ++++++++++++++++++--- 4 files changed, 88 insertions(+), 4 deletions(-) diff --git a/compiler/res/prog8lib/math.p8 b/compiler/res/prog8lib/math.p8 index e90f66e68..9b01ebaa8 100644 --- a/compiler/res/prog8lib/math.p8 +++ b/compiler/res/prog8lib/math.p8 @@ -1,4 +1,6 @@ ; Internal Math library routines - always included by the compiler +; note: some functions you might expect here are builtin functions, +; such as abs, sqrt, clamp, min, max for example. math { %option no_symbol_prefixing @@ -445,4 +447,41 @@ log2_tab }} } + asmsub diff(ubyte v1 @A, ubyte v2 @Y) -> ubyte @A { + ; -- returns the (absolute) difference, or distance, between the two bytes + %asm {{ + sty P8ZP_SCRATCH_REG + sec + sbc P8ZP_SCRATCH_REG + bcs + + eor #255 + inc a ++ rts + }} + } + + asmsub diffw(uword w1 @R0, uword w2 @AY) -> uword @AY { + ; -- returns the (absolute) difference, or distance, between the two words + %asm {{ + sec + sbc cx16.r0L + sta cx16.r0L + tya + sbc cx16.r0H + sta cx16.r0H + bcs + + eor #255 + sta cx16.r0H + lda cx16.r0L + eor #255 + inc a + sta cx16.r0L + bne + + inc cx16.r0H ++ lda cx16.r0L + ldy cx16.r0H + rts + }} + } + } diff --git a/compiler/res/prog8lib/virtual/math.p8 b/compiler/res/prog8lib/virtual/math.p8 index 1e58632bb..a0f50c17b 100644 --- a/compiler/res/prog8lib/virtual/math.p8 +++ b/compiler/res/prog8lib/virtual/math.p8 @@ -1,4 +1,6 @@ ; Internal Math library routines - always included by the compiler +; note: some functions you might expect here are builtin functions, +; such as abs, sqrt, clamp, min, max for example. math { @@ -277,4 +279,17 @@ math { returnr.w r0 }} } + + sub diff(ubyte b1, ubyte b2) -> ubyte { + if b1>b2 + return b1-b2 + return b2-b1 + } + + sub diffw(uword w1, uword w2) -> uword { + if w1>w2 + return w1-w2 + return w2-w1 + } + } diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst index 1e41ab086..b20e54122 100644 --- a/docs/source/libraries.rst +++ b/docs/source/libraries.rst @@ -407,6 +407,13 @@ but perhaps the provided ones can be of service too. If you already know the quadrant and x/y deltas, calculate discrete direction between 0 and 23. This is a heavily optimized routine (small and fast). +``diff (ubyte b1, ubyte b2) -> ubyte`` + Returns the absolute difference, or distance, between the two byte values. + (This routine is more efficient than doing a compare and a subtract separately, or using abs) + +``diffw (uword w1, uword w2) -> uword`` + Returns the absolute difference, or distance, between the two word values. + (This routine is more efficient than doing a compare and a subtract separately, or using abs) cx16logo diff --git a/examples/test.p8 b/examples/test.p8 index 87c047047..b0c9ecfb4 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,14 +1,37 @@ %import textio +%import math %option no_sysinit %zeropage basicsafe main { sub start() { - byte @shared bb = -44 - uword uw = 8888 + (bb as ubyte) - txt.print_uw(uw) ; 9100 + ubyte ub1 = 12 + ubyte ub2 = 233 + + txt.print_ub(math.diff(ub1, ub2)) txt.nl() - txt.print_uw(8888 + (bb as ubyte)) ; 9100 + ub1 = 200 + ub2 = 90 + txt.print_ub(math.diff(ub1, ub2)) + txt.nl() + ub1 = 144 + ub2 = 144 + txt.print_ub(math.diff(ub1, ub2)) + txt.nl() + txt.nl() + + + uword uw1 = 1200 + uword uw2 = 40000 + txt.print_uw(math.diffw(uw1, uw2)) + txt.nl() + uw1 = 40000 + uw2 = 21000 + txt.print_uw(math.diffw(uw1, uw2)) + txt.nl() + uw1 = 30000 + uw2 = 30000 + txt.print_uw(math.diffw(uw1, uw2)) txt.nl() } }