// ilo.cs, (c) charles childers using System; using System.IO; using System.Text; namespace ilo { class VM { public int sp, rp, ip; public int[] d, a, m; public VM() { sp = 0; rp = 0; ip = 0; d = new int[33]; a = new int[257]; m = new int[65536]; load_rom(); } public void load_rom() { int i = 0; if (!File.Exists("ilo.rom")) { Console.Write("ilo.rom missing"); Environment.Exit(1); } BinaryReader rom = new BinaryReader(File.Open("ilo.rom", FileMode.Open)); while (i < 65536) { m[i] = rom.ReadInt32(); i++; } rom.Close(); } public void read_block() { int buffer = d[sp]; sp--; int block = d[sp]; sp--; int i = 0; BinaryReader blocks = new BinaryReader(File.Open("ilo.blocks", FileMode.Open)); blocks.BaseStream.Seek(4096 * block, SeekOrigin.Begin); while (i < 1024) { m[buffer + i] = blocks.ReadInt32(); i++; } blocks.Close(); } public void write_block() { int buffer = d[sp]; sp--; int block = d[sp]; sp--; int i = 0; BinaryWriter blocks = new BinaryWriter(File.Open("ilo.blocks", FileMode.Open, FileAccess.ReadWrite)); blocks.BaseStream.Seek(4096 * block, SeekOrigin.Begin); while (i < 1024) { blocks.Write(m[buffer + i]); i++; } blocks.Close(); } public void push(int x) { sp++; d[sp] = x; } public int pop() { sp--; return d[sp + 1]; } public void no() { } public void li() { ip++; sp++; d[sp] = m[ip]; } public void du() { sp++; d[sp] = d[sp - 1]; } public void dr() { sp--; } public void sw() { int x = d[sp], y = d[sp - 1]; d[sp] = y; d[sp - 1] = x; } public void pu() { rp++; a[rp] = d[sp]; sp--; } public void po() { sp++; d[sp] = a[rp]; rp--; } public void ju() { ip = d[sp] - 1; sp--; } public void ca() { rp++; a[rp] = ip; ju(); } public void cc() { if (d[sp - 1] != 0) { rp++; a[rp] = ip; ip = d[sp] - 1; } sp -= 2; } public void cj() { if (d[sp - 1] != 0) { ip = d[sp] - 1; } sp -= 2; } public void re() { ip = a[rp]; rp--; } public void eq() { d[sp - 1] = (d[sp - 1] == d[sp]) ? -1 : 0; sp--; } public void ne() { d[sp - 1] = (d[sp - 1] != d[sp]) ? -1 : 0; sp--; } public void lt() { d[sp - 1] = (d[sp - 1] < d[sp]) ? -1 : 0; sp--; } public void gt() { d[sp - 1] = (d[sp - 1] > d[sp]) ? -1 : 0; sp--; } public void fe() { d[sp] = m[d[sp]]; } public void st() { m[d[sp]] = d[sp - 1]; sp -= 2; } public void ad() { d[sp - 1] += d[sp]; sp--; } public void su() { d[sp - 1] -= d[sp]; sp--; } public void mu() { d[sp - 1] *= d[sp]; sp--; } public void di() { int x = d[sp], y = d[sp - 1]; d[sp] = y / x; d[sp - 1] = y % x; } public void an() { d[sp - 1] = d[sp] & d[sp - 1]; sp--; } public void or() { d[sp - 1] = d[sp] | d[sp - 1]; sp--; } public void xo() { d[sp - 1] = d[sp] ^ d[sp - 1]; sp--; } public void sl() { d[sp - 1] = d[sp] << d[sp - 1]; sp--; } public void sr() { d[sp - 1] = d[sp] >>= d[sp - 1]; sp--; } public void cp() { int len = d[sp]; sp--; int dest = d[sp]; sp--; int src = d[sp]; sp--; sp++; d[sp] = -1; while (len > 0) { if (m[dest] != m[src]) { d[sp] = 0; } len -= 1; src += 1; dest += 1; } } public void cy() { int len = d[sp]; sp--; int dest = d[sp]; sp--; int src = d[sp]; sp--; while (len > 0) { m[dest] = m[src]; len -= 1; src += 1; dest += 1; } } public void iowr() { Console.Write((char)d[sp]); sp--; } public void iord() { ConsoleKeyInfo x = Console.ReadKey(); sp++; d[sp] = (int)x.KeyChar; if (d[sp] == 13) { d[sp] = 10; } } public void iorb() { read_block(); } public void iowb() { write_block(); } public void iosi() { } public void ioli() { load_rom(); ip = -1; } public void ioen() { ip = 65536; } public void iost() { sp++; d[sp] = sp - 1; sp++; d[sp] = rp; } public void io() { int act = d[sp]; sp--; switch (act) { case 0: iowr(); break; case 1: iord(); break; case 2: iorb(); break; case 3: iowb(); break; case 4: iosi(); break; case 5: ioli(); break; case 6: ioen(); break; case 7: iost(); break; } } public void process(int o) { switch(o) { case 0: no(); break; case 1: li(); break; case 2: du(); break; case 3: dr(); break; case 4: sw(); break; case 5: pu(); break; case 6: po(); break; case 7: ju(); break; case 8: ca(); break; case 9: cc(); break; case 10: cj(); break; case 11: re(); break; case 12: eq(); break; case 13: ne(); break; case 14: lt(); break; case 15: gt(); break; case 16: fe(); break; case 17: st(); break; case 18: ad(); break; case 19: su(); break; case 20: mu(); break; case 21: di(); break; case 22: an(); break; case 23: or(); break; case 24: xo(); break; case 25: sl(); break; case 26: sr(); break; case 27: cp(); break; case 28: cy(); break; case 29: io(); break; } } public void execute() { int raw = 0; ip = 0; while (ip < 65536) { raw = m[ip]; for (int i = 0; i < 4; i++) { process(raw & 0xFF); raw = raw >> 8; } ip++; } } public static void Main(string[] args) { VM ilo = new VM(); ilo.execute(); } } }