ilo-vm/source/ilo.cs

161 lines
5.4 KiB
C#

// 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();
}
}
}