⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmix_vm.c

📁 汇编语言编程源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ---------------------- xmix_vm.c : * Implementation of the functions declared in xmix_vm.h * ------------------------------------------------------------------ * Copyright (C) 2000 Free Software Foundation, Inc. *   * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *   */#include "xmix_vm.h"/* auxiliar functions */G_INLINE_FUNC mix_address_tget_M_(const mix_vm_t *vm, const mix_ins_t *ins);G_INLINE_FUNC mix_word_tget_V_(const mix_vm_t *vm, const mix_ins_t *ins);G_INLINE_FUNC mix_device_t *get_dev_ (mix_vm_t *vm, mix_fspec_t type);G_INLINE_FUNC mix_address_tget_M_(const mix_vm_t *vm, const mix_ins_t *ins){  if ( ins->index == 0 )    return ins->address;  else    return mix_short_add(ins->address, 			 mix_word_to_short_fast(get_rI_(vm, ins->index)));}G_INLINE_FUNC mix_word_tget_V_(const mix_vm_t *vm, const mix_ins_t *ins){  return mix_word_get_field(ins->fspec, get_cell_(vm, get_M_(vm,ins)));}G_INLINE_FUNC mix_device_t *get_dev_ (mix_vm_t *vm, mix_fspec_t type) {  if (type >= BD_NO_) return NULL;  if (vm->devices[type] == NULL)    vm->devices[type] = vm->factory (type);  return vm->devices[type];}/* Instruction handlers */static gboolean nop_handler_(mix_vm_t *vm, const mix_ins_t *ins){  g_assert(ins->opcode == mix_opNOP);  inc_loc_(vm);  return TRUE;}static gboolean add_handler_(mix_vm_t *vm, const mix_ins_t *ins){  mix_word_t val = get_V_(vm, ins);  g_assert(ins->opcode == mix_opADD || ins->opcode == mix_opSUB);  if ( ins->opcode == mix_opSUB ) mix_word_reverse_sign(val);  if ( mix_word_add_and_carry(get_rA_(vm), val, NULL, &get_rA_(vm)) )    set_over_(vm,TRUE);  inc_loc_(vm);  return TRUE;}static gboolean mul_handler_(mix_vm_t *vm, const mix_ins_t *ins){  g_assert(ins->opcode == mix_opMUL);  mix_word_mul(get_rA_(vm), get_V_(vm,ins), &get_rA_(vm), &get_rX_(vm));  inc_loc_(vm);  return TRUE;}static gboolean div_handler_(mix_vm_t *vm, const mix_ins_t *ins){  g_assert(ins->opcode == mix_opDIV);  if ( mix_word_div(get_rA_(vm), get_rX_(vm), get_V_(vm,ins),		    &get_rA_(vm), &get_rX_(vm)) )    set_over_(vm,TRUE);  inc_loc_(vm);  return TRUE;}static gboolean spc_handler_(mix_vm_t *vm, const mix_ins_t *ins){  g_assert(ins->opcode == mix_opSPC);    switch (mix_ins_id_from_ins(*ins)) {  case mix_HLT: halt_(vm, TRUE); break;  case mix_CHAR:    {       guint32 num = mix_word_magnitude(get_rA_(vm));      mix_char_t z = mix_ascii_to_char('0');      guint i;      for (i = 5; 0 < i; --i, num /= 10)	mix_word_set_byte(&get_rX_(vm), i, z + num % 10);      for (i = 5; 0 < i; --i, num /= 10)	mix_word_set_byte(&get_rA_(vm), i, z + num % 10);      break;    }  case mix_NUM:     {       guint i;      mix_word_t num = MIX_WORD_ZERO;      mix_word_t ten = 10;      for (i = 1; i <= 5; ++i) {	mix_word_mul(ten, num, NULL, &num);	mix_word_add_and_carry(num, mix_word_get_byte(get_rA_(vm),i)%10,			       NULL, &num);      }      for (i = 1; i <= 5; ++i) {	mix_word_mul(ten, num, NULL, &num);	mix_word_add_and_carry(num, mix_word_get_byte(get_rX_(vm),i)%10,			       NULL, &num);      }      set_rA_(vm,	      mix_word_is_negative(get_rA_(vm)) ? mix_word_negative(num):num);      break;    }  default: return FALSE;  }  inc_loc_(vm);  return TRUE;}static gboolean sla_handler_(mix_vm_t *vm, const mix_ins_t *ins){  mix_short_t n = get_M_(vm,ins);    g_assert(ins->opcode == mix_opSLx);  g_return_val_if_fail(mix_short_is_positive(n), FALSE);    switch ( mix_ins_id_from_ins(*ins) ) {  case mix_SLA:    mix_word_shift_left(get_rA_(vm), MIX_WORD_ZERO, n, &get_rA_(vm), NULL);    break;  case mix_SRA:    mix_word_shift_right(get_rA_(vm), MIX_WORD_ZERO, n, &get_rA_(vm), NULL);    break;  case mix_SLAX:    mix_word_shift_left(get_rA_(vm), get_rX_(vm), n, 			&get_rA_(vm), &get_rX_(vm));    break;  case mix_SRAX:    mix_word_shift_right(get_rA_(vm), get_rX_(vm), n, 			&get_rA_(vm), &get_rX_(vm));    break;  case mix_SLC:    mix_word_shift_left_circular(get_rA_(vm), get_rX_(vm), n, 				 &get_rA_(vm), &get_rX_(vm));    break;  case mix_SRC:    mix_word_shift_right_circular(get_rA_(vm), get_rX_(vm), n, 				  &get_rA_(vm), &get_rX_(vm));    break;  default:    return FALSE;  }    inc_loc_(vm);  return TRUE;}static gboolean mov_handler_(mix_vm_t *vm, const mix_ins_t *ins){  mix_short_t from = get_M_(vm,ins),     to = mix_word_to_short_fast(get_rI_(vm,1));  guint k, delta = ins->fspec;    g_assert(ins->opcode == mix_opMOVE);  g_return_val_if_fail(mix_short_is_positive(from), FALSE);  g_return_val_if_fail(mix_short_is_positive(to), FALSE);  g_return_val_if_fail(MEMOK_(from + delta -1), FALSE);  g_return_val_if_fail(MEMOK_(to + delta - 1), FALSE);    for (k = 0; k < delta; ++k)    set_cell_(vm, to+k, get_cell_(vm, from+k));  set_rI_(vm, 1, to+delta);  inc_loc_(vm);  return TRUE;}static gbooleanlda_handler_(mix_vm_t *vm, const mix_ins_t *ins){  gint r = 0;  mix_word_t val;  mix_ins_id_t id = mix_ins_id_from_ins(*ins);      g_assert(id >= mix_LDA && id <= mix_LDXN);    val = get_V_(vm, ins);  if ( id > mix_LDX && mix_fspec_left(ins->fspec) == 0)     mix_word_reverse_sign(val);  if ( (id > mix_LDA && id < mix_LDX) || (id > mix_LDAN && id < mix_LDXN) )    /* Bytes 1-3 of I regs are always null */    val = mix_word_set_field(mix_fspec_new(1,3),MIX_WORD_ZERO,val);          switch (id) {  case mix_LDA: case mix_LDAN: r = A_; break;  case mix_LDX: case mix_LDXN: r = X_; break;  case mix_LD1: case mix_LD1N: r = I1_; break;  case mix_LD2: case mix_LD2N: r = I2_; break;  case mix_LD3: case mix_LD3N: r = I3_; break;  case mix_LD4: case mix_LD4N: r = I4_; break;  case mix_LD5: case mix_LD5N: r = I5_; break;  case mix_LD6: case mix_LD6N: r = I6_; break;  default: g_assert_not_reached();  }  set_reg_(vm, r, val);  inc_loc_(vm);  return TRUE;}static gbooleansta_handler_(mix_vm_t *vm, const mix_ins_t *ins){  mix_address_t addr = get_M_(vm, ins);  mix_ins_id_t id = mix_ins_id_from_ins(*ins);  mix_word_t from;    g_assert(id >= mix_STA && id <= mix_STZ);  switch (id) {  case mix_STA: from = get_rA_(vm); break;  case mix_STX: from = get_rX_(vm); break;  case mix_STJ: from = get_rJ_(vm); break;  case mix_STZ: from = MIX_WORD_ZERO; break;  default: from = get_rI_(vm, id - mix_ST1 + 1); break;  }  set_cell_(vm, addr,	    mix_word_store_field(ins->fspec, from,  get_cell_(vm, addr)));  inc_loc_(vm);  return TRUE;}static gboolean jbs_handler_ (mix_vm_t *vm, const mix_ins_t *ins){  g_assert (ins->opcode == mix_opJBUS);  g_return_val_if_fail (ins->fspec < BD_NO_, TRUE);  g_return_val_if_fail (get_dev_ (vm, ins->fspec) != NULL, TRUE);  if ( mix_device_busy (get_dev_ (vm, ins->fspec)) ) {      set_rJ_(vm, get_loc_ (vm));      set_loc_ (vm, get_M_ (vm, ins));  } else inc_loc_ (vm);  return TRUE;}static gboolean ioc_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_opIOC);  addr = get_M_ (vm, ins);  g_return_val_if_fail (ins->fspec < BD_NO_, TRUE);  dev = get_dev_ (vm, ins->fspec);  g_return_val_if_fail (dev != NULL, TRUE);  result =    mix_device_ioc (dev, addr);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -