;;########################################################################### ;; ;; FILE: atoIQN.asm ;; ;; TITLE: C Callable IQ Math Function ;; ;;########################################################################### ;; ;; Ver | Date | Who | Description of changes ;; =====|=============|=======|============================================== ;; 1.2 | 11 Oct 2001 | A. T. | Original Release. ;; -----|-------------|-------|---------------------------------------------- ;; 1.3 | 19 Nov 2001 | A. T. | No changes. ;; -----|-------------|-------|---------------------------------------------- ;; 1.4 | 17 May 2002 | A. T. | Fixed bug (thanks Settu) with input char ;; | | | range comparison. ;; -----|-------------|-------|---------------------------------------------- ;; | | | ;; ;;########################################################################### ;;=========================================================================== ;; Function: _atoIQN ;;=========================================================================== ;; ;; C Usage: extern long _atoIQN(const char *st, long q_value); ;; ;;--------------------------------------------------------------------------- ;; ;; On Entry: XAR4 = pointer to character string ;; ACC = q_value ;; ;; Regs Used: ACC, P, XT ;; XAR7, XAR6, XAR5 ;; ;; On Exit: ACC = IQ value from string (0 if an error occured) ;; ;; Q Range: 30 to 1 ;; ;;--------------------------------------------------------------------------- ;; Algorithm: The input string must only contain decimal characters ;; '0' to '9' and the characters '-' for negative value ;; if applicable and '.' character for delimiting integer and ;; fraction components. Some examples of valid inputs are: ;; ;; 12.23456 ;; -12.23456 ;; 0.2345 ;; 0.0 ;; 0 ;; 127 ;; -89 ;; ;; If the input string converts to a number greater then ;; the max/min values for the given Q value, then the returned ;; value will be limited to the min/max values. ;; ;; If the string contains illegal characters, it will return ;; the value zero. ;; ;;--------------------------------------------------------------------------- ;; Benchmark: ;; Cycles = Can be approximately from 200 to 800 cycles based on number ;; of characters in string. ;; ;;=========================================================================== ;;############################################################################# ;;! ;;! Copyright: Copyright (C) 2023 Texas Instruments Incorporated - ;;! All rights reserved not granted herein. ;;! Limited License. ;;! ;;! Texas Instruments Incorporated grants a world-wide, royalty-free, ;;! non-exclusive license under copyrights and patents it now or hereafter ;;! owns or controls to make, have made, use, import, offer to sell and sell ;;! ("Utilize") this software subject to the terms herein. With respect to the ;;! foregoing patent license, such license is granted solely to the extent that ;;! any such patent is necessary to Utilize the software alone. The patent ;;! license shall not apply to any combinations which include this software, ;;! other than combinations with devices manufactured by or for TI ;;! ("TI Devices"). ;;! No hardware patent is licensed hereunder. ;;! ;;! Redistributions must preserve existing copyright notices and reproduce this ;;! license (including the above copyright notice and the disclaimer and ;;! (if applicable) source code license limitations below) in the documentation ;;! and/or other materials provided with the distribution. ;;! ;;! Redistribution and use in binary form, without modification, are permitted ;;! provided that the following conditions are met: ;;! ;;! * No reverse engineering, decompilation, or disassembly of this software is ;;! permitted with respect to any software provided in binary form. ;;! * Any redistribution and use are licensed by TI for use only ;;! with TI Devices. ;;! * Nothing shall obligate TI to provide you with source code for the ;;! software licensed and provided to you in object code. ;;! ;;! If software source code is provided to you, modification and redistribution ;;! of the source code are permitted provided that the following conditions ;;! are met: ;;! ;;! * any redistribution and use of the source code, including any resulting ;;! derivative works, are licensed by TI for use only with TI Devices. ;;! * any redistribution and use of any object code compiled from the source ;;! code and any resulting derivative works, are licensed by TI for use ;;! only with TI Devices. ;;! ;;! Neither the name of Texas Instruments Incorporated nor the names of its ;;! suppliers may be used to endorse or promote products derived from this ;;! software without specific prior written permission. ;;############################################################################# .sect "IQmath" .def __atoIQN __atoIQN: NEG ACC ; ACC = - q_value ADDB ACC,#32 ; ACC = 32 - q_value MOV AH,@AL ; AH = 32 - q_value MOVL *SP++,ACC ; Save on stack ADDB SP,#8 CMP @AH,#31 ; Check to make sure that q_value range SB _atoIQerror,GT ; is 30 to 1 CMP @AH,#2 SB _atoIQerror,LT MOVB ACC,#0 MOVL *-SP[8],ACC ; I64l MOVL *-SP[6],ACC ; I64h, I64 = integer portion MOVL *-SP[4],ACC ; F64l MOVL *-SP[2],ACC ; F64h, F64 = fraction portion MOV AL,#0x999A MOV AH,#0x1999 MOVL XAR7,@ACC ; XAR7 = 0.1 * 2^32 = scale frac MOVB XAR6,#10 ; XAR6 = 10 = scale int ZAPA ; ACC, P = 0 CLRC TC ; TC = 0 = sign flag (default +ve) _atoIQloop: MOVZ AR0,*XAR4++ ; AR0 = char CMP @AR0,#0x00 SB _atoIQend,EQ ; Exit if zero (end of string) CMP @AR0,#'-' SB _atoIQneg,EQ ; Set sign flag if char == "-" CMP @AR0,#'.' SB _atoIQdot,EQ ; End of integer component if char == "." SUB @AR0,#'0' SB _atoIQerror,LT CMP @AR0,#9 SB _atoIQerror,GT ; Error if char not between "0".."9" MOVL XT,@XAR6 IMPYXUL P,XT,*-SP[8] ADDUL P,@XAR0 MOVL ACC,@P QMPYXUL P,XT,*-SP[8] MOVL *-SP[8],ACC IMPYL ACC,XT,*-SP[6] ADDCL ACC,@P MOVL *-SP[6],ACC ; I64 = I64*10 + char dec value SB _atoIQloop,UNC ;------------------------------------------------------------------------- ; Search for end of string and count frac characters: _atoIQdot: MOVB XAR5,#0 ; clear frac character counter _atoIQdotloop: INC @AR5 ; Increment character counter MOVZ AR0,*XAR4++ ; AR0 = char CMP @AR0,#0x00 SB _atoIQfrac,EQ ; Exit if end of string SUB @AR0,#'0' SB _atoIQerror,LT CMP @AR0,#9 SB _atoIQerror,GT ; Error if char not between "0".."9" SB _atoIQdotloop,UNC ;------------------------------------------------------------------------- _atoIQfrac: SUBB XAR4,#1 CMP @AR5,#10 SB _atoIQfracloop,LT SUBB XAR5,#10 MOVL ACC,@XAR4 SUBL ACC,@XAR5 MOVL @XAR4,ACC _atoIQfracloop: MOVZ AR0,*--XAR4 ; AR0 = char CMP @AR0,#'.' SB _atoIQend,EQ ; Exit if char == "." SUB @AR0,#'0' SB _atoIQerror,LT CMP @AR0,#9 SB _atoIQerror,GT ; Error if char not between "0".."9" MOVL ACC,*-SP[2] MOV AH,@AR0 MOVL *-SP[2],ACC MOVL XT,@XAR7 QMPYXUL P,XT,*-SP[4] IMPYL ACC,XT,*-SP[2] ADDUL P,@ACC MOVL *-SP[4],P MPYB P,T,#0 QMPYL ACC,XT,*-SP[2] ADDCL ACC,@P MOVL *-SP[2],ACC ; F64 = F64*0.1 + char dec value SB _atoIQfracloop,UNC ;------------------------------------------------------------------------- _atoIQneg: SB _atoIQerror,TC ; Error if more then one -ve sign detected SETC TC ; Set -ve sign value SB _atoIQloop,UNC ;------------------------------------------------------------------------- _atoIQerror: MOV AH,#0x0000 MOV AL,#0x0000 ; Return zero if error detected SUBB SP,#10 LRETR ;------------------------------------------------------------------------- _atoIQend: MOVL P,*-SP[4] MOVL ACC,*-SP[2] LSR64 ACC:P,#16 MOVL ACC,*-SP[8] ; ACC = int, P =frac MOVL XT,*-SP[10] ; T = 32 - q_value LSR64 ACC:P,T ; P = IQ value, ACC = overflow SB _atoIQendPos,NTC NEG64 ACC:P _atoIQendPos: ; Set saturation limits: MOV *-SP[8],#0xFFFF MOV *-SP[7],#0x7FFF MOV *-SP[6],#0x0000 MOV *-SP[5],#0x0000 MOV *-SP[4],#0x0000 MOV *-SP[3],#0x8000 MOV *-SP[2],#0xFFFF MOV *-SP[1],#0xFFFF ; Saturate result: MINL ACC,*-SP[6] MINCUL P,*-SP[8] MAXL ACC,*-SP[2] MAXCUL P,*-SP[4] ; Return value in ACC: MOVL ACC,@P SUBB SP,#10 LRETR ;;########################################################################### ;; No More. ;;###########################################################################