void cpu_6800_execute(struct cpu_6800 *self) {
if (self->regs.bit.nmi_pending) {
self->regs.bit.nmi_pending = false;
+ if (!self->regs.bit.wai_flag)
+ cpu_6800_wai(self);
self->regs.bit.wai_flag = false;
- cpu_6800_swi(self, CPU_6800_NMI_VECTOR);
+ self->regs.word.pc = cpu_6800_read_word(self, CPU_6800_NMI_VECTOR);
+ self->regs.bit._if = true;
return;
}
- if (self->regs.bit.irq_pending) {
- if (self->regs.bit._if == 0) {
- self->regs.bit.irq_pending = false;
- self->regs.bit.wai_flag = false;
- cpu_6800_swi(self, CPU_6800_IRQ_VECTOR);
- return;
- }
- if (self->regs.bit.wai_flag) {
- self->regs.bit.irq_pending = false;
- self->regs.bit.wai_flag = false;
- }
+ if (self->regs.bit.irq_pending && !self->regs.bit._if) {
+ self->regs.bit.irq_pending = false;
+ if (!self->regs.bit.wai_flag)
+ cpu_6800_wai(self);
+ self->regs.bit.wai_flag = false;
+ self->regs.word.pc = cpu_6800_read_word(self, CPU_6800_IRQ_VECTOR);
+ self->regs.bit._if = true;
+ return;
}
- else if (self->regs.bit.wai_flag) {
+
+ if (self->regs.bit.wai_flag) {
++self->cycles;
return;
}
cpu_6800_wai(self);
break;
case 0x3f:
- cpu_6800_swi(self, CPU_6800_SWI_VECTOR);
+ cpu_6800_swi(self);
break;
case 0x40:
cpu_6800_neg(self, CPU_6800_EA_A);
cpu_6800_asr(self, CPU_6800_EA_A);
break;
case 0x48:
- cpu_6800_lsl(self, CPU_6800_EA_A);
+ cpu_6800_asl(self, CPU_6800_EA_A);
break;
case 0x49:
cpu_6800_rol(self, CPU_6800_EA_A);
cpu_6800_asr(self, CPU_6800_EA_B);
break;
case 0x58:
- cpu_6800_lsl(self, CPU_6800_EA_B);
+ cpu_6800_asl(self, CPU_6800_EA_B);
break;
case 0x59:
cpu_6800_rol(self, CPU_6800_EA_B);
cpu_6800_asr(self, cpu_6800_ea_direct_indexed(self, self->regs.word.x));
break;
case 0x68:
- cpu_6800_lsl(self, cpu_6800_ea_direct_indexed(self, self->regs.word.x));
+ cpu_6800_asl(self, cpu_6800_ea_direct_indexed(self, self->regs.word.x));
break;
case 0x69:
cpu_6800_rol(self, cpu_6800_ea_direct_indexed(self, self->regs.word.x));
cpu_6800_asr(self, cpu_6800_ea_extended(self));
break;
case 0x78:
- cpu_6800_lsl(self, cpu_6800_ea_extended(self));
+ cpu_6800_asl(self, cpu_6800_ea_extended(self));
break;
case 0x79:
cpu_6800_rol(self, cpu_6800_ea_extended(self));
self->regs.bit.vf = false;
}
+static ALWAYS_INLINE void cpu_6800_asl(struct cpu_6800 *self, int lvalue) {
+ int result = cpu_6800_read_byte(self, lvalue) << 1;
+ ++self->cycles;
+
+ cpu_6800_write_byte(self, lvalue, result & 0xff);
+ self->regs.bit.nf = (result >> 7) & 1;
+ self->regs.bit.zf = (result & 0xff) == 0;
+ self->regs.bit.vf = ((result >> 7) ^ (result >> 8)) & 1;
+ self->regs.bit.cf = result >> 8;
+}
+
static ALWAYS_INLINE void cpu_6800_asr(struct cpu_6800 *self, int lvalue) {
int data = cpu_6800_read_byte(self, lvalue);
static ALWAYS_INLINE void cpu_6800_bit(struct cpu_6800 *self, int rvalue0, int rvalue1) {
int result = rvalue0 & rvalue1;
- self->regs.bit.zf = result == 0;
self->regs.bit.nf = result >> 7;
-}
-
-static ALWAYS_INLINE void cpu_6800_bit_imm(struct cpu_6800 *self, int rvalue) {
- int result = self->regs.byte.a & rvalue;
self->regs.bit.zf = result == 0;
+ self->regs.bit.vf = false;
}
static ALWAYS_INLINE void cpu_6800_bra(struct cpu_6800 *self, bool pred, int lvalue) {
}
static ALWAYS_INLINE void cpu_6800_daa(struct cpu_6800 *self) {
- abort();
-}
-
-static ALWAYS_INLINE void cpu_6800_des(struct cpu_6800 *self) {
- --self->regs.word.s;
- ++self->cycles;
-}
+ int correction = 0;
+ if (self->regs.bit.hf || (self->regs.byte.a & 0xf) >= 0xa)
+ correction = 6;
+ if (self->regs.bit.cf || self->regs.byte.a >= 0x9a) {
+ correction |= 0x60;
+ self->regs.bit.cf = true;
+ }
-static ALWAYS_INLINE void cpu_6800_dex(struct cpu_6800 *self) {
- int result = (self->regs.word.x - 1) & 0xffff;
- ++self->cycles;
+ int result0 = (self->regs.byte.a & 0x7f) + correction;
+ int result1 = result0 + (self->regs.byte.a & 0x80);
- self->regs.word.x = result;
- self->regs.bit.zf = result == 0;
+ self->regs.byte.a = result1 & 0xff;
+ self->regs.bit.nf = (result1 >> 7) & 1;
+ self->regs.bit.zf = (result1 & 0xff) == 0;
+ self->regs.bit.vf = ((result0 >> 7) ^ (result1 >> 8)) & 1;
+ //self->regs.bit.cf |= result1 >> 8;
}
static ALWAYS_INLINE void cpu_6800_dec(struct cpu_6800 *self, int lvalue) {
self->regs.bit.vf = ((result0 >> 7) ^ (result1 >> 8)) & 1;
}
+static ALWAYS_INLINE void cpu_6800_des(struct cpu_6800 *self) {
+ --self->regs.word.s;
+ ++self->cycles;
+}
+
+static ALWAYS_INLINE void cpu_6800_dex(struct cpu_6800 *self) {
+ int result = (self->regs.word.x - 1) & 0xffff;
+ ++self->cycles;
+
+ self->regs.word.x = result;
+ self->regs.bit.zf = result == 0;
+}
+
static ALWAYS_INLINE void cpu_6800_eor(struct cpu_6800 *self, int lvalue, int rvalue) {
int result = cpu_6800_read_byte(self, lvalue) ^ rvalue;
abort();
}
-static ALWAYS_INLINE void cpu_6800_ins(struct cpu_6800 *self) {
- ++self->regs.word.s;
- ++self->cycles;
-}
-
-static ALWAYS_INLINE void cpu_6800_inx(struct cpu_6800 *self) {
- int result = (self->regs.word.x + 1) & 0xffff;
- ++self->cycles;
-
- self->regs.word.x = result;
- self->regs.bit.zf = result == 0;
-}
-
static ALWAYS_INLINE void cpu_6800_inc(struct cpu_6800 *self, int lvalue) {
int data = cpu_6800_read_byte(self, lvalue);
self->regs.bit.vf = ((result0 >> 7) ^ (result1 >> 8)) & 1;
}
-static ALWAYS_INLINE void cpu_6800_swi(struct cpu_6800 *self, int lvalue) {
+static ALWAYS_INLINE void cpu_6800_ins(struct cpu_6800 *self) {
+ ++self->regs.word.s;
+ ++self->cycles;
+}
+
+static ALWAYS_INLINE void cpu_6800_inx(struct cpu_6800 *self) {
+ int result = (self->regs.word.x + 1) & 0xffff;
++self->cycles;
+
+ self->regs.word.x = result;
+ self->regs.bit.zf = result == 0;
+}
+
+static ALWAYS_INLINE void cpu_6800_swi(struct cpu_6800 *self) {
cpu_6800_push_word(self, self->regs.word.pc);
+ cpu_6800_push_word(self, self->regs.word.x);
+ cpu_6800_push_byte(self, self->regs.byte.a);
+ cpu_6800_push_byte(self, self->regs.byte.b);
cpu_6800_push_byte(self, self->regs.byte.p);
- self->regs.word.pc = cpu_6800_read_word(self, lvalue);
+ self->regs.word.pc = cpu_6800_read_word(self, CPU_6800_SWI_VECTOR);
self->regs.bit._if = true;
}
self->regs.bit.vf = false;
}
-static ALWAYS_INLINE void cpu_6800_lsl(struct cpu_6800 *self, int lvalue) {
- int result = cpu_6800_read_byte(self, lvalue) << 1;
- ++self->cycles;
-
- cpu_6800_write_byte(self, lvalue, result & 0xff);
- self->regs.bit.nf = (result >> 7) & 1;
- self->regs.bit.zf = (result & 0xff) == 0;
- self->regs.bit.vf = ((result >> 7) ^ (result >> 8)) & 1;
- self->regs.bit.cf = result >> 8;
-}
-
static ALWAYS_INLINE void cpu_6800_lsr(struct cpu_6800 *self, int lvalue) {
int data = cpu_6800_read_byte(self, lvalue);
static ALWAYS_INLINE void cpu_6800_rti(struct cpu_6800 *self) {
self->regs.byte.p = cpu_6800_pop_byte(self) | 0xc0;
+ self->regs.byte.b = cpu_6800_pop_byte(self);
+ self->regs.byte.a = cpu_6800_pop_byte(self);
+ self->regs.word.x = cpu_6800_pop_word(self);
self->regs.word.pc = cpu_6800_pop_word(self);
}
self->regs.byte.a = self->regs.byte.p;
}
-static ALWAYS_INLINE void cpu_6800_tst(struct cpu_6800 *self, int rvalue) {
- self->regs.bit.zf = rvalue == 0;
- self->regs.bit.nf = rvalue >> 7;
-}
-
static ALWAYS_INLINE void cpu_6800_tsx(struct cpu_6800 *self) {
self->regs.word.x = (self->regs.word.s + 1) & 0xffff;
}
}
static ALWAYS_INLINE void cpu_6800_wai(struct cpu_6800 *self) {
+ cpu_6800_push_word(self, self->regs.word.pc);
+ cpu_6800_push_word(self, self->regs.word.x);
+ cpu_6800_push_byte(self, self->regs.byte.a);
+ cpu_6800_push_byte(self, self->regs.byte.b);
+ cpu_6800_push_byte(self, self->regs.byte.p);
self->regs.bit.wai_flag = true;
}