umx

UMX VM implementation (ifcfc '06)
git clone git://bsandro.tech/umx
Log | Files | Refs

commit 6bd8a1b98acaa0f692e80a8758cc8b44772ac1b2
parent 65dfe3f0a7339cc0be4da92e771b7c5c64fdd550
Author: bsandro <[email protected]>
Date:   Sun,  9 Jan 2022 22:41:24 +0200

unix line endings

Diffstat:
Mmain.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