📄 mix_vm.c
字号:
/* -*-c-*- ------------------ mix_vm.c : * Implementation of the functions declared in mix_vm.h * ------------------------------------------------------------------ * Copyright (C) 2000, 2001 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 "mix.h"#include "xmix_vm.h"#define vm_reset_(vm) vm_reset_reload_ (vm, FALSE);static voidvm_reset_reload_ (mix_vm_t *vm, gboolean is_reload){ guint k; set_status_ (vm, MIX_VM_EMPTY); set_rA_ (vm, MIX_WORD_ZERO); set_rX_ (vm, MIX_WORD_ZERO); set_rJ_ (vm, MIX_WORD_ZERO); for ( k = 1; k < IREG_NO_+1; ++k ) set_rI_ (vm, k, MIX_WORD_ZERO); set_over_ (vm, FALSE); set_cmp_ (vm, mix_EQ); set_loc_ (vm, MIX_WORD_ZERO); for ( k = 0; k < MEM_CELLS_NO_; ++k) set_cell_ (vm, k, MIX_WORD_ZERO); if (vm->symbol_table != NULL ) { mix_symbol_table_delete (vm->symbol_table); vm->symbol_table = NULL; } if (vm->line_table != NULL) { g_tree_destroy (vm->line_table); vm->line_table = NULL; } if (vm->address_table != NULL) { g_tree_destroy (vm->address_table); vm->address_table = NULL; } if (vm->src_file != NULL) { mix_src_file_delete (vm->src_file); vm->src_file = NULL; } for (k = 0; k < BD_NO_; ++k) if (vm->devices[k] != NULL) { mix_device_delete (vm->devices[k]); vm->devices[k] = NULL; } if (!is_reload) mix_vm_clear_all_breakpoints (vm); if (vm->address_list) { g_slist_free (vm->address_list); vm->address_list = NULL; }}/* Create/destroy a mix vm */mix_vm_t *mix_vm_new (void){ int i; mix_vm_t *vm = g_new (struct mix_vm_t,1); vm->line_table = NULL; vm->address_table = NULL; vm->symbol_table = NULL; vm->src_file = NULL; vm->pred_list = mix_predicate_list_new (vm); vm->address_list = NULL; for (i = 0; i < BD_NO_; ++i) vm->devices[i] = NULL; vm->clock = mix_vm_clock_new (); vm->factory = mix_device_new; vm_reset_ (vm); return vm;}voidmix_vm_delete (mix_vm_t * vm){ int i; g_return_if_fail (vm != NULL); if (vm->line_table != NULL) g_tree_destroy (vm->line_table); if (vm->address_table != NULL) g_tree_destroy (vm->address_table); if (vm->symbol_table != NULL) mix_symbol_table_delete (vm->symbol_table); if (vm->src_file != NULL) mix_src_file_delete (vm->src_file); if (vm->pred_list != NULL) mix_predicate_list_delete (vm->pred_list); if (vm->address_list != NULL) g_slist_free (vm->address_list); for (i = 0; i < BD_NO_; ++i) mix_device_delete (vm->devices[i]); mix_vm_clock_delete (vm->clock); g_free (vm);}/* connect devices to a virtual machine */mix_device_t *mix_vm_connect_device (mix_vm_t *vm, mix_device_t *device){ mix_device_t *old; mix_device_type_t type; g_return_val_if_fail (vm != NULL, NULL); g_return_val_if_fail (device != NULL, NULL); type = mix_device_type (device); old = vm->devices[type]; vm->devices[type] = device; return old;}/* get device */mix_device_t *mix_vm_get_device (const mix_vm_t *vm, mix_device_type_t dev){ g_return_val_if_fail (vm != NULL, NULL); g_return_val_if_fail (dev < mix_dev_INVALID, NULL); return vm->devices[dev];}/* install a device factory for automatic connection */voidmix_vm_set_device_factory (mix_vm_t *vm, mix_device_factory_t factory){ g_return_if_fail (vm != NULL); g_return_if_fail (factory != NULL); vm->factory = factory;}/* Reset a vm (set state as of a newly created one) */voidmix_vm_reset (mix_vm_t * vm){ g_return_if_fail (vm != NULL); vm_reset_ (vm);}/* Set start address for execution */voidmix_vm_set_start_addr (mix_vm_t *vm, mix_address_t addr){ g_return_if_fail (vm != NULL); set_loc_ (vm, addr);}/* Access to the vm's registers */mix_word_tmix_vm_get_rA (const mix_vm_t *vm){ g_return_val_if_fail (vm != NULL, MIX_WORD_ZERO); return get_rA_ (vm);}mix_word_tmix_vm_get_rX (const mix_vm_t *vm){ g_return_val_if_fail (vm != NULL, MIX_WORD_ZERO); return get_rX_ (vm);}mix_short_tmix_vm_get_rJ (const mix_vm_t *vm){ g_return_val_if_fail (vm != NULL, MIX_SHORT_ZERO); return mix_word_to_short_fast (get_rJ_ (vm));}mix_short_tmix_vm_get_rI (const mix_vm_t *vm, guint idx){ g_return_val_if_fail (vm != NULL, MIX_SHORT_ZERO); g_return_val_if_fail (IOK_ (idx), MIX_SHORT_ZERO); return mix_word_to_short_fast (get_rI_ (vm, idx));}void mix_vm_set_rA (mix_vm_t *vm, mix_word_t value){ g_return_if_fail (vm != NULL); set_rA_ (vm, value);}voidmix_vm_set_rX (mix_vm_t *vm, mix_word_t value){ g_return_if_fail (vm != NULL); set_rX_ (vm, value);}void mix_vm_set_rJ (mix_vm_t *vm, mix_short_t value){ g_return_if_fail (vm != NULL); g_return_if_fail (mix_short_is_positive (value)); set_rJ_ (vm, mix_short_to_word_fast (value));}void mix_vm_set_rI (mix_vm_t *vm, guint idx, mix_short_t value){ g_return_if_fail (vm != NULL); g_return_if_fail (IOK_ (idx)); set_rI_ (vm, idx, mix_short_to_word_fast (value));}/* Access to the comparison flag and overflow toggle */mix_cmpflag_tmix_vm_get_cmpflag (const mix_vm_t *vm){ g_return_val_if_fail (vm != NULL, mix_EQ); return get_cmp_ (vm);}voidmix_vm_set_cmpflag (mix_vm_t *vm, mix_cmpflag_t value){ g_return_if_fail (vm != NULL); set_cmp_ (vm, value);}gbooleanmix_vm_get_overflow (const mix_vm_t *vm){ g_return_val_if_fail (vm != NULL, TRUE); return get_over_ (vm);}voidmix_vm_set_overflow (mix_vm_t *vm, gboolean value){ g_return_if_fail (vm != NULL); set_over_ (vm, value);}voidmix_vm_toggle_overflow (mix_vm_t *vm){ g_return_if_fail (vm != NULL); set_over_ (vm, !get_over_ (vm));}/* Access to memory cells */mix_word_tmix_vm_get_addr_contents (const mix_vm_t *vm, mix_address_t addr){ g_return_val_if_fail (vm != NULL, MIX_WORD_ZERO); g_return_val_if_fail (MEMOK_ (addr), MIX_WORD_ZERO); return get_cell_ (vm, addr);}voidmix_vm_set_addr_contents (mix_vm_t *vm, mix_address_t addr, mix_word_t value){ g_return_if_fail (vm != NULL); g_return_if_fail (MEMOK_ (addr)); set_cell_ (vm, addr, value);}gbooleanmix_vm_is_halted (const mix_vm_t *vm){ return is_halted_ (vm);}/* Execution of instructions */gboolean /* TRUE if success */mix_vm_exec_ins (mix_vm_t *vm, const mix_ins_t *ins){ g_return_val_if_fail (vm != NULL, FALSE); g_return_val_if_fail (ins != NULL, FALSE); return (*ins_handlers_[ins->opcode]) (vm,ins);}/* comparison function for the line and address tables tree */static gintcmp_uint_ (gconstpointer a, gconstpointer b){ return GPOINTER_TO_UINT (a) - GPOINTER_TO_UINT (b);}gbooleanmix_vm_load_file (mix_vm_t *vm, const gchar *name){ mix_code_file_t *file; mix_src_file_t *sfile = NULL; mix_ins_desc_t ins; const gchar *sp; gboolean reload = FALSE; g_return_val_if_fail (vm != NULL, FALSE); file = mix_code_file_new_read (name); if (file == NULL) { set_status_ (vm, MIX_VM_ERROR); return FALSE; } sp = mix_code_file_get_source_path (file); if (sp != NULL) { sfile = mix_src_file_new_for_read (sp); reload = (vm->src_file && !strcmp (mix_src_file_get_path (vm->src_file),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -