commit 1ca2c2fcdc0645612f90f8a0e6a152ab9ac110dc
parent 05ba1a534e7081c3aaed75570bf6715175db2108
Author: bsandro <brian.drosan@gmail.com>
Date: Mon, 10 Jan 2022 00:23:34 +0200
rest of the opcodes
Diffstat:
M | main.c | | | 74 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------- |
1 file changed, 63 insertions(+), 11 deletions(-)
diff --git a/main.c b/main.c
@@ -4,9 +4,10 @@
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/stat.h>
-#define FILENAME "um.um"
+#define FILENAME "sandmark.umz"
#define PLATTER_SIZE 4
struct array_t {
@@ -22,6 +23,7 @@ struct arena_t {
struct state_t {
struct arena_t arena;
uint32_t registers[8];
+ uint32_t finger;
};
enum opcode_t {
@@ -50,22 +52,26 @@ struct instruction_t {
char * int2bin(uint32_t num);
void print_instruction(struct instruction_t instruction);
void exec_instruction(struct state_t *state, struct instruction_t in);
-uint32_t array_add(struct arena_t *arena, uint32_t size);
+uint32_t array_new(struct arena_t *arena, uint32_t size);
+void array_free(struct arena_t *arena, uint32_t index);
+void array_dup(struct arena_t *arena, uint32_t index);
int main(void)
{
FILE *f = fopen(FILENAME, "r");
- uint32_t finger = 0;
+ struct state_t state = {0};
struct stat fileinfo;
size_t read_platters = 0;
- struct state_t state = {0};
+
+ state.finger = 0;
state.arena.arrays = NULL;
state.arena.size = 0;
+
assert(f != NULL);
stat(FILENAME, &fileinfo);
assert(fileinfo.st_size % PLATTER_SIZE == 0);
printf("%s (%lu bytes):\n", FILENAME, fileinfo.st_size);
- array_add(&state.arena, fileinfo.st_size); // Initial array #0
+ array_new(&state.arena, fileinfo.st_size / PLATTER_SIZE); // Initial array #0
read_platters = fread(state.arena.arrays[0].data, PLATTER_SIZE, fileinfo.st_size / PLATTER_SIZE, f);
assert(fileinfo.st_size == read_platters * PLATTER_SIZE);
printf("read ok, %lu platters (%lu bytes)\n", read_platters, state.arena.arrays[0].size);
@@ -73,7 +79,7 @@ int main(void)
while (1) {
uint32_t platter;
struct instruction_t instruction = {0};
- platter = state.arena.arrays[0].data[finger];
+ platter = state.arena.arrays[0].data[state.finger];
instruction.opcode = platter >> 28;
if (instruction.opcode == ORTH) {
instruction.reg_a = ((platter >> 25) & 7);
@@ -84,9 +90,9 @@ int main(void)
instruction.reg_c = platter & 7; // mask 000 000 111 = 7
}
//print_instruction(instruction);
+ state.finger++;
exec_instruction(&state, instruction);
- finger++;
- if (finger >= state.arena.arrays[0].size / PLATTER_SIZE) {
+ if (state.finger >= state.arena.arrays[0].size / PLATTER_SIZE) {
break;
}
}
@@ -135,15 +141,61 @@ void exec_instruction(struct state_t *state, struct instruction_t in) {
case NOTA:
state->registers[in.reg_a] = ~(state->registers[in.reg_b] & state->registers[in.reg_c]);
break;
+ case HALT:
+ printf("HALT\n");
+ exit(0);
+ break;
+ case ALLO:
+ state->registers[in.reg_b] = array_new(&state->arena, state->registers[in.reg_c]);
+ break;
+ case ABAN:
+ array_free(&state->arena, state->registers[in.reg_c]);
+ break;
+ case OUTP:
+ putchar(state->registers[in.reg_c]);
+ break;
+ case INP:
+ {
+ int c = getchar();
+ state->registers[in.reg_c] = (c == EOF) ? 0xFFFFFFFF : c;
+ }
+ break;
+ case LOAD:
+ {
+ array_dup(&state->arena, state->registers[in.reg_b]);
+ state->finger = state->registers[in.reg_c];
+ }
+ break;
+ case ORTH:
+ state->registers[in.reg_a] = in.value;
+ break;
+ default:
+ printf("invalid opcode\n");
+ exit(1);
}
}
-uint32_t array_add(struct arena_t *arena, uint32_t size) {
+uint32_t array_new(struct arena_t *arena, uint32_t size) {
uint32_t array_index = arena->size++;
- assert(size != NULL);
+ assert(arena != NULL);
+ assert(size != 0);
arena->arrays = (struct array_t *)realloc(arena->arrays, arena->size * sizeof(struct array_t));
- arena->arrays[array_index].data = (uint32_t *)malloc(size);
+ arena->arrays[array_index].data = (uint32_t *)calloc(size, PLATTER_SIZE);
arena->arrays[array_index].size = size;
assert(arena->arrays[array_index].data != NULL);
return array_index;
+}
+
+void array_free(struct arena_t *arena, uint32_t index) {
+ assert(index < arena->size);
+ free(arena->arrays[index].data);
+ arena->arrays[index].size = 0;
+}
+
+void array_dup(struct arena_t *arena, uint32_t index) {
+ assert(index < arena->size);
+ array_free(arena, 0);
+ arena->arrays[0].data = (uint32_t *)malloc(arena->arrays[index].size * PLATTER_SIZE);
+ memcpy(arena->arrays[0].data, arena->arrays[index].data, arena->arrays[index].size * PLATTER_SIZE);
+ arena->arrays[0].size = arena->arrays[index].size;
}
\ No newline at end of file