summaryrefslogtreecommitdiffhomepage
path: root/mixlib/xmix_vm.c
diff options
context:
space:
mode:
Diffstat (limited to 'mixlib/xmix_vm.c')
-rw-r--r--mixlib/xmix_vm.c123
1 files changed, 77 insertions, 46 deletions
diff --git a/mixlib/xmix_vm.c b/mixlib/xmix_vm.c
index 718a9d3..ecb67c9 100644
--- a/mixlib/xmix_vm.c
+++ b/mixlib/xmix_vm.c
@@ -56,6 +56,20 @@ get_dev_ (mix_vm_t *vm, mix_fspec_t type)
return vm->devices[type];
}
+/* error macro */
+#define fail_if_not_(vm,cond,error) \
+do { \
+ if (!(cond)) \
+ { \
+ set_last_error_ (vm, error); \
+ return FALSE; \
+ } \
+} while (FALSE)
+
+#define fail_(vm,error) fail_if_not_ (vm, FALSE, error)
+
+#define fail_unexpected_(vm) fail_ (vm, MIX_VM_ERROR_UNEXPECTED)
+
/* Instruction handlers */
static gboolean
@@ -136,7 +150,7 @@ spc_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
mix_word_negative (num) : num);
break;
}
- default: return FALSE;
+ default: fail_ (vm, MIX_VM_ERROR_BAD_FSPEC);
}
inc_loc_ (vm);
return TRUE;
@@ -148,7 +162,8 @@ 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);
+
+ fail_if_not_ (vm, mix_short_is_positive (n), MIX_VM_ERROR_BAD_M);
switch ( mix_ins_id_from_ins (*ins) ) {
case mix_SLA:
@@ -174,7 +189,7 @@ sla_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
&get_rA_ (vm), &get_rX_ (vm));
break;
default:
- return FALSE;
+ fail_unexpected_ (vm);
}
inc_loc_ (vm);
@@ -189,16 +204,19 @@ mov_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
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;
+ if (mix_short_is_positive (from)
+ && mix_short_is_positive (to)
+ && MEMOK_ (from + delta -1)
+ && MEMOK_ (to + delta - 1))
+ {
+ 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;
+ }
+ else
+ return FALSE;
}
static gboolean
@@ -258,8 +276,10 @@ 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);
+ fail_if_not_ (vm, ins->fspec < BD_NO_, MIX_VM_ERROR_BAD_DEVICE_NO);
+ fail_if_not_ (vm, get_dev_ (vm, ins->fspec) != NULL,
+ MIX_VM_ERROR_BAD_DEVICE_NO);
+
if ( mix_device_busy (get_dev_ (vm, ins->fspec)) ) {
set_rJ_ (vm, get_loc_ (vm));
set_loc_ (vm, get_M_ (vm, ins));
@@ -272,18 +292,19 @@ 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);
+ fail_if_not_ (vm, ins->fspec < BD_NO_, MIX_VM_ERROR_BAD_DEVICE_NO);
+
dev = get_dev_ (vm, ins->fspec);
- g_return_val_if_fail (dev != NULL, TRUE);
- result =
- mix_device_ioc (dev, addr);
+ fail_if_not_ (vm, dev != NULL, MIX_VM_ERROR_BAD_DEVICE_NO);
+
+ fail_if_not_ (vm, mix_device_ioc (dev, addr), MIX_VM_ERROR_DEV_CTL);
inc_loc_ (vm);
- return result;
+ return TRUE;
}
static gboolean
@@ -291,21 +312,24 @@ 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);
+ fail_if_not_ (vm, ins->fspec < BD_NO_, MIX_VM_ERROR_BAD_DEVICE_NO);
+
addr = get_M_ (vm, ins);
- g_return_val_if_fail (ins->fspec < BD_NO_, TRUE);
- g_return_val_if_fail (MEMOK_ (addr), TRUE);
+ fail_if_not_ (vm, MEMOK_ (addr), MIX_VM_ERROR_BAD_ACCESS);
+
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));
+ fail_if_not_ (vm, dev != NULL, MIX_VM_ERROR_BAD_DEVICE_NO);
+
+ fail_if_not_ (vm, MEM_CELLS_NO_ - addr > mix_device_block_size (dev),
+ MIX_VM_ERROR_BAD_ACCESS);
+
+ fail_if_not_ (vm, mix_device_read (dev, get_cell_ptr_ (vm, addr)),
+ MIX_VM_ERROR_DEV_READ);
inc_loc_ (vm);
- return result;
+ return TRUE;
}
static gboolean
@@ -313,29 +337,35 @@ 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);
+
+ fail_if_not_ (vm, ins->fspec < BD_NO_, MIX_VM_ERROR_BAD_DEVICE_NO);
+
addr = get_M_ (vm, ins);
- g_return_val_if_fail (ins->fspec < BD_NO_, TRUE);
- g_return_val_if_fail (MEMOK_ (addr), TRUE);
+ fail_if_not_ (vm, MEMOK_ (addr), MIX_VM_ERROR_BAD_ACCESS);
+
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));
+ fail_if_not_ (vm, dev != NULL, MIX_VM_ERROR_BAD_DEVICE_NO);
+
+ fail_if_not_ (vm, MEM_CELLS_NO_ - addr > mix_device_block_size (dev),
+ MIX_VM_ERROR_BAD_ACCESS);
+
+ fail_if_not_ (vm, mix_device_write (dev, get_cell_ptr_ (vm, addr)),
+ MIX_VM_ERROR_DEV_WRITE);
inc_loc_ (vm);
- return result;
+ return TRUE;
}
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);
+ fail_if_not_ (vm, ins->fspec < BD_NO_, MIX_VM_ERROR_BAD_DEVICE_NO);
+ fail_if_not_ (vm, get_dev_ (vm, ins->fspec) != NULL,
+ MIX_VM_ERROR_BAD_DEVICE_NO);
+
inc_loc_ (vm);
if ( !mix_device_busy (get_dev_ (vm, ins->fspec)) )
{
@@ -353,7 +383,8 @@ jmp_handler_ (mix_vm_t *vm, const mix_ins_t *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);
+ fail_if_not_ (vm, MEMOK_ (addr), MIX_VM_ERROR_BAD_ACCESS);
+
switch ( id ) {
case mix_JMP:
case mix_JSJ:
@@ -386,7 +417,7 @@ jmp_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
jump = ( get_cmp_ (vm) != mix_GREAT );
break;
default:
- return FALSE;
+ fail_unexpected_ (vm);
}
inc_loc_ (vm);
@@ -406,7 +437,7 @@ jpx_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
mix_word_t val;
g_assert (ins->opcode >= mix_opJAx || ins->opcode <= mix_opJXx);
- g_return_val_if_fail (MEMOK_ (addr), FALSE);
+ fail_if_not_ (vm, MEMOK_ (addr), MIX_VM_ERROR_BAD_ACCESS);
switch (ins->opcode) {
case mix_opJAx: val = get_rA_ (vm); break;
@@ -448,7 +479,7 @@ jpx_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
|| mix_word_is_negative (val);
break;
default:
- return FALSE;
+ fail_unexpected_ (vm);
}
inc_loc_ (vm);
@@ -509,7 +540,7 @@ ina_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
mix_word_reverse_sign (val);
break;
default:
- return FALSE;
+ fail_unexpected_ (vm);
}
set_reg_ (vm, r, val);
inc_loc_ (vm);