static void subx_l(struct cpu *cpu, WORD op) { LONG s,d,r; int rx,ry; rx = (op&0xe00)>>9; ry = op&0x7; if(op&0x8) { cpu->a[ry] -= 4; s = bus_read_long(cpu->a[ry]); cpu->a[rx] -= 4; d = bus_read_long(cpu->a[rx]); r = d-s; if(CHKX) r -= 1; bus_write_long(cpu->a[rx], r); ADD_CYCLE(30); } else { s = cpu->d[ry]; d = cpu->d[rx]; r = d-s; if(CHKX) r -= 1; cpu->d[rx] = r; ADD_CYCLE(8); } cpu_set_flags_subx(cpu, s&0x80000000, d&0x80000000, r&0x80000000, r); }
static void subx_w(struct cpu *cpu, WORD op) { WORD s,d,r; int rx,ry; rx = (op&0xe00)>>9; ry = op&0x7; if(op&0x8) { cpu->a[ry] -= 2; s = bus_read_word(cpu->a[ry]); cpu->a[rx] -= 2; d = bus_read_word(cpu->a[rx]); r = d-s; if(CHKX) r -= 1; bus_write_word(cpu->a[rx], r); ADD_CYCLE(18); } else { s = cpu->d[ry]&0xffff; d = cpu->d[rx]&0xffff; r = d-s; if(CHKX) r -= 1; cpu->d[rx] = (cpu->d[rx]&0xffff0000)|r; ADD_CYCLE(4); } cpu_set_flags_subx(cpu, s&0x8000, d&0x8000, r&0x8000, r); }
static void addq(struct cpu *cpu, WORD op) { int s; ENTER; s = (op&0xe00)>>9; if(!s) s = 8; if(((op&0x38)>>3) == 1) { if(op&0x80) { ADD_CYCLE(8); } else { ADD_CYCLE(4); } cpu->a[op&7] += s; return; } if(op&0x38) { ADD_CYCLE(4); } switch((op&0xc0)>>6) { case 0: addq_b(cpu, s, op&0x3f); return; case 1: addq_w(cpu, s, op&0x3f); return; case 2: addq_l(cpu, s, op&0x3f); return; } }
static void not_l(struct cpu *cpu, WORD op) { LONG r; ADD_CYCLE(6); if(op&0x38) { ADD_CYCLE(6); } r = ~ea_read_long(cpu, op&0x3f, 1); ea_set_prefetch_before_write(); ea_write_long(cpu, op&0x3f, r); cpu_set_flags_move(cpu, r&0x80000000, r); }
static void not_b(struct cpu *cpu, WORD op) { BYTE r; ADD_CYCLE(4); if(op&0x38) { ADD_CYCLE(4); } r = ~ea_read_byte(cpu, op&0x3f, 1); ea_set_prefetch_before_write(); ea_write_byte(cpu, op&0x3f, r); cpu_set_flags_move(cpu, r&0x80, r); }
static void nop(struct cpu *cpu, WORD op) { ENTER; ADD_CYCLE(4); cpu_prefetch(); }
static void negx_l(struct cpu *cpu, WORD op) { LONG d,r; d = ea_read_long(cpu, op&0x3f, 1); r = 0-d; if(CHKX) r -= 1; ea_set_prefetch_before_write(); ea_write_long(cpu, op&0x3f, r); ADD_CYCLE(6); if(op&0x38) { ADD_CYCLE(6); } cpu_set_flags_negx(cpu, d&0x80000000, r&0x80000000, r); }
static void negx_b(struct cpu *cpu, WORD op) { BYTE d,r; d = ea_read_byte(cpu, op&0x3f, 1); r = 0-d; if(CHKX) r -= 1; ea_set_prefetch_before_write(); ea_write_byte(cpu, op&0x3f, r); ADD_CYCLE(4); if(op&0x38) { ADD_CYCLE(4); } cpu_set_flags_negx(cpu, d&0x80, r&0x80, r); }
static void subi_l(struct cpu *cpu, WORD op) { LONG s,d,r; s = bus_read_long(cpu->pc); cpu->pc += 4; if(op&0x38) { ADD_CYCLE(20); } else { ADD_CYCLE(16); } d = ea_read_long(cpu, op&0x3f, 1); r = d-s; ea_set_prefetch_before_write(); ea_write_long(cpu, op&0x3f, r); cpu_set_flags_sub(cpu, s&0x80000000, d&0x80000000, r&0x80000000, r); }
static void movep(struct cpu *cpu, WORD op) { LONG d,a; int dr,ar; ENTER; ar = op&0x7; dr = (op&0xe00)>>9; a = bus_read_word(cpu->pc); if(a&0x8000) a |= 0xffff0000; a += cpu->a[ar]; cpu->pc += 2; switch((op&0xc0)>>6) { case 0: d = (bus_read_byte(a)<<8)|bus_read_byte(a+2); cpu->d[dr] = (cpu->d[dr]&0xffff0000)|(d&0xffff); ADD_CYCLE(16); return; case 1: d = ((bus_read_byte(a)<<24)| (bus_read_byte(a+2)<<16)| (bus_read_byte(a+4)<<8)| (bus_read_byte(a+6))); cpu->d[dr] = d; ADD_CYCLE(24); return; case 2: d = cpu->d[dr]&0xffff; cpu_prefetch(); bus_write_byte(a, (BYTE)((d&0xff00)>>8)); bus_write_byte(a+2, (BYTE)((d&0xff))); ADD_CYCLE(16); return; case 3: d = cpu->d[dr]; cpu_prefetch(); bus_write_byte(a, (BYTE)((d&0xff000000)>>24)); bus_write_byte(a+2, (BYTE)((d&0xff0000)>>16)); bus_write_byte(a+4, (BYTE)((d&0xff00)>>8)); bus_write_byte(a+6, (BYTE)((d&0xff))); ADD_CYCLE(24); return; } }
static void tst_w(struct cpu *cpu, WORD op) { WORD s; s = ea_read_word(cpu, op&0x3f, 0); cpu_set_flags_move(cpu, s&0x8000, s); ADD_CYCLE(4); }
static void tst_l(struct cpu *cpu, WORD op) { LONG s; s = ea_read_long(cpu, op&0x3f, 0); cpu_set_flags_move(cpu, s&0x80000000, s); ADD_CYCLE(4); }
static void addi_w(struct cpu *cpu, WORD op) { WORD s,d,r; s = bus_read_word(cpu->pc); cpu->pc += 2; if(op&0x38) { ADD_CYCLE(12); } else { ADD_CYCLE(8); } d = ea_read_word(cpu, op&0x3f, 1); r = d+s; ea_set_prefetch_before_write(); ea_write_word(cpu, op&0x3f, r); cpu_set_flags_add(cpu, s&0x8000, d&0x8000, r&0x8000, r); }
static void tst_b(struct cpu *cpu, WORD op) { BYTE s; s = ea_read_byte(cpu, op&0x3f, 0); cpu_set_flags_move(cpu, s&0x80, s); ADD_CYCLE(4); }
static void move_from_sr(struct cpu *cpu, WORD op) { ENTER; ADD_CYCLE(8); /* really 6 for EA==reg, but that will be 8 anyway */ ea_set_prefetch_before_write(); ea_write_word(cpu, op&0x3f, cpu->sr); }
static void subi_b(struct cpu *cpu, WORD op) { BYTE s,d,r; s = bus_read_word(cpu->pc)&0xff; cpu->pc += 2; if(op&0x38) { ADD_CYCLE(12); } else { ADD_CYCLE(8); } d = ea_read_byte(cpu, op&0x3f, 1); r = d-s; ea_set_prefetch_before_write(); ea_write_byte(cpu, op&0x3f, r); cpu_set_flags_sub(cpu, s&0x80, d&0x80, r&0x80, r); }
static void bset_r(struct cpu *cpu, int reg, int mode) { BYTE b,d; b = cpu->d[reg]&31; if(mode&0x38) { ADD_CYCLE(4); d = ea_read_byte(cpu, mode, 1); if(d & (1<<(b&7))) CLRZ; else SETZ; d |= (1<<(b&7)); ea_set_prefetch_before_write(); ea_write_byte(cpu, mode, d); } else { ADD_CYCLE(6); if(cpu->d[mode&7] & (1<<b)) CLRZ; else SETZ; cpu->d[mode&7] |= (1<<b); } }
static void jmp(struct cpu *cpu, WORD op) { ENTER; ADD_CYCLE(4); cpu->cyclecomp = 1; cpu->pc = ea_get_addr(cpu, op&0x3f); cprint_set_label(cpu->pc, NULL); cpu_prefetch(); }
static void adda(struct cpu *cpu, WORD op) { LONG s; int r; ENTER; r = (op&0xe00)>>9; if(op&0x100) { ADD_CYCLE(6); s = ea_read_long(cpu, op&0x3f, 0); } else { ADD_CYCLE(8); s = ea_read_word(cpu, op&0x3f, 0); if(s&0x8000) s |= 0xffff0000; } cpu->a[r] += s; }
static void bset_i(struct cpu *cpu, int mode) { BYTE b,d; b = (BYTE)bus_read_word(cpu->pc)&0xff; b &= 31; cpu->pc += 2; if(mode&0x38) { ADD_CYCLE(8); d = ea_read_byte(cpu, mode, 1); if(d & (1<<(b&7))) CLRZ; else SETZ; d |= (1<<(b&7)); ea_set_prefetch_before_write(); ea_write_byte(cpu, mode, d); } else { ADD_CYCLE(10); if(cpu->d[mode&7] & (1<<b)) CLRZ; else SETZ; cpu->d[mode&7] |= (1<<b); } }
static void swap(struct cpu *cpu, WORD op) { int r; r = op&0x7; cpu->d[r] = ((cpu->d[r]&0xffff0000)>>16)|((cpu->d[r]&0xffff)<<16); ADD_CYCLE(4); cpu_set_flags_move(cpu, cpu->d[r]&0x80000000, cpu->d[r]); cpu_prefetch(); }
static void addq_w(struct cpu *cpu, int s, int mode) { WORD d,r; d = ea_read_word(cpu, mode, 1); r = s+d; ea_write_word(cpu, mode, r); ADD_CYCLE(4); cpu_set_flags_add(cpu, 0, d&0x8000, r&0x8000, r); }
static void addq_l(struct cpu *cpu, int s, int mode) { LONG d,r; d = ea_read_long(cpu, mode, 1); r = s+d; ea_write_long(cpu, mode, r); ADD_CYCLE(8); cpu_set_flags_add(cpu, 0, d&0x80000000, r&0x80000000, r); }
static void addq_b(struct cpu *cpu, int s, int mode) { BYTE d,r; d = ea_read_byte(cpu, mode, 1); r = s+d; ea_write_byte(cpu, mode, r); ADD_CYCLE(4); cpu_set_flags_add(cpu, 0, d&0x80, r&0x80, r); }
static void mulu(struct cpu *cpu, WORD op) { LONG s,d,r; int reg; int i; ENTER; s = ea_read_word(cpu, op&0x3f, 0); reg = (op&0xe00)>>9; d = cpu->d[reg]&0xffff; r = s*d; cpu->d[reg] = r; ADD_CYCLE(38); for(i=0;i<16;i++) { if(s&(1<<i)) { ADD_CYCLE(2); } } cpu_set_flags_move(cpu, r&0x80000000, r); }
static void ori_to_ccr(struct cpu *cpu, WORD op) { WORD d; ENTER; ADD_CYCLE(20); d = bus_read_word(cpu->pc)&0x1f; cpu->pc += 2; cpu_set_sr(cpu->sr|d); cpu_prefetch(); }
static void subx_b(struct cpu *cpu, WORD op) { BYTE s,d,r; int rx,ry; rx = (op&0xe00)>>9; ry = op&0x7; if(op&0x8) { if(ry == 7) cpu->a[ry] -= 2; else cpu->a[ry] -= 1; s = bus_read_byte(cpu->a[ry]); if(rx == 7) cpu->a[rx] -= 2; else cpu->a[rx] -= 1; d = bus_read_byte(cpu->a[rx]); r = d-s; if(CHKX) r -= 1; cpu_prefetch(); bus_write_byte(cpu->a[rx], r); ADD_CYCLE(18); } else { s = cpu->d[ry]&0xff; d = cpu->d[rx]&0xff; r = d-s; if(CHKX) r -= 1; cpu->d[rx] = (cpu->d[rx]&0xffffff00)|r; ADD_CYCLE(4); } cpu_set_flags_subx(cpu, s&0x80, d&0x80, r&0x80, r); }
static void unlk(struct cpu *cpu, WORD op) { int r; ENTER; r = op&0x7; cpu->a[7] = cpu->a[r]; cpu->a[r] = bus_read_long(cpu->a[7]); cpu->a[7] += 4; ADD_CYCLE(12); cpu_prefetch(); }
static void andi_to_sr(struct cpu *cpu, WORD op) { WORD d; ENTER; if(cpu->sr&0x2000) { ADD_CYCLE(20); d = bus_read_word(cpu->pc); cpu->pc += 2; cpu_set_sr(cpu->sr&d); cpu->tracedelay = 1; } else { cpu_set_exception(8); /* Privilege violation */ } }
static void cmpm_l(struct cpu *cpu, WORD op) { int rx,ry; LONG s,d,r; rx = (op&0xe00)>>9; ry = op&0x7; s = bus_read_long(cpu->a[ry]); cpu->a[ry] += 4; d = bus_read_long(cpu->a[rx]); cpu->a[rx] += 4; r = d-s; ADD_CYCLE(20); cpu_set_flags_cmp(cpu, s&0x80000000, d&0x80000000, r&0x80000000, r); }