// ilo.go, (c) charles childers package main import ( "encoding/binary" "fmt" "os" ) var d [33]int32 var a [257]int32 var m [65536]int32 var sp = 0 var rp = 0 var ip = 0 func pop() int32 { sp--; return d[sp + 1] } func push(x int32) { sp++; d[sp] = x } func prepare_vm() { ip = 0; sp = 0; rp = 0; } func load_image() { f, err := os.OpenFile("ilo.rom", os.O_RDONLY, 0) if err != nil { return } defer f.Close() buf := make([]byte, 4) var i int = 0 for i < 65536 { f.Read(buf) m[i] = int32(binary.LittleEndian.Uint32(buf[:4])) i++ } prepare_vm() } func save_image() { } func read_block() { var buffer = pop() var block = pop() var blocks = "ilo.blocks" if f, err := os.OpenFile(blocks, os.O_RDWR, 0666); err == nil { f.Seek(int64(block * 4096), 0) buf := make([]byte, 4) var i int = 0 for i < 1024 { f.Read(buf) m[int(buffer) + i] = int32(binary.LittleEndian.Uint32(buf[:4])) i++ } f.Close() } } func write_block() { var buffer = pop() var block = pop() var blocks = "ilo.blocks" if f, err := os.OpenFile(blocks, os.O_RDWR, 0666); err == nil { f.Seek(int64(block * 4096), 0) var buf = m[buffer:buffer+1024] binary.Write(f, binary.LittleEndian, buf) f.Close() } } func no() { } func li() { ip++; push(m[ip]) } func du() { push(d[sp]) } func dr() { sp-- } func sw() { var y = pop(); var x = pop(); push(y); push(x); } func pu() { rp++; a[rp] = pop() } func po() { push(a[rp]); rp-- } func ju() { ip = int(pop() - 1) } func ca() { rp++; a[rp] = int32(ip); ju() } func cc() { sw(); if (pop() != 0) { ca() } else { dr() } } func cj() { sw(); if (pop() != 0) { ju() } else { dr() } } func re() { ip = int(a[rp]); rp-- } func eq() { var y = pop(); var x = pop(); if (x == y) { push(-1) } else { push(0) } } func ne() { var y = pop(); var x = pop(); if (x != y) { push(-1) } else { push(0) } } func lt() { var y = pop(); var x = pop(); if (x < y) { push(-1) } else { push(0) } } func gt() { var y = pop(); var x = pop(); if (x > y) { push(-1) } else { push(0) } } func fe() { var t = pop(); push(m[t]) } func st() { var t = pop(); m[t] = pop() } func ad() { var y = pop(); var x = pop(); push(x + y) } func su() { var y = pop(); var x = pop(); push(x - y) } func mu() { var y = pop(); var x = pop(); push(x * y) } func di() { var y = pop(); var x = pop(); push(x % y); push(x / y) } func an() { var y = pop(); var x = pop(); push(x & y) } func or() { var y = pop(); var x = pop(); push(x | y) } func xo() { var y = pop(); var x = pop(); push(x ^ y) } func sl() { var y = pop(); var x = pop(); push(x << y) } func sr() { var y = pop(); var x = pop(); push(x >> y) } func cp() { var len = pop() var dest = pop() var src = pop() push(-1) for len > 0 { if m[dest] != m[src] { d[sp] = 0 } len--; src++; dest++ } } func cy() { var len = pop() var dest = pop() var src = pop() for len > 0 { m[dest] = m[src] len--; src++; dest++ } } func iowr() { fmt.Printf("%c", pop()) } func iord() { var b []byte = make([]byte, 1) os.Stdin.Read(b) var c int = int(b[0]) push(int32(c)) } func iorb() { read_block() } func iowb() { write_block() } func iosi() { save_image() } func ioli() { load_image(); ip = -1 } func ioen() { ip = 65536 } func iost() { push(int32(sp)); push(int32(rp)) } func io() { var o = pop() if o == 0 { iowr() } if o == 1 { iord() } if o == 2 { iorb() } if o == 3 { iowb() } if o == 4 { iosi() } if o == 5 { ioli() } if o == 6 { ioen() } if o == 7 { iost() } } func process(o int32) { if o == 0 { no() } if o == 1 { li() } if o == 2 { du() } if o == 3 { dr() } if o == 4 { sw() } if o == 5 { pu() } if o == 6 { po() } if o == 7 { ju() } if o == 8 { ca() } if o == 9 { cc() } if o == 10 { cj() } if o == 11 { re() } if o == 12 { eq() } if o == 13 { ne() } if o == 14 { lt() } if o == 15 { gt() } if o == 16 { fe() } if o == 17 { st() } if o == 18 { ad() } if o == 19 { su() } if o == 20 { mu() } if o == 21 { di() } if o == 22 { an() } if o == 23 { or() } if o == 24 { xo() } if o == 25 { sl() } if o == 26 { sr() } if o == 27 { cp() } if o == 28 { cy() } if o == 29 { io() } } func process_bundle(o int32) { process(o & 0xFF) process((o >> 8) & 0xFF) process((o >> 16) & 0xFF) process((o >> 24) & 0xFF) } func execute() { for ip < 65536 { process_bundle(m[ip]) ip++ } } func main() { load_image() execute() }