-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathP7.asm
199 lines (184 loc) · 5.46 KB
/
P7.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
; ---------------------------------
; AUTHOR: Díaz García, Rodrigo
; DATE: 12 April 2017
; ASSIGNMENT: P7
; ---------------------------------
OUTPT EQU 041DH ; Function Output
RDKBD EQU 044EH ; Function Read Keyboard
ORG 1000H
MVI A, 08H ; Initialize A as interrupt mask
MVI B, FFH ; Initialize B
MVI C, FFH ; Initialize C
LXI SP, 2000H ; Initialize SP
SIM ; Set iterrupt mask
EI ; Enable interrupt
REP: ; Main loop
CALL RDKBD ; Wait until keypress
CALL CHKKP ; Check key
JMP REP ; Repeat
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; @function CHKKP
; @abstract Checks the pressed key
; @discussion Checks pressed key in port 0,
; stores numbers or executes
; mathematical operation.
; @input A Pressed key's ASCII
; @result M1600 First number's ASCII
; @result M1601 Second number's ASCII
; @result M1602 First result number's ASCII
; @result M1603 Second result number's ASCII
; @result M1604 Operation mode (0 = -, 1 = +)
; @result M1605 Result sign (0 = -, 1 = +)
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
CHKKP:
CPI 41H ; is key = 'a'?
JZ KPADD ; if true, addition
CPI 61H ; is key = 'A'?
JZ KPADD ; if true, addition
CPI 46H ; is key = 'f'?
JZ KPSUB ; if true, subtraction
CPI 66H ; is key = 'F'?
JZ KPSUB ; if true, subtraction
CPI 3AH ; is key > 39?
RNC ; if true, return
CPI 30H ; is key > 30?
JNC KPNUM ; if true, store number
RET ; Return
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; @subroutine KPADD
; @abstract Adds two numbers
; @discussion Adds two single digit numbers,
; stores result in memory.
; @input B First operand
; @input C Second operand
; @result M1602 First result number's ASCII
; @result M1603 Second result number's ASCII
; @result M1604 1 (Addition)
; @result M1605 1 (Positive)
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
KPADD:
LXI H, 1602H
MOV A, B ; A = B
ADD C ; A = B + C
DAA ; Convert A to BCD
MOV E, A ; Store result in E
ANI F0H ; Get first digit
RAR ; A=A/10
RAR ; A=A/10
RAR ; A=A/10
RAR ; A=A/10
ADI 30H ; Obtain ASCII
MOV M, A ; Store first result number's ASCII
INX H ; Next memory position
MOV A, E ; Load result
ANI FH ; Get second digit
ADI 30H ; Obtain ASCII
MOV M, A ; Store second result number's ASCII
INX H
MVI M, 1H ; mode = addition
INX H
MVI M, 1H ; sign = positive
CALL UPDATE ; Update screen
MVI B, FFH ; Empty B
MVI C, FFH ; Empty C
RET ; Return
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; @subroutine KPSUB
; @abstract Subtracts two numbers
; @discussion Subtracts two single digit numbers,
; obtains absolute value, and stores
; result and sign in memory.
; @input B First operand
; @input C Second operand
; @result M1602 30 (0)
; @result M1603 Absolute result's ASCII (|A-B|)
; @result M1604 0 (Subtraction)
; @result M1605 Result sign (0 = -, 1 = +)
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
KPSUB:
LXI H, 1602H
MVI M, 30H ; |Result| will always be < 10
INX H
MOV A, B ; A = B
CMP C ; is C > B?
JC ABS ; if true go to ABS
SUB C ; A = B - C
MOV E, A ; Store result in E
ADI 30H ; Obtain ASCII
MOV M, A ; Store result's ASCII
INX H
MVI M, 0H ; mode = subtraction
INX H
MVI M, 1H ; sign = positive
CALL UPDATE ; Update screen
MVI B, FFH ; Empty B
MVI C, FFH ; Empty C
RET ; Return
ABS:
MOV A, B ; A = B
SUB C ; A = B - C
XRI FFH ; A = NOT A
ADI 1H ; Fix XOR deviation
MOV E, A ; Store result in E
ADI 30H ; Obtain ASCII
MOV M, A ; Store result's ASCII
INX H
MVI M, 0H ; mode = subtraction
INX H
MVI M, 0H ; sign = negative
CALL UPDATE ; Update screen
MVI B, FFH ; Empty B
MVI C, FFH ; Empty C
RET ; Return
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; @subroutine KPNUM
; @abstract Stores number
; @discussion Decides where to store number,
; B/1600 for the first one and
; C/1601 for the second one.
; @input A Number's ASCII
; @result M1600 First number's ASCII
; @result B First number
; @result M1601 Second number's ASCII
; @result C Second number
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
KPNUM:
PUSH PSW ; Store state
MOV A, B ; obtain first stored number
CPI FFH ; is it empty?
JNZ ELSE ; if false, go to else
POP PSW ; Load state
STA 1600H ; Store as first number
SUI 30H ; Obtain number
MOV B, A ; Store number in B
RET ; Return
ELSE:
POP PSW ; Load state
STA 1601H ; Store as second number
SUI 30H ; Obtain number
MOV C, A ; Store number in C
RET ; Return
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; @function UPDATE
; @abstract Shows operation in screen
; @discussion Writes the 2 operands, the mode,
; the sign, and the result.
; @input M1600 First operand's ASCII
; @input M1601 Second operand's ASCII
; @input M1602 First result digit's ASCII
; @input M1603 Second result digit's ASCII
; @input M1604 Operation mode (0 = -, 1 = +)
; @input M1605 Result sign (0 = -, 1 = +)
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
UPDATE:
LXI H, 1604H ; Get mode
MVI A, 0H ; Select first screen half
MOV B, M ; Write dash if mode is subtraction
LXI H, 1600H ; Write both operands
OUTPT ; Write screen
LXI H, 1605H ; Get sign
MVI A, 1H; Select second screen half
MOV B, M ; Write dot if sign is negative
LXI H, 1602H ; Write result
OUTPT ; Write screen
RET ; Return