--RVController Loader
--A product of Advanced Mesecons Devices, a Cheapie Systems company
--This is free and unencumbered software released into the public domain.
--See http://unlicense.org/ for more information

local function formspec_escape(text)
	local ret = ""
	local badchars = {
		["\\"] = true,
		["["] = true,
		["]"] = true,
		[";"] = true,
		[","] = true
	}
	for i=1,string.len(text),1 do
		local char = string.sub(text,i,i)
		if badchars[char] then ret = ret.."\\" end
		ret = ret..char
	end
	return ret
end

local function sendfs()
	digiline_send("touchscreen","formspec_version[10]size[15,15]textarea[0,0;15,14;program;;"..formspec_escape(mem.data).."]button_exit[6.5,14;2,1;go;Load]checkbox[0.5,14.5;autorun;Run after load;"..tostring(mem.autorun).."]")
end

if event.type == "program" then
	mem.autorun = true
	mem.data = "(paste Intel HEX data here)"
	sendfs()
elseif event.channel == "touchscreen" and event.msg.autorun then
	mem.autorun = event.msg.autorun == "true"
	mem.data = event.msg.program
	sendfs()
elseif event.channel == "touchscreen" and event.msg.go then
	mem.data = event.msg.program
	mem.addresshigh = 0
	mem.addressmid = 0
	digiline_send("reset","")
	interrupt(1,"tick")
elseif event.iid == "tick" then
	local nlpos = string.find(mem.data,"\n",1,true)
	local thisline
	if nlpos then
		thisline = string.sub(mem.data,1,nlpos-1)
		mem.data = string.sub(mem.data,nlpos+1,-1)
	else
		thisline = mem.data
		mem.data = ""
	end
	local startpos = string.find(thisline,":",1,true)
	local eof = false
	if startpos then
		thisline = string.sub(thisline,startpos+1,-1)
		local rectype = string.sub(thisline,7,8)
		if rectype == "00" then
			--data
			local bytecount = tonumber(string.sub(thisline,1,2),16)
			local addresslow = tonumber(string.sub(thisline,3,6),16)
			local linedata = string.sub(thisline,9,-3)
			local address = (mem.addresshigh*2^16)+(mem.addressmid*2^4)+addresslow
			digiline_send("load",{address=address,data=linedata,size=bytecount})
		elseif rectype == "01" then
			--end of file
			eof = true
			digiline_send("load",{done=true,autorun=mem.autorun})
		elseif rectype == "02" then
			--extended segment address
			mem.addressmid = tonumber(string.sub(thisline,9,12),16)
		elseif rectype == "04" then
			--extended linear address
			mem.addresshigh = tonumber(string.sub(thisline,9,12),16)
		end
	end
	if string.len(mem.data) > 0 and not eof then
		interrupt(0.05,"tick")
	else
		mem.data = "(paste Intel HEX data here)"
		sendfs()
	end
elseif event.iid == "run" then
	digiline_send("monitorkb","run")
end
