Added an emulator and eventual separate library for emulating the T400
This commit is contained in:
parent
f3395ca307
commit
6c99d1b3c6
51
test3d_t400/emut400.lua
Normal file
51
test3d_t400/emut400.lua
Normal file
@ -0,0 +1,51 @@
|
||||
stab = {}
|
||||
stab.stack = {}
|
||||
stab.pc = 1
|
||||
stab.cins = 0
|
||||
mem = {}
|
||||
t400 = require "t400"
|
||||
|
||||
while true do
|
||||
io.write("*> ")
|
||||
i=io.read()
|
||||
it = {}
|
||||
for s in i:gmatch("%S+") do it[#it+1] = s end
|
||||
if it[1] == "peek" then
|
||||
print(mem[tonumber(it[2])])
|
||||
elseif it[1] == "poke" then
|
||||
mem[tonumber(it[2])] = tonumber(it[3])
|
||||
elseif it[1] == "push" then
|
||||
stab.stack[#stab.stack+1] = tonumber(it[2])
|
||||
elseif it[1] == "dumpstack" then
|
||||
for k,v in ipairs(stab.stack) do print(k,v) end
|
||||
elseif it[1] == "ppc" then
|
||||
print(stab.pc)
|
||||
elseif it[1] == "spc" then
|
||||
stab.pc=tonumber(it[2])
|
||||
elseif it[1] == "step" then
|
||||
local scount = tonumber(it[2]) or 1
|
||||
for i = 1, scount do
|
||||
stab.cins = mem[stab.pc]
|
||||
stab,rw,addr,val=t400.run(stab)
|
||||
if rw == "halt" then break end
|
||||
if rw == "read" then
|
||||
stab.stack[#stab.stack+1] = mem[addr]
|
||||
elseif rw == "write" then
|
||||
mem[addr] = dat
|
||||
end
|
||||
end
|
||||
elseif it[1] == "load" then
|
||||
local f,e = io.open(it[2])
|
||||
if f == nil then
|
||||
print("Error: "..e)
|
||||
else
|
||||
local n = tonumber(it[3]) or 0
|
||||
local c = f:read("*a")
|
||||
f:close()
|
||||
for v in c:gmatch("%S+") do
|
||||
mem[n] = tonumber(v) or 0
|
||||
n = n + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
85
test3d_t400/t400.lua
Normal file
85
test3d_t400/t400.lua
Normal file
@ -0,0 +1,85 @@
|
||||
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
|
Loading…
Reference in New Issue
Block a user