commit 6bd8a1b98acaa0f692e80a8758cc8b44772ac1b2
parent 65dfe3f0a7339cc0be4da92e771b7c5c64fdd550
Author: bsandro <[email protected]>
Date: Sun, 9 Jan 2022 22:41:24 +0200
unix line endings
Diffstat:
M | main.c | | | 131 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- |
1 file changed, 129 insertions(+), 2 deletions(-)
diff --git a/main.c b/main.c
@@ -1 +1,128 @@
-#pragma gcc_extensions on #include <stdio.h>#include <assert.h>#include <stdint.h>#include <stdlib.h>#include <sys/stat.h>#define FILENAME "um.um"#define PLATTER_SIZE 4struct array_t { uint32_t *data; size_t size;};struct arena_t { struct array_t *arrays; uint32_t size;};struct state_t { struct arena_t arena; uint32_t registers[8];};enum opcode_t { CMOV = 0, ARRI = 1, ARRA = 2, ADD = 3, MUL = 4, DIV = 5, NOTA = 6, HALT = 7, ALLO = 8, ABAN = 9, OUTP = 10, INP = 11, LOAD = 12, ORTH = 13};struct instruction_t { enum opcode_t opcode; uint8_t reg_a, reg_b, reg_c; uint32_t value;};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);int main(void){ FILE *f = fopen(FILENAME, "r"); uint32_t finger = 0; struct stat fileinfo; size_t read_platters = 0; struct state_t state = {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 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); while (1) { uint32_t platter; struct instruction_t instruction = {0}; platter = state.arena.arrays[0].data[finger]; instruction.opcode = platter >> 28; if (instruction.opcode == ORTH) { instruction.reg_a = ((platter >> 25) & 7); instruction.value = platter & 0x1FFFFFF; } else { instruction.reg_a = (platter & 448) >> 6; // mask 111 000 000 = 448 instruction.reg_b = (platter & 56) >> 3; // mask 000 111 000 = 56 instruction.reg_c = platter & 7; // mask 000 000 111 = 7 } print_instruction(instruction); exec_instruction(&state, instruction); finger++; if (finger >= state.arena.arrays[0].size / PLATTER_SIZE) { break; } } fclose(f); //getchar(); // in case SIOUX starts closing the window after exec again return 0;}char * int2bin(uint32_t num) { static char str[33] = {'\0'}; int cnt = 0; uint32_t i; for (i = 1 << 31; i > 0; i >>= 1) { str[cnt++] = ((num & i) == i) ? '1' : '0'; assert(cnt < 34); } str[32] = '\0'; return str;}void print_instruction(struct instruction_t instruction) { printf("%2d: A:%d B:%d C:%d value:%lu\n", instruction.opcode, instruction.reg_a, instruction.reg_b, instruction.reg_c, instruction.value);}void exec_instruction(struct state_t *state, struct instruction_t in) { (void)state; (void)in;}uint32_t array_add(struct arena_t *arena, uint32_t size) { uint32_t array_index = arena->size++; assert(size != NULL); 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].size = size; assert(arena->arrays[array_index].data != NULL); return array_index;}
-\ No newline at end of file
+#pragma gcc_extensions on
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#define FILENAME "um.um"
+#define PLATTER_SIZE 4
+
+struct array_t {
+ uint32_t *data;
+ size_t size;
+};
+
+struct arena_t {
+ struct array_t *arrays;
+ uint32_t size;
+};
+
+struct state_t {
+ struct arena_t arena;
+ uint32_t registers[8];
+};
+
+enum opcode_t {
+ CMOV = 0,
+ ARRI = 1,
+ ARRA = 2,
+ ADD = 3,
+ MUL = 4,
+ DIV = 5,
+ NOTA = 6,
+ HALT = 7,
+ ALLO = 8,
+ ABAN = 9,
+ OUTP = 10,
+ INP = 11,
+ LOAD = 12,
+ ORTH = 13
+};
+
+struct instruction_t {
+ enum opcode_t opcode;
+ uint8_t reg_a, reg_b, reg_c;
+ uint32_t value;
+};
+
+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);
+
+int main(void)
+{
+ FILE *f = fopen(FILENAME, "r");
+ uint32_t finger = 0;
+ struct stat fileinfo;
+ size_t read_platters = 0;
+ struct state_t state = {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
+ 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);
+
+ while (1) {
+ uint32_t platter;
+ struct instruction_t instruction = {0};
+ platter = state.arena.arrays[0].data[finger];
+ instruction.opcode = platter >> 28;
+ if (instruction.opcode == ORTH) {
+ instruction.reg_a = ((platter >> 25) & 7);
+ instruction.value = platter & 0x1FFFFFF;
+ } else {
+ instruction.reg_a = (platter & 448) >> 6; // mask 111 000 000 = 448
+ instruction.reg_b = (platter & 56) >> 3; // mask 000 111 000 = 56
+ instruction.reg_c = platter & 7; // mask 000 000 111 = 7
+ }
+ print_instruction(instruction);
+ exec_instruction(&state, instruction);
+ finger++;
+ if (finger >= state.arena.arrays[0].size / PLATTER_SIZE) {
+ break;
+ }
+ }
+
+ fclose(f);
+ //getchar(); // in case SIOUX starts closing the window after exec again
+ return 0;
+}
+
+char * int2bin(uint32_t num) {
+ static char str[33] = {'\0'};
+ int cnt = 0;
+ uint32_t i;
+ for (i = 1 << 31; i > 0; i >>= 1) {
+ str[cnt++] = ((num & i) == i) ? '1' : '0';
+ assert(cnt < 34);
+ }
+ str[32] = '\0';
+ return str;
+}
+
+void print_instruction(struct instruction_t instruction) {
+ printf("%2d: A:%d B:%d C:%d value:%lu\n", instruction.opcode, instruction.reg_a, instruction.reg_b, instruction.reg_c, instruction.value);
+}
+
+void exec_instruction(struct state_t *state, struct instruction_t in) {
+ (void)state;
+ (void)in;
+}
+
+uint32_t array_add(struct arena_t *arena, uint32_t size) {
+ uint32_t array_index = arena->size++;
+ assert(size != NULL);
+ 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].size = size;
+ assert(arena->arrays[array_index].data != NULL);
+ return array_index;
+}
+\ No newline at end of file