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