Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
716 | lvd | 1 | #include "defs.h" |
784 | DimkaM | 2 | #include "op_noprefix.h" |
716 | lvd | 3 | #include "tables.h" |
4 | #include "op_ed.h" |
||
5 | #include "op_dd.h" |
||
6 | #include "op_fd.h" |
||
7 | |||
8 | /* DDCB/FDCB opcodes */ |
||
9 | /* note: cpu.t and destination updated in step(), here process 'byte' */ |
||
10 | |||
11 | //#ifdef Z80_COMMON |
||
784 | DimkaM | 12 | static Z80LOGIC oplx_00(Z80 *cpu, unsigned char byte) { // rlc (ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
716 | lvd | 13 | cpu->f = rlcf[byte]; return rol[byte]; |
14 | } |
||
784 | DimkaM | 15 | static Z80LOGIC oplx_08(Z80 *cpu, unsigned char byte) { // rrc (ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
716 | lvd | 16 | cpu->f = rrcf[byte]; return ror[byte]; |
17 | } |
||
784 | DimkaM | 18 | static Z80LOGIC oplx_10(Z80 *cpu, unsigned char byte) { // rl (ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
19 | if(cpu->f & CF) |
||
20 | { |
||
21 | cpu->f = rl1[byte]; |
||
22 | return u8((byte << 1) | 1); |
||
23 | } |
||
24 | else |
||
25 | { |
||
26 | cpu->f = rl0[byte]; |
||
27 | return u8(byte << 1); |
||
28 | } |
||
716 | lvd | 29 | } |
784 | DimkaM | 30 | static Z80LOGIC oplx_18(Z80 *cpu, unsigned char byte) { // rr (ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
716 | lvd | 31 | if (cpu->f & CF) { |
32 | cpu->f = rr1[byte]; return (byte >> 1) + 0x80; |
||
33 | } else { |
||
34 | cpu->f = rr0[byte]; return (byte >> 1); |
||
35 | } |
||
36 | } |
||
784 | DimkaM | 37 | static Z80LOGIC oplx_20(Z80 *cpu, unsigned char byte) { // sla (ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
38 | cpu->f = rl0[byte]; |
||
39 | return u8(byte << 1); |
||
716 | lvd | 40 | } |
784 | DimkaM | 41 | static Z80LOGIC oplx_28(Z80 *cpu, unsigned char byte) { // sra (ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
716 | lvd | 42 | cpu->f = sraf[byte]; return (byte >> 1) + (byte & 0x80); |
43 | } |
||
784 | DimkaM | 44 | static Z80LOGIC oplx_30(Z80 *cpu, unsigned char byte) { // sli (ix+nn) |
45 | cpu->f = rl1[byte]; |
||
46 | return u8((byte << 1) | 1); |
||
716 | lvd | 47 | } |
784 | DimkaM | 48 | static Z80LOGIC oplx_38(Z80 *cpu, unsigned char byte) { // srl (ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
716 | lvd | 49 | cpu->f = rr0[byte]; return (byte >> 1); |
50 | } |
||
784 | DimkaM | 51 | static Z80LOGIC oplx_40(Z80 *cpu, unsigned char byte) { // bit 0,(ix+nn) | M:5 T:20 (4, 4, 3, 5, 4) |
716 | lvd | 52 | bitmem(cpu, byte, 0); return byte; |
53 | } |
||
784 | DimkaM | 54 | static Z80LOGIC oplx_48(Z80 *cpu, unsigned char byte) { // bit 1,(ix+nn) | M:5 T:20 (4, 4, 3, 5, 4) |
716 | lvd | 55 | bitmem(cpu, byte, 1); return byte; |
56 | } |
||
784 | DimkaM | 57 | static Z80LOGIC oplx_50(Z80 *cpu, unsigned char byte) { // bit 2,(ix+nn) | M:5 T:20 (4, 4, 3, 5, 4) |
716 | lvd | 58 | bitmem(cpu, byte, 2); return byte; |
59 | } |
||
784 | DimkaM | 60 | static Z80LOGIC oplx_58(Z80 *cpu, unsigned char byte) { // bit 3,(ix+nn) | M:5 T:20 (4, 4, 3, 5, 4) |
716 | lvd | 61 | bitmem(cpu, byte, 3); return byte; |
62 | } |
||
784 | DimkaM | 63 | static Z80LOGIC oplx_60(Z80 *cpu, unsigned char byte) { // bit 4,(ix+nn) | M:5 T:20 (4, 4, 3, 5, 4) |
716 | lvd | 64 | bitmem(cpu, byte, 4); return byte; |
65 | } |
||
784 | DimkaM | 66 | static Z80LOGIC oplx_68(Z80 *cpu, unsigned char byte) { // bit 5,(ix+nn) | M:5 T:20 (4, 4, 3, 5, 4) |
716 | lvd | 67 | bitmem(cpu, byte, 5); return byte; |
68 | } |
||
784 | DimkaM | 69 | static Z80LOGIC oplx_70(Z80 *cpu, unsigned char byte) { // bit 6,(ix+nn) | M:5 T:20 (4, 4, 3, 5, 4) |
716 | lvd | 70 | bitmem(cpu, byte, 6); return byte; |
71 | } |
||
784 | DimkaM | 72 | static Z80LOGIC oplx_78(Z80 *cpu, unsigned char byte) { // bit 7,(ix+nn) | M:5 T:20 (4, 4, 3, 5, 4) |
716 | lvd | 73 | bitmem(cpu, byte, 7); return byte; |
74 | } |
||
784 | DimkaM | 75 | static Z80LOGIC oplx_80(Z80 *cpu, unsigned char byte) { // res 0,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
76 | (void)cpu; |
||
77 | return resbyte(byte, 0); |
||
716 | lvd | 78 | } |
784 | DimkaM | 79 | static Z80LOGIC oplx_88(Z80 *cpu, unsigned char byte) { // res 1,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
80 | (void)cpu; |
||
81 | return resbyte(byte, 1); |
||
716 | lvd | 82 | } |
784 | DimkaM | 83 | static Z80LOGIC oplx_90(Z80 *cpu, unsigned char byte) { // res 2,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
84 | (void)cpu; |
||
85 | return resbyte(byte, 2); |
||
716 | lvd | 86 | } |
784 | DimkaM | 87 | static Z80LOGIC oplx_98(Z80 *cpu, unsigned char byte) { // res 3,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
88 | (void)cpu; |
||
89 | return resbyte(byte, 3); |
||
716 | lvd | 90 | } |
784 | DimkaM | 91 | static Z80LOGIC oplx_A0(Z80 *cpu, unsigned char byte) { // res 4,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
92 | (void)cpu; |
||
93 | return resbyte(byte, 4); |
||
716 | lvd | 94 | } |
784 | DimkaM | 95 | static Z80LOGIC oplx_A8(Z80 *cpu, unsigned char byte) { // res 5,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
96 | (void)cpu; |
||
97 | return resbyte(byte, 5); |
||
716 | lvd | 98 | } |
784 | DimkaM | 99 | static Z80LOGIC oplx_B0(Z80 *cpu, unsigned char byte) { // res 6,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
100 | (void)cpu; |
||
101 | return resbyte(byte, 6); |
||
716 | lvd | 102 | } |
784 | DimkaM | 103 | static Z80LOGIC oplx_B8(Z80 *cpu, unsigned char byte) { // res 7,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
104 | (void)cpu; |
||
105 | return resbyte(byte, 7); |
||
716 | lvd | 106 | } |
784 | DimkaM | 107 | static Z80LOGIC oplx_C0(Z80 *cpu, unsigned char byte) { // set 0,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
108 | (void)cpu; |
||
109 | return setbyte(byte, 0); |
||
716 | lvd | 110 | } |
784 | DimkaM | 111 | static Z80LOGIC oplx_C8(Z80 *cpu, unsigned char byte) { // set 1,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
112 | (void)cpu; |
||
113 | return setbyte(byte, 1); |
||
716 | lvd | 114 | } |
784 | DimkaM | 115 | static Z80LOGIC oplx_D0(Z80 *cpu, unsigned char byte) { // set 2,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
116 | (void)cpu; |
||
117 | return setbyte(byte, 2); |
||
716 | lvd | 118 | } |
784 | DimkaM | 119 | static Z80LOGIC oplx_D8(Z80 *cpu, unsigned char byte) { // set 3,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
120 | (void)cpu; |
||
121 | return setbyte(byte, 3); |
||
716 | lvd | 122 | } |
784 | DimkaM | 123 | static Z80LOGIC oplx_E0(Z80 *cpu, unsigned char byte) { // set 4,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
124 | (void)cpu; |
||
125 | return setbyte(byte, 4); |
||
716 | lvd | 126 | } |
784 | DimkaM | 127 | static Z80LOGIC oplx_E8(Z80 *cpu, unsigned char byte) { // set 5,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
128 | (void)cpu; |
||
129 | return setbyte(byte, 5); |
||
716 | lvd | 130 | } |
784 | DimkaM | 131 | static Z80LOGIC oplx_F0(Z80 *cpu, unsigned char byte) { // set 6,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
132 | (void)cpu; |
||
133 | return setbyte(byte, 6); |
||
716 | lvd | 134 | } |
784 | DimkaM | 135 | static Z80LOGIC oplx_F8(Z80 *cpu, unsigned char byte) { // set 7,(ix+nn) | M:6 T:23 (4, 4, 3, 5, 4, 3) |
136 | (void)cpu; |
||
137 | return setbyte(byte, 7); |
||
716 | lvd | 138 | } |
139 | |||
140 | LOGICFUNC const logic_ix_opcode[0x100] = { |
||
141 | |||
142 | oplx_00, oplx_00, oplx_00, oplx_00, oplx_00, oplx_00, oplx_00, oplx_00, |
||
143 | oplx_08, oplx_08, oplx_08, oplx_08, oplx_08, oplx_08, oplx_08, oplx_08, |
||
144 | oplx_10, oplx_10, oplx_10, oplx_10, oplx_10, oplx_10, oplx_10, oplx_10, |
||
145 | oplx_18, oplx_18, oplx_18, oplx_18, oplx_18, oplx_18, oplx_18, oplx_18, |
||
146 | oplx_20, oplx_20, oplx_20, oplx_20, oplx_20, oplx_20, oplx_20, oplx_20, |
||
147 | oplx_28, oplx_28, oplx_28, oplx_28, oplx_28, oplx_28, oplx_28, oplx_28, |
||
148 | oplx_30, oplx_30, oplx_30, oplx_30, oplx_30, oplx_30, oplx_30, oplx_30, |
||
149 | oplx_38, oplx_38, oplx_38, oplx_38, oplx_38, oplx_38, oplx_38, oplx_38, |
||
150 | |||
151 | oplx_40, oplx_40, oplx_40, oplx_40, oplx_40, oplx_40, oplx_40, oplx_40, |
||
152 | oplx_48, oplx_48, oplx_48, oplx_48, oplx_48, oplx_48, oplx_48, oplx_48, |
||
153 | oplx_50, oplx_50, oplx_50, oplx_50, oplx_50, oplx_50, oplx_50, oplx_50, |
||
154 | oplx_58, oplx_58, oplx_58, oplx_58, oplx_58, oplx_58, oplx_58, oplx_58, |
||
155 | oplx_60, oplx_60, oplx_60, oplx_60, oplx_60, oplx_60, oplx_60, oplx_60, |
||
156 | oplx_68, oplx_68, oplx_68, oplx_68, oplx_68, oplx_68, oplx_68, oplx_68, |
||
157 | oplx_70, oplx_70, oplx_70, oplx_70, oplx_70, oplx_70, oplx_70, oplx_70, |
||
158 | oplx_78, oplx_78, oplx_78, oplx_78, oplx_78, oplx_78, oplx_78, oplx_78, |
||
159 | |||
160 | oplx_80, oplx_80, oplx_80, oplx_80, oplx_80, oplx_80, oplx_80, oplx_80, |
||
161 | oplx_88, oplx_88, oplx_88, oplx_88, oplx_88, oplx_88, oplx_88, oplx_88, |
||
162 | oplx_90, oplx_90, oplx_90, oplx_90, oplx_90, oplx_90, oplx_90, oplx_90, |
||
163 | oplx_98, oplx_98, oplx_98, oplx_98, oplx_98, oplx_98, oplx_98, oplx_98, |
||
164 | oplx_A0, oplx_A0, oplx_A0, oplx_A0, oplx_A0, oplx_A0, oplx_A0, oplx_A0, |
||
165 | oplx_A8, oplx_A8, oplx_A8, oplx_A8, oplx_A8, oplx_A8, oplx_A8, oplx_A8, |
||
166 | oplx_B0, oplx_B0, oplx_B0, oplx_B0, oplx_B0, oplx_B0, oplx_B0, oplx_B0, |
||
167 | oplx_B8, oplx_B8, oplx_B8, oplx_B8, oplx_B8, oplx_B8, oplx_B8, oplx_B8, |
||
168 | |||
169 | oplx_C0, oplx_C0, oplx_C0, oplx_C0, oplx_C0, oplx_C0, oplx_C0, oplx_C0, |
||
170 | oplx_C8, oplx_C8, oplx_C8, oplx_C8, oplx_C8, oplx_C8, oplx_C8, oplx_C8, |
||
171 | oplx_D0, oplx_D0, oplx_D0, oplx_D0, oplx_D0, oplx_D0, oplx_D0, oplx_D0, |
||
172 | oplx_D8, oplx_D8, oplx_D8, oplx_D8, oplx_D8, oplx_D8, oplx_D8, oplx_D8, |
||
173 | oplx_E0, oplx_E0, oplx_E0, oplx_E0, oplx_E0, oplx_E0, oplx_E0, oplx_E0, |
||
174 | oplx_E8, oplx_E8, oplx_E8, oplx_E8, oplx_E8, oplx_E8, oplx_E8, oplx_E8, |
||
175 | oplx_F0, oplx_F0, oplx_F0, oplx_F0, oplx_F0, oplx_F0, oplx_F0, oplx_F0, |
||
176 | oplx_F8, oplx_F8, oplx_F8, oplx_F8, oplx_F8, oplx_F8, oplx_F8, oplx_F8, |
||
177 | |||
178 | }; |
||
179 | |||
784 | DimkaM | 180 | // offsets to b,c,d,e,h,l,trash,a from cpu.c |
800 | DimkaM | 181 | static const unsigned reg_offset[] = |
784 | DimkaM | 182 | { |
183 | (offsetof(TZ80State, b) - offsetof(TZ80State, c)), |
||
184 | (offsetof(TZ80State, c) - offsetof(TZ80State, c)), |
||
185 | (offsetof(TZ80State, d) - offsetof(TZ80State, c)), |
||
186 | (offsetof(TZ80State, e) - offsetof(TZ80State, c)), |
||
187 | (offsetof(TZ80State, h) - offsetof(TZ80State, c)), |
||
188 | (offsetof(TZ80State, l) - offsetof(TZ80State, c)), |
||
189 | (offsetof(TZ80State, trash) - offsetof(TZ80State, c)), |
||
190 | (offsetof(TZ80State, a) - offsetof(TZ80State, c)) |
||
191 | }; |
||
192 | static_assert((offsetof(TZ80State, b) - offsetof(TZ80State, c)) == 1, "bad offset b->c"); |
||
193 | static_assert((offsetof(TZ80State, c) - offsetof(TZ80State, c)) == 0, "bad offset c->c"); |
||
194 | static_assert((offsetof(TZ80State, d) - offsetof(TZ80State, c)) == 5, "bad offset d->c"); |
||
195 | static_assert((offsetof(TZ80State, e) - offsetof(TZ80State, c)) == 4, "bad offset e->c"); |
||
196 | static_assert((offsetof(TZ80State, h) - offsetof(TZ80State, c)) == 9, "bad offset h->c"); |
||
197 | static_assert((offsetof(TZ80State, l) - offsetof(TZ80State, c)) == 8, "bad offset l->c"); |
||
198 | static_assert((offsetof(TZ80State, trash) - offsetof(TZ80State, c)) == 2, "bad offset trash->c"); |
||
199 | static_assert((offsetof(TZ80State, a) - offsetof(TZ80State, c)) == 13, "bad offset a->c"); |
||
716 | lvd | 200 | //#endif |
201 | |||
202 | //#ifndef Z80_COMMON |
||
203 | Z80INLINE void Z80FAST ddfd(Z80 *cpu, unsigned char opcode) |
||
204 | { |
||
205 | unsigned char op1; // last DD/FD prefix |
||
206 | do { |
||
207 | op1 = opcode; |
||
208 | opcode = cpu->m1_cycle(); |
||
209 | } while ((opcode | 0x20) == 0xFD); // opcode == DD/FD |
||
210 | |||
211 | if (opcode == 0xCB) { |
||
212 | |||
213 | unsigned ptr; // pointer to DDCB operand |
||
784 | DimkaM | 214 | ptr = unsigned(int((op1 == 0xDD) ? cpu->ix:cpu->iy) + i8(cpu->MemIf->xm(cpu->pc++))); |
716 | lvd | 215 | cpu->memptr = ptr; |
216 | // DDCBnnXX,FDCBnnXX increment R by 2, not 3! |
||
217 | opcode = cpu->m1_cycle(); cpu->r_low--; |
||
218 | unsigned char byte = (logic_ix_opcode[opcode])(cpu, cpu->MemIf->rm(ptr)); |
||
219 | if ((opcode & 0xC0) == 0x40) { cpu->t += 8; return; } // bit n,rm |
||
220 | |||
221 | // select destination register for shift/res/set |
||
222 | *(&cpu->c + reg_offset[opcode & 7]) = byte; |
||
223 | cpu->MemIf->wm(ptr, byte); |
||
224 | cpu->t += 11; |
||
225 | return; |
||
226 | } |
||
227 | |||
228 | if (opcode == 0xED) { |
||
229 | opcode = cpu->m1_cycle(); |
||
230 | (ext_opcode[opcode])(cpu); |
||
231 | return; |
||
232 | } |
||
233 | |||
234 | // one prefix: DD/FD |
||
235 | ((op1 == 0xDD) ? ix_opcode[opcode] : iy_opcode[opcode])(cpu); |
||
236 | } |
||
237 | |||
238 | Z80OPCODE op_DD(Z80 *cpu) |
||
239 | { |
||
240 | ddfd(cpu, 0xDD); |
||
241 | } |
||
242 | |||
243 | Z80OPCODE op_FD(Z80 *cpu) |
||
244 | { |
||
245 | ddfd(cpu, 0xFD); |
||
246 | } |
||
247 | //#endif |