161 lines
5.4 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|