📄 xmix_vm.c
字号:
inc_loc_(vm); return result;}static gboolean inp_handler_ (mix_vm_t *vm, const mix_ins_t *ins){ mix_address_t addr; mix_device_t *dev; gboolean result; g_assert(ins->opcode == mix_opIN); addr = get_M_ (vm, ins); g_return_val_if_fail (ins->fspec < BD_NO_, TRUE); g_return_val_if_fail (MEMOK_(addr), TRUE); dev = get_dev_ (vm, ins->fspec); g_return_val_if_fail ( dev != NULL, TRUE); g_return_val_if_fail (MEM_CELLS_NO_ - addr > mix_device_block_size(dev), TRUE); result = mix_device_read (dev, get_cell_ptr_ (vm, addr)); inc_loc_(vm); return result;}static gboolean out_handler_(mix_vm_t *vm, const mix_ins_t *ins){ mix_address_t addr; mix_device_t *dev; gboolean result; g_assert(ins->opcode == mix_opOUT); addr = get_M_ (vm, ins); g_return_val_if_fail (ins->fspec < BD_NO_, TRUE); g_return_val_if_fail (MEMOK_(addr), TRUE); dev = get_dev_ (vm, ins->fspec); g_return_val_if_fail ( dev != NULL, TRUE); g_return_val_if_fail (MEM_CELLS_NO_ - addr > mix_device_block_size(dev), TRUE); result = mix_device_write (dev, get_cell_ptr_ (vm, addr)); inc_loc_(vm); return result;}static gboolean jrd_handler_(mix_vm_t *vm, const mix_ins_t *ins){ g_assert(ins->opcode == mix_opJRED); g_return_val_if_fail (ins->fspec < BD_NO_, TRUE); g_return_val_if_fail (get_dev_ (vm, ins->fspec) != NULL, TRUE); inc_loc_ (vm); if ( !mix_device_busy (get_dev_ (vm, ins->fspec)) ) { set_rJ_(vm, get_loc_(vm)); set_loc_ (vm, get_M_ (vm, ins)); } return TRUE;}static gbooleanjmp_handler_(mix_vm_t *vm, const mix_ins_t *ins){ gboolean jump = FALSE; mix_address_t addr = get_M_(vm, ins); mix_ins_id_t id = mix_ins_id_from_ins(*ins); g_assert(ins->opcode == mix_opJMP); g_return_val_if_fail(MEMOK_(addr), FALSE); switch ( id ) { case mix_JMP: case mix_JSJ: jump = TRUE; break; case mix_JOV: jump = get_over_(vm); if (jump) set_over_(vm, FALSE); break; case mix_JNOV: jump = !get_over_(vm); set_over_(vm, FALSE); break; case mix_JL: jump = ( get_cmp_(vm) == mix_LESS ); break; case mix_JE: jump = ( get_cmp_(vm) == mix_EQ ); break; case mix_JG: jump = ( get_cmp_(vm) == mix_GREAT ); break; case mix_JGE: jump = ( get_cmp_(vm) != mix_LESS ); break; case mix_JNE: jump = ( get_cmp_(vm) != mix_EQ ); break; case mix_JLE: jump = ( get_cmp_(vm) != mix_GREAT ); break; default: return FALSE; } inc_loc_(vm); if ( jump ) { if ( id != mix_JSJ ) set_rJ_(vm, get_loc_(vm)); set_loc_(vm, addr); } return TRUE;}static gbooleanjpx_handler_(mix_vm_t *vm, const mix_ins_t *ins){ gboolean jump = FALSE; mix_address_t addr = get_M_(vm, ins); mix_ins_id_t id = mix_ins_id_from_ins(*ins); mix_word_t val; g_assert(ins->opcode >= mix_opJAx || ins->opcode <= mix_opJXx); g_return_val_if_fail(MEMOK_(addr), FALSE); switch (ins->opcode) { case mix_opJAx: val = get_rA_(vm); break; case mix_opJXx: val = get_rX_(vm); break; default: val = get_rI_(vm, ins->opcode - mix_opJAx); } switch (id) { case mix_JAN: case mix_JXN: case mix_J1N: case mix_J2N: case mix_J3N: case mix_J4N: case mix_J5N: case mix_J6N: jump = mix_word_is_negative(val) && val != MIX_WORD_MINUS_ZERO; break; case mix_JAZ: case mix_JXZ: case mix_J1Z: case mix_J2Z: case mix_J3Z: case mix_J4Z: case mix_J5Z: case mix_J6Z: jump = mix_word_magnitude(val) == MIX_WORD_ZERO; break; case mix_JAP: case mix_JXP: case mix_J1P: case mix_J2P: case mix_J3P: case mix_J4P: case mix_J5P: case mix_J6P: jump = mix_word_is_positive(val) && val != MIX_WORD_ZERO; break; case mix_JANN: case mix_JXNN: case mix_J1NN: case mix_J2NN: case mix_J3NN: case mix_J4NN: case mix_J5NN: case mix_J6NN: jump = mix_word_magnitude(val) == MIX_WORD_ZERO || mix_word_is_positive(val); break; case mix_JANZ: case mix_JXNZ: case mix_J1NZ: case mix_J2NZ: case mix_J3NZ: case mix_J4NZ: case mix_J5NZ: case mix_J6NZ: jump = mix_word_magnitude(val) != MIX_WORD_ZERO; break; case mix_JANP: case mix_JXNP: case mix_J1NP: case mix_J2NP: case mix_J3NP: case mix_J4NP: case mix_J5NP: case mix_J6NP: jump = mix_word_magnitude(val) == MIX_WORD_ZERO || mix_word_is_negative(val); break; default: return FALSE; } inc_loc_(vm); if ( jump ) { set_rJ_(vm, get_loc_(vm)); set_loc_(vm, addr); } return TRUE;}static gbooleanina_handler_(mix_vm_t *vm, const mix_ins_t *ins){ mix_word_t val = mix_short_to_word_fast(get_M_(vm, ins)); mix_ins_id_t id = mix_ins_id_from_ins(*ins); gint r; g_assert(id >= mix_INCA && id <= mix_ENNX); switch (ins->opcode) { case mix_opINCA: r = A_; break; case mix_opINCX: r = X_; break; default: r = I1_ + ins->opcode - mix_opINC1; } switch (id) { case mix_ENTA: case mix_ENTX: break; case mix_ENT1: case mix_ENT2: case mix_ENT3: case mix_ENT4: case mix_ENT5: case mix_ENT6: val = mix_word_set_field(mix_fspec_new(1,3), MIX_WORD_ZERO, val); break; case mix_INCA: case mix_INCX: if ( mix_word_add_and_carry(val, get_reg_(vm, r), NULL, &val) ) set_over_(vm, TRUE); break; case mix_INC1: case mix_INC2: case mix_INC3: case mix_INC4: case mix_INC5: case mix_INC6: mix_word_add_and_carry(val, get_reg_(vm,r), NULL, &val); val = mix_word_set_field(mix_fspec_new(1,3), MIX_WORD_ZERO, val); break; case mix_DECA: case mix_DECX: if ( mix_word_add_and_carry(mix_word_negative(val), get_reg_(vm, r), NULL, &val) ) set_over_(vm, TRUE); break; case mix_DEC1: case mix_DEC2: case mix_DEC3: case mix_DEC4: case mix_DEC5: case mix_DEC6: mix_word_add_and_carry(mix_word_negative(val), get_reg_(vm,r), NULL, &val); val = mix_word_set_field(mix_fspec_new(1,3), MIX_WORD_ZERO, val); break; case mix_ENN1: case mix_ENN2: case mix_ENN3: case mix_ENN4: case mix_ENN5: case mix_ENN6: val = mix_word_set_field(mix_fspec_new(1,3), MIX_WORD_ZERO, val); /* fallthrough */ case mix_ENNA: case mix_ENNX: mix_word_reverse_sign(val); break; default: return FALSE; } set_reg_(vm, r, val); inc_loc_(vm); return TRUE;}static gbooleancmp_handler_(mix_vm_t *vm, const mix_ins_t *ins){ g_assert(ins->opcode >= mix_opCMPA && ins->opcode <= mix_opCMPX); if ( ins->fspec == 0 ) { /* shortcut: +0 == -0 */ set_cmp_(vm, mix_EQ); } else { mix_word_t v = get_V_(vm, ins); mix_word_t reg; mix_cmpflag_t flag; switch (ins->opcode) { case mix_opCMPA: reg = get_rA_(vm); break; case mix_opCMPX: reg = get_rX_(vm); break; default: reg = get_rI_(vm, ins->opcode - mix_opCMPA); break; } reg = mix_word_get_field(ins->fspec, reg); mix_word_add_and_carry(reg, mix_word_negative(v), NULL, ®); if ( mix_word_magnitude(reg) == MIX_WORD_ZERO ) flag = mix_EQ; else if ( mix_word_is_positive(reg) ) flag = mix_GREAT; else flag = mix_LESS; set_cmp_(vm, flag); } inc_loc_(vm); return TRUE;}ins_handler_t_ ins_handlers_[MIX_BYTE_MAX + 1] = { nop_handler_, add_handler_, add_handler_, mul_handler_, div_handler_, spc_handler_, sla_handler_, mov_handler_, lda_handler_, lda_handler_, lda_handler_, lda_handler_, lda_handler_, lda_handler_, lda_handler_, lda_handler_, lda_handler_, lda_handler_, lda_handler_, lda_handler_, lda_handler_, lda_handler_, lda_handler_, lda_handler_, sta_handler_, sta_handler_, sta_handler_, sta_handler_, sta_handler_, sta_handler_, sta_handler_, sta_handler_, sta_handler_, sta_handler_, jbs_handler_, ioc_handler_, inp_handler_, out_handler_, jrd_handler_, jmp_handler_, jpx_handler_, jpx_handler_, jpx_handler_, jpx_handler_, jpx_handler_, jpx_handler_, jpx_handler_, jpx_handler_, ina_handler_, ina_handler_, ina_handler_, ina_handler_, ina_handler_, ina_handler_, ina_handler_, ina_handler_, cmp_handler_, cmp_handler_, cmp_handler_, cmp_handler_, cmp_handler_, cmp_handler_, cmp_handler_, cmp_handler_, };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -