From 6c99d1b3c6440a025de75f9a78ad674292510682 Mon Sep 17 00:00:00 2001 From: Izaya Orihara Date: Wed, 25 Jan 2017 12:13:14 +1100 Subject: [PATCH] Added an emulator and eventual separate library for emulating the T400 --- test3d_t400/emut400.lua | 51 +++++++++++++++++++++++++ test3d_t400/t400.lua | 85 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 test3d_t400/emut400.lua create mode 100644 test3d_t400/t400.lua diff --git a/test3d_t400/emut400.lua b/test3d_t400/emut400.lua new file mode 100644 index 0000000..20c27ac --- /dev/null +++ b/test3d_t400/emut400.lua @@ -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 diff --git a/test3d_t400/t400.lua b/test3d_t400/t400.lua new file mode 100644 index 0000000..136f030 --- /dev/null +++ b/test3d_t400/t400.lua @@ -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