INLINE void saturn_jump_bit_set(int reg) { int adr; switch(READ_OP_ARG()) { case 0: saturn.carry=S64_BYTE( reg, 0)&1;break; case 1: saturn.carry=S64_BYTE( reg, 0)&2;break; case 2: saturn.carry=S64_BYTE( reg, 0)&4;break; case 3: saturn.carry=S64_BYTE( reg, 0)&8;break; case 4: saturn.carry=S64_BYTE( reg, 0)&0x10;break; case 5: saturn.carry=S64_BYTE( reg, 0)&0x20;break; case 6: saturn.carry=S64_BYTE( reg, 0)&0x40;break; case 7: saturn.carry=S64_BYTE( reg, 0)&0x80;break; case 8: saturn.carry=S64_BYTE( reg, 1)&1;break; case 9: saturn.carry=S64_BYTE( reg, 1)&2;break; case 0xa: saturn.carry=S64_BYTE( reg, 1)&4;break; case 0xb: saturn.carry=S64_BYTE( reg, 1)&8;break; case 0xc: saturn.carry=S64_BYTE( reg, 1)&0x10;break; case 0xd: saturn.carry=S64_BYTE( reg, 1)&0x20;break; case 0xe: saturn.carry=S64_BYTE( reg, 1)&0x40;break; case 0xf: saturn.carry=S64_BYTE( reg, 1)&0x80;break; } adr=READ_OP_DIS8(); if (saturn.carry) { if (adr==0) { saturn.pc=saturn_pop(); } else { saturn.pc=(saturn.pc+adr-2)&0xfffff; } change_pc(saturn.pc); } }
INLINE void saturn_st_jump_bit_clear(void) { int adr; switch(READ_OP_ARG()) { case 0: saturn.carry=!saturn.st&1;break; case 1: saturn.carry=!saturn.st&2;break; case 2: saturn.carry=!saturn.st&4;break; case 3: saturn.carry=!saturn.st&8;break; case 4: saturn.carry=!saturn.st&0x10;break; case 5: saturn.carry=!saturn.st&0x20;break; case 6: saturn.carry=!saturn.st&0x40;break; case 7: saturn.carry=!saturn.st&0x80;break; case 8: saturn.carry=!saturn.st&0x100;break; case 9: saturn.carry=!saturn.st&0x200;break; case 0xa: saturn.carry=!saturn.st&0x400;break; case 0xb: saturn.carry=!saturn.st&0x800;break; case 0xc: saturn.carry=!saturn.st&0x1000;break; case 0xd: saturn.carry=!saturn.st&0x2000;break; case 0xe: saturn.carry=!saturn.st&0x4000;break; case 0xf: saturn.carry=!saturn.st&0x8000;break; } adr=READ_OP_DIS8(); if (saturn.carry) { if (adr==0) { saturn.pc=saturn_pop(); } else { saturn.pc=(saturn.pc+adr-2)&0xfffff; } change_pc(saturn.pc); } }
INLINE void saturn_p_not_equals(void) { int nr=READ_OP_ARG(); int adr; saturn.carry=saturn.p!=nr; adr=READ_OP_DIS8(); if (saturn.carry) { if (adr==0) { saturn.pc=saturn_pop(); } else { saturn.pc=(saturn.pc+adr-2)&0xfffff; } change_pc(saturn.pc); } }
INLINE void saturn_not_equals_zero(int reg, int begin, int count) { int i, t,adr; for (i=0; i<count; i++) { t=S64_READ_NIBBLE(reg, (begin+i)&0xf ); if (t==0) break; saturn_ICount-=2; } saturn.carry=i==count; adr=READ_OP_DIS8(); if (saturn.carry) { if (adr==0) { saturn.pc=saturn_pop(); } else { saturn.pc=(saturn.pc+adr-2)&0xfffff; } change_pc(saturn.pc); } }
INLINE void saturn_smaller(int reg, int begin, int count, int right) { int i, t,t2,adr; for (i=count; i>=0; i--) { t=S64_READ_NIBBLE(reg, (begin+i)&0xf ); t2=S64_READ_NIBBLE(right, (begin+i)&0xf ); if (t>=t2) break; saturn_ICount-=2; } saturn.carry=i<0; adr=READ_OP_DIS8(); if (saturn.carry) { if (adr==0) { saturn.pc=saturn_pop(); } else { saturn.pc=(saturn.pc+adr-2)&0xfffff; } change_pc(saturn.pc); } }
static void saturn_instruction(saturn_state *cpustate) { int reg, adr; switch(READ_OP(cpustate)) { case 0: switch(READ_OP(cpustate)) { case 0: saturn_return_xm_set(cpustate);break; case 1: saturn_return(cpustate, 1);break; case 2: saturn_return_carry_set(cpustate);break; case 3: saturn_return_carry_clear(cpustate);break; case 4: saturn_sethex(cpustate);break; case 5: saturn_setdec(cpustate);break; case 6: saturn_push_c(cpustate);break; case 7: saturn_pop_c(cpustate);break; case 8: saturn_clear_st(cpustate);break; case 9: saturn_st_to_c(cpustate);break; case 0xa: saturn_c_to_st(cpustate);break; case 0xb: saturn_exchange_c_st(cpustate);break; case 0xc: saturn_inc_p(cpustate);break; case 0xd: saturn_dec_p(cpustate);break; case 0xe: saturn_instruction_0e(cpustate);break; case 0xf: saturn_return_interrupt(cpustate);break; } break; case 1: saturn_instruction_1(cpustate); break; case 2: saturn_load_p(cpustate); break; case 3: saturn_load_reg(cpustate, C); break; // lc case 4: adr=READ_OP_DIS8(cpustate); if (adr==0) { saturn_return(cpustate, cpustate->carry); } else { saturn_jump(cpustate, (cpustate->pc+adr-2)&0xfffff, cpustate->carry); } break; case 5: adr=READ_OP_DIS8(cpustate); if (adr==0) { saturn_return(cpustate, !cpustate->carry); } else { saturn_jump(cpustate, (cpustate->pc+adr-2)&0xfffff,!cpustate->carry); } break; case 6: adr=READ_OP_DIS12(cpustate); saturn_jump(cpustate, (cpustate->pc+adr-3)&0xfffff,1); break; case 7: adr=READ_OP_DIS12(cpustate); saturn_call(cpustate, (adr+cpustate->pc)&0xfffff); break; case 8: saturn_instruction_8(cpustate); break; case 9: saturn_instruction_9(cpustate); break; case 0xa: saturn_instruction_a(cpustate); break; case 0xb: saturn_instruction_b(cpustate); break; case 0xc: switch (reg=READ_OP(cpustate)) { case 0: case 1: case 2: case 3: case 8: case 9: case 0xa: case 0xb: saturn_add(cpustate, add_left[reg], BEGIN_A, COUNT_A, add_right[reg]); break; case 4: case 5: case 6: case 7: saturn_add(cpustate, A+(reg&3), BEGIN_A, COUNT_A, A+(reg&3)); break; case 0xc: case 0xd: case 0xe: case 0xf: saturn_decrement(cpustate, A+(reg&3), BEGIN_A, COUNT_A); break; } break; case 0xd: switch(reg=READ_OP(cpustate)) { case 0: case 1: case 2: case 3: saturn_clear(cpustate, A+reg, BEGIN_A, COUNT_A); break; // a=0 a case 4: case 5: case 6: case 7: case 8: case 9: case 0xa: case 0xb: saturn_copy(cpustate, reg_right[reg&7], BEGIN_A, COUNT_A, reg_left[reg&7]); break; // a=b a case 0xc: case 0xd: case 0xe: case 0xf: saturn_exchange(cpustate, reg_left[reg&3], BEGIN_A, COUNT_A, reg_right[reg&3]); break; // abex a } break; case 0xe: switch(reg=READ_OP(cpustate)) { case 0: case 1: case 2: case 3: case 8: case 9: case 0xa: case 0xb: saturn_sub(cpustate, sub_left[reg], BEGIN_A, COUNT_A, sub_right[reg]); break; case 4: case 5: case 6: case 7: saturn_increment(cpustate, A+(reg&3), BEGIN_A, COUNT_A); break; // a=a+1 a case 0xc: case 0xd: case 0xe: case 0xf: saturn_sub2(cpustate, sub_left[reg], BEGIN_A, COUNT_A, sub_right[reg]); break; } break; case 0xf: switch(reg=READ_OP(cpustate)) { case 0: case 1: case 2: case 3: saturn_shift_nibble_left(cpustate, A+reg,BEGIN_A, COUNT_A); break; // asl a case 4: case 5: case 6: case 7: saturn_shift_nibble_right(cpustate, A+(reg&3),BEGIN_A, COUNT_A); break; // asr a case 8: case 9: case 0xa: case 0xb: saturn_negate(cpustate, A+(reg&3),BEGIN_A, COUNT_A); break; // A=-A a case 0xc: case 0xd: case 0xe: case 0xf: saturn_invert(cpustate, A+(reg&3),BEGIN_A, COUNT_A); break; // A=-A-1 a } break; } }
static void saturn_instruction(void) { int reg, adr; switch(READ_OP()) { case 0: switch(READ_OP()) { case 0: saturn_return_xm_set();break; case 1: saturn_return(1);break; case 2: saturn_return_carry_set();break; case 3: saturn_return_carry_clear();break; case 4: saturn_sethex();break; case 5: saturn_setdec();break; case 6: saturn_push_c();break; case 7: saturn_pop_c();break; case 8: saturn_clear_st();break; case 9: saturn_st_to_c();break; case 0xa: saturn_c_to_st();break; case 0xb: saturn_exchange_c_st();break; case 0xc: saturn_inc_p(); break; case 0xd: saturn_dec_p(); break; case 0xf: saturn_return_interrupt();break; case 0xe: saturn_instruction_0e(); break; } break; case 1: saturn_instruction_1(); break; case 2: saturn_load_p(); break; case 3: saturn_load_reg(C);break; /* lc */ case 4: adr=READ_OP_DIS8(); if (adr==0) { saturn_return(saturn.carry); } else { saturn_jump((saturn.pc+adr-2)&0xfffff, saturn.carry); } break; case 5: adr=READ_OP_DIS8(); if (adr==0) { saturn_return(!saturn.carry); } else { saturn_jump((saturn.pc+adr-2)&0xfffff,!saturn.carry); } break; case 6: adr=READ_OP_DIS12(); saturn_jump((saturn.pc+adr-3)&0xfffff,1); break; case 7: adr=READ_OP_DIS12(); saturn_call((adr+saturn.pc)&0xfffff); break; case 8: saturn_instruction_8(); break; case 9: saturn_instruction_9(); break; case 0xa: saturn_instruction_a(); break; case 0xb: saturn_instruction_b(); break; case 0xc: switch (reg=READ_OP()) { case 0: case 1: case 2: case 3: case 8: case 9: case 0xa: case 0xb: saturn_add(add_left[reg], BEGIN_A, COUNT_A, add_right[reg]); break; case 4: case 5: case 6: case 7: saturn_shift_left(A+(reg&3), BEGIN_A, COUNT_A); break; case 0xc: case 0xd: case 0xe: case 0xf: saturn_decrement(A+(reg&3), BEGIN_A, COUNT_A); break; } break; case 0xd: switch(reg=READ_OP()) { case 0: case 1: case 2: case 3: saturn_clear(A+reg, BEGIN_A, COUNT_A); break; /* a=0 a */ case 4: case 5: case 6: case 7: case 8: case 9: case 0xa: case 0xb: saturn_copy(reg_right[reg&7], BEGIN_A, COUNT_A, reg_left[reg&7]); /*correct */ break; /* a=b a */ case 0xc: case 0xd: case 0xe: case 0xf: saturn_exchange(reg_left[reg&3], BEGIN_A, COUNT_A, reg_right[reg&3]); break; /* abex a */ } break; case 0xe: switch(reg=READ_OP()) { case 0: case 1: case 2: case 3: case 8: case 9: case 0xa: case 0xb: saturn_sub(sub_left[reg], BEGIN_A, COUNT_A, S64_READ_A(sub_right[reg])); break; case 4: case 5: case 6: case 7: saturn_increment(A+(reg&3), BEGIN_A, COUNT_A); break; /* a=a+1 a */ case 0xc: case 0xd: case 0xe: case 0xf: saturn_sub2(sub_left[reg], BEGIN_A, COUNT_A, S64_READ_A(sub_right[reg])); break; } break; case 0xf: switch(reg=READ_OP()) { case 0: case 1: case 2: case 3: saturn_shift_nibble_left(A+reg,BEGIN_A, COUNT_A); break; /* asl a */ case 4: case 5: case 6: case 7: saturn_shift_nibble_right(A+(reg&3),BEGIN_A, COUNT_A); break; /* asr a */ case 8: case 9: case 0xa: case 0xb: saturn_invert(A+(reg&3),BEGIN_A, COUNT_A); break; /* A=-A a */ case 0xc: case 0xd: case 0xe: case 0xf: saturn_negate(A+(reg&3),BEGIN_A, COUNT_A); break; /* A=-A-1 a */ } break; } }