jb302@28
|
1 /* iset.c
|
jb302@28
|
2 * IR functions */
|
jb302@28
|
3 #include <stdlib.h>
|
jb302@28
|
4 #include "iset.h"
|
jb302@28
|
5 #include "mem.h"
|
jb302@28
|
6
|
jb302@28
|
7 /* useful macros */
|
jb302@28
|
8 #define NNN (IR & 0x07)
|
jb302@28
|
9 #define MMM ((IR & 0x38) >> 3)
|
jb302@28
|
10
|
jb302@28
|
11 /* 0x00 - NOP */
|
jb302@28
|
12 void
|
jb302@28
|
13 NOP(void) {
|
jb302@28
|
14 }
|
jb302@28
|
15
|
jb302@28
|
16 /* 0x08 - SET C
|
jb302@28
|
17 * 0x0A - SET BS
|
jb302@28
|
18 * 0x0C - SET IE */
|
jb302@28
|
19 void
|
jb302@28
|
20 SET(void) {
|
jb302@28
|
21 switch (IR) {
|
jb302@28
|
22
|
jb302@28
|
23 case 0x08:
|
jb302@29
|
24 set_flag(C, 0x01);
|
jb302@28
|
25 break;
|
jb302@28
|
26
|
jb302@28
|
27 case 0x0A:
|
jb302@29
|
28 set_flag(BS, 0x01);
|
jb302@28
|
29 break;
|
jb302@28
|
30
|
jb302@28
|
31 case 0x0C:
|
jb302@29
|
32 set_flag(IE, 0x01);
|
jb302@28
|
33 break;
|
jb302@28
|
34
|
jb302@28
|
35 default:
|
jb302@28
|
36 break;
|
jb302@28
|
37 }
|
jb302@28
|
38 }
|
jb302@28
|
39
|
jb302@28
|
40 /* 0x09 - CLR C
|
jb302@28
|
41 * 0x0B - CLR BS
|
jb302@28
|
42 * 0x0D - CLR IE */
|
jb302@28
|
43 void
|
jb302@28
|
44 CLR(void) {
|
jb302@28
|
45 switch (IR) {
|
jb302@28
|
46
|
jb302@28
|
47 case 0x09:
|
jb302@29
|
48 set_flag(C, 0x00);
|
jb302@28
|
49 break;
|
jb302@28
|
50
|
jb302@28
|
51 case 0x0B:
|
jb302@29
|
52 set_flag(BS, 0x00);
|
jb302@28
|
53 break;
|
jb302@28
|
54
|
jb302@28
|
55 case 0x0D:
|
jb302@29
|
56 set_flag(IE, 0x00);
|
jb302@28
|
57 break;
|
jb302@28
|
58
|
jb302@28
|
59 default:
|
jb302@28
|
60 break;
|
jb302@28
|
61 }
|
jb302@28
|
62 }
|
jb302@28
|
63
|
jb302@28
|
64 /* 0x0E - CPL C
|
jb302@28
|
65 * 0x0F - CPL A */
|
jb302@28
|
66 void
|
jb302@28
|
67 CPL(void) {
|
jb302@28
|
68 switch (IR) {
|
jb302@28
|
69
|
jb302@28
|
70 case 0x0E:
|
jb302@29
|
71 if (get_flag(C) == 0) {
|
jb302@29
|
72 set_flag(C, 0x01);
|
jb302@28
|
73 }
|
jb302@28
|
74 else {
|
jb302@29
|
75 set_flag(C, 0x00);
|
jb302@28
|
76 }
|
jb302@28
|
77
|
jb302@28
|
78 case 0x0F:
|
jb302@28
|
79 A = ~A;
|
jb302@28
|
80 break;
|
jb302@28
|
81
|
jb302@28
|
82 default:
|
jb302@28
|
83 break;
|
jb302@28
|
84 }
|
jb302@28
|
85 }
|
jb302@28
|
86
|
jb302@28
|
87 /* 0x10 - XCSD */
|
jb302@28
|
88 void
|
jb302@28
|
89 XCSD(void) {
|
jb302@28
|
90 tmpw = get_wide(SP);
|
jb302@28
|
91 set_wide(SP, get_wide(DPTR));
|
jb302@28
|
92 set_wide(DPTR, tmpw);
|
jb302@28
|
93 }
|
jb302@28
|
94
|
jb302@28
|
95 /* 0x11 - SFA */
|
jb302@28
|
96 void
|
jb302@28
|
97 SFA(void) {
|
jb302@28
|
98 A = flags;
|
jb302@28
|
99 }
|
jb302@28
|
100
|
jb302@28
|
101 /* 0x12 - LAF */
|
jb302@28
|
102 void
|
jb302@28
|
103 LAF(void) {
|
jb302@28
|
104 flags = A;
|
jb302@28
|
105 }
|
jb302@28
|
106
|
jb302@28
|
107 /* 0b00010XXX - special MOVs
|
jb302@28
|
108 * 0b00011XXX - direct, indirect and indexed MOVs
|
jb302@28
|
109 * 0b00100nnn - register-indirect MOVs - MOV @DPTR, Rn
|
jb302@28
|
110 * 0b00101nnn - immediate movs - MOV Rn, #data8
|
jb302@28
|
111 * 0b00110nnn - MOV Rn, A
|
jb302@28
|
112 * 0b00111nnn - MOV A, Rn
|
jb302@28
|
113 * 0b01mmmnnn - 64 register move instructions
|
jb302@28
|
114 *
|
jb302@28
|
115 * this is a mess */
|
jb302@28
|
116 void
|
jb302@28
|
117 MOV(void) {
|
jb302@28
|
118 switch (IR & 0x40) {
|
jb302@28
|
119
|
jb302@28
|
120 case 0x00:
|
jb302@28
|
121 switch (IR & 0xF8) {
|
jb302@28
|
122
|
jb302@29
|
123 /* 0b00010XXX - special MOVs*/
|
jb302@28
|
124 case 0x10:
|
jb302@28
|
125 switch (NNN) {
|
jb302@28
|
126
|
jb302@28
|
127 /* MOV DPTR, SP */
|
jb302@28
|
128 case 3:
|
jb302@28
|
129 set_wide(DPTR, get_wide(SP));
|
jb302@28
|
130 break;
|
jb302@28
|
131
|
jb302@28
|
132 /* MOV SP, DPTR */
|
jb302@28
|
133 case 4:
|
jb302@28
|
134 set_wide(SP, get_wide(DPTR));
|
jb302@28
|
135 break;
|
jb302@28
|
136
|
jb302@28
|
137 /* MOV A, #data8 */
|
jb302@28
|
138 case 5:
|
jb302@28
|
139 A = fetch();
|
jb302@28
|
140 break;
|
jb302@28
|
141
|
jb302@28
|
142 /* MOV SP, #data16 */
|
jb302@28
|
143 case 6:
|
jb302@28
|
144 set_wide(SP, fetch_wide());
|
jb302@28
|
145 break;
|
jb302@28
|
146
|
jb302@28
|
147 /* MOV DPTR, #data16 */
|
jb302@28
|
148 case 7:
|
jb302@28
|
149 set_wide(DPTR, fetch_wide());
|
jb302@28
|
150 break;
|
jb302@28
|
151
|
jb302@28
|
152 default:
|
jb302@28
|
153 break;
|
jb302@28
|
154 }
|
jb302@28
|
155 break;
|
jb302@28
|
156
|
jb302@29
|
157 /* 0b00011XXX - direct, indirect and indexed MOVs*/
|
jb302@28
|
158 case 0x18:
|
jb302@28
|
159 switch (NNN) {
|
jb302@28
|
160
|
jb302@28
|
161 /* MOV A, addr16 */
|
jb302@28
|
162 case 0:
|
jb302@28
|
163 set_wide(TMP, fetch_wide());
|
jb302@28
|
164 A = mem[get_wide(TMP)];
|
jb302@28
|
165 break;
|
jb302@28
|
166
|
jb302@28
|
167 /* MOV addr16, A */
|
jb302@28
|
168 case 1:
|
jb302@28
|
169 set_wide(TMP, fetch_wide());
|
jb302@28
|
170 mem[get_wide(TMP)] = A;
|
jb302@28
|
171 break;
|
jb302@28
|
172
|
jb302@28
|
173 /* MOV A, @A+DPTR */
|
jb302@28
|
174 case 2:
|
jb302@29
|
175 set_wide(TMP, A + get_wide(DPTR));
|
jb302@29
|
176 A = mem[get_wide(TMP)];
|
jb302@28
|
177 break;
|
jb302@28
|
178
|
jb302@28
|
179 /* MOV A, @A+PC */
|
jb302@28
|
180 case 3:
|
jb302@29
|
181 set_wide(TMP, A + get_wide(PC));
|
jb302@29
|
182 A = mem[TMP];
|
jb302@28
|
183 break;
|
jb302@28
|
184
|
jb302@28
|
185 /* MOV A, @addr16 */
|
jb302@28
|
186 case 4:
|
jb302@28
|
187 set_wide(TMP, fetch_wide());
|
jb302@28
|
188 A = mem[mem[get_wide(TMP)]];
|
jb302@28
|
189 break;
|
jb302@28
|
190
|
jb302@28
|
191 /* MOV @addr16, A */
|
jb302@28
|
192 case 5:
|
jb302@28
|
193 set_wide(TMP, fetch_wide());
|
jb302@28
|
194 mem[mem[get_wide(TMP)]] = A;
|
jb302@28
|
195 break;
|
jb302@28
|
196
|
jb302@28
|
197 /* MOV A, @DPTR */
|
jb302@28
|
198 case 6:
|
jb302@29
|
199 set_wide(TMP, get_wide(DPTR));
|
jb302@29
|
200 A = mem[get_wide(TMP)];
|
jb302@28
|
201 break;
|
jb302@28
|
202
|
jb302@28
|
203 /* MOV @DPTR, A */
|
jb302@28
|
204 case 7:
|
jb302@29
|
205 set_wide(TMP, get_wide(DPTR));
|
jb302@29
|
206 mem[get_wide(TMP)] = A;
|
jb302@28
|
207 break;
|
jb302@28
|
208
|
jb302@28
|
209 default:
|
jb302@28
|
210 break;
|
jb302@28
|
211 }
|
jb302@28
|
212 break;
|
jb302@28
|
213
|
jb302@29
|
214 /* 0b00100nnn - MOV @DPTR, Rn*/
|
jb302@28
|
215 case 0x20:
|
jb302@29
|
216 set_wide(TMP, get_wide(DPTR));
|
jb302@30
|
217 mem[get_wide(TMP)] = get_reg(NNN);
|
jb302@28
|
218 break;
|
jb302@28
|
219
|
jb302@29
|
220 /* 0b00101nnn - immediate movs - MOV Rn, #data8*/
|
jb302@28
|
221 case 0x28:
|
jb302@29
|
222 set_reg(NNN, fetch());
|
jb302@28
|
223 break;
|
jb302@28
|
224
|
jb302@29
|
225 /* 0b00110nnn - MOV Rn, A */
|
jb302@28
|
226 case 0x30:
|
jb302@29
|
227 set_reg(NNN, A);
|
jb302@28
|
228 break;
|
jb302@28
|
229
|
jb302@30
|
230 /* 0b00111nnn MOV A, Rn */
|
jb302@28
|
231 case 0x38:
|
jb302@29
|
232 A = get_reg(NNN);
|
jb302@28
|
233 break;
|
jb302@28
|
234
|
jb302@28
|
235 default:
|
jb302@28
|
236 break;
|
jb302@28
|
237 }
|
jb302@29
|
238 break;;
|
jb302@28
|
239
|
jb302@30
|
240 /* 0b01mmmnnn MOV Rm Rn
|
jb302@30
|
241 * if m == n: MOV Rm, @DPTR */
|
jb302@28
|
242 case 0x40:
|
jb302@29
|
243 if (NNN == MMM) {
|
jb302@29
|
244 set_wide(TMP, get_wide(DPTR));
|
jb302@29
|
245 set_reg(NNN, mem[get_wide(TMP)]);
|
jb302@29
|
246 }
|
jb302@29
|
247 else {
|
jb302@29
|
248 set_reg(MMM, get_reg(NNN));
|
jb302@29
|
249 }
|
jb302@28
|
250 break;
|
jb302@28
|
251
|
jb302@28
|
252 default:
|
jb302@28
|
253 break;
|
jb302@28
|
254 }
|
jb302@28
|
255 }
|
jb302@28
|
256
|
jb302@30
|
257
|
jb302@30
|
258 /* 0x80 - ANL A, R0
|
jb302@30
|
259 * 0x81 - ANL A, R1
|
jb302@30
|
260 * 0x82 - ANL A, R2
|
jb302@30
|
261 * 0x83 - ANL A, R3
|
jb302@30
|
262 * 0x84 - ANL A, DPH
|
jb302@30
|
263 * 0x85 - ANL A, DPL
|
jb302@30
|
264 * 0x86 - ANL A, #data8
|
jb302@30
|
265 * 0x87 - ANL A, @DPTR */
|
jb302@28
|
266 void
|
jb302@28
|
267 ANL(void) {
|
jb302@30
|
268 if (NNN < 6) {
|
jb302@30
|
269 A = A & get_reg(NNN);
|
jb302@30
|
270 }
|
jb302@30
|
271 else {
|
jb302@30
|
272 switch (NNN) {
|
jb302@30
|
273
|
jb302@30
|
274 case 6:
|
jb302@30
|
275 A = A & fetch();
|
jb302@30
|
276 break;
|
jb302@30
|
277
|
jb302@30
|
278 case 7:
|
jb302@30
|
279 set_wide(TMP, get_wide(DPTR));
|
jb302@30
|
280 A = A & mem[TMP];
|
jb302@30
|
281 break;
|
jb302@30
|
282 }
|
jb302@30
|
283 }
|
jb302@30
|
284 set_zp(A);
|
jb302@28
|
285 }
|
jb302@28
|
286
|
jb302@30
|
287 /* 0x88 - ORL A, R0
|
jb302@30
|
288 * 0x89 - ORL A, R1
|
jb302@30
|
289 * 0x8A - ORL A, R2
|
jb302@30
|
290 * 0x8B - ORL A, R3
|
jb302@30
|
291 * 0x8C - ORL A, DPH
|
jb302@30
|
292 * 0x8D - ORL A, DPL
|
jb302@30
|
293 * 0x8E - ORL A, #data8
|
jb302@30
|
294 * 0x8F - ORL A, @DPTR */
|
jb302@28
|
295 void
|
jb302@28
|
296 ORL(void) {
|
jb302@30
|
297 if (NNN < 6) {
|
jb302@30
|
298 A = A | get_reg(NNN);
|
jb302@30
|
299 }
|
jb302@30
|
300 else {
|
jb302@30
|
301 switch (NNN) {
|
jb302@30
|
302
|
jb302@30
|
303 case 6:
|
jb302@30
|
304 A = A | fetch();
|
jb302@30
|
305 break;
|
jb302@30
|
306
|
jb302@30
|
307 case 7:
|
jb302@30
|
308 set_wide(TMP, get_wide(DPTR));
|
jb302@30
|
309 A = A | mem[TMP];
|
jb302@30
|
310 break;
|
jb302@30
|
311 }
|
jb302@30
|
312 }
|
jb302@30
|
313 set_zp(A);
|
jb302@28
|
314 }
|
jb302@28
|
315
|
jb302@30
|
316 /* 0x90 - XRL A, R0
|
jb302@30
|
317 * 0x91 - XRL A, R1
|
jb302@30
|
318 * 0x92 - XRL A, R2
|
jb302@30
|
319 * 0x93 - XRL A, R3
|
jb302@30
|
320 * 0x94 - XRL A, DPH
|
jb302@30
|
321 * 0x95 - XRL A, DPL
|
jb302@30
|
322 * 0x96 - XRL A, #data8
|
jb302@30
|
323 * 0x97 - XRL A, @DPTR */
|
jb302@28
|
324 void
|
jb302@28
|
325 XRL(void) {
|
jb302@30
|
326 if (NNN < 6) {
|
jb302@30
|
327 A = A ^ get_reg(NNN);
|
jb302@30
|
328 }
|
jb302@30
|
329 else {
|
jb302@30
|
330 switch (NNN) {
|
jb302@30
|
331
|
jb302@30
|
332 case 6:
|
jb302@30
|
333 A = A ^ fetch();
|
jb302@30
|
334 break;
|
jb302@28
|
335
|
jb302@30
|
336 case 7:
|
jb302@30
|
337 set_wide(TMP, get_wide(DPTR));
|
jb302@30
|
338 A = A ^ mem[TMP];
|
jb302@30
|
339 break;
|
jb302@30
|
340 }
|
jb302@30
|
341 }
|
jb302@30
|
342 set_zp(A);
|
jb302@28
|
343 }
|
jb302@28
|
344
|
jb302@28
|
345 /* 0x98 - RL A */
|
jb302@28
|
346 void
|
jb302@28
|
347 RL(void) {
|
jb302@28
|
348 A = (A << 1) | (A >> 7);
|
jb302@28
|
349 }
|
jb302@28
|
350
|
jb302@28
|
351 /* 0x99 - RLC A */
|
jb302@28
|
352 void
|
jb302@28
|
353 RLC(void) {
|
jb302@30
|
354 tmpb = A;
|
jb302@30
|
355 A = (A << 1) | get_flag(C);
|
jb302@30
|
356 set_flag(C, tmpb >> 7);
|
jb302@28
|
357 }
|
jb302@28
|
358
|
jb302@28
|
359 /* 0x9A - RR A */
|
jb302@28
|
360 void
|
jb302@28
|
361 RR(void) {
|
jb302@28
|
362 A = (A >> 1) | (A << 7);
|
jb302@28
|
363 }
|
jb302@28
|
364
|
jb302@28
|
365 /* 0x9B - RRC A */
|
jb302@28
|
366 void
|
jb302@28
|
367 RRC(void) {
|
jb302@30
|
368 tmpb = A;
|
jb302@30
|
369 A = (A >> 1) | (get_flag(C) << 7);
|
jb302@30
|
370 set_flag(C, tmpb & 0x01);
|
jb302@28
|
371 }
|
jb302@28
|
372
|
jb302@28
|
373 /* 0x9C - INC DPTR
|
jb302@28
|
374 * 0x9E - INC A */
|
jb302@28
|
375 void
|
jb302@30
|
376 INC(void) {
|
jb302@30
|
377 switch (IR) {
|
jb302@30
|
378
|
jb302@30
|
379 case 0x9C:
|
jb302@30
|
380 tmpw = get_wide(DPTR);
|
jb302@30
|
381 if ((tmpw + 1) > 0xFFFF) {
|
jb302@30
|
382 set_flag(OV, 1);
|
jb302@30
|
383 }
|
jb302@30
|
384 set_wide(DPTR, tmpw + 1);
|
jb302@30
|
385 set_zp(DPL);
|
jb302@30
|
386 set_zp(DPH);
|
jb302@30
|
387 break;
|
jb302@30
|
388
|
jb302@30
|
389 case 0x9E:
|
jb302@30
|
390 if ((A + 1) > 0xFF) {
|
jb302@30
|
391 set_flag(OV, 1);
|
jb302@30
|
392 }
|
jb302@30
|
393 A++;
|
jb302@30
|
394 set_zp(A);
|
jb302@30
|
395
|
jb302@30
|
396 }
|
jb302@28
|
397 }
|
jb302@28
|
398
|
jb302@28
|
399 /* 0x9D - DEC DPTR
|
jb302@28
|
400 * 0x9F - DEC A */
|
jb302@28
|
401 void
|
jb302@28
|
402 DEC(void) {
|
jb302@30
|
403 switch (IR) {
|
jb302@30
|
404
|
jb302@30
|
405 case 0x9D:
|
jb302@30
|
406 tmpw = get_wide(DPTR);
|
jb302@30
|
407 if ((tmpw - 1) < 0) {
|
jb302@30
|
408 set_flag(OV, 1);
|
jb302@30
|
409 }
|
jb302@30
|
410 set_wide(DPTR, tmpw - 1);
|
jb302@30
|
411 set_zp(DPL);
|
jb302@30
|
412 set_zp(DPH);
|
jb302@30
|
413
|
jb302@30
|
414 case 0x9F:
|
jb302@30
|
415 if ((A - 1) < 0) {
|
jb302@30
|
416 set_flag(OV, 1);
|
jb302@30
|
417 }
|
jb302@30
|
418 A--;
|
jb302@30
|
419 set_zp(A);
|
jb302@30
|
420 }
|
jb302@28
|
421 }
|
jb302@28
|
422
|
jb302@30
|
423 /* 0xA0 - ADD A, R0
|
jb302@30
|
424 * 0xA1 - ADD A, R1
|
jb302@30
|
425 * 0xA2 - ADD A, R2
|
jb302@30
|
426 * 0xA3 - ADD A, R3
|
jb302@30
|
427 * 0xA4 - ADD A, DPH
|
jb302@30
|
428 * 0xA5 - ADD A, DPL
|
jb302@30
|
429 * 0xA6 - ADD A, #data8
|
jb302@30
|
430 * 0xA7 - ADD A, @DPTR */
|
jb302@28
|
431 void
|
jb302@28
|
432 ADD(void) {
|
jb302@30
|
433 if (NNN < 6) {
|
jb302@31
|
434 if ((A + get_reg(NNN)) > 0xFF) {
|
jb302@31
|
435 set_flag(OV, 1);
|
jb302@31
|
436 }
|
jb302@31
|
437 else {
|
jb302@31
|
438 set_flag(OV, 0);
|
jb302@30
|
439 }
|
jb302@30
|
440 A = A + get_reg(NNN);
|
jb302@30
|
441 set_zp(A);
|
jb302@30
|
442 }
|
jb302@30
|
443 else {
|
jb302@30
|
444 switch (NNN) {
|
jb302@30
|
445
|
jb302@30
|
446 case 6:
|
jb302@31
|
447 tmpb = fetch();
|
jb302@31
|
448 if ((A + tmpb) > 0xFF) {
|
jb302@31
|
449 set_flag(OV, 1);
|
jb302@31
|
450 }
|
jb302@31
|
451 else {
|
jb302@31
|
452 set_flag(OV, 0);
|
jb302@31
|
453 }
|
jb302@31
|
454 A = A + tmpb;
|
jb302@30
|
455 set_zp(A);
|
jb302@30
|
456 break;
|
jb302@30
|
457
|
jb302@30
|
458 case 7:
|
jb302@30
|
459 set_wide(TMP, get_wide(DPTR));
|
jb302@31
|
460 if ((A + mem[TMP]) > 0xFF) {
|
jb302@31
|
461 set_flag(OV, 1);
|
jb302@31
|
462 }
|
jb302@31
|
463 else {
|
jb302@31
|
464 set_flag(OV, 0);
|
jb302@31
|
465 }
|
jb302@30
|
466 A = A + mem[TMP];
|
jb302@30
|
467 set_zp(A);
|
jb302@30
|
468 break;
|
jb302@30
|
469 }
|
jb302@30
|
470 }
|
jb302@30
|
471
|
jb302@28
|
472 }
|
jb302@28
|
473
|
jb302@35
|
474 /* 0xA8 - ADDC A, R0
|
jb302@35
|
475 * 0xA9 - ADDC A, R1
|
jb302@35
|
476 * 0xAA - ADDC A, R2
|
jb302@35
|
477 * 0xAB - ADDC A, R3
|
jb302@35
|
478 * 0xAC - ADDC A, DPH
|
jb302@35
|
479 * 0xAD - ADDC A, DPL
|
jb302@35
|
480 * 0xAE - ADDC A, #data8
|
jb302@35
|
481 * 0xAF - ADDC A, @DPTR */
|
jb302@28
|
482 void
|
jb302@28
|
483 ADDC(void) {
|
jb302@35
|
484 if (NNN < 6) {
|
jb302@35
|
485 if ((A + get_reg(NNN) + get_flag(C)) > 0xFF) {
|
jb302@35
|
486 set_flag(C, 1);
|
jb302@35
|
487 }
|
jb302@35
|
488 else {
|
jb302@35
|
489 set_flag(C, 0);
|
jb302@35
|
490 }
|
jb302@35
|
491 A = A + get_reg(NNN) + get_flag(C);
|
jb302@35
|
492 set_zp(A);
|
jb302@35
|
493 }
|
jb302@35
|
494 else {
|
jb302@35
|
495 switch (NNN) {
|
jb302@35
|
496
|
jb302@35
|
497 case 6:
|
jb302@35
|
498 tmpb = fetch();
|
jb302@35
|
499 if ((A + tmpb + get_flag(C)) > 0xFF) {
|
jb302@35
|
500 set_flag(C, 1);
|
jb302@35
|
501 }
|
jb302@35
|
502 else {
|
jb302@35
|
503 set_flag(C, 0);
|
jb302@35
|
504 }
|
jb302@35
|
505 A = A + tmpb + get_flag(C);
|
jb302@35
|
506 set_zp(A);
|
jb302@35
|
507 break;
|
jb302@35
|
508
|
jb302@35
|
509 case 7:
|
jb302@35
|
510 set_wide(TMP, get_wide(DPTR));
|
jb302@35
|
511 if ((A + mem[TMP] + get_flag(C)) > 0xFF) {
|
jb302@35
|
512 set_flag(C, 1);
|
jb302@35
|
513 }
|
jb302@35
|
514 else {
|
jb302@35
|
515 set_flag(C, 0);
|
jb302@35
|
516 }
|
jb302@35
|
517 A = A + mem[TMP] + get_flag(C);
|
jb302@35
|
518 set_zp(A);
|
jb302@35
|
519 break;
|
jb302@35
|
520 }
|
jb302@35
|
521 }
|
jb302@35
|
522
|
jb302@35
|
523
|
jb302@28
|
524 }
|
jb302@28
|
525
|
jb302@30
|
526 /* 0xB0 - SUB A, R0
|
jb302@30
|
527 * 0xB1 - SUB A, R1
|
jb302@30
|
528 * 0xB2 - SUB A, R2
|
jb302@30
|
529 * 0xB3 - SUB A, R3
|
jb302@35
|
530 * 0xB4 - SB A, DPH
|
jb302@30
|
531 * 0xB5 - SUB A, DPL
|
jb302@30
|
532 * 0xB6 - SUB A, #data8
|
jb302@30
|
533 * 0xB7 - SUB A, @DPTR */
|
jb302@28
|
534 void
|
jb302@28
|
535 SUB(void) {
|
jb302@30
|
536 if (NNN < 6) {
|
jb302@31
|
537 if ((A - get_reg(NNN)) < 0){
|
jb302@34
|
538 set_flag(S, 1);
|
jb302@31
|
539 }
|
jb302@31
|
540 else {
|
jb302@34
|
541 set_flag(S, 0);
|
jb302@31
|
542 }
|
jb302@30
|
543 A = A - get_reg(NNN);
|
jb302@30
|
544 set_zp(A);
|
jb302@30
|
545 }
|
jb302@30
|
546 else {
|
jb302@30
|
547 switch (NNN) {
|
jb302@30
|
548
|
jb302@30
|
549 case 6:
|
jb302@31
|
550 tmpb = fetch();
|
jb302@31
|
551 if ((A - tmpb) < 0) {
|
jb302@34
|
552 set_flag(S, 1);
|
jb302@31
|
553 }
|
jb302@31
|
554 else {
|
jb302@34
|
555 set_flag(S, 0);
|
jb302@31
|
556 }
|
jb302@31
|
557 A = A - tmpb;
|
jb302@30
|
558 set_zp(A);
|
jb302@30
|
559 break;
|
jb302@30
|
560
|
jb302@30
|
561 case 7:
|
jb302@30
|
562 set_wide(TMP, get_wide(DPTR));
|
jb302@31
|
563 if ((A - mem[TMP]) < 0) {
|
jb302@34
|
564 set_flag(S, 1);
|
jb302@31
|
565 }
|
jb302@31
|
566 else {
|
jb302@34
|
567 set_flag(S, 0);
|
jb302@31
|
568 }
|
jb302@30
|
569 A = A - mem[TMP];
|
jb302@30
|
570 set_zp(A);
|
jb302@30
|
571 break;
|
jb302@30
|
572 }
|
jb302@30
|
573 }
|
jb302@28
|
574 }
|
jb302@28
|
575
|
jb302@35
|
576 /* 0xB8 - SUBB A, R0
|
jb302@35
|
577 * 0xB9 - SUBB A, R1
|
jb302@35
|
578 * 0xBA - SUBB A, R2
|
jb302@35
|
579 * 0xBB - SUBB A, R3
|
jb302@35
|
580 * 0xBC - SUBB A, DPH
|
jb302@35
|
581 * 0xBD - SUBB A, DPL
|
jb302@35
|
582 * 0xBE - SUBB A, #data8
|
jb302@35
|
583 * 0xBF - SUBB A, @DPTR */
|
jb302@28
|
584 void
|
jb302@28
|
585 SUBB(void) {
|
jb302@35
|
586 if (NNN < 6) {
|
jb302@35
|
587 if ((A - get_reg(NNN) - get_flag(C)) < 0){
|
jb302@35
|
588 set_flag(C, 1);
|
jb302@35
|
589 }
|
jb302@35
|
590 else {
|
jb302@35
|
591 set_flag(C, 0);
|
jb302@35
|
592 }
|
jb302@35
|
593 A = A - get_reg(NNN) -get_flag(C);
|
jb302@35
|
594 set_zp(A);
|
jb302@35
|
595 }
|
jb302@35
|
596 else {
|
jb302@35
|
597 switch (NNN) {
|
jb302@35
|
598
|
jb302@35
|
599 case 6:
|
jb302@35
|
600 tmpb = fetch();
|
jb302@35
|
601 if ((A - tmpb - get_flag(C)) < 0) {
|
jb302@35
|
602 set_flag(C, 1);
|
jb302@35
|
603 }
|
jb302@35
|
604 else {
|
jb302@35
|
605 set_flag(C, 0);
|
jb302@35
|
606 }
|
jb302@35
|
607 A = A - tmpb - get_flag(C);
|
jb302@35
|
608 set_zp(A);
|
jb302@35
|
609 break;
|
jb302@35
|
610
|
jb302@35
|
611 case 7:
|
jb302@35
|
612 set_wide(TMP, get_wide(DPTR));
|
jb302@35
|
613 if ((A - mem[TMP] - get_flag(C)) < 0) {
|
jb302@35
|
614 set_flag(C, 1);
|
jb302@35
|
615 }
|
jb302@35
|
616 else {
|
jb302@35
|
617 set_flag(C, 0);
|
jb302@35
|
618 }
|
jb302@35
|
619 A = A - mem[TMP] - get_flag(C);
|
jb302@35
|
620 set_zp(A);
|
jb302@35
|
621 break;
|
jb302@35
|
622 }
|
jb302@35
|
623 }
|
jb302@28
|
624 }
|
jb302@28
|
625
|
jb302@28
|
626 void
|
jb302@28
|
627 PJMP(void) {
|
jb302@28
|
628 /* implement me */
|
jb302@28
|
629 }
|
jb302@28
|
630
|
jb302@28
|
631 void
|
jb302@28
|
632 PCALL(void) {
|
jb302@28
|
633 /* implement me */
|
jb302@28
|
634 }
|
jb302@28
|
635
|
jb302@28
|
636 /* 0xD0 - DJNZ R0, rel8
|
jb302@28
|
637 * 0xD1 - DJNZ R1, rel8
|
jb302@28
|
638 * 0xD2 - DJNZ R2, rel8
|
jb302@28
|
639 * 0xD3 - DJNZ R3, rel8 */
|
jb302@28
|
640 void
|
jb302@28
|
641 DJNZ(void) {
|
jb302@35
|
642 set_reg(NNN, get_reg(NNN) - 1);
|
jb302@35
|
643 if (get_reg(NNN) == 0) {
|
jb302@35
|
644 set_wide(PC, get_wide(PC) + (signed char)fetch() - 1);
|
jb302@35
|
645 }
|
jb302@35
|
646 else {
|
jb302@35
|
647 inc_pc(1);
|
jb302@35
|
648 }
|
jb302@28
|
649 }
|
jb302@28
|
650
|
jb302@35
|
651 /* 0xD4 - CJNE R0, #data, rel8
|
jb302@35
|
652 * 0xD5 - CJNE R1, #data, rel8
|
jb302@35
|
653 * 0xD6 - CJNE R2, #data, rel8
|
jb302@35
|
654 * 0xD7 - CJNE R3, #data, rel8
|
jb302@35
|
655 * 0xDF - CJNE A, #data8, rel8 */
|
jb302@28
|
656 void
|
jb302@28
|
657 CJNE(void) {
|
jb302@35
|
658 switch(IR) {
|
jb302@35
|
659
|
jb302@35
|
660 case 0xDF:
|
jb302@35
|
661 tmpb = fetch();
|
jb302@35
|
662 if (tmpb != A) {
|
jb302@35
|
663 set_wide(PC, get_wide(PC) + (signed char)fetch() - 1);
|
jb302@35
|
664 }
|
jb302@35
|
665 else {
|
jb302@35
|
666 inc_pc(1);
|
jb302@35
|
667 }
|
jb302@35
|
668 break;
|
jb302@35
|
669
|
jb302@35
|
670
|
jb302@35
|
671 default:
|
jb302@35
|
672 tmpb = fetch();
|
jb302@35
|
673 if (tmpb != get_reg(NNN - 4)) {
|
jb302@35
|
674 set_wide(PC, get_wide(PC) + (signed char)fetch() - 1);
|
jb302@35
|
675 }
|
jb302@35
|
676 else {
|
jb302@35
|
677 inc_pc(1);
|
jb302@35
|
678 }
|
jb302@35
|
679 break;
|
jb302@35
|
680 }
|
jb302@28
|
681 }
|
jb302@28
|
682
|
jb302@28
|
683 /* 0xD8 - LJMP addr16 */
|
jb302@28
|
684 void
|
jb302@28
|
685 LJMP(void) {
|
jb302@35
|
686 set_wide(PC, fetch_wide());
|
jb302@28
|
687 }
|
jb302@28
|
688
|
jb302@35
|
689 /* 0xD9 - LCALL addr16 */
|
jb302@28
|
690 void
|
jb302@28
|
691 LCALL(void) {
|
jb302@35
|
692 /* push PC to stack */
|
jb302@35
|
693 mem[get_wide(SP)] = get_reg(PCL);
|
jb302@35
|
694 set_wide(SP, get_wide(SP) + 1);
|
jb302@35
|
695 mem[get_wide(SP)] = get_reg(PCH);
|
jb302@35
|
696 set_wide(SP, get_wide(SP) + 1);
|
jb302@35
|
697 /* jmp */
|
jb302@35
|
698 set_wide(PC, fetch_wide());
|
jb302@28
|
699 }
|
jb302@28
|
700
|
jb302@35
|
701 /* 0xDA - RET */
|
jb302@28
|
702 void
|
jb302@28
|
703 RET(void) {
|
jb302@35
|
704 /* get PC from stack */
|
jb302@35
|
705 set_wide(SP, get_wide(SP) - 1);
|
jb302@35
|
706 tmpb = mem[get_wide(SP)]; /* PCH */
|
jb302@35
|
707 set_wide(SP, get_wide(SP) - 1);
|
jb302@35
|
708 set_wide(PC, MWIDE(tmpb, mem[get_wide(SP)]));
|
jb302@28
|
709 }
|
jb302@28
|
710
|
jb302@28
|
711 void
|
jb302@28
|
712 RETI(void) {
|
jb302@28
|
713 /* implement me */
|
jb302@28
|
714 }
|
jb302@28
|
715
|
jb302@28
|
716 /* 0xDC - SJMP rel8 */
|
jb302@28
|
717 void
|
jb302@28
|
718 SJMP(void) {
|
jb302@34
|
719 /* -1 because the fetch() increments the PC */
|
jb302@34
|
720 set_wide(PC, get_wide(PC) + (signed char)fetch() -1);
|
jb302@28
|
721 }
|
jb302@28
|
722
|
jb302@28
|
723 /* 0xDD - JMP @A+DPTR
|
jb302@28
|
724 * 0xDE - JMP @DPTR */
|
jb302@28
|
725 void
|
jb302@28
|
726 JMP(void) {
|
jb302@34
|
727 switch(IR) {
|
jb302@34
|
728
|
jb302@34
|
729 case 0xDD:
|
jb302@34
|
730 set_wide(PC, A + get_wide(DPTR));
|
jb302@34
|
731 break;
|
jb302@34
|
732
|
jb302@34
|
733 case 0xDE:
|
jb302@34
|
734 set_wide(PC, get_wide(DPTR));
|
jb302@34
|
735 break;
|
jb302@34
|
736 }
|
jb302@28
|
737 }
|
jb302@28
|
738
|
jb302@34
|
739 /* 0xE0 - JZ rel8 */
|
jb302@28
|
740 void
|
jb302@34
|
741 JZ(void) {
|
jb302@34
|
742 if (get_flag(Z) == 1) {
|
jb302@34
|
743 set_wide(PC, get_wide(PC) + (signed char)fetch() -1);
|
jb302@34
|
744 }
|
jb302@34
|
745 /* skip rel8 if jump not needed */
|
jb302@34
|
746 else {
|
jb302@34
|
747 inc_pc(1);
|
jb302@34
|
748 }
|
jb302@28
|
749 }
|
jb302@28
|
750
|
jb302@34
|
751 /* 0xE1 - JNZ rel8 */
|
jb302@28
|
752 void
|
jb302@28
|
753 JNZ(void) {
|
jb302@34
|
754 if (get_flag(Z) == 0) {
|
jb302@34
|
755 set_wide(PC, get_wide(PC) + (signed char)fetch() -1);
|
jb302@34
|
756 }
|
jb302@34
|
757 else {
|
jb302@34
|
758 inc_pc(1);
|
jb302@34
|
759 }
|
jb302@28
|
760 }
|
jb302@28
|
761
|
jb302@34
|
762 /* 0xE2 - JC rel8 */
|
jb302@28
|
763 void
|
jb302@34
|
764 JC(void) {
|
jb302@34
|
765 if (get_flag(C) == 1) {
|
jb302@34
|
766 set_wide(PC, get_wide(PC) + (signed char)fetch() -1);
|
jb302@34
|
767 }
|
jb302@34
|
768 else {
|
jb302@34
|
769 inc_pc(1);
|
jb302@34
|
770 }
|
jb302@28
|
771 }
|
jb302@28
|
772
|
jb302@34
|
773 /* 0xE3 - JNC rel8 */
|
jb302@28
|
774 void
|
jb302@34
|
775 JNC(void) {
|
jb302@34
|
776 if (get_flag(C) == 0) {
|
jb302@34
|
777 set_wide(PC, get_wide(PC) + (signed char)fetch() -1);
|
jb302@34
|
778 }
|
jb302@34
|
779 else {
|
jb302@34
|
780 inc_pc(1);
|
jb302@34
|
781 }
|
jb302@28
|
782 }
|
jb302@28
|
783
|
jb302@34
|
784 /* 0xE4 - JPO rel8 */
|
jb302@28
|
785 void
|
jb302@34
|
786 JPO(void) {
|
jb302@34
|
787 /* P = 1 when parity even */
|
jb302@34
|
788 if (get_flag(P) == 0) {
|
jb302@34
|
789 set_wide(PC, get_wide(PC) + (signed char)fetch() -1);
|
jb302@34
|
790 }
|
jb302@34
|
791 else {
|
jb302@34
|
792 inc_pc(1);
|
jb302@34
|
793 }
|
jb302@34
|
794
|
jb302@28
|
795 }
|
jb302@28
|
796
|
jb302@34
|
797 /* 0xE5 - JPE rel8 */
|
jb302@28
|
798 void
|
jb302@28
|
799 JPE(void) {
|
jb302@34
|
800 if (get_flag(P) == 1) {
|
jb302@34
|
801 set_wide(PC, get_wide(PC) + (signed char)fetch() -1);
|
jb302@34
|
802 }
|
jb302@34
|
803 else {
|
jb302@34
|
804 inc_pc(1);
|
jb302@34
|
805 }
|
jb302@28
|
806 }
|
jb302@28
|
807
|
jb302@34
|
808 /* 0xE6 - JS rel8 */
|
jb302@28
|
809 void
|
jb302@34
|
810 JS(void) {
|
jb302@34
|
811 if (get_flag(S) == 1) {
|
jb302@34
|
812 set_wide(PC, get_wide(PC) + (signed char)fetch() -1);
|
jb302@34
|
813 }
|
jb302@34
|
814 else {
|
jb302@34
|
815 inc_pc(1);
|
jb302@34
|
816 }
|
jb302@28
|
817 }
|
jb302@28
|
818
|
jb302@34
|
819 /* 0xE7 - JNS rel8 */
|
jb302@28
|
820 void
|
jb302@28
|
821 JNS(void) {
|
jb302@34
|
822 if (get_flag(S) == 0) {
|
jb302@34
|
823 set_wide(PC, get_wide(PC) + (signed char)fetch() -1);
|
jb302@34
|
824 }
|
jb302@34
|
825 else {
|
jb302@34
|
826 inc_pc(1);
|
jb302@34
|
827 }
|
jb302@28
|
828 }
|
jb302@28
|
829
|
jb302@35
|
830 /* 0xE8 - PUSH R0
|
jb302@35
|
831 * 0xE9 - PUSH R1
|
jb302@35
|
832 * 0xEA - PUSH R2
|
jb302@35
|
833 * 0xEB - PUSH R3
|
jb302@35
|
834 * 0xEC - PUSH DPH
|
jb302@35
|
835 * 0xED - PUSH DPL
|
jb302@35
|
836 * 0xEE - PUSH A
|
jb302@35
|
837 * 0xEF - PUSH FLAGS */
|
jb302@28
|
838 void
|
jb302@28
|
839 PUSH(void) {
|
jb302@35
|
840 if (NNN < 6) {
|
jb302@35
|
841 mem[get_wide(SP)] = get_reg(NNN);
|
jb302@35
|
842 set_wide(SP, get_wide(SP) + 1);
|
jb302@35
|
843
|
jb302@35
|
844 }
|
jb302@35
|
845 else {
|
jb302@35
|
846 switch(IR) {
|
jb302@35
|
847
|
jb302@35
|
848 case 0xEE:
|
jb302@35
|
849 mem[get_wide(SP)] = A;
|
jb302@35
|
850 set_wide(SP, get_wide(SP) + 1);
|
jb302@35
|
851 break;
|
jb302@35
|
852
|
jb302@35
|
853 case 0xEF:
|
jb302@35
|
854 mem[get_wide(SP)] = flags;
|
jb302@35
|
855 set_wide(SP, get_wide(SP) + 1);
|
jb302@35
|
856 break;
|
jb302@35
|
857
|
jb302@35
|
858 default:
|
jb302@35
|
859 break;
|
jb302@35
|
860 }
|
jb302@35
|
861 }
|
jb302@28
|
862 }
|
jb302@28
|
863
|
jb302@35
|
864 /* 0xF0 - POP R0
|
jb302@35
|
865 * 0xF1 - POP R1
|
jb302@35
|
866 * 0xF2 - POP R2
|
jb302@35
|
867 * 0xF3 - POP R3
|
jb302@35
|
868 * 0xF4 - POP DPH
|
jb302@35
|
869 * 0xF5 - POP DPL
|
jb302@35
|
870 * 0xF6 - POP A
|
jb302@35
|
871 * 0xF7 - POP FLAGS */
|
jb302@28
|
872 void
|
jb302@35
|
873 POP(void) {
|
jb302@35
|
874 if (NNN < 6) {
|
jb302@35
|
875 set_wide(SP, get_wide(SP) - 1);
|
jb302@35
|
876 set_reg(NNN, mem[get_wide(SP)]);
|
jb302@35
|
877 }
|
jb302@35
|
878 else {
|
jb302@35
|
879 switch(IR) {
|
jb302@35
|
880
|
jb302@35
|
881 case 0xF6:
|
jb302@35
|
882 set_wide(SP, get_wide(SP) - 1);
|
jb302@35
|
883 A = mem[get_wide(SP)];
|
jb302@35
|
884 break;
|
jb302@35
|
885
|
jb302@35
|
886 case 0xF7:
|
jb302@35
|
887 set_wide(SP, get_wide(SP) - 1);
|
jb302@35
|
888 flags = mem[get_wide(SP)];
|
jb302@35
|
889 break;
|
jb302@35
|
890
|
jb302@35
|
891 default:
|
jb302@35
|
892 break;
|
jb302@35
|
893 }
|
jb302@35
|
894 }
|
jb302@28
|
895 }
|
jb302@28
|
896
|
jb302@35
|
897
|
jb302@35
|
898 /* 0xF8 - MUL R0, R1 */
|
jb302@28
|
899 void
|
jb302@35
|
900 MUL(void) {
|
jb302@42
|
901 tmpw = regs[R0] * regs[R1];
|
jb302@42
|
902 regs[R0] = GHIGH(tmpw);
|
jb302@42
|
903 regs[R1] = GLOW(tmpw);
|
jb302@28
|
904 }
|
jb302@28
|
905
|
jb302@35
|
906 /* 0xF9 - DIV R0, R1 */
|
jb302@28
|
907 void
|
jb302@35
|
908 DIV(void) {
|
jb302@42
|
909 tmpw = regs[R0] / regs[R1];
|
jb302@42
|
910 regs[R0] = GHIGH(tmpw);
|
jb302@42
|
911 regs[R1] = GLOW(tmpw);
|
jb302@28
|
912 }
|
jb302@28
|
913
|
jb302@35
|
914 /* 0xFA - DA A */
|
jb302@28
|
915 void
|
jb302@35
|
916 DA(void) {
|
jb302@42
|
917 if (((A & 0xF) > 9) | get_flag(AC) == 1) {
|
jb302@42
|
918 A = A + 6;
|
jb302@42
|
919 }
|
jb302@42
|
920 if (((A & 0xF0) > 9) | get_flag(C) == 1) {
|
jb302@42
|
921 A = A + 0x60;
|
jb302@42
|
922 }
|
jb302@28
|
923 }
|
jb302@28
|
924
|
jb302@35
|
925 /* 0xFC - IN port_addr */
|
jb302@28
|
926 void
|
jb302@35
|
927 IN(void) {
|
jb302@35
|
928 /* implement me */
|
jb302@28
|
929 }
|
jb302@28
|
930
|
jb302@35
|
931 /* 0xFD - OUT port_addr */
|
jb302@28
|
932 void
|
jb302@28
|
933 OUT(void) {
|
jb302@35
|
934 /* implement me */
|
jb302@28
|
935 }
|
jb302@28
|
936
|
jb302@35
|
937 /* 0xFE INT vect8 */
|
jb302@28
|
938 void
|
jb302@35
|
939 INT(void) {
|
jb302@35
|
940 /* implement me */
|
jb302@28
|
941 }
|
jb302@28
|
942
|
jb302@28
|
943 /* 0xFF - HLT */
|
jb302@28
|
944 void
|
jb302@28
|
945 HLT(void) {
|
jb302@42
|
946 exit(0);
|
jb302@28
|
947 }
|