Add an EEPROM to the Microcontroller

This commit is contained in:
Jeija 2012-08-08 23:35:36 +02:00
parent 7ed60c75b9
commit 2d94a08d2e

View File

@ -1,3 +1,5 @@
EEPROM_SIZE = 255
minetest.register_node("mesecons_microcontroller:microcontroller", { minetest.register_node("mesecons_microcontroller:microcontroller", {
description = "Microcontroller", description = "Microcontroller",
drawtype = "nodebox", drawtype = "nodebox",
@ -23,6 +25,9 @@ minetest.register_node("mesecons_microcontroller:microcontroller", {
"field[0.256,0.5;8,1;code;Code:;]".. "field[0.256,0.5;8,1;code;Code:;]"..
"button_exit[3,0.5;2,2;program;Program]") "button_exit[3,0.5;2,2;program;Program]")
meta:set_string("infotext", "Unprogrammed Microcontroller") meta:set_string("infotext", "Unprogrammed Microcontroller")
local r = ""
for i=1, EEPROM_SIZE+1 do r=r.."0" end --Generate a string with EEPROM_SIZE*"0"
meta:set_string("eeprom", r)
end, end,
on_receive_fields = function(pos, formanme, fields, sender) on_receive_fields = function(pos, formanme, fields, sender)
if fields.program then if fields.program then
@ -52,6 +57,10 @@ function reset_yc(pos)
mesecon:receptor_off(pos, mesecon:get_rules("microcontrollerB")) mesecon:receptor_off(pos, mesecon:get_rules("microcontrollerB"))
mesecon:receptor_off(pos, mesecon:get_rules("microcontrollerC")) mesecon:receptor_off(pos, mesecon:get_rules("microcontrollerC"))
mesecon:receptor_off(pos, mesecon:get_rules("microcontrollerD")) mesecon:receptor_off(pos, mesecon:get_rules("microcontrollerD"))
local meta = minetest.env:get_meta(pos)
local r = ""
for i=1, EEPROM_SIZE+1 do r=r.."0" end --Generate a string with EEPROM_SIZE*"0"
meta:set_string("eeprom", r)
end end
function update_yc(pos) function update_yc(pos)
@ -70,12 +79,13 @@ function parse_yccode(code, pos)
local endi = 1 local endi = 1
local L = yc_get_portstates(pos) local L = yc_get_portstates(pos)
local c local c
local eeprom = minetest.env:get_meta(pos):get_string("eeprom")
while true do while true do
command, endi = parse_get_command(code, endi) command, endi = parse_get_command(code, endi)
if command == nil then return nil end if command == nil then return nil end
if command == true then break end if command == true then break end
if command == "if" then if command == "if" then
r, endi = yc_command_if(code, endi, L) r, endi = yc_command_if(code, endi, L, eeprom)
if r == nil then return nil end if r == nil then return nil end
if r == true then -- nothing if r == true then -- nothing
elseif r == false then elseif r == false then
@ -90,11 +100,15 @@ function parse_yccode(code, pos)
L = yc_command_on (params, L) L = yc_command_on (params, L)
elseif command == "off" then elseif command == "off" then
L = yc_command_off(params, L) L = yc_command_off(params, L)
elseif command == "sbi" then
eeprom = yc_command_sbi (params, eeprom)
elseif command == "if" then --nothing elseif command == "if" then --nothing
else else
return nil return nil
end end
if L == nil then return nil end if L == nil then return nil end
if eeprom == nil then return nil else
minetest.env:get_meta(pos):set_string("eeprom", eeprom) end
end end
yc_action(pos, L) yc_action(pos, L)
return true return true
@ -140,6 +154,22 @@ function parse_get_params(code, starti)
return nil, nil return nil, nil
end end
function yc_parse_get_eeprom_params(code, starti)
i = starti
s = nil
local params = {}
while s ~= "" do
s = string.sub(code, i, i)
if s == ">" then
table.insert(params, string.sub(code, starti, i-1)) -- i: ) i+1 after )
return params, i + 1
end
if s == "," then return nil, nil end
i = i + 1
end
return nil, nil
end
function yc_command_on(params, L) function yc_command_on(params, L)
local rules = {} local rules = {}
for i, port in ipairs(params) do for i, port in ipairs(params) do
@ -156,11 +186,25 @@ function yc_command_off(params, L)
return L return L
end end
function yc_command_if(code, starti, L) function yc_command_sbi(params, eeprom)
if params[1]==nil or params[2]==nil or params[3] ~=nil or tonumber(params[1])==nil or tonumber(params[2])==nil then return nil end
if tonumber(params[1])>EEPROM_SIZE or tonumber(params[1])<1 or (tonumber(params[2])~=1 and tonumber(params[2]~=0)) then return nil end
new_eeprom = "";
for i=1, #eeprom do
if tonumber(params[1])==i then
new_eeprom = new_eeprom..params[2]
else
new_eeprom = new_eeprom..eeprom:sub(i, i)
end
end
return new_eeprom
end
function yc_command_if(code, starti, L, eeprom)
local cond, endi = yc_command_if_getcondition(code, starti) local cond, endi = yc_command_if_getcondition(code, starti)
if cond == nil then return nil end if cond == nil then return nil end
cond = yc_command_if_parsecondition(cond, L) cond = yc_command_if_parsecondition(cond, L, eeprom)
if cond == "0" then result = false if cond == "0" then result = false
elseif cond == "1" then result = true elseif cond == "1" then result = true
@ -171,17 +215,28 @@ end
function yc_command_if_getcondition(code, starti) function yc_command_if_getcondition(code, starti)
i = starti i = starti
s = nil s = nil
local brackets = 1 --1 Bracket to close
while s ~= "" do while s ~= "" do
s = string.sub(code, i, i) s = string.sub(code, i, i)
if s == ")" then if s == ")" then
return string.sub(code, starti, i-1), i + 1 -- i: (; i+1 after (; brackets = brackets - 1
end end
if s == "(" then
brackets = brackets + 1
end
if brackets == 0 then
return string.sub(code, starti, i-1), i + 1 -- i: ( i+1 after (
end
i = i + 1 i = i + 1
end end
return nil, nil return nil, nil
end end
function yc_command_if_parsecondition(cond, L) function yc_command_if_parsecondition(cond, L, eeprom)
cond = string.gsub(cond, "A", tostring(L.a and 1 or 0)) cond = string.gsub(cond, "A", tostring(L.a and 1 or 0))
cond = string.gsub(cond, "B", tonumber(L.b and 1 or 0)) cond = string.gsub(cond, "B", tonumber(L.b and 1 or 0))
cond = string.gsub(cond, "C", tonumber(L.c and 1 or 0)) cond = string.gsub(cond, "C", tonumber(L.c and 1 or 0))
@ -190,6 +245,22 @@ function yc_command_if_parsecondition(cond, L)
cond = string.gsub(cond, "!0", "1") cond = string.gsub(cond, "!0", "1")
cond = string.gsub(cond, "!1", "0") cond = string.gsub(cond, "!1", "0")
local i = 1
local l = string.len(cond)
while i<=l do
local s = cond:sub(i,i)
if s == "<" then
params, endi = yc_parse_get_eeprom_params(cond, i+1)
buf = yc_eeprom_read(tonumber(params[1]), eeprom)
if buf == nil then return nil end
local call = cond:sub(i, endi-1)
cond = string.gsub(cond, call, buf)
i = 0
l = string.len(cond)
end
i = i + 1
end
local i = 2 local i = 2
local l = string.len(cond) local l = string.len(cond)
while i<=l do while i<=l do
@ -207,7 +278,7 @@ function yc_command_if_parsecondition(cond, L)
i = i + 1 i = i + 1
end end
local i = 2 local i = 2
local l = string.len(cond) local l = string.len(cond)
while i<=l do while i<=l do
local s = cond:sub(i,i) local s = cond:sub(i,i)
@ -243,6 +314,13 @@ function yc_command_if_parsecondition(cond, L)
return cond return cond
end end
function yc_eeprom_read(number, eeprom)
if params == nil then return nil, nil end
value = eeprom:sub(params[1], number)
if value == nil then return nil, nil end
return value, endi
end
function yc_get_port_rules(port) function yc_get_port_rules(port)
local rules = nil local rules = nil
if port == "A" then if port == "A" then