[ บทความ : FP11 ] |
วันก่อนผมเอา Lib11 มาให้ดูเป็นตัวอย่างไปแล้ว .. .พอดี ผมไปเจอไฟล์ Fp11 เข้า เลยเอามาขึ้น web ให้นำไปใช้กันครับ ... หน้าที่ของ FP11 คือ เพิ่มความสามารถเรื่อง floating point (ตัวเลขแบบทศนิยม) ให้แก่ไมโครคอนโทรลเลอร์ 68hc11 นั่นเอง รายละเอียดของไฟล์ FP11.ASM เป็นดังนี้ครับ
********************************************************************** * Floating Point Package 22/1/86 * * written by R.Soja, Motorola * ********************************************************************** * All floating point routines use * * two, 3-byte operands located in RAM at OP1,OP2 * * Each is organised as: 7 bit exponent + 1 sign bit (2's complement)* * 15 bit mantissa + 1 sign bit * * (15 bit positive notation) * * Sign bit is always is always MSBit * * * * Routines implemented: * * 1. Addition MAD (FADD) OP1+OP2 * * 2. Subtraction MSB (FSUB) OP1-OP2 * * 3. Division MDV (FDIV) OP1/OP2 * * 4. Multiplication MML (FMUL) OP1*OP2 * * * * On exit from routine, OP1 contains result, OP2 is destroyed * * * * Two conversion routines are also included: * * FLOATINT converts FP number in OP1 to unsigned integer in ACCD * * INTFLOAT converts unsigned integer in ACCD to FP number in OP1 * * * ********************************************************************** * * Constants SYSRAM EQU 0 START EQU $E000 For EVM board. * * OP1, OP2 in RAM * ORG SYSRAM MANT1 RMB 2 EXP1 RMB 1 MANT2 RMB 2 EXP2 RMB 1 * ORG START MAD EQU * OP1 + OP2 => OP1 FADD EQU * BSR ALIGN BVS FADDEX If exponent difference too great, return. LDAA MANT1 Put sign bit of mantissa 1 in X reg. ANDA #$80 XGDX LDAA MANT1 EORA MANT2 BMI SUBMANT If signs are same BSR GETABS then add positive parts of mantissas. ADDD MANT2 BPL FADD1 if MSBit of result set, then result has INC EXP1 overflowed, so increment exponent, while BVC FADD2 limiting value to upper bound. DEC EXP1 LDD #$7FFF BRA FADD1 FADD2 LSRD FADD1 STX MANT2 Save sign bit STD MANT1 and result, prior to BSR NORM normalising it. FADDEX RTS Return to calling program segment. SUBMANT BSR GETABS If signs are different, SUBD MANT2 then subtract positive parts of mantissas. BSR CONVFP Change 2s compl result to floating point format BRA FADD1 and store result (X contains corrected sign bit) * GETABS BCLR MANT2,#$80 Clear sign bits in MANT2 LDD MANT1 and MANT1 in ACCD ANDA #$7F RTS * MSB EQU * OP1 - OP2 => OP1 FSUB EQU * LDAA MANT2 ADDA #$80 Negate sign of mantissa 2 STAA MANT2 and perform addition BRA FADD * ALIGN CLRA LDAB EXP1 SUBB EXP2 BPL POS If EXP1OP1 FDIV EQU * LDD MANT2 BEQ MAXRES Trap divide by 0 LDAA MANT1 EORA MANT2 BMI FDIV1 If signs are same LDY #0 then result sign is positive BRA FDIV2 FDIV1 LDY #$8000 else result sign is negative FDIV2 LDAB EXP1 SUBB EXP2 BVC FDIV3 If V bit set then its an under/overflow, so STAA MANT1 ! update result sign BCC MINRES ! If C bit clear then force result to min limit BRA MAXRES ! else force result to max limit, retaining sign FDIV3 STAB EXP1 Save result exponent. JSR GETABS Load ACCD with +ive part of MANT1 LDX MANT2 and X with +ive part of MANT2 IDIV STX MANT1 Store integer part of result in ACCD LDX MANT2 and reload denominator. FDIV XGDX Get result into ACCD COMBINE TST MANT1 BNE COMBINE1 TST MANT1+1 BEQ FDIV5 If non-zero integer part then COMBINE1 INC EXP1 combine it with fractional part CLC and adjust exponent accordingly ROR MANT1 ROR MANT1+1 RORA RORB BRA COMBINE FDIV5 LSRD Clear sign bit of adjusted result STY MANT2 ADDD MANT2 Update sign bit BRA NORM3 and store result, checking for -0 * MAXRES BSET MANT1,#$7F Maximise MSbyte of mantissa, retaining sign. LDD #$FF7F Maximise LSbyte of mantissa, and exponent. STD MANT1+1 RTS * MINRES CLRA Result = 0 CLRB STD MANT1 CLR EXP1 RTS * MML EQU * OP1 * OP2 => OP1 FMUL EQU * LDAB EXP1 First, add exponents. ADDB EXP2 BVC FMUL1 If V bit is set then its an under/overflow, so STAA MANT1 ! update result sign BCS MINRES ! If C bit set then force result to min limit BRA MAXRES ! else force result to max limit, retaining sign FMUL1 STAB EXP1 Store result exponent. LDAA MANT1 Evaluate result sign, and EORA MANT2 put it in X reg XGDX BCLR MANT1,#$80 Make both operands positive BCLR MANT2,#$80 BSR CONVFPI Convert MANT1,MANT2 to unsigned integer format * !and return with result sign + MANT1 in Y reg LDAA MANT1 multiply MSbytes of mantissas. LDAB MANT2 MUL XGDX Save 1st partial result in X LDAA MANT1+1 Cross multiply. LDAB MANT2 MUL ADCA #0 Round up and TAB CLRA restore weighting of partial result (in ACCD) STX MANT1 Add 1st and 2nd partial results ADDD MANT1 XGDX Store updated partial result. STY MANT1 Restore MANT1 LDAA MANT1 Cross multiply again. LDAB MANT2+1 MUL ADCA #0 Round up again. TAB CLRA Correctly weighted 3rd partial result now in ACCD STX MANT1 so add it to stored partial result. ADDD MANT1 BSR CONVIFP Convert integer in ACCD to FP format,and store. * Multiplication of LS bytes is unnecessary, as * the result will always overflow if both non-zero. RTS Return to calling program. * CONVFPI EQU * Enter with +ive MANT1,MANT2: result sign in X reg LSL MANT1+1 De-normalise both operands. ROL MANT1 LSL MANT2+1 ROL MANT2 LDD MANT1 CPX #0 Add result sign bit to ACCD BPL FPI1 ORAB #1 FPI1 XGDY and save result sign+operand 1 in Y. RTS * CONVIFP EQU * LDX #0 STX MANT2 STD MANT1 Temporarily store result. XGDY Move result sign bit LSRD ROR MANT2 to MANT2 before LDD MANT1 LSRD JSR NORM normalising result mantissa. IFP2 RTS Return with result stored in MANT1. * FLOATINT EQU * CLRB LDAA EXP1 If exponent <= 0 BGT FLTINT1 then clear ACCD and return. CLRA RTS FLTINT1 CLRA else LSL MANT1+1 adjust mantissa, destroying sign bit ROL MANT1 FLTINT2 LSL MANT1+1 then move mantissa into ACCD ROL MANT1 ROLB ROLA DEC EXP1 BNE FLTINT2 until exponent = 0 RTS * INTFLOAT EQU * On entry, unsigned integer in ACCD LDX #0 Initialise result mantissa STX MANT1 INX STX EXP1 and exponent. INTFLT1 LSRD Move integer to F.P. mantissa ROR MANT1 ROR MANT1+1 INC EXP1 adjusting exponent with every shift. CPD #0 BNE INTFLT1 When no more bits in ACCD ROR MANT1 clear sign bit as integer was always >=0 ROR MANT1+1 RTS *