mirror of
https://github.com/ChronosX88/YAVM.git
synced 2024-11-23 20:02:19 +00:00
88 lines
2.3 KiB
Go
88 lines
2.3 KiB
Go
|
package main
|
||
|
|
||
|
import "fmt"
|
||
|
|
||
|
type VM struct {
|
||
|
Registers []int32
|
||
|
CurrentProgramBytecode []uint8
|
||
|
CurrentProgramPos int
|
||
|
Remainder uint32
|
||
|
}
|
||
|
|
||
|
func NewVM() *VM {
|
||
|
return &VM {
|
||
|
Registers: make([]int32, 32),
|
||
|
CurrentProgramBytecode: make([]uint8, 0),
|
||
|
CurrentProgramPos: 0,
|
||
|
Remainder: 0,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (vm *VM) Run() {
|
||
|
for {
|
||
|
if vm.CurrentProgramPos >= len(vm.CurrentProgramBytecode) {
|
||
|
break
|
||
|
}
|
||
|
|
||
|
switch vm.decodeOpcode() {
|
||
|
case HALT: {
|
||
|
fmt.Println("HALT encountered")
|
||
|
return
|
||
|
}
|
||
|
case LOAD: {
|
||
|
register := uint(vm.next8Bits())
|
||
|
number := uint32(vm.next16Bits())
|
||
|
fmt.Println(register, number)
|
||
|
vm.Registers[register] = int32(number)
|
||
|
}
|
||
|
case ADD: {
|
||
|
number1 := vm.Registers[uint(vm.next8Bits())]
|
||
|
number2 := vm.Registers[uint(vm.next8Bits())]
|
||
|
targetRegister := vm.next8Bits()
|
||
|
vm.Registers[targetRegister] = number1 + number2
|
||
|
}
|
||
|
case SUB: {
|
||
|
number1 := vm.Registers[uint(vm.next8Bits())]
|
||
|
number2 := vm.Registers[uint(vm.next8Bits())]
|
||
|
targetRegister := vm.next8Bits()
|
||
|
vm.Registers[targetRegister] = number1 - number2
|
||
|
}
|
||
|
case MULTIPLE: {
|
||
|
number1 := vm.Registers[uint(vm.next8Bits())]
|
||
|
number2 := vm.Registers[uint(vm.next8Bits())]
|
||
|
targetRegister := vm.next8Bits()
|
||
|
vm.Registers[targetRegister] = number1 * number2
|
||
|
}
|
||
|
case DIVIDE: {
|
||
|
number1 := vm.Registers[uint(vm.next8Bits())]
|
||
|
number2 := vm.Registers[uint(vm.next8Bits())]
|
||
|
targetRegister := vm.next8Bits()
|
||
|
vm.Registers[targetRegister] = number1 / number2
|
||
|
vm.Remainder = uint32(number1 % number2)
|
||
|
}
|
||
|
default: {
|
||
|
fmt.Println("Unrecognized opcode, terminating VM...")
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (vm *VM) decodeOpcode() Opcode {
|
||
|
opcode := OpcodeFrom(vm.CurrentProgramBytecode[vm.CurrentProgramPos])
|
||
|
vm.CurrentProgramPos++
|
||
|
return opcode
|
||
|
}
|
||
|
|
||
|
func (vm *VM) next8Bits() uint8 {
|
||
|
result := vm.CurrentProgramBytecode[vm.CurrentProgramPos]
|
||
|
vm.CurrentProgramPos++
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
func (vm *VM) next16Bits() uint16 {
|
||
|
result := ((uint16(vm.CurrentProgramBytecode[vm.CurrentProgramPos])) << 8) | uint16(vm.CurrentProgramBytecode[vm.CurrentProgramPos + 1])
|
||
|
vm.CurrentProgramPos += 2
|
||
|
return result
|
||
|
}
|