?? cnv04.s43
字號:
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 + -