static ALWAYS_INLINE void cpu_z80_cpd(struct cpu_z80 *self) {
int data = cpu_z80_read_byte(self, self->regs.word.hl--);
+ --self->regs.word.bc;
int result0 = (self->regs.byte.a & 0xf) - (data & 0xf);
int result1 = result0 + (self->regs.byte.a & 0xf0) - (data & 0xf0);
- int result2 = (self->regs.word.bc - 1) & 0xffff;
- self->regs.word.bc = result2;
self->regs.bit.nf = true;
- self->regs.bit.pvf = result2 != 0;
+ self->regs.bit.pvf = self->regs.word.bc != 0;
self->regs.bit.hf = (result0 >> 4) & 1;
self->regs.bit.zf = (result1 & 0xff) == 0;
self->regs.bit.sf = (result1 >> 7) & 1;
}
static ALWAYS_INLINE void cpu_z80_cpdr(struct cpu_z80 *self) {
- int data = cpu_z80_read_byte(self, self->regs.word.hl--);
-
- int result0 = (self->regs.byte.a & 0xf) - (data & 0xf);
- int result1 = result0 + (self->regs.byte.a & 0xf0) - (data & 0xf0);
- int result2 = (self->regs.word.bc - 1) & 0xffff;
-
- self->regs.word.bc = result2;
- self->regs.bit.nf = true;
- self->regs.bit.pvf = result2 != 0;
- self->regs.bit.hf = (result0 >> 4) & 1;
- self->regs.bit.zf = (result1 & 0xff) == 0;
- self->regs.bit.sf = (result1 >> 7) & 1;
-
- if ((result1 & 0xff) && result2)
+ cpu_z80_cpd(self);
+ if (!self->regs.bit.zf && self->regs.word.bc)
self->regs.word.pc -= 2;
}
static ALWAYS_INLINE void cpu_z80_cpi(struct cpu_z80 *self) {
int data = cpu_z80_read_byte(self, self->regs.word.hl++);
+ --self->regs.word.bc;
int result0 = (self->regs.byte.a & 0xf) - (data & 0xf);
int result1 = result0 + (self->regs.byte.a & 0xf0) - (data & 0xf0);
- int result2 = (self->regs.word.bc - 1) & 0xffff;
- self->regs.word.bc = result2;
self->regs.bit.nf = true;
- self->regs.bit.pvf = result2 != 0;
+ self->regs.bit.pvf = self->regs.word.bc != 0;
self->regs.bit.hf = (result0 >> 4) & 1;
self->regs.bit.zf = (result1 & 0xff) == 0;
self->regs.bit.sf = (result1 >> 7) & 1;
}
static ALWAYS_INLINE void cpu_z80_cpir(struct cpu_z80 *self) {
- int data = cpu_z80_read_byte(self, self->regs.word.hl++);
-
- int result0 = (self->regs.byte.a & 0xf) - (data & 0xf);
- int result1 = result0 + (self->regs.byte.a & 0xf0) - (data & 0xf0);
- int result2 = (self->regs.word.bc - 1) & 0xffff;
-
- self->regs.word.bc = result2;
- self->regs.bit.nf = true;
- self->regs.bit.pvf = result2 != 0;
- self->regs.bit.hf = (result0 >> 4) & 1;
- self->regs.bit.zf = (result1 & 0xff) == 0;
- self->regs.bit.sf = (result1 >> 7) & 1;
-
- if ((result1 & 0xff) && result2)
+ cpu_z80_cpi(self);
+ if (!self->regs.bit.zf && self->regs.word.bc)
self->regs.word.pc -= 2;
}
}
static ALWAYS_INLINE void cpu_z80_ind(struct cpu_z80 *self) {
- abort();
+ cpu_z80_write_byte(
+ self,
+ self->regs.word.hl--,
+ cpu_z80_in_byte(self, self->regs.word.bc)
+ );
+ --self->regs.byte.b;
+
+ self->regs.bit.nf = true;
+ self->regs.bit.zf = self->regs.byte.b != 0;
}
static ALWAYS_INLINE void cpu_z80_indr(struct cpu_z80 *self) {
- abort();
+ cpu_z80_ind(self);
+ if (self->regs.byte.b)
+ self->regs.word.pc -= 2;
}
static ALWAYS_INLINE void cpu_z80_ini(struct cpu_z80 *self) {
- abort();
+ cpu_z80_write_byte(
+ self,
+ self->regs.word.hl++,
+ cpu_z80_in_byte(self, self->regs.word.bc)
+ );
+ --self->regs.byte.b;
+
+ self->regs.bit.nf = true;
+ self->regs.bit.zf = self->regs.byte.b != 0;
}
static ALWAYS_INLINE void cpu_z80_inir(struct cpu_z80 *self) {
- abort();
+ cpu_z80_ini(self);
+ if (self->regs.byte.b)
+ self->regs.word.pc -= 2;
}
static ALWAYS_INLINE void cpu_z80_jp(struct cpu_z80 *self, bool pred, int rvalue) {
}
static ALWAYS_INLINE void cpu_z80_ldd(struct cpu_z80 *self) {
- int data = cpu_z80_read_byte(self, self->regs.word.hl--);
- cpu_z80_write_byte(self, self->regs.word.de--, data);
-
- int result = (self->regs.word.bc - 1) & 0xffff;
+ cpu_z80_write_byte(
+ self,
+ self->regs.word.de++,
+ cpu_z80_read_byte(self, self->regs.word.hl--)
+ );
+ --self->regs.word.bc;
- self->regs.word.bc = result;
self->regs.bit.nf = false;
- self->regs.bit.pvf = result != 0;
+ self->regs.bit.pvf = self->regs.word.bc != 0;
self->regs.bit.hf = false;
}
static ALWAYS_INLINE void cpu_z80_lddr(struct cpu_z80 *self) {
- int data = cpu_z80_read_byte(self, self->regs.word.hl--);
- cpu_z80_write_byte(self, self->regs.word.de--, data);
-
- int result = (self->regs.word.bc - 1) & 0xffff;
-
- self->regs.word.bc = result;
- self->regs.bit.nf = false;
- self->regs.bit.pvf = result != 0;
- self->regs.bit.hf = false;
-
- if (result)
+ cpu_z80_ldd(self);
+ if (self->regs.word.bc)
self->regs.word.pc -= 2;
}
static ALWAYS_INLINE void cpu_z80_ldi(struct cpu_z80 *self) {
- int data = cpu_z80_read_byte(self, self->regs.word.hl++);
- cpu_z80_write_byte(self, self->regs.word.de++, data);
+ cpu_z80_write_byte(
+ self,
+ self->regs.word.de++,
+ cpu_z80_read_byte(self, self->regs.word.hl++)
+ );
+ --self->regs.word.bc;
- int result = (self->regs.word.bc - 1) & 0xffff;
-
- self->regs.word.bc = result;
self->regs.bit.nf = false;
- self->regs.bit.pvf = result != 0;
+ self->regs.bit.pvf = self->regs.word.bc != 0;
self->regs.bit.hf = false;
}
static ALWAYS_INLINE void cpu_z80_ldir(struct cpu_z80 *self) {
- int data = cpu_z80_read_byte(self, self->regs.word.hl++);
- cpu_z80_write_byte(self, self->regs.word.de++, data);
-
- int result = (self->regs.word.bc - 1) & 0xffff;
-
- self->regs.word.bc = result;
- self->regs.bit.nf = false;
- self->regs.bit.pvf = result != 0;
- self->regs.bit.hf = false;
-
- if (result)
+ cpu_z80_ldi(self);
+ if (self->regs.word.bc)
self->regs.word.pc -= 2;
}
self->regs.bit.sf = result >> 7;
}
-static ALWAYS_INLINE void cpu_z80_otdr(struct cpu_z80 *self) {
- abort();
-}
-
-static ALWAYS_INLINE void cpu_z80_otir(struct cpu_z80 *self) {
- abort();
-}
-
static ALWAYS_INLINE void cpu_z80_out(struct cpu_z80 *self, int lvalue, int rvalue) {
cpu_z80_out_byte(self, lvalue, rvalue);
}
static ALWAYS_INLINE void cpu_z80_outd(struct cpu_z80 *self) {
- abort();
+ --self->regs.byte.b;
+ cpu_z80_out_byte(
+ self,
+ self->regs.word.bc,
+ cpu_z80_read_byte(self, self->regs.word.hl--)
+ );
+
+ self->regs.bit.nf = true;
+ self->regs.bit.zf = self->regs.byte.b != 0;
+}
+
+static ALWAYS_INLINE void cpu_z80_otdr(struct cpu_z80 *self) {
+ cpu_z80_outd(self);
+ if (self->regs.byte.b)
+ self->regs.word.pc -= 2;
}
static ALWAYS_INLINE void cpu_z80_outi(struct cpu_z80 *self) {
- abort();
+ --self->regs.byte.b;
+ cpu_z80_out_byte(
+ self,
+ self->regs.word.bc,
+ cpu_z80_read_byte(self, self->regs.word.hl++)
+ );
+
+ self->regs.bit.nf = true;
+ self->regs.bit.zf = self->regs.byte.b != 0;
+}
+
+static ALWAYS_INLINE void cpu_z80_otir(struct cpu_z80 *self) {
+ cpu_z80_outi(self);
+ if (self->regs.byte.b)
+ self->regs.word.pc -= 2;
}
static ALWAYS_INLINE void cpu_z80_pop(struct cpu_z80 *self, int lvalue) {