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 #if defined(PREFIX_DD) || defined(PREFIX_FD)
22 
23 # define CBINST(fnc, reg) do {			\
24 		UNDOCUMENTED(16);		\
25 		tmp1 = readb(WZ);		\
26 		fnc(tmp1);			\
27 		writeb(WZ, tmp1);		\
28 		(reg) = tmp1;			\
29 		delay(19);			\
30 	} while (0)
31 
32 # define CBINST_HL(fnc) do {			\
33 		tmp1 = readb(WZ);		\
34 		fnc(tmp1);			\
35 		writeb(WZ, tmp1);		\
36 		delay(19);			\
37 	} while (0)
38 
39 # define CBINST_UNDOC(fnc, reg) CBINST(fnc, reg)
40 
41 # define CBINST_UNDOC_HL(fnc) do {		\
42 		UNDOCUMENTED(12);		\
43 		CBINST_HL(fnc);			\
44 	} while (0)
45 
46 # define CB_BIT(b, reg) do {			\
47 		UNDOCUMENTED(12);		\
48 		CB_BIT_HL(b);			\
49 	} while (0)
50 
51 # define CB_BIT_HL(b) do {					\
52 		tmp1 = readb(WZ) & (1 << b);			\
53 		F = ((tmp1 & FLAG_S)	     /* S */		\
54 		     | (W & FLAG_XY)	     /* X/Y */		\
55 		     | (tmp1 ? 0 : FLAG_ZP)  /* Z/P */		\
56 		     | (FLAG_H)		     /* H */		\
57 		     | (F & FLAG_C));				\
58 		delay(16);					\
59 	} while (0)
60 
61 # define CB_RES(b, reg) do {			\
62 		UNDOCUMENTED(16);		\
63 		tmp1 = readb(WZ) & ~(1 << b);	\
64 		writeb(WZ, tmp1);		\
65 		(reg) = tmp1;			\
66 		delay(19);			\
67 	} while (0)
68 
69 # define CB_RES_HL(b) do {			\
70 		tmp1 = readb(WZ) & ~(1 << b);	\
71 		writeb(WZ, tmp1);		\
72 		delay(19);			\
73 	} while (0)
74 
75 # define CB_SET(b, reg) do {			\
76 		UNDOCUMENTED(16);		\
77 		tmp1 = readb(WZ) | (1 << b);	\
78 		writeb(WZ, tmp1);		\
79 		(reg) = tmp1;			\
80 		delay(19);			\
81 	} while (0)
82 
83 # define CB_SET_HL(b) do {			\
84 		tmp1 = readb(WZ) | (1 << b);	\
85 		writeb(WZ, tmp1);		\
86 		delay(19);			\
87 	} while (0)
88 
89 #else  /* ! PREFIX_DD, ! PREFIX_FD */
90 
91 # define CBINST(fnc, reg) do {  \
92 		fnc(reg);	\
93 		delay(8);	\
94 	} while (0)
95 
96 # define CBINST_HL(fnc) do {			\
97 		tmp1 = readb(HL);		\
98 		fnc(tmp1);			\
99 		writeb(HL, tmp1);		\
100 		delay(15);			\
101 	} while (0)
102 
103 # define CBINST_UNDOC(fnc, reg) do {		\
104 		UNDOCUMENTED(8);		\
105 		CBINST(fnc, reg);		\
106 	} while (0)
107 
108 # define CBINST_UNDOC_HL(fnc) do {		\
109 		UNDOCUMENTED(8);		\
110 		CBINST_HL(fnc);			\
111 	} while (0)
112 
113 # define CB_BIT(b, reg) do {					\
114 		tmp1 = (reg) & (1 << b);			\
115 		F = ((tmp1 & FLAG_SXY)         /* S/X/Y */	\
116 		     | (tmp1 ? 0 : FLAG_ZP)    /* Z/P */	\
117 		     | (FLAG_H)		       /* H */		\
118 		     | (F & FLAG_C));				\
119 		delay(8);					\
120 	} while (0)
121 
122 # define CB_BIT_HL(b) do {					\
123 		tmp1 = readb(HL) & (1 << b);			\
124 		F = ((tmp1 & FLAG_S)	       /* S */		\
125 		     | (W & FLAG_XY)	       /* X/Y */	\
126 		     | (tmp1 ? 0 : FLAG_ZP)    /* Z/P */	\
127 		     | (FLAG_H)		       /* H */		\
128 		     | (F & FLAG_C));				\
129 		delay(12);					\
130 	} while (0)
131 
132 # define CB_RES(b, reg) do {			\
133 		(reg) &= ~(1 << b);		\
134 		delay(8);			\
135 	} while (0)
136 
137 # define CB_RES_HL(b) do {				\
138 		writeb(HL, readb(HL) & ~(1 << b));	\
139 		delay(15);				\
140 	} while (0)
141 
142 # define CB_SET(b, reg) do {			\
143 		(reg) |= (1 << b);		\
144 		delay(8);			\
145 	} while (0)
146 
147 # define CB_SET_HL(b) do {				\
148 		writeb(HL, readb(HL) | (1 << b));	\
149 		delay(15);				\
150 	} while (0)
151 
152 #endif
153 
154 switch (op) {
155  case 0x00: CBINST(rlc, B); break;
156  case 0x01: CBINST(rlc, C); break;
157  case 0x02: CBINST(rlc, D); break;
158  case 0x03: CBINST(rlc, E); break;
159  case 0x04: CBINST(rlc, H); break;
160  case 0x05: CBINST(rlc, L); break;
161  case 0x06: CBINST_HL(rlc); break;
162  case 0x07: CBINST(rlc, A); break;
163  case 0x08: CBINST(rrc, B); break;
164  case 0x09: CBINST(rrc, C); break;
165  case 0x0A: CBINST(rrc, D); break;
166  case 0x0B: CBINST(rrc, E); break;
167  case 0x0C: CBINST(rrc, H); break;
168  case 0x0D: CBINST(rrc, L); break;
169  case 0x0E: CBINST_HL(rrc); break;
170  case 0x0F: CBINST(rrc, A); break;
171  case 0x10: CBINST(rl, B); break;
172  case 0x11: CBINST(rl, C); break;
173  case 0x12: CBINST(rl, D); break;
174  case 0x13: CBINST(rl, E); break;
175  case 0x14: CBINST(rl, H); break;
176  case 0x15: CBINST(rl, L); break;
177  case 0x16: CBINST_HL(rl); break;
178  case 0x17: CBINST(rl, A); break;
179  case 0x18: CBINST(rr, B); break;
180  case 0x19: CBINST(rr, C); break;
181  case 0x1A: CBINST(rr, D); break;
182  case 0x1B: CBINST(rr, E); break;
183  case 0x1C: CBINST(rr, H); break;
184  case 0x1D: CBINST(rr, L); break;
185  case 0x1E: CBINST_HL(rr); break;
186  case 0x1F: CBINST(rr, A); break;
187  case 0x20: CBINST(sla, B); break;
188  case 0x21: CBINST(sla, C); break;
189  case 0x22: CBINST(sla, D); break;
190  case 0x23: CBINST(sla, E); break;
191  case 0x24: CBINST(sla, H); break;
192  case 0x25: CBINST(sla, L); break;
193  case 0x26: CBINST_HL(sla); break;
194  case 0x27: CBINST(sla, A); break;
195  case 0x28: CBINST(sra, B); break;
196  case 0x29: CBINST(sra, C); break;
197  case 0x2A: CBINST(sra, D); break;
198  case 0x2B: CBINST(sra, E); break;
199  case 0x2C: CBINST(sra, H); break;
200  case 0x2D: CBINST(sra, L); break;
201  case 0x2E: CBINST_HL(sra); break;
202  case 0x2F: CBINST(sra, A); break;
203  case 0x30: CBINST_UNDOC(slia, B); break;
204  case 0x31: CBINST_UNDOC(slia, C); break;
205  case 0x32: CBINST_UNDOC(slia, D); break;
206  case 0x33: CBINST_UNDOC(slia, E); break;
207  case 0x34: CBINST_UNDOC(slia, H); break;
208  case 0x35: CBINST_UNDOC(slia, L); break;
209  case 0x36: CBINST_UNDOC_HL(slia); break;
210  case 0x37: CBINST_UNDOC(slia, A); break;
211  case 0x38: CBINST(srl, B); break;
212  case 0x39: CBINST(srl, C); break;
213  case 0x3A: CBINST(srl, D); break;
214  case 0x3B: CBINST(srl, E); break;
215  case 0x3C: CBINST(srl, H); break;
216  case 0x3D: CBINST(srl, L); break;
217  case 0x3E: CBINST_HL(srl); break;
218  case 0x3F: CBINST(srl, A); break;
219 
220  case 0x40: CB_BIT(0, B); break;
221  case 0x41: CB_BIT(0, C); break;
222  case 0x42: CB_BIT(0, D); break;
223  case 0x43: CB_BIT(0, E); break;
224  case 0x44: CB_BIT(0, H); break;
225  case 0x45: CB_BIT(0, L); break;
226  case 0x46: CB_BIT_HL(0); break;
227  case 0x47: CB_BIT(0, A); break;
228  case 0x48: CB_BIT(1, B); break;
229  case 0x49: CB_BIT(1, C); break;
230  case 0x4A: CB_BIT(1, D); break;
231  case 0x4B: CB_BIT(1, E); break;
232  case 0x4C: CB_BIT(1, H); break;
233  case 0x4D: CB_BIT(1, L); break;
234  case 0x4E: CB_BIT_HL(1); break;
235  case 0x4F: CB_BIT(1, A); break;
236  case 0x50: CB_BIT(2, B); break;
237  case 0x51: CB_BIT(2, C); break;
238  case 0x52: CB_BIT(2, D); break;
239  case 0x53: CB_BIT(2, E); break;
240  case 0x54: CB_BIT(2, H); break;
241  case 0x55: CB_BIT(2, L); break;
242  case 0x56: CB_BIT_HL(2); break;
243  case 0x57: CB_BIT(2, A); break;
244  case 0x58: CB_BIT(3, B); break;
245  case 0x59: CB_BIT(3, C); break;
246  case 0x5A: CB_BIT(3, D); break;
247  case 0x5B: CB_BIT(3, E); break;
248  case 0x5C: CB_BIT(3, H); break;
249  case 0x5D: CB_BIT(3, L); break;
250  case 0x5E: CB_BIT_HL(3); break;
251  case 0x5F: CB_BIT(3, A); break;
252  case 0x60: CB_BIT(4, B); break;
253  case 0x61: CB_BIT(4, C); break;
254  case 0x62: CB_BIT(4, D); break;
255  case 0x63: CB_BIT(4, E); break;
256  case 0x64: CB_BIT(4, H); break;
257  case 0x65: CB_BIT(4, L); break;
258  case 0x66: CB_BIT_HL(4); break;
259  case 0x67: CB_BIT(4, A); break;
260  case 0x68: CB_BIT(5, B); break;
261  case 0x69: CB_BIT(5, C); break;
262  case 0x6A: CB_BIT(5, D); break;
263  case 0x6B: CB_BIT(5, E); break;
264  case 0x6C: CB_BIT(5, H); break;
265  case 0x6D: CB_BIT(5, L); break;
266  case 0x6E: CB_BIT_HL(5); break;
267  case 0x6F: CB_BIT(5, A); break;
268  case 0x70: CB_BIT(6, B); break;
269  case 0x71: CB_BIT(6, C); break;
270  case 0x72: CB_BIT(6, D); break;
271  case 0x73: CB_BIT(6, E); break;
272  case 0x74: CB_BIT(6, H); break;
273  case 0x75: CB_BIT(6, L); break;
274  case 0x76: CB_BIT_HL(6); break;
275  case 0x77: CB_BIT(6, A); break;
276  case 0x78: CB_BIT(7, B); break;
277  case 0x79: CB_BIT(7, C); break;
278  case 0x7A: CB_BIT(7, D); break;
279  case 0x7B: CB_BIT(7, E); break;
280  case 0x7C: CB_BIT(7, H); break;
281  case 0x7D: CB_BIT(7, L); break;
282  case 0x7E: CB_BIT_HL(7); break;
283  case 0x7F: CB_BIT(7, A); break;
284 
285  case 0x80: CB_RES(0, B); break;
286  case 0x81: CB_RES(0, C); break;
287  case 0x82: CB_RES(0, D); break;
288  case 0x83: CB_RES(0, E); break;
289  case 0x84: CB_RES(0, H); break;
290  case 0x85: CB_RES(0, L); break;
291  case 0x86: CB_RES_HL(0); break;
292  case 0x87: CB_RES(0, A); break;
293  case 0x88: CB_RES(1, B); break;
294  case 0x89: CB_RES(1, C); break;
295  case 0x8A: CB_RES(1, D); break;
296  case 0x8B: CB_RES(1, E); break;
297  case 0x8C: CB_RES(1, H); break;
298  case 0x8D: CB_RES(1, L); break;
299  case 0x8E: CB_RES_HL(1); break;
300  case 0x8F: CB_RES(1, A); break;
301  case 0x90: CB_RES(2, B); break;
302  case 0x91: CB_RES(2, C); break;
303  case 0x92: CB_RES(2, D); break;
304  case 0x93: CB_RES(2, E); break;
305  case 0x94: CB_RES(2, H); break;
306  case 0x95: CB_RES(2, L); break;
307  case 0x96: CB_RES_HL(2); break;
308  case 0x97: CB_RES(2, A); break;
309  case 0x98: CB_RES(3, B); break;
310  case 0x99: CB_RES(3, C); break;
311  case 0x9A: CB_RES(3, D); break;
312  case 0x9B: CB_RES(3, E); break;
313  case 0x9C: CB_RES(3, H); break;
314  case 0x9D: CB_RES(3, L); break;
315  case 0x9E: CB_RES_HL(3); break;
316  case 0x9F: CB_RES(3, A); break;
317  case 0xA0: CB_RES(4, B); break;
318  case 0xA1: CB_RES(4, C); break;
319  case 0xA2: CB_RES(4, D); break;
320  case 0xA3: CB_RES(4, E); break;
321  case 0xA4: CB_RES(4, H); break;
322  case 0xA5: CB_RES(4, L); break;
323  case 0xA6: CB_RES_HL(4); break;
324  case 0xA7: CB_RES(4, A); break;
325  case 0xA8: CB_RES(5, B); break;
326  case 0xA9: CB_RES(5, C); break;
327  case 0xAA: CB_RES(5, D); break;
328  case 0xAB: CB_RES(5, E); break;
329  case 0xAC: CB_RES(5, H); break;
330  case 0xAD: CB_RES(5, L); break;
331  case 0xAE: CB_RES_HL(5); break;
332  case 0xAF: CB_RES(5, A); break;
333  case 0xB0: CB_RES(6, B); break;
334  case 0xB1: CB_RES(6, C); break;
335  case 0xB2: CB_RES(6, D); break;
336  case 0xB3: CB_RES(6, E); break;
337  case 0xB4: CB_RES(6, H); break;
338  case 0xB5: CB_RES(6, L); break;
339  case 0xB6: CB_RES_HL(6); break;
340  case 0xB7: CB_RES(6, A); break;
341  case 0xB8: CB_RES(7, B); break;
342  case 0xB9: CB_RES(7, C); break;
343  case 0xBA: CB_RES(7, D); break;
344  case 0xBB: CB_RES(7, E); break;
345  case 0xBC: CB_RES(7, H); break;
346  case 0xBD: CB_RES(7, L); break;
347  case 0xBE: CB_RES_HL(7); break;
348  case 0xBF: CB_RES(7, A); break;
349 
350  case 0xC0: CB_SET(0, B); break;
351  case 0xC1: CB_SET(0, C); break;
352  case 0xC2: CB_SET(0, D); break;
353  case 0xC3: CB_SET(0, E); break;
354  case 0xC4: CB_SET(0, H); break;
355  case 0xC5: CB_SET(0, L); break;
356  case 0xC6: CB_SET_HL(0); break;
357  case 0xC7: CB_SET(0, A); break;
358  case 0xC8: CB_SET(1, B); break;
359  case 0xC9: CB_SET(1, C); break;
360  case 0xCA: CB_SET(1, D); break;
361  case 0xCB: CB_SET(1, E); break;
362  case 0xCC: CB_SET(1, H); break;
363  case 0xCD: CB_SET(1, L); break;
364  case 0xCE: CB_SET_HL(1); break;
365  case 0xCF: CB_SET(1, A); break;
366  case 0xD0: CB_SET(2, B); break;
367  case 0xD1: CB_SET(2, C); break;
368  case 0xD2: CB_SET(2, D); break;
369  case 0xD3: CB_SET(2, E); break;
370  case 0xD4: CB_SET(2, H); break;
371  case 0xD5: CB_SET(2, L); break;
372  case 0xD6: CB_SET_HL(2); break;
373  case 0xD7: CB_SET(2, A); break;
374  case 0xD8: CB_SET(3, B); break;
375  case 0xD9: CB_SET(3, C); break;
376  case 0xDA: CB_SET(3, D); break;
377  case 0xDB: CB_SET(3, E); break;
378  case 0xDC: CB_SET(3, H); break;
379  case 0xDD: CB_SET(3, L); break;
380  case 0xDE: CB_SET_HL(3); break;
381  case 0xDF: CB_SET(3, A); break;
382  case 0xE0: CB_SET(4, B); break;
383  case 0xE1: CB_SET(4, C); break;
384  case 0xE2: CB_SET(4, D); break;
385  case 0xE3: CB_SET(4, E); break;
386  case 0xE4: CB_SET(4, H); break;
387  case 0xE5: CB_SET(4, L); break;
388  case 0xE6: CB_SET_HL(4); break;
389  case 0xE7: CB_SET(4, A); break;
390  case 0xE8: CB_SET(5, B); break;
391  case 0xE9: CB_SET(5, C); break;
392  case 0xEA: CB_SET(5, D); break;
393  case 0xEB: CB_SET(5, E); break;
394  case 0xEC: CB_SET(5, H); break;
395  case 0xED: CB_SET(5, L); break;
396  case 0xEE: CB_SET_HL(5); break;
397  case 0xEF: CB_SET(5, A); break;
398  case 0xF0: CB_SET(6, B); break;
399  case 0xF1: CB_SET(6, C); break;
400  case 0xF2: CB_SET(6, D); break;
401  case 0xF3: CB_SET(6, E); break;
402  case 0xF4: CB_SET(6, H); break;
403  case 0xF5: CB_SET(6, L); break;
404  case 0xF6: CB_SET_HL(6); break;
405  case 0xF7: CB_SET(6, A); break;
406  case 0xF8: CB_SET(7, B); break;
407  case 0xF9: CB_SET(7, C); break;
408  case 0xFA: CB_SET(7, D); break;
409  case 0xFB: CB_SET(7, E); break;
410  case 0xFC: CB_SET(7, H); break;
411  case 0xFD: CB_SET(7, L); break;
412  case 0xFE: CB_SET_HL(7); break;
413  case 0xFF: CB_SET(7, A); break;
414  }
415 
416 #undef CBINST
417 #undef CBINST_HL
418 #undef CBINST_UNDOC
419 #undef CBINST_UNDOC_HL
420 #undef CB_BIT
421 #undef CB_BIT_HL
422 #undef CB_RES
423 #undef CB_RES_HL
424 #undef CB_SET
425 #undef CB_SET_HL
426 
427