Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
716 | lvd | 1 | #include "defs.h" |
2 | #include "tables.h" |
||
3 | #include "op_noprefix.h" |
||
4 | #include "op_ed.h" |
||
5 | |||
6 | /* ED opcodes */ |
||
7 | |||
8 | //#ifndef Z80_COMMON |
||
784 | DimkaM | 9 | static Z80OPCODE ope_40(Z80 *cpu) { // in b,(c) |
716 | lvd | 10 | cpu->t += 4; |
11 | cpu->memptr = cpu->bc+1; |
||
12 | cpu->b = cpu->in(cpu->bc); |
||
13 | cpu->f = log_f[cpu->b] | (cpu->f & CF); |
||
14 | } |
||
784 | DimkaM | 15 | static Z80OPCODE ope_41(Z80 *cpu) { // out (c),b | M:3 T:12 (4, 4, 4) |
716 | lvd | 16 | cpu->t += 4; |
17 | cpu->memptr = cpu->bc+1; |
||
18 | cpu->out(cpu->bc, cpu->b); |
||
19 | } |
||
20 | //#endif |
||
21 | //#ifdef Z80_COMMON |
||
784 | DimkaM | 22 | static Z80OPCODE ope_42(Z80 *cpu) { // sbc hl,bc |
716 | lvd | 23 | cpu->memptr = cpu->hl+1; |
24 | unsigned char fl = NF; |
||
25 | fl |= (((cpu->hl & 0x0FFF) - (cpu->bc & 0x0FFF) - (cpu->af & CF)) >> 8) & 0x10; /* HF */ |
||
26 | unsigned tmp = (cpu->hl & 0xFFFF) - (cpu->bc & 0xFFFF) - (cpu->af & CF); |
||
27 | if (tmp & 0x10000) fl |= CF; |
||
28 | if (!(tmp & 0xFFFF)) fl |= ZF; |
||
29 | int ri = (int)(short)cpu->hl - (int)(short)cpu->bc - (int)(cpu->af & CF); |
||
30 | if (ri < -0x8000 || ri >= 0x8000) fl |= PV; |
||
31 | cpu->hl = tmp; |
||
32 | cpu->f = fl | (cpu->h & (F3|F5|SF)); |
||
33 | cpu->t += 7; |
||
34 | } |
||
35 | //#endif |
||
36 | //#ifndef Z80_COMMON |
||
784 | DimkaM | 37 | static Z80OPCODE ope_43(Z80 *cpu) { // ld (nnnn),bc | M:6 T:20 (4, 4, 3, 3, 3, 3) |
716 | lvd | 38 | unsigned adr = cpu->MemIf->xm(cpu->pc++); |
39 | adr += cpu->MemIf->xm(cpu->pc++)*0x100; |
||
40 | cpu->memptr = adr+1; |
||
41 | cpu->MemIf->wm(adr, cpu->c); |
||
42 | cpu->MemIf->wm(adr+1, cpu->b); |
||
43 | cpu->t += 12; |
||
44 | } |
||
45 | //#endif |
||
46 | //#ifdef Z80_COMMON |
||
784 | DimkaM | 47 | static Z80OPCODE ope_44(Z80 *cpu) { // neg |
716 | lvd | 48 | cpu->f = sbcf[cpu->a]; |
49 | cpu->a = -cpu->a; |
||
50 | } |
||
51 | //#endif |
||
52 | //#ifndef Z80_COMMON |
||
784 | DimkaM | 53 | static Z80OPCODE ope_45(Z80 *cpu) { // retn |
716 | lvd | 54 | cpu->iff1 = cpu->iff2; |
55 | unsigned addr = cpu->MemIf->rm(cpu->sp++); |
||
56 | addr += 0x100*cpu->MemIf->rm(cpu->sp++); |
||
784 | DimkaM | 57 | cpu->last_branch = u16(cpu->pc-2); |
716 | lvd | 58 | cpu->pc = addr; |
59 | cpu->memptr = addr; |
||
60 | cpu->t += 6; |
||
61 | cpu->retn(); |
||
62 | } |
||
63 | //#endif |
||
64 | //#ifdef Z80_COMMON |
||
784 | DimkaM | 65 | static Z80OPCODE ope_46(Z80 *cpu) { // im 0 |
716 | lvd | 66 | cpu->im = 0; |
67 | } |
||
784 | DimkaM | 68 | static Z80OPCODE ope_47(Z80 *cpu) { // ld i,a |
716 | lvd | 69 | cpu->i = cpu->a; |
70 | cpu->t++; |
||
71 | } |
||
72 | //#endif |
||
73 | //#ifndef Z80_COMMON |
||
784 | DimkaM | 74 | static Z80OPCODE ope_48(Z80 *cpu) { // in c,(c) |
716 | lvd | 75 | cpu->t += 4; |
76 | cpu->memptr = cpu->bc+1; |
||
77 | cpu->c = cpu->in(cpu->bc); |
||
78 | cpu->f = log_f[cpu->c] | (cpu->f & CF); |
||
79 | } |
||
784 | DimkaM | 80 | static Z80OPCODE ope_49(Z80 *cpu) { // out (c),c | M:3 T:12 (4, 4, 4) |
716 | lvd | 81 | cpu->t += 4; |
82 | cpu->memptr = cpu->bc+1; |
||
83 | cpu->out(cpu->bc, cpu->c); |
||
84 | } |
||
85 | //#endif |
||
86 | //#ifdef Z80_COMMON |
||
784 | DimkaM | 87 | static Z80OPCODE ope_4A(Z80 *cpu) { // adc hl,bc |
716 | lvd | 88 | cpu->memptr = cpu->hl+1; |
89 | unsigned char fl = (((cpu->hl & 0x0FFF) + (cpu->bc & 0x0FFF) + (cpu->af & CF)) >> 8) & 0x10; /* HF */ |
||
90 | unsigned tmp = (cpu->hl & 0xFFFF) + (cpu->bc & 0xFFFF) + (cpu->af & CF); |
||
91 | if (tmp & 0x10000) fl |= CF; |
||
92 | if (!(tmp & 0xFFFF)) fl |= ZF; |
||
93 | int ri = (int)(short)cpu->hl + (int)(short)cpu->bc + (int)(cpu->af & CF); |
||
94 | if (ri < -0x8000 || ri >= 0x8000) fl |= PV; |
||
95 | cpu->hl = tmp; |
||
96 | cpu->f = fl | (cpu->h & (F3|F5|SF)); |
||
97 | cpu->t += 7; |
||
98 | } |
||
99 | //#endif |
||
100 | //#ifndef Z80_COMMON |
||
784 | DimkaM | 101 | static Z80OPCODE ope_4B(Z80 *cpu) { // ld bc,(nnnn) |
716 | lvd | 102 | unsigned adr = cpu->MemIf->xm(cpu->pc++); |
103 | adr += cpu->MemIf->xm(cpu->pc++)*0x100; |
||
104 | cpu->memptr = adr+1; |
||
105 | cpu->c = cpu->MemIf->rm(adr); |
||
106 | cpu->b = cpu->MemIf->rm(adr+1); |
||
107 | cpu->t += 12; |
||
108 | } |
||
109 | #define ope_4C ope_44 // neg |
||
784 | DimkaM | 110 | static Z80OPCODE ope_4D(Z80 *cpu) { // reti |
716 | lvd | 111 | cpu->iff1 = cpu->iff2; |
112 | unsigned addr = cpu->MemIf->rm(cpu->sp++); |
||
113 | addr += 0x100*cpu->MemIf->rm(cpu->sp++); |
||
784 | DimkaM | 114 | cpu->last_branch = u16(cpu->pc-2); |
716 | lvd | 115 | cpu->pc = addr; |
116 | cpu->memptr = addr; |
||
117 | cpu->t += 6; |
||
118 | } |
||
119 | //#endif |
||
120 | |||
121 | #define ope_4E ope_56 // im 0/1 -> im1 |
||
122 | |||
123 | //#ifdef Z80_COMMON |
||
784 | DimkaM | 124 | static Z80OPCODE ope_4F(Z80 *cpu) { // ld r,a |
716 | lvd | 125 | cpu->r_low = cpu->a; |
126 | cpu->r_hi = cpu->a & 0x80; |
||
127 | cpu->t++; |
||
128 | } |
||
129 | //#endif |
||
130 | //#ifndef Z80_COMMON |
||
784 | DimkaM | 131 | static Z80OPCODE ope_50(Z80 *cpu) { // in d,(c) |
716 | lvd | 132 | cpu->t += 4; |
133 | cpu->memptr = cpu->bc+1; |
||
134 | cpu->d = cpu->in(cpu->bc); |
||
135 | cpu->f = log_f[cpu->d] | (cpu->f & CF); |
||
136 | } |
||
784 | DimkaM | 137 | static Z80OPCODE ope_51(Z80 *cpu) { // out (c),d | M:3 T:12 (4, 4, 4) |
716 | lvd | 138 | cpu->t += 4; |
139 | cpu->memptr = cpu->bc+1; |
||
140 | cpu->out(cpu->bc, cpu->d); |
||
141 | } |
||
142 | //#endif |
||
143 | //#ifdef Z80_COMMON |
||
784 | DimkaM | 144 | static Z80OPCODE ope_52(Z80 *cpu) { // sbc hl,de |
716 | lvd | 145 | cpu->memptr = cpu->hl+1; |
146 | unsigned char fl = NF; |
||
147 | fl |= (((cpu->hl & 0x0FFF) - (cpu->de & 0x0FFF) - (cpu->af & CF)) >> 8) & 0x10; /* HF */ |
||
148 | unsigned tmp = (cpu->hl & 0xFFFF) - (cpu->de & 0xFFFF) - (cpu->af & CF); |
||
149 | if (tmp & 0x10000) fl |= CF; |
||
150 | if (!(tmp & 0xFFFF)) fl |= ZF; |
||
151 | int ri = (int)(short)cpu->hl - (int)(short)cpu->de - (int)(cpu->af & CF); |
||
152 | if (ri < -0x8000 || ri >= 0x8000) fl |= PV; |
||
153 | cpu->hl = tmp; |
||
154 | cpu->f = fl | (cpu->h & (F3|F5|SF)); |
||
155 | cpu->t += 7; |
||
156 | } |
||
157 | //#endif |
||
158 | //#ifndef Z80_COMMON |
||
784 | DimkaM | 159 | static Z80OPCODE ope_53(Z80 *cpu) { // ld (nnnn),de | M:6 T:20 (4, 4, 3, 3, 3, 3) |
716 | lvd | 160 | unsigned adr = cpu->MemIf->xm(cpu->pc++); |
161 | adr += cpu->MemIf->xm(cpu->pc++)*0x100; |
||
162 | cpu->memptr = adr+1; |
||
163 | cpu->MemIf->wm(adr, cpu->e); |
||
164 | cpu->MemIf->wm(adr+1, cpu->d); |
||
165 | cpu->t += 12; |
||
166 | } |
||
167 | //#endif |
||
168 | |||
169 | #define ope_54 ope_44 // neg |
||
170 | #define ope_55 ope_45 // retn |
||
171 | |||
172 | //#ifdef Z80_COMMON |
||
784 | DimkaM | 173 | static Z80OPCODE ope_56(Z80 *cpu) { // im 1 |
716 | lvd | 174 | cpu->im = 1; |
175 | } |
||
176 | |||
784 | DimkaM | 177 | static Z80OPCODE ope_57(Z80 *cpu) |
716 | lvd | 178 | { // ld a,i |
179 | cpu->a = cpu->i; |
||
180 | cpu->f = (log_f[cpu->a] | (cpu->f & CF)) & ~PV; |
||
765 | dimkam | 181 | if (cpu->iff2 && (cpu->t+10 < cpu->tpi)) |
716 | lvd | 182 | cpu->f |= PV; |
183 | cpu->t++; |
||
184 | } |
||
185 | //#endif |
||
186 | //#ifndef Z80_COMMON |
||
784 | DimkaM | 187 | static Z80OPCODE ope_58(Z80 *cpu) { // in e,(c) |
716 | lvd | 188 | cpu->t += 4; |
189 | cpu->memptr = cpu->bc+1; |
||
190 | cpu->e = cpu->in(cpu->bc); |
||
191 | cpu->f = log_f[cpu->e] | (cpu->f & CF); |
||
192 | } |
||
784 | DimkaM | 193 | static Z80OPCODE ope_59(Z80 *cpu) { // out (c),e | M:3 T:12 (4, 4, 4) |
716 | lvd | 194 | cpu->t += 4; |
195 | cpu->memptr = cpu->bc+1; |
||
196 | cpu->out(cpu->bc, cpu->e); |
||
197 | } |
||
198 | //#endif |
||
199 | //#ifdef Z80_COMMON |
||
784 | DimkaM | 200 | static Z80OPCODE ope_5A(Z80 *cpu) { // adc hl,de |
716 | lvd | 201 | cpu->memptr = cpu->hl+1; |
202 | unsigned char fl = (((cpu->hl & 0x0FFF) + (cpu->de & 0x0FFF) + (cpu->af & CF)) >> 8) & 0x10; /* HF */ |
||
203 | unsigned tmp = (cpu->hl & 0xFFFF) + (cpu->de & 0xFFFF) + (cpu->af & CF); |
||
204 | if (tmp & 0x10000) fl |= CF; |
||
205 | if (!(tmp & 0xFFFF)) fl |= ZF; |
||
206 | int ri = (int)(short)cpu->hl + (int)(short)cpu->de + (int)(cpu->af & CF); |
||
207 | if (ri < -0x8000 || ri >= 0x8000) fl |= PV; |
||
208 | cpu->hl = tmp; |
||
209 | cpu->f = fl | (cpu->h & (F3|F5|SF)); |
||
210 | cpu->t += 7; |
||
211 | } |
||
212 | //#endif |
||
213 | //#ifndef Z80_COMMON |
||
784 | DimkaM | 214 | static Z80OPCODE ope_5B(Z80 *cpu) { // ld de,(nnnn) |
716 | lvd | 215 | unsigned adr = cpu->MemIf->xm(cpu->pc++); |
216 | adr += cpu->MemIf->xm(cpu->pc++)*0x100; |
||
217 | cpu->memptr = adr+1; |
||
218 | cpu->e = cpu->MemIf->rm(adr); |
||
219 | cpu->d = cpu->MemIf->rm(adr+1); |
||
220 | cpu->t += 12; |
||
221 | } |
||
222 | //#endif |
||
223 | |||
224 | #define ope_5C ope_44 // neg |
||
225 | #define ope_5D ope_4D // reti |
||
226 | |||
227 | //#ifdef Z80_COMMON |
||
784 | DimkaM | 228 | static Z80OPCODE ope_5E(Z80 *cpu) { // im 2 |
716 | lvd | 229 | cpu->im = 2; |
230 | } |
||
231 | |||
784 | DimkaM | 232 | static Z80OPCODE ope_5F(Z80 *cpu) |
716 | lvd | 233 | { // ld a,r |
234 | cpu->a = (cpu->r_low & 0x7F) | cpu->r_hi; |
||
235 | cpu->f = (log_f[cpu->a] | (cpu->f & CF)) & ~PV; |
||
236 | if (cpu->iff2 && ((cpu->t+10 < cpu->tpi) || cpu->eipos+8==cpu->t)) |
||
237 | cpu->f |= PV; |
||
238 | cpu->t++; |
||
239 | } |
||
240 | //#endif |
||
241 | //#ifndef Z80_COMMON |
||
784 | DimkaM | 242 | static Z80OPCODE ope_60(Z80 *cpu) { // in h,(c) |
716 | lvd | 243 | cpu->t += 4; |
244 | cpu->memptr = cpu->bc+1; |
||
245 | cpu->h = cpu->in(cpu->bc); |
||
246 | cpu->f = log_f[cpu->h] | (cpu->f & CF); |
||
247 | } |
||
784 | DimkaM | 248 | static Z80OPCODE ope_61(Z80 *cpu) { // out (c),h | M:3 T:12 (4, 4, 4) |
716 | lvd | 249 | cpu->t += 4; |
250 | cpu->memptr = cpu->bc+1; |
||
251 | cpu->out(cpu->bc, cpu->h); |
||
252 | } |
||
253 | //#endif |
||
254 | //#ifdef Z80_COMMON |
||
784 | DimkaM | 255 | static Z80OPCODE ope_62(Z80 *cpu) { // sbc hl,hl |
716 | lvd | 256 | cpu->memptr = cpu->hl+1; |
257 | unsigned char fl = NF; |
||
258 | fl |= (cpu->f & CF) << 4; /* HF - copy from CF */ |
||
259 | unsigned tmp = 0-(cpu->af & CF); |
||
260 | if (tmp & 0x10000) fl |= CF; |
||
261 | if (!(tmp & 0xFFFF)) fl |= ZF; |
||
262 | // never set PV |
||
263 | cpu->hl = tmp; |
||
264 | cpu->f = fl | (cpu->h & (F3|F5|SF)); |
||
265 | cpu->t += 7; |
||
266 | } |
||
267 | //#endif |
||
268 | |||
269 | #define ope_63 op_22 // ld (nnnn),hl |
||
270 | #define ope_64 ope_44 // neg |
||
271 | #define ope_65 ope_45 // retn |
||
272 | #define ope_66 ope_46 // im 0 |
||
273 | |||
274 | //#ifndef Z80_COMMON |
||
784 | DimkaM | 275 | static Z80OPCODE ope_67(Z80 *cpu) { // rrd | M:5 T:18 (4, 4, 3, 4, 3) |
716 | lvd | 276 | unsigned char tmp = cpu->MemIf->rm(cpu->hl); |
277 | cpu->memptr = cpu->hl+1; |
||
784 | DimkaM | 278 | cpu->MemIf->wm(cpu->hl, u8(cpu->a << 4) | u8(tmp >> 4)); |
716 | lvd | 279 | cpu->a = (cpu->a & 0xF0) | (tmp & 0x0F); |
280 | cpu->f = log_f[cpu->a] | (cpu->f & CF); |
||
281 | cpu->t += 10; |
||
282 | } |
||
283 | //#endif |
||
284 | //#ifndef Z80_COMMON |
||
784 | DimkaM | 285 | static Z80OPCODE ope_68(Z80 *cpu) { // in l,(c) |
716 | lvd | 286 | cpu->t += 4; |
287 | cpu->memptr = cpu->bc+1; |
||
288 | cpu->l = cpu->in(cpu->bc); |
||
289 | cpu->f = log_f[cpu->l] | (cpu->f & CF); |
||
290 | } |
||
784 | DimkaM | 291 | static Z80OPCODE ope_69(Z80 *cpu) { // out (c),l | M:3 T:12 (4, 4, 4) |
716 | lvd | 292 | cpu->t += 4; |
293 | cpu->memptr = cpu->bc+1; |
||
294 | cpu->out(cpu->bc, cpu->l); |
||
295 | } |
||
296 | //#endif |
||
297 | //#ifdef Z80_COMMON |
||
784 | DimkaM | 298 | static Z80OPCODE ope_6A(Z80 *cpu) { // adc hl,hl |
716 | lvd | 299 | cpu->memptr = cpu->hl+1; |
300 | unsigned char fl = ((cpu->h << 1) & 0x10); /* HF */ |
||
301 | unsigned tmp = (cpu->hl & 0xFFFF)*2 + (cpu->af & CF); |
||
302 | if (tmp & 0x10000) fl |= CF; |
||
303 | if (!(tmp & 0xFFFF)) fl |= ZF; |
||
304 | int ri = 2*(int)(short)cpu->hl + (int)(cpu->af & CF); |
||
305 | if (ri < -0x8000 || ri >= 0x8000) fl |= PV; |
||
306 | cpu->hl = tmp; |
||
307 | cpu->f = fl | (cpu->h & (F3|F5|SF)); |
||
308 | cpu->t += 7; |
||
309 | } |
||
310 | //#endif |
||
311 | |||
312 | #define ope_6B op_2A // ld hl,(nnnn) |
||
313 | #define ope_6C ope_44 // neg |
||
314 | #define ope_6D ope_4D // reti |
||
315 | #define ope_6E ope_56 // im 0/1 -> im 1 |
||
316 | |||
317 | //#ifndef Z80_COMMON |
||
784 | DimkaM | 318 | static Z80OPCODE ope_6F(Z80 *cpu) { // rld | M:5 T:18 (4, 4, 3, 4, 3) |
716 | lvd | 319 | unsigned char tmp = cpu->MemIf->rm(cpu->hl); |
320 | cpu->memptr = cpu->hl+1; |
||
784 | DimkaM | 321 | cpu->MemIf->wm(cpu->hl, u8(cpu->a & 0x0F) | u8(tmp << 4)); |
716 | lvd | 322 | cpu->a = (cpu->a & 0xF0) | (tmp >> 4); |
323 | cpu->f = log_f[cpu->a] | (cpu->f & CF); |
||
324 | cpu->t += 10; |
||
325 | } |
||
784 | DimkaM | 326 | static Z80OPCODE ope_70(Z80 *cpu) { // in (c) |
716 | lvd | 327 | cpu->t += 4; |
328 | cpu->memptr = cpu->bc+1; |
||
329 | cpu->f = log_f[cpu->in(cpu->bc)] | (cpu->f & CF); |
||
330 | } |
||
784 | DimkaM | 331 | static Z80OPCODE ope_71(Z80 *cpu) { // out (c),0 |
716 | lvd | 332 | cpu->t += 4; |
333 | cpu->memptr = cpu->bc+1; |
||
334 | cpu->out(cpu->bc, 0); |
||
335 | } |
||
336 | //#endif |
||
337 | //#ifdef Z80_COMMON |
||
784 | DimkaM | 338 | static Z80OPCODE ope_72(Z80 *cpu) { // sbc hl,sp |
716 | lvd | 339 | cpu->memptr = cpu->hl+1; |
340 | unsigned char fl = NF; |
||
341 | fl |= (((cpu->hl & 0x0FFF) - (cpu->sp & 0x0FFF) - (cpu->af & CF)) >> 8) & 0x10; /* HF */ |
||
342 | unsigned tmp = (cpu->hl & 0xFFFF) - (cpu->sp & 0xFFFF) - (cpu->af & CF); |
||
343 | if (tmp & 0x10000) fl |= CF; |
||
344 | if (!(tmp & 0xFFFF)) fl |= ZF; |
||
345 | int ri = (int)(short)cpu->hl - (int)(short)cpu->sp - (int)(cpu->af & CF); |
||
346 | if (ri < -0x8000 || ri >= 0x8000) fl |= PV; |
||
347 | cpu->hl = tmp; |
||
348 | cpu->f = fl | (cpu->h & (F3|F5|SF)); |
||
349 | cpu->t += 7; |
||
350 | } |
||
351 | //#endif |
||
352 | //#ifndef Z80_COMMON |
||
784 | DimkaM | 353 | static Z80OPCODE ope_73(Z80 *cpu) { // ld (nnnn),sp | M:6 T:20 (4, 4, 3, 3, 3, 3) |
716 | lvd | 354 | unsigned adr = cpu->MemIf->xm(cpu->pc++); |
355 | adr += cpu->MemIf->xm(cpu->pc++)*0x100; |
||
356 | cpu->memptr = adr+1; |
||
357 | cpu->MemIf->wm(adr, cpu->spl); |
||
358 | cpu->MemIf->wm(adr+1, cpu->sph); |
||
359 | cpu->t += 12; |
||
360 | } |
||
361 | //#endif |
||
362 | |||
363 | #define ope_74 ope_44 // neg |
||
364 | #define ope_75 ope_45 // retn |
||
365 | |||
366 | //#ifdef Z80_COMMON |
||
784 | DimkaM | 367 | static Z80OPCODE ope_76(Z80 *cpu) { // im 1 |
716 | lvd | 368 | cpu->im = 1; |
369 | } |
||
370 | //#endif |
||
371 | |||
372 | #define ope_77 op_00 // nop |
||
373 | |||
374 | //#ifndef Z80_COMMON |
||
784 | DimkaM | 375 | static Z80OPCODE ope_78(Z80 *cpu) { // in a,(c) |
716 | lvd | 376 | cpu->t += 4; |
377 | cpu->memptr = cpu->bc+1; |
||
378 | cpu->a = cpu->in(cpu->bc); |
||
379 | cpu->f = log_f[cpu->a] | (cpu->f & CF); |
||
380 | } |
||
784 | DimkaM | 381 | static Z80OPCODE ope_79(Z80 *cpu) { // out (c),a | M:3 T:12 (4, 4, 4) |
716 | lvd | 382 | cpu->t += 4; |
383 | cpu->memptr = cpu->bc+1; |
||
384 | cpu->out(cpu->bc, cpu->a); |
||
385 | } |
||
386 | //#endif |
||
387 | //#ifdef Z80_COMMON |
||
784 | DimkaM | 388 | static Z80OPCODE ope_7A(Z80 *cpu) { // adc hl,sp |
716 | lvd | 389 | cpu->memptr = cpu->hl+1; |
390 | unsigned char fl = (((cpu->hl & 0x0FFF) + (cpu->sp & 0x0FFF) + (cpu->af & CF)) >> 8) & 0x10; /* HF */ |
||
391 | unsigned tmp = (cpu->hl & 0xFFFF) + (cpu->sp & 0xFFFF) + (cpu->af & CF); |
||
392 | if (tmp & 0x10000) fl |= CF; |
||
393 | if (!(unsigned short)tmp) fl |= ZF; |
||
394 | int ri = (int)(short)cpu->hl + (int)(short)cpu->sp + (int)(cpu->af & CF); |
||
395 | if (ri < -0x8000 || ri >= 0x8000) fl |= PV; |
||
396 | cpu->hl = tmp; |
||
397 | cpu->f = fl | (cpu->h & (F3|F5|SF)); |
||
398 | cpu->t += 7; |
||
399 | } |
||
400 | //#endif |
||
401 | //#ifndef Z80_COMMON |
||
784 | DimkaM | 402 | static Z80OPCODE ope_7B(Z80 *cpu) { // ld sp,(nnnn) |
716 | lvd | 403 | unsigned adr = cpu->MemIf->xm(cpu->pc++); |
404 | adr += cpu->MemIf->xm(cpu->pc++)*0x100; |
||
405 | cpu->memptr = adr+1; |
||
406 | cpu->spl = cpu->MemIf->rm(adr); |
||
407 | cpu->sph = cpu->MemIf->rm(adr+1); |
||
408 | cpu->t += 12; |
||
409 | } |
||
410 | //#endif |
||
411 | |||
412 | #define ope_7C ope_44 // neg |
||
413 | #define ope_7D ope_4D // reti |
||
414 | #define ope_7E ope_5E // im 2 |
||
415 | #define ope_7F op_00 // nop |
||
416 | |||
417 | //#ifndef Z80_COMMON |
||
784 | DimkaM | 418 | static Z80OPCODE ope_A0(Z80 *cpu) { // ldi | M:4 T:16 (4, 4, 3, 5) |
716 | lvd | 419 | cpu->t += 8; |
420 | unsigned char tempbyte = cpu->MemIf->rm(cpu->hl++); |
||
421 | cpu->MemIf->wm(cpu->de++, tempbyte); |
||
422 | tempbyte += cpu->a; tempbyte = (tempbyte & F3) + ((tempbyte << 4) & F5); |
||
423 | cpu->f = (cpu->f & ~(NF|HF|PV|F3|F5)) + tempbyte; |
||
424 | if (--cpu->bc16) cpu->f |= PV; |
||
425 | } |
||
784 | DimkaM | 426 | static Z80OPCODE ope_A1(Z80 *cpu) { // cpi |
716 | lvd | 427 | cpu->t += 8; |
428 | unsigned char cf = cpu->f & CF; |
||
429 | unsigned char tempbyte = cpu->MemIf->rm(cpu->hl++); |
||
430 | cpu->f = cpf8b[cpu->a*0x100 + tempbyte] + cf; |
||
431 | if (--cpu->bc16) cpu->f |= PV; |
||
432 | cpu->memptr++; |
||
433 | } |
||
784 | DimkaM | 434 | static Z80OPCODE ope_A2(Z80 *cpu) { // ini | M:4 T:16 (4, 5, 3, 4) |
716 | lvd | 435 | cpu->memptr = cpu->bc+1; |
436 | cpu->t += 8; |
||
437 | u8 tmp = cpu->in(cpu->bc); |
||
438 | cpu->MemIf->wm(cpu->hl++, tmp); |
||
439 | cpu->b--; |
||
440 | u8 ftmp = tmp + cpu->c + 1; |
||
441 | cpu->f = log_f[cpu->b] & ~PV; |
||
442 | cpu->f |= (log_f[(ftmp & 7) ^ cpu->b] & PV); |
||
443 | if(ftmp < tmp) cpu->f |= (HF | CF); |
||
444 | cpu->f |= (tmp & 0x80) >> 6; // NF |
||
445 | } |
||
784 | DimkaM | 446 | static Z80OPCODE ope_A3(Z80 *cpu) { // outi | M:4 T:16 (4, 5, 3, 4) |
716 | lvd | 447 | cpu->t += 8; |
448 | cpu->b--; |
||
449 | u8 tmp = cpu->MemIf->rm(cpu->hl++); |
||
450 | cpu->out(cpu->bc, tmp); |
||
451 | |||
452 | u8 ftmp = tmp + cpu->l; |
||
453 | cpu->f = log_f[cpu->b] & ~PV; |
||
454 | cpu->f |= (log_f[(ftmp & 7) ^ cpu->b] & PV); |
||
455 | if(ftmp < tmp) cpu->f |= (HF | CF); |
||
456 | cpu->f |= (tmp & 0x80) >> 6; // NF |
||
457 | |||
458 | cpu->memptr = cpu->bc+1; |
||
459 | } |
||
784 | DimkaM | 460 | static Z80OPCODE ope_A8(Z80 *cpu) { // ldd | M:4 T:16 (4, 4, 3, 5) |
716 | lvd | 461 | cpu->t += 8; |
462 | unsigned char tempbyte = cpu->MemIf->rm(cpu->hl--); |
||
463 | cpu->MemIf->wm(cpu->de--, tempbyte); |
||
464 | tempbyte += cpu->a; tempbyte = (tempbyte & F3) + ((tempbyte << 4) & F5); |
||
465 | cpu->f = (cpu->f & ~(NF|HF|PV|F3|F5)) + tempbyte; |
||
466 | if (--cpu->bc16) cpu->f |= PV; |
||
467 | } |
||
784 | DimkaM | 468 | static Z80OPCODE ope_A9(Z80 *cpu) { // cpd |
716 | lvd | 469 | cpu->t += 8; |
470 | unsigned char cf = cpu->f & CF; |
||
471 | unsigned char tempbyte = cpu->MemIf->rm(cpu->hl--); |
||
472 | cpu->f = cpf8b[cpu->a*0x100 + tempbyte] + cf; |
||
473 | if (--cpu->bc16) cpu->f |= PV; |
||
474 | cpu->memptr--; |
||
475 | } |
||
784 | DimkaM | 476 | static Z80OPCODE ope_AA(Z80 *cpu) { // ind | M:4 T:16 (4, 5, 3, 4) |
716 | lvd | 477 | cpu->memptr = cpu->bc-1; |
478 | cpu->t += 8; |
||
479 | u8 tmp = cpu->in(cpu->bc); |
||
480 | cpu->MemIf->wm(cpu->hl--, tmp); |
||
481 | cpu->b--; |
||
482 | u8 ftmp = tmp + cpu->c - 1; |
||
483 | cpu->f = log_f[cpu->b] & ~PV; |
||
484 | cpu->f |= (log_f[(ftmp & 7) ^ cpu->b] & PV); |
||
485 | if(ftmp < tmp) cpu->f |= (HF | CF); |
||
486 | cpu->f |= (tmp & 0x80) >> 6; // NF |
||
487 | } |
||
784 | DimkaM | 488 | static Z80OPCODE ope_AB(Z80 *cpu) { // outd | M:4 T:16 (4, 5, 3, 4) |
716 | lvd | 489 | cpu->t += 8; |
490 | cpu->b--; |
||
491 | |||
492 | u8 tmp = cpu->MemIf->rm(cpu->hl--); |
||
493 | cpu->out(cpu->bc, tmp); |
||
494 | |||
495 | u8 ftmp = tmp + cpu->l; |
||
496 | cpu->f = log_f[cpu->b] & ~PV; |
||
497 | cpu->f |= (log_f[(ftmp & 7) ^ cpu->b] & PV); |
||
498 | if(ftmp < tmp) cpu->f |= (HF | CF); |
||
499 | cpu->f |= (tmp & 0x80) >> 6; // NF |
||
500 | |||
501 | cpu->memptr = cpu->bc-1; |
||
502 | } |
||
784 | DimkaM | 503 | static Z80OPCODE ope_B0(Z80 *cpu) { // ldir | BC!=0 M:5 T:21 (4, 4, 3, 5, 5) | BC==0 M:4 T:16 (4, 4, 3, 5) |
504 | cpu->t += 8; |
||
505 | unsigned char tempbyte = cpu->MemIf->rm(cpu->hl++); |
||
506 | cpu->MemIf->wm(cpu->de++, tempbyte); |
||
507 | tempbyte += cpu->a; tempbyte = (tempbyte & F3) + ((tempbyte << 4) & F5); |
||
508 | cpu->f = (cpu->f & ~(NF | HF | PV | F3 | F5)) + tempbyte; |
||
509 | if(--cpu->bc16) |
||
510 | { |
||
511 | cpu->f |= PV; |
||
512 | cpu->pc -= 2; |
||
513 | cpu->t += 5; |
||
514 | cpu->memptr = cpu->pc + 1; |
||
515 | } |
||
716 | lvd | 516 | } |
784 | DimkaM | 517 | static Z80OPCODE ope_B1(Z80 *cpu) { // cpir |
518 | cpu->memptr++; |
||
519 | cpu->t += 8; |
||
520 | unsigned char cf = cpu->f & CF; |
||
521 | unsigned char tempbyte = cpu->MemIf->rm(cpu->hl++); |
||
522 | cpu->f = cpf8b[cpu->a * 0x100 + tempbyte] + cf; |
||
523 | if(--cpu->bc16) |
||
524 | { |
||
525 | cpu->f |= PV; |
||
526 | if(!(cpu->f & ZF)) |
||
527 | { |
||
528 | cpu->pc -= 2; |
||
529 | cpu->t += 5; |
||
530 | cpu->memptr = cpu->pc + 1; |
||
531 | } |
||
532 | } |
||
716 | lvd | 533 | } |
784 | DimkaM | 534 | static Z80OPCODE ope_B2(Z80 *cpu) { // inir | BC!=0 M:5 T:21 (4, 5, 3, 4, 5) | BC==0 M:4 T:16 (4, 5, 3, 4) |
535 | cpu->t += 8; |
||
536 | cpu->memptr = cpu->bc + 1; |
||
537 | cpu->MemIf->wm(cpu->hl++, cpu->in(cpu->bc)); |
||
538 | dec8(cpu, cpu->b); |
||
539 | if(cpu->b) |
||
540 | { |
||
541 | cpu->f |= PV; |
||
542 | cpu->pc -= 2; |
||
543 | cpu->t += 5; |
||
544 | } |
||
545 | else cpu->f &= ~PV; |
||
716 | lvd | 546 | } |
784 | DimkaM | 547 | static Z80OPCODE ope_B3(Z80 *cpu) { // otir | B!=0 M:5 T:21 (4, 5, 3, 4, 5) | B==0 M:4 T:16 (4, 5, 3, 4) |
548 | cpu->t += 8; |
||
549 | dec8(cpu, cpu->b); |
||
550 | cpu->out(cpu->bc, cpu->MemIf->rm(cpu->hl++)); |
||
551 | if(cpu->b) |
||
552 | { |
||
553 | cpu->f |= PV; |
||
554 | cpu->pc -= 2; |
||
555 | cpu->t += 5; |
||
556 | } |
||
557 | else cpu->f &= ~PV; |
||
558 | cpu->f &= ~CF; if(!cpu->l) cpu->f |= CF; |
||
559 | cpu->memptr = cpu->bc + 1; |
||
716 | lvd | 560 | } |
784 | DimkaM | 561 | static Z80OPCODE ope_B8(Z80 *cpu) { // lddr | BC!=0 M:5 T:21 (4, 4, 3, 5, 5) | BC==0 M:4 T:16 (4, 4, 3, 5) |
562 | cpu->t += 8; |
||
563 | unsigned char tempbyte = cpu->MemIf->rm(cpu->hl--); |
||
564 | cpu->MemIf->wm(cpu->de--, tempbyte); |
||
565 | tempbyte += cpu->a; tempbyte = (tempbyte & F3) | ((tempbyte << 4) & F5); |
||
566 | cpu->f = (cpu->f & ~(NF | HF | PV | F3 | F5)) | tempbyte; |
||
567 | if(--cpu->bc16) |
||
568 | { |
||
569 | cpu->f |= PV; |
||
570 | cpu->pc -= 2; |
||
571 | cpu->t += 5; |
||
572 | cpu->memptr = cpu->pc + 1; |
||
573 | } |
||
716 | lvd | 574 | } |
784 | DimkaM | 575 | static Z80OPCODE ope_B9(Z80 *cpu) { // cpdr |
576 | cpu->memptr--; |
||
577 | cpu->t += 8; |
||
578 | unsigned char cf = cpu->f & CF; |
||
579 | unsigned char tempbyte = cpu->MemIf->rm(cpu->hl--); |
||
580 | cpu->f = cpf8b[cpu->a * 0x100 + tempbyte] + cf; |
||
581 | if(--cpu->bc16) |
||
582 | { |
||
583 | cpu->f |= PV; |
||
584 | if(!(cpu->f & ZF)) |
||
585 | { |
||
586 | cpu->pc -= 2; |
||
587 | cpu->t += 5; |
||
588 | cpu->memptr = cpu->pc + 1; |
||
589 | } |
||
590 | } |
||
716 | lvd | 591 | } |
784 | DimkaM | 592 | static Z80OPCODE ope_BA(Z80 *cpu) { // indr | BC!=0 M:5 T:21 (4, 5, 3, 4, 5) | BC==0 M:4 T:16 (4, 5, 3, 4) |
593 | cpu->t += 8; |
||
594 | cpu->memptr = cpu->bc - 1; |
||
595 | cpu->MemIf->wm(cpu->hl--, cpu->in(cpu->bc)); |
||
596 | dec8(cpu, cpu->b); |
||
597 | if(cpu->b) |
||
598 | { |
||
599 | cpu->f |= PV; |
||
600 | cpu->pc -= 2; |
||
601 | cpu->t += 5; |
||
602 | } |
||
603 | else cpu->f &= ~PV; |
||
716 | lvd | 604 | } |
784 | DimkaM | 605 | static Z80OPCODE ope_BB(Z80 *cpu) { // otdr | B!=0 M:5 T:21 (4, 5, 3, 4, 5) | B==0 M:4 T:16 (4, 5, 3, 4) |
716 | lvd | 606 | cpu->t += 8; |
607 | dec8(cpu, cpu->b); |
||
608 | cpu->out(cpu->bc, cpu->MemIf->rm(cpu->hl--)); |
||
784 | DimkaM | 609 | if(cpu->b) |
610 | { |
||
611 | cpu->f |= PV; |
||
612 | cpu->pc -= 2; |
||
613 | cpu->t += 5; |
||
614 | } |
||
716 | lvd | 615 | else cpu->f &= ~PV; |
616 | cpu->f &= ~CF; if (cpu->l == 0xFF) cpu->f |= CF; |
||
617 | cpu->memptr = cpu->bc-1; |
||
618 | } |
||
619 | |||
620 | |||
621 | STEPFUNC const ext_opcode[0x100] = { |
||
622 | |||
623 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
624 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
625 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
626 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
627 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
628 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
629 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
630 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
631 | |||
632 | ope_40, ope_41, ope_42, ope_43, ope_44, ope_45, ope_46, ope_47, |
||
633 | ope_48, ope_49, ope_4A, ope_4B, ope_4C, ope_4D, ope_4E, ope_4F, |
||
634 | ope_50, ope_51, ope_52, ope_53, ope_54, ope_55, ope_56, ope_57, |
||
635 | ope_58, ope_59, ope_5A, ope_5B, ope_5C, ope_5D, ope_5E, ope_5F, |
||
636 | ope_60, ope_61, ope_62, ope_63, ope_64, ope_65, ope_66, ope_67, |
||
637 | ope_68, ope_69, ope_6A, ope_6B, ope_6C, ope_6D, ope_6E, ope_6F, |
||
638 | ope_70, ope_71, ope_72, ope_73, ope_74, ope_75, ope_76, ope_77, |
||
639 | ope_78, ope_79, ope_7A, ope_7B, ope_7C, ope_7D, ope_7E, ope_7F, |
||
640 | |||
641 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
642 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
643 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
644 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
645 | ope_A0, ope_A1, ope_A2, ope_A3, op_00, op_00, op_00, op_00, |
||
646 | ope_A8, ope_A9, ope_AA, ope_AB, op_00, op_00, op_00, op_00, |
||
647 | ope_B0, ope_B1, ope_B2, ope_B3, op_00, op_00, op_00, op_00, |
||
648 | ope_B8, ope_B9, ope_BA, ope_BB, op_00, op_00, op_00, op_00, |
||
649 | |||
650 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
651 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
652 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
653 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
654 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
655 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
656 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
657 | op_00, op_00, op_00, op_00, op_00, op_00, op_00, op_00, |
||
658 | |||
659 | }; |
||
660 | |||
661 | Z80OPCODE op_ED(Z80 *cpu) |
||
662 | { |
||
663 | unsigned char opcode = cpu->m1_cycle(); |
||
664 | (ext_opcode[opcode])(cpu); |
||
665 | } |
||
666 | //#endif |