Exemple #1
0
void vm_op_mdi(vm_t* vm, uint16_t b, uint16_t a)
{
	uint16_t val_a;
	uint16_t val_b;
	int16_t val_b_signed;
	uint16_t* store_b;
	val_a = vm_resolve_value(vm, a, POS_A);
	val_b = vm_resolve_value_once(vm, b, POS_B);
	store_b = vm_internal_get_store(vm, b, POS_B);
	OP_NUM_CYCLES(3);

	VM_SKIP_RESET;

	// compute 2s complement
	if (val_b > (2 ^ 8))
		val_b_signed = 0 - (0x10000 - val_b);
	else
		val_b_signed = val_b;

	if (val_a != 0)
		*store_b = val_b_signed % val_a;
	else
		*store_b = 0;

	VM_HOOK_FIRE(store_b);
}
Exemple #2
0
void vm_op_hcf(vm_t* vm, uint16_t a)
{
    uint16_t val_a = vm_resolve_value(vm, a, POS_A);
    (void)val_a;
    OP_NUM_CYCLES(9);
    vm->halted = true;
}
Exemple #3
0
void vm_op_hwq(vm_t* vm, uint16_t a)
{
	hw_t queried_device;
	uint16_t* store_a = vm_internal_get_store(vm, REG_A, POS__);
	uint16_t* store_b = vm_internal_get_store(vm, REG_B, POS__);
	uint16_t* store_c = vm_internal_get_store(vm, REG_C, POS__);
	uint16_t* store_x = vm_internal_get_store(vm, REG_X, POS__);
	uint16_t* store_y = vm_internal_get_store(vm, REG_Y, POS__);

	uint16_t val_a = vm_resolve_value(vm, a, POS_A);
	OP_NUM_CYCLES(4);

	VM_SKIP_RESET;
	if (val_a < vm_hw_count(vm))
	{
		queried_device = vm_hw_get_device(vm, val_a);

		printd(LEVEL_DEBUG, "hwq: index %d %08X\n", val_a, queried_device.id);

		*store_a = (queried_device.id & 0x0000FFFF) >>	0;
		*store_b = (queried_device.id & 0xFFFF0000) >> 16;
		*store_c = queried_device.version;
		*store_x = (queried_device.manufacturer & 0x0000FFFF) >>  0;
		*store_y = (queried_device.manufacturer & 0xFFFF0000) >> 16;

		VM_HOOK_FIRE(store_a);
		VM_HOOK_FIRE(store_b);
		VM_HOOK_FIRE(store_c);
		VM_HOOK_FIRE(store_x);
		VM_HOOK_FIRE(store_y);
	}
Exemple #4
0
void vm_op_dvi(vm_t* vm, uint16_t b, uint16_t a)
{
	uint16_t val_a;
	int16_t val_b;
	uint16_t* store_b;
	val_a = vm_resolve_value(vm, a, POS_A);
	val_b = (int16_t)vm_resolve_value_once(vm, b, POS_B);
	store_b = vm_internal_get_store(vm, b, POS_B);
	OP_NUM_CYCLES(3);

	VM_SKIP_RESET;

	if (val_a != 0)
	{
		*store_b = val_b / val_a;
		vm->ex = ((val_b << 16) / val_a) & 0xffff;
	}
	else
	{
		*store_b = 0;
		vm->ex = 0;
	}

	VM_HOOK_FIRE(store_b);
}
Exemple #5
0
void vm_op_int(vm_t* vm, uint16_t a)
{
	uint16_t val_a = vm_resolve_value(vm, a, POS_A);
	OP_NUM_CYCLES(4);

	printd(LEVEL_DEBUG, "sending interrupt %u\n", val_a);
	vm_interrupt(vm, val_a);
}
Exemple #6
0
void vm_op_jsr(vm_t* vm, uint16_t a)
{
	uint16_t val_a = vm_resolve_value(vm, a, POS_A);
	uint16_t t;
	OP_NUM_CYCLES(3);

	VM_SKIP_RESET;
	t = --vm->sp;
	vm->ram[t] = vm->pc;
	vm->pc = val_a;
}
Exemple #7
0
void vm_op_hwn(vm_t* vm, uint16_t a)
{
    uint16_t* store_a = vm_internal_get_store(vm, a, POS_A);
    OP_NUM_CYCLES(2);

    VM_SKIP_RESET;

    *store_a = vm_hw_count(vm);

    VM_HOOK_FIRE(store_a);
    vm->skip = false;
}
Exemple #8
0
void vm_op_rfi(vm_t* vm, uint16_t a)
{
	uint16_t val_a = vm_resolve_value(vm, a, POS_A);
	OP_NUM_CYCLES(3);
	VM_SKIP_RESET;
	vm->registers[REG_A] = vm->ram[vm->sp++];
	vm->pc = vm->ram[vm->sp++];
	printd(LEVEL_DEBUG, "turning off interrupt queue\n");
	vm->queue_interrupts = false;
	printd(LEVEL_DEBUG, "returning from interrupt.\n");
	VM_HOOK_FIRE(&vm->registers[REG_A]);
}
Exemple #9
0
void vm_op_xor(vm_t* vm, uint16_t b, uint16_t a)
{
	uint16_t val_b, val_a;
	uint16_t* store_b;
	val_a = vm_resolve_value(vm, a, POS_A);
	val_b = vm_resolve_value_once(vm, b, POS_B);
	store_b = vm_internal_get_store(vm, b, POS_B);
	OP_NUM_CYCLES(1);

	VM_SKIP_RESET;
	*store_b = val_b ^ val_a;
	VM_HOOK_FIRE(store_b);
}
Exemple #10
0
void vm_op_set(vm_t* vm, uint16_t b, uint16_t a)
{
	uint16_t val_a;
	uint16_t* store_b;
	val_a = vm_resolve_value(vm, a, POS_A);
	store_b = vm_internal_get_store(vm, b, POS_B);
	OP_NUM_CYCLES(1);

	VM_SKIP_RESET;
	*store_b = val_a;
	VM_HOOK_FIRE(store_b);
	vm->skip = false;
}
Exemple #11
0
void vm_op_shl(vm_t* vm, uint16_t b, uint16_t a)
{
	uint16_t val_b, val_a;
	uint16_t* store_b;
	val_a = vm_resolve_value(vm, a, POS_A);
	val_b = vm_resolve_value_once(vm, b, POS_B);
	store_b = vm_internal_get_store(vm, b, POS_B);
	OP_NUM_CYCLES(1);

	VM_SKIP_RESET;
	*store_b = val_b << val_a;
	vm->ex = ((val_b << val_a) >> 16) & 0xffff;
	VM_HOOK_FIRE(store_b);
}
Exemple #12
0
void vm_op_sub(vm_t* vm, uint16_t b, uint16_t a)
{
	uint16_t val_b, val_a;
	uint16_t* store_b;
	val_a = vm_resolve_value(vm, a, POS_A);
	val_b = vm_resolve_value_once(vm, b, POS_B);
	store_b = vm_internal_get_store(vm, b, POS_B);
	OP_NUM_CYCLES(2);

	VM_SKIP_RESET;
	*store_b = val_b - val_a;
	VM_CHECK_ARITHMETIC_FLOW(-, val_b, val_a);
	VM_HOOK_FIRE(store_b);
}
Exemple #13
0
void vm_op_adx(vm_t* vm, uint16_t b, uint16_t a)
{
	uint16_t val_b, val_a, val_ex;
	uint16_t* store_b;
	val_a = vm_resolve_value(vm, a, POS_A);
	val_b = vm_resolve_value_once(vm, b, POS_B);
	store_b = vm_internal_get_store(vm, b, POS_B);
	OP_NUM_CYCLES(3);

	val_ex = vm->ex;
	VM_SKIP_RESET;
	*store_b = val_b + val_a + val_ex;
	VM_CHECK_ARITHMETIC_FLOW_EX(+, val_b, val_a, val_ex);
	VM_HOOK_FIRE(store_b);
}
Exemple #14
0
void vm_op_mli(vm_t* vm, uint16_t b, uint16_t a)
{
    int16_t val_a;
    int16_t val_b;
    uint16_t* store_b;
    val_a = vm_resolve_value(vm, a, POS_A);
    store_b = vm_internal_get_store(vm, b, POS_B);
    val_b = *store_b;
    OP_NUM_CYCLES(2);

    VM_SKIP_RESET;
    *store_b = val_b * val_a;
    vm->ex = ((val_b * val_a) >> 16) & 0xffff;
    VM_HOOK_FIRE(store_b);
}
Exemple #15
0
void vm_op_mod(vm_t* vm, uint16_t b, uint16_t a)
{
	uint16_t val_b, val_a;
	uint16_t* store_b;
	val_a = vm_resolve_value(vm, a, POS_A);
	val_b = vm_resolve_value_once(vm, b, POS_B);
	store_b = vm_internal_get_store(vm, b, POS_B);
	OP_NUM_CYCLES(3);

	VM_SKIP_RESET;

	if (val_a != 0)
		*store_b = val_b % val_a;
	else
		*store_b = 0;

	VM_HOOK_FIRE(store_b);
}
Exemple #16
0
void vm_op_asr(vm_t* vm, uint16_t b, uint16_t a)
{
	// TODO: This may not infact be correct.  C uses
	// arithmetic shifts if the left-hand value is
	// signed, however, we still need to make sure that the
	// excess register is completely compliant.
	int16_t val_b, val_a;
	uint16_t* store_b;
	val_a = (int16_t)vm_resolve_value(vm, a, POS_A);
	val_b = (int16_t)vm_resolve_value_once(vm, b, POS_B);
	store_b = vm_internal_get_store(vm, b, POS_B);
	OP_NUM_CYCLES(1);

	VM_SKIP_RESET;
	*store_b = val_b >> val_a;
	vm->ex = ((val_b << 16) >> val_a) & 0xffff;
	VM_HOOK_FIRE(store_b);
}
Exemple #17
0
void vm_op_iaq(vm_t* vm, uint16_t a)
{
    uint16_t val_a = vm_resolve_value(vm, a, POS_A);
    OP_NUM_CYCLES(2);

    VM_SKIP_RESET;

    printd(LEVEL_DEBUG, "IAQ CALLED WITH %u\n", val_a);

    if (val_a == 0)
    {
        printd(LEVEL_DEBUG, "turning off interrupt queue\n");
        vm->queue_interrupts = false;
    }
    else
    {
        printd(LEVEL_DEBUG, "turning on interrupt queue\n");
        vm->queue_interrupts = true;
    }
}