From 3705ec154f2700d1b3c60ce56626cc520fb3e068 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Mon, 15 Jan 2018 00:32:37 +0100 Subject: rename --- eval.go | 187 ---------------------------------------------------------------- 1 file changed, 187 deletions(-) delete mode 100644 eval.go (limited to 'eval.go') diff --git a/eval.go b/eval.go deleted file mode 100644 index c879d7a..0000000 --- a/eval.go +++ /dev/null @@ -1,187 +0,0 @@ -package j1 - -import ( - "bytes" - "context" - "encoding/binary" - "fmt" - "io/ioutil" -) - -const memSize = 0x4000 - -type Console interface { - Read() uint16 - Write(uint16) - Len() uint16 -} - -// J1 Forth processor VM -type J1 struct { - memory [memSize]uint16 // 0..0x3fff main memory, 0x4000 .. 0x7fff mem-mapped i/o - pc uint16 // 13 bit - st0 uint16 // top of data stack - d stack - r stack - console Console - stop context.CancelFunc -} - -func New() *J1 { - return new(J1) -} - -// Reset VM -func (j1 *J1) Reset() { - j1.pc, j1.st0, j1.d.sp, j1.r.sp = 0, 0, 0, 0 -} - -// LoadBytes into memory -func (j1 *J1) LoadBytes(data []byte) error { - size := len(data) >> 1 - if size >= memSize { - return fmt.Errorf("too big") - } - return binary.Read(bytes.NewReader(data), binary.LittleEndian, j1.memory[:size]) -} - -// LoadFile into memory -func (j1 *J1) LoadFile(fname string) error { - data, err := ioutil.ReadFile(fname) - if err != nil { - return err - } - return j1.LoadBytes(data) -} - -// Run evaluates content of memory -func (j1 *J1) Run() { - ctx, cancel := context.WithCancel(context.Background()) - j1.console = NewConsole(ctx) - j1.stop = cancel - for { - select { - case <-ctx.Done(): - return - default: - ins := Decode(j1.memory[j1.pc]) - //fmt.Printf("%v\n%v", ins, j1) - j1.Eval(ins) - } - } -} - -func (j1 *J1) String() string { - s := fmt.Sprintf("\tPC=%0.4X ST=%0.4X\n", j1.pc, j1.st0) - s += fmt.Sprintf("\tD=%0.4X\n", j1.d.dump()) - s += fmt.Sprintf("\tR=%0.4X\n", j1.r.dump()) - return s -} - -func (j1 *J1) writeAt(addr, value uint16) { - if off := int(addr >> 1); off < memSize { - j1.memory[addr>>1] = value - } - switch addr { - case 0xf000: // key - j1.console.Write(value) - case 0xf002: // bye - j1.stop() - } -} - -func (j1 *J1) readAt(addr uint16) uint16 { - if off := int(addr >> 1); off < memSize { - return j1.memory[off] - } - switch addr { - case 0xf000: // tx! - return j1.console.Read() - case 0xf001: // ?rx - return j1.console.Len() - } - return 0 -} - -func (j1 *J1) Eval(ins Instruction) { - j1.pc++ - switch v := ins.(type) { - case Lit: - j1.d.push(j1.st0) - j1.st0 = v.Value() - case Jump: - j1.pc = v.Value() - case Call: - j1.r.push(j1.pc << 1) - j1.pc = v.Value() - case Cond: - if j1.st0 == 0 { - j1.pc = v.Value() - } - j1.st0 = j1.d.pop() - case ALU: - if v.RtoPC { - j1.pc = j1.r.get() >> 1 - } - if v.NtoAtT { - j1.writeAt(j1.st0, j1.d.get()) - } - st0 := j1.newST0(v.Opcode) - j1.d.move(v.Ddir) - j1.r.move(v.Rdir) - if v.TtoN { - j1.d.set(j1.st0) - } - if v.TtoR { - j1.r.set(j1.st0) - } - j1.st0 = st0 - } -} - -func (j1 *J1) newST0(opcode uint16) uint16 { - T, N, R := j1.st0, j1.d.get(), j1.r.get() - switch opcode { - case opT: // T - return T - case opN: // N - return N - case opTplusN: // T+N - return T + N - case opTandN: // T&N - return T & N - case opTorN: // T|N - return T | N - case opTxorN: // T^N - return T ^ N - case opNotT: // ~T - return ^T - case opNeqT: // N==T - return bool2int(N == T) - case opNleT: // N>T - return N >> (T & 0xf) - case opTminus1: // T-1 - return T - 1 - case opR: // R (rT) - return R - case opAtT: // [T] - return j1.readAt(T) - case opNlshiftT: // N<