📄 calc.lst
字号:
ASEM-51 V1.2 Copyright (c) 1996 by W.W. Heinz PAGE 1
MCS-51 Family Cross Assembler A S E M - 5 1 V 1.2
=====================================================
Source File: CALC.ASM
Object File: CALC.HEX
List File: CALC.LST
Line I Addr Code Source
1: ;4 FUNCTION CALCULATOR PROGRAM
2: ;Assumes 1.2MHz Clock for scan timing.
3:
4:
5:
6: ; TODO : Custom Character for the 'M' sign
7: ; Check instances of multiple decimal point presses ( all covered ?)
8:
9: ;Reset vector
10: N 0000 org 0000h
11: 0000 02 01 00 jmp start
12:
13: ;Start of the program
14: N 0100 org 0100h
15:
16: 0100 74 30 start: mov A,#030h ;1 line, 8 bits
17: 0102 12 08 A9 call wrcmd
18: 0105 74 0C mov A,#LCD_SETVISIBLE + 4
19: 0107 12 08 A9 call wrcmd
20: 010A 74 8F mov A,#LCD_SETDDADDR+15 ; Start at right hand side of the display
21: 010C 12 08 A9 call wrcmd
22: 010F 74 07 mov A,#LCD_SETMODE + 3 ; Automatic Increment - Display shift left.
23: 0111 12 08 A9 call wrcmd
24:
25: 0114 75 25 00 mov 025h,#00h ; Set output mode (floating point).
26:
27: 0117 12 10 9C call boundsbuffer ; Initialise the bounds buffer - used for error chec
king.
28: 011A 75 6E 04 mov mode,#4 ; Initialise the constant buffer to 100. Primarily u
sed for % ops.
29: 011D 75 6D 31 mov digitcode,#031h
30: 0120 12 0E EA call storedigit
31: 0123 75 6D 30 mov digitcode,#030h
32: 0126 12 0E EA call storedigit
33: 0129 75 6D 30 mov digitcode,#030h
34: 012C 12 0E EA call storedigit
35:
36: 012F 75 67 00 mov status,#00h ; variable used to determine the first key press aft
er an operation.
37: 0132 75 6B 00 mov bufferctr,#00h
38: 0135 75 6C 00 mov opcounter,#00h
39: 0138 75 73 00 mov decimalcnt,#00h
40: 013B 12 09 83 call waitkey
ASEM-51 V1.2 Copyright (c) 1996 by W.W. Heinz PAGE 2
Line I Addr Code Source
41:
42: 013E 75 87 01 halt: mov PCON,#1 ;Halt
43:
44:
45: ;***********************************************************
46: ;**** Floating Point Package ****
47: ;********************************
48:
49: $INCLUDE (FP52.ASM)
50: 1 ; This is a complete BCD floating point package for the 8051 micro-
51: 1 ; controller. It provides 8 digits of accuracy with exponents that
52: 1 ; range from +127 to -127. The mantissa is in packed BCD, while the
53: 1 ; exponent is expressed in pseudo-twos complement. A ZERO exponent
54: 1 ; is used to express the number ZERO. An exponent value of 80H or
55: 1 ; greater than means the exponent is positive, i.e. 80H = E 0,
56: 1 ; 81H = E+1, 82H = E+2 and so on. If the exponent is 7FH or less,
57: 1 ; the exponent is negative, 7FH = E-1, 7EH = E-2, and so on.
58: 1 ; ALL NUMBERS ARE ASSUMED TO BE NORMALIZED and all results are
59: 1 ; normalized after calculation. A normalized mantissa is >=.10 and
60: 1 ; <=.99999999.
61: 1 ;
62: 1 ; The numbers in memory assumed to be stored as follows:
63: 1 ;
64: 1 ; EXPONENT OF ARGUMENT 2 = VALUE OF ARG_STACK+FP_NUMBER_SIZE
65: 1 ; SIGN OF ARGUMENT 2 = VALUE OF ARG_STACK+FP_NUMBER_SIZE-1
66: 1 ; DIGIT 78 OF ARGUMENT 2 = VALUE OF ARG_STACK+FP_NUMBER_SIZE-2
67: 1 ; DIGIT 56 OF ARGUMENT 2 = VALUE OF ARG_STACK+FP_NUMBER_SIZE-3
68: 1 ; DIGIT 34 OF ARGUMENT 2 = VALUE OF ARG_STACK+FP_NUMBER_SIZE-4
69: 1 ; DIGIT 12 OF ARGUMENT 2 = VALUE OF ARG_STACK+FP_NUMBER_SIZE-5
70: 1 ;
71: 1 ; EXPONENT OF ARGUMENT 1 = VALUE OF ARG_STACK
72: 1 ; SIGN OF ARGUMENT 1 = VALUE OF ARG_STACK-1
73: 1 ; DIGIT 78 OF ARGUMENT 1 = VALUE OF ARG_STACK-2
74: 1 ; DIGIT 56 OF ARGUMENT 1 = VALUE OF ARG_STACK-3
75: 1 ; DIGIT 34 OF ARGUMENT 1 = VALUE OF ARG_STACK-4
76: 1 ; DIGIT 12 OF ARGUMENT 1 = VALUE OF ARG_STACK-5
77: 1 ;
78: 1 ; The operations are performed thusly:
79: 1 ;
80: 1 ; ARG_STACK+FP_NUMBER_SIZE = ARG_STACK+FP_NUMBER_SIZE # ARG_STACK
81: 1 ;
82: 1 ; Which is ARGUMENT 2 = ARGUMENT 2 # ARGUMENT 1
83: 1 ;
84: 1 ; Where # can be ADD, SUBTRACT, MULTIPLY OR DIVIDE.
85: 1 ;
86: 1 ; Note that the stack gets popped after an operation.
87: 1 ;
88: 1 ; The FP_COMP instruction POPS the ARG_STACK TWICE and returns status.
89: 1 ;
90: 1 ;**********************************************************************
91: 1 ;
92: 1 $EJECT
ASEM-51 V1.2 Copyright (c) 1996 by W.W. Heinz PAGE 3
Line I Addr Code Source
93: 1 ;**********************************************************************
94: 1 ;
95: 1 ; STATUS ON RETURN - After performing an operation (+, -, *, /)
96: 1 ; the accumulator contains the following status
97: 1 ;
98: 1 ; ACCUMULATOR - BIT 0 - FLOATING POINT UNDERFLOW OCCURED
99: 1 ;
100: 1 ; - BIT 1 - FLOATING POINT OVERFLOW OCCURED
101: 1 ;
102: 1 ; - BIT 2 - RESULT WAS ZER0
103: 1 ;
104: 1 ; - BIT 3 - DIVIDE BY ZERO ATTEMPTED
105: 1 ;
106: 1 ; - BIT 4 - NOT USED, 0 RETURNED
107: 1 ;
108: 1 ; - BIT 5 - NOT USED, 0 RETURNED
109: 1 ;
110: 1 ; - BIT 6 - NOT USED, 0 RETURNED
111: 1 ;
112: 1 ; - BIT 7 - NOT USED, 0 RETURNED
113: 1 ;
114: 1 ; NOTE: When underflow occures, a ZERO result is returned.
115: 1 ; When overflow or divide by zero occures, a result of
116: 1 ; .99999999 E+127 is returned and it is up to the user
117: 1 ; to handle these conditions as needed in the program.
118: 1 ;
119: 1 ; NOTE: The Compare instruction returns F0 = 0 if ARG 1 = ARG 2
120: 1 ; and returns a CARRY FLAG = 1 if ARG 1 is > ARG 2
121: 1 ;
122: 1 ;***********************************************************************
123: 1 ;
124: 1 $EJECT
ASEM-51 V1.2 Copyright (c) 1996 by W.W. Heinz PAGE 4
Line I Addr Code Source
125: 1 ;***********************************************************************
126: 1 ;
127: 1 ; The following values MUST be provided by the user
128: 1 ;
129: 1 ;***********************************************************************
130: 1 ;
131: 1 N 0001 ARG_STACK_PAGE EQU 01h ;External memory page for arg stack
132: 1 N 0024 ARG_STACK EQU 24H ;ARGUMENT STACK POINTER
133: 1 N 0025 FORMAT EQU 25H ;LOCATION OF OUTPUT FORMAT BYTE
134: 1 ;OUTPUT EQU R5OUT ;CALL LOCATION TO OUTPUT A CHARACTER in R5
135: 1 N 0048 CONVT EQU 0048H ;String addr TO CONVERT NUMBERS
136: 1 B 31 INTGRC BIT 26H.1 ;BIT SET IF INTEGER ERROR
137: 1 B 33 ADD_IN BIT 26H.3 ;DCMPXZ IN BASIC BACKAGE
138: 1 B 36 ZSURP BIT 26H.6 ;ZERO SUPRESSION FOR HEX PRINT
139: 1 ;
140: 1 ;***********************************************************************
141: 1 ;
142: 1 ; The following equates are used internally
143: 1 ;
144: 1 ;***********************************************************************
145: 1 ;
146: 1 N 0006 FP_NUMBER_SIZE EQU 6
147: 1 N 0004 DIGIT EQU FP_NUMBER_SIZE-2
148: 1 N 0000 R0B0 EQU 0
149: 1 N 0001 R1B0 EQU 1
150: 1 N 0000 UNDERFLOW EQU 0
151: 1 N 0001 OVERFLOW EQU 1
152: 1 N 0002 ZERO EQU 2
153: 1 N 0003 ZERO_DIVIDE EQU 3
154: 1 ;
155: 1 ;***********************************************************************
156: 1 $EJECT
ASEM-51 V1.2 Copyright (c) 1996 by W.W. Heinz PAGE 5
Line I Addr Code Source
157: 1 ;**************************************************************
158: 1 ;
159: 1 ; The following internal locations are used by the math pack
160: 1 ; ordering is important and the FP_DIGITS must be bit
161: 1 ; addressable
162: 1 ;
163: 1 ;***************************************************************
164: 1 ;
165: 1 N 0028 FP_STATUS EQU 28H ;NOT used data pointer me
166: 1 N 0029 FP_TEMP EQU FP_STATUS+1 ;NOT USED
167: 1 N 002A FP_CARRY EQU FP_STATUS+2 ;USED FOR BITS
168: 1 N 002B FP_DIG12 EQU FP_CARRY+1
169: 1 N 002C FP_DIG34 EQU FP_CARRY+2
170: 1 N 002D FP_DIG56 EQU FP_CARRY+3
171: 1 N 002E FP_DIG78 EQU FP_CARRY+4
172: 1 N 002F FP_SIGN EQU FP_CARRY+5
173: 1 N 0030 FP_EXP EQU FP_CARRY+6
174: 1 B 78 MSIGN BIT FP_SIGN.0
175: 1 B 50 XSIGN BIT FP_CARRY.0
176: 1 B 51 FOUND_RADIX BIT FP_CARRY.1
177: 1 B 52 FIRST_RADIX BIT FP_CARRY.2
178: 1 B 53 DONE_LOAD BIT FP_CARRY.3
179: 1 N 002B FP_NIB1 EQU FP_DIG12
180: 1 N 002C FP_NIB2 EQU FP_NIB1+1
181: 1 N 002D FP_NIB3 EQU FP_NIB1+2
182: 1 N 002E FP_NIB4 EQU FP_NIB1+3
183: 1 N 002F FP_NIB5 EQU FP_NIB1+4
184: 1 N 0030 FP_NIB6 EQU FP_NIB1+5
185: 1 N 0031 FP_NIB7 EQU FP_NIB1+6
186: 1 N 0032 FP_NIB8 EQU FP_NIB1+7
187: 1 N 0033 FP_ACCX EQU FP_NIB1+8
188: 1 N 0034 FP_ACCC EQU FP_NIB1+9
189: 1 N 0035 FP_ACC1 EQU FP_NIB1+10
190: 1 N 0036 FP_ACC2 EQU FP_NIB1+11
191: 1 N 0037 FP_ACC3 EQU FP_NIB1+12
192: 1 N 0038 FP_ACC4 EQU FP_NIB1+13
193: 1 N 0039 FP_ACC5 EQU FP_NIB1+14
194: 1 N 003A FP_ACC6 EQU FP_NIB1+15
195: 1 N 003B FP_ACC7 EQU FP_NIB1+16
196: 1 N 003C FP_ACC8 EQU FP_NIB1+17
197: 1 N 003D FP_ACCS EQU FP_NIB1+18
198: 1 ;
199: 1 $EJECT
ASEM-51 V1.2 Copyright (c) 1996 by W.W. Heinz PAGE 6
Line I Addr Code Source
200: 1
201: 1 C 0141 FP_BASE EQU $
202: 1
203: 1 ;**************************************************************
204: 1 ;
205: 1 ; The floating point entry points and jump table
206: 1 ;
207: 1 ;**************************************************************
208: 1 ;
209: 1 0141 21 71 AJMP FLOATING_ADD
210: 1 0143 21 67 AJMP FLOATING_SUB
211: 1 0145 41 24 AJMP FLOATING_COMP
212: 1 0147 41 55 AJMP FLOATING_MUL
213: 1 0149 41 8A AJMP FLOATING_DIV
214: 1 014B 81 51 AJMP HEXSCAN
215: 1 014D 81 8A AJMP FLOATING_POINT_INPUT
216: 1 014F A1 42 AJMP FLOATING_POINT_OUTPUT
217: 1 0151 C1 BF AJMP CONVERT_BINARY_TO_ASCII_STRING
218: 1 0153 C1 66 AJMP CONVERT_ASCII_STRING_TO_BINARY
219: 1 0155 C1 9B AJMP MULNUM10
220: 1 0157 E1 07 AJMP HEXOUT
221: 1 ;
222: 1 ; the remaining jump to routines were extracted from basic52
223: 1 ; by me to make the floating point software stand alone
224: 1 ;
225: 1 0159 81 7E AJMP PUSHR2R0 ; INTEGER to FLOAT
226: 1 015B E1 4C AJMP IFIX ; FLOAT to INTEGER
227: 1 015D E1 8D AJMP PUSHAS ; PUSH R2:R0 TO ARGUMENT
228: 1 015F E1 89 AJMP POPAS ; POP ARGUMENT TO R3:R1
229: 1 0161 E1 AA AJMP MOVAS ; COPY ARGUMENT
230: 1 0163 E1 CE AJMP AINT ; INT FUNCTION
231: 1 0165 E1 F6 AJMP PUSHC ; PUSH ARG IN DPTR TO STACK
232: 1 ;
233: 1 $EJECT
ASEM-51 V1.2 Copyright (c) 1996 by W.W. Heinz PAGE 7
Line I Addr Code Source
234: 1 ;
235: 1 0167 FLOATING_SUB:
236: 1 ;
237: 1 0167 75 A0 01 MOV P2,#ARG_STACK_PAGE
238: 1 016A A8 24 MOV R0,ARG_STACK
239: 1 016C 18 DEC R0 ;POINT TO SIGN
240: 1 016D E2 MOVX A,@R0 ;READ SIGN
241: 1 016E B2 E0 CPL ACC.0
242: 1 0170 F2 MOVX @R0,A
243: 1 ;
244: 1 ;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
245: 1 ;
246: 1 0171 FLOATING_ADD:
247: 1 ;
248: 1 ;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
249: 1 ;
250: 1 ;
251: 1 0171 91 32 ACALL MDES1 ;R7=TOS EXP, R6=TOS-1 EXP, R4=TOS SIGN
252: 1 ;R3=TOS-1 SIGN, OPERATION IS R1 # R0
253: 1 ;
254: 1 0173 EF MOV A,R7 ;GET TOS EXPONENT
255: 1 0174 60 0D JZ POP_AND_EXIT ;IF TOS=0 THEN POP AND EXIT
256: 1 0176 BE 00 12 CJNE R6,#0,LOAD1 ;CLEAR CARRY EXIT IF ZERO
257: 1 ;
258: 1 ;**************************************************************
259: 1 ;
260: 1 0179 SWAP_AND_EXIT: ; Swap external args and return
261: 1 ;
262: 1 ;**************************************************************
263: 1 ;
264: 1 0179 91 26 ACALL LOAD_POINTERS
265: 1 017B 7F 06 MOV R7,#FP_NUMBER_SIZE
266: 1 ;
267: 1 017D E2 SE1: MOVX A,@R0 ;SWAP THE ARGUMENTS
268: 1 017E F3 MOVX @R1,A
269: 1 017F 18 DEC R0
270: 1 0180 19 DEC R1
271: 1 0181 DF FA DJNZ R7,SE1
272: 1 ;
273: 1 0183 POP_AND_EXIT:
274: 1 ;
275: 1 0183 E5 24 MOV A,ARG_STACK ;POP THE STACK
276: 1 0185 24 06 ADD A,#FP_NUMBER_SIZE
277: 1 0187 F5 24 MOV ARG_STACK,A
278: 1 0189 E4 CLR A
279: 1 018A 22 RET
280: 1 ;
281: 1 ;
282: 1 018B 9E LOAD1: SUBB A,R6 ;A = ARG 1 EXP - ARG 2 EXP
283: 1 018C 8F 30 MOV FP_EXP,R7 ;SAVE EXPONENT AND SIGN
284: 1 018E 8C 2F MOV FP_SIGN,R4
285: 1 0190 50 09 JNC LOAD2 ;ARG1 EXPONENT IS LARGER OR SAME
286: 1 0192 8E 30 MOV FP_EXP,R6
287: 1 0194 8B 2F MOV FP_SIGN,R3
288: 1 0196 F4 CPL A
289: 1 0197 04 INC A ;COMPENSATE FOR EXP DELTA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -