T exas Instruments (TI) reserves the right to make changes to its products or to discontinue any semiconductor
product or service without notice, and advises its customers to obtain the latest version of relevant information
to verify, before placing orders, that the information being relied on is current.
TI warrants performance of its semiconductor products and related software to the specifications applicable at
the time of sale in accordance with TI’s standard warranty. Testing and other quality control techniques are
utilized to the extent TI deems necessary to support this warranty. Specific testing of all parameters of each
device is not necessarily performed, except those mandated by government requirements.
Certain applications using semiconductor products may involve potential risks of death, personal injury, or
severe property or environmental damage (“Critical Applications”).
TI SEMICONDUCTOR PRODUCTS ARE NOT DESIGNED, INTENDED, AUTHORIZED, OR WARRANTED
TO BE SUITABLE FOR USE IN LIFE-SUPPORT APPLICATIONS, DEVICES OR SYSTEMS OR OTHER
CRITICAL APPLICATIONS.
Inclusion of TI products in such applications is understood to be fully at the risk of the customer. Use of TI
products in such applications requires the written approval of an appropriate TI officer . Questions concerning
potential risk applications should be directed to TI through a local SC sales office.
In order to minimize risks associated with the customer’s applications, adequate design and operating
safeguards should be provided by the customer to minimize inherent or procedural hazards.
TI assumes no liability for applications assistance, customer product design, software performance, or
infringement of patents or services described herein. Nor does TI warrant or represent that any license, either
express or implied, is granted under any patent right, copyright, mask work right, or other intellectual property
right of TI covering or relating to any combination, machine, or process in which such semiconductor products
or services might be or are used.
The TMS370 family consists of VLSI, 8-bit, CMOS microcontrollers with on-chip EEPROM storage and
peripheral support functions. These devices offer superior performance in complex, real-time control
applications in demanding environments. They are available with mask-programmable ROM and
EPROM.
Robust features in the TMS370 family of devices enhance performance and enable new application
technologies. These features include watchdog modes and low-power modes for mask-OM devices. All
family members share software compatibility, so you can run many existing applications on different
devices without having to modify the software.
This application book contains software routines, helpful hints, and other resources that will help you
take advantage of the many uses of the TMS370 family of microcontrollers. The software routines in this
book are available on the TI TMS370 Microcontroller BBS. The parameters are: 8 data, no parity, and
1 stop bit. If you have questions concerning the TMS370 family, please contact us at the following
numbers:
•T echnical Hotline: (713) 274-2370
•Bulletin Board:(713) 274-3700
•Fax:(713) 274–4203
Other info, including routines, will also be available on TI’s world wide web site:
Typical Applications
In expanding its powerful TMS370 family of microcontrollers, TI offers many configurable devices for
specific applications. As microcontrollers have evolved, TI has added multiple peripheral functions to
chips that originally had only a CPU, memory, and I/O blocks. Now, with the high-performance,
software-compatible TMS370 microcontrollers, you can choose from over 78 standard products.
Alternatively , you can use as many as 16 function modules to configure your new device quickly, easily,
and cost effectively for your application.
The TMS370 family of devices is the ideal choice for (but not limited to) the applications shown in
T able 1.
Table 1. Typical Applications for TMS370 Family Microcontroller Devices
http://www.ti.com/
Application AreaApplications
Climate control systems
Automotive
Computer
Industrial
Telecommunications
Cruise control
Entertainment systems
Instrumentation
Keyboards
Peripheral interface control
Motor control
Temperature controllers
Process control
Modems
Intelligent phones
Intelligent line card control
Navigational systems
Engine control
Antilock braking
Disk controllers
Terminals
Meter control
Medical instrumentation
Security systems
This example multiplies the 16-bit value in register pair R2, R3 by the value in register pair R4, R5. The
results are stored in R6, R7, R8, R9; registers A and B are altered.
Routine
********************************************************
* 16-BIT MPY: XH XL X VALUE
* X YH YL Y VALUE
* –––––––––––––––
* XLYLm XLYL1 1 = LSB
* XHYLm XHYL1 m = MSB
* XLYHm XLYH1
* + XHYHm XHYH1
* –––––––––––––––––––––––––––––––
* RSLT3 RSLT2 RSLT1 RSLT0
********************************************************
XH .EQU R2 ;Higher operand of X
XL .EQU R3 ;Lower operand of X
YH .EQU R4 ;Higher operand of Y
YL .EQU R5 ;Lower operand of Y
RSLT3 .EQU R6 ;MSbyte of the final result
RSLT2 .EQU R7
RSLT1 .EQU R8
RSLT0 .EQU R9 ;LSbyte of the final result
MPY32 CLR RSLT2 ;Clear the present value
CLR RSLT3
MPY XL,YL ;Multiply LSbytes
MOVW B,RSLT0 ;Store in result register 0
MPY XH,YL ;Get XHYL
ADD R1,RSLT1 ;Add to existing result XLYL
ADC R0,RSLT2 ;Add carry if present
ADC #0,RSLT3 ;Add if carry present
MPY XL,YH ;Multiply to get XLYH
ADD R1,RSLT1 ;Add to existing result XLYL+XHYL
ADC R0,RSLT2 ;Add to existing results and carry
ADC #0,RSLT3 ;Add if carry present
MPY XH,YH ;Multiply MSbytes
ADD R1,RSLT2 ;Add once again to the result register
ADC R0,RSLT3 ;Do the final add to the result reg
RTS ;Return to call subroutine
11
Binary Division
*14*
With the TMS370
Microcontroller Products—Semiconductor Group
Texas Instruments
13
Divide 16-Bit Number by 8-Bit Number
*
This routine divides a 16-bit number concatenated in R1:R2 by an 8-bit number in R3 to give a 16-bit
quotient and an 8-bit remainder as shown in Figure 1. This routine uses the DIV instruction (note that a DIV
10
function provides maximum values of 8-bits, 255
MSbyte is divided to find the quotient’s MSbyte; then the concatenated remainder and dividend LSbyte
are divided to find the quotient’s LSbyte.
Figure 1. Before and After Register Values for 16/8 Divide
BEFORE DIVISIONAFTER DIVISION
R1
R2
R3
= Dividend
= Divisor
Routine
.TEXT 7000h
;
FLAGS.EQU R7; Register location of FLAG bits
OVERFLOW .DBIT 0,FLAGS; Bit 0 of FLAGS register is OVERFLOW bit
;
;
; Register assignments:
; R1/R2 contain the dividend MSbyte/LSbyte
; R3 contains the divisor
; R4/R5 contain the quotient MSbyte/LSbyte after operation
; Register B holds the remainder after operation
;
;
;
DIVIDE8CLRA ; Clear MSbyte of registers A:B
OVERF SBIT2 OVERFLOW; Set overflow bot if overflow occurs
DIVR3,A ; Divide dividend MSbyte to getquotient MSbyte
JV OVERF ; Exit if overflow
MOV A,R4 ; Move MSbyte of quotient to storage.
MOV B,A ; Move remainder to MSbyte of registers A:B
MOV R2,B ; Move dividend LSbyte to reg. B
DIV R3,A ; Divide A:B to get quotient LSbyte and remainder
JV OVERF ; Exit if overflow
MOV A,R5 ; Store the quotient LSbyte next to MSbyte with
RTS ; remainder staying in B
;
RTS ;
, for both quotient and remainder). First, the dividend
R4R5
= Quotient
B
= Remainder
15
Divide 16-Bit Number by 16-Bit Number
*
This program divides a 16-bit dividend by a 16-bit divisor and produces a 16-bit quotient with a 16-bit
remainder. All numbers are unsigned positive integers and can range from 0 to FFFFh. The same principle
can be applied to larger or smaller divide routines to allow different-sized quotients, dividends, divisors,
and remainders. Registers used in the division can be visualized as shown in Figure 2.
Figure 2. Before and After Register Values for 16/16 Divide
BEFORE DIVISIONAFTER DIVISION
R2R3
R4R5
Routine
.TEXT 7000h
;
;
; Register assignments:
; R2/R3 contain the dividend MSbyte/LSbyte
; R4/R5 contain the divisor
; R2/R3 contain the quotient MSbyte/LSbyte after operation
; Registers A and B hold the remainder after operation
;
;
;
;
DIV16 MOV #16,R6 ; Set loop counter to 16 –– one for each
CLR A ; Initialize result register (MSbyte)
CLR B ; Initialize result register (LSbyte)
DIVLOP RLC R3 ; Multiply dividend by 2 (MSbyte)
RLC R2 ;
RLC B ; Shift dividend into A:B for comparison
RLC A ; to divisor
JNC SKIP1 ; Check for possible error condition that
SUB R5,B ; results when a 1 is shifted past the
SBB R4,A ; MSbyte,
SETC ; Correct by subtracting divisor and
JMPDIVEND ; If MSB=1, then subtract is possible
SKIP1 CMPR4,A ; Compare MSbytes of dividend and divisor
JNCDIVEND ; Jump if divisor is bigger
JNEMSBNE ; If not equal, jump
CMPR5,B ; If equal, compare LSbytes
JNCDIVEND ; Jump if divisor is bigger
MSBNE SUBR5,B ; If smaller, subtract divisor from
SBBR4,A ; dividend. Carry gets folded into next
DIVEND DJNZR6,DIVLOP ; Do next bit, is divide done?
RLCR3 ; Finish last rotate.
RLCR2 ;
= Dividend
= Divisor
R2R3
= Quotient
A
; quotient bit
; setting carry.
; rotate and gets doubled each time.
B
= Remainder
16
BCD-to-Binary Conversion
*18*
on the TMS370
Microcontroller Products—Semiconductor Group
Texas Instruments
17
BCD-to-Binary Conversion
*20*
This routine converts a four-digit BCD number to binary. The maximum BCD number is 9999 decimal.
Operands originate and are stored in general-purpose RAM. The BCD number is composed of the four
digits (D3, D2, D1, and D0) contained in the bytes DH and DL. The binary number is calculated by dividing
the number into powers of ten (Binary = D3 × 1000 + D2 × 100 + D1 × 10 + D0 × 1). Multiplying by 10
is easier if the number is further broken up into other numbers so that D2 × 10 = D2 × (8 + 2) = D2 × 8 +
D2 ×2. Likewise, multiplying by 1000 can be calculated by D3 ×(1000) = D3 ×(1024 – 24) = D3 × (1024
– (8 + 16)) = D3 ×1024 – (D3 × 8 + D3 ×16). This may seem complex, but it works quickly and uses few
bytes.
Routine
.TEXT 7000h
BH .EQU R2 ;Binary number MSbyte
BL .EQU R3 ;Binary number LSbyte
DH .EQU R4 ;Decimal number MSbyte
DL .EQU R5 ;Decimal number LSbyte
;D0=ones, D1=tens,
;D2=hundreds, D3=thousands
TOP CLR BH ;Clear out binary MSbyte
MOV DL,BL ;D0 to B0
AND #0Fh, BL ;Convert D0
;
MOV DL,A ;D1 × 10=D1 × 8+D1 ×2
AND #0F0h,A ;Isolate D1
MOV A,B ;B=D1 × 16
SWAP R1 ;B=D1
RR A ;A=D1 × 16/2=D1 × 8
RL B ;B=D1 × 2
ADD B,A ;A=D1 × 10 (D1 × 8+D1 ×2)
ADD R0,BL ;D1:D0 converted
;
MOV DH,B ;Get upper two digits
AND #0Fh,B ;Isolate D2
MPY #100,B ;R0:R1=D2 × 100
ADD R1,BL ;Add to current total
ADC R0,BH ;D2:D1:D0 converted
;
MOV DH,A ;Isolate D3
AND #0F0h,A ;A=D3 × 16
MOV A,B ;B=D3 × 16
RRC B ;B=D3 × 8
ADD B,A ;A=D3 × 24
SUB R0,BL ;BH:BL=BH:BL–24 × D3
SBB #0,BH ;
CLRC ;Setup for rotate
RRC B ;B=D3 × 4
ADD R1,BH ;BH:BL=BH:BL+D3 × 4 × 256
19
Binary-to-BCD Conversion
*22*
on the TMS370
Microcontroller Products—Semiconductor Group
Texas Instruments
21
Binary-to-BCD Conversion
*24*
This program converts a 16-bit binary word (0 to 65.535) to a packed six-nibble BCD value.
.TEXT 7000H ;Absolute start address
BN2BCD CLR A ;Prepare answer registers
CLR B ;
CLR R2 ;
MOV #16,R5 ;Move loop count to register
LOOP RLC R4 ;Shift higher binary bit out
RLC R3 ;Carry contains higher bit
DAC R2,R2 ;Double the number then add
;the binary bit
DAC R1,B ;Binary bit (a 1 in carry on
;the 1st time is
DAC R0,A ;doubled 16 times).
DJNZ R5,LOOP ;Do this 16 times, once for
;each bit
RTS ;Back to calling routine
23
BCD String Addition
*26*
With the TMS370
Microcontroller Products—Semiconductor Group
Texas Instruments
25
BCD String Addition
*28*
The following routine uses the addition instruction to add two multi-digit numbers together. Each number
is a packed BCD string of less than 256 bytes (512 digits), stored at memory locations STR1 and STR2.
This routine adds the two strings together and places the result in STR2. The strings must be stored with
the most significant byte in the lowest numbered register.
Table 1. Register Values and Functions
RegisterBeforeAfterFunction
AXX??Accumulator
BXX0Length of string
R2XX??Temporary save register
STR1BINARY MSbyteno changeBCD string
STR2BINARY LSbyteSTR1 + STR2Target string, 6 bytes max
Routine
;Decimal addition subroutine. Stack must have 3 available bytes.
;On output: STR2 = STR1 + STR2
STR1.EQU80E0h;Start of first string
STR2.EQU80F0h;Start of second string
ADDBCD CLRC;Clear carry bit
LOOPMOV*STR1–1[B],A ;Load current byte
.TEXT 7000h;Absolute start address
;and result
PUSHST;Save status to stack
MOVA,R2;Save it in R2
MOV*STR2–1[B],A ;Load next byte of STR2
POPST;Restore carry from last add
DACR2,A;Add decimal bytes
PUSHST;Save the carry from this add
MOVA,*STR2–1[B] ;Store result
DJNZB,LOOP;Loop until done
POPST;Restore stack to starting
;position
RTS;Back to calling routine
27
TMS370 Floating Point Package
*30*
Microcontroller Products—Semiconductor Group
Texas Instruments
29
Introduction
*
This report describes assembly language floating point math routines for the TMS370 family of
microcontrollers. Floating point operations allow binary processors to carry out decimal, signed arithmetic.
This package includes most of the common arithmetic and conversion routines used in floating point
operations. The routines included are:
•Floating point addition/subtraction
•Floating point number comparison
•Floating point division
•Floating point multiplication
•Floating point increment/decrement
•Floating point number test
•Floating point negation
•Floating point to signed 8-bit integer conversion
•Floating point to signed long (16-bit) integer conversion
•Floating point to unsigned 8-bit integer conversion
•Floating point to unsigned long (16-bit) integer conversion
•Signed 8-bit integer to floating point conversion
•Signed long (16-bit) integer to floating point conversion
•Unsigned long (16-bit) integer to floating point conversion
•Unsigned 8-bit integer to floating point conversion
31
Floating Point Format
*
Each number in this floating point format is 24 bits long. This includes eight bits for the exponent, fifteen
for the mantissa, and the remaining bits for the sign.
The format is as follows:
E E E E E E E E S M M M M M M M M M M M M M M M
The first byte is devoted to the exponent. The most significant bit of the second byte is the sign bit and the
remaining bits are the mantissa. This format has been chosen so that arithmetic on the objects are restricted
to normal 8-bit operation or a 16-bit operations.
With this format, a routine that operates on one of these floating point values can check the sign bit and
then set that bit as implied. A 16-bit operation can then be used to modify the value.
The exponent’s bias is 128: subtract 128 from the unsigned value of the eight exponential bits to find the
actual value of the exponent.
MAX_POS is the largest positive number the format can represent. MIN_POS is the smallest positive
number that can be represented. ZERO is a special case which is treated as true 0. EPSILON is the smallest
number which can be added to 1.0 and result in a sum which is not 1.0.
The actual value of a floating point number can be expressed as : s × M × 2
e-128
, where s is the sign of the
number –1 or 1, M is the value of the mantissa, and e is the bit value of the exponent.
A few more examples:
11 = 833000h–31.25 = 84FA00h
1 = 800000h–1 = 808000h
32
Floating Point Routines
*
Floating Point Addition/Subtraction
;Rev.1.0
;Function name - $fp_add,$fp_sub
;
;Purpose - 1) Perform the addition of two floating point numbers.
;
; OP1 + OP2
;
; 2) Perform the subtraction of two floating point
; numbers.
;
; OP1 - OP2
;
;
;Registers used - Register Before After
; ------------------------------------------------------; Status | XX | Modified
;
; R14 | OP1 exponent | Modified
; R15 | OP1 mantissa MSB | Modified
; R16 | OP1 mantissa LSB | Modified
;
; R17 | OP2 exponent | Result exponent
; R18 | OP2 mantissa MSB | Result mantissa MSB
; R19 | OP2 mantissa LSB | Result mantissa LSB
;
;Size 200 Bytes
;
;Stack space 4 Bytes
;
;Notes - 1) Some special considerations for floating point
; operations are:
;
; ZERO + OP2 = OP2
; OP1 + ZERO = OP1
;
; ZERO - OP2 = -OP2
; OP1 - ZERO = OP1
;
33
; 2) If an operation results in a sum or difference
*
; which is greater than MAX_POS, then it is overflow.
; The result placed in registers R17, R18, R19 will
; be MAX_POS.
;
; 3) If an operation results in a sum or difference
; which is less than MAX_NEG, then it is overflow. The
; result placed in registers R17, R18, R19
; will be MAX_NEG.
;
; 4) If an addition results in a sum with a magnitude too
; small to represent, then it is underflow. The result
; placed in registers R17, R18, R19 will be ZERO.
mov exp2,b ;Find the difference between
sub exp1,b ;exponents.
jc noswitch ;Jump if exp2 >= exp1.
switch push exp1 ;Switch operands to make OP2 > OP1.
push msb1
push lsb1
movw lsb2,lsb1
mov exp2,exp1
pop lsb2
pop msb2
pop exp2
compl b
noswitch
cmp #16,b ;Will the smaller number affect result?
jhs done2 ;No, we are done.
push a
jbit1 sign2,neg ;Determine which of four cases based on
jbit0 sign1,pospos ;sign.
posneg mov #02h,a ;Result positive, but set subtract flag.
jmp cont
neg jbit0 sign1,negpos
34
negneg mov #80h,a ;Eventual sign negative
*
jmp cont
negpos mov #82h,a ;Result negative, set subtract flag.
jmp cont
pospos clr a ;Eventual sign positive
cont or #80h,msb1 ;Set the implied one.
noshift jbit1 subflag,sub
add lsb1,lsb2 ;Add the mantissas.
adc msb1,msb2
jnc done ;If carry, adjust the mantissa and
rrc msb2 ;increment the exponent.
rrc lsb2
inc exp2
jz maxval ;If overflow occurs, return max value.
done and #7fh,msb2 ;Clear the implied one bit.
and #080h,a ;Clear the subtract flag.
or a,msb2 ;Set sign bit if appropriate.
pop a
done2 pop b
rts
sub sub lsb1,lsb2
sbb msb1,msb2
jc skp2 ;If borrow occurred, exp1=exp2,man1>man2,
xor #80h,a ;toggle the sign bit, and complement result
inv msb2
compl lsb2
adc #0,msb2
skp2 jn done ;Adjust the mantissa if implied one is not
;set.
jnz shift ;Check the MSB and LSB.
or #0h,lsb2
jz zero
shift dec exp2
jnc zero ;Underflow, return 0.
clrc
rlc lsb2
rlc msb2
jpz shift
jmp done
zero clr exp2 ;Special case for result = 0.
clr msb2
clr lsb2
pop a
pop b
rts
35
maxval mov #0ffh,exp2 ;Create maximum value.
*
movw #07fffh,lsb2
or a,msb2 ;Set sign bit as appropriate.
pop a
pop b
rts
36
Floating Point Number Comparison
*
;Rev.1.0
;Function name - $fp_cmp
;
;Purpose - Perform a comparison of two floating point numbers.
; The routine compares OP2 to OP1 and sets the status
; bits. The status result of this routine will be
; equivalent to an 8-bit integer cmp such as: CMP
; OP1,OP2.
;
;
;
;Registers used - Register Before After
; ------------------------------------------------------; Status | XX | Set on result
;
; R14 | OP1 exponent | OP1 exponent
; R15 | OP1 mantissa MSB | OP1 mantissa MSB
; R16 | OP1 mantissa LSB | OP1 mantissa LSB
;
; R17 | OP2 exponent | OP2 exponent
; R18 | OP2 mantissa MSB | Modified
; R19 | OP2 mantissa LSB | OP2 mantissa LSB
;
; The status register will be set according to the result
; of the compare:
;
; C = 0
; V = 0
; Z = 1, if OP1 is bit for bit the same as OP2,
; = 0, otherwise.
; N = 0, if OP2 is greater than or equal to OP1,
; = 1, otherwise.
;
$fp_cmp PUSH msb2 ;Check for different sign first.
*
XOR msb1,msb2
BTJZ #080h,msb2,SAMESIGN ;If MSB is 0, operands have same sign.
POP msb2 ;Operands have different sign. Test
JN NEG ;MSB2 to check sign. Make
;appropriate dummy move to set
JMP NONEG ;status.
RTS
SAMESIGN POP msb2 ;Restore MSB2
CMP exp1,exp2 ;OP1 > OP2 ?
JLO LESS
JNE GREATER
CMP msb1,msb2
JLO LESS
JNE GREATER
CMP lsb1,lsb2
JLO LESS
JEQ DONE
;Rev.1.0
;Function name - $fp_div
;
;Purpose - Perform the division of two floating point numbers
;
; OP1 / OP2
;
;Registers used - Register Before After
; ------------------------------------------------------; Status | XX | Modified
;
; R14 | OP1 exponent | Modified
; R15 | OP1 mantissa MSB | Modified
; R16 | OP1 mantissa LSB | Modified
;
; R17 | OP2 exponent | Result exponent
; R18 | OP2 mantissa MSB | Result mantissa MSB
; R19 | OP2 mantissa LSB | Result mantissa LSB
;
;Size 189 bytes
;
39
;Stack space 4 bytes
*
;
;
;Notes - 1) Some special considerations for floating point
; divide are:
;
; ZERO / OP2 = ZERO
; OP1 / ZERO = MAX_POS (if OP1 >= 0)
; MAX_NEG (if OP1 < 0)
;
; 2) If a division results in a quotient which is
; greater than MAX_POS, then it is overflow. The
; result placed in registers R17, R18, R19 will be
; MAX_POS.
;
; 3) If a division results in a quotient which is
; less than MAX_NEG, then it is overflow. The result
; placed in registers R17, R18, R19 will be MAX_NEG.
;
; 4) If a division results in a quotient with a
; magnitude too small to represent, then it is underflow.
; The result placed in registers R17, R18, R19
; will be ZERO.
$fp_div PUSH A ;Save registers
CHK_OP1 ;Check for OP1=ZERO.
MOV MAN1MSB,A ;Use FLAGS here as dummy register
OR EXP1,A ;OR all parts operand together.
OR MAN1LSB,A ;If ZERO, no bits will be ones.
JNZ CHK_OP2
CLR MAN2LSB ;OP1 is ZERO, so clear OP2 as answer.
CLR MAN2MSB ;Store results in OP2 registers.
CLR EXP2
POP A ;Restore registers to original
;values.
RTS ;Exit fp_div.
CHK_OP2 ;Check for OP2=ZERO.
MOV MAN2MSB,A ;Use FLAGS here as dummy register
OR EXP2,A ;OR all parts operand together.
OR MAN2LSB,A ;If ZERO, no bits will be ones.
JNZ FINDSIGN
MOV #0FFh,EXP2 ;Set result to MAX_POS or MAX_NEG
MOVW #07FFFh,MAN2LSB ;depending on the sign bit.
OR MAN1LSB,MAN2LSB
POP A ;Restore registers to original
;values.
RTS ;Exit fp_div.
40
FINDSIGN
*
PUSH B ;Save registers.
PUSH COUNTER
PUSH FLAGS
MOV MAN1MSB,FLAGS ;Find sign of quotient.
XOR MAN2MSB,FLAGS ;If sign flags differ, FLAGS 7=1.
AND #080h,FLAGS ;Clear other bits in FLAGS.
OR #080h,MAN1MSB ;Set implied 1 in sign bit position.
OR #080h,MAN2MSB ;
SUBEXP CLR B ;Clear B for result of exponent math.
SUB EXP2,EXP1 ;Subtract exponents.
ADC #0h,B ;Save status of carry bit from SUB.
MOV EXP1,EXP2 ;Move result of SUB to EXP2.
ADD #080h,EXP2 ;Correct for +128 offset.
ADC #0FFh,B ;Save status of carry bit and
JZ SETUP ;subtract 1 from SUB. Jump on result
JP CHK_OVER ;of exponent math:
; 01 = possible overflow
; 00 = ok
; FF = definite underflow
UNDERFLOW ;Result of division is underflow.
CLR MAN2LSB ;Store results in OP2 registers.
CLR MAN2MSB
CLR EXP2
POP FLAGS ;Restore registers to original
;values.
POP COUNTER
POP B
POP A
RTS ;Exit fp_div.
CHK_OVER ;Subtraction of exponents may have
BTJO #0FFh,EXP2,OVERFLOW ;overflowed. If exponent is not 00,
SBIT1 OVFL ;then result has definitely
;overflowed.
;If result may be ok, set flag.
SETUP MOV #16,COUNTER ;Set loop counter to 16, one for each
CLR A ;quotient bit, and initalize result
;registers (reg B was cleared above).
SKIP1 CMP MAN2MSB,MAN1MSB ;Compare MSBs of dividend and
;divisor.
JLO DIVEND ;Jump if divisor is bigger.
JNE MSBNE ;If equal, compare LSBs.
CMP MAN2LSB,MAN1LSB ;Compare LSBs.
JLO DIVEND ;Jump if divisor is bigger.
MSBNE SUB MAN2LSB,MAN1LSB ;If smaller, subtract divisor from
SBB MAN2MSB,MAN1MSB ;dividend. Carry is folded into
;next rotate and doubled each time.
41
DIVEND DJNZ COUNTER,DIVIDE ;Next bit. Is divide done?
*
RLC B ;Finish last rotate.
RLC A
JN DONE ;If MSB is not one, decrement EXP2
SUB #01h,EXP2 ;and go back up and shift one more
;time.
JNC UNDERFLOW ;If EXP2 was zero, decrement has
;caused an underflow.
SBIT0 OVFL ;Clear flag to show possible overflow
;condition has been corrected.
INC COUNTER ;Reset counter for 1 last loop
;through.
JMP LAST1
OVERFLOW ;Result of divide is overflow.
MOVW #07FFFh,MAN2LSB ;Store results in OP2 registers.
MOV #0FFh,EXP2
OR FLAGS,MAN2MSB ;Set sign bit of result.
POP FLAGS ;Restore registers to original
;values.
POP COUNTER
POP B
POP A
RTS ;Exit fp_div.
DIVIDE ;16 x 16 division routine.
RLC B ;Multiply divend by 2.
RLC A ;
LAST1 RLC MAN1LSB ;Shift dividend into MAN1MSB:MAN1LSB
RLC MAN1MSB ;for comparison to divisor.
JNC SKIP1 ;Check for possible error condition
SUB MAN2LSB,MAN1LSB ;that results when a 1 is shifted
;past the MSB.
SBB MAN2MSB,MAN1MSB ;Correct by subtracting
SETC ;divisor and setting carry.
JMP DIVEND
DONE BTJO #01h,FLAGS,OVERFLOW ;Make sure that divide sequence fixed
;previous exponent overflow.
OR #07Fh,FLAGS ;Set FLAGS bits except for sign bit.
AND FLAGS,A ;Set sign bit.
MOVW B,MAN2LSB ;Put answer in result register.
POP FLAGS ;Restore registers to original
;values.
POP COUNTER
POP B
POP A
RTS ;Exit fp_div.
42
Floating Point Multiplication
*
;Rev.1.0
;Function name - $fp_mul
;
;Purpose - Perform the multiplication of two floating point
; numbers.
;
; OP1 * OP2
;
;Registers used - Register Before After
; ------------------------------------------------------; Status | XX | Modified
;
; R14 | OP1 exponent | Modified
; R15 | OP1 mantissa MSB | Modified
; R16 | OP1 mantissa LSB | Modified
;
; R17 | OP2 exponent | Result exponent
; R18 | OP2 mantissa MSB | Result mantissa MSB
; R19 | OP2 mantissa LSB | Result mantissa LSB
;
;Size 189 Bytes
;
;Stack space 4 Bytes
;
;Notes - 1) Some special considerations for floating point
; multiplication are:
;
; ZERO * OP2 = ZERO
; OP1 * ZERO = ZERO
;
; 2) If a multiplication results in a product which is
; greater than MAX_POS, then it is overflow. The result
; placed in registers R17, R18, R19 will be MAX_POS.
;
; 3) If a multiplication results in a product which is
; less than MAX_NEG, then it is overflow. The result
; placed in registers R17, R18, R19 will be MAX_NEG.
;
; 4) If a multiplication results in a product with a
; magnitude too small to represent, then it is underflow.
; The result placed in registers R17, R18, R19
; will be ZERO.
$fp_mul ;Check for OP1=ZERO.
BTJO #0FFh,EXP2,CHK_OP2
BTJO #0FFh,MAN1LSB,CHK_OP2
BTJO #0FFh,MAN1MSB,CHK_OP2
CLR MAN2LSB ;OP1 is ZERO, so clear OP2 as answer.
CLR MAN2MSB
CLR EXP2
RTS ;Exit fp_mul
CHK_OP2 ;Check for OP2=ZERO
BTJO #0FFh,EXP2,FINDSIGN
BTJO #0FFh,MAN2LSB,FINDSIGN
BTJO #0FFh,MAN2MSB,FINDSIGN
RTS ;OP2 is ZERO, so done. Exit fp_mul.
FINDSIGN
PUSH R0 ;Save values of registers used.
PUSH RSLT1
PUSH FLAGS
MOV MAN1MSB,FLAGS ;Find sign of product.
XOR MAN2MSB,FLAGS ;If sign flags differ, FLAGS 7=1.
AND #080h,FLAGS ;Clear other bits in FLAGS.
OR #080h,MAN1MSB ;Set implied 1 in sign bit position.
OR #080h,MAN2MSB
ADDEXP
CLR R0 ;Clear A for result of exponent math.
ADD EXP1,EXP2 ;Add exponents.
ADC #0h,A ;Save status of carry bit from ADD.
SUB #080h,EXP2 ;Correct for +128 offset.
ADC #0FFh,A ;Save status of carry bit and
;subtract 1 from SUB.
JZ MULTIPLY ;Jump according to
;result of exponent math:
JN CHK_UNDER ; FF = underflow
; 00 = ok
; 01 = definite overflow
OVERFLOW ;Result of multiplication is
;overflow.
MOVW #07FFFh,MAN2LSB ;Store results in OP2 registers.
MOV #0FFh,EXP2
OR FLAGS,MAN2MSB ;Set sign bit of result.
POP FLAGS ;Restore registers to original
;values.
POP RSLT1
POP R0
RTS ;Exit fp_mul
UNDERFLOW ;Result of multiplication is
;underflow.
CLR MAN2LSB ;Store results in OP2 registers.
CLR MAN2MSB
CLR EXP2
POP FLAGS ;Restore registers to original
;values.
POP RSLT1
POP R0
RTS ;Exit fp_mul
44
CHK_UNDER ;Addition of exponents has
*
;underflowed.
BTJZ #0FFh,EXP2,UNDERFLOW ;If exponent is not FF, then the
;exponent has definitely
;underflowed.
SBIT1 UNDER_BIT ;Set bit to indicate that an
;underflow is possible if not
;corrected at end of multiplication
;routine.
MULTIPLY
PUSH R1 ;Save value of B register.
MPY MAN1LSB,MAN2LSB ;Start multiplying.
MOV A,RSLT1
MPY MAN1MSB,MAN2LSB
CLR MAN2LSB ;MAN2LSB = LSB of mantissa product.
ADD R1,RSLT1
ADC R0,MAN2LSB
MPY MAN1LSB,MAN2MSB
CLR MAN1LSB ;Since MAN1LSB is not needed anymore,
;use it as temporary storage during
;the multiplication process.
ADD R1,RSLT1
ADC R0,MAN2LSB
ADC #0,MAN1LSB
MPY MAN1MSB,MAN2MSB
ADD R1,MAN2LSB
ADC R0,MAN1LSB
POP R1 ;Restore value of B register.
DONE_MULT
JBIT0 IMPLIED_ONE,JUSTIFY ;If result has no implied one, need
;to justify result.
BTJZ #0FFh,EXP2,INCEXP ;If exponent is not FFh, then
;increment will not cause
JMP OVERFLOW ;overflow.
JUSTIFY JBIT1 UNDER_BIT,UNDERFLOW ;Previous underflow will not be
;corrected, so result is underflow.
RL RSLT1 ;Justify result to add implied one.
RLC MAN2LSB
RLC MAN1LSB
DEC EXP2 ;Value of exponent does not need to
;be changed, so decrement here to
;make up for next INC instruction.
INCEXP INC EXP2
SET_RESULTS ;Result of multiplication is in
;range.
MOV MAN1LSB,MAN2MSB ;Store results in OP2 registers.
OR #07Fh,FLAGS ;Set FLAGS bits except for sign bit.
AND FLAGS,MAN2MSB ;Set sign bit. LSB is in correct
;place from multiply routine.
POP FLAGS ;Restore registers to original
;values.
POP RSLT1
POP R0
RTS ;Exit fp_mul
45
Floating Point Increment / Decrement
*
;Rev.1.0
;Function name - $fp_inc,$fp_dec
;
;Purpose - 1) Increment a floating point number,
; i.e. add a 1.0 to it.
;
; OP1 + 1.0
;
; 2) Decrement a floating point number,
; i.e. subtract 1.0 from it.
;
; OP1 - 1.0
;
;Registers used - Register Before After
; ------------------------------------------------------; Status | XX | Modified
;
; R17 | OP1 exponent | Result exponent
; R18 | OP1 mantissa MSB | Result mantissa MSB
; R19 | OP1 mantissa LSB | Result mantissa LSB
;
;Size 180 Bytes
;
;Stack space 4 Bytes
;
;Notes - 1) Incrementing or decrementing a number with an
; exponent greater than or equal to 90 will have no
; effect.
;
; 2) Incrementing or decrementing a number with an
; exponent less than or equal to 71 will have no
; effect.
;
msb2 .equ r15
lsb2 .equ r16
exp1 .equ r17
msb1 .equ r18
lsb1 .equ r19
sign .dbit 7,r0 ;Flag to indicate whether to add or
;subtract numbers as a result of
;math.
$fp_dec .text 7000h ;Entry point for decrement.
push a ;Save A register.
mov #80h,a ;Complement the sign bit and set all
xor msb1,a ;other bits of msb1=1.
or #07fh,a ;
sbit0 decflag ;Set flag to indicate decrement op.
jmp $1
46
$fp_inc ;Entry point for increment.
*
push a ;Save A register.
mov msb1,a ;Move msb1 to A register and set every
or #07fh,a ;bit except sign bit.
$1 cmp #90h,exp1 ;Check to see if 1.0 is insignificant
jhs done ;compared with size of OP1. Exit if
;OP1 will not change.
cmp #71h,exp1 ;Check to see if OP1 is insignificant
jhs size_ok ;compared with 1.0.
mov #80h,exp1 ;If so, result=1.0 or -1.0.
clr lsb1
jbit0 decflag,$5 ;Is it a decrement operation?
clr msb1 ;No, set result to 1.0.
jmp done ;
$5 mov #080h,msb1 ;Yes, set result to -1.0.
done pop a
rts
size_ok push b ;Save registers that will be modified.
push msb2
push lsb2
or #80h,msb1 ;Set the implied one.
mov exp1,b ;Calculate number of spaces needed to
sub #80h,b ;shift number to align mantissas.
jc greater ;If exp1>#80h then OP1>1.0: adjust
;OP2.
compl b ;Take absolute value of exponent diff.
mov #80h,exp1 ;Set the exponent.
loop clrc
rrc msb1 ;Adjust OP1 so that it has the same
rrc lsb1 ;exponent as OP2. This is necessary
djnz b,loop ;for the two numbers to be added.
btjo #80h,a,subt ;Choose whether you need to add or
;subtract numbers based on sign of
;numbers and whether you are
;incrementing or decrementing.
add #80h,msb1 ;Need to add numbers. Add one to OP1.
done2 jbit1 decflag,$4 ;If a decrement is in progress,
xor #80h,a ;flip the sign of the result.
sbit1 decflag
$4 and a,msb1 ;Set the sign bit according to the
;result.
done3 pop lsb2 ;Restore registers and exit.
pop msb2
pop a
pop b
rts
subt sbit0 sign ;The result is positive. (OP1 is less
sub #80h,msb1 ;than 1.0) The operands have already
inv msb1 ;been aligned to have the same
compl lsb1 ;exponent. Subtract 1 from OP1 and
adc #0,msb1 ;invert the MSB and complement the LSB
;to get the absolute value.
47
adjust dec exp1 ;Shift the mantissa and adjust the
*
clrc ;exponent until an implied one is set.
rlc lsb1
rlc msb1
jpz adjust
jmp done2
greater clr lsb2 ;OP1 is greater than 1. Shift 1 so it
clr msb2 ;has the same exponent as OP1. If the
cmp #07h,b ;exponents differ by < 7, then only
;MSB is affected. Otherwise, implied
jle msb_only ;one will roll on into LSB.
sub #07h,b ;Calculate number of shifts needed.
setc ;Since implied 1 will roll all the
$2 rrc lsb2 ;way through the MSB, go ahead and
djnz b,$2 ;subtract 7 from number of shifts
jmp calc ;needed and start with LSB.
msb_only inc b ;Adjust to 1 needs less than 7 shifts,
setc ;so only the MSB will be affected.
$3 rrc msb2
djnz b,$3
calc btjo #80h,a,subtr ;If the sign flag is negative,operands
;actually need to be subtracted.
add lsb2,lsb1 ;Sign flag is positive, so add
;OP1+1.0.
adc msb2,msb1
chkadj jnc done2 ;If carry occurs, need to roll back
rrc msb1 ;mantissa and increment exponent.
rrc lsb1
inc exp1
jmp done2
subtr sub lsb2,lsb1 ;Subtract mantissa2 - mantissa1.
sbb msb2,msb1
jn done2 ;Implied 1 is present. Do not adjust.
jnz adjust ;If MSBs are not equal, adjust.
or #0h,lsb1 ;MSBs are equal, check to see if
jnz adjust ;LSBs are equal. If not, adjust.
clr exp1 ;Mantissas are zero, so it is a
jmp done3 ;floating point zero.
48
Floating Point Number T est
*
;Rev.1.0
;Function name - $fp_tst
;
;Purpose - Perform a test of the floating point number, similar
; to the hardware TST instruction for the A and B
; registers.
;
;Registers used - Register Before After
; ------------------------------------------------------; Status | XX | Set on result
;
; R17 | OP1 exponent | OP1 exponent
; R18 | OP1 mantissa MSB | Modified
; R19 | OP1 mantissa LSB | OP1 mantissa LSB
;
;Size 22 bytes
;
;Stack space None
;
;Notes - 1) The output will be the new contents of the status
; bits C, N, Z, and V.
;
; C = 0.
; V = 0.
; N = sign bit of the floating point number.
; Z = 1, if the floating point number is ZERO.
; = 0, otherwise.
;
; 2) This routine is the same as a call to $fp_cmp,
; with OP1 = ZERO and OP2 = the number to test.
exp1 .equ r17
msb1 .equ r18
lsb1 .equ r19
.global $fp_tst
$fp_tst mov msb1,msb1 ;Test the MSB. If negative, return
jn done ;and status register will be set
;correctly.
btjo #0ffh,exp1,$1 ;Check for zero.
btjo #0ffh,lsb1,$1
btjo #0ffh,msb1,$1
done rts ;Result is zero. Status reg is
;correct.
$1 mov #01h,msb1 ;Number is not negative and not zero,
rts ;so it must be positive. Do a dummy
;move to set status flags correctly.
49
Floating Point Number Negation
*
;Rev.1.0
;Function name - $fp_neg
;
;Purpose - Perform the sign negation of a floating point number
;
; -OP1
;
;Registers used - Register Before After
; ------------------------------------------------------; Status | XX | Set on result MSB
;
; R17 | OP1 exponent | Result exponent
; R18 | OP1 mantissa MSB | Result mantissa MSB
; R19 | OP1 mantissa LSB | Result mantissa LSB
;
;Size 17 Bytes
;
;Stack space None
;
;Notes - Some special considerations for floating point
; negation are:
;
; -ZERO = ZERO
exp .equ r17
msb .equ r18
lsb .equ r19
zero rts ;Number was zero, return.
negate xor #80h,msb ;Toggle sign bit if not zero.
rts
50
Floating Point To Signed 8-Bit Integer Conversion
*
;Rev.1.0
;Function name - $fp_ftoi
;
;Purpose - Convert a 24-bit signed floating representation
; of a number to an equivalent 8-bit signed integer
; representation.
;
;Registers used - Register Before After
; ------------------------------------------------------; Status | XX | Modified
; A | XX | Result
;
; R17 | OP2 exponent | OP2 exponent
; R18 | OP2 mantissa MSB | OP2 mantissa MSB
; R19 | OP2 mantissa LSB | OP2 mantissa LSB
;
;Size 45 bytes
;
;Stack space 1 byte
;
;Notes - 1) The fractional part of the float is discarded.
;
; 2) If the value of the integral part of the float cannot
; be represented by the signed int, the behavior is
; undefined.
;
; 3) A float value of ZERO will be converted to 0.
expon .equ r17
fsign .dbit 7,r18
.global $fp_ftoi
.text 7000h
$fp_ftoi ;Floating point to integer conversion.
btjo #80h,expon,$1 ;If exponent < 1, then number is too small.
clr a ;Set result = 0 and return.
rts
$1 cmp #87h,expon ;Check for too big (>127).
jhs big
mov r18,a ;Put MSB into A reg to be adjusted.
or #80h,a ;Set the implied one.
push expon ;Save true value of exponent.
sub #87h,expon ;Exponent – 87h = # of shifts needed to
compl expon ;represent number as 7 binary digit number.
loop clrc
rrc a ;Rotate A as needed. Loop until implied 1 is
djnz expon,loop ;in position.
jbit0 fsign,pos ;Check for minus sign.
compl a ;Take the 2’s complement of integer to set
;sign.
pos pop expon ;Restore the original exponent.
rts
big jbit1 fsign,bigminus ;Number is too big to be represented as a
mov #7fh,a ;signed integer. Set result to max positive
;value.
rts
51
bigminus ;Number is too small to be represented as a
*
mov #80h,a ;signed integer. Set result to max negative
rts ;value.
52
Floating Point To Signed Long (16-Bit) Integer Conversion
*
;Rev.1.0
;Function name - $fp_ftol
;
;Purpose - Convert a 24-bit signed floating representation
; of a number to an equivalent 16-bit signed integer
; representation.
;
;Registers used - Register Before After
; ------------------------------------------------------; Status | XX | Modified
; A | XX | Signed integer MSB
; B | XX | Signed integer LSB
;
; R17 | OP1 exponent | OP1 exponent
; R18 | OP1 mantissa MSB | OP1 mantissa MSB
; R19 | OP1 mantissa LSB | OP1 mantissa LSB
;
;Size 56 bytes
;
;Stack space 1 byte
;
;Notes - 1) The fractional part of the float is discarded.
;
; 2) If the value of the integral part of the float cannot
; be represented by the signed long int, the behavior is
; undefined.
;
; 3) A float value of ZERO will be converted to 0.
expon .equ r17
fsign .dbit 7,r18
.global $fp_ftol
.text 7000h
$fp_ftol ;Floating point to long integer conversion.
btjo #80h,expon,$1 ;If exponent < 1, then number is too small.
clr a ;Set result = 0 and return.
clr b
rts
$1 cmp #8fh,expon ;Check for too big (>32767)
jhs big
mov r19,b
mov r18,a
or #80h,a ;Set the implied one
push expon ;Save true value of exponent.
sub #8fh,expon ;Exponent – 8Fh = # of shifts needed to
;represent
compl expon ;number as binary 15 digit number.
loop clrc
rrc a ;Rotate A and B as needed. Loop until implied 1
rrc b ;is in position.
djnz expon,loop
jbit0 fsign,pos ;Check for minus sign.
inv a ;Take the 2’s complement of integer to set
;sign.
compl b
adc #0,a
53
pos pop expon
*
rts
big jbit1 fsign,bigminus
mov #0ffh,b ;Number is too big to be represented as a
;signed integer.
mov #7fh,a ;Set result to max positive value.
rts
bigminus
mov #0,b ;Number is too small to be represented as a
mov #80h,a ;signed integer. Set result to max negative
rts ;value.
54
Floating Point To Unsigned 8-Bit Integer Conversion
*
;Rev.1.0
;Function name - $fp_ftou
;
;Purpose - Convert a 24-bit signed floating representation
; of a number to an equivalent 8-bit unsigned integer
; representation.
;
;Registers used - Register Before After
; ------------------------------------------------------; Status | XX | Modified
; A | XX | Result
;
; R17 | OP1 exponent | OP1 exponent
; R18 | OP1 mantissa MSB | OP1 mantissa MSB
; R19 | OP1 mantissa LSB | OP1 mantissa LSB
;
;Size 35 Bytes
;
;Stack space 1 Byte
;
;Notes - 1) The fractional part of the float is discarded.
;
; 2) If the value of the integral part of the float cannot
; be represented by the unsigned int, the behavior is
; undefined.
;
; 3) A float value of ZERO will be converted to 0.
expon .equ r17
fsign .dbit 7,r18
.global $fp_ftou
.text 7000h
$fp_ftou ;Floating point to unsigned integer conversion.
btjo #80h,expon,$1;If exponent<1, then number is too small.
clr a ;Set result = 0 and return.
rts
$1 cmp #88h,expon ;Check for too big (>255).
jhs big
mov r18,a
or #80h,a ;Set the implied one.
push expon ;Save true value of exponent.
sub #87h,expon ;Exponent-87h = # of shifts needed to represent
compl expon ;number as 7 binary digit number.
jz done
loop clrc
rrc a ;Rotate A as needed. Loop until implied 1 is
djnz expon,loop ;in position.
done pop expon
rts
big mov #0ffh,a ;Number is too big to be represented as a signed
rts ;integer. Set result to max positive value.
55
Floating Point To Unsigned Long (16-Bit) Integer Conversion
*
;Rev.1.0
;Function name - $fp_ftoul
;
;Purpose - Convert a 24-bit signed floating representation
; of a number to an equivalent 16-bit unsigned integer
; representation.
;
;Registers used - Register Before After
; ------------------------------------------------------; Status | XX | Modified
; A | XX | Signed integer MSB
; B | XX | Signed integer LSB
;
; R17 | OP1 exponent | OP1 exponent
; R18 | OP1 mantissa MSB | OP1 mantissa MSB
; R19 | OP1 mantissa LSB | OP1 mantissa LSB
;
;Size 41 bytes
;
;Stack space 1 byte
;Notes - 1) The fractional part of the float is discarded.
;
; 2) If the value of the integral part of the float
; cannot be represented by the unsinged signed long int,
; the behavior is undefined.
;
; 3) A float value of ZERO will be converted to 0.
expon .equ r17
fsign .dbit 7,r18
.global $fp_ftoul
.text 7000h
$fp_ftoul ;Floating point to unsigned long integer.
btjo #80h,expon,$1;If exponent < 1, then number is too small.
clr a ;Set result = 0 and return.
clr b
rts
$1 cmp #90h,expon ;Check for too big (> 65535)
jhs big
mov r19,b
mov r18,a
or #80h,a ;Set the implied one.
push expon ;Save true value of exponent.
sub #8fh,expon ;Exponent-8fh = # of shifts needed to represent
compl expon ;number as 7 binary digit number.
jz ok
loop clrc
rrc a ;Rotate A and B as needed.
rrc b
djnz expon,loop ;Loop until implied 1 is in position.
ok pop expon
rts
big mov #0ffh,b ;Number is too big to be represented as a signed
mov #0ffh,a ;integer. Set result to max positive value.
rts
56
Signed 8-Bit Integer To Floating Point Conversion
*
;Rev.1.0
;Function name - $fp_itof
;
;Purpose - Convert an 8-bit signed integer representation
; of a number to an equivalent 24-bit signed floating
; point representation.
;
;Registers used - Register Before After
; ------------------------------------------------------; Status | XX | Set on Result
; A | Signed integer | Modified
;
; R17 | XX | Result exponent
; R18 | XX | Result mantissa MSB
; R19 | XX | Result mantissa LSB
;
;Size 34 bytes
;
;Stack space None
;
;Note - A zero integer value will convert to the
; floating point ZERO value.
expon .equ r17
isign .dbit 7,r0
fsign .dbit 7,r18
.global $fp_itof
.text 7000h
$fp_itof ;Integer to floating point conversion.
clr r18 ;Initialize fp to zero.
clr r19
mov #87h,expon ;Initialize exponent for 7 binary digit
number.
btjo #0ffh,a,nonzero;Check to make sure the number to be converted
;is not zero before we go any further.
zero clr expon ;Set result to fp zero.
rts
nonzero jp pos ;Test for negative integer.
sbit1 fsign ;Set the implied 1.
compl a ;Take 2s complement to get absolute value.
jn ok ;Check if implied 1 is in position.
pos dec expon ;Implied 1 is not in posistion. Rotate
clrc ;mantissa and decrement exponent until 1
;is in right place.
rlc a
jp pos
ok or #07Fh,r18 ;Set the sign bit of the MSB.
and a,r18
rts
57
Signed Long (16-Bit) Integer To Floating Point Conversion Comparison
*
;Rev.1.0
;Function name - $fp_ltof
;
;Purpose - Convert a 16-bit signed long integer representation
; of a number to an equivalent 24-bit signed floating
; point representation.
;
;Registers used - Register Before After
; ------------------------------------------------------; Status | XX | Set on result MSB
; A | Signed integer MSB | Modified
; B | Signed integer LSB | Modified
;
; R17 | XX | Result exponent
; R18 | XX | Result mantissa MSB
; R19 | XX | Result mantissa LSB
;
;
;Size 42 Bytes
;
;Stack space None
;
;Note - A zero long integer value will convert to the
; floating point ZERO value.
expon .equ r17
isign .dbit 7,r0
fsign .dbit 7,r18
.global $fp_ltof
.text 7000h
$fp_ltof ;Long integer to floating point conversion.
clr r18
mov #8fh,expon ;Set resulting exponent.
btjo #0ffh,a,nonzero;Test if MSB <> 0.
zero btjo #0ffh,b,pos ;Test if LSB <> 0. Since MSB = 0, value must
;be positive if not zero.
clr expon ;Long integer is zero. Return fp = zero.
clr r19
rts
nonzero jp pos ;Test for negative integer.
sbit1 fsign ;Integer is negative, so set sign bit of
;result.
inv a ;Invert MSB and take 2’s complement of LSB to
compl b ;get absolute value of mantissa.
adc #0,a
jn ok ;Check if implied 1 is in position.
pos dec expon ;Rotate mantissa and decrement exponent until
clrc ;implied 1 is in position.
rlc b
rlc a
jpz pos
ok and #07fh,a ;Mask out implied one
mov b,r19
or a,r18 ;or data with the sign bit.
rts
58
Unsigned Long (16-Bit) Integer To Floating Point Conversion
*
;Rev.1.0
;Function name - $fp_ultof
;
;Purpose - Convert a 16-bit unsigned long integer representation
; of a number to an equivalent 24-bit signed floating
; point representation.
;
;Registers used - Register Before After
; ------------------------------------------------------; Status | XX | Set on status of MSB
; A | Integer MSB | XX
; B | Integer LSB | XX
;
; R17 | XX | Result exponent
; R18 | XX | Result mantissa MSB
; R19 | XX | Result mantissa LSB
;
;
;Size 32 Bytes
;
;Stack space None
;
;Note - A zero long integer value will convert to the
; floating point ZERO value.
expon .equ r17
.global $fp_ultof
.text 7000h
$fp_ultof ;Unsigned long integer to floating point.
mov #08fh,expon ;Set exponent of result.
btjo #0ffh,a,nonzero;Test if MSB <> 0.
zero btjo #0ffh,b,pos ;Test if LSB <> 0.
clr expon ;Number is zero. Set result to fp zero.
clr r18
clr r19
rts
nonzero jn ok ;If MSB already has implied one, then done.
pos dec expon ;MSB was zero, so rotate mantissa and
clrc ;decrement exponent to shift implied 1 into
;place.
rlc b
rlc a
jpz pos ;Loop until implied 1 is in position.
ok and #07fh,a ;Set sign of result and save MSB.
mov a,r18
mov b,r19 ;Save LSB.
rts
59
Unsigned 8-Bit Integer To Floating Point Conversion
*
;Rev.1.0
;Function name - $fp_utof
;
;Purpose - Convert an 8-bit unsigned integer representation
; of a number to an equivalent 24-bit signed floating
; point representation.
;
;Registers used - Register Before After
; ------------------------------------------------------; Status | XX | Set on status of MSB
; A | Integer MSB | Modified
; B | Integer LSB | Integer LSB
;
; R17 | XX | Result exponent
; R18 | XX | Result mantissa MSB
; R19 | XX | Result mantissa LSB
;
;Size 26 Bytes
;
;Stack space None
;
;Note - A zero integer value will convert to the
; floating point ZERO value.
expon .equ r17
.global $fp_utof
.text 7000h
$fp_utof ;Unsigned integer to floating point
;conversion.
clr r19 ;Initialize MSB.
mov #87h,expon ;Initialize the exponent.
btjo #0ffh,a,nonzero;Test to see if integer is zero.
zero clr r18 ;Integer is zero, result will be fp zero.
clr expon
rts
nonzero jn ok ;Check if implied 1 is in position.
pos dec expon ;Implied 1 is not in position, rotate and
clrc ;decrement until implied one is in position.
rlc a ;
jp pos ;
This routine clears all of the internal RAM registers. It can be used at the beginning of a program to
initialize the first 256 bytes of RAM to a known value. Registers A and B have the following functions
in this routine:
•Register A holds the initialization value.
•Register B serves as the index into the RAM.
Routine
.TEXT 7000h;Absolute start address
CLEARMOV #254,B;Number of registers to clear less 2
CLR A;Load the initialization
;value of zero
LOOPMOV A,1[B];Clear the location indexed
;by B+1
DJNZ B,LOOP;Loop until all RAM is
;cleared
;A and B end up as zeros.
65
RAM Self-Test on the TMS370
*68*
Microcontroller Products—Semiconductor Group
Texas Instruments
67
RAM Self-Test
*70*
This routine performs a simple alternating 0/1 test on RAM locations R3–R255 by writing an AA,55 pattern
to this RAM space and then checking the RAM for this pattern. The inverted pattern is then written to RAM
and rechecked. Finally, the entire RAM is cleared. If an error is found, a bit is set in the flag register. The
error flag bit should be cleared before the routine is started.
Table 1. Register Values
Register
BeforeAfter: No ErrorAfter: Error
AXX0?
BXX0?
FLAGXX0Bit 0 = 1
NOTE:
•Passing data: none
•Registers affected: all
•Ending data: all registers = 0; bit 0 in FLAG = 1 if error was found
Routine
.TEXT 7000H ;Absolute start address
FLAG .EQU R2 ;Error register
MOV #55h,A ;Start RAM fill with 55h
FILLR MOV #0FDh,B ;Set RAM start address – 3
;(don’t change registers A, B, or R2)
FILL1 MOV A,*2[B] ;Fill RAM with AA to 55 pattern
RR A ;Change to beginning number
DJNZ B,FILL1 ;Fill entire RAM with pattern
RR A ;Change to beginning number
MOV #0FDh,B ;Refresh index
COMPAR CMP *2[B],A ;Check for errors
JNE ERROR ;Exit if values don’t match
RR A ;Change from 55 to AA to 55
DJNZ B,COMPAR ;Check the entire RAM
CLRC ;Is reg A now 55, AA or 00?
JN FILLR ;=AA, change to opposite pattern
JZ EXIT ;=00,
FILL0 CLR A ;=55,clear the ram now
JMP FILLR ;Repeat the fill and check routine
ERROR OR #1,FLAG ;Set bit zero in the flag
;register
EXIT .EQU $ ;Continue program here
69
ROM Checksum on the TMS370
*72*
Microcontroller Products—Semiconductor Group
Texas Instruments
71
ROM Checksum
*
This routine checks the integrity of a 4K-byte ROM by performing a checksum on the entire ROM. All
ROM bytes from 7002h to 7FDFh are added together in a 16-bit word. The sum is checked against the value
at the beginning of the ROM (7000h, 7001h). If the values don’t match, then an error has occurred, and a
bit is set in a register. The error flag bit should be cleared before the start of the routine. This routine can
easily be modified for other ROM sizes.
NOTE:
Addresses 7FE0h through 7FEBh ar e reserved for TI use only and should not
be used in a checksum calculation.
;memory)
MOVW #0FDDh,R7;Number of bytes to add + 1
MOVW #0,R3;Reset summing register
;
ADDLOPMOV@R5,A;Get ROM byte
ADDA,R3;Add to 16-bit sum
ADC#0,R2;Add any carry
INCW #–1,R5;Decrement address
INCW #–1,R7;Decrement byte counter
JCADDLOP;Continue until byte count
;goes past 0
;
MOV7000h,A;Compare MSbyte stored to
;MSbyte sum
CMPA,R2;
JNEERROR;Set error bit if different
MOV7001h,A;Compare LSbyte stored to
;LSbyte sum
CMPA,R3;
JEQEXIT;Set error bit if different
ERROROR#2,FLAG;Set bit 1 in the flag
;register
EXIT.EQU $;Continue program here
74
Table Search With the TMS370
*76*
Microcontroller Products—Semiconductor Group
Texas Instruments
75
Table Search
*78*
The CMPA (Compare Register A Extended) instruction efficiently performs table searches. In the
following example, a 150-byte table is searched for a match with a 6-byte string.
The indexed addressing mode is used in this example and has the capability to search a 256-byte string,
if needed. Register B alternates between a pointer into the 6-byte test string and a pointer into the longer
table string.
Table 1. Register and Expression Functions
RegisterBefore After Function
AXX ??
BXX ??
R2XX ?? Table length
TABLEXX no change Long string in table
STRINGXX no change Target string, 6 bytes max
Routine
TABLE.EQU2000h;Start of data table in external RAM
STRING.EQUR10;Start of target string,
SEARCHMOV#150,R2;Table length = 150 bytes
LOOP1MOV#6,B;String length = 6 bytes
LOOP2XCHBR2;Swap pointers, long string in B
MATCH.EQU$;Match found
NOFIND.EQU$;No match found
.TEXT 7000h;Absolute start address
;6 bytes max
DECB;Reduce index into table
JNCNOFIND;Table end? if so, no match found
MOV*TABLE[B],A;Load test character
XCHBR2;Swap pointers, string pointer in
CMP*STRING–1[B],A;Match?
JNELOOP1;If not, reset string pointer
;else test
DJNZB,LOOP2;Next character
77
Bubble Sort With the TMS370
*80*
Microcontroller Products—Semiconductor Group
Texas Instruments
79
Bubble Sort
*82*
This routine sorts up to 256 bytes using the bubble sort method. Longer tables can be sorted using the
indirect addressing mode.
Table 1. Register Functions
RegisterFunction
AT emporary storage register
BIndex into the RAM
R2Holds flag to indicate a byte swap has been made
Routine
TABLE .EQU2000h;Start of data table in external RAM
FLAG.EQUR2;’Swap has been made’ flag
SORTCLRFLAG;Reset swap flag
LOOP1 MOV*TABLE[B],A;Look at entry in table
LOOP2 DJNZB,LOOP1;Loop until all the table is looked at
.TEXT 7000h;Absolute start address
MOV#0FFh,B;Load table offset value
CMP*TABLE–1[B],A;Look at next lower byte
JHSLOOP2;If higher or equal, skip to next value
INCFLAG;Entry is not lower, set swap flag
PUSHA;Store upper byte
MOV*TABLE-1[B],A;Take lower byte
MOVA,*TABLE[B];Put where upper was
POPA;Get the old upper byte
MOVA,*TABLE-1[B];Put where the lower byte was
BTJO#0FFh,FLAG,SORT ;If swap was made, then resweep table
RTS;If no swap was made, then table is done
81
Loading...
+ hidden pages
You need points to download manuals.
1 point = 1 manual.
You can buy points or you can get point for every manual you upload.