; 否则,指数为负,数字形式为 0.0..0XXX CPL A ; 将A取反加1,就是绝对值 INC A
MOV R6, A ; 放入R6用于迭代 SJMP R2R_PURE_DEC ; 纯小数
R2R_ZERO_E: ; RES2RAW, ZERO EXPONENT, FORMAT IS 0.XXXX MOV R6, 0 ; 指数为0
SJMP R2R_PURE_DEC ; 纯小数 ; ------------------------- R2R_PURE_DEC:
; 根据R6中存放的指数(已经由二进制补码的负数转换为正数)在 ; 小数点后面添加0
; 首先放置2个字符 '0' '.' MOV @R1, #00H ; '0' INC R1 INC DCOUNT MOV @R1, #0FFH ; '.' INC R1 INC DCOUNT
R2R_PAD_ZERO: ; 开始补0,根据R6值确定0的个数 MOV A, R6
; 如果指数为零则结束 JZ R2R_PAD_DONE ; 否则添加0 MOV @R1, #00H INC R1
INC DCOUNT ; DCOUNT 必须相应更新,包括'.' 和 '-' 的添加 ; 更新指数信息 DEC R6
SJMP R2R_PAD_ZERO ; -----------
R2R_PAD_DONE: ; 纯小数小数点后的补零完成
MOV R7, #02H ; R7为计数器,处理BCD浮点数的2个字节的尾数 R2R_EX_MAN: ; RES2RAW, EXTRACT MANTISSA ; 开始尾数提取
INC R0 ; 源地址指向第2个字节,即尾数 MOV A, @R0 ; 取出 ANL A, #0F0H ; 去掉低字节 SWAP A ; 高字节换到低字节 MOV @R1, A ; 保存结果 ; 更新目的状态 INC R1 INC DCOUNT
MOV A, @R0 ; 再次取数 ANL A, #0FH ; 屏蔽高字节 MOV @R1, A ; 储存
; 更新目的状态 INC R1 INC DCOUNT
DJNZ R7, R2R_EX_MAN ; 2个字节是否已完成?
; 纯小数的转换最终完成 RET
; ------------------------- ; RES2RAW, 指数为正的情况
; R6 中存放指数,当R6为零的时候,插入小数点 ; 例如,23.45,指数为2,当提取了数字2和3,指数 ; 迭代器减为0,应该插入小数点
; 例如,2345000,指数为7,当尾数提取完成,即2345时, ; 指数为3大于零,应该继续添加末尾的0,此时就没有小数点 R2R_POS_E:
; 小数点位,12.34的形式中,小数点添加后将此位置一 CLR DPB ; DECIMAL POINT BIT
MOV R6, A ; A 中已经保存了去掉ACC.7位的指数 INC R0 ; 源指针指向第2个字节,即尾数 ; 字节1 ; 高位
MOV A, @R0 ; 读入高位字节 ANL A, #0F0H
SWAP A ; 转换到低4位 ACALL R2R_PUSHD ; 低位 MOV A, @R0
ANL A, #0FH ; 保留低4位 ACALL R2R_PUSHD ; 字节2
INC R0 ; 指向字节2 ; 高位 MOV A, @R0
ANL A, #0F0H ; 保留高4位
SWAP A ; 转换到低4位 ACALL R2R_PUSHD ; 低位
MOV A, @R0 ; 重新读入 ANL A, #0FH ; 保留低4位
; 第2个字节的低4位不需要判断指数是否为 ; 0 来添加小数点,因为即使此时尾数变为0 ; 也表示这个数是非零结尾的整数 MOV @R1, A INC R1 INC DCOUNT
; 这时还要判断指数是否还有,有则添加0 (EG. 12340000)
R2R_PE_JUDGE_E: ; RES2RAW, POSITIVE EXPONENT, JUDGE THE EXPONENT MOV A, R6
JZ R2R_PE_DONE ; R6 已经为0,返回 ; 不为零
R2R_PE_PAD0: ; RES2RAW, POSITIVE EXPONETN, PAD ZERO ; 非零继续在末尾添加0 MOV @R1, #00H INC R1 INC DCOUNT
DJNZ R6, R2R_PE_PAD0 ; 继续判断指数是否为0 ; ---------------------------- R2R_PE_DONE: RET
; ------------------------
; 这是由 RES2RAW 调用的子程序 R2R_PUSHD: ; R2R, PUSH DIGIT
; 将 A 放入目的,并判断 R6 是否为0,是则加小数点 MOV @R1, A INC R1 INC DCOUNT
; 如果小数点已经写入,则R6已经为0,直接返回 JB DPB, R2R_PD_DONE ; DECIMAL POINT? DJNZ R6, R2R_PD_DONE ; 指数变为0,应该添加小数点 SETB DPB ; DECIMAL POINT BIT MOV @R1, #0FFH INC R1 INC DCOUNT
R2R_PD_DONE: ; R2R, PUSH DIGIT, DONE RET
; ------------------------
; ======================================================= ;***************************************** ; KEY
;***************************************** KEY: MOV DPTR,#2003H MOV A,#81H MOVX @DPTR,A KEY0:MOV DPTR,#2001H CLR A
MOVX @DPTR,A MOV DPTR,#2002H MOVX A,@DPTR CPL A ANL A,#0FH JZ KEY5
MOV R6,#0FEH MOV R7,#00H KEY1:MOV DPTR,#2001H
MOV A,R6 MOVX @DPTR,A MOV DPTR,#2002H MOVX A,@DPTR CPL A ANL A,#0FH JNZ KEY2 MOV A,R7 ADD A,#04H MOV R7,A MOV A,R6 RL A MOV R6,A JB ACC.4,KEY1 SJMP KEY KEY2: RRC A JC KEY3 INC R7 SJMP KEY2 KEY3: MOV R6,#21H MOV DPTR,#2001H
CLR A
MOVX @DPTR,A MOV DPTR,#2002H MOVX A,@DPTR CPL A ANL A,#0FH JZ KEY4 DJNZ R6,KEY3 KEY4: SETB P1.0 MOV DPTR,#TBK MOV A,R7
MOVC A,@A+DPTR MOV R7,A SJMP KEY6 KEY5: MOV A,#0F0H NOP KEY6: NOP RET ;--- TBK: ; 键盘布局
DB 07H, 08H, 09H, 10H ; 7 8 9 + DB 04H, 05H, 06H, 20H ; 4 5 6 - DB 01H, 02H, 03H, 30H ; 1 2 3 * DB 00H, 0FFH, 80H, 40H ; 0 . = /
;************************************** ;显示程序
;************************************** DISPLAY:
MOV DPTR, #DISPTAB MOV R0, #RAWIN MOV TEMP1, DCOUNT ; CLEAR THE SCREEN MOV COM, #01H LCALL PR1
MOV A, DCOUNT JZ DISP_ZERO
JB STAT.7, DISP_ERR DISP_NORMAL: MOV A, @R0 INC R0