Moves program into its own memory space and fills in all but one of the rest of the ops

This commit is contained in:
sloum 2023-12-30 20:46:26 -08:00
parent 242d5ccf13
commit 7d9e6da1aa
6 changed files with 167 additions and 29 deletions

10
README.md Normal file
View File

@ -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

View File

@ -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

View File

@ -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])
}

View File

@ -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
View File

@ -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?
}

View File

@ -123,9 +123,8 @@ func (s *Stack) PopLong() (uint16) {
type Vm struct {
PC uint16 // Current Position
HP uint16 // Current start of heap
MemOffset uint16 // Start of user memory
Mem Memory
Mem Memory
Prog Memory
Data Stack
Return Stack
}