Merge pull request #4 from XeonSquared/dev

Replace all with T408
This commit is contained in:
Izaya 2017-03-13 17:41:09 +11:00 committed by GitHub
commit 3af961ac7b
15 changed files with 321 additions and 355 deletions

View File

@ -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 (<prefix>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.

View File

@ -1,214 +0,0 @@
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")

58
test3d_t408/emut408.lua Normal file
View File

@ -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

198
test3d_t408/init.lua Normal file
View File

@ -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 = "<node ID> <address>",
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 = "<node ID> <address> <new value>",
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 = "<node ID> <variable> <new value>",
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 = "<node ID> <address> <new value>",
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)

View File

@ -1,3 +1,4 @@
local MAXADDR = 255
local t = {}
-- internal state
--- program counter (pc)
@ -8,16 +9,19 @@ local function pop(s)
end
local function push(s,v)
v=v or 0
s[#s+1] = v%4096
s[#s+1] = v%256
if #s > 16 then
table.remove(s,1)
end
end
function t.run(stab)
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
@ -25,60 +29,68 @@ function t.run(stab)
local addr = 0
local dat = 0
-- instruction processing
if ci == 4095 then -- ppc
if ci == 255 then -- ppc
push(stack,pc)
elseif ci == 4094 then -- swp
elseif ci == 254 then -- swp
a=pop(stack)
b=pop(stack)
push(stack,a)
pusk(stack,b)
elseif ci == 4093 then -- read
push(stack,b)
elseif ci == 253 then -- read
rw = "read" -- terrible IPC
addr = pop(stack)
elseif ci == 4092 then -- write
elseif ci == 252 then -- write
rw = "write"
addr = pop(stack)
dat = pop(stack)
elseif ci == 4091 then -- add
--print("writing "..tostring(dat).." to "..tostring(addr))
elseif ci == 251 then -- add
push(stack,pop(stack)+pop(stack))
elseif ci == 4090 then -- sub
elseif ci == 250 then -- sub
push(stack,pop(stack)+pop(stack))
elseif ci == 4089 then -- jmp
elseif ci == 249 then -- jmp
pc = pop(stack)
pci = 0
elseif ci == 4088 then -- sez
elseif ci == 248 then -- sez
if pop(stack) == 0 then
pci = pci + 1
end
elseif ci == 4087 then -- jez
elseif ci == 247 then -- jez
local a = pop(stack)
if pop(stack) == 0 then
pc = a
pci = 0
end
elseif ci == 4086 then -- jsr
elseif ci == 246 then -- jsr
push(rstack,pc)
pc = pop(stack)
pci = 0
elseif ci == 4085 then -- ret
elseif ci == 245 then -- ret
pc = pop(rstack)
elseif ci == 4084 then -- dup
elseif ci == 244 then -- dup
local v = pop(stack)
push(stack,v)
push(stack,v)
elseif ci == 4083 then -- drop
elseif ci == 243 then -- drop
pop(stack)
elseif ci == 4082 then -- hlt
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

View File

Before

Width:  |  Height:  |  Size: 778 B

After

Width:  |  Height:  |  Size: 778 B

View File

@ -1,2 +0,0 @@
default
digilines

View File

@ -1,30 +0,0 @@
if not digiline then
print("Digilines not found.")
return
end
local oldprint=print
local function print(...)
for k,v in ipairs({...}) do
oldprint("[Test3D:T410] "..tostring(v))
end
end
print("Loading.")
local function t410_set_meta(pos)
minetest.get_meta(pos):set_string("formspec","size[2,4]\nfield[0,1;2.9,1;addr;Address;]\nfield[0,2;2.9,1;data;Data;]\nbutton[0,3;2,1;write;Write]")
end
minetest.register_node("test3d_t410:t410", {
description = "T410 Memory Access Console",
tiles = {"t416-top.png","t416-top.png","t416-side.png","t416-side.png","t416-side.png","t416-side.png"},
on_construct = t410_set_meta,
groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3},
on_receive_fields = function(pos,_,fields,sender)
if fields.addr == nil then return end
digiline:receptor_send(pos, digiline.rules.default, fields.addr, tonumber(fields.data) or 0)
print("Set "..fields.addr.." to "..fields.data)
end,
digiline = {
receptor = {},
},
})
print("T410 node registered")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 301 B

View File

@ -1,2 +0,0 @@
default
digilines

View File

@ -1,68 +0,0 @@
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:T416] "..tostring(v))
end
end
print("Loading.")
local function t416_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)
local mem = string.split(meta:get_string("mem"),"\n")
local ms = ""
local chan = meta:get_string("channel")
local memoffset = meta:get_int("startaddr")
if channel:sub(1,#chan) == chan and tonumber(channel:sub(#chan+1),16)+1-memoffset <= MEMSIZE and tonumber(channel:sub(#chan+1),16)+1-memoffset > 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")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 301 B