ilo-vm/source/ilo.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()
}