<commit_before>/**

	File:			dcpubase.c

	Project:		DCPU-16 Tools
	Component:		Emulator

	Authors:		<NAME>
					<NAME>

	Description:	Handles core functionality of
					the virtual machine.

**/

#define PRIVATE_VM_ACCESS

#include <stdarg.h>
#include <stdio.h>
#include "dcpubase.h"
#include "dcpuops.h"
#include "dcpuhook.h"

void vm_halt(vm_t* vm, const char* message, ...)
{
    va_list argptr;
    va_start(argptr, message);
    vfprintf(stderr, message, argptr);
    va_end(argptr);
	vm->halted = true;
	return;
}

void vm_interrupt(vm_t* vm, uint16_t msgid)
{
	if (vm->ia == 0)
		return;
	vm->ram[vm->sp--] = vm->pc;
	vm->ram[vm->sp--] = vm->registers[REG_A];
	vm->pc = vm->ia;
	vm->registers[REG_A] = msgid;
}

uint16_t vm_consume_word(vm_t* vm)
{
	uint16_t v = vm->ram[vm->pc];
	vm->pc++;
	return v;
}

uint16_t vm_resolve_value(vm_t* vm, uint16_t val, uint8_t pos)
{
	uint16_t t;
	switch (val)
	{
	case REG_A:
	case REG_B:
	case REG_C:
	case REG_X:
	case REG_Y:
	case REG_Z:
	case REG_I:
	case REG_J:
		return vm->registers[val];
	case VAL_A:
	case VAL_B:
	case VAL_C:
	case VAL_X:
	case VAL_Y:
	case VAL_Z:
	case VAL_I:
	case VAL_J:
		return vm->ram[vm->registers[val - VAL_A]];
	case NXT_VAL_A:
	case NXT_VAL_B:
	case NXT_VAL_C:
	case NXT_VAL_X:
	case NXT_VAL_Y:
	case NXT_VAL_Z:
	case NXT_VAL_I:
	case NXT_VAL_J:
		return vm->ram[(uint16_t)(vm->registers[val - NXT_VAL_A] + vm_consume_word(vm))];
	case PUSH_POP:
		if (vm->skip) return vm->dummy;
		if (pos == POS_A)
			t = vm->sp++;
		else if (pos == POS_B)
			t = --vm->sp;
		else
			// Probably should handle if pos is neither
			// A nor B to catch internal errors.
			t = vm->sp;
		return vm->ram[t];
	case PEEK:
		t = vm->sp;
		return vm->ram[t];
	case PICK:
		t = vm->sp;
		return vm->ram[(uint16_t)(t + vm_consume_word(vm))];
	case IA:
		return vm->ia;
	case SP:
		return vm->sp;
	case PC:
		return vm->pc;
	case EX:
		return vm->ex;
	case NXT:
		return vm->ram[vm_consume_word(vm)];
	case NXT_LIT:
		t = vm_consume_word(vm);
		if(vm->debug) printf(" (0x%04X) ", t);
		return t;
	default:
		return val - 0x21;
	}
}

void vm_print_op(const char* opname, vm_t* vm, uint16_t a, uint16_t b)
{
	if (!vm->debug)
		return;
	if (vm->skip)
		printf("0x%04X: (skipped) %s 0x%04X 0x%04X", vm->pc, opname, a, b);
	else
		printf("0x%04X: %s 0x%04X 0x%04X", vm->pc, opname, a, b);
}

void vm_print_op_nonbasic(const char* opname, vm_t* vm, uint16_t a)
{
	if (!vm->debug)
		return;
	if (vm->skip)
		printf("0x%04X: (skipped) %s 0x%04X", vm->pc, opname, a);
	else
		printf("0x%04X: %s 0x%04X", vm->pc, opname, a);
}

void vm_cycle(vm_t* vm)
{
        if(vm->sleep_cycles > 0)
        {
            vm->sleep_cycles--;
            return;
        }

	uint16_t instruction = vm_consume_word(vm);
	uint16_t op = INSTRUCTION_GET_OP(instruction);
	uint16_t b = INSTRUCTION_GET_B(instruction);
	uint16_t a = INSTRUCTION_GET_A(instruction);

	if(vm->debug) printf("Instruction: %04X\n", instruction);
	switch (op)
	{
	case OP_SET:
		vm_print_op("SET", vm, b, a);
		vm_op_set(vm, b, a);
		break;<commit_msg>Fixed whitespace.<commit_after>/**

	File:			dcpubase.c

	Project:		DCPU-16 Tools
	Component:		Emulator

	Authors:		<NAME>
					<NAME>

	Description:	Handles core functionality of
					the virtual machine.

**/

#define PRIVATE_VM_ACCESS

#include <stdarg.h>
#include <stdio.h>
#include "dcpubase.h"
#include "dcpuops.h"
#include "dcpuhook.h"

void vm_halt(vm_t* vm, const char* message, ...)
{
    va_list argptr;
    va_start(argptr, message);
    vfprintf(stderr, message, argptr);
    va_end(argptr);
	vm->halted = true;
	return;
}

void vm_interrupt(vm_t* vm, uint16_t msgid)
{
	if (vm->ia == 0)
		return;
	vm->ram[vm->sp--] = vm->pc;
	vm->ram[vm->sp--] = vm->registers[REG_A];
	vm->pc = vm->ia;
	vm->registers[REG_A] = msgid;
}

uint16_t vm_consume_word(vm_t* vm)
{
	uint16_t v = vm->ram[vm->pc];
	vm->pc++;
	return v;
}

uint16_t vm_resolve_value(vm_t* vm, uint16_t val, uint8_t pos)
{
	uint16_t t;
	switch (val)
	{
	case REG_A:
	case REG_B:
	case REG_C:
	case REG_X:
	case REG_Y:
	case REG_Z:
	case REG_I:
	case REG_J:
		return vm->registers[val];
	case VAL_A:
	case VAL_B:
	case VAL_C:
	case VAL_X:
	case VAL_Y:
	case VAL_Z:
	case VAL_I:
	case VAL_J:
		return vm->ram[vm->registers[val - VAL_A]];
	case NXT_VAL_A:
	case NXT_VAL_B:
	case NXT_VAL_C:
	case NXT_VAL_X:
	case NXT_VAL_Y:
	case NXT_VAL_Z:
	case NXT_VAL_I:
	case NXT_VAL_J:
		return vm->ram[(uint16_t)(vm->registers[val - NXT_VAL_A] + vm_consume_word(vm))];
	case PUSH_POP:
		if (vm->skip) return vm->dummy;
		if (pos == POS_A)
			t = vm->sp++;
		else if (pos == POS_B)
			t = --vm->sp;
		else
			// Probably should handle if pos is neither
			// A nor B to catch internal errors.
			t = vm->sp;
		return vm->ram[t];
	case PEEK:
		t = vm->sp;
		return vm->ram[t];
	case PICK:
		t = vm->sp;
		return vm->ram[(uint16_t)(t + vm_consume_word(vm))];
	case IA:
		return vm->ia;
	case SP:
		return vm->sp;
	case PC:
		return vm->pc;
	case EX:
		return vm->ex;
	case NXT:
		return vm->ram[vm_consume_word(vm)];
	case NXT_LIT:
		t = vm_consume_word(vm);
		if(vm->debug) printf(" (0x%04X) ", t);
		return t;
	default:
		return val - 0x21;
	}
}

void vm_print_op(const char* opname, vm_t* vm, uint16_t a, uint16_t b)
{
	if (!vm->debug)
		return;
	if (vm->skip)
		printf("0x%04X: (skipped) %s 0x%04X 0x%04X", vm->pc, opname, a, b);
	else
		printf("0x%04X: %s 0x%04X 0x%04X", vm->pc, opname, a, b);
}

void vm_print_op_nonbasic(const char* opname, vm_t* vm, uint16_t a)
{
	if (!vm->debug)
		return;
	if (vm->skip)
		printf("0x%04X: (skipped) %s 0x%04X", vm->pc, opname, a);
	else
		printf("0x%04X: %s 0x%04X", vm->pc, opname, a);
}

void vm_cycle(vm_t* vm)
{
	if(vm->sleep_cycles > 0)
	{
		vm->sleep_cycles--;
		return;
	}

	uint16_t instruction = vm_consume_word(vm);
	uint16_t op = INSTRUCTION_GET_OP(instruction);
	uint16_t b = INSTRUCTION_GET_B(instruction);
	uint16_t a = INSTRUCTION_GET_A(instruction);

	if(vm->debug) printf("Instruction: %04X\n", instruction);
	switch (op)
	{
	case OP_SET:
		vm_print_op("SET", vm, b, a);
		vm_op_set(vm, b, a);
		break;
{'fraction_non_alphanumeric': 0.1612584417723604, 'fraction_numerical': 0.02404875638280349, 'mean_word_length': 3.579185520361991, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 105, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4183757', 'n_tokens_mistral': 3011, 'n_tokens_neox': 2791, 'n_words': 640}