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 #ifdef PREFIX_DD
22 # define RegH IXh
23 # define RegL IXl
24 # define RegHL IX
25 #else
26 # define RegH IYh
27 # define RegL IYl
28 # define RegHL IY
29 #endif
30 
31 switch (op) {
32  case 0x09:			/* ADD IX, BC */
33 	 WZ = RegHL + 1;
34 	 add16(RegHL, BC);
35 	 delay(11);
36 	 break;
37  case 0x19:			/* ADD IX, DE */
38 	 WZ = RegHL + 1;
39 	 add16(RegHL, DE);
40 	 delay(11);
41 	 break;
42  case 0x21:			/* LD IX, nn */
43 	 RegHL = readw(PC);
44 	 PC += 2;
45 	 delay(10);
46 	 break;
47  case 0x22:			/* LD (nn), IX */
48 	 WZ = readw(PC);
49 	 PC += 2;
50 	 writeb(WZ, RegL);
51 	 WZ++;
52 	 writeb(WZ, RegH);
53 	 delay(16);
54 	 break;
55  case 0x23:			/* INC IX */
56 	 RegHL++;
57 	 delay(6);
58 	 break;
59  case 0x24:			/* INC IXH */
60 	 UNDOCUMENTED(4);
61 	 inc(RegH);
62 	 delay(4);
63 	 break;
64  case 0x25:			/* DEC IXH */
65 	 UNDOCUMENTED(4);
66 	 dec(RegH);
67 	 delay(4);
68 	 break;
69  case 0x26:			/* LD IXH, n */
70 	 UNDOCUMENTED(4);
71 	 RegH = readb(PC++);
72 	 delay(7);
73 	 break;
74  case 0x29:			/* ADD IX, IX */
75 	 WZ = RegHL + 1;
76 	 add16(RegHL, RegHL);
77 	 delay(11);
78 	 break;
79  case 0x2A:			/* LD IX, (nn) */
80 	 WZ = readw(PC);
81 	 PC += 2;
82 	 RegL = readb(WZ);
83 	 WZ++;
84 	 RegH = readb(WZ);
85 	 delay(16);
86 	 break;
87  case 0x2B:			/* DEC IX */
88 	 RegHL--;
89 	 delay(6);
90 	 break;
91  case 0x2C:			/* INC IXL */
92 	 UNDOCUMENTED(4);
93 	 inc(RegL);
94 	 delay(4);
95 	 break;
96  case 0x2D:			/* DEC IXL */
97 	 UNDOCUMENTED(4);
98 	 dec(RegL);
99 	 delay(4);
100 	 break;
101  case 0x2E:			/* LD IXL,n */
102 	 UNDOCUMENTED(4);
103 	 RegL = readb(PC++);
104 	 delay(7);
105 	 break;
106 
107  case 0x34:			/* INC (IX + n) */
108 	 offs = (int) (signed char) readb(PC++);
109 	 WZ = RegHL + offs;
110 	 tmp1 = readb(WZ);
111 	 inc(tmp1);
112 	 writeb(WZ, tmp1);
113 	 delay(19);
114 	 break;
115  case 0x35:			/* DEC (IX + n) */
116 	 offs = (int) (signed char) readb(PC++);
117 	 WZ = RegHL + offs;
118 	 tmp1 = readb(WZ);
119 	 dec(tmp1);
120 	 writeb(WZ, tmp1);
121 	 delay(19);
122 	 break;
123  case 0x36:			/* LD (IX + n), n */
124 	 offs = (int) (signed char) readb(PC++);
125 	 writeb(RegHL + offs, readb(PC++));
126 	 delay(15);		/* Yes, really! */
127 	 break;
128 
129  case 0x39:			/* ADD IX, SP */
130 	 WZ = RegHL + 1;
131 	 add16(RegHL, SP);
132 	 delay(11);
133 	 break;
134 
135  case 0x44: UNDOCUMENTED(4); B = RegH; delay(4); break;
136  case 0x45: UNDOCUMENTED(4); B = RegL; delay(4); break;
137  case 0x46:
138 	 offs = (int) (signed char) readb(PC++);
139 	 B = readb(RegHL + offs);
140 	 delay(15);
141 	 break;
142 
143  case 0x4C: UNDOCUMENTED(4); C = RegH; delay(4); break;
144  case 0x4D: UNDOCUMENTED(4); C = RegL; delay(4); break;
145  case 0x4E:
146 	 offs = (int) (signed char) readb(PC++);
147 	 C = readb(RegHL + offs);
148 	 delay(15);
149 	 break;
150 
151  case 0x54: UNDOCUMENTED(4); D = RegH; delay(4); break;
152  case 0x55: UNDOCUMENTED(4); D = RegL; delay(4); break;
153  case 0x56:
154 	 offs = (int) (signed char) readb(PC++);
155 	 D = readb(RegHL + offs);
156 	 delay(15);
157 	 break;
158 
159  case 0x5C: UNDOCUMENTED(4); E = RegH; delay(4); break;
160  case 0x5D: UNDOCUMENTED(4); E = RegL; delay(4); break;
161  case 0x5E:
162 	 offs = (int) (signed char) readb(PC++);
163 	 E = readb(RegHL + offs);
164 	 delay(15);
165 	 break;
166 
167  case 0x60: UNDOCUMENTED(4); RegH = B; delay(4); break;
168  case 0x61: UNDOCUMENTED(4); RegH = C; delay(4); break;
169  case 0x62: UNDOCUMENTED(4); RegH = D; delay(4); break;
170  case 0x63: UNDOCUMENTED(4); RegH = E; delay(4); break;
171  case 0x64: UNDOCUMENTED(4); RegH = RegH; delay(4); break;
172  case 0x65: UNDOCUMENTED(4); RegH = RegL; delay(4); break;
173  case 0x66:
174 	 offs = (int) (signed char) readb(PC++);
175 	 H = readb(RegHL + offs);
176 	 delay(15);
177 	 break;
178  case 0x67: UNDOCUMENTED(4); RegH = A; delay(4); break;
179 
180  case 0x68: UNDOCUMENTED(4); RegL = B; delay(4); break;
181  case 0x69: UNDOCUMENTED(4); RegL = C; delay(4); break;
182  case 0x6A: UNDOCUMENTED(4); RegL = D; delay(4); break;
183  case 0x6B: UNDOCUMENTED(4); RegL = E; delay(4); break;
184  case 0x6C: UNDOCUMENTED(4); RegL = RegH; delay(4); break;
185  case 0x6D: UNDOCUMENTED(4); RegL = RegL; delay(4); break;
186  case 0x6E:
187 	 offs = (int) (signed char) readb(PC++);
188 	 L = readb(RegHL + offs);
189 	 delay(15);
190 	 break;
191  case 0x6F: UNDOCUMENTED(4); RegL = A; delay(4); break;
192 
193  case 0x70:
194 	 offs = (int) (signed char) readb(PC++);
195 	 writeb(RegHL + offs, B);
196 	 delay(15);
197 	 break;
198  case 0x71:
199 	 offs = (int) (signed char) readb(PC++);
200 	 writeb(RegHL + offs, C);
201 	 delay(15);
202 	 break;
203  case 0x72:
204 	 offs = (int) (signed char) readb(PC++);
205 	 writeb(RegHL + offs, D);
206 	 delay(15);
207 	 break;
208  case 0x73:
209 	 offs = (int) (signed char) readb(PC++);
210 	 writeb(RegHL + offs, E);
211 	 delay(15);
212 	 break;
213  case 0x74:
214 	 offs = (int) (signed char) readb(PC++);
215 	 writeb(RegHL + offs, H);
216 	 delay(15);
217 	 break;
218  case 0x75:
219 	 offs = (int) (signed char) readb(PC++);
220 	 writeb(RegHL + offs, L);
221 	 delay(15);
222 	 break;
223  case 0x77:
224 	 offs = (int) (signed char) readb(PC++);
225 	 writeb(RegHL + offs, A);
226 	 delay(15);
227 	 break;
228 
229  case 0x7C: UNDOCUMENTED(4); A = RegH; delay(4); break;
230  case 0x7D: UNDOCUMENTED(4); A = RegL; delay(4); break;
231  case 0x7E:
232 	 offs = (int) (signed char) readb(PC++);
233 	 A = readb(RegHL + offs);
234 	 delay(15);
235 	 break;
236 
237  case 0x84: UNDOCUMENTED(4); add8(A, RegH); delay(4); break;
238  case 0x85: UNDOCUMENTED(4); add8(A, RegL); delay(4); break;
239  case 0x86:
240 	 offs = (int) (signed char) readb(PC++);
241 	 add8(A, readb(RegHL + offs));
242 	 delay(7);
243 	 break;
244 
245  case 0x8C: UNDOCUMENTED(4); adc8(A, RegH); delay(4); break;
246  case 0x8D: UNDOCUMENTED(4); adc8(A, RegL); delay(4); break;
247  case 0x8E:
248 	 offs = (int) (signed char) readb(PC++);
249 	 adc8(A, readb(RegHL + offs));
250 	 delay(15);
251 	 break;
252 
253  case 0x94: UNDOCUMENTED(4); sub8(A, RegH); delay(4); break;
254  case 0x95: UNDOCUMENTED(4); sub8(A, RegL); delay(4); break;
255  case 0x96:
256 	 offs = (int) (signed char) readb(PC++);
257 	 sub8(A, readb(RegHL + offs));
258 	 delay(15);
259 	 break;
260 
261  case 0x9C: UNDOCUMENTED(4); sbc8(A, RegH); delay(4); break;
262  case 0x9D: UNDOCUMENTED(4); sbc8(A, RegL); delay(4); break;
263  case 0x9E:
264 	 offs = (int) (signed char) readb(PC++);
265 	 sbc8(A, readb(RegHL + offs));
266 	 delay(15);
267 	 break;
268 
269  case 0xA4: UNDOCUMENTED(4); and(A, RegH); delay(4); break;
270  case 0xA5: UNDOCUMENTED(4); and(A, RegL); delay(4); break;
271  case 0xA6:
272 	 offs = (int) (signed char) readb(PC++);
273 	 and(A, readb(RegHL + offs));
274 	 delay(15);
275 	 break;
276 
277  case 0xAC: UNDOCUMENTED(4); xor(A, RegH); delay(4); break;
278  case 0xAD: UNDOCUMENTED(4); xor(A, RegL); delay(4); break;
279  case 0xAE:
280 	 offs = (int) (signed char) readb(PC++);
281 	 xor(A, readb(RegHL + offs));
282 	 delay(15);
283 	 break;
284 
285  case 0xB4: UNDOCUMENTED(4); or(A, RegH); delay(4); break;
286  case 0xB5: UNDOCUMENTED(4); or(A, RegL); delay(4); break;
287  case 0xB6:
288 	 offs = (int) (signed char) readb(PC++);
289 	 or(A, readb(RegHL + offs));
290 	 delay(15);
291 	 break;
292 
293  case 0xBC: UNDOCUMENTED(4); cp(A, RegH); delay(4); break;
294  case 0xBD: UNDOCUMENTED(4); cp(A, RegL); delay(4); break;
295  case 0xBE:
296 	 offs = (int) (signed char) readb(PC++);
297 	 cp(A, readb(RegHL + offs));
298 	 delay(15);
299 	 break;
300 
301  case 0xCB:
302 	 offs = (int) (signed char) readb(PC++);
303 	 WZ = RegHL + offs;
304 	 op = readb(PC++);
305 #ifdef PREFIX_DD
306 	 goto opcode_ddcb;
307 #else
308 	 goto opcode_fdcb;
309 #endif
310 
311  case 0xE1:			/* POP IX */
312 	 pop(RegHL);
313 	 delay(10);
314 	 break;
315  case 0xE3:			/* EX (SP), IX */
316 	 WZ = readw(SP);
317 	 writew(SP, RegHL);
318 	 RegHL = WZ;
319 	 delay(19);
320 	 break;
321  case 0xE5:			/* PUSH IX */
322 	 push(RegHL);
323 	 delay(11);
324 	 break;
325 
326  case 0xE9:			/* JP IX */
327 	 PC = RegHL;
328 	 delay(4);
329 	 break;
330 
331  case 0xF9:			/* LD SP, IX */
332 	 SP = RegHL;
333 	 delay(4);
334 	 break;
335 
336  default:
337 	 goto opcode_main;
338  }
339 
340 #undef RegH
341 #undef RegL
342 #undef RegHL
343 
344