1 /*
2  * libtilemcore - Graphing calculator emulation library
3  *
4  * Copyright (C) 2009 Benjamin Moody
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public License
8  * as published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
21 switch (op) {
22  case 0x40:			/* IN B, (C) */
23 	 WZ = BC;
24 	 delay(12);
25 	 in(B);
26 	 break;
27  case 0x41:			/* OUT (C), B */
28 	 delay(12);
29 	 output(BC, B);
30 	 break;
31  case 0x42:			/* SBC HL, BC */
32 	 WZ = HL + 1;
33 	 sbc16(HLw, BCw);
34 	 delay(15);
35 	 break;
36  case 0x43:			/* LD (nn), BC */
37 	 WZ = readw(PC);
38 	 PC += 2;
39 	 writew(WZ++, BC);
40 	 delay(20);
41 	 break;
42  case 0x44:			/* NEG */
43 	 neg(A);
44 	 delay(8);
45 	 break;
46  case 0x45:			/* RETN */
47 	 IFF1 = IFF2;
48 	 pop(PC);
49 	 delay(14);
50 	 break;
51  case 0x46:			/* IM 0 */
52 	 IM = 0;
53 	 delay(8);
54 	 break;
55  case 0x47:			/* LD I,A */
56 	 I = A;
57 	 delay(9);
58 	 break;
59 
60  case 0x48:			/* IN C, (C) */
61 	 WZ = BC;
62 	 delay(12);
63 	 in(C);
64 	 break;
65  case 0x49:			/* OUT (C), C */
66 	 delay(12);
67 	 output(BC, C);
68 	 break;
69  case 0x4A:			/* ADC HL, BC */
70 	 WZ = HL + 1;
71 	 adc16(HLw, BCw);
72 	 delay(15);
73 	 break;
74  case 0x4B:			/* LD BC, (nn) */
75 	 WZ = readw(PC);
76 	 PC += 2;
77 	 BC = readw(WZ++);
78 	 delay(20);
79 	 break;
80  case 0x4C:			/* NEG */
81 	 UNDOCUMENTED(8);
82 	 neg(A);
83 	 delay(8);
84 	 break;
85  case 0x4D:			/* RETI */
86 	 IFF1 = IFF2;
87 	 pop(PC);
88 	 delay(14);
89 	 break;
90  case 0x4E:			/* IM 0 */
91 	 UNDOCUMENTED(8);
92 	 IM = 0;
93 	 delay(8);
94 	 break;
95  case 0x4F:			/* LD R,A */
96 	 Rl = A;
97 	 Rh = A & 0x80;
98 	 delay(9);
99 	 break;
100 
101  case 0x50:			/* IN D, (C) */
102 	 WZ = BC;
103 	 delay(12);
104 	 in(D);
105 	 break;
106  case 0x51:			/* OUT (C), D */
107 	 delay(12);
108 	 output(BC, D);
109 	 break;
110  case 0x52:			/* SBC HL, DE */
111 	 WZ = HL + 1;
112 	 sbc16(HLw, DEw);
113 	 delay(15);
114 	 break;
115  case 0x53:			/* LD (nn), DE */
116 	 WZ = readw(PC);
117 	 PC += 2;
118 	 writew(WZ++, DE);
119 	 delay(20);
120 	 break;
121  case 0x54:			/* NEG */
122 	 UNDOCUMENTED(8);
123 	 neg(A);
124 	 delay(8);
125 	 break;
126  case 0x55:			/* RETN */
127 	 UNDOCUMENTED(8);
128 	 IFF1 = IFF2;
129 	 pop(PC);
130 	 delay(14);
131 	 break;
132  case 0x56:			/* IM 1 */
133 	 IM = 1;
134 	 delay(8);
135 	 break;
136  case 0x57:			/* LD A,I */
137 	 ld_a_ir(I);
138 	 delay(9);
139 	 break;
140 
141  case 0x58:			/* IN E, (C) */
142 	 WZ = BC;
143 	 delay(12);
144 	 in(E);
145 	 break;
146  case 0x59:			/* OUT (C), E */
147 	 delay(12);
148 	 output(BC, E);
149 	 break;
150  case 0x5A:			/* ADC HL, DE */
151 	 WZ = HL + 1;
152 	 adc16(HLw, DEw);
153 	 delay(15);
154 	 break;
155  case 0x5B:			/* LD DE, (nn) */
156 	 WZ = readw(PC);
157 	 PC += 2;
158 	 DE = readw(WZ++);
159 	 delay(20);
160 	 break;
161  case 0x5C:			/* NEG */
162 	 UNDOCUMENTED(8);
163 	 neg(A);
164 	 delay(8);
165 	 break;
166  case 0x5D:			/* RETN */
167 	 UNDOCUMENTED(8);
168 	 IFF1 = IFF2;
169 	 pop(PC);
170 	 delay(14);
171 	 break;
172  case 0x5E:			/* IM 2 */
173 	 IM = 2;
174 	 delay(8);
175 	 break;
176  case 0x5F:			/* LD A,R */
177 	 ld_a_ir(R);
178 	 delay(9);
179 	 break;
180 
181  case 0x60:			/* IN H, (C) */
182 	 WZ = BC;
183 	 delay(12);
184 	 in(H);
185 	 break;
186  case 0x61:			/* OUT (C), H */
187 	 delay(12);
188 	 output(BC, H);
189 	 break;
190  case 0x62:			/* SBC HL, HL */
191 	 WZ = HL + 1;
192 	 sbc16(HLw, HLw);
193 	 delay(15);
194 	 break;
195  case 0x63:			/* LD (nn), HL */
196 	 WZ = readw(PC);
197 	 PC += 2;
198 	 writew(WZ++, HL);
199 	 delay(20);
200 	 break;
201  case 0x64:			/* NEG */
202 	 UNDOCUMENTED(8);
203 	 neg(A);
204 	 delay(8);
205 	 break;
206  case 0x65:			/* RETN */
207 	 UNDOCUMENTED(8);
208 	 IFF1 = IFF2;
209 	 pop(PC);
210 	 delay(14);
211 	 break;
212  case 0x66:			/* IM 0 */
213 	 UNDOCUMENTED(8);
214 	 IM = 0;
215 	 delay(8);
216 	 break;
217  case 0x67:			/* RRD */
218 	 rrd;
219 	 delay(18);
220 	 break;
221 
222  case 0x68:			/* IN L, (C) */
223 	 WZ = BC;
224 	 delay(12);
225 	 in(L);
226 	 break;
227  case 0x69:			/* OUT (C), L */
228 	 delay(12);
229 	 output(BC, L);
230 	 break;
231  case 0x6A:			/* ADC HL, HL */
232 	 WZ = HL + 1;
233 	 adc16(HLw, HLw);
234 	 delay(15);
235 	 break;
236  case 0x6B:			/* LD HL, (nn) */
237 	 WZ = readw(PC);
238 	 PC += 2;
239 	 HL = readw(WZ++);
240 	 delay(20);
241 	 break;
242  case 0x6C:			/* NEG */
243 	 UNDOCUMENTED(8);
244 	 neg(A);
245 	 delay(8);
246 	 break;
247  case 0x6D:			/* RETN */
248 	 UNDOCUMENTED(8);
249 	 IFF1 = IFF2;
250 	 pop(PC);
251 	 delay(14);
252 	 break;
253  case 0x6E:			/* IM 0 */
254 	 UNDOCUMENTED(8);
255 	 IM = 0;
256 	 delay(8);
257 	 break;
258  case 0x6F:			/* RLD */
259 	 rld;
260 	 delay(18);
261 	 break;
262 
263  case 0x70:			/* IN (C) */
264 	 UNDOCUMENTED(8);
265 	 WZ = BC;
266 	 delay(12);
267 	 in(tmp1);
268 	 break;
269  case 0x71:			/* OUT (C), 0 */
270 	 UNDOCUMENTED(8);
271 	 delay(12);
272 	 output(BC, 0);
273 	 break;
274  case 0x72:			/* SBC HL, SP */
275 	 WZ = HL + 1;
276 	 sbc16(HLw, SPw);
277 	 delay(15);
278 	 break;
279  case 0x73:			/* LD (nn), SP */
280 	 WZ = readw(PC);
281 	 PC += 2;
282 	 writew(WZ++, SP);
283 	 delay(20);
284 	 break;
285  case 0x74:			/* NEG */
286 	 UNDOCUMENTED(8);
287 	 neg(A);
288 	 delay(8);
289 	 break;
290  case 0x75:			/* RETN */
291 	 UNDOCUMENTED(8);
292 	 IFF1 = IFF2;
293 	 pop(PC);
294 	 delay(14);
295 	 break;
296  case 0x76:			/* IM 1 */
297 	 UNDOCUMENTED(8);
298 	 IM = 1;
299 	 delay(8);
300 	 break;
301 
302  case 0x78:			/* IN A, (C) */
303 	 WZ = BC;
304 	 delay(12);
305 	 in(A);
306 	 break;
307  case 0x79:			/* OUT (C), A */
308 	 delay(12);
309 	 output(BC, A);
310 	 break;
311  case 0x7A:			/* ADC HL, SP */
312 	 WZ = HL + 1;
313 	 adc16(HLw, SPw);
314 	 delay(15);
315 	 break;
316  case 0x7B:			/* LD SP, (nn) */
317 	 WZ = readw(PC);
318 	 PC += 2;
319 	 SP = readw(WZ);
320 	 WZ++;
321 	 delay(20);
322 	 break;
323  case 0x7C:			/* NEG */
324 	 UNDOCUMENTED(8);
325 	 neg(A);
326 	 delay(8);
327 	 break;
328  case 0x7D:			/* RETN */
329 	 UNDOCUMENTED(8);
330 	 IFF1 = IFF2;
331 	 pop(PC);
332 	 delay(14);
333 	 break;
334  case 0x7E:			/* IM 2 */
335 	 UNDOCUMENTED(8);
336 	 IM = 2;
337 	 delay(8);
338 	 break;
339 
340  case 0xA0:			/* LDI */
341 	 ldi;
342 	 delay(16);
343 	 break;
344  case 0xA1:			/* CPI */
345 	 cpi;
346 	 delay(16);
347 	 break;
348  case 0xA2:			/* INI */
349 	 delay(13);
350 	 ini;
351 	 delay(3);
352 	 break;
353  case 0xA3:			/* OUTI */
354 	 delay(16);
355 	 outi;
356 	 break;
357 
358  case 0xA8:			/* LDD */
359 	 ldd;
360 	 delay(16);
361 	 break;
362  case 0xA9:			/* CPD */
363 	 cpd;
364 	 delay(16);
365 	 break;
366  case 0xAA:			/* IND */
367 	 delay(13);
368 	 ind;
369 	 delay(3);
370 	 break;
371  case 0xAB:			/* OUTD */
372 	 delay(16);
373 	 outd;
374 	 break;
375 
376  case 0xB0:			/* LDIR */
377 	 ldi;
378 	 if (BCw) {
379 		 PC -= 2;
380 		 delay(21);
381 	 }
382 	 else
383 		 delay(16);
384 	 break;
385  case 0xB1:			/* CPIR */
386 	 cpi;
387 	 if (BCw && !(F & FLAG_Z)) {
388 		 PC -= 2;
389 		 delay(21);
390 	 }
391 	 else
392 		 delay(16);
393 	 break;
394  case 0xB2:			/* INIR */
395 	 delay(13);
396 	 ini;
397 	 if (B) {
398 		 PC -= 2;
399 		 delay(8);
400 	 }
401 	 else
402 		 delay(3);
403 	 break;
404  case 0xB3:			/* OTIR */
405 	 delay(16);
406 	 outi;
407 	 if (B) {
408 		 PC -= 2;
409 		 delay(5);
410 	 }
411 	 break;
412 
413  case 0xB8:			/* LDDR */
414 	 ldd;
415 	 if (BCw) {
416 		 PC -= 2;
417 		 delay(21);
418 	 }
419 	 else
420 		 delay(16);
421 	 break;
422  case 0xB9:			/* CPDR */
423 	 cpd;
424 	 if (BCw && !(F & FLAG_Z)) {
425 		 PC -= 2;
426 		 delay(21);
427 	 }
428 	 else
429 		 delay(16);
430 	 break;
431  case 0xBA:			/* INDR */
432 	 delay(13);
433 	 ind;
434 	 if (B) {
435 		 PC -= 2;
436 		 delay(8);
437 	 }
438 	 else
439 		 delay(3);
440 	 break;
441  case 0xBB:			/* OTDR */
442 	 delay(16);
443 	 outd;
444 	 if (B) {
445 		 PC -= 2;
446 		 delay(5);
447 	 }
448 	 break;
449 
450  default:
451 	 delay(8);
452 	 if (calc->hw.z80_instr)
453 		 (*calc->hw.z80_instr)(calc, 0xed00 | op);
454 	 else if (calc->z80.emuflags & TILEM_Z80_BREAK_INVALID)
455 		 tilem_z80_stop(calc, TILEM_STOP_INVALID_INST);
456 	 break;
457  }
458