Moves program into its own memory space and fills in all but one of the rest of the ops
This commit is contained in:
parent
242d5ccf13
commit
7d9e6da1aa
|
@ -0,0 +1,10 @@
|
|||
# bird, a vm
|
||||
|
||||
This is a learning project. Many mistakes are being made, but lots of fun is being had. Inspired by varvara/uxn, but without looking at their implementation details and mostly just taking my memory of their project as a point of inspiration.
|
||||
|
||||
Coming soon:
|
||||
|
||||
1. An assembler that produces bird bytecode
|
||||
2. More ops filled in within the vm
|
||||
3. A higher level language that compiles down to either the assembler or to bytecode
|
||||
|
26
design.md
26
design.md
|
@ -64,6 +64,19 @@ The first three bits are the category, the next four are the op, the last one is
|
|||
13. .
|
||||
14. .
|
||||
15. .
|
||||
16. .
|
||||
17. .
|
||||
18. .
|
||||
19. .
|
||||
20. .
|
||||
21. .
|
||||
22. .
|
||||
23. .
|
||||
24. .
|
||||
25. .
|
||||
26. .
|
||||
27. .
|
||||
28. .
|
||||
8. dev - 111
|
||||
1. .
|
||||
2. .
|
||||
|
@ -80,6 +93,19 @@ The first three bits are the category, the next four are the op, the last one is
|
|||
13. .
|
||||
14. .
|
||||
15. .
|
||||
16. .
|
||||
17. .
|
||||
18. .
|
||||
19. .
|
||||
20. .
|
||||
21. .
|
||||
22. .
|
||||
23. .
|
||||
24. .
|
||||
25. .
|
||||
26. .
|
||||
27. .
|
||||
28. .
|
||||
|
||||
## Memory Layout
|
||||
|
||||
|
|
10
helpers.go
10
helpers.go
|
@ -45,22 +45,20 @@ func To8s(n uint16) (byte, byte) {
|
|||
return byte(n>>8), byte(n & uint16(0xFF))
|
||||
}
|
||||
|
||||
func LoadMemory(b []byte) {
|
||||
func LoadProg(b []byte) {
|
||||
for i := range b {
|
||||
vm.Mem[i] = b[i]
|
||||
vm.Prog[i] = b[i]
|
||||
}
|
||||
vm.HP = uint16(len(b))
|
||||
vm.MemOffset = uint16(len(b))
|
||||
}
|
||||
|
||||
func DumpVm() {
|
||||
fmt.Fprintf(
|
||||
os.Stderr,
|
||||
"\n<%03d>Data : %v\n<%03d>Return: %v\nPC: %d\nHP: %d\n",
|
||||
"\n<%03d>Data : %v\n<%03d>Return: %v\nPC: %d\nData: %v",
|
||||
vm.Data.pointer,
|
||||
vm.Data.data[:vm.Data.pointer],
|
||||
vm.Return.pointer,
|
||||
vm.Return.data[:vm.Return.pointer],
|
||||
vm.PC,
|
||||
vm.HP-vm.MemOffset)
|
||||
vm.Prog[:vm.PC])
|
||||
}
|
||||
|
|
6
main.go
6
main.go
|
@ -39,7 +39,7 @@ var ops = []func(bool, *Stack){
|
|||
opGrt, opLst, opGte, opLte, opEql, opNeq, opNop,
|
||||
}
|
||||
|
||||
var vm Vm = Vm{0, 0, 0, [65535]byte{0}, Stack{0, [255]byte{0}}, Stack{0, [255]byte{0}}}
|
||||
var vm Vm = Vm{0, [MaxUint16]byte{0}, [MaxUint16]byte{0}, Stack{0, [MaxByte]byte{0}}, Stack{0, [MaxByte]byte{0}}}
|
||||
var dumpVmData bool
|
||||
var halt = -1
|
||||
|
||||
|
@ -53,11 +53,11 @@ func main() {
|
|||
0x07, 0x02, 0x27, // Then exit with 0x02 as the exit code
|
||||
}
|
||||
|
||||
LoadMemory(test)
|
||||
LoadProg(test)
|
||||
|
||||
// Loop
|
||||
for ;vm.PC < MaxUint16 && halt < 0;vm.PC++{
|
||||
o := vm.Mem.Read(vm.PC)
|
||||
o := vm.Prog.Read(vm.PC)
|
||||
if IsRetStackOp(o) {
|
||||
ops[o](IsLongOp(o), &(vm.Return))
|
||||
} else {
|
||||
|
|
139
ops.go
139
ops.go
|
@ -49,11 +49,11 @@ func opGei(longOp bool, s *Stack) {
|
|||
func opPsh(longOp bool, s *Stack) {
|
||||
vm.PC++
|
||||
if longOp {
|
||||
s.Push2(vm.Mem.Read2(vm.PC))
|
||||
s.Push2(vm.Prog.Read2(vm.PC))
|
||||
vm.PC++
|
||||
return
|
||||
}
|
||||
s.Push(vm.Mem.Read(vm.PC))
|
||||
s.Push(vm.Prog.Read(vm.PC))
|
||||
}
|
||||
|
||||
// ( v1 -- )
|
||||
|
@ -365,22 +365,127 @@ func opPhx(longOp bool, s *Stack){
|
|||
}
|
||||
fmt.Printf("%02x", vm.Data.Pop())
|
||||
}
|
||||
func opGrt(longOp bool, s *Stack){}
|
||||
func opLst(longOp bool, s *Stack){}
|
||||
func opGte(longOp bool, s *Stack){}
|
||||
func opLte(longOp bool, s *Stack){}
|
||||
func opEql(longOp bool, s *Stack){}
|
||||
func opNeq(longOp bool, s *Stack){}
|
||||
|
||||
func opGrt(longOp bool, s *Stack){
|
||||
if longOp {
|
||||
l := s.PopLong()
|
||||
if s.PopLong() > l {
|
||||
s.Push(1)
|
||||
} else {
|
||||
s.Push(0)
|
||||
}
|
||||
return
|
||||
}
|
||||
h, l := s.Pop2()
|
||||
if h > l {
|
||||
s.Push(1)
|
||||
} else {
|
||||
s.Push(0)
|
||||
}
|
||||
}
|
||||
|
||||
func opLst(longOp bool, s *Stack){
|
||||
if longOp {
|
||||
l := s.PopLong()
|
||||
if s.PopLong() < l {
|
||||
s.Push(1)
|
||||
} else {
|
||||
s.Push(0)
|
||||
}
|
||||
return
|
||||
}
|
||||
h, l := s.Pop2()
|
||||
if h < l {
|
||||
s.Push(1)
|
||||
} else {
|
||||
s.Push(0)
|
||||
}
|
||||
}
|
||||
|
||||
func opGte(longOp bool, s *Stack){
|
||||
if longOp {
|
||||
l := s.PopLong()
|
||||
if s.PopLong() >= l {
|
||||
s.Push(1)
|
||||
} else {
|
||||
s.Push(0)
|
||||
}
|
||||
return
|
||||
}
|
||||
h, l := s.Pop2()
|
||||
if h >= l {
|
||||
s.Push(1)
|
||||
} else {
|
||||
s.Push(0)
|
||||
}
|
||||
}
|
||||
|
||||
func opLte(longOp bool, s *Stack){
|
||||
if longOp {
|
||||
l := s.PopLong()
|
||||
if s.PopLong() < l {
|
||||
s.Push(1)
|
||||
} else {
|
||||
s.Push(0)
|
||||
}
|
||||
return
|
||||
}
|
||||
h, l := s.Pop2()
|
||||
if h < l {
|
||||
s.Push(1)
|
||||
} else {
|
||||
s.Push(0)
|
||||
}
|
||||
}
|
||||
|
||||
func opEql(longOp bool, s *Stack){
|
||||
if longOp {
|
||||
l := s.PopLong()
|
||||
if s.PopLong() == l {
|
||||
s.Push(1)
|
||||
} else {
|
||||
s.Push(0)
|
||||
}
|
||||
return
|
||||
}
|
||||
h, l := s.Pop2()
|
||||
if h == l {
|
||||
s.Push(1)
|
||||
} else {
|
||||
s.Push(0)
|
||||
}
|
||||
}
|
||||
|
||||
func opNeq(longOp bool, s *Stack){
|
||||
if longOp {
|
||||
l := s.PopLong()
|
||||
if s.PopLong() != l {
|
||||
s.Push(1)
|
||||
} else {
|
||||
s.Push(0)
|
||||
}
|
||||
return
|
||||
}
|
||||
h, l := s.Pop2()
|
||||
if h != l {
|
||||
s.Push(1)
|
||||
} else {
|
||||
s.Push(0)
|
||||
}
|
||||
}
|
||||
|
||||
// ( [count] count -- addrHigh addrLow )
|
||||
func opAlo(longOp bool, s *Stack){
|
||||
if longOp {
|
||||
count := PopAddress()
|
||||
vm.Data.PushLong(vm.HP)
|
||||
vm.HP += count
|
||||
return
|
||||
}
|
||||
count := uint16(vm.Data.Pop())
|
||||
vm.Data.PushLong(vm.HP)
|
||||
vm.HP += count
|
||||
// if longOp {
|
||||
// count := PopAddress()
|
||||
// vm.Data.PushLong(vm.HP)
|
||||
// vm.HP += count
|
||||
// return
|
||||
// }
|
||||
// count := uint16(vm.Data.Pop())
|
||||
// vm.Data.PushLong(vm.HP)
|
||||
// vm.HP += count
|
||||
|
||||
// Remove this?
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue