⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cnv04.s43

📁 MSP430浮点库
💻 S43
📖 第 1 页 / 共 2 页
字号:
          ADDC   @SP+,BIN_MID
          ADDC   @SP+,BIN_MSB
;
	  CLR	 HELP		; BCD digit buffer
CNVL$5	  RLA	 BCD_LSB	; Next BCD digit to HELP
          RLC    BCD_MID
          RLC    BCD_MSB
	  RLC	 HELP		; insert BCD number
	  DEC	 COUNTER
	  BIT	 #3,COUNTER	; One BCD digit stored?
          JNZ    CNVL$5         ; Not yet, continue
;
	  ADD	 HELP,BIN_LSB	; BCD digit buffer contains BCD digit
	  ADC	 BIN_MID	; Add BCD digit to binary buffer
          ADC    BIN_MSB
	  TST	 COUNTER	; 12 BCD digits converted?
          JNZ    BCD_LOP1       ; No, next digit
;
; The converted binary number (max. 40 bits) is in the binary buffer.
; Shift left mantissa now until MSB = 1 (bit 7 of BIN_MSB). Create FP-sign
;
NORM	  SWPB	 2(SP)		; Stored sign from bit 15 to bit 7
	  AND	 #080h,2(SP)	; only sign remains
	  MOV.B  #080h+39,COUNTER ; max. exponent: true if MSB yet 1
NORM_LOP  TST.B  BIN_MSB	; Check if MSB = 1
          JN     NORMED         ; MSB = 1: normed mantissa
          RLA    BIN_LSB        ; Shift left 40 bit mantissa
          RLC    BIN_MID
          RLC.B  BIN_MSB
	  DEC.B  COUNTER	; Max. 39 times, decr. exponent
	  JN	 NORM_LOP	; if exponent < 080h: number < 1
;
; BCD number is 0: MSB is still 0 after 40 shifts. Output zero
;
	  JMP	 RES0		; Result is .FLOAT/.DOUBLE zero
;
; MSB of mantissa is 1 now: COUNTER contains exponent. Prepare FP number
; Rounding necessary only for .FLOAT format: .DOUBLE contains all 40 bits
; The completion part of the FPP is used for the number generation
;
NORMED	 MOV.B	 COUNTER,3(SP)	; Exponent in FPP format
      IF (DOUBLE=0) AND (SW_RND=1)  ; Conditions for rounding
	 RLA	 BIN_LSB	; MSB of BIN_LSB to carry (LSB-1)
	 JMP	 NORMLZ 	; Round mantissa with this bit
      ELSE
	 JMP	 DDRNZ		; Output FPP number without rounding
      ENDIF
;
;---------------------------------------------------------------------------
; Floating Point to Binary Conversion: the integer part of the Floating
; Point number RPARG points to is converted to a 40 bit signed binary number
; on top of the stack: (range FF00 0000 0001 to 00FF FFFF FFFF)
;
; Call:   RPARG points to the .FLOAT resp. .DOUBLE format number
; Return: the converted, signed 40 bit binary number is located on top
;	  of the stack (3 words). RPRES, RPARG and SP point to TOS
; Errors: N = 0: no error  (3 words result on TOS)
;	  N = 1: FP number > 2^39. The largest signed binary number is
;		 placed on TOS (00FF FFFF FFFF resp. FF00 0000 0001)
;
; Call    MOV   #FPnumber,RPARG ; Pointer to MSBs of a FP number
;         CALL  #CNV_FP_BIN     ; Call conversion routine
;	  JN	ERROR		; N=1: Largest number on TOS (3 words)
;         ...                   ; N=0: Result on TOS (3 words binary number)
;
CNV_FP_BIN  EQU  $
	  MOV	 #0FFFFh,HELP	; Set switch to binary conversion
	  JMP	 CNV_FP_GEM	; Use CNV_FP_BCD FP to binary part
;
;---------------------------------------------------------------------------
; Floating Point to BCD Conversion: the integer part of the Floating
; Point number RPARG points to is converted to a 12 digit BCD number
; on top of the stack:
;
; Call:   RPARG points to .FLOAT resp. .DOUBLE format number
; Return: the converted, signed 12 digit BCD number is located on top
;         of the stack (3 words)
; Errors: N = 0: no error  (3 words result on TOS)
;	  N = 1: |FP number| > 2^39 or |BCD number| >= 8 x 10^12
;		 The largest signed BCD number is placed on TOS:
;		 (+7999 9999 9999 resp. -7999 9999 9999)
;
; Call    MOV   #FPnumber,RPARG ; Pointer to MSBs of a FP number
;         CALL  #CNV_FP_BCD     ; Call conversion routine
;	  JN	ERROR		; N=1: Error: largest number on TOS (3 words)
;         ...                   ; N=0: Result on TOS (3 words BCD number)
;
CNV_FP_BCD MOV	 #0h,HELP	; Set switch to BCD conversion
CNV_FP_GEM  EQU  $                       ; Common part
          MOV.B  1(R5),COUNTER        ; Save exponent of FP number
          MOV    @R5+,BIN_MSB         ; Move FP number to BIN_xxx
          MOV    @R5+,BIN_MID
      IF  DOUBLE=1
          MOV    @R5,BIN_LSB
      ELSE
	  CLR	 BIN_LSB	; LSBs = 0 for .FLOAT numbers
      ENDIF
	  PUSH	 BIN_MSB	; Save FP MSBs with sign
;
	  BIS.B  #080h,BIN_MSB	; Set hidden bit in mantissa, clear HI byte
;
; The mantissa in BIN_xxx is shifted until the 2^0 bit is at the LSB
; of BIN_LSB: this is the case if the exponent (in COUNTER) is 080h+39
;
      IF  SW_RND
	  CLR	 BCD_LSB	; Clear Carry save for rounding
      ENDIF
EXP_LOP2   EQU   $
	  CMP.B  #080h+39,COUNTER     ; Exponent = 080h+39?
	  JEQ	 B_CNV		; Yes, binary buffer contains integer now
	  JHS	 CNV_ERR4	; FP number too large for BCD buffer (C = 1)
	  RRC	 BIN_MSB	; BIN_MSB: 00xxh  Carry = 0
	  RRC	 BIN_MID	; Exponent < 39: shift right binary buffer
	  RRC	 BIN_LSB
      IF  SW_RND
	  MOV	 SR,BCD_LSB	; Save last carry for rounding
      ENDIF
	  INC.B  COUNTER	; Incr. exponent
	  JMP	 EXP_LOP2

; 2^0 bit in BIN_LSB.0:
; Rounding is made if selected. The 2^-1 bit (LSB-1) is added
;
B_CNV      equ  $
      IF   SW_RND               ; Rounding selected?
	  BIT	#FC,BCD_LSB	; Test last carry for rounding
          ADC   BIN_LSB         ; Add it to binary buffer
          ADC   BIN_MID
          ADC   BIN_MSB
      ENDIF
;
; The value in HELP defines the kind of conversion:
; BCD_MSB = 0: FP to BCD conversion
; BCD_MSB # 0: FP to binary conversion

	  TST	HELP
          JZ    BCD_CNV
;
; Floating Point to Binary Conversion:
; The integer in the binary buffer is converted to signed binary
;
          MOV   BIN_LSB,BCD_LSB ; Move integer to BCD buffer
          MOV   BIN_MID,BCD_MID
          MOV   BIN_MSB,BCD_MSB
	  CLR	HELP		; No error indication
;
FPBIN	  POP	COUNTER 	; Restore MSBs and sign of FP number
	  TST.B COUNTER 	; Test sign
          JGE   CNVL$10         ; Sign is positive, output integer
          INV   BCD_LSB         ; Neg.sign: negate integer
          INV   BCD_MID
          INV   BCD_MSB
          INC   BCD_LSB
          ADC   BCD_MID
          ADC   BCD_MSB
          JMP   CNVL$10         ; Use common output part
;
; Floating Point to BCD Conversion:
; The integer in the binary buffer is converted to BCD in the BCD buffer
;
BCD_CNV   MOV	#40,COUNTER	; 40 binary bits max.
          CLR   BCD_LSB         ; Clear BCD buffer
          CLR   BCD_MID
          CLR   BCD_MSB
BCD_LOP2  RLA   BIN_LSB         ; Start binary to BCD conversion
          RLC   BIN_MID
	  RLC.B BIN_MSB 	; Only LO byte of MSBs is used: 00xx
          DADD  BCD_LSB,BCD_LSB ; Carry to LSB, double BCD-number
          DADD  BCD_MID,BCD_MID
          DADD  BCD_MSB,BCD_MSB
	  JC	CNV_ERR3	; Error: |FP number| >= 1 x 10^12
	  JN	CNV_ERR3	;	 |FP number| >= 8 x 10^11
	  DEC	COUNTER
	  JNZ	BCD_LOP2	; No error: HELP = 0
;
; The BCD buffer contains the converted 12 digit number: insert sign
;
FPBCD	  POP	COUNTER 	; Restore MSBs and sign of FP number
	  TST.B COUNTER 	; Test sign
          JGE   CNVL$10         ; Sign is positive
          BIS   #08000h,BCD_MSB ; Insert neg. sign to BCD buffer
CNVL$10    EQU  $
;
; Write result on top of stack
; .FLOAT:  One additional word is needed for the result. Push return address
; .DOUBLE: Three words for result are available
;
      IF  DOUBLE=0              ; .DOUBLE format places 3 words on stack
	  PUSH	2(SP)		; .FLOAT format: PUSH return address
      ENDIF                     ; to get room for 3 word result
          MOV   BCD_LSB,6(SP)   ; BCD result to stack
          MOV   BCD_MID,4(SP)
          MOV   BCD_MSB,2(SP)   ; MSDs on TOS (after return)
	  JMP	FLT_END 	; Use FPP completion part
;
; Error: |FP number| >= 1 x 10^12 or >= 8 x 10^11. N = 1
; Return with largest,signed BCD-number on TOS.
;
CNV_ERR3  MOV	#07999h,BCD_MSB ; largest BCD number
	  MOV	#09999h,BCD_MID ; 7999 9999 9999
	  MOV	#09999h,BCD_LSB
	  MOV	#FN,HELP	; indicate error
	  JMP	FPBCD		; output this number signed
;
; Error: |FP number| > 2^39. Check if BCD or binary conversion
;
CNV_ERR4  TST	HELP		; FP_BIN or FP_BCD?
	  JZ	CNV_ERR3	; FP_BCD conversion: output BCD number
          MOV.B #0FFh,BCD_MSB   ; FP_BIN conversion: output largest binary
	  MOV	#0FFFFh,BCD_MID ; number: 00FF FFFF FFFF
	  MOV	#0FFFFh,BCD_LSB
	  MOV	#FN,HELP	; indicate error
	  JMP	FPBIN		; output this number signed
;
;   END OF THE FLOATING POINT CONVERSION SUBROUTINES

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -