10 #define ALWAYS_INLINE __attribute__((always_inline))
13 #define CPU_6809_IRQ_VECTOR 0xfff8
14 #define CPU_6809_SWI_VECTOR 0xfffa
15 #define CPU_6809_NMI_VECTOR 0xfffc
16 #define CPU_6809_RESET_VECTOR 0xfffe
19 #define CPU_6809_REG_CC_BIT_H 5
20 #define CPU_6809_REG_CC_BIT_I 4
21 #define CPU_6809_REG_CC_BIT_N 3
22 #define CPU_6809_REG_CC_BIT_Z 2
23 #define CPU_6809_REG_CC_BIT_V 1
24 #define CPU_6809_REG_CC_BIT_C 0
26 // special memory locations (negative address)
27 // m1 and sink are used to implement undefined registers for TFR/EXG
28 #define CPU_6809_EA_PC (-0x12)
29 #define CPU_6809_EA_D (-0x10)
30 #define CPU_6809_EA_A (-0x10)
31 #define CPU_6809_EA_B (-0xf)
32 #define CPU_6809_EA_U (-0xe)
33 #define CPU_6809_EA_S (-0xc)
34 #define CPU_6809_EA_X (-0xa)
35 #define CPU_6809_EA_Y (-8)
36 #define CPU_6809_EA_CC (-6)
37 #define CPU_6809_EA_DP (-5)
38 #define CPU_6809_EA_IFLAGS (-4)
39 #define CPU_6809_EA_M1 (-3)
40 #define CPU_6809_EA_SINK (-2)
42 // registers, in same order as special memory locations, but reversed on
43 // little endian hardware where special memory address will be complemented
44 // (this allows special memory to always look like it is big endian)
46 #if __BYTE_ORDER == __BIG_ENDIAN
63 uint8_t _fill_iflags : 5;
65 uint8_t irq_pending : 1;
66 uint8_t nmi_pending : 1;
100 uint8_t mem_be[0x10];
106 uint8_t nmi_pending : 1;
107 uint8_t irq_pending : 1;
108 uint8_t wai_flag : 1;
109 uint8_t _fill_iflags : 5;
145 uint8_t _fill_iflags;
155 uint8_t mem_le[0x10];
161 int (*read_byte)(void *context, int addr);
162 void *read_byte_context;
163 void (*write_byte)(void *context, int addr, int data);
164 void *write_byte_context;
165 union cpu_6809_regs regs;
169 extern int cpu_6809_ea_src[0x10][2];
170 extern int cpu_6809_ea_dest[0x10][2];
172 // memory or special memory access
173 static ALWAYS_INLINE int cpu_6809_read_byte(struct cpu_6809 *self, int addr) {
175 #if __BYTE_ORDER == __BIG_ENDIAN
176 return self->regs.mem_be[sizeof(union cpu_6809_regs) + addr];
178 return self->regs.mem_le[~addr];
181 return self->read_byte(self->read_byte_context, addr & 0xffff);
184 static ALWAYS_INLINE int cpu_6809_read_word(struct cpu_6809 *self, int addr) {
185 int data = cpu_6809_read_byte(self, addr) << 8;
186 return data | cpu_6809_read_byte(self, addr + 1);
189 static ALWAYS_INLINE void cpu_6809_write_byte(struct cpu_6809 *self, int addr, int data) {
192 #if __BYTE_ORDER == __BIG_ENDIAN
193 self->regs.mem_be[sizeof(union cpu_6809_regs) + addr] = data;
195 self->regs.mem_le[~addr] = data;
198 self->write_byte(self->write_byte_context, addr, data);
201 static ALWAYS_INLINE void cpu_6809_write_word(struct cpu_6809 *self, int addr, int data) {
202 cpu_6809_write_byte(self, addr, data >> 8);
203 cpu_6809_write_byte(self, addr + 1, data & 0xff);
206 static ALWAYS_INLINE int cpu_6809_fetch_byte(struct cpu_6809 *self) {
207 int data = cpu_6809_read_byte(self, self->regs.word.pc++);
211 static ALWAYS_INLINE int cpu_6809_fetch_word(struct cpu_6809 *self) {
212 int data = cpu_6809_fetch_byte(self) << 8;
213 return data | cpu_6809_fetch_byte(self);
216 static ALWAYS_INLINE void cpu_6809_push_byte(struct cpu_6809 *self, uint16_t *sp, int data) {
217 cpu_6809_write_byte(self, --*sp, data);
220 static ALWAYS_INLINE void cpu_6809_push_word(struct cpu_6809 *self, uint16_t *sp, int data) {
221 cpu_6809_push_byte(self, sp, data & 0xff);
222 cpu_6809_push_byte(self, sp, data >> 8);
225 static ALWAYS_INLINE int cpu_6809_pop_byte(struct cpu_6809 *self, uint16_t *sp) {
226 return cpu_6809_read_byte(self, (*sp)++);
229 static ALWAYS_INLINE int cpu_6809_pop_word(struct cpu_6809 *self, uint16_t *sp) {
230 int data = cpu_6809_pop_byte(self, sp) << 8;
231 return data | cpu_6809_pop_byte(self, sp);
234 // effective address calculation
235 static ALWAYS_INLINE int cpu_6809_ea_extended(struct cpu_6809 *self) {
236 return cpu_6809_fetch_word(self);
239 static ALWAYS_INLINE int cpu_6809_ea_relative(struct cpu_6809 *self) {
240 return (int8_t)cpu_6809_fetch_byte(self);
243 static ALWAYS_INLINE int cpu_6809_ea_long_relative(struct cpu_6809 *self) {
244 return cpu_6809_fetch_word(self);
247 static ALWAYS_INLINE int cpu_6809_ea_direct(struct cpu_6809 *self) {
248 return cpu_6809_fetch_byte(self);
251 // instruction execute
252 static ALWAYS_INLINE void cpu_6809_abx(struct cpu_6809 *self) {
253 self->regs.word.x += self->regs.byte.b;
256 static ALWAYS_INLINE void cpu_6809_adc(struct cpu_6809 *self, int lvalue, int rvalue) {
257 int data = cpu_6809_read_byte(self, lvalue);
259 int result0 = (data & 0xf) + (rvalue & 0xf) + self->regs.bit.cf;
260 int result1 = result0 + (data & 0x70) + (rvalue & 0x70);
261 int result2 = result1 + (data & 0x80) + (rvalue & 0x80);
263 cpu_6809_write_byte(self, lvalue, result2 & 0xff);
264 self->regs.bit.hf = result0 >> 4;
265 self->regs.bit.nf = (result2 >> 7) & 1;
266 self->regs.bit.zf = (result2 & 0xff) == 0;
267 self->regs.bit.vf = ((result1 >> 7) ^ (result2 >> 8)) & 1;
268 self->regs.bit.cf = result2 >> 8;
271 static ALWAYS_INLINE void cpu_6809_add_byte(struct cpu_6809 *self, int lvalue, int rvalue) {
272 int data = cpu_6809_read_byte(self, lvalue);
274 int result0 = (data & 0xf) + (rvalue & 0xf);
275 int result1 = result0 + (data & 0x70) + (rvalue & 0x70);
276 int result2 = result1 + (data & 0x80) + (rvalue & 0x80);
278 cpu_6809_write_byte(self, lvalue, result2 & 0xff);
279 self->regs.bit.hf = result0 >> 4;
280 self->regs.bit.nf = (result2 >> 7) & 1;
281 self->regs.bit.zf = (result2 & 0xff) == 0;
282 self->regs.bit.vf = ((result1 >> 7) ^ (result2 >> 8)) & 1;
283 self->regs.bit.cf = result2 >> 8;
286 static ALWAYS_INLINE void cpu_6809_add_word(struct cpu_6809 *self, int lvalue, int rvalue) {
287 int data = cpu_6809_read_word(self, lvalue);
289 int result0 = (data & 0x7fff) + (rvalue & 0x7fff);
290 int result1 = result0 + (data & 0x8000) + (rvalue & 0x8000);
292 cpu_6809_write_word(self, lvalue, result1 & 0xffff);
293 self->regs.bit.nf = (result1 >> 15) & 1;
294 self->regs.bit.zf = (result1 & 0xffff) == 0;
295 self->regs.bit.vf = ((result0 >> 15) ^ (result1 >> 16)) & 1;
296 self->regs.bit.cf = result1 >> 16;
299 static ALWAYS_INLINE void cpu_6809_and(struct cpu_6809 *self, int lvalue, int rvalue) {
300 int result = cpu_6809_read_byte(self, lvalue) & rvalue;
302 cpu_6809_write_byte(self, lvalue, result);
303 self->regs.bit.nf = result >> 7;
304 self->regs.bit.zf = result == 0;
305 self->regs.bit.vf = false;
308 static ALWAYS_INLINE void cpu_6809_andcc(struct cpu_6809 *self, int rvalue) {
309 self->regs.byte.cc &= rvalue;
312 static ALWAYS_INLINE void cpu_6809_asl(struct cpu_6809 *self, int lvalue) {
313 int result = cpu_6809_read_byte(self, lvalue) << 1;
316 cpu_6809_write_byte(self, lvalue, result & 0xff);
317 self->regs.bit.nf = (result >> 7) & 1;
318 self->regs.bit.zf = (result & 0xff) == 0;
319 self->regs.bit.vf = ((result >> 7) ^ (result >> 8)) & 1;
320 self->regs.bit.cf = result >> 8;
323 static ALWAYS_INLINE void cpu_6809_asr(struct cpu_6809 *self, int lvalue) {
324 int data = cpu_6809_read_byte(self, lvalue);
326 int result = data | ((data << 1) & 0x100);
329 cpu_6809_write_byte(self, lvalue, result >> 1);
330 self->regs.bit.nf = result >> 8;
331 self->regs.bit.zf = (result & 0xfe) == 0;
332 self->regs.bit.cf = result & 1;
335 static ALWAYS_INLINE void cpu_6809_bit(struct cpu_6809 *self, int rvalue0, int rvalue1) {
336 int result = rvalue0 & rvalue1;
338 self->regs.bit.nf = result >> 7;
339 self->regs.bit.zf = result == 0;
340 self->regs.bit.vf = false;
343 static ALWAYS_INLINE void cpu_6809_bra(struct cpu_6809 *self, bool pred, int lvalue) {
345 self->cycles += ((self->regs.word.pc & 0xff) + (lvalue & 0xff)) >> 8;
346 self->regs.word.pc += lvalue;
350 static ALWAYS_INLINE void cpu_6809_bsr(struct cpu_6809 *self, int lvalue) {
351 cpu_6809_push_word(self, &self->regs.word.s, self->regs.word.pc);
352 self->cycles += ((self->regs.word.pc & 0xff) + (lvalue & 0xff)) >> 8;
353 self->regs.word.pc += lvalue;
356 static ALWAYS_INLINE void cpu_6809_clr(struct cpu_6809 *self, int lvalue) {
357 //cpu_6809_read_byte(self, lvalue); // clr is implemented as RMW like inc/dec
358 cpu_6809_write_byte(self, lvalue, 0);
360 self->regs.bit.nf = false;
361 self->regs.bit.zf = true;
362 self->regs.bit.vf = false;
363 self->regs.bit.cf = false;
366 static ALWAYS_INLINE void cpu_6809_cmp_byte(struct cpu_6809 *self, int rvalue0, int rvalue1) {
367 int result0 = (rvalue0 & 0x7f) - (rvalue1 & 0x7f);
368 int result1 = result0 + (rvalue0 & 0x80) - (rvalue1 & 0x80);
370 self->regs.bit.nf = (result1 >> 7) & 1;
371 self->regs.bit.zf = (result1 & 0xff) == 0;
372 self->regs.bit.vf = ((result0 >> 7) ^ (result1 >> 8)) & 1;
373 self->regs.bit.cf = (result1 >> 8) & 1;
376 static ALWAYS_INLINE void cpu_6809_cmp_word(struct cpu_6809 *self, int rvalue0, int rvalue1) {
377 int result0 = (rvalue0 & 0x7fff) - (rvalue1 & 0x7fff);
378 int result1 = result0 + (rvalue0 & 0x8000) - (rvalue1 & 0x8000);
380 self->regs.bit.nf = (result1 >> 15) & 1;
381 self->regs.bit.zf = (result1 & 0xffff) == 0;
382 self->regs.bit.vf = ((result0 >> 15) ^ (result1 >> 16)) & 1;
383 self->regs.bit.cf = (result1 >> 16) & 1;
386 static ALWAYS_INLINE void cpu_6809_com(struct cpu_6809 *self, int lvalue) {
387 int result = cpu_6809_read_byte(self, lvalue) ^ 0xff;
389 cpu_6809_write_byte(self, lvalue, result);
390 self->regs.bit.nf = result >> 7;
391 self->regs.bit.zf = result == 0;
392 self->regs.bit.vf = false;
393 self->regs.bit.cf = true;
396 static ALWAYS_INLINE void cpu_6809_cwai(struct cpu_6809 *self, int rvalue) {
397 cpu_6809_push_word(self, &self->regs.word.s, self->regs.word.pc);
398 cpu_6809_push_word(self, &self->regs.word.s, self->regs.word.x);
399 cpu_6809_push_byte(self, &self->regs.word.s, self->regs.byte.a);
400 cpu_6809_push_byte(self, &self->regs.word.s, self->regs.byte.b);
401 cpu_6809_push_byte(self, &self->regs.word.s, self->regs.byte.cc);
402 self->regs.bit.wai_flag = true;
405 static ALWAYS_INLINE void cpu_6809_daa(struct cpu_6809 *self) {
407 if (self->regs.bit.hf || (self->regs.byte.a & 0xf) >= 0xa)
409 if (self->regs.bit.cf || self->regs.byte.a >= 0x9a) {
411 self->regs.bit.cf = true;
414 int result0 = (self->regs.byte.a & 0x7f) + correction;
415 int result1 = result0 + (self->regs.byte.a & 0x80);
417 self->regs.byte.a = result1 & 0xff;
418 self->regs.bit.nf = (result1 >> 7) & 1;
419 self->regs.bit.zf = (result1 & 0xff) == 0;
420 self->regs.bit.vf = ((result0 >> 7) ^ (result1 >> 8)) & 1;
421 //self->regs.bit.cf |= result1 >> 8;
424 static ALWAYS_INLINE void cpu_6809_dec_byte(struct cpu_6809 *self, int lvalue) {
425 int data = cpu_6809_read_byte(self, lvalue);
427 int result0 = (data & 0x7f) - 1;
428 int result1 = result0 + (data & 0x80);
431 cpu_6809_write_byte(self, lvalue, result1 & 0xff);
432 self->regs.bit.nf = (result1 >> 7) & 1;
433 self->regs.bit.zf = (result1 & 0xff) == 0;
434 self->regs.bit.vf = ((result0 >> 7) ^ (result1 >> 8)) & 1;
437 static ALWAYS_INLINE void cpu_6809_dec_word(struct cpu_6809 *self, int lvalue) {
441 (cpu_6809_read_word(self, lvalue) - 1) & 0xffff
446 static ALWAYS_INLINE void cpu_6809_dec_word_zf(struct cpu_6809 *self, int lvalue) {
447 int result = (cpu_6809_read_word(self, lvalue) - 1) & 0xffff;
450 self->regs.word.x = result;
451 self->regs.bit.zf = result == 0;
454 static ALWAYS_INLINE void cpu_6809_eor(struct cpu_6809 *self, int lvalue, int rvalue) {
455 int result = cpu_6809_read_byte(self, lvalue) ^ rvalue;
457 cpu_6809_write_byte(self, lvalue, result);
458 self->regs.bit.nf = result >> 7;
459 self->regs.bit.zf = result == 0;
460 self->regs.bit.vf = false;
463 static ALWAYS_INLINE void cpu_6809_exg(struct cpu_6809 *self, int postbyte) {
464 int reg0 = postbyte >> 4;
465 int reg1 = postbyte & 0xf;
467 int rvalue00 = cpu_6809_read_byte(self, cpu_6809_ea_src[reg0][0]);
468 int rvalue10 = cpu_6809_read_byte(self, cpu_6809_ea_src[reg1][0]);
469 cpu_6809_write_byte(self, cpu_6809_ea_dest[reg1][0], rvalue00);
470 cpu_6809_write_byte(self, cpu_6809_ea_dest[reg0][0], rvalue10);
472 int rvalue01 = cpu_6809_read_byte(self, cpu_6809_ea_src[reg0][1]);
473 int rvalue11 = cpu_6809_read_byte(self, cpu_6809_ea_src[reg1][1]);
474 cpu_6809_write_byte(self, cpu_6809_ea_dest[reg1][1], rvalue01);
475 cpu_6809_write_byte(self, cpu_6809_ea_dest[reg0][1], rvalue11);
478 static ALWAYS_INLINE void cpu_6809_illegal_opcode(struct cpu_6809 *self) {
482 static ALWAYS_INLINE void cpu_6809_inc_byte(struct cpu_6809 *self, int lvalue) {
483 int data = cpu_6809_read_byte(self, lvalue);
485 int result0 = (data & 0x7f) + 1;
486 int result1 = result0 + (data & 0x80);
489 cpu_6809_write_byte(self, lvalue, result1 & 0xff);
490 self->regs.bit.nf = (result1 >> 7) & 1;
491 self->regs.bit.zf = (result1 & 0xff) == 0;
492 self->regs.bit.vf = ((result0 >> 7) ^ (result1 >> 8)) & 1;
495 static ALWAYS_INLINE void cpu_6809_inc_word(struct cpu_6809 *self, int lvalue) {
499 (cpu_6809_read_word(self, lvalue) + 1) & 0xffff
504 static ALWAYS_INLINE void cpu_6809_inc_word_zf(struct cpu_6809 *self, int lvalue) {
505 int result = (cpu_6809_read_word(self, lvalue) + 1) & 0xffff;
508 self->regs.word.x = result;
509 self->regs.bit.zf = result == 0;
512 static ALWAYS_INLINE void cpu_6809_jmp(struct cpu_6809 *self, int lvalue) {
513 self->regs.word.pc = lvalue;
516 static ALWAYS_INLINE void cpu_6809_jsr(struct cpu_6809 *self, int lvalue) {
517 cpu_6809_push_word(self, &self->regs.word.s, self->regs.word.pc);
518 self->regs.word.pc = lvalue;
521 static ALWAYS_INLINE void cpu_6809_lbra(struct cpu_6809 *self, bool pred, int lvalue) {
523 self->cycles += ((self->regs.word.pc & 0xff) + (lvalue & 0xff)) >> 8;
524 self->regs.word.pc += lvalue;
528 static ALWAYS_INLINE void cpu_6809_lbsr(struct cpu_6809 *self, int lvalue) {
529 cpu_6809_push_word(self, &self->regs.word.s, self->regs.word.pc);
530 self->cycles += ((self->regs.word.pc & 0xff) + (lvalue & 0xff)) >> 8;
531 self->regs.word.pc += lvalue;
534 static ALWAYS_INLINE void cpu_6809_ld_word(struct cpu_6809 *self, int lvalue, int rvalue) {
535 cpu_6809_write_word(self, lvalue, rvalue);
537 self->regs.bit.nf = (rvalue >> 15) & 1;
538 self->regs.bit.zf = rvalue == 0;
539 self->regs.bit.vf = false;
542 static ALWAYS_INLINE void cpu_6809_ld_byte(struct cpu_6809 *self, int lvalue, int rvalue) {
543 cpu_6809_write_byte(self, lvalue, rvalue);
545 self->regs.bit.nf = (rvalue >> 7) & 1;
546 self->regs.bit.zf = rvalue == 0;
547 self->regs.bit.vf = false;
550 static ALWAYS_INLINE void cpu_6809_lea(struct cpu_6809 *self, int lvalue0, int lvalue1) {
551 cpu_6809_write_word(self, lvalue0, lvalue1);
554 static ALWAYS_INLINE void cpu_6809_lea_zf(struct cpu_6809 *self, int lvalue0, int lvalue1) {
555 cpu_6809_write_word(self, lvalue0, lvalue1);
557 self->regs.bit.zf = lvalue1 == 0;
560 static ALWAYS_INLINE void cpu_6809_lsr(struct cpu_6809 *self, int lvalue) {
561 int data = cpu_6809_read_byte(self, lvalue);
566 cpu_6809_write_byte(self, lvalue, result >> 1);
567 self->regs.bit.nf = result >> 8;
568 self->regs.bit.zf = (result & 0xfe) == 0;
569 self->regs.bit.cf = result & 1;
572 static ALWAYS_INLINE void cpu_6809_mul(struct cpu_6809 *self) {
576 static ALWAYS_INLINE void cpu_6809_neg(struct cpu_6809 *self, int lvalue) {
577 int data = cpu_6809_read_byte(self, lvalue);
579 int result0 = -(data & 0x7f);
580 int result1 = result0 - (data & 0x80);
582 cpu_6809_write_byte(self, lvalue, result1 & 0xff);
583 self->regs.bit.nf = (result1 >> 7) & 1;
584 self->regs.bit.zf = (result1 & 0xff) == 0;
585 self->regs.bit.vf = ((result0 >> 7) ^ (result1 >> 8)) & 1;
586 self->regs.bit.cf = (result1 >> 8) & 1;
589 static ALWAYS_INLINE void cpu_6809_nop(struct cpu_6809 *self) {
592 static ALWAYS_INLINE void cpu_6809_or(struct cpu_6809 *self, int lvalue, int rvalue) {
593 int result = cpu_6809_read_byte(self, lvalue) | rvalue;
595 cpu_6809_write_byte(self, lvalue, result);
596 self->regs.bit.nf = result >> 7;
597 self->regs.bit.zf = result == 0;
598 self->regs.bit.vf = false;
601 static ALWAYS_INLINE void cpu_6809_orcc(struct cpu_6809 *self, int rvalue) {
602 self->regs.byte.cc |= rvalue;
605 static ALWAYS_INLINE void cpu_6809_psh(struct cpu_6809 *self, int lvalue, int postbyte) {
606 uint16_t sp = cpu_6809_read_word(self, lvalue);
608 cpu_6809_push_word(self, &sp, self->regs.word.pc);
613 cpu_6809_read_word(self, lvalue ^ (CPU_6809_EA_U ^ CPU_6809_EA_S))
616 cpu_6809_push_word(self, &sp, self->regs.word.y);
618 cpu_6809_push_word(self, &sp, self->regs.word.x);
620 cpu_6809_push_byte(self, &sp, self->regs.byte.dp);
622 cpu_6809_push_byte(self, &sp, self->regs.byte.b);
624 cpu_6809_push_byte(self, &sp, self->regs.byte.a);
626 cpu_6809_push_byte(self, &sp, self->regs.byte.cc);
627 cpu_6809_write_word(self, lvalue, sp);
630 static ALWAYS_INLINE void cpu_6809_pul(struct cpu_6809 *self, int lvalue, int postbyte) {
631 uint16_t sp = cpu_6809_read_word(self, lvalue);
633 self->regs.byte.cc = cpu_6809_pop_byte(self, &sp);
635 self->regs.byte.a = cpu_6809_pop_byte(self, &sp);
637 self->regs.byte.b = cpu_6809_pop_byte(self, &sp);
639 self->regs.byte.dp = cpu_6809_pop_byte(self, &sp);
641 self->regs.word.x = cpu_6809_pop_word(self, &sp);
643 self->regs.word.y = cpu_6809_pop_word(self, &sp);
647 lvalue ^ (CPU_6809_EA_U ^ CPU_6809_EA_S),
648 cpu_6809_pop_word(self, &sp)
651 self->regs.word.pc = cpu_6809_pop_word(self, &sp);
652 cpu_6809_write_word(self, lvalue, sp);
655 static ALWAYS_INLINE void cpu_6809_rol(struct cpu_6809 *self, int lvalue) {
656 int result = self->regs.bit.cf | (cpu_6809_read_byte(self, lvalue) << 1);
659 cpu_6809_write_byte(self, lvalue, result & 0xff);
660 self->regs.bit.nf = (result >> 7) & 1;
661 self->regs.bit.zf = (result & 0xff) == 0;
662 self->regs.bit.vf = ((result >> 7) ^ (result >> 8)) & 1;
663 self->regs.bit.cf = result >> 8;
666 static ALWAYS_INLINE void cpu_6809_ror(struct cpu_6809 *self, int lvalue) {
667 int result = cpu_6809_read_byte(self, lvalue) | (self->regs.bit.cf << 8);
669 cpu_6809_write_byte(self, lvalue, result >> 1);
671 self->regs.bit.nf = result >> 8;
672 self->regs.bit.zf = (result & 0x1fe) == 0;
673 self->regs.bit.cf = result & 1;
676 static ALWAYS_INLINE void cpu_6809_rti(struct cpu_6809 *self) {
677 self->regs.byte.cc = cpu_6809_pop_byte(self, &self->regs.word.s);
678 self->regs.byte.b = cpu_6809_pop_byte(self, &self->regs.word.s);
679 self->regs.byte.a = cpu_6809_pop_byte(self, &self->regs.word.s);
680 self->regs.word.x = cpu_6809_pop_word(self, &self->regs.word.s);
681 self->regs.word.pc = cpu_6809_pop_word(self, &self->regs.word.s);
684 static ALWAYS_INLINE void cpu_6809_rts(struct cpu_6809 *self) {
685 self->regs.word.pc = cpu_6809_pop_word(self, &self->regs.word.s);
688 static ALWAYS_INLINE void cpu_6809_sbc(struct cpu_6809 *self, int lvalue, int rvalue) {
689 int data = cpu_6809_read_byte(self, lvalue);
691 int result0 = (data & 0x7f) - (rvalue & 0x7f) - self->regs.bit.cf;
692 int result1 = result0 + (data & 0x80) - (rvalue & 0x80);
694 cpu_6809_write_byte(self, lvalue, result1 & 0xff);
695 self->regs.bit.nf = (result1 >> 7) & 1;
696 self->regs.bit.zf = (result1 & 0xff) == 0;
697 self->regs.bit.vf = ((result0 >> 7) ^ (result1 >> 8)) & 1;
698 self->regs.bit.cf = (result1 >> 8) & 1;
701 static ALWAYS_INLINE void cpu_6809_sex(struct cpu_6809 *self) {
705 static ALWAYS_INLINE void cpu_6809_st_word(struct cpu_6809 *self, int rvalue, int lvalue) {
706 cpu_6809_write_word(self, lvalue, rvalue);
708 self->regs.bit.nf = (rvalue >> 15) & 1;
709 self->regs.bit.zf = rvalue == 0;
710 self->regs.bit.vf = false;
713 static ALWAYS_INLINE void cpu_6809_st_byte(struct cpu_6809 *self, int rvalue, int lvalue) {
714 cpu_6809_write_byte(self, lvalue, rvalue);
716 self->regs.bit.nf = (rvalue >> 7) & 1;
717 self->regs.bit.zf = rvalue == 0;
718 self->regs.bit.vf = false;
721 static ALWAYS_INLINE void cpu_6809_sub_byte(struct cpu_6809 *self, int lvalue, int rvalue) {
722 int data = cpu_6809_read_byte(self, lvalue);
724 int result0 = (data & 0x7f) - (rvalue & 0x7f);
725 int result1 = result0 + (data & 0x80) - (rvalue & 0x80);
727 cpu_6809_write_byte(self, lvalue, result1 & 0xff);
728 self->regs.bit.nf = (result1 >> 7) & 1;
729 self->regs.bit.zf = (result1 & 0xff) == 0;
730 self->regs.bit.vf = ((result0 >> 7) ^ (result1 >> 8)) & 1;
731 self->regs.bit.cf = (result1 >> 8) & 1;
734 static ALWAYS_INLINE void cpu_6809_sub_word(struct cpu_6809 *self, int lvalue, int rvalue) {
735 int data = cpu_6809_read_word(self, lvalue);
737 int result0 = (data & 0x7fff) - (rvalue & 0x7fff);
738 int result1 = result0 + (data & 0x8000) - (rvalue & 0x8000);
740 cpu_6809_write_word(self, lvalue, result1 & 0xffff);
741 self->regs.bit.nf = (result1 >> 15) & 1;
742 self->regs.bit.zf = (result1 & 0xffff) == 0;
743 self->regs.bit.vf = ((result0 >> 15) ^ (result1 >> 16)) & 1;
744 self->regs.bit.cf = (result1 >> 16) & 1;
747 static ALWAYS_INLINE void cpu_6809_swi(struct cpu_6809 *self) {
748 cpu_6809_push_word(self, &self->regs.word.s, self->regs.word.pc);
749 cpu_6809_push_word(self, &self->regs.word.s, self->regs.word.x);
750 cpu_6809_push_byte(self, &self->regs.word.s, self->regs.byte.a);
751 cpu_6809_push_byte(self, &self->regs.word.s, self->regs.byte.b);
752 cpu_6809_push_byte(self, &self->regs.word.s, self->regs.byte.cc);
753 self->regs.word.pc = cpu_6809_read_word(self, CPU_6809_SWI_VECTOR);
754 self->regs.bit._if = true;
757 static ALWAYS_INLINE void cpu_6809_swi_n(struct cpu_6809 *self, int n) {
758 cpu_6809_push_word(self, &self->regs.word.s, self->regs.word.pc);
759 cpu_6809_push_word(self, &self->regs.word.s, self->regs.word.x);
760 cpu_6809_push_byte(self, &self->regs.word.s, self->regs.byte.a);
761 cpu_6809_push_byte(self, &self->regs.word.s, self->regs.byte.b);
762 cpu_6809_push_byte(self, &self->regs.word.s, self->regs.byte.cc);
763 self->regs.word.pc = cpu_6809_read_word(self, CPU_6809_SWI_VECTOR);
764 self->regs.bit._if = true;
767 static ALWAYS_INLINE void cpu_6809_sync(struct cpu_6809 *self) {
771 static ALWAYS_INLINE void cpu_6809_tfr(struct cpu_6809 *self, int postbyte) {
772 int reg0 = postbyte >> 4;
773 int reg1 = postbyte & 0xf;
777 cpu_6809_ea_dest[reg1][0],
778 cpu_6809_read_byte(self, cpu_6809_ea_src[reg0][0])
782 cpu_6809_ea_dest[reg1][1],
783 cpu_6809_read_byte(self, cpu_6809_ea_src[reg0][1])
787 static ALWAYS_INLINE void cpu_6809_tst(struct cpu_6809 *self, int rvalue) {
788 self->regs.bit.nf = (rvalue >> 7) & 1;
789 self->regs.bit.zf = rvalue == 0;
790 self->regs.bit.vf = false;
795 struct cpu_6809 *self,
796 int (*read_byte)(void *context, int addr),
797 void *read_byte_context,
798 void (*write_byte)(void *context, int addr, int data),
799 void *write_byte_context
801 void cpu_6809_reset(struct cpu_6809 *self);
802 int cpu_6809_addressing_mode(struct cpu_6809 *self);
803 void cpu_6809_execute(struct cpu_6809 *self);
804 void cpu_6809_execute_10(struct cpu_6809 *self);
805 void cpu_6809_execute_11(struct cpu_6809 *self);