function string:split(sep) local sep, fields = sep or ":", {} local pattern = string.format("([^%s]+)", sep) self:gsub(pattern, function(c) fields[#fields+1] = c end) return fields end function conv_neg(x) if (x < 0) then return (2147483647 + (2147483649 - ((x * (-1)) ))) else return x end end function conv_to_neg(x) if (x > 2147483647) then return x - (2* 2147483648) else return x end end function binary_and(a,b) local r = 0 local neg = 1 if (a < 0) then a = a * (-1) neg = neg * (-1) end if (b < 0) then b = b * (-1) neg = neg * (-1) end for i = 31, 0, -1 do local x = 2^i if (a >= x and b>=x) then r = r + 2^i end if (a >= x) then a = a - x end if (b >= x) then b = b - x end end return r * neg end function binary_or(a,b) local r = 0 local neg = 1 if (a < 0) then a = a * (-1) neg = neg * (-1) end if (b < 0) then b = b * (-1) neg = neg * (-1) end for i = 31, 0, -1 do local x = 2^i if (a >= x or b>=x) then r = r + 2^i end if (a >= x) then a = a - x end if (b >= x) then b = b - x end end return r * neg end -------------- -- file access -------------- inputfile = "../input.txt" outputfile = "../output.txt" blockwritesize = 128 wait_on_writeblock = true function write_one(command) local file = nil while (file == nil) do file=io.open(inputfile,"a+") end io.output(file) io.write(command) io.write("\n") io.close(file) end function read_one(command) local read_line = "" command = string.sub(command, 1, #command - 1) --print("#command: "..#command) if (endpointer > 1000) then endpointer = endpointer - 1000 else endpointer = 0 end while read_line ~= command do local file = nil while (file == nil) do file=io.open(outputfile,"r") end file:seek("set", endpointer) local line = file:read() while (line ~= nil) do local buf_line = line local ix = #command + 1 while ix < #buf_line do if (string.sub(buf_line,ix,ix) == "#") then break end ix = ix + 1 end result = string.sub(buf_line,ix + 2,#buf_line - 1) buf_line = string.sub(buf_line,0,ix - 2) --print("########") --print(line) --print(command) --print(buf_line) --print("Result:"..result) if (buf_line == command) then read_line = buf_line break; end line = file:read() end new_endpointer = file:seek("end") io.close(file) end endpointer = new_endpointer return result end ------------------- -- connect commands ------------------- function reg_get_block_connection(reg, index, size) command_nr = command_nr + 1 if (index == null) then index = 0 end block = {} local readindex = 0 local dataleft = size while (dataleft > 0) do local blocksize = math.min(dataleft, 128) command = "get # "..command_nr.." # "..process_id.." # ".."1".." # "..blocksize.." # "..(reg[1] + index).."&" write_one(command) values = read_one(command) blockraw = values:split("#") for i = 1, blocksize do block[readindex] = tonumber(blockraw[i]) readindex = readindex + 1 end dataleft = dataleft - blocksize index = index + blocksize end return block end function reg_get_connection(reg, index) block = reg_get_block_connection(reg, index, 1) return block[0] end function reg_set_block_connection(values, reg, index) if (index == null) then index = 0 end command_nr = command_nr + 1 local length = (#values + 1) command = "set # "..command_nr.." # "..process_id.." # ".."1".." # "..math.min(blockwritesize, length).." # "..(reg[1] + index) local writecount = 0 for i = 0, #values do value = conv_to_neg(values[i]) command = command.." # "..value writecount = writecount + 1 if (writecount == blockwritesize) then command = command.."&" write_one(command) if (wait_on_writeblock) then read_one(command) end writecount = 0 index = index + blockwritesize command_nr = command_nr + 1 length = length - blockwritesize command = "set # "..command_nr.." # "..process_id.." # ".."1".." # "..math.min(blockwritesize, length).." # "..(reg[1] + index) end end if (length > 0) then command = command.."&" write_one(command) if (wait_on_writeblock) then read_one(command) end end end function reg_set_connection(value, reg, index) values = {} values[0] = value reg_set_block_connection(values, reg, index) end ----------- -- commands ----------- function reg_filter(reg, value) filter = 0 for i = reg[3], reg[2] do filter = filter + 2^i; end value = conv_neg(value) value = binary_and(value,filter); value = value / (2 ^ reg[3]); return value end function reg_get(reg, index) value = reg_get_connection(reg, index) value = reg_filter(reg, value) return value end function reg_get_block(reg, index, size) block = reg_get_block_connection(reg, index, size) for i = 0, size - 1 do value = block[i] filter = 0 for i = reg[3], reg[2] do filter = filter + 2^i; end value = conv_neg(value) value = binary_and(value,filter); value = value / (2 ^ reg[3]); block[i] = value end return block end function reg_set_block(block, reg, index) reg_set_block_connection(block, reg, index) end function reg_set(value, reg, index) if (index == null) then index = 0 end if (value < 100) then --print ("Address "..(reg[1] + index).."["..reg[2]..".."..reg[3].."] => "..value) else --print ("Address "..(reg[1] + index).."["..reg[2]..".."..reg[3].."] => 0x"..string.format("%X", value)) end -- find out if parameter is the only one in this register local singlereg = true local fullname = reg[6] local sectionname = fullname:split(".")[1] local secttable = _G[sectionname] for name, register in pairs(secttable) do if (register[1] == reg[1]) then if (register[6] ~= reg[6]) then singlereg = false break end end end oldval = 0 if (singlereg == false) then oldval = reg_get_connection(reg, index) --print ("oldval= "..oldval.." at "..(reg[1]+index)) filter = 0 for i = 0, reg[3] - 1 do filter = filter + 2^i; end for i = reg[2] + 1, 31 do filter = filter + 2^i; end oldval = binary_and(oldval,filter); --print ("oldval filtered= "..oldval.." at "..(reg[1]+index).." with filter "..filter) end value = value * (2 ^ reg[3]) value = binary_or(value, oldval); reg_set_connection(value, reg, index) end function compare_reg(target, reg, index) if (index == null) then index = 0 end value = reg_get(reg, index) if (value == target) then if (value < 100 and target < 100) then print (reg[6].." -> Address "..(reg[1] + index).."["..reg[2]..".."..reg[3].."] = "..value.." - OK") else print (reg[6].." -> Address "..(reg[1] + index).."["..reg[2]..".."..reg[3].."] = 0x"..string.format("%X", value).." - OK") end return true else testerrorcount = testerrorcount + 1 if (value < 100 and target < 100) then print (reg[6].." -> Address "..(reg[1] + index).."["..reg[2]..".."..reg[3].."] = "..value.." | should be = "..target.." - ERROR") else print (reg[6].." -> Address "..(reg[1] + index).."["..reg[2]..".."..reg[3].."] = 0x"..string.format("%X", tonumber(value)).." | should be = 0x"..string.format("%X", tonumber(target)).." - ERROR") end return false; end end function reg_set_file(filename, baseaddress, index, endian) if (index == null) then index = 0 end if (endian == null) then endian = 0 end command_nr = command_nr + 1 command = "fil # "..command_nr.." # "..process_id.." # "..endian.." # "..(baseaddress + index).." # "..filename command = command.."&" write_one(command) if (wait_on_writeblock) then read_one(command) end end function wait_ns(waittime) command_nr = command_nr + 1 command = "wtn # "..command_nr.." # "..process_id.." # "..waittime.."&" write_one(command) read_one(command) end function brk() command_nr = command_nr + 1 command = "brk&" write_one(command) end function sleep(n) -- seconds local t0 = os.clock() while os.clock() - t0 <= n do end end ---------- -- init ---------- seed = os.time() + os.clock() * 1000 math.randomseed(seed) process_id = math.random(2147483647) process_id = math.random(2147483647) process_id = math.random(2147483647) process_id = math.random(2147483647) process_id = math.random(2147483647) endpointer = 0 command_nr = 0