193 lines
4.4 KiB
Go
193 lines
4.4 KiB
Go
// 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()
|
|
}
|