return data | cpu_6809_fetch_byte(self);
}
-static ALWAYS_INLINE void cpu_6809_push_byte(struct cpu_6809 *self, int data) {
- cpu_6809_write_byte(self, --self->regs.word.s, data);
+static ALWAYS_INLINE void cpu_6809_push_byte(struct cpu_6809 *self, uint16_t *sp, int data) {
+ cpu_6809_write_byte(self, --*sp, data);
}
-static ALWAYS_INLINE void cpu_6809_push_word(struct cpu_6809 *self, int data) {
- cpu_6809_push_byte(self, data & 0xff);
- cpu_6809_push_byte(self, data >> 8);
+static ALWAYS_INLINE void cpu_6809_push_word(struct cpu_6809 *self, uint16_t *sp, int data) {
+ cpu_6809_push_byte(self, sp, data & 0xff);
+ cpu_6809_push_byte(self, sp, data >> 8);
}
-static ALWAYS_INLINE int cpu_6809_pop_byte(struct cpu_6809 *self) {
- return cpu_6809_read_byte(self, self->regs.word.s++);
+static ALWAYS_INLINE int cpu_6809_pop_byte(struct cpu_6809 *self, uint16_t *sp) {
+ return cpu_6809_read_byte(self, (*sp)++);
}
-static ALWAYS_INLINE int cpu_6809_pop_word(struct cpu_6809 *self) {
- int data = cpu_6809_pop_byte(self) << 8;
- return data | cpu_6809_pop_byte(self);
+static ALWAYS_INLINE int cpu_6809_pop_word(struct cpu_6809 *self, uint16_t *sp) {
+ int data = cpu_6809_pop_byte(self, sp) << 8;
+ return data | cpu_6809_pop_byte(self, sp);
}
// effective address calculation
}
// instruction execute
+static ALWAYS_INLINE void cpu_6809_abx(struct cpu_6809 *self) {
+ self->regs.word.x += self->regs.byte.b;
+}
+
static ALWAYS_INLINE void cpu_6809_adc(struct cpu_6809 *self, int lvalue, int rvalue) {
int data = cpu_6809_read_byte(self, lvalue);
static ALWAYS_INLINE void cpu_6809_add_word(struct cpu_6809 *self, int lvalue, int rvalue) {
int data = cpu_6809_read_word(self, lvalue);
- int result0 = (data & 0xfff) + (rvalue & 0xfff);
- int result1 = result0 + (data & 0x7000) + (rvalue & 0x7000);
- int result2 = result1 + (data & 0x8000) + (rvalue & 0x8000);
+ int result0 = (data & 0x7fff) + (rvalue & 0x7fff);
+ int result1 = result0 + (data & 0x8000) + (rvalue & 0x8000);
- cpu_6809_write_word(self, lvalue, result2 & 0xffff);
- self->regs.bit.hf = result0 >> 12;
- self->regs.bit.nf = (result2 >> 15) & 1;
- self->regs.bit.zf = (result2 & 0xffff) == 0;
- self->regs.bit.vf = ((result1 >> 15) ^ (result2 >> 16)) & 1;
- self->regs.bit.cf = result2 >> 16;
+ cpu_6809_write_word(self, lvalue, result1 & 0xffff);
+ self->regs.bit.nf = (result1 >> 15) & 1;
+ self->regs.bit.zf = (result1 & 0xffff) == 0;
+ self->regs.bit.vf = ((result0 >> 15) ^ (result1 >> 16)) & 1;
+ self->regs.bit.cf = result1 >> 16;
}
static ALWAYS_INLINE void cpu_6809_and(struct cpu_6809 *self, int lvalue, int rvalue) {
cpu_6809_write_byte(self, lvalue, result >> 1);
self->regs.bit.nf = result >> 8;
self->regs.bit.zf = (result & 0xfe) == 0;
- self->regs.bit.vf = (result ^ (result >> 8)) & 1;
self->regs.bit.cf = result & 1;
}
}
static ALWAYS_INLINE void cpu_6809_bsr(struct cpu_6809 *self, int lvalue) {
- cpu_6809_push_word(self, self->regs.word.pc);
+ cpu_6809_push_word(self, &self->regs.word.s, self->regs.word.pc);
self->cycles += ((self->regs.word.pc & 0xff) + (lvalue & 0xff)) >> 8;
self->regs.word.pc += lvalue;
}
}
static ALWAYS_INLINE void cpu_6809_cwai(struct cpu_6809 *self, int rvalue) {
- cpu_6809_push_word(self, self->regs.word.pc);
- cpu_6809_push_word(self, self->regs.word.x);
- cpu_6809_push_byte(self, self->regs.byte.a);
- cpu_6809_push_byte(self, self->regs.byte.b);
- cpu_6809_push_byte(self, self->regs.byte.cc);
+ cpu_6809_push_word(self, &self->regs.word.s, self->regs.word.pc);
+ cpu_6809_push_word(self, &self->regs.word.s, self->regs.word.x);
+ cpu_6809_push_byte(self, &self->regs.word.s, self->regs.byte.a);
+ cpu_6809_push_byte(self, &self->regs.word.s, self->regs.byte.b);
+ cpu_6809_push_byte(self, &self->regs.word.s, self->regs.byte.cc);
self->regs.bit.wai_flag = true;
}
}
static ALWAYS_INLINE void cpu_6809_jsr(struct cpu_6809 *self, int lvalue) {
- cpu_6809_push_word(self, self->regs.word.pc);
+ cpu_6809_push_word(self, &self->regs.word.s, self->regs.word.pc);
self->regs.word.pc = lvalue;
}
}
static ALWAYS_INLINE void cpu_6809_lbsr(struct cpu_6809 *self, int lvalue) {
- cpu_6809_push_word(self, self->regs.word.pc);
+ cpu_6809_push_word(self, &self->regs.word.s, self->regs.word.pc);
self->cycles += ((self->regs.word.pc & 0xff) + (lvalue & 0xff)) >> 8;
self->regs.word.pc += lvalue;
}
cpu_6809_write_byte(self, lvalue, result >> 1);
self->regs.bit.nf = result >> 8;
self->regs.bit.zf = (result & 0xfe) == 0;
- self->regs.bit.vf = (result ^ (result >> 8)) & 1;
self->regs.bit.cf = result & 1;
}
static ALWAYS_INLINE void cpu_6809_psh(struct cpu_6809 *self, int lvalue, int postbyte) {
uint16_t sp = cpu_6809_read_word(self, lvalue);
- if (postbyte & 0x80) {
- sp -= 2;
- cpu_6809_write_word(self, sp, self->regs.word.pc);
- }
- if (postbyte & 0x40) {
- sp -= 2;
- cpu_6809_write_word(
+ if (postbyte & 0x80)
+ cpu_6809_push_word(self, &sp, self->regs.word.pc);
+ if (postbyte & 0x40)
+ cpu_6809_push_word(
self,
- sp,
+ &sp,
cpu_6809_read_word(self, lvalue ^ (CPU_6809_EA_U ^ CPU_6809_EA_S))
);
- }
- if (postbyte & 0x20) {
- sp -= 2;
- cpu_6809_write_word(self, sp, self->regs.word.y);
- }
- if (postbyte & 0x10) {
- sp -= 2;
- cpu_6809_write_word(self, sp, self->regs.word.x);
- }
+ if (postbyte & 0x20)
+ cpu_6809_push_word(self, &sp, self->regs.word.y);
+ if (postbyte & 0x10)
+ cpu_6809_push_word(self, &sp, self->regs.word.x);
if (postbyte & 8)
- cpu_6809_write_byte(self, --sp, self->regs.byte.dp);
+ cpu_6809_push_byte(self, &sp, self->regs.byte.dp);
if (postbyte & 4)
- cpu_6809_write_byte(self, --sp, self->regs.byte.b);
+ cpu_6809_push_byte(self, &sp, self->regs.byte.b);
if (postbyte & 2)
- cpu_6809_write_byte(self, --sp, self->regs.byte.a);
+ cpu_6809_push_byte(self, &sp, self->regs.byte.a);
if (postbyte & 1)
- cpu_6809_write_byte(self, --sp, self->regs.byte.cc);
+ cpu_6809_push_byte(self, &sp, self->regs.byte.cc);
cpu_6809_write_word(self, lvalue, sp);
}
static ALWAYS_INLINE void cpu_6809_pul(struct cpu_6809 *self, int lvalue, int postbyte) {
uint16_t sp = cpu_6809_read_word(self, lvalue);
if (postbyte & 1)
- self->regs.byte.cc = cpu_6809_read_byte(self, sp++);
+ self->regs.byte.cc = cpu_6809_pop_byte(self, &sp);
if (postbyte & 2)
- self->regs.byte.a = cpu_6809_read_byte(self, sp++);
+ self->regs.byte.a = cpu_6809_pop_byte(self, &sp);
if (postbyte & 4)
- self->regs.byte.b = cpu_6809_read_byte(self, sp++);
+ self->regs.byte.b = cpu_6809_pop_byte(self, &sp);
if (postbyte & 8)
- self->regs.byte.dp = cpu_6809_read_byte(self, sp++);
- if (postbyte & 0x10) {
- self->regs.word.x = cpu_6809_read_word(self, sp);
- sp += 2;
- }
- if (postbyte & 0x20) {
- self->regs.word.y = cpu_6809_read_word(self, sp);
- sp += 2;
- }
- if (postbyte & 0x40) {
+ self->regs.byte.dp = cpu_6809_pop_byte(self, &sp);
+ if (postbyte & 0x10)
+ self->regs.word.x = cpu_6809_pop_word(self, &sp);
+ if (postbyte & 0x20)
+ self->regs.word.y = cpu_6809_pop_word(self, &sp);
+ if (postbyte & 0x40)
cpu_6809_write_word(
self,
lvalue ^ (CPU_6809_EA_U ^ CPU_6809_EA_S),
- cpu_6809_read_word(self, sp)
+ cpu_6809_pop_word(self, &sp)
);
- sp += 2;
- }
- if (postbyte & 0x80) {
- self->regs.word.pc = cpu_6809_read_word(self, sp);
- sp += 2;
- }
+ if (postbyte & 0x80)
+ self->regs.word.pc = cpu_6809_pop_word(self, &sp);
cpu_6809_write_word(self, lvalue, sp);
}
self->regs.bit.nf = result >> 8;
self->regs.bit.zf = (result & 0x1fe) == 0;
- self->regs.bit.vf = (result ^ (result >> 8)) & 1;
self->regs.bit.cf = result & 1;
}
static ALWAYS_INLINE void cpu_6809_rti(struct cpu_6809 *self) {
- self->regs.byte.cc = cpu_6809_pop_byte(self);
- self->regs.byte.b = cpu_6809_pop_byte(self);
- self->regs.byte.a = cpu_6809_pop_byte(self);
- self->regs.word.x = cpu_6809_pop_word(self);
- self->regs.word.pc = cpu_6809_pop_word(self);
+ self->regs.byte.cc = cpu_6809_pop_byte(self, &self->regs.word.s);
+ self->regs.byte.b = cpu_6809_pop_byte(self, &self->regs.word.s);
+ self->regs.byte.a = cpu_6809_pop_byte(self, &self->regs.word.s);
+ self->regs.word.x = cpu_6809_pop_word(self, &self->regs.word.s);
+ self->regs.word.pc = cpu_6809_pop_word(self, &self->regs.word.s);
}
static ALWAYS_INLINE void cpu_6809_rts(struct cpu_6809 *self) {
- self->regs.word.pc = cpu_6809_pop_word(self);
+ self->regs.word.pc = cpu_6809_pop_word(self, &self->regs.word.s);
}
static ALWAYS_INLINE void cpu_6809_sbc(struct cpu_6809 *self, int lvalue, int rvalue) {
}
static ALWAYS_INLINE void cpu_6809_swi(struct cpu_6809 *self) {
- cpu_6809_push_word(self, self->regs.word.pc);
- cpu_6809_push_word(self, self->regs.word.x);
- cpu_6809_push_byte(self, self->regs.byte.a);
- cpu_6809_push_byte(self, self->regs.byte.b);
- cpu_6809_push_byte(self, self->regs.byte.cc);
+ cpu_6809_push_word(self, &self->regs.word.s, self->regs.word.pc);
+ cpu_6809_push_word(self, &self->regs.word.s, self->regs.word.x);
+ cpu_6809_push_byte(self, &self->regs.word.s, self->regs.byte.a);
+ cpu_6809_push_byte(self, &self->regs.word.s, self->regs.byte.b);
+ cpu_6809_push_byte(self, &self->regs.word.s, self->regs.byte.cc);
self->regs.word.pc = cpu_6809_read_word(self, CPU_6809_SWI_VECTOR);
self->regs.bit._if = true;
}
static ALWAYS_INLINE void cpu_6809_swi_n(struct cpu_6809 *self, int n) {
- cpu_6809_push_word(self, self->regs.word.pc);
- cpu_6809_push_word(self, self->regs.word.x);
- cpu_6809_push_byte(self, self->regs.byte.a);
- cpu_6809_push_byte(self, self->regs.byte.b);
- cpu_6809_push_byte(self, self->regs.byte.cc);
+ cpu_6809_push_word(self, &self->regs.word.s, self->regs.word.pc);
+ cpu_6809_push_word(self, &self->regs.word.s, self->regs.word.x);
+ cpu_6809_push_byte(self, &self->regs.word.s, self->regs.byte.a);
+ cpu_6809_push_byte(self, &self->regs.word.s, self->regs.byte.b);
+ cpu_6809_push_byte(self, &self->regs.word.s, self->regs.byte.cc);
self->regs.word.pc = cpu_6809_read_word(self, CPU_6809_SWI_VECTOR);
self->regs.bit._if = true;
}