local t = {} -- internal state --- program counter (pc) --- current instruction (ci) -- only passed from the environment to the emulator --- stack (stack) local function pop(s) return table.remove(s,#s) or 0 end local function push(s,v) v=v or 0 s[#s+1] = v%4096 if #s > 16 then table.remove(s,1) end end function t.run(stab) -- variables local pc = stab.pc or 1 local ci = stab.cins or 0 local stack = stab.stack or {} local rstack = stab.rstack or {} local pci = 1 local rw = nil local addr = 0 local dat = 0 -- instruction processing if ci == 4095 then -- ppc push(stack,pc) elseif ci == 4094 then -- swp a=pop(stack) b=pop(stack) push(stack,a) pusk(stack,b) elseif ci == 4093 then -- read rw = "read" -- terrible IPC addr = pop(stack) elseif ci == 4092 then -- write rw = "write" addr = pop(stack) dat = pop(stack) elseif ci == 4091 then -- add push(stack,pop(stack)+pop(stack)) elseif ci == 4090 then -- sub push(stack,pop(stack)+pop(stack)) elseif ci == 4089 then -- jmp pc = pop(stack) pci = 0 elseif ci == 4088 then -- sez if pop(stack) == 0 then pci = pci + 1 end elseif ci == 4087 then -- jez local a = pop(stack) if pop(stack) == 0 then pc = a pci = 0 end elseif ci == 4086 then -- jsr push(rstack,pc) pc = pop(stack) pci = 0 elseif ci == 4085 then -- ret pc = pop(rstack) elseif ci == 4084 then -- dup local v = pop(stack) push(stack,v) push(stack,v) elseif ci == 4083 then -- drop pop(stack) elseif ci == 4082 then -- hlt rw = "halt" else push(stack,ci) end -- return stuff stab = {} stab.pc = pc + pci -- increment pc stab.cins = 0 stab.stack = stack stab.rstack = rstack return stab, rw, addr, dat end return t