add dasm and braces
This commit is contained in:
parent
5fe3adca2a
commit
ded021ee99
@ -1,4 +1,6 @@
|
|||||||
|
|
||||||
|
local arch8608 = require("rom-8608-defs")
|
||||||
|
|
||||||
local function trim(s) return s:gsub("^ +", ""):gsub(" +$", "").."" end
|
local function trim(s) return s:gsub("^ +", ""):gsub(" +$", "").."" end
|
||||||
local function validWordsFromInstrs(instrs)
|
local function validWordsFromInstrs(instrs)
|
||||||
local words = {}
|
local words = {}
|
||||||
@ -12,9 +14,9 @@ end
|
|||||||
local function decodeNumber(n)
|
local function decodeNumber(n)
|
||||||
n = trim(n)
|
n = trim(n)
|
||||||
local sign = 1; if n:sub(1, 1)=="-" then sign = -1; n = n:sub(2, #n); end;
|
local sign = 1; if n:sub(1, 1)=="-" then sign = -1; n = n:sub(2, #n); end;
|
||||||
if n:sub(1, 1)=="$" then return sign*tonumber(n:sub(2, #n ), 16), (#n-1)/2
|
if n:sub(1, 1)=="$" then return sign*tonumber(n:sub(2, #n ), 16), math.ceil((#n-1)/2)
|
||||||
elseif n:sub(1, 2)=="0x" then return sign*tonumber(n:sub(3, #n ), 16), (#n-2)/2
|
elseif n:sub(1, 2)=="0x" then return sign*tonumber(n:sub(3, #n ), 16), math.ceil((#n-2)/2)
|
||||||
elseif n:sub(#n, #n)=="h" then return sign*tonumber(n:sub(1, #n-1), 16), (#n-1)/2
|
elseif n:sub(#n, #n)=="h" then return sign*tonumber(n:sub(1, #n-1), 16), math.ceil((#n-1)/2)
|
||||||
else
|
else
|
||||||
local v = tonumber(n) or error("invalid number "..n)
|
local v = tonumber(n) or error("invalid number "..n)
|
||||||
if v>=-128 and v<=255 then return v, 1
|
if v>=-128 and v<=255 then return v, 1
|
||||||
@ -50,7 +52,7 @@ local function mnemFromLine(line, instrs, validWords)
|
|||||||
end
|
end
|
||||||
local function addByte(state, val)
|
local function addByte(state, val)
|
||||||
assert(val>=-128 and val<=255, "invalid byte "..val)
|
assert(val>=-128 and val<=255, "invalid byte "..val)
|
||||||
assert(not state.memory[state.curAddr], "overwriting memory at "..state.curAddr)
|
assert(state.memory[state.curAddr]==nil, "overwriting memory at "..state.curAddr)
|
||||||
state.memory[state.curAddr] = val%256
|
state.memory[state.curAddr] = val%256
|
||||||
state.curAddr = state.curAddr + 1
|
state.curAddr = state.curAddr + 1
|
||||||
end
|
end
|
||||||
@ -59,6 +61,13 @@ local function addWord(state, val)
|
|||||||
addByte(state, math.floor(val/256))
|
addByte(state, math.floor(val/256))
|
||||||
addByte(state, val%256)
|
addByte(state, val%256)
|
||||||
end
|
end
|
||||||
|
local function addSpace(state, len)
|
||||||
|
for i = 1, len do
|
||||||
|
assert(state.memory[state.curAddr]==nil, "overwriting memory at "..state.curAddr)
|
||||||
|
state.memory[state.curAddr] = false
|
||||||
|
state.curAddr = state.curAddr + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
local function assembleInstruction(line, state, instrs, validWords)
|
local function assembleInstruction(line, state, instrs, validWords)
|
||||||
local mnem, imms = mnemFromLine(line, instrs, validWords)
|
local mnem, imms = mnemFromLine(line, instrs, validWords)
|
||||||
local opcode = instrs[mnem] or error("invalid instruction "..line.." (mnem "..mnem..")")
|
local opcode = instrs[mnem] or error("invalid instruction "..line.." (mnem "..mnem..")")
|
||||||
@ -66,7 +75,7 @@ local function assembleInstruction(line, state, instrs, validWords)
|
|||||||
local padlen = 0
|
local padlen = 0
|
||||||
if type(opcode)=="function" then
|
if type(opcode)=="function" then
|
||||||
padlen, writeimms = opcode(imms)
|
padlen, writeimms = opcode(imms)
|
||||||
state.curAddr = state.curAddr + padlen
|
addSpace(state, padlen)
|
||||||
elseif opcode>=0 then
|
elseif opcode>=0 then
|
||||||
addByte(state, opcode)
|
addByte(state, opcode)
|
||||||
end
|
end
|
||||||
@ -175,8 +184,10 @@ local function preprocessCode(code)
|
|||||||
end
|
end
|
||||||
local function fixCode(code)
|
local function fixCode(code)
|
||||||
code = code:gsub(",", " ")
|
code = code:gsub(",", " ")
|
||||||
|
code = code:gsub(":([^\\/])", ":\n%1")
|
||||||
code = code:gsub("%]", " %] ")
|
code = code:gsub("%]", " %] ")
|
||||||
code = code:gsub("%[", " %[ ")
|
code = code:gsub("%[", " %[ ")
|
||||||
|
code = code:gsub("%*", " %* ")
|
||||||
code = code:gsub("\n[ \t\r\n]*", "\n")
|
code = code:gsub("\n[ \t\r\n]*", "\n")
|
||||||
code = code:gsub(" +", " ")
|
code = code:gsub(" +", " ")
|
||||||
return code
|
return code
|
||||||
@ -194,6 +205,8 @@ local function prefixCode(code, fn) -- fix strings, add line numbers
|
|||||||
local lastbracelabel = 0
|
local lastbracelabel = 0
|
||||||
local function bracelabel() lastbracelabel = lastbracelabel+1; return "_BRACE_"..lastbracelabel.."_"; end
|
local function bracelabel() lastbracelabel = lastbracelabel+1; return "_BRACE_"..lastbracelabel.."_"; end
|
||||||
local bracestack = {}
|
local bracestack = {}
|
||||||
|
local bracehasmid = {}
|
||||||
|
local lastnl = false
|
||||||
|
|
||||||
out(".ln 1"); out("\n");
|
out(".ln 1"); out("\n");
|
||||||
for i = 1, #code do
|
for i = 1, #code do
|
||||||
@ -202,18 +215,29 @@ local function prefixCode(code, fn) -- fix strings, add line numbers
|
|||||||
if c=="\r" then
|
if c=="\r" then
|
||||||
elseif c=="\n" then
|
elseif c=="\n" then
|
||||||
linenum = linenum+1
|
linenum = linenum+1
|
||||||
if skipnl then out("\\")
|
if skipnl then out("\\"); skipnl = false;
|
||||||
else out("\n") out(".ln "..linenum) out("\n") end
|
else out("\n") out(".ln "..linenum); out("\n"); end
|
||||||
skipnl = false
|
lastnl = true
|
||||||
elseif c=="\t" or c==" " then out(" ")
|
elseif c=="\t" or c==" " then out(" ")
|
||||||
elseif c=="#" or c==";" or c=="/" then state = "comment"
|
elseif c=="#" or c==";" or c=="/" then state = "comment"
|
||||||
elseif c=="\"" then state = "string"
|
elseif c=="\"" then state = "string" lastnl = false
|
||||||
elseif c:find("^[a-zA-Z0-9_%.:%$%(%)%*,%[%]]$") then out(c)
|
|
||||||
elseif c=="\\" then skipnl = true
|
elseif c=="\\" then skipnl = true
|
||||||
|
elseif c:find("^[a-zA-Z0-9_%.:%$%(%)%*,%[%]]$") then out(c) lastnl = false
|
||||||
elseif c=="{" then
|
elseif c=="{" then
|
||||||
|
table.insert(bracestack, bracelabel())
|
||||||
|
|
||||||
|
if not lastnl then out(bracestack[#bracestack].."MID") out("\n") end
|
||||||
|
out(bracestack[#bracestack].."START:") out("\n")
|
||||||
elseif c=="}" then
|
elseif c=="}" then
|
||||||
|
if not lastnl then out(bracestack[#bracestack].."START") out("\n") end
|
||||||
|
out(bracestack[#bracestack].."END:") out("\n")
|
||||||
|
if not bracehasmid[#bracestack] then out(bracestack[#bracestack].."MID:") out("\n") end
|
||||||
|
bracehasmid[#bracestack] = nil
|
||||||
|
bracestack[#bracestack] = nil
|
||||||
|
elseif c=="|" then
|
||||||
|
if not lastnl then out(bracestack[#bracestack].."END") out("\n") end
|
||||||
|
out(bracestack[#bracestack].."MID:") out("\n")
|
||||||
|
bracehasmid[#bracestack] = true
|
||||||
else error("invalid char "..c) end
|
else error("invalid char "..c) end
|
||||||
elseif state=="comment" then
|
elseif state=="comment" then
|
||||||
if c=="\n" then state = "code" out("\n") end
|
if c=="\n" then state = "code" out("\n") end
|
||||||
@ -225,7 +249,8 @@ local function prefixCode(code, fn) -- fix strings, add line numbers
|
|||||||
out(stringEscapes[c] or error("invalid escape "..c)); state = "string";
|
out(stringEscapes[c] or error("invalid escape "..c)); state = "string";
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return table.concat(outt)
|
local code2 = table.concat(outt)
|
||||||
|
return code2
|
||||||
end
|
end
|
||||||
local function includeFile(fn)
|
local function includeFile(fn)
|
||||||
fn = fn:gsub("\\", "/")
|
fn = fn:gsub("\\", "/")
|
||||||
@ -238,7 +263,7 @@ local function includeFile(fn)
|
|||||||
return code
|
return code
|
||||||
end
|
end
|
||||||
local function instrsFromArch(arch)
|
local function instrsFromArch(arch)
|
||||||
local function arraySize(imms) local s = 1; for i = 1, #imms do s = s*imms[i].val end; return s; end
|
local function arraySize(imms) local s = 1; for i = 1, #imms do s = s*(imms[i].val or error("invalid array size")) end; return s; end
|
||||||
local instrs = {
|
local instrs = {
|
||||||
imm8 = function() return 0, true end,
|
imm8 = function() return 0, true end,
|
||||||
imm16 = function() return 0, true end,
|
imm16 = function() return 0, true end,
|
||||||
@ -253,22 +278,78 @@ local function instrsFromArch(arch)
|
|||||||
}
|
}
|
||||||
for _, instr in ipairs(arch.instructions) do
|
for _, instr in ipairs(arch.instructions) do
|
||||||
if instr.mnem then
|
if instr.mnem then
|
||||||
instrs[instr.mnem] = instr.opcode
|
local mnem = instr.mnem
|
||||||
|
mnem = mnem:gsub("%*([^ ])", "%* %1")
|
||||||
|
instrs[mnem] = instr.opcode
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return instrs
|
return instrs
|
||||||
end
|
end
|
||||||
local function assembleFile(fn)
|
local function assembleFile(fn, arch)
|
||||||
local code = includeFile(fn)
|
local code = includeFile(fn)
|
||||||
code = preprocessCode(code)
|
code = preprocessCode(code)
|
||||||
code = fixCode(code)
|
code = fixCode(code)
|
||||||
local arch = require("rom-8608-defs")
|
|
||||||
local instrs = instrsFromArch(arch)
|
local instrs = instrsFromArch(arch)
|
||||||
local mem = assembleCode(code, instrs)
|
local mem = assembleCode(code, instrs)
|
||||||
return mem
|
return mem
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function mnemsFromArch(arch)
|
||||||
|
local mnems = {}
|
||||||
|
for _, instr in ipairs(arch.instructions) do
|
||||||
|
if instr.mnem then
|
||||||
|
mnems[instr.opcode] = instr.mnem
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return mnems
|
||||||
|
end
|
||||||
|
local function disassembleMemory(mem, arch)
|
||||||
|
local mnems = mnemsFromArch(arch)
|
||||||
|
local addr = 0
|
||||||
|
local function nextByte() local b = mem[addr]; addr = addr+1; return b; end
|
||||||
|
local lastaddr = 0
|
||||||
|
while addr<=0xFFFF do
|
||||||
|
local opcode = nextByte()
|
||||||
|
if opcode then
|
||||||
|
local line = {}
|
||||||
|
local mnem = mnems[opcode] or "???"
|
||||||
|
table.insert(line, trim(mnem:gsub("imm[0-9]+", "")))
|
||||||
|
local tlen = 1
|
||||||
|
for lens in mnem:gmatch("imm([0-9]+)") do local len = tonumber(lens)/8
|
||||||
|
if len==1 then
|
||||||
|
table.insert(line, "$"..string.format("%02X", nextByte() or 0))
|
||||||
|
elseif len==2 then
|
||||||
|
table.insert(line, "$"..string.format("%04X", (nextByte() or 0)*256 + (nextByte() or 0)))
|
||||||
|
else error("invalid imm len") end
|
||||||
|
tlen = tlen + len
|
||||||
|
end
|
||||||
|
local lineb = {}
|
||||||
|
for i = addr-tlen, addr-1 do
|
||||||
|
table.insert(lineb, string.format("%02X", mem[i] or 0))
|
||||||
|
end
|
||||||
|
local lb = table.concat(lineb, " ")
|
||||||
|
if lastaddr~=addr-tlen then print("...") end
|
||||||
|
print(string.format("%04X", addr-tlen).." | "..(" "):rep(9-#lb)..lb.." | "..table.concat(line, " "))
|
||||||
|
lastaddr = addr
|
||||||
|
end
|
||||||
|
end
|
||||||
|
print()
|
||||||
|
end
|
||||||
|
local function memToHex(hex)
|
||||||
|
local mem = {}
|
||||||
|
local addr = 0
|
||||||
|
for d in hex:gmatch("[0-9a-fA-F][0-9a-fA-F]") do
|
||||||
|
mem[addr] = tonumber(d, 16)
|
||||||
|
addr = addr+1
|
||||||
|
end
|
||||||
|
return mem
|
||||||
|
end
|
||||||
|
local function disassembleHex(hex, arch)
|
||||||
|
disassembleMemory(memToHex(hex), arch)
|
||||||
|
end
|
||||||
|
|
||||||
local function printMemory(mem)
|
local function printMemory(mem)
|
||||||
|
local anynonempty = false
|
||||||
local lastbase = -16
|
local lastbase = -16
|
||||||
for base = 0, 0xFFF0, 16 do
|
for base = 0, 0xFFF0, 16 do
|
||||||
local line = { string.format("%04X", base), " | " }
|
local line = { string.format("%04X", base), " | " }
|
||||||
@ -285,8 +366,11 @@ local function printMemory(mem)
|
|||||||
if base ~= lastbase+16 then print("...") end
|
if base ~= lastbase+16 then print("...") end
|
||||||
print(table.concat(line))
|
print(table.concat(line))
|
||||||
lastbase = base
|
lastbase = base
|
||||||
|
anynonempty = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if not anynonempty then print("Memory empty") end
|
||||||
|
print()
|
||||||
end
|
end
|
||||||
|
|
||||||
local ts = ts or {
|
local ts = ts or {
|
||||||
@ -322,21 +406,23 @@ local function buildMemory(mem, romsize, offset, len)
|
|||||||
local pow = math.pow(2, z%8)
|
local pow = math.pow(2, z%8)
|
||||||
local data = (addr>=offset and ((not len) or addr<offset+len) and mem[addr]) or 0
|
local data = (addr>=offset and ((not len) or addr<offset+len) and mem[addr]) or 0
|
||||||
local bit = math.floor(data/pow)%2
|
local bit = math.floor(data/pow)%2
|
||||||
if bit==1 then plantBrickAt(brickpos, {x, y, z}) end
|
if bit==1 then plantBrickAt(brickpos, {x, -y, z}) end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function strtovec(str) local v = {}; for word in str:gmatch("[^ \t\r\n]+") do table.insert(v, tonumber(word)) end; return v; end
|
local function strtovec(str) local v = {}; for word in str:gmatch("[^ \t\r\n]+") do table.insert(v, tonumber(word)) end; return v; end
|
||||||
function AssembleFile(fn, romsizes, offsets, lens) offset = tonumber(offsets); len = tonumber(lens); romsize = strtovec(romsizes);
|
function AssembleFile(fn, romsizes, offsets, lens) local offset = tonumber(offsets); local len = tonumber(lens); local romsize = strtovec(romsizes);
|
||||||
local mem = assembleFile(fn)
|
local arch = arch8608
|
||||||
|
local mem = assembleFile(fn, arch)
|
||||||
printMemory(mem)
|
printMemory(mem)
|
||||||
if #romsize>0 then assert(#romsize==3, "incorrect rom size") end
|
if #romsize>0 then assert(#romsize==3, "incorrect rom size") end
|
||||||
buildMemory(mem, romsize, offset, len)
|
buildMemory(mem, romsize, offset, len)
|
||||||
|
disassembleMemory(mem, arch)
|
||||||
end
|
end
|
||||||
ts.eval [[
|
ts.eval [[
|
||||||
function AssembleFile(%fn, %romsize, %offset, %len) { luacall("AssembleFile", %fn, %romsize, %offset, %len); }
|
function AssembleFile(%fn, %romsize, %offset, %len) { luacall("AssembleFile", %fn, %romsize, %offset, %len); }
|
||||||
]]
|
]]
|
||||||
|
|
||||||
if arg then AssembleFile(arg[1] or "programs/keyboard.asm", "16 16 8", "0", "256") end
|
if arg then AssembleFile(arg[1] or "../8608programs/keyboard.asm", "16 16 8", "0", "256") end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user