MT-test3d/test3d_t400/init.lua

215 lines
6.5 KiB
Lua

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")