📄 fp52.sdi
字号:
,,,; This is a complete BCD floating point package for the 8051 micro-
,,,; controller. It provides 8 digits of accuracy with exponents that
,,,; range from +127 to -127. The mantissa is in packed BCD, while the
,,,; exponent is expressed in pseudo-twos complement. A ZERO exponent
,,,; is used to express the number ZERO. An exponent value of 80H or
,,,; greater than means the exponent is positive, i.e. 80H = E 0,
,,,; 81H = E+1, 82H = E+2 and so on. If the exponent is 7FH or less,
,,,; the exponent is negative, 7FH = E-1, 7EH = E-2, and so on.
,,,; ALL NUMBERS ARE ASSUMED TO BE NORMALIZED and all results are
,,,; normalized after calculation. A normalized mantissa is >=.10 and
,,,; <=.99999999.
,,,;
,,,; The numbers in memory assumed to be stored as follows:
,,,;
,,,; EXPONENT OF ARGUMENT 2 = VALUE OF ARG_STACK+FP_NUMBER_SIZE
,,,; SIGN OF ARGUMENT 2 = VALUE OF ARG_STACK+FP_NUMBER_SIZE-1
,,,; DIGIT 78 OF ARGUMENT 2 = VALUE OF ARG_STACK+FP_NUMBER_SIZE-2
,,,; DIGIT 56 OF ARGUMENT 2 = VALUE OF ARG_STACK+FP_NUMBER_SIZE-3
,,,; DIGIT 34 OF ARGUMENT 2 = VALUE OF ARG_STACK+FP_NUMBER_SIZE-4
,,,; DIGIT 12 OF ARGUMENT 2 = VALUE OF ARG_STACK+FP_NUMBER_SIZE-5
,,,;
,,,; EXPONENT OF ARGUMENT 1 = VALUE OF ARG_STACK
,,,; SIGN OF ARGUMENT 1 = VALUE OF ARG_STACK-1
,,,; DIGIT 78 OF ARGUMENT 1 = VALUE OF ARG_STACK-2
,,,; DIGIT 56 OF ARGUMENT 1 = VALUE OF ARG_STACK-3
,,,; DIGIT 34 OF ARGUMENT 1 = VALUE OF ARG_STACK-4
,,,; DIGIT 12 OF ARGUMENT 1 = VALUE OF ARG_STACK-5
,,,;
,,,; The operations are performed thusly:
,,,;
,,,; ARG_STACK+FP_NUMBER_SIZE = ARG_STACK+FP_NUMBER_SIZE # ARG_STACK
,,,;
,,,; Which is ARGUMENT 2 = ARGUMENT 2 # ARGUMENT 1
,,,;
,,,; Where # can be ADD, SUBTRACT, MULTIPLY OR DIVIDE.
,,,;
,,,; Note that the stack gets popped after an operation.
,,,;
,,,; The FP_COMP instruction POPS the ARG_STACK TWICE and returns status.
,,,;
,,,;**********************************************************************
,,,;
,,,$EJECT
,,,;**********************************************************************
,,,;
,,,; STATUS ON RETURN - After performing an operation (+, -, *, /)
,,,; the accumulator contains the following status
,,,;
,,,; ACCUMULATOR - BIT 0 - FLOATING POINT UNDERFLOW OCCURED
,,,;
,,,; - BIT 1 - FLOATING POINT OVERFLOW OCCURED
,,,;
,,,; - BIT 2 - RESULT WAS ZER0
,,,;
,,,; - BIT 3 - DIVIDE BY ZERO ATTEMPTED
,,,;
,,,; - BIT 4 - NOT USED, 0 RETURNED
,,,;
,,,; - BIT 5 - NOT USED, 0 RETURNED
,,,;
,,,; - BIT 6 - NOT USED, 0 RETURNED
,,,;
,,,; - BIT 7 - NOT USED, 0 RETURNED
,,,;
,,,; NOTE: When underflow occures, a ZERO result is returned.
,,,; When overflow or divide by zero occures, a result of
,,,; .99999999 E+127 is returned and it is up to the user
,,,; to handle these conditions as needed in the program.
,,,;
,,,; NOTE: The Compare instruction returns F0 = 0 if ARG 1 = ARG 2
,,,; and returns a CARRY FLAG = 1 if ARG 1 is > ARG 2
,,,;
,,,;***********************************************************************
,,,;
,,,$EJECT
,,,;***********************************************************************
,,,;
,,,; The following values MUST be provided by the user
,,,;
,,,;***********************************************************************
,,,;
,,,ARG_STACK_PAGE EQU 01h ;External memory page for arg stack
,,,ARG_STACK EQU 24H ;ARGUMENT STACK POINTER
,,,FORMAT EQU 25H ;LOCATION OF OUTPUT FORMAT BYTE
,,,;OUTPUT EQU R5OUT ;CALL LOCATION TO OUTPUT A CHARACTER in R5
,,,CONVT EQU 0048H ;String addr TO CONVERT NUMBERS
000B,,,INTGRC BIT 26H.1 ;BIT SET IF INTEGER ERROR
000B,,,ADD_IN BIT 26H.3 ;DCMPXZ IN BASIC BACKAGE
000B,,,ZSURP BIT 26H.6 ;ZERO SUPRESSION FOR HEX PRINT
,,,;
,,,;***********************************************************************
,,,;
,,,; The following equates are used internally
,,,;
,,,;***********************************************************************
,,,;
,,,FP_NUMBER_SIZE EQU 6
,,,DIGIT EQU FP_NUMBER_SIZE-2
,,,R0B0 EQU 0
,,,R1B0 EQU 1
,,,UNDERFLOW EQU 0
,,,OVERFLOW EQU 1
,,,ZERO EQU 2
,,,ZERO_DIVIDE EQU 3
,,,;
,,,;***********************************************************************
,,,$EJECT
,,, ;**************************************************************
,,, ;
,,, ; The following internal locations are used by the math pack
,,, ; ordering is important and the FP_DIGITS must be bit
,,, ; addressable
,,, ;
,,, ;***************************************************************
,,, ;
,,,FP_STATUS EQU 28H ;NOT used data pointer me
,,,FP_TEMP EQU FP_STATUS+1 ;NOT USED
,,,FP_CARRY EQU FP_STATUS+2 ;USED FOR BITS
,,,FP_DIG12 EQU FP_CARRY+1
,,,FP_DIG34 EQU FP_CARRY+2
,,,FP_DIG56 EQU FP_CARRY+3
,,,FP_DIG78 EQU FP_CARRY+4
,,,FP_SIGN EQU FP_CARRY+5
,,,FP_EXP EQU FP_CARRY+6
000B,,,MSIGN BIT FP_SIGN.0
000B,,,XSIGN BIT FP_CARRY.0
000B,,,FOUND_RADIX BIT FP_CARRY.1
000B,,,FIRST_RADIX BIT FP_CARRY.2
000B,,,DONE_LOAD BIT FP_CARRY.3
,,,FP_NIB1 EQU FP_DIG12
,,,FP_NIB2 EQU FP_NIB1+1
,,,FP_NIB3 EQU FP_NIB1+2
,,,FP_NIB4 EQU FP_NIB1+3
,,,FP_NIB5 EQU FP_NIB1+4
,,,FP_NIB6 EQU FP_NIB1+5
,,,FP_NIB7 EQU FP_NIB1+6
,,,FP_NIB8 EQU FP_NIB1+7
,,,FP_ACCX EQU FP_NIB1+8
,,,FP_ACCC EQU FP_NIB1+9
,,,FP_ACC1 EQU FP_NIB1+10
,,,FP_ACC2 EQU FP_NIB1+11
,,,FP_ACC3 EQU FP_NIB1+12
,,,FP_ACC4 EQU FP_NIB1+13
,,,FP_ACC5 EQU FP_NIB1+14
,,,FP_ACC6 EQU FP_NIB1+15
,,,FP_ACC7 EQU FP_NIB1+16
,,,FP_ACC8 EQU FP_NIB1+17
,,,FP_ACCS EQU FP_NIB1+18
,,, ;
,,,$EJECT
,,,
000C,,,FP_BASE EQU $
,,,
,,, ;**************************************************************
,,, ;
,,, ; The floating point entry points and jump table
,,, ;
,,, ;**************************************************************
,,, ;
0000,01 30,, AJMP FLOATING_ADD
0002,01 26,, AJMP FLOATING_SUB
0004,01 E3,, AJMP FLOATING_COMP
0006,21 14,, AJMP FLOATING_MUL
0008,21 49,, AJMP FLOATING_DIV
000A,61 10,, AJMP HEXSCAN
000C,61 49,, AJMP FLOATING_POINT_INPUT
000E,81 01,, AJMP FLOATING_POINT_OUTPUT
0010,A1 7E,, AJMP CONVERT_BINARY_TO_ASCII_STRING
0012,A1 25,, AJMP CONVERT_ASCII_STRING_TO_BINARY
0014,A1 5A,, AJMP MULNUM10
0016,A1 C6,, AJMP HEXOUT
,,,;
,,,; the remaining jump to routines were extracted from basic52
,,,; by me to make the floating point software stand alone
,,,;
0018,61 3D,, AJMP PUSHR2R0 ; INTEGER to FLOAT
001A,C1 0B,, AJMP IFIX ; FLOAT to INTEGER
001C,C1 4C,, AJMP PUSHAS ; PUSH R2:R0 TO ARGUMENT
001E,C1 48,, AJMP POPAS ; POP ARGUMENT TO R3:R1
0020,C1 69,, AJMP MOVAS ; COPY ARGUMENT
0022,C1 8D,, AJMP AINT ; INT FUNCTION
0024,C1 B5,, AJMP PUSHC ; PUSH ARG IN DPTR TO STACK
,,, ;
,,,$EJECT
,,, ;
0026,,FLOATING_SUB,FLOATING_SUB:
,,, ;
0026,75 A0 01,, MOV P2,#ARG_STACK_PAGE
0029,A8 24,, MOV R0,ARG_STACK
002B,18,, DEC R0 ;POINT TO SIGN
002C,E2,, MOVX A,@R0 ;READ SIGN
002D,B2 E0,, CPL ACC.0
002F,F2,, MOVX @R0,A
,,, ;
,,, ;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
,,, ;
0030,,FLOATING_ADD,FLOATING_ADD:
,,, ;
,,, ;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
,,, ;
,,, ;
0030,51 F1,, ACALL MDES1 ;R7=TOS EXP, R6=TOS-1 EXP, R4=TOS SIGN
,,, ;R3=TOS-1 SIGN, OPERATION IS R1 # R0
,,, ;
0032,EF,, MOV A,R7 ;GET TOS EXPONENT
0033,60 0D,, JZ POP_AND_EXIT ;IF TOS=0 THEN POP AND EXIT
0035,BE 00 12,, CJNE R6,#0,LOAD1 ;CLEAR CARRY EXIT IF ZERO
,,, ;
,,, ;**************************************************************
,,, ;
0038,,SWAP_AND_EXIT,SWAP_AND_EXIT: ; Swap external args and return
,,, ;
,,, ;**************************************************************
,,, ;
0038,51 E5,, ACALL LOAD_POINTERS
003A,7F 06,, MOV R7,#FP_NUMBER_SIZE
,,, ;
003C,E2,SE1,SE1: MOVX A,@R0 ;SWAP THE ARGUMENTS
003D,F3,, MOVX @R1,A
003E,18,, DEC R0
003F,19,, DEC R1
0040,DF FA,, DJNZ R7,SE1
,,, ;
0042,,POP_AND_EXIT,POP_AND_EXIT:
,,, ;
0042,E5 24,, MOV A,ARG_STACK ;POP THE STACK
0044,24 06,, ADD A,#FP_NUMBER_SIZE
0046,F5 24,, MOV ARG_STACK,A
0048,E4,, CLR A
0049,22,, RET
,,, ;
,,, ;
004A,9E,LOAD1,LOAD1: SUBB A,R6 ;A = ARG 1 EXP - ARG 2 EXP
004B,8F 30,, MOV FP_EXP,R7 ;SAVE EXPONENT AND SIGN
004D,8C 2F,, MOV FP_SIGN,R4
004F,50 09,, JNC LOAD2 ;ARG1 EXPONENT IS LARGER OR SAME
0051,8E 30,, MOV FP_EXP,R6
0053,8B 2F,, MOV FP_SIGN,R3
0055,F4,, CPL A
0056,04,, INC A ;COMPENSATE FOR EXP DELTA
0057,C8,, XCH A,R0 ;FORCE R0 TO POINT AT THE LARGEST
0058,C9,, XCH A,R1 ;EXPONENT
0059,C8,, XCH A,R0
,,, ;
005A,FF,LOAD2,LOAD2: MOV R7,A ;SAVE THE EXPONENT DELTA IN R7
005B,C2 33,, CLR ADD_IN
005D,BD 00 02,, CJNE R5,#0,$+5
0060,D2 33,, SETB ADD_IN
,,, ;
,,,$EJECT
,,, ; Load the R1 mantissa
,,, ;
0062,71 02,, ACALL LOADR1_MANTISSA ;LOAD THE SMALLEST NUMBER
,,, ;
,,, ; Now align the number to the delta exponent
,,, ; R4 points to the string of the last digits lost
,,, ;
0064,BF 0B 00,, CJNE R7,#DIGIT+DIGIT+3,$+3
0067,40 02,, JC $+4
0069,7F 0A,, MOV R7,#DIGIT+DIGIT+2
,,, ;
006B,75 2A 00,, MOV FP_CARRY,#00 ;CLEAR THE CARRY
006E,51 42,, ACALL RIGHT ;SHIFT THE NUMBER
,,, ;
,,, ; Set up for addition and subtraction
,,, ;
0070,7F 04,, MOV R7,#DIGIT ;LOOP COUNT
0072,79 2E,, MOV R1,#FP_DIG78
0074,74 9E,, MOV A,#9EH
0076,C3,, CLR C
0077,9C,, SUBB A,R4
0078,D4,, DA A
0079,CC,, XCH A,R4
007A,70 01,, JNZ $+3
007C,FC,, MOV R4,A
007D,B4 50 00,, CJNE A,#50H,$+3 ;TEST FOR SUBTRACTION
0080,30 33 18,, JNB ADD_IN,SUBLP ;DO SUBTRACTION IF NO ADD_IN
0083,B3,, CPL C ;FLIP CARRY FOR ADDITION
0084,11 92,, ACALL ADDLP ;DO ADDITION
,,, ;
0086,50 08,, JNC ADD_R
0088,05 2A,, INC FP_CARRY
008A,7F 01,, MOV R7,#1
008C,51 42,, ACALL RIGHT
008E,31 F9,, ACALL INC_FP_EXP ;SHIFT AND BUMP EXPONENT
,,, ;
0090,21 EA,ADD_R,ADD_R: AJMP STORE_ALIGN_TEST_AND_EXIT
,,, ;
0092,E2,ADDLP,ADDLP: MOVX A,@R0
0093,37,, ADDC A,@R1
0094,D4,, DA A
0095,F7,, MOV @R1,A
0096,18,, DEC R0
0097,19,, DEC R1
0098,DF F8,, DJNZ R7,ADDLP ;LOOP UNTIL DONE
009A,22,, RET
,,, ;
,,,$EJECT
,,, ;
009B,E2,SUBLP,SUBLP: MOVX A,@R0 ;NOW DO SUBTRACTION
009C,FE,, MOV R6,A
009D,E4,, CLR A
009E,34 99,, ADDC A,#99H
00A0,97,, SUBB A,@R1
00A1,2E,, ADD A,R6
00A2,D4,, DA A
00A3,F7,, MOV @R1,A
00A4,18,, DEC R0
00A5,19,, DEC R1
00A6,DF F3,, DJNZ R7,SUBLP
00A8,40 11,, JC FSUB6
,,, ;
,,,$EJECT
,,, ;
,,, ; Need to complement the result and sign because the floating
,,, ; point accumulator mantissa was larger than the external
,,, ; memory and their signs were equal.
,,, ;
00AA,B2 78,, CPL FP_SIGN.0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -