; CFFADD FAR CALL MODIFICATIONS 1200 2-MAR-81 ; CFADD VERSION 1.1 0945 6-SEP-79 ; RCC86 FLOATING ADD CF@CODE SEGMENT BYTE PUBLIC ASSUME CS:CF@CODE PUBLIC CF@ADD PUBLIC CF@SUB EXTRN CF@NEG:NEAR CF@SUB PROC FAR ;FLOATING SUBTRACT CALL CF@NEG ;NEGATE SECOND OPERAND & ADD CF@ADD LABEL FAR ;FLOATING ADD PUSH BP ;SET UP LOCAL FRAME MOV BP,SP CMP DX,0 ;CHECK OPERAND-2 ZERO JNE SECNZ CMP AX,0 JE RET1ST ;IF SO RETURN OPERAND-1 SECNZ LABEL NEAR XCHG AX,[BP+4] ;SWAP OPERANDS XCHG DX,[BP+6] CMP DX,0 ;CHECK OPERAND-1 ZERO JNE NOTZERO CMP AX,0 JNE NOTZERO RET1ST LABEL NEAR ;RETURN ON-STACK OPERAND POP BP POP BX ;RETURN LINK POP AX POP DX JMP BX ;EXIT NOTZERO LABEL NEAR ;NEITHER OPERAND ZERO MOV BL,DH ;EXPONENT OF REGISTER OPERAND MOV BH,0 ; WIDEN MOV CL,[BP+7] ;EXPONENT OF STACK OPERAND MOV CH,BH ; BH=0 SUB CX,BX ;DIFFERENCE OF EXPONENTS JE FINECMP ; JUMP IF EXPONENTS EQUAL JG NOSWAP ;WANT SMALLER OPERAND IN REGISTERS XCHG AX,[BP+4] ;SWAP IF SMALLER OPERAND ON STACK XCHG DX,[BP+6] NEG CX ;WANT POSITIVE DIFFERENCE OF EXPONENTS NOSWAP LABEL NEAR CMP CX,24 ;CHECK IF SMALLER OPERAND INSIGNIFICANT JG RET1ST ; IGNORE IT IF IT IS PUSH DX ;TO SAVE SIGN MOV DH,0 ;CLEAR EXPONENT OF SMALLER OPERAND OR DL,80H ;SET HIDDEN 2**-1 MOV BX,DX ;SAVE COPY OF MS PART SHR DX,CL ;ALIGN MS PART SHR AX,CL ;ALIGN LS PART NEG CX ;FORM COMPLEMENTARY SHIFT COUNT ADD CX,16 SHL BX,CL ;EXTRACT AND POSITION BITS WHICH ; ; CARRY FROM MS TO LS OR AX,BX ;INSERT CARRY BITS IN LS POP BX ;RETRIEVE SIGN JMP SIGNTST FINECMP LABEL NEAR ;HERE IF EXPONENTS EQUAL MOV BX,[BP+6] ;EXTRACT MANTISSA BITS OF STACK OPERAND MS AND BX,7FH ; KEEPING ORIGINAL ON STACK MOV CX,DX ;DITTO FOR REGISTER OPERAND AND CX,7FH ; CMP BX,CX ;COMPARE OPERAND MS PARTS JG COMPUTE ;GREATER ON STACK JL FCSWAP ;GREATER IN DX,AX CMP [BP+4],AX ;EQUAL,COMPARE LS HALVES JGE COMPUTE ;NO SWAP FCSWAP LABEL NEAR XCHG AX,[BP+4] ;SWAP OPERANDS XCHG DX,[BP+6] COMPUTE LABEL NEAR MOV BX,DX ;KEEP FOR SIGN MOV DH,0 ;CLEAR EXPONENT FIELD OR DL,80H ;SET HIDDEN 2**-1 SIGNTST LABEL NEAR XOR BX,[BP+6] ;FORM DIFFERENCE OF SIGNS MOV CX,[BP+6] ;RESULT EXPONENT AND SIGN AND CL,80H ;CLEAN UNUSED BITS AND WORD PTR[BP+6],007FH ;CLEAR EXPONENT OF STACK OPERAND OR BYTE PTR[BP+6],80H ;SET HIDDEN 2**-1 AND BX,0080H ;TEST DIFFERENCE OF SIGNS JNE SUBTRCT ;SUBTRACT IF SIGNS DIFFER ADD AX,[BP+4] ; ELSE ADD DOUBLE LENGTH ADC DX,[BP+6] JMP NORMAL SUBTRCT LABEL NEAR SUB [BP+4],AX ;SUBTRACT DOUBLE LENGTH SBB [BP+6],DX MOV AX,[BP+4] MOV DX,[BP+6] NORMAL LABEL NEAR CMP DH,0 ;NORMALISE JNE RIGHT ;RIGHT SHIFT REQUIRED CMP DL,0 JL SIGNEXP ;FINISHED WHEN DH ZERO AND DL 'SIGN' SET JNE LEFT ;LEFT SHIFT REQUIRED CMP AX,0 ;BEWARE NORMALISING ZERO JE CLEARUP LEFT LABEL NEAR ;LEFT SHIFT DOUBLE LENGTH 1 BIT SHL AX,1 RCL DX,1 DEC CH ;COMPENSATE EXPONENT JNE NORMAL ;LOOK FOR UNDERFLOW MOV AX,0 ;RESULT ZERO IF SO MOV CX,AX ;ALWAYS +ZERO RESULT JMP UOFLO RIGHT LABEL NEAR ;RIGHT SHIFT DOUBLE LENGTH 1 BIT SHR DX,1 RCR AX,1 INC CH ;COMPENSATE EXPONENT JNE SIGNEXP ;LOOK FOR OVERFLOW MOV AX,0FFFFH ;MAXIMUM + OR - VALUE IF SO UOFLO LABEL NEAR ;UNDER OR OVER FLOW MOV DL,AL ;PROPAGATE ALL OR NOTHING MOV CH,AL ;AND TO EXPONENT SIGNEXP LABEL NEAR ;RESULT SIGN AND EXPONENT AND DX,7FH ;MAKE CLEAN SPACE OR DX,CX ;INSERT SIGN AND EXPONENT CLEARUP LABEL NEAR POP BP RET 4 CF@SUB ENDP CF@CODE ENDS END