aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2017-06-17 13:57:58 +0200
committerDimitri Sokolyuk <demon@dim13.org>2017-06-17 13:57:58 +0200
commit5b10c8a1a3f14beafe5e9b47663bc5dc67bb6409 (patch)
treea107d8a06fb36fb27ec0b084feae355d80cc0d44
parent34b234fc5a66d646bee90370e149abc5b15e35c9 (diff)
Add value
-rw-r--r--eval.go60
-rw-r--r--parse.go30
2 files changed, 56 insertions, 34 deletions
diff --git a/eval.go b/eval.go
index c3891c3..eedffd4 100644
--- a/eval.go
+++ b/eval.go
@@ -10,10 +10,10 @@ import (
// J1 Forth processor VM
type J1 struct {
- dsp uint16 // 5 bit data stack pointer
- st0 uint16 // top of data stack
pc uint16 // 13 bit
- rsp uint16 // 5 bit retrun stack pointer
+ st0 uint16 // top of data stack
+ dsp int8 // 5 bit data stack pointer
+ rsp int8 // 5 bit retrun stack pointer
dstack [0x20]uint16 // data stack
rstack [0x20]uint16 // deturn stack
memory [0x8000]uint16 // memory
@@ -21,12 +21,17 @@ type J1 struct {
// Reset VM
func (vm *J1) Reset() {
- vm.dsp = 0
- vm.st0 = 0
vm.pc = 0
+ vm.st0 = 0
+ vm.dsp = 0
vm.rsp = 0
}
+func (vm *J1) Depth() uint16 { return (uint16(vm.rsp) << 8) | uint16(vm.dsp) }
+func (vm *J1) T() uint16 { return vm.st0 }
+func (vm *J1) N() uint16 { return vm.dstack[vm.dsp] }
+func (vm *J1) R() uint16 { return vm.rstack[vm.rsp] }
+
// LoadBytes into memory
func (vm *J1) LoadBytes(data []byte) error {
size := len(data) >> 1
@@ -79,17 +84,17 @@ func (vm *J1) eval(ins Instruction) {
vm.pc++
vm.dsp++
vm.dstack[vm.dsp] = vm.st0
- vm.st0 = uint16(v)
+ vm.st0 = v.Value()
case Jump:
- vm.pc = uint16(v)
+ vm.pc = v.Value()
case Call:
vm.rsp++
vm.rstack[vm.rsp] = vm.pc + 1
- vm.pc = uint16(v)
+ vm.pc = v.Value()
case Cond:
vm.pc++
if vm.st0 == 0 {
- vm.pc = uint16(v)
+ vm.pc = v.Value()
}
vm.st0 = vm.dstack[vm.dsp] // N
vm.dsp--
@@ -102,8 +107,8 @@ func (vm *J1) eval(ins Instruction) {
if v.NtoAtT {
vm.memory[vm.st0] = vm.dstack[vm.dsp]
}
- vm.dsp = uint16(int8(vm.dsp) + v.Ddir)
- vm.rsp = uint16(int8(vm.rsp) + v.Rdir)
+ vm.dsp += v.Ddir
+ vm.rsp += v.Rdir
if v.TtoR {
vm.rstack[vm.rsp] = vm.st0
}
@@ -115,46 +120,45 @@ func (vm *J1) eval(ins Instruction) {
}
func (vm *J1) newST0(v ALU) uint16 {
- T, N, R := vm.st0, vm.dstack[vm.dsp], vm.rstack[vm.rsp]
switch v.Opcode {
case opT: // T
- return T
+ return vm.T()
case opN: // N
- return N
+ return vm.N()
case opTplusN: // T+N
- return T + N
+ return vm.T() + vm.N()
case opTandN: // T&N
- return T & N
+ return vm.T() & vm.N()
case opTorN: // T|N
- return T | N
+ return vm.T() | vm.N()
case opTxorN: // T^N
- return T ^ N
+ return vm.T() ^ vm.N()
case opNotT: // ~T
- return ^T
+ return ^vm.T()
case opNeqT: // N==T
- if N == T {
+ if vm.N() == vm.T() {
return 1
}
return 0
case opNleT: // N<T
- if int16(N) < int16(T) {
+ if int16(vm.N()) < int16(vm.T()) {
return 1
}
return 0
case opNrshiftT: // N>>T
- return N >> (T & 0xf)
+ return vm.N() >> (vm.T() & 0xf)
case opTminus1: // T-1
- return T - 1
+ return vm.T() - 1
case opR: // R (rT)
- return R
+ return vm.R()
case opAtT: // [T]
- return vm.memory[T]
+ return vm.memory[vm.T()]
case opNlshiftT: // N<<T
- return N << (T & 0xf)
+ return vm.N() << (vm.T() & 0xf)
case opDepth: // depth (dsp)
- return (vm.rsp << 8) | vm.dsp
+ return vm.Depth()
case opNuleT: // Nu<T
- if N < T {
+ if vm.N() < vm.T() {
return 1
}
return 0
diff --git a/parse.go b/parse.go
index bf39ee8..336ce5a 100644
--- a/parse.go
+++ b/parse.go
@@ -21,7 +21,8 @@ func Decode(v uint16) Instruction {
// Instruction interface
type Instruction interface {
- isInstruction()
+ String() string
+ Value() uint16
}
// Lit is a literal
@@ -29,28 +30,28 @@ type Lit uint16
func newLit(v uint16) Lit { return Lit(v &^ uint16(1<<15)) }
func (v Lit) String() string { return fmt.Sprintf("LIT %0.4X", uint16(v)) }
-func (v Lit) isInstruction() {}
+func (v Lit) Value() uint16 { return uint16(v) }
// Jump is an unconditional branch
type Jump uint16
func newJump(v uint16) Jump { return Jump(v &^ uint16(7<<13)) }
func (v Jump) String() string { return fmt.Sprintf("UBRANCH %0.4X", uint16(v<<1)) }
-func (v Jump) isInstruction() {}
+func (v Jump) Value() uint16 { return uint16(v) }
// Cond is a conditional branch
type Cond uint16
func newCond(v uint16) Cond { return Cond(v &^ uint16(7<<13)) }
func (v Cond) String() string { return fmt.Sprintf("0BRANCH %0.4X", uint16(v<<1)) }
-func (v Cond) isInstruction() {}
+func (v Cond) Value() uint16 { return uint16(v) }
// Call procedure
type Call uint16
func newCall(v uint16) Call { return Call(v &^ uint16(7<<13)) }
func (v Call) String() string { return fmt.Sprintf("CALL %0.4X", uint16(v<<1)) }
-func (v Call) isInstruction() {}
+func (v Call) Value() uint16 { return uint16(v) }
// ALU instruction
type ALU struct {
@@ -75,7 +76,24 @@ func newALU(v uint16) ALU {
}
}
-func (v ALU) isInstruction() {}
+func (v ALU) Value() uint16 {
+ ret := v.Opcode << 8
+ if v.RtoPC {
+ ret |= 1 << 12
+ }
+ if v.TtoN {
+ ret |= 1 << 7
+ }
+ if v.TtoR {
+ ret |= 1 << 6
+ }
+ if v.NtoAtT {
+ ret |= 1 << 5
+ }
+ ret |= uint16(v.Rdir&3) << 2
+ ret |= uint16(v.Ddir & 3)
+ return ret
+}
func expand(v uint16) int8 {
if v&2 != 0 {