local MEMSIZE=16 local SHUTUP = false if not digiline then print("Digilines not found.") return end local path = minetest.get_modpath(minetest.get_current_modname()) 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 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)) 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 end print("Created T400 digiline function") local function t400_set_meta(pos) local meta = minetest.get_meta(pos) local ms = "" for i = 1, MEMSIZE do ms = ms .. "0\n" end meta:set_string("stack",ms) meta:set_string("retstack",ms) meta:set_string("channel","Default") 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}]") 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, }, }, }, on_construct = t400_set_meta, groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3}, digiline = { receptor = {}, effector = { action = t400_digiline_receive } }, 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, 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) 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 end end }) print("T400 ABM registered") print("T400 init finished")