local MEMSIZE=16 if not digiline then print("Digilines not found.") return end local oldprint=print local function print(...) 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)) if #sstab > 16 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 sval 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) if meta:get_string("state") == "waitingdat" and meta:get_string("waitingfor") == channel then push(pos,tonumber(msg)) meta:set_int("pc",meta:get_int("pc")+1) meta:set_string("state","running") 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("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) 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") --[[ 4095 = drop 4094 = dup 4093 = swap 4092 = read 4091 = write 4090 = add 4089 = sup 4088 = multiply 4087 = jmp 4086 = skip if zero ]]-- if ci == 4095 then print("Dropped "..tostring(pop(pos)).." from "..tostring(pos.x)..","..tostring(pos.y)..","..tostring(pos.z)) elseif ci == 4094 then local dat = pop(pos) push(pos,dat) push(pos,dat) print("Duplicated "..tostring(dat).." at "..tostring(pos.x)..","..tostring(pos.y)..","..tostring(pos.z)) elseif ci == 4093 then local a = pop(pos) local b = pop(pos) push(pos,b) push(pos,a) --[[ I'll write the stuff for reading and writing memory eventually(TM) ]]-- elseif ci == 4092 then skipnext = true meta:set_string("state","waitingdat") meta:set_string("waitingfor",meta:get_string("channel")..string.format("%X",addr)) local addr = pop(pos) digiline:receptor_send(pos,digiline.rules.default,meta:get_string("channel")..string.format("%X",addr),"get") elseif ci == 4091 then 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 == 4090 then print("Adding stuff") push(pos,pop(pos)+pop(pos)) elseif ci == 4089 then push(pos,pop(pos)-pop(pos)) elseif ci == 4088 then push(pos,pop(pos)*pop(pos)) elseif ci == 4087 then local npc = pop(pos) print("Jumping to "..tostring(npc)) meta:set_int("pc",npc) elseif ci == 4086 then if pop(pos) == 0 then meta:set_int("pc",meta:get_int("pc")+1) end else print("Pushing "..ci.." to "..pos2string(pos)) push(pos,ci) end if not skipnext then meta:set_int("pc",meta:get_int("pc")+1) 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")