98 lines
2.1 KiB
Lua
98 lines
2.1 KiB
Lua
local MAXADDR = 255
|
|
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%256
|
|
if #s > 16 then
|
|
table.remove(s,1)
|
|
end
|
|
end
|
|
|
|
function t.run(stab,ov)
|
|
-- variables
|
|
local pc = stab.pc or 1
|
|
local ci = stab.cins or 0
|
|
if ov then
|
|
ci = tonumber(ov) or 0
|
|
end
|
|
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 == 255 then -- ppc
|
|
push(stack,pc)
|
|
elseif ci == 254 then -- swp
|
|
a=pop(stack)
|
|
b=pop(stack)
|
|
push(stack,a)
|
|
push(stack,b)
|
|
elseif ci == 253 then -- read
|
|
rw = "read" -- terrible IPC
|
|
addr = pop(stack)
|
|
elseif ci == 252 then -- write
|
|
rw = "write"
|
|
addr = pop(stack)
|
|
dat = pop(stack)
|
|
--print("writing "..tostring(dat).." to "..tostring(addr))
|
|
elseif ci == 251 then -- add
|
|
push(stack,pop(stack)+pop(stack))
|
|
elseif ci == 250 then -- sub
|
|
push(stack,pop(stack)+pop(stack))
|
|
elseif ci == 249 then -- jmp
|
|
pc = pop(stack)
|
|
pci = 0
|
|
elseif ci == 248 then -- sez
|
|
if pop(stack) == 0 then
|
|
pci = pci + 1
|
|
end
|
|
elseif ci == 247 then -- jez
|
|
local a = pop(stack)
|
|
if pop(stack) == 0 then
|
|
pc = a
|
|
pci = 0
|
|
end
|
|
elseif ci == 246 then -- jsr
|
|
push(rstack,pc)
|
|
pc = pop(stack)
|
|
pci = 0
|
|
elseif ci == 245 then -- ret
|
|
pc = pop(rstack)
|
|
elseif ci == 244 then -- dup
|
|
local v = pop(stack)
|
|
push(stack,v)
|
|
push(stack,v)
|
|
elseif ci == 243 then -- drop
|
|
pop(stack)
|
|
elseif ci == 242 then -- hlt
|
|
rw = "halt"
|
|
elseif ci == 241 then -- prd
|
|
rw = "preread"
|
|
addr = pop(stack)
|
|
else
|
|
push(stack,ci)
|
|
end
|
|
-- return stuff
|
|
stab = {}
|
|
stab.pc = pc + pci -- increment pc
|
|
if stab.pc > MAXADDR then
|
|
stab.pc = 0
|
|
end
|
|
stab.cins = 0
|
|
stab.stack = stack
|
|
stab.rstack = rstack
|
|
if t.debug then print("t408: pc: "..tostring(stab.pc),"cins: "..tostring(ci),"tos: "..tostring(stab.stack[1]).." #s: "..tostring(#stab.stack),stab.rw,stab.addr,stab.dat) end
|
|
return stab, rw, addr, dat
|
|
end
|
|
|
|
return t
|