diff --git a/test3d_t410/depends.txt b/test3d_t408/depends.txt similarity index 100% rename from test3d_t410/depends.txt rename to test3d_t408/depends.txt diff --git a/test3d_t408/emut408.lua b/test3d_t408/emut408.lua new file mode 100644 index 0000000..c34d0c7 --- /dev/null +++ b/test3d_t408/emut408.lua @@ -0,0 +1,58 @@ +stab = {} +stab.stack = {} +stab.pc = 1 +stab.cins = 0 +mem = {} +t408 = require "t408" + +while true do + io.write("*> ") + i=io.read() + it = {} + for s in i:gmatch("%S+") do it[#it+1] = s end + if it[1] == "quit" then + break + elseif 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=t408.run(stab) + --print(rw,addr,val) + if rw == "halt" then print("Halted at "..tostring(stab.pc) )break end + if rw == "read" then + stab.stack[#stab.stack+1] = mem[addr] + elseif rw == "write" then + mem[addr] = val + if addr == 0 then io.write(string.char(val)) end + end + end + elseif it[1] == "debug" then + print(not t408.debug) + t408.debug = not t408.debug + 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("%d+") do + mem[n] = tonumber(v) or 0 + n = n + 1 + end + end + end +end diff --git a/test3d_t408/init.lua b/test3d_t408/init.lua new file mode 100644 index 0000000..95091b3 --- /dev/null +++ b/test3d_t408/init.lua @@ -0,0 +1,198 @@ +local MEMSIZE=16 +local path = minetest.get_modpath(minetest.get_current_modname()) +local t408_mem, t408_stab = {},{} +print("Looking for memory file at "..path.."/mem.dat") +local f=io.open(path.."/mem.dat","rb") +if f ~= nil then + local c = f:read("*a") + print("Found T408 memory file.") +-- rawset(_G,"t408_mem",minetest.deserialize(c)) + t408_mem = minetest.deserialize(c) + print("Contents: "..c) + f:close() +end +print("Looking for metadata file at "..path.."/stab.dat") +local f=io.open(path.."/stab.dat","rb") +if f ~= nil then + print("Found T408 metadata file.") + local c = f:read("*a") + t408_stab = minetest.deserialize(c) + print("Contents: "..c) + f:close() +end +local t408 = dofile(path.."/t408.lua") +t408.debug = true +print(type(_G.t408_mem)) +if not digiline then + print("Digilines not found.") + return +end +local oldprint=print +local function print(...) + for k,v in ipairs({...}) do + oldprint("[Test3D:T408] "..tostring(v)) + end +end +print("Loading.") + +local function t408_digiline_receive(pos, node, channel, msg) + local meta = minetest.get_meta(pos) + local nid = minetest.pos_to_string(pos) + local prea,preb = string.find(channel,meta:get_string("channel")) + print("Start channel: "..prea,"End channel: "..preb) + print("Recieved (pre)"..tostring(msg).." from "..tostring(channel).." (device channel: "..tostring(meta:get_string("channel"))..")") + if prea == 1 then + --if string.sub(channel,1,meta:get_string("channel"):len()) == meta:get_string("channel") then +-- local addr = tonumber(msg:sub(meta:get_string("channel"):len()+1)) +-- local addr = tonumber(channel) + print("Correct channel.") + local addr = tonumber(string.sub(channel,preb+1)) + print(addr) + if addr > -1 and addr < 16 then + print("Recieved "..tostring(msg).." from "..tostring(channel).." for "..tostring(addr).." (device channel: "..tostring(meta:get_string("channel"))..")") + t408_mem[nid][addr+224] = tonumber(msg) + end + end + --end +end +print("Created T408 digiline function") + +local function t408_read(pos,addr) + if t408_mem[pos] == nil then return false end + print("Read: "..tostring(pos).." "..tostring(addr)..": "..tostring(t408_mem[pos][addr])) + return t408_mem[pos][addr] or 0 +end +local function t408_write(pos,addr,val) + print(tostring(pos).." "..tostring(addr).." "..tostring(val)) + if t408_mem[pos] == nil then return false end + t408_mem[pos][tonumber(addr)] = (tonumber(val)%256) + print("Write: "..tostring(pos).." "..tostring(addr)..": "..tostring(t408_mem[pos][addr]).." = "..tostring(val)) + return true +end + +local function t408_set_meta(pos) + local meta = minetest.get_meta(pos) + meta:set_string("channel","") + meta:set_string("state","running") + t408_mem[minetest.pos_to_string(pos)] = {} + t408_stab[minetest.pos_to_string(pos)] = {["ci"]=1,["pc"]=1,["stack"]={},["rstack"]={}} + print("Created T408 memory table with ID "..minetest.pos_to_string(pos)) +end +minetest.register_node("test3d_t408:t408", { + description = "T408 Memory Node", + tiles = {{image="t408.png",animation={type="vertical_frames",aspect_w=16,aspect_h=16,length=1.8}}}, + on_construct = t408_set_meta, + groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3}, + digiline = { + receptor = {}, + effector = { + action = function (a,b,c,d) pcall(t408_digiline_receive,a,b,c,d) end + } + }, + on_punch = function(pos,_,fields,sender) +-- if fields.channel == nil then return end + local meta = minetest.get_meta(pos) +-- fields.channel = fields.channel or "" +-- meta:set_string("channel",fields.channel) + if meta:get_string("state") == "running" then + meta:set_string("state","halted") + else + meta:set_string("state","running") + end + print(meta:get_string("state")) + end +}) +minetest.register_chatcommand("test3d-t408-read", { + params = "
", + description = "Read the memory in a T408 node", + func = function(name,str) + local tArg = {} + for s in str:gmatch("%S+") do + tArg[#tArg+1] = s + end + local nid,addr = tArg[1],tArg[2] + print(nid,addr) + minetest.chat_send_player(name,tostring(t408_read(nid,tonumber(addr)))) + end +}) +minetest.register_chatcommand("test3d-t408-write", { + params = "
", + description = "Read the memory in a T408 node", + func = function(name,str) + local tArg = {} + for s in str:gmatch("%S+") do + tArg[#tArg+1] = s + end + local nid,addr,val = tArg[1],tArg[2],tArg[3] + print(nid,addr,val) + minetest.chat_send_player(name,tostring(t408_write(nid,tonumber(addr),tostring(val)))) + end +}) +minetest.register_chatcommand("test3d-t408-set", { + params = " ", + description = "Set T408 variables.", + func = function(name,str) + local tArg = {} + for s in str:gmatch("%S+") do + tArg[#tArg+1] = s + end + local nid,addr,val = tArg[1],tArg[2],tArg[3] + local meta = minetest.get_meta(minetest.string_to_pos(nid)) + meta:set_string(addr,tArg[3] or "") + print("Set "..nid.."'s "..addr.." to "..(tArg[3] or "")) + end +}) +minetest.register_chatcommand("test3d-t408-dump", { + params = "
", + description = "Read the memory in a T408 node", + func = function(name,nid,addr,val) + for k,v in ipairs(t408_mem) do + print(k,v) + end + end +}) + +print("T408 node registered") + +minetest.register_abm({ + nodenames={"test3d_t408:t408"}, + interval=1, + chance=1, + action = function(pos) + local meta = minetest.get_meta(pos) + if meta:get_string("state") == "running" then + local nid = minetest.pos_to_string(pos) + local stab,rw,addr,val = t408_stab[nid],nil,0,0 + stab.cins = t408_mem[nid][stab.pc] + stab,rw,addr,val = t408.run(stab) + if rw == "read" then + stab.stack[#stab.stack+1] = t408_mem[nid][addr] + elseif rw == "preread" then + if addr > 223 and addr < 240 then + digiline:receptor_send(pos,digiline.rules.default,meta:get_string("channel")..string.format("%X",tonumber(addr)-224),"get") + end + elseif rw == "write" then + t408_mem[nid][addr] = tonumber(val) + print("Writing "..tostring(val).." to "..tostring(addr)) + if addr > 223 and addr < 240 then + digiline:receptor_send(pos,digiline.rules.default,meta:get_string("channel")..string.format("%X",tonumber(addr)-224),tonumber(val)) + print(string.char(val)) + end + end + t408_stab[nid] = stab + end + end +}) + +minetest.register_on_shutdown(function() + local f=io.open(path.."/mem.dat","wb") + if f then + f:write(minetest.serialize(t408_mem)) + f:close() + end + local f=io.open(path.."/stab.dat","wb") + if f then + f:write(minetest.serialize(t408_stab)) + f:close() + end +end) diff --git a/test3d_t408/t408.lua b/test3d_t408/t408.lua new file mode 100644 index 0000000..893074b --- /dev/null +++ b/test3d_t408/t408.lua @@ -0,0 +1,97 @@ +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 diff --git a/test3d_t408/textures/t408.png b/test3d_t408/textures/t408.png new file mode 100644 index 0000000..e5bfed3 Binary files /dev/null and b/test3d_t408/textures/t408.png differ diff --git a/test3d_t410/init.lua b/test3d_t410/init.lua deleted file mode 100644 index 7d6f874..0000000 --- a/test3d_t410/init.lua +++ /dev/null @@ -1,30 +0,0 @@ -if not digiline then - print("Digilines not found.") - return -end -local oldprint=print -local function print(...) - for k,v in ipairs({...}) do - oldprint("[Test3D:T410] "..tostring(v)) - end -end -print("Loading.") - -local function t410_set_meta(pos) - minetest.get_meta(pos):set_string("formspec","size[2,4]\nfield[0,1;2.9,1;addr;Address;]\nfield[0,2;2.9,1;data;Data;]\nbutton[0,3;2,1;write;Write]") -end -minetest.register_node("test3d_t410:t410", { - description = "T410 Memory Access Console", - tiles = {"t416-top.png","t416-top.png","t416-side.png","t416-side.png","t416-side.png","t416-side.png"}, - on_construct = t410_set_meta, - groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3}, - on_receive_fields = function(pos,_,fields,sender) - if fields.addr == nil then return end - digiline:receptor_send(pos, digiline.rules.default, fields.addr, tonumber(fields.data) or 0) - print("Set "..fields.addr.." to "..fields.data) - end, - digiline = { - receptor = {}, - }, -}) -print("T410 node registered") diff --git a/test3d_t410/textures/t416-side.png b/test3d_t410/textures/t416-side.png deleted file mode 100755 index 43b5703..0000000 Binary files a/test3d_t410/textures/t416-side.png and /dev/null differ diff --git a/test3d_t410/textures/t416-top.png b/test3d_t410/textures/t416-top.png deleted file mode 100755 index 05c2d9c..0000000 Binary files a/test3d_t410/textures/t416-top.png and /dev/null differ