aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2017-06-09 09:35:30 +0200
committerDimitri Sokolyuk <demon@dim13.org>2017-06-09 09:35:30 +0200
commitf13e7891763305dd36b510104192af734271e1b3 (patch)
treee8f6b6ed512ba6c93fefa694c24b3040e63258ad
parentf5fa5aa79d3841f0c8f3f658d544dad30d5fe330 (diff)
direct stack access
-rw-r--r--eval.go62
-rw-r--r--eval_test.go18
2 files changed, 40 insertions, 40 deletions
diff --git a/eval.go b/eval.go
index 0cd0205..d04ea01 100644
--- a/eval.go
+++ b/eval.go
@@ -18,9 +18,17 @@ type J1 struct {
memory [0x8000]uint16 // memory
}
+// Reset VM
+func (vm *J1) Reset() {
+ vm.dsp = 0
+ vm.st0 = 0
+ vm.pc = 0
+ vm.rsp = 0
+}
+
func (vm *J1) String() string {
return fmt.Sprintf("PC=%0.4X ST=%0.4X D=%0.4X R=%0.4X",
- vm.pc, vm.st0, vm.dstack[:vm.dsp], vm.rstack[:vm.rsp])
+ vm.pc, vm.st0, vm.dstack[:vm.dsp+1], vm.rstack[:vm.rsp+1])
}
// LoadBytes into memory
@@ -68,14 +76,14 @@ func (vm *J1) eval(ins Instruction) {
case Lit:
st0 = uint16(v)
dsp = vm.dsp + 1
- vm.dstack[vm.dsp] = vm.T()
+ vm.dstack[dsp] = vm.st0
case Jump:
st0 = vm.newST0(opT)
pc = uint16(v)
case Call:
st0 = vm.newST0(opT)
rsp = vm.rsp + 1
- vm.rstack[vm.rsp] = pc
+ vm.rstack[rsp] = pc
pc = uint16(v)
case Cond:
st0 = vm.newST0(opN)
@@ -86,18 +94,18 @@ func (vm *J1) eval(ins Instruction) {
case ALU:
st0 = vm.newST0(v)
if v.RtoPC {
- pc = vm.R()
+ pc = vm.rstack[vm.rsp]
}
if v.NtoAtT {
- vm.memory[vm.st0] = vm.N()
+ vm.memory[vm.st0] = vm.dstack[vm.dsp]
}
dsp = uint16(int8(vm.dsp)+v.Ddir) % 32
rsp = uint16(int8(vm.rsp)+v.Rdir) % 32
if v.TtoR {
- vm.rstack[(rsp-1)%32] = vm.T()
+ vm.rstack[rsp] = vm.st0
}
if v.TtoN {
- vm.dstack[(dsp-1)%32] = vm.T()
+ vm.dstack[dsp] = vm.st0
}
}
@@ -107,55 +115,47 @@ func (vm *J1) eval(ins Instruction) {
vm.rsp = rsp
}
-// T is top of data stack
-func (vm *J1) T() uint16 { return vm.st0 }
-
-// N is second element of data stack
-func (vm *J1) N() uint16 { return vm.dstack[(vm.dsp-1)%32] }
-
-// R is top of return stack
-func (vm *J1) R() uint16 { return vm.rstack[(vm.rsp-1)%32] }
-
func (vm *J1) newST0(v ALU) uint16 {
+ T, N, R := vm.st0, vm.dstack[vm.dsp], vm.rstack[vm.rsp]
switch v.Opcode {
case 0: // T
- return vm.T()
+ return T
case 1: // N
- return vm.N()
+ return N
case 2: // T+N
- return vm.T() + vm.N()
+ return T + N
case 3: // T&N
- return vm.T() & vm.N()
+ return T & N
case 4: // T|N
- return vm.T() | vm.N()
+ return T | N
case 5: // T^N
- return vm.T() ^ vm.N()
+ return T ^ N
case 6: // ~T
- return ^vm.T()
+ return ^T
case 7: // N==T
- if vm.N() == vm.T() {
+ if N == T {
return 1
}
return 0
case 8: // N<T
- if int16(vm.N()) < int16(vm.T()) {
+ if int16(N) < int16(T) {
return 1
}
return 0
case 9: // N>>T
- return vm.N() >> (vm.T() & 0xf)
+ return N >> (T & 0xf)
case 10: // T-1
- return vm.T() - 1
+ return T - 1
case 11: // R (rT)
- return vm.R()
+ return R
case 12: // [T]
- return vm.memory[vm.T()]
+ return vm.memory[T]
case 13: // N<<T
- return vm.N() << (vm.T() & 0xf)
+ return N << (T & 0xf)
case 14: // depth (dsp)
return (vm.rsp << 8) | vm.dsp
case 15: // Nu<T
- if vm.N() < vm.T() {
+ if N < T {
return 1
}
return 0
diff --git a/eval_test.go b/eval_test.go
index 51aeebb..62cd01c 100644
--- a/eval_test.go
+++ b/eval_test.go
@@ -24,7 +24,7 @@ func TestEval(t *testing.T) {
},
{
ins: []Instruction{Call(0xff)},
- end: J1{pc: 0xff, rstack: [32]uint16{1}, rsp: 1},
+ end: J1{pc: 0xff, rstack: [32]uint16{0x00, 0x01}, rsp: 1},
},
{
ins: []Instruction{Lit(0xff)},
@@ -32,15 +32,15 @@ func TestEval(t *testing.T) {
},
{
ins: []Instruction{Lit(0xff), Lit(0xfe)},
- end: J1{pc: 2, st0: 0xfe, dstack: [32]uint16{0x00, 0xff}, dsp: 2},
+ end: J1{pc: 2, st0: 0xfe, dstack: [32]uint16{0x00, 0x00, 0xff}, dsp: 2},
},
{ // dup
ins: []Instruction{Lit(0xff), ALU{Opcode: 0, TtoN: true, Ddir: 1}},
- end: J1{pc: 2, st0: 0xff, dstack: [32]uint16{0x00, 0xff}, dsp: 2},
+ end: J1{pc: 2, st0: 0xff, dstack: [32]uint16{0x00, 0x00, 0xff}, dsp: 2},
},
{ // over
ins: []Instruction{Lit(0xaa), Lit(0xbb), ALU{Opcode: 1, TtoN: true, Ddir: 1}},
- end: J1{pc: 3, st0: 0xaa, dstack: [32]uint16{0x00, 0xaa, 0xbb}, dsp: 3},
+ end: J1{pc: 3, st0: 0xaa, dstack: [32]uint16{0x00, 0x00, 0xaa, 0xbb}, dsp: 3},
},
{ // invert
ins: []Instruction{Lit(0x00ff), ALU{Opcode: 6}},
@@ -48,23 +48,23 @@ func TestEval(t *testing.T) {
},
{ // +
ins: []Instruction{Lit(1), Lit(2), ALU{Opcode: 2, Ddir: -1}},
- end: J1{pc: 3, st0: 3, dsp: 1, dstack: [32]uint16{0, 1}},
+ end: J1{pc: 3, st0: 3, dsp: 1, dstack: [32]uint16{0, 0, 1}},
},
{ // swap
ins: []Instruction{Lit(2), Lit(3), ALU{Opcode: 1, TtoN: true}},
- end: J1{pc: 3, st0: 2, dsp: 2, dstack: [32]uint16{0, 3}},
+ end: J1{pc: 3, st0: 2, dsp: 2, dstack: [32]uint16{0, 0, 3}},
},
{ // nip
ins: []Instruction{Lit(2), Lit(3), ALU{Opcode: 0, Ddir: -1}},
- end: J1{pc: 3, st0: 3, dsp: 1, dstack: [32]uint16{0, 2}},
+ end: J1{pc: 3, st0: 3, dsp: 1, dstack: [32]uint16{0, 0, 2}},
},
{ // drop
ins: []Instruction{Lit(2), Lit(3), ALU{Opcode: 1, Ddir: -1}},
- end: J1{pc: 3, st0: 2, dsp: 1, dstack: [32]uint16{0, 2}},
+ end: J1{pc: 3, st0: 2, dsp: 1, dstack: [32]uint16{0, 0, 2}},
},
{ // ;
ins: []Instruction{Call(10), Call(20), ALU{Opcode: 0, RtoPC: true, Rdir: -1}},
- end: J1{pc: 11, rsp: 1, rstack: [32]uint16{1, 11}},
+ end: J1{pc: 11, rsp: 1, rstack: [32]uint16{0, 1, 11}},
},
{ // >r
// ins: []Instruction{Lit(10), ALU{Opcode: 1, TtoR: true, Ddir: -1, Rdir: 1}},