umx

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

commit 70ff0cf3223855933a456c60b596f5b0116aed02
parent e40b7132628ca99d5a3ebe5d61ea46855c3dd010
Author: bsandro <[email protected]>
Date:   Wed, 12 Jan 2022 02:14:55 +0200

instruction is passed by ptr and not copied

Diffstat:
Mmain.c | 60+++++++++++++++++++++++++++++++-----------------------------
Mumx | 0
2 files changed, 31 insertions(+), 29 deletions(-)

diff --git a/main.c b/main.c @@ -59,15 +59,16 @@ 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); +void print_instruction(struct instruction_t *instruction); +void exec_instruction(struct state_t *state, struct instruction_t *in); 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) +int main(int argc, char *argv[]) { - FILE *f = fopen(FILENAME, "rb"); + char *fname = argc > 1 ? argv[1] : FILENAME; + FILE *f = fopen(fname, "rb"); struct state_t *state = (struct state_t *)malloc(sizeof(struct state_t)); struct stat fileinfo; size_t read_platters = 0; @@ -75,15 +76,17 @@ int main(void) memset(state, 0, sizeof(struct state_t)); assert(f != NULL); - stat(FILENAME, &fileinfo); + stat(fname, &fileinfo); assert(fileinfo.st_size % PLATTER_SIZE == 0); - printf("%s (%lu bytes):\n", FILENAME, fileinfo.st_size); + //printf("%s (%lu bytes):\n", fname, fileinfo.st_size); 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); + //printf("read ok, %lu platters (%lu bytes)\n", read_platters, state->arena.arrays[0].size); fclose(f); + fflush(stdout); + while (1) { struct instruction_t instruction = {0}; uint32_t platter = _NTOHL(state->arena.arrays[0].data[state->finger]); @@ -98,9 +101,9 @@ int main(void) instruction.reg_c = platter & 7; // mask 000 000 111 = 7 } //printf("[%2d][%8x]\n", state->finger, platter); - //print_instruction(instruction); + //print_instruction(&instruction); state->finger++; - exec_instruction(state, instruction); + exec_instruction(state, &instruction); //sleep(1); } @@ -120,60 +123,59 @@ char * int2bin(uint32_t num) { 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 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) { - switch (in.opcode) { +void exec_instruction(struct state_t *state, struct instruction_t *in) { + switch (in->opcode) { case CMOV: - if (state->registers[in.reg_c] != 0) state->registers[in.reg_a] = state->registers[in.reg_b]; + if (state->registers[in->reg_c] != 0) state->registers[in->reg_a] = state->registers[in->reg_b]; break; case ARRI: - state->registers[in.reg_a] = _NTOHL(state->arena.arrays[state->registers[in.reg_b]].data[state->registers[in.reg_c]]); + state->registers[in->reg_a] = _NTOHL(state->arena.arrays[state->registers[in->reg_b]].data[state->registers[in->reg_c]]); break; case ARRA: - state->arena.arrays[state->registers[in.reg_a]].data[state->registers[in.reg_b]] = _HTONL(state->registers[in.reg_c]); + state->arena.arrays[state->registers[in->reg_a]].data[state->registers[in->reg_b]] = _HTONL(state->registers[in->reg_c]); break; case ADD: - state->registers[in.reg_a] = state->registers[in.reg_b] + state->registers[in.reg_c]; //@todo: modulo 2^32 ? + state->registers[in->reg_a] = state->registers[in->reg_b] + state->registers[in->reg_c]; //@todo: modulo 2^32 ? break; case MUL: - state->registers[in.reg_a] = state->registers[in.reg_b] * state->registers[in.reg_c]; //@todo: modulo 2^32 ? + state->registers[in->reg_a] = state->registers[in->reg_b] * state->registers[in->reg_c]; //@todo: modulo 2^32 ? break; case DIV: - state->registers[in.reg_a] = state->registers[in.reg_b] / state->registers[in.reg_c]; //@todo: modulo 2^32 ? + state->registers[in->reg_a] = state->registers[in->reg_b] / state->registers[in->reg_c]; //@todo: modulo 2^32 ? break; case NOTA: - state->registers[in.reg_a] = ~(state->registers[in.reg_b] & state->registers[in.reg_c]); + 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]); + 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]); + array_free(&state->arena, state->registers[in->reg_c]); break; case OUTP: - putchar(state->registers[in.reg_c]); + putchar(state->registers[in->reg_c]); break; case INP: { int c = getchar(); - state->registers[in.reg_c] = (c == EOF) ? 0xFFFFFFFFUL : c; + state->registers[in->reg_c] = (c == EOF) ? 0xFFFFFFFFUL : c; } break; case LOAD: - if (state->registers[in.reg_b] != 0) { - array_dup(&state->arena, state->registers[in.reg_b]); + if (state->registers[in->reg_b] != 0) { + array_dup(&state->arena, state->registers[in->reg_b]); } - state->finger = state->registers[in.reg_c]; + state->finger = state->registers[in->reg_c]; break; case ORTH: - state->registers[in.reg_a] = in.value; + state->registers[in->reg_a] = in->value; break; default: printf("invalid opcode\n"); diff --git a/umx b/umx Binary files differ.