From 812fbd44ae5793b10d5c9da82eb4bf9f893e57b0 Mon Sep 17 00:00:00 2001 From: Izaya Date: Mon, 13 Feb 2017 10:15:41 +0000 Subject: [PATCH 1/5] Updated to use t400.lua from test3d-tools --- test3d_t400/init.lua | 200 +++++++++++++------------------------------ 1 file changed, 61 insertions(+), 139 deletions(-) diff --git a/test3d_t400/init.lua b/test3d_t400/init.lua index fe56aa9..46d11c4 100644 --- a/test3d_t400/init.lua +++ b/test3d_t400/init.lua @@ -1,10 +1,11 @@ -local MEMSIZE=16 +local MEMSIZE=16 -- does this still apply? local SHUTUP = false if not digiline then print("Digilines not found.") return end local path = minetest.get_modpath(minetest.get_current_modname()) +local t400 = dofile(path.."/t400.lua") local oldprint=print local function print(...) if SHUTUP then return end @@ -31,51 +32,34 @@ local function push(pos,val) end meta:set_string("stack",sstring) end -local function pop(pos) - local meta = minetest.get_meta(pos) - local sstring = "" - local sstab = string.split(meta:get_string("stack"),"\n") - local sval = table.remove(sstab,#sstab) - for k,v in ipairs(sstab) do - sstring = sstring .. v .. "\n" - end - meta:set_string("stack",sstring) - if not sval then sval = 0 end - return tonumber(sval) % 4096 -end -local function t400_digiline_receive(pos, node, channel, msg) - print("Digiline: "..tostring(pos.x)..","..tostring(pos.y)..","..tostring(pos.z).."; Channel: "..tostring(channel).."; Message: "..tostring(msg)) +function rqaddr(pos,addr,tp) local meta = minetest.get_meta(pos) - print(meta:get_string("state").." "..meta:get_string("waitingfor")) - if meta:get_string("state") == "waitingdat" and meta:get_string("waitingfor") == channel then - print("got data") - push(pos,tonumber(msg)) - meta:set_int("pc",meta:get_int("pc")+1) - meta:set_string("state","running") - print("finished getting data") - elseif meta:get_string("state") == "waitingins" and meta:get_string("waitingfor") == channel then - meta:set_int("ci",tonumber(msg)) - meta:set_string("state","running") - end + meta:set_string("state","waiting"..tostring(tp)) + meta:set_string("addr",addr) + print("rqaddr: "..addr.." "..tp) + digiline:receptor_send(pos,digiline.rules.default,meta:get_string("channel")..string.format("%X",tonumber(addr)),"get") end -print("Created T400 digiline function") local function t400_set_meta(pos) local meta = minetest.get_meta(pos) - local ms = "" + local stab = {} + stab.stack,stab.rstack = {},{} for i = 1, MEMSIZE do - ms = ms .. "0\n" + stab.stack[#stab.stack+1] = 0 + stab.rstack[#stab.stack+1] = 0 end - meta:set_string("stack",ms) - meta:set_string("retstack",ms) - meta:set_string("channel","Default") + stab.cins = 0 + stab.pc = 0 + meta:set_string("stab",minetest.serialize(stab)) + meta:set_string("channel","") + meta:set_string("rw","") meta:set_string("state","running") - meta:set_string("waitingfor","") meta:set_int("pc",0) - meta:set_int("ci",0) meta:set_string("formspec","size[5,5]\nlabel[0.4,0.5;T400 Execution Node]\nfield[0.5,2;4,1;channel;Channel prefix;${channel}]\nfield[0.5,3;4,1;pc;Program Counter;${pc}]field[0.5,4;4,1;state;State;${state}]") + print("Set metadata for a T400 node at "..pos2string(pos)) end + minetest.register_node("test3d_t400:t400", { description = "T400 Execution Node", tiles = { @@ -90,125 +74,63 @@ minetest.register_node("test3d_t400:t400", { }, }, }, - on_construct = t400_set_meta, groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3}, + on_construct = t400_set_meta, + on_receive_fields = function(pos,_,fields,sender) + print("Received fields for a T400 node at "..pos2string(pos)) + for k,v in pairs(fields) do print(tostring(k).." = "..tostring(v)) end + local meta = minetest.get_meta(pos) + if fields.channel ~= nil then + meta:set_string("channel",fields.channel) + end + if fields.pc ~= nil then + local stab = minetest.deserialize(meta:get_string("stab")) + stab.pc = tonumber(fields.pc) + meta:set_int("pc",fields.pc) -- for display only + meta:set_string("stab",minetest.serialize(stab)) + end + if fields.state ~= nil then + meta:set_string("state",fields.state) + end + end, digiline = { receptor = {}, effector = { - action = t400_digiline_receive + action = function(pos,node,channel,msg) + local meta = minetest.get_meta(pos) + local stab = minetest.deserialize(meta:get_string("stab")) + print(meta:get_string("state").." "..meta:get_string("addr"),channel.." "..msg.." = "..meta:get_string("channel")..string.format("%X",meta:get_string("addr"))) + if meta:get_string("state") == "waitingread" and meta:get_string("channel")..string.format("%X",meta:get_string("addr")) == channel then + push(pos,tonumber(msg)%4096) + rqaddr(pos,stab.pc,"ins") + elseif meta:get_string("state") == "waitingins" and meta:get_string("channel")..string.format("%X",meta:get_string("addr")) == channel then + stab.ins = (tonumber(msg)%4096) + meta:set_string("state","running") + end + end } - }, - on_receive_fields = 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) - meta:set_string("pc",fields.pc) - meta:set_string("state",fields.state) - end + } }) print("T400 node registered") - minetest.register_abm({ nodenames={"test3d_t400:t400"}, - interval=0.1, + interval=1, chance=1, action = function(pos) local meta = minetest.get_meta(pos) - local nins = 1 - if meta:get_string("state") == "running" then - local skipnext = false - print("Attempting to run T400 node at "..pos2string(pos)) - local ci = meta:get_int("ci") - if ci == 4095 then -- ppc - push(pos,meta:get_int("pc")) - elseif ci == 4094 then -- swp - why do I have this? - local a = pop(pos) - local b = pop(pos) - print("Swapping "..tostring(a).." for "..tostring(b)) - push(pos,b) - push(pos,a) - elseif ci == 4093 then -- read - skipnext = true - local addr = pop(pos) - meta:set_string("state","waitingdat") - meta:set_string("waitingfor",meta:get_string("channel")..string.format("%X",addr)) - meta:set_int("pc",meta:get_int("pc")+nins) - digiline:receptor_send(pos,digiline.rules.default,meta:get_string("channel")..string.format("%X",addr),"get") - return - elseif ci == 4092 then -- write - local addr = pop(pos) - local dat = pop(pos) - print("Writing "..tostring(dat).." to address "..addr) + if meta:get_string("state") ~= "running" then return false end + local stab = minetest.deserialize(meta:get_string("stab")) + local stab, rw, addr, dat = t400.run(stab) + meta:set_int("pc",stab.pc) + meta:set_string("stab",minetest.serialize(stab)) + print(minetest.serialize(stab)) + if rw == "read" then + rqaddr(pos,addr,rw) + else + if rw == "write" then digiline:receptor_send(pos,digiline.rules.default,meta:get_string("channel")..string.format("%X",addr),dat) - elseif ci == 4091 then -- add - print("Adding stuff") - push(pos,pop(pos)+pop(pos)) - elseif ci == 4090 then -- sub - push(pos,pop(pos)-pop(pos)) - elseif ci == 4089 then -- jmp - local npc = pop(pos) - print("Jumping to "..tostring(npc)) - meta:set_int("pc",npc) - nins=0 - elseif ci == 4088 then -- sez - local val = pop(pos) - print(val,type(val)) - if val == 0 then - print("Skipping because "..tostring(val).." = 0") - nins=nins+1 - end - elseif ci == 4087 then -- jez - local addr = pop(pos) - local val = pop(pos) - if val == 0 then - print("Jumping to "..addr.." because "..val.." = 0") - meta:set_int("pc",addr) - nins=0 - end - elseif ci == 4086 then -- jsr - local sstring = "" - local sstab = string.split(meta:get_string("retstack"),"\n") - sstab[#sstab+1] = tostring(tonumber(meta:get_int("pc")) % 4096) - if #sstab > MEMSIZE then - table.remove(sstab,1) - end - for k,v in ipairs(sstab) do - sstring = sstring .. v .. "\n" - end - meta:set_string("retstack",sstring) - meta:set_int("pc",pop(pos)) - nins=0 - elseif ci == 4085 then -- ret - local sstring = "" - local sstab = string.split(meta:get_string("retstack"),"\n") - local sval = tonumber(table.remove(sstab,#sstab)) - for k,v in ipairs(sstab) do - sstring = sstring .. v .. "\n" - end - meta:set_string("retstack",sstring) - if not sval then sval = 0 end - meta:set_int("pc",sval) - elseif ci == 4084 then -- dup - local v = pop(pos) - push(pos,v) - push(pos,v) - print("Duplicating "..v) - elseif ci == 4083 then -- drop - print("Dropping stuff") - pop(pos) - else - print("Pushing "..ci.." to "..pos2string(pos)) - push(pos,ci) - end - if not skipnext then - meta:set_int("pc",meta:get_int("pc")+nins) - meta:set_string("state","waitingins") - meta:set_string("waitingfor",meta:get_string("channel")..string.format("%X",meta:get_int("pc"))) - digiline:receptor_send(pos, digiline.rules.default, meta:get_string("channel")..string.format("%X",meta:get_int("pc")), "get") end + rqaddr(pos,stab.pc,"ins") end end }) -print("T400 ABM registered") -print("T400 init finished") From d50ccc7ddee27b7caf5fb39c324ba2624ff75165 Mon Sep 17 00:00:00 2001 From: Izaya Date: Mon, 13 Mar 2017 13:36:49 +1100 Subject: [PATCH 2/5] working T408 --- {test3d_t410 => test3d_t408}/depends.txt | 0 test3d_t408/emut408.lua | 58 +++++++ test3d_t408/init.lua | 198 +++++++++++++++++++++++ test3d_t408/t408.lua | 97 +++++++++++ test3d_t408/textures/t408.png | Bin 0 -> 778 bytes test3d_t410/init.lua | 30 ---- test3d_t410/textures/t416-side.png | Bin 217 -> 0 bytes test3d_t410/textures/t416-top.png | Bin 301 -> 0 bytes 8 files changed, 353 insertions(+), 30 deletions(-) rename {test3d_t410 => test3d_t408}/depends.txt (100%) create mode 100644 test3d_t408/emut408.lua create mode 100644 test3d_t408/init.lua create mode 100644 test3d_t408/t408.lua create mode 100644 test3d_t408/textures/t408.png delete mode 100644 test3d_t410/init.lua delete mode 100755 test3d_t410/textures/t416-side.png delete mode 100755 test3d_t410/textures/t416-top.png 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 0000000000000000000000000000000000000000..e5bfed3840363a715966e6332eb1bec92a3d06c7 GIT binary patch literal 778 zcmV+l1NHogP)+v8?yE3yLO72OU8Q|lz<#VJq zAoSR2e^5#x#HcL!cn|pKE3M^Ua`mUYmeVeN+4jvp*TUfUmHy`;9i)0NdZ-!r^@u}{ zP(8xXBUX=e0f7fMkH#TWJ-CBZ4@HkS^hnhs3_U{iNJEc^9$Gy*2T%3T4pKer#eVM* zh90SUq@hO`d6*ScJsO8j^@ts0PJ7Ob9*iEQ5SZ$5l|A4gm>-ND`gJ{~=)ssDf*z(& zoa@m*Fh4SS2-Y8r9$GyVJs9f`L6402(K+UNgbsopg7rs652+sdvVv@ltJOo$BV+v` z=+QZ5=V=4M`h(F!uz$(bgI{LY9*C<)#{NangR%bT9CJNl2SE?T{-xyy5CVsr}2fETO+` z9)k5p#{ETx`60N!WUM~~J-GLC{YIYJ-(Il=&p%rKlF>u3{@~&M!dQO@dSvWh+Vc++ z^i!XIT-(|?Bcq34|H9~@!}>$fgRy@R^vL~rP%i}j{XE z)7O>#AtN8F7R#c2-|hj0WHUn|N}Tg^b5rw5fLsO!=c3falGGH1^30M91$R&1fE2w{ zcA&Vwr;B5V#`$EMk{1HZnhmT@OP4Pf4zVhJ=EKIucFeh*@9peB*CikQBy)9mczCqW z?^g|DKH~YX?a-2+iC5YbGnkcCwhB$2Gsozb!~>}gc7~tws&+PkYz-hgJzf1=);T3K F0RRU9J!k*` diff --git a/test3d_t410/textures/t416-top.png b/test3d_t410/textures/t416-top.png deleted file mode 100755 index 05c2d9cee1905bb88dbad48a9fab6cafc1cf8e31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 301 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#AtN6vhoT=x%1)q=Y-UJAiF1B#Zfaf$kjuc}T$GwvlA5AWo>`Ki;O^-gkfN8$ z4isPP>EaloaX#6muvsvIUSM| zn{JWNoD;}90o22g nc;Kwt55`HWI(%w+mZ;@3gnwUQ(jzi|0>~epu6{1-oD!M<-NI?U From bc9215493693fee51258c1b21e7617ed04010c2a Mon Sep 17 00:00:00 2001 From: Izaya Date: Mon, 13 Mar 2017 13:37:30 +1100 Subject: [PATCH 3/5] cleaned up some stuff, just the T408 right now --- test3d_t400/depends.txt | 2 - test3d_t400/init.lua | 136 ----------------------------- test3d_t400/t400.lua | 85 ------------------ test3d_t400/textures/t400.png | Bin 778 -> 0 bytes test3d_t416/depends.txt | 2 - test3d_t416/init.lua | 68 --------------- test3d_t416/textures/t416-side.png | Bin 217 -> 0 bytes test3d_t416/textures/t416-top.png | Bin 301 -> 0 bytes 8 files changed, 293 deletions(-) delete mode 100644 test3d_t400/depends.txt delete mode 100644 test3d_t400/init.lua delete mode 100644 test3d_t400/t400.lua delete mode 100644 test3d_t400/textures/t400.png delete mode 100644 test3d_t416/depends.txt delete mode 100644 test3d_t416/init.lua delete mode 100755 test3d_t416/textures/t416-side.png delete mode 100755 test3d_t416/textures/t416-top.png diff --git a/test3d_t400/depends.txt b/test3d_t400/depends.txt deleted file mode 100644 index 2cec86e..0000000 --- a/test3d_t400/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -default -digilines diff --git a/test3d_t400/init.lua b/test3d_t400/init.lua deleted file mode 100644 index 46d11c4..0000000 --- a/test3d_t400/init.lua +++ /dev/null @@ -1,136 +0,0 @@ -local MEMSIZE=16 -- does this still apply? -local SHUTUP = false -if not digiline then - print("Digilines not found.") - return -end -local path = minetest.get_modpath(minetest.get_current_modname()) -local t400 = dofile(path.."/t400.lua") -local oldprint=print -local function print(...) - if SHUTUP then return end - for k,v in ipairs({...}) do - oldprint("[Test3D:T400] "..tostring(v)) - end -end -print("Loading.") - -local function pos2string(pos) - return tostring(pos.x)..","..tostring(pos.y)..","..tostring(pos.z) -end - -local function push(pos,val) - local meta = minetest.get_meta(pos) - local sstring = "" - local sstab = string.split(meta:get_string("stack"),"\n") - sstab[#sstab+1] = tostring(tonumber(val) % 4096) - if #sstab > MEMSIZE then - table.remove(sstab,1) - end - for k,v in ipairs(sstab) do - sstring = sstring .. v .. "\n" - end - meta:set_string("stack",sstring) -end - -function rqaddr(pos,addr,tp) - local meta = minetest.get_meta(pos) - meta:set_string("state","waiting"..tostring(tp)) - meta:set_string("addr",addr) - print("rqaddr: "..addr.." "..tp) - digiline:receptor_send(pos,digiline.rules.default,meta:get_string("channel")..string.format("%X",tonumber(addr)),"get") -end - -local function t400_set_meta(pos) - local meta = minetest.get_meta(pos) - local stab = {} - stab.stack,stab.rstack = {},{} - for i = 1, MEMSIZE do - stab.stack[#stab.stack+1] = 0 - stab.rstack[#stab.stack+1] = 0 - end - stab.cins = 0 - stab.pc = 0 - meta:set_string("stab",minetest.serialize(stab)) - meta:set_string("channel","") - meta:set_string("rw","") - meta:set_string("state","running") - meta:set_int("pc",0) - meta:set_string("formspec","size[5,5]\nlabel[0.4,0.5;T400 Execution Node]\nfield[0.5,2;4,1;channel;Channel prefix;${channel}]\nfield[0.5,3;4,1;pc;Program Counter;${pc}]field[0.5,4;4,1;state;State;${state}]") - print("Set metadata for a T400 node at "..pos2string(pos)) -end - -minetest.register_node("test3d_t400:t400", { - description = "T400 Execution Node", - tiles = { - { - image="t400.png", - animation={ - type = "vertical_frames", - aspect_w=16, - aspect_h=16, - length=18, - length=1.8, - }, - }, - }, - groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3}, - on_construct = t400_set_meta, - on_receive_fields = function(pos,_,fields,sender) - print("Received fields for a T400 node at "..pos2string(pos)) - for k,v in pairs(fields) do print(tostring(k).." = "..tostring(v)) end - local meta = minetest.get_meta(pos) - if fields.channel ~= nil then - meta:set_string("channel",fields.channel) - end - if fields.pc ~= nil then - local stab = minetest.deserialize(meta:get_string("stab")) - stab.pc = tonumber(fields.pc) - meta:set_int("pc",fields.pc) -- for display only - meta:set_string("stab",minetest.serialize(stab)) - end - if fields.state ~= nil then - meta:set_string("state",fields.state) - end - end, - digiline = { - receptor = {}, - effector = { - action = function(pos,node,channel,msg) - local meta = minetest.get_meta(pos) - local stab = minetest.deserialize(meta:get_string("stab")) - print(meta:get_string("state").." "..meta:get_string("addr"),channel.." "..msg.." = "..meta:get_string("channel")..string.format("%X",meta:get_string("addr"))) - if meta:get_string("state") == "waitingread" and meta:get_string("channel")..string.format("%X",meta:get_string("addr")) == channel then - push(pos,tonumber(msg)%4096) - rqaddr(pos,stab.pc,"ins") - elseif meta:get_string("state") == "waitingins" and meta:get_string("channel")..string.format("%X",meta:get_string("addr")) == channel then - stab.ins = (tonumber(msg)%4096) - meta:set_string("state","running") - end - end - } - } -}) -print("T400 node registered") -minetest.register_abm({ - nodenames={"test3d_t400:t400"}, - interval=1, - chance=1, - action = function(pos) - local meta = minetest.get_meta(pos) - if meta:get_string("state") ~= "running" then return false end - local stab = minetest.deserialize(meta:get_string("stab")) - local stab, rw, addr, dat = t400.run(stab) - meta:set_int("pc",stab.pc) - meta:set_string("stab",minetest.serialize(stab)) - print(minetest.serialize(stab)) - if rw == "read" then - rqaddr(pos,addr,rw) - else - if rw == "write" then - digiline:receptor_send(pos,digiline.rules.default,meta:get_string("channel")..string.format("%X",addr),dat) - end - rqaddr(pos,stab.pc,"ins") - end - end -}) diff --git a/test3d_t400/t400.lua b/test3d_t400/t400.lua deleted file mode 100644 index 136f030..0000000 --- a/test3d_t400/t400.lua +++ /dev/null @@ -1,85 +0,0 @@ -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 diff --git a/test3d_t400/textures/t400.png b/test3d_t400/textures/t400.png deleted file mode 100644 index e5bfed3840363a715966e6332eb1bec92a3d06c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 778 zcmV+l1NHogP)+v8?yE3yLO72OU8Q|lz<#VJq zAoSR2e^5#x#HcL!cn|pKE3M^Ua`mUYmeVeN+4jvp*TUfUmHy`;9i)0NdZ-!r^@u}{ zP(8xXBUX=e0f7fMkH#TWJ-CBZ4@HkS^hnhs3_U{iNJEc^9$Gy*2T%3T4pKer#eVM* zh90SUq@hO`d6*ScJsO8j^@ts0PJ7Ob9*iEQ5SZ$5l|A4gm>-ND`gJ{~=)ssDf*z(& zoa@m*Fh4SS2-Y8r9$GyVJs9f`L6402(K+UNgbsopg7rs652+sdvVv@ltJOo$BV+v` z=+QZ5=V=4M`h(F!uz$(bgI{LY9*C<)#{NangR%bT9CJNl2SE?T{-xyy5CVsr}2fETO+` z9)k5p#{ETx`60N!WUM~~J-GLC{YIYJ-(Il=&p%rKlF>u3{@~&M!dQO@dSvWh+Vc++ z^i!XIT-(|?Bcq34|H9~@!}>$fgRy@R^vL~rP%i}j 0 then - local memaddr = tonumber(channel:sub(#chan+1),16)+1-memoffset - if tostring(msg):lower() == "get" then - digiline:receptor_send(pos, digiline.rules.default, channel, tonumber(mem[memaddr] or 0)) - print("Reading address "..tostring(memaddr)..": "..tostring(mem[memaddr])) - else - mem[memaddr] = tonumber(msg) or 0 - for k,v in ipairs(mem) do - ms = ms .. tostring(v) .. "\n" - end - meta:set_string("mem",ms) - print("Set address "..tostring(memaddr).." to "..tostring(tonumber(msg))) - end - end -end -print("Created T416 digiline function") - -local function t416_set_meta(pos) - local meta = minetest.get_meta(pos) - local ms = "" - for i = 1, MEMSIZE do - ms = ms .. "0\n" - end - meta:set_string("mem",ms) - meta:set_string("channel","Default") - meta:set_int("startaddr",0) - meta:set_string("formspec","size[5,12]\nlabel[0.4,0.5;T416 Memory Node (16 words)]\nfield[0.5,2;4,1;channel;Channel prefix;${channel}]\nfield[0.5,3;4,1;startaddr;Starting address;${startaddr}]\ntextarea[0.5,4;4,8;mem;Memory contents;${mem}]") -end -minetest.register_node("test3d_t416:t416", { - description = "T416 Memory Node", - tiles = {"t416-top.png","t416-top.png","t416-side.png","t416-side.png","t416-side.png","t416-side.png"}, - on_construct = t416_set_meta, - groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3}, - digiline = { - receptor = {}, - effector = { - action = function (a,b,c,d) pcall(t416_digiline_receive,a,b,c,d) end - } - }, - on_receive_fields = 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) - meta:set_int("startaddr",tonumber(fields.startaddr)) - end -}) -print("T416 node registered") diff --git a/test3d_t416/textures/t416-side.png b/test3d_t416/textures/t416-side.png deleted file mode 100755 index 43b57037bbed1e92f96f7cfad5a4edc4c7c222a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 217 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#AtN8F7R#c2-|hj0WHUn|N}Tg^b5rw5fLsO!=c3falGGH1^30M91$R&1fE2w{ zcA&Vwr;B5V#`$EMk{1HZnhmT@OP4Pf4zVhJ=EKIucFeh*@9peB*CikQBy)9mczCqW z?^g|DKH~YX?a-2+iC5YbGnkcCwhB$2Gsozb!~>}gc7~tws&+PkYz-hgJzf1=);T3K F0RRU9J!k*` diff --git a/test3d_t416/textures/t416-top.png b/test3d_t416/textures/t416-top.png deleted file mode 100755 index 05c2d9cee1905bb88dbad48a9fab6cafc1cf8e31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 301 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#AtN6vhoT=x%1)q=Y-UJAiF1B#Zfaf$kjuc}T$GwvlA5AWo>`Ki;O^-gkfN8$ z4isPP>EaloaX#6muvsvIUSM| zn{JWNoD;}90o22g nc;Kwt55`HWI(%w+mZ;@3gnwUQ(jzi|0>~epu6{1-oD!M<-NI?U From 856bcf40f5514a25589722ce238057fe94dabe5d Mon Sep 17 00:00:00 2001 From: Izaya Date: Mon, 13 Mar 2017 17:34:51 +1100 Subject: [PATCH 4/5] updated README --- README.md | 54 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 532eab5..5e8cab7 100644 --- a/README.md +++ b/README.md @@ -8,29 +8,43 @@ Memory access in this mod occurs over digilines, with the channel as the prefix |A | 1 | 4 | A1 | 4 | |Default| 15 | get | DefaultF | get | -## T400 -The T400 is a 12-bit stack machine operating at 1Hz (due to ABMs only running once per second). It has a 16-word stack, 0 registers and a very simple instruction set. +## T408 +The T400 is an 8-bit stack machine operating at 1Hz (due to ABMs only running once per second). It has a 16-word stack, 0 registers and a very simple instruction set. ### Instructions -There are 8 instructions for the T400. Any values encountered by the processor that are not instructions are treated as data and pushed to the stack. While this does make both the code for the emulator and the code for the emulated computer simple, it has the downside that if you really do want the value 4095 you have to add two things together. +Any words encountered that aren't instructions are pushed to the stack. This makes very compact simple program code. | ins | function | mnemonic | |--------|----------------------------------------------|---------------| -|4095 | push program counter | ppc | -|4094 | swap TOS | swp | -|4093 | read memory from TOS | read | -|4092 | write to memory from TOS | write | -|4091 | add TOS | add | -|4090 | suptract TOS | sub | -|4089 | jump to TOS | jmp | -|4088 | skip if TOS = zero | sez | -|4087 | jump if TOS = zero | jez | -|4086 | jump to subroutine, push pc to retstack | jsr | -|4085 | return from subroutine, PC = top of retstack | ret | -|4084 | duplicate TOS | dup | -|4083 | drop TOS | drop | +| 255 | push program counter | ppc | +| 254 | swap TOS | swp | +| 253 | read memory from TOS | read | +| 252 | write to memory from TOS | write | +| 251 | add TOS | add | +| 250 | suptract TOS | sub | +| 249 | jump to TOS | jmp | +| 248 | skip if TOS = zero | sez | +| 247 | jump if TOS = zero | jez | +| 246 | jump to subroutine, push pc to retstack | jsr | +| 245 | return from subroutine, PC = top of retstack | ret | +| 244 | duplicate TOS | dup | +| 243 | drop TOS | drop | +| 242 | halt processor | hlt | +| 241 | pre-read address at TOS | prd | -## T410 -The T410, is, in essence, the write instruction in a block. You put in an address and a value and it tries to write the value to that address. +### I/O +The T408 uses memory-mapped I/O. This may seem like a stupid idea on a machine with 8-bit addressing but port-based I/O isn't hugely sane. + +Address 224 to 239 (16 words) are used for access to external devices. In Minetest you need to execute the **prd** instruction first, though in an emulator that is treated as a no-op. + +### Examples +Counts upwards from zero, writing the result to address 224 (0) +``` +1 -- push 1 +251 -- add +244 -- dup +224 -- push 224 +252 -- write result to 224 +1 -- push 1 +249 -- jump to 1 +``` -## T416 -The T416 is a 16-word memory. It stores 16 ints and is accessed as described in the Memory access section. From c5d745608e2db504b243acb07511d6c4e9ff0786 Mon Sep 17 00:00:00 2001 From: Izaya Date: Mon, 13 Mar 2017 17:36:11 +1100 Subject: [PATCH 5/5] README formatting --- README.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 5e8cab7..9a4c7ac 100644 --- a/README.md +++ b/README.md @@ -13,23 +13,23 @@ The T400 is an 8-bit stack machine operating at 1Hz (due to ABMs only running on ### Instructions Any words encountered that aren't instructions are pushed to the stack. This makes very compact simple program code. -| ins | function | mnemonic | -|--------|----------------------------------------------|---------------| -| 255 | push program counter | ppc | -| 254 | swap TOS | swp | -| 253 | read memory from TOS | read | -| 252 | write to memory from TOS | write | -| 251 | add TOS | add | -| 250 | suptract TOS | sub | -| 249 | jump to TOS | jmp | -| 248 | skip if TOS = zero | sez | -| 247 | jump if TOS = zero | jez | -| 246 | jump to subroutine, push pc to retstack | jsr | -| 245 | return from subroutine, PC = top of retstack | ret | -| 244 | duplicate TOS | dup | -| 243 | drop TOS | drop | -| 242 | halt processor | hlt | -| 241 | pre-read address at TOS | prd | +| ins | function | mnemonic | +|-------|-----------------------------------------------|---------------| +| 255 | push program counter | ppc | +| 254 | swap TOS | swp | +| 253 | read memory from TOS | read | +| 252 | write to memory from TOS | write | +| 251 | add TOS | add | +| 250 | suptract TOS | sub | +| 249 | jump to TOS | jmp | +| 248 | skip if TOS = zero | sez | +| 247 | jump if TOS = zero | jez | +| 246 | jump to subroutine, push pc to retstack | jsr | +| 245 | return from subroutine, PC = top of retstack | ret | +| 244 | duplicate TOS | dup | +| 243 | drop TOS | drop | +| 242 | halt processor | hlt | +| 241 | pre-read address at TOS | prd | ### I/O The T408 uses memory-mapped I/O. This may seem like a stupid idea on a machine with 8-bit addressing but port-based I/O isn't hugely sane.