137 lines
4.2 KiB
Lua
137 lines
4.2 KiB
Lua
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
|
|
})
|