/* ilo-windows.c (c) 2022, charles childers */ #include #include int ip, sp, rp, data[33], address[257], memory[65536]; char *blocks, *rom; #define T data[sp] #define N data[sp-1] #define R address[rp] int pop() { return data[(--sp) + 1]; } void push(int value) { data[++sp] = value; } void prepare_vm() { ip = sp = rp = 0; } void load_image() { int fp; fp = open(rom, O_RDONLY, 0666); if (!fp) return; read(fp, &memory, 65536 * sizeof(int)); close(fp); prepare_vm(); } void save_image() { int fp; fp = open(rom, O_WRONLY, 0666); write(fp, &memory, 65536 * sizeof(int)); close(fp); } void read_block() { int f, block, buffer; buffer = pop(); block = pop(); f = open(blocks, O_RDONLY, 0666); lseek(f, 4096 * block, SEEK_SET); read(f, memory + buffer, 1024 * 4); close(f); } void write_block() { int f, block, buffer; buffer = pop(); block = pop(); f = open(blocks, O_WRONLY, 0666); lseek(f, 4096 * block, SEEK_SET); write(f, memory + buffer, 4096); close(f); } void process(int o) { int a, b, target, src, dest, len; switch (o) { case 0: break; case 1: ip++; push(memory[ip]); break; case 2: push(T); break; case 3: data[sp] = 0; sp--; break; case 4: a = T; T = N; N = a; break; case 5: rp++; R = pop(); break; case 6: push(R); rp--; break; case 7: ip = pop() - 1; break; case 8: rp++; R = ip; ip = pop() - 1; break; case 9: target = pop(); if (pop() != 0) { rp++; R = ip; ip = target - 1; } break; case 10: target = pop(); if (pop() != 0) ip = target - 1; break; case 11: ip = R; rp--; break; case 12: N = (N == T) ? -1 : 0; sp--; break; case 13: N = (N != T) ? -1 : 0; sp--; break; case 14: N = (N < T) ? -1 : 0; sp--; break; case 15: N = (N > T) ? -1 : 0; sp--; break; case 16: T = memory[T]; break; case 17: memory[T] = N; sp--; sp--; break; case 18: N += T; sp--; break; case 19: N -= T; sp--; break; case 20: N *= T; sp--; break; case 21: a = T; b = N; T = b / a; N = b % a; break; case 22: N = T & N; sp--; break; case 23: N = T | N; sp--; break; case 24: N = T ^ N; sp--; break; case 25: N = N << T; sp--; break; case 26: N = N >> T; sp--; break; case 27: len = pop(); dest = pop(); src = pop(); push(-1); while (len) { if (memory[dest] != memory[src]) T = 0; len -= 1; src += 1; dest += 1; } break; case 28: len = pop(); dest = pop(); src = pop(); while (len) { memory[dest] = memory[src]; len -= 1; src += 1; dest += 1; } break; case 29: switch (pop()) { case 0: putc(pop(), stdout); break; case 1: push(getc(stdin)); break; case 2: read_block(); break; case 3: write_block(); break; case 4: save_image(); break; case 5: load_image(); ip = -1; break; case 6: ip = 65536; break; case 7: push(sp); push(rp); break; default: break; } break; default: break; } } void process_bundle(int opcode) { process(opcode & 0xFF); process((opcode >> 8) & 0xFF); process((opcode >> 16) & 0xFF); process((opcode >> 24) & 0xFF); } void execute() { while (ip < 65536) { process_bundle(memory[ip]); ip++; } } void dump_stack() { for (; sp > 0; sp--) printf(" %d", data[sp]); printf("\n"); } int main(int argc, char **argv) { blocks = (argc > 1) ? argv[1] : "ilo.blocks"; rom = (argc > 2) ? argv[2] : "ilo.rom"; load_image(); execute(); dump_stack(); }