;=============================================================================== ; SPLat Controls. ; ; Product Development Group ; ; Melbourne, AUSTRALIA ; ;=============================================================================== ;PURPOSE: ; A collection of utilities ; ;=============================================================================== ;=============================================================================== ; Copyright (c) 2021 SPLat Controls. All rights reserved. ; ; ; ; THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SPLat Controls. ; ; The copyright notice above does not evidence any ; ; actual or intended publication of such source code. ; ;=============================================================================== ;=============================================================================== ; ; ; ;=============================================================================== ;=============================================================================== ; ; ; ;=============================================================================== ;Compare result CMPkXeqY EQU 0 CMPkXgtY EQU 1 CMPkXltY EQU 2 ;=============================================================================== ; ; ;RAM storage ; ;=============================================================================== ;=============================================================================== ; ; ;I/O Assignments ; ;=============================================================================== ;=============================================================================== ; ;AUTOMATIC RAM ; ;=============================================================================== ; ; ; ; ; ; ;=============================================================================== ; ; ; ;=============================================================================== ;=============================================================================== ;DESCRIPTION: ; A helper the allows a subroutine to return using a goto, eg "GoIfXlt 3,Return" ;PARAMETERS: ; -> Nil ;RETURNS: ; <- Nil ;=============================================================================== Return: Return ;=============================================================================== ;DESCRIPTION: ; Calculates Q % W = W ;PARAMETERS: ; -> Q: number (clobbered) ; -> W: divisor ;RETURNS: ; <- W: result ;=============================================================================== fMod: QtoU 4 ;save WtoU 8 ;save GoSub fIntDiv UtoQ 8 ;get original W fMul UtoQ 4 fSub ;calc remainder Return ;=============================================================================== ;DESCRIPTION: ; Calculates (int)(Q / W) = W ;PARAMETERS: ; -> Q: number (clobbered) ; -> W: divisor ;RETURNS: ; <- W: result ;=============================================================================== fIntDiv: fDiv WtoU 0 ;temp save fAbs fLoadQ 0.5 fGoIfWgeQ _fIntDoAdj fLoadW 0.0 Return _fIntDoAdj UtoW 0 fGoIfNeg _fInfDoUnRound ;round down as.. fLoadQ -0.5 _fInfDoUnRound fAdd ;..fixToU will round up, thus U will contain the integer fixToU 0 floatFromU 0 Return ;=============================================================================== ;DESCRIPTION: ; This function rounds a number to the nearest whole divisor. For example: ; Parameters: ; w = 157 ; q = -20 ; Result: ; w = 160 ; q = -20 ; This is useful in the UI when changing from a small step size to a large step ; size because a button has been long held. It looks odd if a number sequence ; does this: ; 159, 158, 157, 137, 117, 97... ; better to do this: ; 159, 158, 157, 140, 120, 100... ;PARAMETERS: ; -> w:value ; -> q:step size ;RETURNS: ; <- w:rounded value ; <- q:unchanged ;=============================================================================== fIntRound: QtoU 4 ;save step fSwap fAbs ;remove sign confusion GoSub fIntDiv ;calc value/step removing decimal fWtoQ ;scale.. UtoW 4 fAbs fMul ;..back up UtoQ 4 ;restore step size Return ;=============================================================================== ;DESCRIPTION: ; Saves the NV pointers (uses UV registers) ;PARAMETERS: ; -> Nil ;RETURNS: ; <- Nil ;=============================================================================== NVSavePtrs: WtoU 7 ;save W NVfGetPtrW WtoU 0 NVPushRecLen PopU 4 NVPushRecNum PopU 5 NVPushPage PopU 6 UtoW 7 ;restore W Return ;=============================================================================== ;DESCRIPTION: ; Restores the NV pointers following a call to NVSavePtrs ;PARAMETERS: ; -> Nil ;RETURNS: ; <- Nil ;=============================================================================== NVRestorePtrs: WtoU 7 ;save W PushU 6 NVPopPage UtoW 0 NVfPutPtrW PushU 4 NVPopRecLen PushU 5 NVPopRecNum UtoW 7 ;restore W Return ;=============================================================================== ;DESCRIPTION: ; This routine is used to smooth a new reading. The equation is: ; SmoothedValue = NewReading * Smoothing + SmoothedValue * (1.0 - Smoothing) ; Usage: ; fMyVar defFLOAT ;filtered reading ; ; fAnIn 0 ;new reading in W ; fLoadQ 0.1 ;smoothing const ; LoadI fMyVar ; GoSub fFilter ;fMyVar contains old and new reading ;PARAMETERS: ; -> w: new reading ; -> q: smoothing constant (0.1 means use 1/10th of the new reading and 0.9 of ; existing smoothed value) ; -> i: smoothed variable float address ;RETURNS: ; <- Nil ;=============================================================================== fFilter: fMul ;calc part of new reading, FracNew = New * Smoothing WtoU 4 ;save fLoadW 1.0 fSwap fSub ;calc InvSmoothing = 1.0 - Smoothing GoSub ipfRecallQ ;read the current filter variable fMul ;calc FracFilter = Filter * InvSmoothing UtoQ 4 fAdd ;calc NewFilt = FracFilter + FracNew GoSub ipfStoreW ;write back to the filter variable Return ;=============================================================================== ;DESCRIPTION: ; This function fetches the floating point varaible from an address pointed to by ; i. This differs from ifRecallW which calculates the varaible address ; as: BaseAddr + i * 4. ;PARAMETERS: ; -> i: floating point varaible address ;RETURNS: ; <- W: floating point value ;=============================================================================== ipfRecallW: GoSub subifRecall ;place the varaible in u[0-3] UtoW 0 ;copy to W Return ;=============================================================================== ;DESCRIPTION: ; This function fetches the floating point varaible from an address pointed to by ; i. This differs from ifRecallW which calculates the varaible address ; as: BaseAddr + i * 4. ;PARAMETERS: ; -> i: floating point varaible address ;RETURNS: ; <- W: floating point value ;=============================================================================== ipfRecallQ: GoSub subifRecall ;place the varaible in u[0-3] UtoQ 0 ;copy to Q Return subifRecall iRecall 0 ;load the.. PopU 0 iRecall 1 PopU 1 iRecall 2 PopU 2 iRecall 3 PopU 3 Return ;=============================================================================== ;DESCRIPTION: ; This function stores the floating point varaible to an address pointed to by ; i. This differs from ifStore which calculates the varaible address ; as: BaseAddr + i * 4. ;PARAMETERS: ; -> i: floating point varaible address ; -> W: floating point value ;RETURNS: ; <- nil ;=============================================================================== ipfStoreW: WtoU 0 ;copy W to U Goto subipfStore ;place u[0-3] to the variable ;=============================================================================== ;DESCRIPTION: ; This function stores the floating point varaible to an address pointed to by ; i. This differs from ifStore which calculates the varaible address ; as: BaseAddr + i * 4. ;PARAMETERS: ; -> i: floating point varaible address ; -> W: floating point value ;RETURNS: ; <- nil ;=============================================================================== ipfStoreQ: QtoU 0 ;copy Q to U Goto subipfStore ;place u[0-3] to the variable subipfStore PushU 0 iStore 0 PushU 1 iStore 1 PushU 2 iStore 2 PushU 3 iStore 3 Return ;=============================================================================== ;DESCRIPTION: ; Calculates a polynomial of any order. The control table format is: ; NV0Byte N ;The order of the polynomial ; NV0fNum An ;The X^n coefficient ; NV0fNum An-1 ;The X^(n-1) coefficient ; .... ; NVfNum A1 ;The X coefficient ; NVfNum A0 ;The constant ; ; Example: ; The polynomial Y = 1.4 * x^4 - 1.3 * x^3 + 1.2 * x^2 - 1.1 * x + 1 ; is a 4th order polynomial. Its control table would be ;PolyTab: ; NV0Byte 4 ;Fourth order ; NV0fNum 1.4 ;Coefficient for x^4 ; NV0fNum -1.3 ;Coefficient for x^3 ; NV0fNum 1.2 ;Coefficient for x^2 ; NV0fNum -1.1 ;Coefficient for x^1 ; NV0fNum 1.0 ;Constant ;PARAMETERS: ; -> W The argument value (normally called X) ; -> NVEMPtr Control table address ;RETURNS: ; <- W the y result ;=============================================================================== PolyCalculate: WtoU 0 ;save argument NVSetpage 0 NVSetRecNum 0 NVSetRecLen 4 NVPushByte 0 ;get the order of the poly to X XtoI NVAddPtr 1 ;now points to first coefficient NVfReadW 0 ;get first coefficient _PolyCalcLoop NVAdvPtr ;ready for next time UtoQ 0 ;argument fMul NVfReadQ 0 ;get next coefficient fAdd DecI GoIfInz _PolyCalcLoop Return ;=============================================================================== ;DESCRIPTION: ; Convert a time in seconds to hours:minutes:seconds ;PARAMETERS: ; -> w:seconds ;RETURNS: ; <- u[12]:hours, u[13]:minutes, u[14]:seconds ;=============================================================================== subSecondsToHMS: ;--hours WtoU 16 ;temp save fWtoQ fLoadW 3600 ;calculate.. GoSub fIntDiv ;..hours fix PopU 12 ;put into u[12] fLoadQ 3600 fMul ;whole hours back to seconds UtoQ 16 fSub ;calc remaining min:sec subSecondsToMS: ;result in u[13]:minutes, u[14]:seconds ;--minutes WtoU 16 ;temp save fWtoQ fLoadW 60 ;calculate.. GoSub fIntDiv ;..minutes fix PopU 13 ;put into u[13] fLoadQ 60 fMul ;whole minutes back to seconds UtoQ 16 fSub ;calc remaining sec ;--seconds fix PopU 14 Return ;=============================================================================== ;DESCRIPTION: ; Converts a value from a signed 16-bit value to a signed floating point. ; Required because FloatMem16S seems to give the same results as FloatMem16U ;PARAMETERS: ; -> W: 16-bit value converted using FloatMem16S ;RETURNS: ; <- W: Converted value ;=============================================================================== ConvertFloatMem16S fGoIfNeg Return ; If already negative, we're good to go fLoadQ 32768.0 ; Are we over the negative value? fGoIfWltQ Return ; No, we're positive: Exit fLoadQ 65537.0 ; Yes: Subtract 10001 fSwap fSub Return ;=============================================================================== ;DESCRIPTION: ; Saves a Floating Point value in Q to the NVEM2 address in W ;PARAMETERS: ; -> W: NVEM2 address ; -> Q: Floating-point value to save ;RETURNS: ; <- W: Original value ;=============================================================================== SaveFloatToNVEM2 NVSetPage 2 NVSetRecLen 4 NVSetRecNum 0 NVfPutPtrW fSwap NVfWriteW 0 NVSetPage 0 Return ;=============================================================================== ;DESCRIPTION: ; Reads a Floating Point value from the NVEM2 address in W ;PARAMETERS: ; -> W: NVEM2 address ;RETURNS: ; <- W: Read value ;=============================================================================== ReadFloatFromNVEM2 NVSetPage 2 NVSetRecLen 4 NVSetRecNum 0 NVfPutPtrW NVfReadW 0 NVSetPage 0 Return ;=============================================================================== ;DESCRIPTION: ; Saves a Byte value in X to the NVEM2 address in W ;PARAMETERS: ; -> W: NVEM2 address ; -> X: Byte value to save ;RETURNS: ; <- None ;=============================================================================== SaveByteToNVEM2 NVSetPage 2 NVSetRecLen 1 NVSetRecNum 0 NVfPutPtrW NVPopByte 0 NVSetPage 0 Return ;=============================================================================== ;DESCRIPTION: ; Reads a Byte value from the NVEM2 address in W ;PARAMETERS: ; -> W: NVEM2 address ;RETURNS: ; <- X: Byte value Read ;=============================================================================== ReadByteFromNVEM2 NVSetPage 2 NVSetRecLen 1 NVSetRecNum 0 NVfPutPtrW NVPushByte 0 NVSetPage 0 Return ;=============================================================================== ;DESCRIPTION: ; Saves a Floating Point value in Q to the NVEM3 address in W ;PARAMETERS: ; -> W: NVEM3 address ; -> Q: Floating-point value to save ;RETURNS: ; <- W: Original value ;=============================================================================== SaveFloatToNVEM3 NVSetPage 3 NVSetRecLen 4 NVSetRecNum 0 NVfPutPtrW fSwap NVfWriteW 0 NVSetPage 0 Return ;=============================================================================== ;DESCRIPTION: ; Reads a Floating Point value from the NVEM3 address in W ;PARAMETERS: ; -> W: NVEM3 address ;RETURNS: ; <- W: Read value ;=============================================================================== ReadFloatFromNVEM3 NVSetPage 3 NVSetRecLen 4 NVSetRecNum 0 NVfPutPtrW NVfReadW 0 NVSetPage 0 Return ;=============================================================================== ;DESCRIPTION: ; Saves a Byte value in X to the NVEM3 address in W ;PARAMETERS: ; -> W: NVEM3 address ; -> X: Byte value to save ;RETURNS: ; <- None ;=============================================================================== SaveByteToNVEM3 NVSetPage 3 NVSetRecLen 1 NVSetRecNum 0 NVfPutPtrW NVPopByte 0 NVSetPage 0 Return ;=============================================================================== ;DESCRIPTION: ; Reads a Byte value from the NVEM3 address in W ;PARAMETERS: ; -> W: NVEM3 address ;RETURNS: ; <- X: Byte value Read ;=============================================================================== ReadByteFromNVEM3 NVSetPage 3 NVSetRecLen 1 NVSetRecNum 0 NVfPutPtrW NVPushByte 0 NVSetPage 0 Return ;=============================================================================== ; ; ; ;=============================================================================== ;=============================================================================== ; ; ; ;===============================================================================