/* * ============================================================================ * OP_EXEC: Execute functions for the CP-1610 instructions * * Author: J. Zbiciak * * $Id: op_exec.c,v 1.21 2001/02/26 12:18:49 im14u2c Exp $ * * ============================================================================ * fn_invalid -- Executed when a decoder failure happens * fn_XXXX_i -- Immediate operand instructions (relative branch, jump) * fn_XXXX_r -- Implied, register 2-ops (eg. ADCR, COMR, etc.) * fn_XXXX_ir -- Immediate, register 2-ops, JSR * fn_XXXX_Ir -- Immediate (no DBD), register 2-ops, JSR * fn_XXXX_rr -- Register, register 2-ops * fn_XXXX_dr -- Direct, register 2-ops * fn_XXXX_mr -- Indirect ("memory"), register 2-ops, non-incrementing * fn_XXXX_nr -- Indirect (no DBD), register 2-ops, non-incrementing * fn_XXXX_Mr -- Indirect ("memory"), register 2-ops, post-incrementing * fn_XXXX_Nr -- Indirect (no DBD), register 2-ops, post-incrementing * fn_XXXX_Sr -- Indirect ("stack"), register 2-ops, pre-decrementing * ============================================================================ */ #include "config.h" #include "periph/periph.h" #include "cp1600/cp1600.h" #include "cp1600/op_decode.h" #include "cp1600/op_exec.h" #include "cp1600/emu_link.h" #include int first_dis = -1; int last_dis = -1; int fn_invalid (const instr_t *instr, cp1600_t *cp1600) { jzp_printf("Invalid opcode @ 0x%.4X : %.4X %.4X %.4X\n", instr->address, CP1600_RD(cp1600, instr->address + 0), CP1600_RD(cp1600, instr->address + 1), CP1600_RD(cp1600, instr->address + 2)); cp1600->r[7]++; return 0; } int fn_breakpt (const instr_t *instr, cp1600_t *cp1600) { uint_32 flags = instr->opcode.breakpt.flags; cp1600->hit_bkpt = flags & CP1600_BKPT_ONCE ? 2 : 1; cp1600->D <<= 1; flags &= ~CP1600_BKPT_ONCE; cp1600->execute[cp1600->r[7]] = flags ? fn_decode_bkpt : fn_decode; /* ugly */ cp1600->instr[cp1600->r[7]]->opcode.breakpt.flags = flags; return CYC_MAX; } int fn_BEXT_i (const instr_t *instr, cp1600_t *cp1600) { int taken; cp1600->r[7] += 2; taken = cp1600->ext == instr->opcode.decoded.imm1; if (taken) cp1600->r[7] = instr->opcode.decoded.imm0; return 7 + (taken << 1); } /* "Positive" versions of branches */ int fn_B_i (const instr_t *instr, cp1600_t *cp1600) { cp1600->r[7] += 2; cp1600->r[7] = instr->opcode.decoded.imm0; return 9; } int fn_BOV_i (const instr_t *instr, cp1600_t *cp1600) { int taken; cp1600->r[7] += 2; /* O = 1 */ taken = cp1600->O; if (taken) cp1600->r[7] = instr->opcode.decoded.imm0; return 7 + (taken << 1); } int fn_BC_i (const instr_t *instr, cp1600_t *cp1600) { int taken; cp1600->r[7] += 2; /* C = 1 */ taken = cp1600->C; if (taken) cp1600->r[7] = instr->opcode.decoded.imm0; return 7 + (taken << 1); } int fn_BPL_i (const instr_t *instr, cp1600_t *cp1600) { int taken; cp1600->r[7] += 2; /* S = 0 */ taken = !cp1600->S; if (taken) cp1600->r[7] = instr->opcode.decoded.imm0; return 7 + (taken << 1); } int fn_BEQ_i (const instr_t *instr, cp1600_t *cp1600) { int taken; cp1600->r[7] += 2; /* Z = 1 */ taken = cp1600->Z; if (taken) cp1600->r[7] = instr->opcode.decoded.imm0; return 7 + (taken << 1); } int fn_BLT_i (const instr_t *instr, cp1600_t *cp1600) { int taken; cp1600->r[7] += 2; /* S ^ O = 1 */ taken = cp1600->S ^ cp1600->O; if (taken) cp1600->r[7] = instr->opcode.decoded.imm0; return 7 + (taken << 1); } int fn_BLE_i (const instr_t *instr, cp1600_t *cp1600) { int taken; cp1600->r[7] += 2; /* Z | S ^ O = 1 */ taken = (cp1600->Z | (cp1600->S ^ cp1600->O)); if (taken) cp1600->r[7] = instr->opcode.decoded.imm0; return 7 + (taken << 1); } int fn_BUSC_i (const instr_t *instr, cp1600_t *cp1600) { int taken; cp1600->r[7] += 2; /* C ^ S = 1 */ taken = cp1600->C ^ cp1600->S; if (taken) cp1600->r[7] = instr->opcode.decoded.imm0; return 7 + (taken << 1); } /* "Negative" versions of branches. */ int fn_NOPP_i (const instr_t *instr, cp1600_t *cp1600) { cp1600->r[7] += 2; UNUSED(instr); return 7; } int fn_BNOV_i (const instr_t *instr, cp1600_t *cp1600) { int taken; cp1600->r[7] += 2; /* O = 0 */ taken = !cp1600->O; if (taken) cp1600->r[7] = instr->opcode.decoded.imm0; return 7 + (taken << 1); } int fn_BNC_i (const instr_t *instr, cp1600_t *cp1600) { int taken; cp1600->r[7] += 2; /* C = 0 */ taken = !cp1600->C; if (taken) cp1600->r[7] = instr->opcode.decoded.imm0; return 7 + (taken << 1); } int fn_BMI_i (const instr_t *instr, cp1600_t *cp1600) { int taken; cp1600->r[7] += 2; /* S = 1 */ taken = cp1600->S; if (taken) cp1600->r[7] = instr->opcode.decoded.imm0; return 7 + (taken << 1); } int fn_BNEQ_i (const instr_t *instr, cp1600_t *cp1600) { int taken; cp1600->r[7] += 2; /* Z = 0 */ taken = !cp1600->Z; if (taken) cp1600->r[7] = instr->opcode.decoded.imm0; return 7 + (taken << 1); } int fn_BGE_i (const instr_t *instr, cp1600_t *cp1600) { int taken; cp1600->r[7] += 2; /* S ^ O = 0 */ taken = !(cp1600->S ^ cp1600->O); if (taken) cp1600->r[7] = instr->opcode.decoded.imm0; return 7 + (taken << 1); } int fn_BGT_i (const instr_t *instr, cp1600_t *cp1600) { int taken; cp1600->r[7] += 2; /* Z | (S ^ O) = 0 */ taken = !(cp1600->Z | (cp1600->S ^ cp1600->O)); if (taken) cp1600->r[7] = instr->opcode.decoded.imm0; return 7 + (taken << 1); } int fn_BESC_i (const instr_t *instr, cp1600_t *cp1600) { int taken; cp1600->r[7] += 2; /* C ^ S = 0 */ taken = cp1600->C == cp1600->S; if (taken) cp1600->r[7] = instr->opcode.decoded.imm0; return 7 + (taken << 1); } int fn_SIN_i (const instr_t *instr, cp1600_t *cp1600) { cp1600->r[7]++; /* XXX: does SIN need to do anything?! */ if (cp1600->r[0] == 0x656D && cp1600->r[1] == 0x753F) { cp1600->r[0] = 0x4A5A; cp1600->r[1] = JZINTV_VERSION; cp1600->C = 0; return 6; } /* We use it as a hook for emulator-specific functionality. */ emu_link_dispatch(cp1600); UNUSED(instr); /*cp1600->intr = 0;*/ return 6; } int fn_NOP_i (const instr_t *instr, cp1600_t *cp1600) { cp1600->r[7]++; UNUSED(instr); /*cp1600->intr = 0;*/ return 6; } int fn_J_i (const instr_t *instr, cp1600_t *cp1600) { int intr = instr->opcode.decoded.imm1; if (intr) cp1600->I = cp1600->intr = intr & 1; cp1600->r[7] = instr->opcode.decoded.imm0; return 13; } int fn_JSR_ir (const instr_t *instr, cp1600_t *cp1600) { int intr = instr->opcode.decoded.imm1; if (intr) cp1600->I = cp1600->intr = intr & 1; cp1600->r[instr->opcode.decoded.reg0] = cp1600->r[7] + 3; cp1600->r[7] = instr->opcode.decoded.imm0; return 13; } #define ADD_SZOC(a,b,c,cp1600) \ do { \ uint_32 op1 = (a); \ uint_32 op2 = (b); \ uint_32 op3; \ uint_16 res; \ op3 = op2 + op1; \ res = (uint_16)op3; \ (cp1600)->S = !!(op3 & 0x8000); \ (cp1600)->C = !!(op3 & 0x10000); \ (cp1600)->O = !!((op2^op3) & ~(op1^op2) & 0x8000); \ (cp1600)->Z = !res; \ (c) = res; \ } while(0); #define SUB_SZOC(a,b,c,cp1600) \ do { \ uint_32 op1 = (a); \ uint_32 op2 = (b); \ uint_32 op3; \ uint_16 res; \ op3 = op2 + (0xFFFF ^ op1) + 1; \ res = (uint_16)op3; \ (cp1600)->S = !!(op3 & 0x8000); \ (cp1600)->C = !!(op3 & 0x10000); \ (cp1600)->O = !!((op2^op3) & (op1^op2) & 0x8000); \ (cp1600)->Z = !res; \ (c) = res; \ } while(0); #define EXEC_SZ(a,b,c,o,cp1600) \ do { \ uint_32 op1 = (a); \ uint_32 op2 = (b); \ uint_32 op3; \ uint_16 res; \ op3 = op2 o op1; \ res = (uint_16)op3; \ (cp1600)->S = !!(op3 & 0x8000); \ (cp1600)->Z = !res; \ (c) = res; \ } while(0); #define NEG(x) (0x10000-(uint_32)(x)) #define EXTRA_IF_R6R7(r) ((instr->opcode.decoded.r) >= 6) int fn_MVO_dr (const instr_t *instr, cp1600_t *cp1600) { uint_16 addr = instr->opcode.decoded.imm0; cp1600->r[7] += 2; CP1600_WR(cp1600, addr, cp1600->r[instr->opcode.decoded.reg0]); cp1600->intr = 0; return 11; } int fn_MVI_dr (const instr_t *instr, cp1600_t *cp1600) { uint_16 addr = instr->opcode.decoded.imm0; cp1600->r[7] += 2; cp1600->r[instr->opcode.decoded.reg0] = CP1600_RD(cp1600, addr); return 10 + EXTRA_IF_R6R7(reg0); } int fn_ADD_dr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = instr->opcode.decoded.imm0; cp1600->r[7] += 2; r0 = CP1600_RD(cp1600,addr); r1 = cp1600->r[instr->opcode.decoded.reg0]; ADD_SZOC(r0,r1,r2,cp1600); cp1600->r[instr->opcode.decoded.reg0] = r2; return 10 + EXTRA_IF_R6R7(reg0); } int fn_SUB_dr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = instr->opcode.decoded.imm0; cp1600->r[7] += 2; r0 = CP1600_RD(cp1600,addr); r1 = cp1600->r[instr->opcode.decoded.reg0]; SUB_SZOC(r0,r1,r2,cp1600); cp1600->r[instr->opcode.decoded.reg0] = r2; return 10 + EXTRA_IF_R6R7(reg0); } int fn_CMP_dr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = instr->opcode.decoded.imm0; cp1600->r[7] += 2; r0 = CP1600_RD(cp1600,addr); r1 = cp1600->r[instr->opcode.decoded.reg0]; SUB_SZOC(r0,r1,r2,cp1600); UNUSED(r2); return 10 + EXTRA_IF_R6R7(reg0); } int fn_AND_dr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = instr->opcode.decoded.imm0; cp1600->r[7] += 2; r0 = CP1600_RD(cp1600,addr); r1 = cp1600->r[instr->opcode.decoded.reg0]; EXEC_SZ(r0,r1,r2,&,cp1600); cp1600->r[instr->opcode.decoded.reg0] = r2; return 10 + EXTRA_IF_R6R7(reg0); } int fn_XOR_dr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = instr->opcode.decoded.imm0; cp1600->r[7] += 2; r0 = CP1600_RD(cp1600,addr); r1 = cp1600->r[instr->opcode.decoded.reg0]; EXEC_SZ(r0,r1,r2,^,cp1600); cp1600->r[instr->opcode.decoded.reg0] = r2; return 10 + EXTRA_IF_R6R7(reg0); } #define DBDI(d,i) ((d)?(i)->opcode.decoded.imm1:(i)->opcode.decoded.imm0) int fn_MVO_ir (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0; cp1600->r[7] += 2 + cp1600->D; r0 = cp1600->r[instr->opcode.decoded.reg0]; if (cp1600->D) { jzp_printf("WARNING: MVO@ w/ SDBD prefix @ %.4X\n", instr->address); /* CP1600_WR(cp1600, instr->address+1, (r0 & 0xFF)); CP1600_WR(cp1600, instr->address+2, (r0 >> 8)); */ CP1600_WR(cp1600, instr->address+1, r0); } else { CP1600_WR(cp1600, instr->address+1, r0); } cp1600->intr = 0; return 9; } int fn_MVI_ir (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0; int d = cp1600->D; cp1600->r[7] += 2 + d; r0 = DBDI(d,instr); cp1600->r[instr->opcode.decoded.reg0] = r0; return (d ? 10 : 8) + EXTRA_IF_R6R7(reg0); } int fn_ADD_ir (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; int d = cp1600->D; cp1600->r[7] += 2 + cp1600->D; r0 = DBDI(d,instr); r1 = cp1600->r[instr->opcode.decoded.reg0]; ADD_SZOC(r0,r1,r2,cp1600); cp1600->r[instr->opcode.decoded.reg0] = r2; return (d ? 10 : 8) + EXTRA_IF_R6R7(reg0); } int fn_SUB_ir (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; int d = cp1600->D; cp1600->r[7] += 2 + cp1600->D; r0 = DBDI(d,instr); r1 = cp1600->r[instr->opcode.decoded.reg0]; SUB_SZOC(r0,r1,r2,cp1600); cp1600->r[instr->opcode.decoded.reg0] = r2; return (d ? 10 : 8) + EXTRA_IF_R6R7(reg0); } int fn_CMP_ir (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; int d = cp1600->D; cp1600->r[7] += 2 + cp1600->D; r0 = DBDI(d,instr); r1 = cp1600->r[instr->opcode.decoded.reg0]; SUB_SZOC(r0,r1,r2,cp1600); UNUSED(r2); return (d ? 10 : 8) + EXTRA_IF_R6R7(reg0); } int fn_AND_ir (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; int d = cp1600->D; cp1600->r[7] += 2 + cp1600->D; r0 = DBDI(d,instr); r1 = cp1600->r[instr->opcode.decoded.reg0]; EXEC_SZ(r0,r1,r2,&,cp1600); cp1600->r[instr->opcode.decoded.reg0] = r2; return (d ? 10 : 8) + EXTRA_IF_R6R7(reg0); } int fn_XOR_ir (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; int d = cp1600->D; cp1600->r[7] += 2 + cp1600->D; r0 = DBDI(d,instr); r1 = cp1600->r[instr->opcode.decoded.reg0]; EXEC_SZ(r0,r1,r2,^,cp1600); cp1600->r[instr->opcode.decoded.reg0] = r2; return (d ? 10 : 8) + EXTRA_IF_R6R7(reg0); } int fn_MVO_Ir (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0; cp1600->r[7] += 2; r0 = cp1600->r[instr->opcode.decoded.reg0]; CP1600_WR(cp1600, instr->address+1, r0); cp1600->intr = 0; return 9; } int fn_MVI_Ir (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0; cp1600->r[7] += 2; r0 = instr->opcode.decoded.imm0; cp1600->r[instr->opcode.decoded.reg0] = r0; return 8 + EXTRA_IF_R6R7(reg0); } int fn_ADD_Ir (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; cp1600->r[7] += 2; r0 = instr->opcode.decoded.imm0; r1 = cp1600->r[instr->opcode.decoded.reg0]; ADD_SZOC(r0,r1,r2,cp1600); cp1600->r[instr->opcode.decoded.reg0] = r2; return 8 + EXTRA_IF_R6R7(reg0); } int fn_SUB_Ir (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; cp1600->r[7] += 2; r0 = instr->opcode.decoded.imm0; r1 = cp1600->r[instr->opcode.decoded.reg0]; SUB_SZOC(r0,r1,r2,cp1600); cp1600->r[instr->opcode.decoded.reg0] = r2; return 8 + EXTRA_IF_R6R7(reg0); } int fn_CMP_Ir (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; cp1600->r[7] += 2; r0 = instr->opcode.decoded.imm0; r1 = cp1600->r[instr->opcode.decoded.reg0]; SUB_SZOC(r0,r1,r2,cp1600); UNUSED(r2); return 8 + EXTRA_IF_R6R7(reg0); } int fn_AND_Ir (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; cp1600->r[7] += 2; r0 = instr->opcode.decoded.imm0; r1 = cp1600->r[instr->opcode.decoded.reg0]; EXEC_SZ(r0,r1,r2,&,cp1600); cp1600->r[instr->opcode.decoded.reg0] = r2; return 8 + EXTRA_IF_R6R7(reg0); } int fn_XOR_Ir (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; cp1600->r[7] += 2; r0 = instr->opcode.decoded.imm0; r1 = cp1600->r[instr->opcode.decoded.reg0]; EXEC_SZ(r0,r1,r2,^,cp1600); cp1600->r[instr->opcode.decoded.reg0] = r2; return 8 + EXTRA_IF_R6R7(reg0); } int fn_HLT (const instr_t *instr, cp1600_t *cp1600) { /* XXX: Uhm... NOP for now? */ cp1600->r[7]++; UNUSED(instr); jzp_printf("HALT! PC=%.4X Instr = %10lu MS = %10lu\n", cp1600->r[7], (unsigned long)cp1600->tot_instr, (unsigned long)cp1600->tot_cycle); //dump_state(); if (cp1600->instr_tick) cp1600->instr_tick(cp1600->instr_tick_periph, (unsigned)-CYC_MAX); else exit(1); return 1; } int fn_TCI (const instr_t *instr, cp1600_t *cp1600) { /* XXX: Uhm... NOP for now? */ cp1600->r[7]++; cp1600->intr = 0; UNUSED(instr); return 4; } int fn_SDBD (const instr_t *instr, cp1600_t *cp1600) { cp1600->r[7]++; cp1600->D = 2; cp1600->intr = 0; UNUSED(instr); return 4; } int fn_EIS (const instr_t *instr, cp1600_t *cp1600) { cp1600->r[7]++; cp1600->I = 1; cp1600->intr = 0; UNUSED(instr); first_dis = last_dis = -1; return 4; } int fn_DIS (const instr_t *instr, cp1600_t *cp1600) { cp1600->r[7]++; if (cp1600->I) first_dis = cp1600->r[7]; last_dis = cp1600->r[7]; cp1600->I = 0; cp1600->intr = 0; UNUSED(instr); return 4; } int fn_CLRC (const instr_t *instr, cp1600_t *cp1600) { cp1600->r[7]++; cp1600->C = 0; cp1600->intr = 0; UNUSED(instr); return 4; } int fn_SETC (const instr_t *instr, cp1600_t *cp1600) { cp1600->r[7]++; cp1600->C = 1; cp1600->intr = 0; UNUSED(instr); return 4; } int fn_INCR_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = 1; EXEC_SZ(r0,r1,r2,+,cp1600); cp1600->r[instr->opcode.decoded.reg0] = r2; return 6 + EXTRA_IF_R6R7(reg0); } int fn_DECR_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; cp1600->r[7]++; r0 = 1; r1 = cp1600->r[instr->opcode.decoded.reg0]; EXEC_SZ(r0,r1,r2,-,cp1600); cp1600->r[instr->opcode.decoded.reg0] = r2; return 6 + EXTRA_IF_R6R7(reg0); } int fn_COMR_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; cp1600->r[7]++; r0 = 0xFFFF; r1 = cp1600->r[instr->opcode.decoded.reg0]; EXEC_SZ(r0,r1,r2,^,cp1600); cp1600->r[instr->opcode.decoded.reg0] = r2; return 6 + EXTRA_IF_R6R7(reg0); } int fn_NEGR_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0, r2; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0]; SUB_SZOC(r0,0,r2,cp1600); cp1600->r[instr->opcode.decoded.reg0] = r2; return 6 + EXTRA_IF_R6R7(reg0); } int fn_ADCR_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = cp1600->C; ADD_SZOC(r0,r1,r2,cp1600); cp1600->r[instr->opcode.decoded.reg0] = r2; return 6 + EXTRA_IF_R6R7(reg0); } int fn_RSWD_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0]; cp1600->S = !!(r0 & 0x80); cp1600->Z = !!(r0 & 0x40); cp1600->O = !!(r0 & 0x20); cp1600->C = !!(r0 & 0x10); cp1600->intr = 0; return 6; } int fn_GSWD_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0; cp1600->r[7]++; r0 = ((cp1600->S << 7) | (cp1600->Z << 6) | (cp1600->O << 5) | (cp1600->C << 4))&0xF0; r0 = r0 | (r0 << 8); cp1600->r[instr->opcode.decoded.reg0] = r0; cp1600->intr = 0; return 6; } int fn_MOV_rr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,rp; int reg0 = instr->opcode.decoded.reg0; int reg1 = instr->opcode.decoded.reg1; rp = cp1600->r[7] + 1; r0 = cp1600->r[reg0]; cp1600->r[reg1] = r0; cp1600->r[7] = rp; cp1600->S = !!(r0 & 0x8000); cp1600->Z = !(r0); return 6 + EXTRA_IF_R6R7(reg1); } int fn_TST_rr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0, rp; int reg0 = instr->opcode.decoded.reg0; rp = cp1600->r[7] + 1; r0 = cp1600->r[reg0] + (reg0 == 7); cp1600->r[7] = rp; cp1600->S = !!(r0 & 0x8000); cp1600->Z = !(r0); return 6 + EXTRA_IF_R6R7(reg1); } int fn_ADD_rr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2,rp; int reg0 = instr->opcode.decoded.reg0; int reg1 = instr->opcode.decoded.reg1; rp = cp1600->r[7] + 1; r0 = cp1600->r[reg0]; r1 = cp1600->r[reg1]; cp1600->r[7] = rp; ADD_SZOC(r0,r1,r2,cp1600); cp1600->r[reg1] = r2; return 6 + EXTRA_IF_R6R7(reg1); } int fn_SUB_rr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2,rp; int reg0 = instr->opcode.decoded.reg0; int reg1 = instr->opcode.decoded.reg1; rp = cp1600->r[7] + 1; r0 = cp1600->r[reg0]; r1 = cp1600->r[reg1]; cp1600->r[7] = rp; SUB_SZOC(r0,r1,r2,cp1600); cp1600->r[reg1] = r2; return 6 + EXTRA_IF_R6R7(reg1); } int fn_CMP_rr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2,rp; int reg0 = instr->opcode.decoded.reg0; int reg1 = instr->opcode.decoded.reg1; rp = cp1600->r[7] + 1; r0 = cp1600->r[reg0]; r1 = cp1600->r[reg1]; cp1600->r[7] = rp; SUB_SZOC(r0,r1,r2,cp1600); UNUSED(r2); return 6 + EXTRA_IF_R6R7(reg1); } int fn_AND_rr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2,rp; int reg0 = instr->opcode.decoded.reg0; int reg1 = instr->opcode.decoded.reg1; rp = cp1600->r[7] + 1; r0 = cp1600->r[reg0]; r1 = cp1600->r[reg1]; cp1600->r[7] = rp; EXEC_SZ(r0,r1,r2,&,cp1600); cp1600->r[reg1] = r2; return 6 + EXTRA_IF_R6R7(reg1); } int fn_XOR_rr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2,rp; int reg0 = instr->opcode.decoded.reg0; int reg1 = instr->opcode.decoded.reg1; rp = cp1600->r[7] + 1; r0 = cp1600->r[reg0]; r1 = cp1600->r[reg1]; cp1600->r[7] = rp; EXEC_SZ(r0,r1,r2,^,cp1600); cp1600->r[reg1] = r2; return 6 + EXTRA_IF_R6R7(reg1); } int fn_MOV_pr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0; int reg1 = instr->opcode.decoded.reg1; r0 = cp1600->r[7] + 1; cp1600->r[reg1] = r0; cp1600->r[7] = r0; cp1600->S = !!(r0 & 0x8000); cp1600->Z = !(r0); return 6 + EXTRA_IF_R6R7(reg1); } int fn_ADD_pr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; int reg1 = instr->opcode.decoded.reg1; r0 = cp1600->r[7] + 1; r1 = cp1600->r[reg1]; cp1600->r[7] = r0; ADD_SZOC(r0,r1,r2,cp1600); cp1600->r[reg1] = r2; return 6 + EXTRA_IF_R6R7(reg1); } int fn_SUB_pr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; int reg1 = instr->opcode.decoded.reg1; r0 = cp1600->r[7] + 1; r1 = cp1600->r[reg1]; cp1600->r[7] = r0; SUB_SZOC(r0,r1,r2,cp1600); cp1600->r[reg1] = r2; return 6 + EXTRA_IF_R6R7(reg1); } int fn_CMP_pr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; int reg1 = instr->opcode.decoded.reg1; r0 = cp1600->r[7] + 1; r1 = cp1600->r[reg1]; cp1600->r[7] = r0; SUB_SZOC(r0,r1,r2,cp1600); UNUSED(r2); return 6 + EXTRA_IF_R6R7(reg1); } int fn_AND_pr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; int reg1 = instr->opcode.decoded.reg1; r0 = cp1600->r[7] + 1; r1 = cp1600->r[reg1]; cp1600->r[7] = r0; EXEC_SZ(r0,r1,r2,&,cp1600); cp1600->r[reg1] = r2; return 6 + EXTRA_IF_R6R7(reg1); } int fn_XOR_pr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; int reg1 = instr->opcode.decoded.reg1; r0 = cp1600->r[7] + 1; r1 = cp1600->r[reg1]; cp1600->r[7] = r0; EXEC_SZ(r0,r1,r2,^,cp1600); cp1600->r[reg1] = r2; return 6 + EXTRA_IF_R6R7(reg1); } int fn_MOV_rp (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0; int reg0 = instr->opcode.decoded.reg0; r0 = cp1600->r[reg0]; cp1600->r[7] = r0; cp1600->S = !!(r0 & 0x8000); cp1600->Z = !(r0); return 7; } int fn_ADD_rp (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = cp1600->r[7] + 1; ADD_SZOC(r0,r1,r2,cp1600); cp1600->r[7] = r2; return 7; } int fn_SUB_rp (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = cp1600->r[7] + 1; SUB_SZOC(r0,r1,r2,cp1600); cp1600->r[7] = r2; return 7; } int fn_CMP_rp (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2,rp; rp = cp1600->r[7] + 1; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = cp1600->r[7] + 1; cp1600->r[7] = rp; SUB_SZOC(r0,r1,r2,cp1600); UNUSED(r2); return 7; } int fn_AND_rp (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = cp1600->r[7] + 1; EXEC_SZ(r0,r1,r2,&,cp1600); cp1600->r[7] = r2; return 7; } int fn_XOR_rp (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = cp1600->r[7] + 1; EXEC_SZ(r0,r1,r2,^,cp1600); cp1600->r[7] = r2; return 7; } int fn_SWAP1_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = (0xFF & (r0 >> 8)) | ((0xFF & r0) << 8); cp1600->Z = !r0; cp1600->S = !!(r0 & 0x8000); cp1600->r[instr->opcode.decoded.reg0] = r1; cp1600->intr = 0; return 6; } int fn_SLL1_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = r0 << 1; cp1600->S = !!(r0 & 0x4000); cp1600->Z = !r1; cp1600->r[instr->opcode.decoded.reg0] = r1; cp1600->intr = 0; return 6; } int fn_SLLC1_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = r0 << 1; cp1600->Z = !r1; cp1600->C = !!(r0 & 0x8000); cp1600->S = !!(r0 & 0x4000); cp1600->r[instr->opcode.decoded.reg0] = r1; cp1600->intr = 0; return 6; } int fn_RLC1_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = (r0 << 1) | cp1600->C; cp1600->Z = !r1; cp1600->C = !!(r0 & 0x8000); cp1600->S = !!(r0 & 0x4000); cp1600->r[instr->opcode.decoded.reg0] = r1; cp1600->intr = 0; return 6; } int fn_SLR1_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = 0x7FFF & (r0 >> 1); cp1600->S = !!(r0 & 0x0100); cp1600->Z = !r1; cp1600->r[instr->opcode.decoded.reg0] = r1; cp1600->intr = 0; return 6; } int fn_RRC1_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = (0x7FFF & (r0 >> 1)) | (cp1600->C << 15); cp1600->S = !!(r0 & 0x0100); cp1600->Z = !r1; cp1600->C = r0 & 1; cp1600->r[instr->opcode.decoded.reg0] = r1; cp1600->intr = 0; return 6; } int fn_SAR1_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = (r0 >> 1) | (r0 & 0x8000); cp1600->S = !!(r0 & 0x0100); cp1600->Z = !r1; cp1600->r[instr->opcode.decoded.reg0] = r1; cp1600->intr = 0; return 6; } int fn_SARC1_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = (r0 >> 1) | (r0 & 0x8000); cp1600->S = !!(r0 & 0x0100); cp1600->Z = !r1; cp1600->C = r0 & 1; cp1600->r[instr->opcode.decoded.reg0] = r1; cp1600->intr = 0; return 6; } int fn_SWAP2_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0, r1; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0] & 0xFF; r1 = r0 | (r0 << 8); cp1600->S = !!(r0 & 0x0080); cp1600->Z = !r1; cp1600->r[instr->opcode.decoded.reg0] = r1; cp1600->intr = 0; return 8; } int fn_SLL2_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = r0 << 2; cp1600->Z = !r1; cp1600->S = !!(r0 & 0x2000); cp1600->r[instr->opcode.decoded.reg0] = r1; cp1600->intr = 0; return 8; } int fn_SLLC2_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = r0 << 2; cp1600->Z = !r1; cp1600->C = !!(r0 & 0x8000); cp1600->O = !!(r0 & 0x4000); cp1600->S = !!(r0 & 0x2000); cp1600->r[instr->opcode.decoded.reg0] = r1; cp1600->intr = 0; return 8; } int fn_RLC2_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = (r0 << 2) | (cp1600->C << 1) | cp1600->O; cp1600->Z = !r1; cp1600->C = !!(r0 & 0x8000); cp1600->O = !!(r0 & 0x4000); cp1600->S = !!(r0 & 0x2000); cp1600->r[instr->opcode.decoded.reg0] = r1; cp1600->intr = 0; return 8; } int fn_SLR2_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = 0x3FFF & (r0 >> 2); cp1600->S = !!(r0 & 0x0200); cp1600->Z = !r1; cp1600->r[instr->opcode.decoded.reg0] = r1; cp1600->intr = 0; return 8; } int fn_RRC2_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0]; r1 = (0x3FFF & (r0 >> 2)) | (cp1600->C << 14) | (cp1600->O << 15); cp1600->S = !!(r0 & 0x0200); cp1600->Z = !r1; cp1600->C = r0 & 1; cp1600->O = !!(r0 & 2); cp1600->r[instr->opcode.decoded.reg0] = r1; cp1600->intr = 0; return 8; } int fn_SAR2_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,s; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0]; s = r0 & 0x8000; r1 = (r0 >> 2) + s + (s >> 1); cp1600->S = !!(r0 & 0x0200); cp1600->Z = !r1; cp1600->r[instr->opcode.decoded.reg0] = r1; cp1600->intr = 0; return 8; } int fn_SARC2_r (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,s; cp1600->r[7]++; r0 = cp1600->r[instr->opcode.decoded.reg0]; s = r0 & 0x8000; r1 = (r0 >> 2) + s + (s >> 1); cp1600->S = !!(r0 & 0x0200); cp1600->Z = !r1; cp1600->C = r0 & 1; cp1600->O = !!(r0 & 2); cp1600->r[instr->opcode.decoded.reg0] = r1; cp1600->intr = 0; return 8; } int fn_MVO_mr (const instr_t *instr, cp1600_t *cp1600) { int d = cp1600->D; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; uint_16 data = cp1600->r[instr->opcode.decoded.reg1]; cp1600->r[7]++; if (d) { jzp_printf("WARNING: MVO@ w/ SDBD prefix @ %.4X\n", instr->address); /* CP1600_WR(cp1600, addr, data & 0xFF); CP1600_WR(cp1600, addr, (data >> 8) & 0xFF); */ CP1600_WR(cp1600, addr, data); } else { CP1600_WR(cp1600, addr, data); } cp1600->intr = 0; return 9; } int fn_MVI_mr (const instr_t *instr, cp1600_t *cp1600) { int d = cp1600->D; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; uint_16 r0; cp1600->r[7]++; r0 = CP1600_RD(cp1600, addr); if (d) { r0 &= 0xFF; r0 |= CP1600_RD(cp1600, addr) << 8; } cp1600->r[instr->opcode.decoded.reg1] = r0; return (d ? 10 : 8) + EXTRA_IF_R6R7(reg0); } int fn_ADD_mr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; int d = cp1600->D; cp1600->r[7]++; r1 = cp1600->r[instr->opcode.decoded.reg1]; r0 = CP1600_RD(cp1600, addr); if (d) { r0 &= 0xFF; r0 |= CP1600_RD(cp1600, addr) << 8; } ADD_SZOC(r0,r1,r2,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; return (d ? 10 : 8) + EXTRA_IF_R6R7(reg0); } int fn_SUB_mr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; int d = cp1600->D; cp1600->r[7]++; r1 = cp1600->r[instr->opcode.decoded.reg1]; r0 = CP1600_RD(cp1600, addr); if (d) { r0 &= 0xFF; r0 |= CP1600_RD(cp1600, addr) << 8; } SUB_SZOC(r0,r1,r2,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; return (d ? 10 : 8) + EXTRA_IF_R6R7(reg0); } int fn_CMP_mr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; int d = cp1600->D; cp1600->r[7]++; r1 = cp1600->r[instr->opcode.decoded.reg1]; r0 = CP1600_RD(cp1600, addr); if (d) { r0 &= 0xFF; r0 |= CP1600_RD(cp1600, addr) << 8; } SUB_SZOC(r0,r1,r2,cp1600); UNUSED(r2); /* r2's value is discarded */ return (d ? 10 : 8) + EXTRA_IF_R6R7(reg0); } int fn_AND_mr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; int d = cp1600->D; cp1600->r[7]++; r1 = cp1600->r[instr->opcode.decoded.reg1]; r0 = CP1600_RD(cp1600, addr); if (d) { r0 &= 0xFF; r0 |= CP1600_RD(cp1600, addr) << 8; } EXEC_SZ(r0,r1,r2,&,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; return (d ? 10 : 8) + EXTRA_IF_R6R7(reg0); } int fn_XOR_mr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; int d = cp1600->D; cp1600->r[7]++; r0 = CP1600_RD(cp1600, addr); if (d) { r0 &= 0xFF; r0 |= CP1600_RD(cp1600, addr) << 8; } r1 = cp1600->r[instr->opcode.decoded.reg1]; EXEC_SZ(r0,r1,r2,^,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; return (d ? 10 : 8) + EXTRA_IF_R6R7(reg0); } #define R0R1CHK(x) if (instr->opcode.decoded.reg0==instr->opcode.decoded.reg1 && d) jzp_printf("WARNING: " #x " w/ op1==op2 and SDBD @ %.4X\n", instr->address); int fn_MVO_Mr (const instr_t *instr, cp1600_t *cp1600) { uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; uint_16 data = cp1600->r[instr->opcode.decoded.reg1]; int d = cp1600->D; cp1600->r[7]++; R0R1CHK(MVO@) if (d) jzp_printf("WARNING: MVO@ w/ SDBD prefix @ %.4X\n", instr->address); CP1600_WR(cp1600, addr, data); addr++; cp1600->r[instr->opcode.decoded.reg0] = addr; cp1600->intr = 0; return 9; } int fn_MVI_Mr (const instr_t *instr, cp1600_t *cp1600) { uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; uint_16 r0 = 0; int d = cp1600->D; cp1600->r[7]++; R0R1CHK(MVI@) r0 = CP1600_RD(cp1600, addr); addr++; if (d) { r0 &= 0xFF; r0 |= CP1600_RD(cp1600, addr) << 8; addr++; } cp1600->r[instr->opcode.decoded.reg0] = addr; cp1600->r[instr->opcode.decoded.reg1] = r0; return (d ? 10 : 8) + EXTRA_IF_R6R7(reg0); } int fn_ADD_Mr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; int d = cp1600->D; cp1600->r[7]++; R0R1CHK(ADD@) r1 = cp1600->r[instr->opcode.decoded.reg1]; r0 = CP1600_RD(cp1600, addr); addr++; if (d) { r0 &= 0xFF; r0 |= CP1600_RD(cp1600, addr) << 8; addr++; } ADD_SZOC(r0,r1,r2,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; cp1600->r[instr->opcode.decoded.reg0] = addr; return (d ? 10 : 8) + EXTRA_IF_R6R7(reg0); } int fn_SUB_Mr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; int d = cp1600->D; cp1600->r[7]++; R0R1CHK(SUB@) r1 = cp1600->r[instr->opcode.decoded.reg1]; r0 = CP1600_RD(cp1600, addr); addr++; if (d) { r0 &= 0xFF; r0 |= CP1600_RD(cp1600, addr) << 8; addr++; } SUB_SZOC(r0,r1,r2,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; cp1600->r[instr->opcode.decoded.reg0] = addr; return (d ? 10 : 8) + EXTRA_IF_R6R7(reg0); } int fn_CMP_Mr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; int d = cp1600->D; cp1600->r[7]++; R0R1CHK(CMP@) r1 = cp1600->r[instr->opcode.decoded.reg1]; r0 = CP1600_RD(cp1600, addr); addr++; if (d) { r0 &= 0xFF; r0 |= CP1600_RD(cp1600, addr) << 8; addr++; } SUB_SZOC(r0,r1,r2,cp1600); UNUSED(r2); /* r2's value is discarded */ cp1600->r[instr->opcode.decoded.reg0] = addr; return (d ? 10 : 8) + EXTRA_IF_R6R7(reg0); } int fn_AND_Mr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; int d = cp1600->D; cp1600->r[7]++; R0R1CHK(AND@) r1 = cp1600->r[instr->opcode.decoded.reg1]; r0 = CP1600_RD(cp1600, addr); addr++; if (d) { r0 &= 0xFF; r0 |= CP1600_RD(cp1600, addr) << 8; addr++; } EXEC_SZ(r0,r1,r2,&,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; cp1600->r[instr->opcode.decoded.reg0] = addr; return (d ? 10 : 8) + EXTRA_IF_R6R7(reg0); } int fn_XOR_Mr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; int d = cp1600->D; cp1600->r[7]++; R0R1CHK(XOR@) r1 = cp1600->r[instr->opcode.decoded.reg1]; r0 = CP1600_RD(cp1600, addr); addr++; if (d) { r0 &= 0xFF; r0 |= CP1600_RD(cp1600, addr) << 8; addr++; } EXEC_SZ(r0,r1,r2,^,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; cp1600->r[instr->opcode.decoded.reg0] = addr; return (d ? 10 : 8) + EXTRA_IF_R6R7(reg0); } int fn_MVO_Nr (const instr_t *instr, cp1600_t *cp1600) { uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; uint_16 data = cp1600->r[instr->opcode.decoded.reg1]; cp1600->r[7]++; CP1600_WR(cp1600, addr, data); addr++; cp1600->r[instr->opcode.decoded.reg0] = addr; cp1600->intr = 0; return 9; } int fn_MVI_Nr (const instr_t *instr, cp1600_t *cp1600) { uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]++; uint_16 r0 = 0; cp1600->r[7]++; r0 = CP1600_RD(cp1600, addr); cp1600->r[instr->opcode.decoded.reg1] = r0; return 8 + EXTRA_IF_R6R7(reg0); } int fn_ADD_Nr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]++; cp1600->r[7]++; r1 = cp1600->r[instr->opcode.decoded.reg1]; r0 = CP1600_RD(cp1600, addr); ADD_SZOC(r0,r1,r2,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; return 8 + EXTRA_IF_R6R7(reg0); } int fn_SUB_Nr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]++; cp1600->r[7]++; r1 = cp1600->r[instr->opcode.decoded.reg1]; r0 = CP1600_RD(cp1600, addr); SUB_SZOC(r0,r1,r2,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; return 8 + EXTRA_IF_R6R7(reg0); } int fn_CMP_Nr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]++; cp1600->r[7]++; r1 = cp1600->r[instr->opcode.decoded.reg1]; r0 = CP1600_RD(cp1600, addr); SUB_SZOC(r0,r1,r2,cp1600); UNUSED(r2); /* r2's value is discarded */ return 8 + EXTRA_IF_R6R7(reg0); } int fn_AND_Nr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]++; cp1600->r[7]++; r1 = cp1600->r[instr->opcode.decoded.reg1]; r0 = CP1600_RD(cp1600, addr); EXEC_SZ(r0,r1,r2,&,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; return 8 + EXTRA_IF_R6R7(reg0); } int fn_XOR_Nr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]++; cp1600->r[7]++; r1 = cp1600->r[instr->opcode.decoded.reg1]; r0 = CP1600_RD(cp1600, addr); EXEC_SZ(r0,r1,r2,^,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; return 8 + EXTRA_IF_R6R7(reg0); } int fn_MVO_nr (const instr_t *instr, cp1600_t *cp1600) { uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; uint_16 data = cp1600->r[instr->opcode.decoded.reg1]; cp1600->r[7]++; CP1600_WR(cp1600, addr, data); cp1600->intr = 0; return 9; } int fn_MVI_nr (const instr_t *instr, cp1600_t *cp1600) { uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; uint_16 r0 = 0; cp1600->r[7]++; r0 = CP1600_RD(cp1600, addr); cp1600->r[instr->opcode.decoded.reg1] = r0; return 8 + EXTRA_IF_R6R7(reg0); } int fn_ADD_nr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; cp1600->r[7]++; r1 = cp1600->r[instr->opcode.decoded.reg1]; r0 = CP1600_RD(cp1600, addr); ADD_SZOC(r0,r1,r2,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; return 8 + EXTRA_IF_R6R7(reg0); } int fn_SUB_nr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; cp1600->r[7]++; r1 = cp1600->r[instr->opcode.decoded.reg1]; r0 = CP1600_RD(cp1600, addr); SUB_SZOC(r0,r1,r2,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; return 8 + EXTRA_IF_R6R7(reg0); } int fn_CMP_nr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; cp1600->r[7]++; r1 = cp1600->r[instr->opcode.decoded.reg1]; r0 = CP1600_RD(cp1600, addr); SUB_SZOC(r0,r1,r2,cp1600); UNUSED(r2); /* r2's value is discarded */ return 8 + EXTRA_IF_R6R7(reg0); } int fn_AND_nr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; cp1600->r[7]++; r1 = cp1600->r[instr->opcode.decoded.reg1]; r0 = CP1600_RD(cp1600, addr); EXEC_SZ(r0,r1,r2,&,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; return 8 + EXTRA_IF_R6R7(reg0); } int fn_XOR_nr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; cp1600->r[7]++; r1 = cp1600->r[instr->opcode.decoded.reg1]; r0 = CP1600_RD(cp1600, addr); EXEC_SZ(r0,r1,r2,^,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; return 8 + EXTRA_IF_R6R7(reg0); } int fn_MVI_Sr (const instr_t *instr, cp1600_t *cp1600) { uint_16 addr = cp1600->r[instr->opcode.decoded.reg0] - 1; uint_16 r0 = 0; cp1600->r[7]++; r0 = CP1600_RD(cp1600, addr); cp1600->r[instr->opcode.decoded.reg0] = addr; cp1600->r[instr->opcode.decoded.reg1] = r0; return 11 + EXTRA_IF_R6R7(reg0); } int fn_ADD_Sr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; cp1600->r[7]++; r0 = CP1600_RD(cp1600, addr - 1); cp1600->r[instr->opcode.decoded.reg0]--; r1 = cp1600->r[instr->opcode.decoded.reg1]; ADD_SZOC(r0,r1,r2,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; return 11 + EXTRA_IF_R6R7(reg0); } int fn_SUB_Sr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; cp1600->r[7]++; r0 = CP1600_RD(cp1600, addr - 1); cp1600->r[instr->opcode.decoded.reg0]--; r1 = cp1600->r[instr->opcode.decoded.reg1]; SUB_SZOC(r0,r1,r2,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; return 11 + EXTRA_IF_R6R7(reg0); } int fn_CMP_Sr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; cp1600->r[7]++; r0 = CP1600_RD(cp1600, addr - 1); cp1600->r[instr->opcode.decoded.reg0]--; r1 = cp1600->r[instr->opcode.decoded.reg1]; SUB_SZOC(r0,r1,r2,cp1600); UNUSED(r2); return 11 + EXTRA_IF_R6R7(reg0); } int fn_AND_Sr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; cp1600->r[7]++; r0 = CP1600_RD(cp1600, addr - 1); cp1600->r[instr->opcode.decoded.reg0]--; r1 = cp1600->r[instr->opcode.decoded.reg1]; EXEC_SZ(r0,r1,r2,&,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; return 11 + EXTRA_IF_R6R7(reg0); } int fn_XOR_Sr (const instr_t *instr, cp1600_t *cp1600) { uint_16 r0,r1,r2; uint_16 addr = cp1600->r[instr->opcode.decoded.reg0]; cp1600->r[7]++; r0 = CP1600_RD(cp1600, addr - 1); cp1600->r[instr->opcode.decoded.reg0]--; r1 = cp1600->r[instr->opcode.decoded.reg1]; EXEC_SZ(r0,r1,r2,^,cp1600); cp1600->r[instr->opcode.decoded.reg1] = r2; return 11 + EXTRA_IF_R6R7(reg0); } /* ======================================================================== */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* This program is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */ /* General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with this program; if not, write to the Free Software */ /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ======================================================================== */ /* Copyright (c) 1998-1999, Joseph Zbiciak */ /* ======================================================================== */