11 #define ALWAYS_INLINE __attribute__((always_inline))
14 #define CPU_Z80_NMI_ADDR 0x66
15 #define CPU_Z80_RESET_ADDR 0
16 #define CPU_Z80_IRQ_ADDR 0x38
19 #define CPU_Z80_REG_F_BIT_C 0
20 #define CPU_Z80_REG_F_BIT_N 1
21 #define CPU_Z80_REG_F_BIT_PV 2
22 #define CPU_Z80_REG_F_BIT_H 4
23 #define CPU_Z80_REG_F_BIT_Z 6
24 #define CPU_Z80_REG_F_BIT_S 7
26 // special memory locations (negative address)
27 // note: CPU_Z80_EA_SINK is a byte-wide sink for implementing the "in f,(c)"
28 // and DDCB/FDCB undocumented instructions, to store into and never read back
29 #define CPU_Z80_EA_PC (-0x1e)
30 #define CPU_Z80_EA_AF (-0x1c)
31 #define CPU_Z80_EA_BC (-0x1a)
32 #define CPU_Z80_EA_DE (-0x18)
33 #define CPU_Z80_EA_HL (-0x16)
34 #define CPU_Z80_EA_SP (-0x14)
35 #define CPU_Z80_EA_IX (-0x12)
36 #define CPU_Z80_EA_IY (-0x10)
37 #define CPU_Z80_EA_AF_PRIME (-0xe)
38 #define CPU_Z80_EA_BC_PRIME (-0xc)
39 #define CPU_Z80_EA_DE_PRIME (-0xa)
40 #define CPU_Z80_EA_HL_PRIME (-8)
41 #define CPU_Z80_EA_IFLAGS (-6)
42 #define CPU_Z80_EA_IV (-4)
45 #define CPU_Z80_EA_F (-0x1c)
46 #define CPU_Z80_EA_A (-0x1b)
47 #define CPU_Z80_EA_C (-0x1a)
48 #define CPU_Z80_EA_B (-0x19)
49 #define CPU_Z80_EA_E (-0x18)
50 #define CPU_Z80_EA_D (-0x17)
51 #define CPU_Z80_EA_L (-0x16)
52 #define CPU_Z80_EA_H (-0x15)
54 #define CPU_Z80_EA_IXL (-0x12)
55 #define CPU_Z80_EA_IXH (-0x11)
56 #define CPU_Z80_EA_IYL (-0x10)
57 #define CPU_Z80_EA_IYH (-0xf)
63 #define CPU_Z80_EA_V (-4)
64 #define CPU_Z80_EA_I (-3)
65 #define CPU_Z80_EA_R (-2)
66 #define CPU_Z80_EA_SINK (-1)
68 // registers, in same order as special memory locations, but reversed on
69 // big endian hardware where special memory address will be complemented
70 // (this allows special memory to always look like it is little endian)
72 #if __BYTE_ORDER == __BIG_ENDIAN
77 uint16_t _fill_iflags : 7;
78 uint16_t reti_flag : 1;
80 uint16_t halt_flag : 1;
81 uint16_t nmi_pending : 1;
82 uint16_t irq_pending : 1;
86 uint16_t _fill_hl_prime;
87 uint16_t _fill_de_prime;
88 uint16_t _fill_bc_prime;
89 uint16_t _fill_af_prime;
112 uint16_t _fill_iflags;
113 uint16_t _fill_hl_prime;
114 uint16_t _fill_de_prime;
115 uint16_t _fill_bc_prime;
116 uint16_t _fill_af_prime;
152 uint8_t mem_be[0x1e];
171 uint16_t _fill_af_prime;
172 uint16_t _fill_bc_prime;
173 uint16_t _fill_de_prime;
174 uint16_t _fill_hl_prime;
178 uint16_t irq_pending : 1;
179 uint16_t nmi_pending : 1;
180 uint16_t halt_flag : 1;
181 uint16_t ei_flag : 1;
182 uint16_t reti_flag : 1;
183 uint16_t _fill_iflags : 7;
203 uint16_t _fill_af_prime;
204 uint16_t _fill_bc_prime;
205 uint16_t _fill_de_prime;
206 uint16_t _fill_hl_prime;
207 uint16_t _fill_iflags;
231 uint8_t mem_le[0x1e];
237 int (*read_byte)(void *context, int addr);
238 void *read_byte_context;
239 void (*write_byte)(void *context, int addr, int data);
240 void *write_byte_context;
241 int (*in_byte)(void *context, int addr);
242 void *in_byte_context;
243 void (*out_byte)(void *context, int addr, int data);
244 void *out_byte_context;
245 union cpu_z80_regs regs;
248 // memory or special memory access
249 static ALWAYS_INLINE int cpu_z80_read_byte(struct cpu_z80 *self, int addr) {
251 #if __BYTE_ORDER == __BIG_ENDIAN
252 return self->regs.mem_be[~addr];
254 return self->regs.mem_le[sizeof(union cpu_z80_regs) + addr];
257 return self->read_byte(self->read_byte_context, addr & 0xffff);
260 static ALWAYS_INLINE int cpu_z80_read_word(struct cpu_z80 *self, int addr) {
261 int data = cpu_z80_read_byte(self, addr);
262 return data | (cpu_z80_read_byte(self, addr + 1) << 8);
265 static ALWAYS_INLINE void cpu_z80_write_byte(struct cpu_z80 *self, int addr, int data) {
268 #if __BYTE_ORDER == __BIG_ENDIAN
269 self->regs.mem_be[~addr] = data;
271 self->regs.mem_le[sizeof(union cpu_z80_regs) + addr] = data;
274 self->write_byte(self->write_byte_context, addr, data);
277 static ALWAYS_INLINE void cpu_z80_write_word(struct cpu_z80 *self, int addr, int data) {
278 cpu_z80_write_byte(self, addr, data & 0xff);
279 cpu_z80_write_byte(self, addr + 1, data >> 8);
282 static ALWAYS_INLINE int cpu_z80_fetch_byte(struct cpu_z80 *self) {
283 int data = cpu_z80_read_byte(self, self->regs.word.pc++);
287 static ALWAYS_INLINE int cpu_z80_fetch_word(struct cpu_z80 *self) {
288 int data = cpu_z80_fetch_byte(self);
289 return data | (cpu_z80_fetch_byte(self) << 8);
292 static ALWAYS_INLINE void cpu_z80_push_word(struct cpu_z80 *self, int data) {
293 self->regs.word.sp -= 2;
294 cpu_z80_write_word(self, self->regs.word.sp, data);
297 static ALWAYS_INLINE int cpu_z80_pop_word(struct cpu_z80 *self) {
298 int data = cpu_z80_read_word(self, self->regs.word.sp);
299 self->regs.word.sp += 2;
303 static ALWAYS_INLINE int cpu_z80_in_byte(struct cpu_z80 *self, int addr) {
305 return self->in_byte(self->in_byte_context, addr);
308 static ALWAYS_INLINE void cpu_z80_out_byte(struct cpu_z80 *self, int addr, int data) {
310 self->out_byte(self->out_byte_context, addr, data);
313 // effective address calculation
314 static ALWAYS_INLINE int cpu_z80_relative(struct cpu_z80 *self) {
315 return (int8_t)cpu_z80_fetch_byte(self);
318 static ALWAYS_INLINE int cpu_z80_displacement(struct cpu_z80 *self, int base) {
319 return (base + (int8_t)cpu_z80_fetch_byte(self)) & 0xffff;
322 // byte-addressed ports are extended to word using a as high 8 bits
323 static ALWAYS_INLINE int cpu_z80_port_word(struct cpu_z80 *self) {
324 return cpu_z80_fetch_byte(self) | (self->regs.byte.a << 8);
327 // instruction execute
328 static ALWAYS_INLINE void cpu_z80_adc_byte(struct cpu_z80 *self, int lvalue, int rvalue) {
329 int data = cpu_z80_read_byte(self, lvalue);
331 int result0 = (data & 0xf) + (rvalue & 0xf) + self->regs.bit.cf;
332 int result1 = result0 + (data & 0x70) + (rvalue & 0x70);
333 int result2 = result1 + (data & 0x80) + (rvalue & 0x80);
335 cpu_z80_write_byte(self, lvalue, result2 & 0xff);
336 self->regs.bit.cf = result2 >> 8;
337 self->regs.bit.nf = false;
338 self->regs.bit.pvf = ((result1 >> 7) ^ (result2 >> 8)) & 1;
339 self->regs.bit.hf = result0 >> 4;
340 self->regs.bit.zf = (result2 & 0xff) == 0;
341 self->regs.bit.sf = (result2 >> 7) & 1;
344 static ALWAYS_INLINE void cpu_z80_adc_word(struct cpu_z80 *self, int lvalue, int rvalue) {
345 int data = cpu_z80_read_word(self, lvalue);
347 int result0 = (data & 0xfff) + (rvalue & 0xfff) + self->regs.bit.cf;
348 int result1 = result0 + (data & 0x7000) + (rvalue & 0x7000);
349 int result2 = result1 + (data & 0x8000) + (rvalue & 0x8000);
351 cpu_z80_write_word(self, lvalue, result2 & 0xffff);
352 self->regs.bit.cf = result2 >> 16;
353 self->regs.bit.nf = false;
354 self->regs.bit.pvf = ((result1 >> 15) ^ (result2 >> 16)) & 1;
355 self->regs.bit.hf = result0 >> 12;
356 self->regs.bit.zf = (result2 & 0xffff) == 0;
357 self->regs.bit.sf = (result2 >> 15) & 1;
360 static ALWAYS_INLINE void cpu_z80_add_byte(struct cpu_z80 *self, int lvalue, int rvalue) {
361 int data = cpu_z80_read_byte(self, lvalue);
363 int result0 = (data & 0xf) + (rvalue & 0xf);
364 int result1 = result0 + (data & 0x70) + (rvalue & 0x70);
365 int result2 = result1 + (data & 0x80) + (rvalue & 0x80);
367 cpu_z80_write_byte(self, lvalue, result2 & 0xff);
368 self->regs.bit.cf = result2 >> 8;
369 self->regs.bit.nf = false;
370 self->regs.bit.pvf = ((result1 >> 7) ^ (result2 >> 8)) & 1;
371 self->regs.bit.hf = result0 >> 4;
372 self->regs.bit.zf = (result2 & 0xff) == 0;
373 self->regs.bit.sf = (result2 >> 7) & 1;
376 static ALWAYS_INLINE void cpu_z80_add_word(struct cpu_z80 *self, int lvalue, int rvalue) {
377 int data = cpu_z80_read_word(self, lvalue);
379 int result0 = (data & 0xfff) + (rvalue & 0xfff);
380 int result1 = result0 + (data & 0xf000) + (rvalue & 0xf000);
382 cpu_z80_write_word(self, lvalue, result1 & 0xffff);
383 self->regs.bit.cf = result1 >> 16;
384 self->regs.bit.nf = false;
385 self->regs.bit.hf = result0 >> 12;
388 static ALWAYS_INLINE void cpu_z80_and(struct cpu_z80 *self, int rvalue) {
389 int result = self->regs.byte.a & rvalue;
392 parity ^= parity >> 4;
393 parity ^= parity >> 2;
394 parity ^= parity >> 1;
396 self->regs.byte.a = result;
397 self->regs.bit.cf = false;
398 self->regs.bit.nf = false;
399 self->regs.bit.pvf = (parity & 1) == 0;
400 self->regs.bit.hf = true;
401 self->regs.bit.zf = result == 0;
402 self->regs.bit.sf = result >> 7;
405 static ALWAYS_INLINE void cpu_z80_bit(struct cpu_z80 *self, int n, int rvalue) {
406 int result = rvalue & (1 << n);
408 self->regs.bit.nf = false;
409 self->regs.bit.pvf = result == 0;
410 self->regs.bit.hf = true;
411 self->regs.bit.zf = result == 0;
412 self->regs.bit.sf = result >> 7;
415 static ALWAYS_INLINE void cpu_z80_call(struct cpu_z80 *self, bool pred, int rvalue) {
417 cpu_z80_push_word(self, self->regs.word.pc);
418 self->regs.word.pc = rvalue;
422 static ALWAYS_INLINE void cpu_z80_ccf(struct cpu_z80 *self) {
423 self->regs.bit.hf = self->regs.bit.cf;
424 self->regs.bit.cf = !self->regs.bit.cf;
425 self->regs.bit.nf = false;
428 static ALWAYS_INLINE void cpu_z80_cp(struct cpu_z80 *self, int rvalue) {
429 int result0 = (self->regs.byte.a & 0xf) - (rvalue & 0xf);
430 int result1 = result0 + (self->regs.byte.a & 0x70) - (rvalue & 0x70);
431 int result2 = result1 + (self->regs.byte.a & 0x80) - (rvalue & 0x80);
433 self->regs.bit.cf = (result2 >> 8) & 1;
434 self->regs.bit.nf = true;
435 self->regs.bit.pvf = ((result1 >> 7) ^ (result2 >> 8)) & 1;
436 self->regs.bit.hf = (result0 >> 4) & 1;
437 self->regs.bit.zf = (result2 & 0xff) == 0;
438 self->regs.bit.sf = (result2 >> 7) & 1;
441 static ALWAYS_INLINE void cpu_z80_cpd(struct cpu_z80 *self) {
442 int data = cpu_z80_read_byte(self, self->regs.word.hl--);
443 --self->regs.word.bc;
445 int result0 = (self->regs.byte.a & 0xf) - (data & 0xf);
446 int result1 = result0 + (self->regs.byte.a & 0xf0) - (data & 0xf0);
448 self->regs.bit.nf = true;
449 self->regs.bit.pvf = self->regs.word.bc != 0;
450 self->regs.bit.hf = (result0 >> 4) & 1;
451 self->regs.bit.zf = (result1 & 0xff) == 0;
452 self->regs.bit.sf = (result1 >> 7) & 1;
455 static ALWAYS_INLINE void cpu_z80_cpdr(struct cpu_z80 *self) {
457 if (!self->regs.bit.zf && self->regs.word.bc)
458 self->regs.word.pc -= 2;
461 static ALWAYS_INLINE void cpu_z80_cpi(struct cpu_z80 *self) {
462 int data = cpu_z80_read_byte(self, self->regs.word.hl++);
463 --self->regs.word.bc;
465 int result0 = (self->regs.byte.a & 0xf) - (data & 0xf);
466 int result1 = result0 + (self->regs.byte.a & 0xf0) - (data & 0xf0);
468 self->regs.bit.nf = true;
469 self->regs.bit.pvf = self->regs.word.bc != 0;
470 self->regs.bit.hf = (result0 >> 4) & 1;
471 self->regs.bit.zf = (result1 & 0xff) == 0;
472 self->regs.bit.sf = (result1 >> 7) & 1;
475 static ALWAYS_INLINE void cpu_z80_cpir(struct cpu_z80 *self) {
477 if (!self->regs.bit.zf && self->regs.word.bc)
478 self->regs.word.pc -= 2;
481 static ALWAYS_INLINE void cpu_z80_cpl(struct cpu_z80 *self) {
482 self->regs.byte.a = ~self->regs.byte.a;
483 self->regs.bit.nf = true;
484 self->regs.bit.hf = true;
487 // see https://github.com/kosarev/z80.git (MIT licensed)
488 // void do_i8080_daa() {
489 // fast_u8 a = self().on_get_a();
490 // flag_set flags = get_flags();
491 // fast_u8 f = flags.get_hf_cf();
494 // fast_u8 t = r + 6;
495 // fast_u8 hfv = a ^ t;
496 // if((hfv | f) & hf_mask)
499 // fast_u16 t2 = r + 0x60;
500 // fast_u16 w = ((t2 >> 8) | f) << 8;
504 // self().on_set_a(r);
505 // flags.set(hfv & hf_mask, (w | r) & 0x1ff);
506 // set_flags(flags); }
507 // void do_z80_daa() {
508 // fast_u8 a = self().on_get_a();
509 // fast_u8 f = self().on_get_f();
510 // bool cf = f & cf_mask;
511 // bool hf = f & hf_mask;
512 // bool nf = f & nf_mask;
515 // if(cf || a >= 0x9a) {
519 // if(hf || (a & 0x0f) >= 0x0a) {
524 // f = (f & cf_mask) | ((a & 0x0f) >= 0x0a ? hf_mask : 0);
527 // f = (f & cf_mask) | (hf && (a & 0x0f) <= 0x05 ? hf_mask : 0) |
531 // f |= (a & (sf_mask | xf_mask | yf_mask)) | pf_log(a) | zf_ari(a);
533 // self().on_set_a(a);
534 // self().on_set_f(f); }
535 static ALWAYS_INLINE void cpu_z80_daa(struct cpu_z80 *self) {
537 if (self->regs.bit.hf || (self->regs.byte.a & 0xf) >= 0xa)
539 if (self->regs.bit.cf || self->regs.byte.a >= 0x9a) {
541 self->regs.bit.cf = true;
544 int result0, result1;
545 if (self->regs.bit.nf) {
546 result0 = (self->regs.byte.a & 0xf) - (correction & 0xf);
547 result1 = result0 + (self->regs.byte.a & 0xf0) - (correction & 0xf0);
550 result0 = (self->regs.byte.a & 0xf) + (correction & 0xf);
551 result1 = result0 + (self->regs.byte.a & 0xf0) + (correction & 0xf0);
554 int parity = result1;
555 parity ^= parity >> 4;
556 parity ^= parity >> 2;
557 parity ^= parity >> 1;
559 self->regs.byte.a = result1 & 0xff;
560 //self->regs.bit.cf |= (result1 >> 8) & 1;
561 self->regs.bit.pvf = (parity & 1) == 0;
562 self->regs.bit.hf = (result0 >> 4) & 1;
563 self->regs.bit.zf = (result1 & 0xff) == 0;
564 self->regs.bit.sf = (result1 >> 7) & 1;
567 static ALWAYS_INLINE void cpu_z80_dec_byte(struct cpu_z80 *self, int lvalue) {
568 int data = cpu_z80_read_byte(self, lvalue);
570 int result0 = (data & 0xf) - 1;
571 int result1 = result0 + (data & 0x70);
572 int result2 = result1 + (data & 0x80);
574 cpu_z80_write_byte(self, lvalue, result2 & 0xff);
575 self->regs.bit.nf = true;
576 self->regs.bit.pvf = ((result1 >> 7) ^ (result2 >> 8)) & 1;
577 self->regs.bit.hf = (result0 >> 4) & 1;
578 self->regs.bit.zf = (result2 & 0xff) == 0;
579 self->regs.bit.sf = (result2 >> 7) & 1;
582 static ALWAYS_INLINE void cpu_z80_dec_word(struct cpu_z80 *self, int lvalue) {
583 int result = (cpu_z80_read_word(self, lvalue) - 1) & 0xffff;
584 cpu_z80_write_word(self, lvalue, result);
587 static ALWAYS_INLINE void cpu_z80_di(struct cpu_z80 *self) {
588 self->regs.bit.iff1 = false;
589 self->regs.bit.iff2 = false;
592 static ALWAYS_INLINE void cpu_z80_djnz(struct cpu_z80 *self, int rvalue) {
593 if (--self->regs.byte.b)
594 self->regs.word.pc += rvalue;
597 static ALWAYS_INLINE void cpu_z80_ei(struct cpu_z80 *self) {
598 self->regs.bit.iff1 = true;
599 self->regs.bit.iff2 = true;
600 self->regs.bit.ei_flag = true; // causes one-cycle interrupt delay
603 static ALWAYS_INLINE void cpu_z80_ex(struct cpu_z80 *self, int lvalue0, int lvalue1) {
604 int data0 = cpu_z80_read_word(self, lvalue0);
605 int data1 = cpu_z80_read_word(self, lvalue1);
606 cpu_z80_write_word(self, lvalue0, data1);
607 cpu_z80_write_word(self, lvalue1, data0);
610 static ALWAYS_INLINE void cpu_z80_halt(struct cpu_z80 *self) {
611 self->regs.bit.halt_flag = true;
612 --self->regs.word.pc;
615 static ALWAYS_INLINE void cpu_z80_ill(struct cpu_z80 *self) {
619 static ALWAYS_INLINE void cpu_z80_im(struct cpu_z80 *self, int n) {
620 self->regs.bit.im = n;
623 static ALWAYS_INLINE void cpu_z80_in(struct cpu_z80 *self, int lvalue, int rvalue) {
624 cpu_z80_write_byte(self, lvalue, rvalue);
627 static ALWAYS_INLINE void cpu_z80_in_z80(struct cpu_z80 *self, int lvalue, int rvalue) {
629 parity ^= parity >> 4;
630 parity ^= parity >> 2;
631 parity ^= parity >> 1;
633 cpu_z80_write_byte(self, lvalue, rvalue);
634 self->regs.bit.nf = false;
635 self->regs.bit.pvf = (parity & 1) == 0;
636 self->regs.bit.hf = false;
637 self->regs.bit.zf = rvalue == 0;
638 self->regs.bit.sf = rvalue >> 7;
641 static ALWAYS_INLINE void cpu_z80_inc_byte(struct cpu_z80 *self, int lvalue) {
642 int data = cpu_z80_read_byte(self, lvalue);
644 int result0 = (data & 0xf) + 1;
645 int result1 = result0 + (data & 0x70);
646 int result2 = result1 + (data & 0x80);
648 cpu_z80_write_byte(self, lvalue, result2 & 0xff);
649 self->regs.bit.nf = false;
650 self->regs.bit.pvf = ((result1 >> 7) ^ (result2 >> 8)) & 1;
651 self->regs.bit.hf = result0 >> 4;
652 self->regs.bit.zf = (result2 & 0xff) == 0;
653 self->regs.bit.sf = (result2 >> 7) & 1;
656 static ALWAYS_INLINE void cpu_z80_inc_word(struct cpu_z80 *self, int lvalue) {
657 int result = (cpu_z80_read_word(self, lvalue) + 1) & 0xffff;
658 cpu_z80_write_word(self, lvalue, result);
661 static ALWAYS_INLINE void cpu_z80_ind(struct cpu_z80 *self) {
664 self->regs.word.hl--,
665 cpu_z80_in_byte(self, self->regs.word.bc)
669 self->regs.bit.nf = true;
670 self->regs.bit.zf = self->regs.byte.b != 0;
673 static ALWAYS_INLINE void cpu_z80_indr(struct cpu_z80 *self) {
675 if (self->regs.byte.b)
676 self->regs.word.pc -= 2;
679 static ALWAYS_INLINE void cpu_z80_ini(struct cpu_z80 *self) {
682 self->regs.word.hl++,
683 cpu_z80_in_byte(self, self->regs.word.bc)
687 self->regs.bit.nf = true;
688 self->regs.bit.zf = self->regs.byte.b != 0;
691 static ALWAYS_INLINE void cpu_z80_inir(struct cpu_z80 *self) {
693 if (self->regs.byte.b)
694 self->regs.word.pc -= 2;
697 static ALWAYS_INLINE void cpu_z80_jp(struct cpu_z80 *self, bool pred, int rvalue) {
699 self->regs.word.pc = rvalue;
702 static ALWAYS_INLINE void cpu_z80_jr(struct cpu_z80 *self, bool pred, int rvalue) {
704 self->regs.word.pc += rvalue;
707 static ALWAYS_INLINE void cpu_z80_ld_byte(struct cpu_z80 *self, int lvalue, int rvalue) {
708 cpu_z80_write_byte(self, lvalue, rvalue);
711 static ALWAYS_INLINE void cpu_z80_ld_word(struct cpu_z80 *self, int lvalue, int rvalue) {
712 cpu_z80_write_word(self, lvalue, rvalue);
715 static ALWAYS_INLINE void cpu_z80_ldd(struct cpu_z80 *self) {
718 self->regs.word.de++,
719 cpu_z80_read_byte(self, self->regs.word.hl--)
721 --self->regs.word.bc;
723 self->regs.bit.nf = false;
724 self->regs.bit.pvf = self->regs.word.bc != 0;
725 self->regs.bit.hf = false;
728 static ALWAYS_INLINE void cpu_z80_lddr(struct cpu_z80 *self) {
730 if (self->regs.word.bc)
731 self->regs.word.pc -= 2;
734 static ALWAYS_INLINE void cpu_z80_ldi(struct cpu_z80 *self) {
737 self->regs.word.de++,
738 cpu_z80_read_byte(self, self->regs.word.hl++)
740 --self->regs.word.bc;
742 self->regs.bit.nf = false;
743 self->regs.bit.pvf = self->regs.word.bc != 0;
744 self->regs.bit.hf = false;
747 static ALWAYS_INLINE void cpu_z80_ldir(struct cpu_z80 *self) {
749 if (self->regs.word.bc)
750 self->regs.word.pc -= 2;
753 static ALWAYS_INLINE void cpu_z80_neg(struct cpu_z80 *self) {
754 int result0 = -(self->regs.byte.a & 0xf);
755 int result1 = result0 - (self->regs.byte.a & 0x70);
756 int result2 = result1 - (self->regs.byte.a & 0x80);
758 self->regs.byte.a = result2 & 0xff;
759 self->regs.bit.cf = (result2 >> 8) & 1;
760 self->regs.bit.nf = true;
761 self->regs.bit.pvf = ((result1 >> 7) ^ (result2 >> 8)) & 1;
762 self->regs.bit.hf = (result0 >> 4) & 1;
763 self->regs.bit.zf = (result2 & 0xff) == 0;
764 self->regs.bit.sf = (result2 >> 7) & 1;
767 static ALWAYS_INLINE void cpu_z80_nop(struct cpu_z80 *self) {
770 static ALWAYS_INLINE void cpu_z80_or(struct cpu_z80 *self, int rvalue) {
771 int result = self->regs.byte.a | rvalue;
774 parity ^= parity >> 4;
775 parity ^= parity >> 2;
776 parity ^= parity >> 1;
778 self->regs.byte.a = result;
779 self->regs.bit.cf = false;
780 self->regs.bit.nf = false;
781 self->regs.bit.pvf = (parity & 1) == 0;
782 self->regs.bit.hf = false;
783 self->regs.bit.zf = result == 0;
784 self->regs.bit.sf = result >> 7;
787 static ALWAYS_INLINE void cpu_z80_out(struct cpu_z80 *self, int lvalue, int rvalue) {
788 cpu_z80_out_byte(self, lvalue, rvalue);
791 static ALWAYS_INLINE void cpu_z80_outd(struct cpu_z80 *self) {
796 cpu_z80_read_byte(self, self->regs.word.hl--)
799 self->regs.bit.nf = true;
800 self->regs.bit.zf = self->regs.byte.b != 0;
803 static ALWAYS_INLINE void cpu_z80_otdr(struct cpu_z80 *self) {
805 if (self->regs.byte.b)
806 self->regs.word.pc -= 2;
809 static ALWAYS_INLINE void cpu_z80_outi(struct cpu_z80 *self) {
814 cpu_z80_read_byte(self, self->regs.word.hl++)
817 self->regs.bit.nf = true;
818 self->regs.bit.zf = self->regs.byte.b != 0;
821 static ALWAYS_INLINE void cpu_z80_otir(struct cpu_z80 *self) {
823 if (self->regs.byte.b)
824 self->regs.word.pc -= 2;
827 static ALWAYS_INLINE void cpu_z80_pop(struct cpu_z80 *self, int lvalue) {
828 cpu_z80_write_word(self, lvalue, cpu_z80_pop_word(self));
831 static ALWAYS_INLINE void cpu_z80_push(struct cpu_z80 *self, int rvalue) {
832 cpu_z80_push_word(self, rvalue);
835 static ALWAYS_INLINE void cpu_z80_res(struct cpu_z80 *self, int n, int lvalue0, int lvalue1) {
836 int result = cpu_z80_read_byte(self, lvalue0) & ~(1 << n);
838 cpu_z80_write_byte(self, lvalue0, result);
839 cpu_z80_write_byte(self, lvalue1, result); // for undocumented DDCB/FDCB
842 static ALWAYS_INLINE void cpu_z80_ret(struct cpu_z80 *self, bool pred) {
844 self->regs.word.pc = cpu_z80_pop_word(self);
847 static ALWAYS_INLINE void cpu_z80_reti(struct cpu_z80 *self) {
848 self->regs.bit.reti_flag = true;
849 self->regs.word.pc = cpu_z80_pop_word(self);
852 static ALWAYS_INLINE void cpu_z80_retn(struct cpu_z80 *self) {
853 self->regs.bit.iff1 = self->regs.bit.iff2;
854 self->regs.word.pc = cpu_z80_pop_word(self);
857 static ALWAYS_INLINE void cpu_z80_rl(struct cpu_z80 *self, int lvalue0, int lvalue1) {
858 int data = cpu_z80_read_byte(self, lvalue0);
860 int result = self->regs.bit.cf | (data << 1);
863 parity ^= parity >> 4;
864 parity ^= parity >> 2;
865 parity ^= parity >> 1;
867 data = result & 0xff;
868 cpu_z80_write_byte(self, lvalue0, data);
869 cpu_z80_write_byte(self, lvalue1, data); // for undocumented DDCB/FDCB
871 self->regs.bit.cf = result >> 8;
872 self->regs.bit.nf = false;
873 self->regs.bit.pvf = (parity & 1) == 0;
874 self->regs.bit.hf = false;
875 self->regs.bit.zf = (result & 0xff) == 0;
876 self->regs.bit.sf = (result >> 7) & 1;
879 static ALWAYS_INLINE void cpu_z80_rla(struct cpu_z80 *self) {
880 int result = self->regs.bit.cf | (self->regs.byte.a << 1);
882 self->regs.byte.a = result & 0xff;
883 self->regs.bit.cf = result >> 8;
884 self->regs.bit.nf = false;
885 self->regs.bit.hf = false;
888 static ALWAYS_INLINE void cpu_z80_rlc(struct cpu_z80 *self, int lvalue0, int lvalue1) {
889 int data = cpu_z80_read_byte(self, lvalue0);
891 int result = (data >> 7) | (data << 1);
894 parity ^= parity >> 4;
895 parity ^= parity >> 2;
896 parity ^= parity >> 1;
898 data = result & 0xff;
899 cpu_z80_write_byte(self, lvalue0, data);
900 cpu_z80_write_byte(self, lvalue1, data); // for undocumented DDCB/FDCB
902 self->regs.bit.cf = result >> 8;
903 self->regs.bit.nf = false;
904 self->regs.bit.pvf = (parity & 1) == 0;
905 self->regs.bit.hf = false;
906 self->regs.bit.zf = (result & 0xff) == 0;
907 self->regs.bit.sf = (result >> 7) & 1;
910 static ALWAYS_INLINE void cpu_z80_rlca(struct cpu_z80 *self) {
911 int result = (self->regs.byte.a >> 7) | (self->regs.byte.a << 1);
913 self->regs.byte.a = result & 0xff;
914 self->regs.bit.cf = result >> 8;
915 self->regs.bit.nf = false;
916 self->regs.bit.hf = false;
919 static ALWAYS_INLINE void cpu_z80_rld(struct cpu_z80 *self) {
921 (self->regs.byte.a & 0xf) |
922 (cpu_z80_read_byte(self, self->regs.word.hl) << 4);
924 cpu_z80_write_byte(self, self->regs.word.hl, result & 0xff);
925 result = (result >> 8) | (self->regs.byte.a & 0xf0);
928 parity ^= parity >> 4;
929 parity ^= parity >> 2;
930 parity ^= parity >> 1;
932 self->regs.byte.a = result;
933 self->regs.bit.nf = false;
934 self->regs.bit.pvf = (parity & 1) == 0;
935 self->regs.bit.hf = false;
936 self->regs.bit.zf = result == 0;
937 self->regs.bit.sf = result >> 7;
940 static ALWAYS_INLINE void cpu_z80_rr(struct cpu_z80 *self, int lvalue0, int lvalue1) {
941 int data = cpu_z80_read_byte(self, lvalue0);
943 int result = data | (self->regs.bit.cf << 8);
946 parity ^= parity >> 4;
947 parity ^= parity >> 2;
948 parity ^= parity >> 1;
951 cpu_z80_write_byte(self, lvalue0, data);
952 cpu_z80_write_byte(self, lvalue1, data); // for undocumented DDCB/FDCB
954 self->regs.bit.cf = result & 1;
955 self->regs.bit.nf = false;
956 self->regs.bit.pvf = (parity & 2) == 0;
957 self->regs.bit.hf = false;
958 self->regs.bit.zf = (result & 0x1fe) == 0;
959 self->regs.bit.sf = result >> 8;
962 static ALWAYS_INLINE void cpu_z80_rra(struct cpu_z80 *self) {
963 int result = self->regs.byte.a | (self->regs.bit.cf << 8);
965 self->regs.byte.a = result >> 1;
966 self->regs.bit.cf = result & 1;
967 self->regs.bit.nf = false;
968 self->regs.bit.hf = false;
971 static ALWAYS_INLINE void cpu_z80_rrc(struct cpu_z80 *self, int lvalue0, int lvalue1) {
972 int data = cpu_z80_read_byte(self, lvalue0);
974 int result = data | ((data & 1) << 8);
977 parity ^= parity >> 4;
978 parity ^= parity >> 2;
979 parity ^= parity >> 1;
982 cpu_z80_write_byte(self, lvalue0, data);
983 cpu_z80_write_byte(self, lvalue1, data); // for undocumented DDCB/FDCB
985 self->regs.bit.cf = result & 1;
986 self->regs.bit.nf = false;
987 self->regs.bit.pvf = (parity & 2) == 0;
988 self->regs.bit.hf = false;
989 self->regs.bit.zf = (result & 0x1fe) == 0;
990 self->regs.bit.sf = result >> 8;
993 static ALWAYS_INLINE void cpu_z80_rrca(struct cpu_z80 *self) {
994 int result = self->regs.byte.a | ((self->regs.byte.a & 1) << 8);
996 self->regs.byte.a = result >> 1;
997 self->regs.bit.cf = result & 1;
998 self->regs.bit.nf = false;
999 self->regs.bit.hf = false;
1002 static ALWAYS_INLINE void cpu_z80_rrd(struct cpu_z80 *self) {
1004 cpu_z80_read_byte(self, self->regs.word.hl) |
1005 ((self->regs.byte.a & 0xf) << 8);
1007 cpu_z80_write_byte(self, self->regs.word.hl, result >> 4);
1008 result = (result & 0xf) | (self->regs.byte.a & 0xf0);
1010 int parity = result;
1011 parity ^= parity >> 4;
1012 parity ^= parity >> 2;
1013 parity ^= parity >> 1;
1015 self->regs.byte.a = result;
1016 self->regs.bit.nf = false;
1017 self->regs.bit.pvf = (parity & 1) == 0;
1018 self->regs.bit.hf = false;
1019 self->regs.bit.zf = result == 0;
1020 self->regs.bit.sf = result >> 7;
1023 static ALWAYS_INLINE void cpu_z80_sbc_byte(struct cpu_z80 *self, int lvalue, int rvalue) {
1024 int data = cpu_z80_read_byte(self, lvalue);
1026 int result0 = (data & 0xf) - (rvalue & 0xf) - self->regs.bit.cf;
1027 int result1 = result0 + (data & 0x70) - (rvalue & 0x70);
1028 int result2 = result1 + (data & 0x80) - (rvalue & 0x80);
1030 cpu_z80_write_byte(self, lvalue, result2 & 0xff);
1031 self->regs.bit.cf = (result2 >> 8) & 1;
1032 self->regs.bit.nf = true;
1033 self->regs.bit.pvf = ((result1 >> 7) ^ (result2 >> 8)) & 1;
1034 self->regs.bit.hf = (result0 >> 4) & 1;
1035 self->regs.bit.zf = (result2 & 0xff) == 0;
1036 self->regs.bit.sf = (result2 >> 7) & 1;
1039 static ALWAYS_INLINE void cpu_z80_sbc_word(struct cpu_z80 *self, int lvalue, int rvalue) {
1040 int data = cpu_z80_read_word(self, lvalue);
1042 int result0 = (data & 0xfff) - (rvalue & 0xfff) - self->regs.bit.cf;
1043 int result1 = result0 + (data & 0x7000) - (rvalue & 0x7000);
1044 int result2 = result1 + (data & 0x8000) - (rvalue & 0x8000);
1046 cpu_z80_write_word(self, lvalue, result2 & 0xffff);
1047 self->regs.bit.cf = (result2 >> 16) & 1;
1048 self->regs.bit.nf = true;
1049 self->regs.bit.pvf = ((result1 >> 15) ^ (result2 >> 16)) & 1;
1050 self->regs.bit.hf = (result0 >> 12) & 1;
1051 self->regs.bit.zf = (result2 & 0xffff) == 0;
1052 self->regs.bit.sf = (result2 >> 15) & 1;
1055 static ALWAYS_INLINE void cpu_z80_scf(struct cpu_z80 *self) {
1056 self->regs.bit.cf = true;
1057 self->regs.bit.nf = false;
1058 self->regs.bit.hf = false;
1061 static ALWAYS_INLINE void cpu_z80_set(struct cpu_z80 *self, int n, int lvalue0, int lvalue1) {
1062 int result = cpu_z80_read_byte(self, lvalue0) | (1 << n);
1064 cpu_z80_write_byte(self, lvalue0, result);
1065 cpu_z80_write_byte(self, lvalue1, result); // for undocumented DDCB/FDCB
1068 static ALWAYS_INLINE void cpu_z80_sla(struct cpu_z80 *self, int lvalue0, int lvalue1) {
1069 int data = cpu_z80_read_byte(self, lvalue0);
1071 int result = data << 1;
1073 int parity = result;
1074 parity ^= parity >> 4;
1075 parity ^= parity >> 2;
1076 parity ^= parity >> 1;
1078 data = result & 0xff;
1079 cpu_z80_write_byte(self, lvalue0, data);
1080 cpu_z80_write_byte(self, lvalue1, data); // for undocumented DDCB/FDCB
1082 self->regs.bit.cf = result >> 8;
1083 self->regs.bit.nf = false;
1084 self->regs.bit.pvf = (parity & 1) == 0;
1085 self->regs.bit.hf = false;
1086 self->regs.bit.zf = (result & 0xff) == 0;
1087 self->regs.bit.sf = (result >> 7) & 1;
1090 static ALWAYS_INLINE void cpu_z80_sll(struct cpu_z80 *self, int lvalue0, int lvalue1) {
1091 int data = cpu_z80_read_byte(self, lvalue0);
1093 int result = 1 | (data << 1);
1095 int parity = result;
1096 parity ^= parity >> 4;
1097 parity ^= parity >> 2;
1098 parity ^= parity >> 1;
1100 data = result & 0xff;
1101 cpu_z80_write_byte(self, lvalue0, data);
1102 cpu_z80_write_byte(self, lvalue1, data); // for undocumented DDCB/FDCB
1104 self->regs.bit.cf = result >> 8;
1105 self->regs.bit.nf = false;
1106 self->regs.bit.pvf = (parity & 1) == 0;
1107 self->regs.bit.hf = false;
1108 self->regs.bit.zf = (result & 0xff) == 0;
1109 self->regs.bit.sf = (result >> 7) & 1;
1112 static ALWAYS_INLINE void cpu_z80_sra(struct cpu_z80 *self, int lvalue0, int lvalue1) {
1113 int data = cpu_z80_read_byte(self, lvalue0);
1115 int result = data | ((data << 1) & 0x100); // sign extend
1117 int parity = result;
1118 parity ^= parity >> 4;
1119 parity ^= parity >> 2;
1120 parity ^= parity >> 1;
1123 cpu_z80_write_byte(self, lvalue0, data);
1124 cpu_z80_write_byte(self, lvalue1, data); // for undocumented DDCB/FDCB
1126 self->regs.bit.cf = result & 1;
1127 self->regs.bit.nf = false;
1128 self->regs.bit.pvf = (parity & 2) == 0;
1129 self->regs.bit.hf = false;
1130 self->regs.bit.zf = (result & 0x1fe) == 0;
1131 self->regs.bit.sf = result >> 8;
1134 static ALWAYS_INLINE void cpu_z80_srl(struct cpu_z80 *self, int lvalue0, int lvalue1) {
1135 int data = cpu_z80_read_byte(self, lvalue0);
1139 int parity = result;
1140 parity ^= parity >> 4;
1141 parity ^= parity >> 2;
1142 parity ^= parity >> 1;
1145 cpu_z80_write_byte(self, lvalue0, data);
1146 cpu_z80_write_byte(self, lvalue1, data); // for undocumented DDCB/FDCB
1148 self->regs.bit.cf = result & 1;
1149 self->regs.bit.nf = false;
1150 self->regs.bit.pvf = (parity & 2) == 0;
1151 self->regs.bit.hf = false;
1152 self->regs.bit.zf = (result & 0x1fe) == 0;
1153 self->regs.bit.sf = result >> 8;
1156 static ALWAYS_INLINE void cpu_z80_sub(struct cpu_z80 *self, int rvalue) {
1157 int result0 = (self->regs.byte.a & 0xf) - (rvalue & 0xf);
1158 int result1 = result0 + (self->regs.byte.a & 0x70) - (rvalue & 0x70);
1159 int result2 = result1 + (self->regs.byte.a & 0x80) - (rvalue & 0x80);
1161 self->regs.byte.a = result2 & 0xff;
1162 self->regs.bit.cf = (result2 >> 8) & 1;
1163 self->regs.bit.nf = true;
1164 self->regs.bit.pvf = ((result1 >> 7) ^ (result2 >> 8)) & 1;
1165 self->regs.bit.hf = (result0 >> 4) & 1;
1166 self->regs.bit.zf = (result2 & 0xff) == 0;
1167 self->regs.bit.sf = (result2 >> 7) & 1;
1170 static ALWAYS_INLINE void cpu_z80_xor(struct cpu_z80 *self, int rvalue) {
1171 int result = self->regs.byte.a ^ rvalue;
1173 int parity = result;
1174 parity ^= parity >> 4;
1175 parity ^= parity >> 2;
1176 parity ^= parity >> 1;
1178 self->regs.byte.a = result;
1179 self->regs.bit.cf = false;
1180 self->regs.bit.nf = false;
1181 self->regs.bit.pvf = (parity & 1) == 0;
1182 self->regs.bit.hf = false;
1183 self->regs.bit.zf = result == 0;
1184 self->regs.bit.sf = result >> 7;
1189 struct cpu_z80 *self,
1190 int (*read_byte)(void *context, int addr),
1191 void *read_byte_context,
1192 void (*write_byte)(void *context, int addr, int data),
1193 void *write_byte_context,
1194 int (*in_byte)(void *context, int addr),
1195 void *in_byte_context,
1196 void (*out_byte)(void *context, int addr, int data),
1197 void *out_byte_context
1199 void cpu_z80_reset(struct cpu_z80 *self);
1200 void cpu_z80_execute(struct cpu_z80 *self);
1201 void cpu_z80_execute_cb(struct cpu_z80 *self);
1202 void cpu_z80_execute_dd(struct cpu_z80 *self);
1203 void cpu_z80_execute_dd_cb(struct cpu_z80 *self);
1204 void cpu_z80_execute_ed(struct cpu_z80 *self);
1205 void cpu_z80_execute_fd(struct cpu_z80 *self);
1206 void cpu_z80_execute_fd_cb(struct cpu_z80 *self);