Generates a binary for the first time.

This commit is contained in:
g012 2017-09-19 15:53:10 +02:00
parent d3cee527f7
commit 8ba7ab6bf6
4 changed files with 60 additions and 56 deletions

2
.gitignore vendored
View File

@ -1,2 +1,4 @@
/build
/tmp
*.bin
*.sym

View File

@ -125,31 +125,30 @@ M.resolve = function()
stats.resolved_count = 0
local count = 0
for k,v in pairs(symbols) do
for k,v in pairs(symbols) do if k ~= '__index' then
local t = type(v)
if v == 'function' then symbols[k] = v() count=count+1
elseif v == 'table' and type(v.resolve) == 'function' then symbols[k] = v.resolve() count=count+1 end
end
if t == 'function' then v=v() t=type(v) symbols[k]=v count=count+1 end
if t == 'table' and type(v.resolve) == 'function' then symbols[k]=v.resolve() count=count+1
elseif t == 'string' then symbols[k]=symbols[v] count=count+1 end
end end
stats.resolved_count = count
end
M.genbin = function(filler)
if not filler then filler = 0xff end
if not filler then filler = 0 end -- brk opcode
M.resolve()
local bin = {}
local ins = table.insert
table.sort(locations, function(a,b) return a.start < b.start end)
for _,location in ipairs(locations) do
if location.start < #bin then
error(string.format("location [%04x,%04x] overlaps another",
location.start, math.type(location.size) == 'integer' and (location.size + location.start) or 0xffff))
error(string.format("location [%04x,%04x] overlaps another", location.start, location.finish))
end
for i=#bin,location.start-1 do ins(bin, filler) end
M.size=0 M.cycles=0
local sections = location.sections
table.sort(sections, function(a,b) return a.org < b.org end)
for _,section in ipairs(sections) do
print(section.org, #bin)
assert(section.org >= #bin)
for i=#bin,section.org-1 do ins(bin, filler) end
for _,instruction in ipairs(section.instructions) do
@ -158,9 +157,8 @@ print(section.org, #bin)
M.size=#bin M.cycles=M.cycles+(instruction.cycles or 0)
end
end
if math.type(location.size) == 'integer' then
local endpos = location.size+location.start-1
for i=#bin,endpos do ins(bin, filler) end
if location.finish then
for i=#bin,location.finish do ins(bin, filler) end
end
end
return bin
@ -170,7 +168,7 @@ M.writebin = function(filename, bin)
if not filename then filename = 'main.bin' end
if not bin then bin = M.genbin() end
local f = assert(io.open(filename, "wb"), "failed to open " .. filename .. " for writing")
f:write(string.char(bin:unpack()))
f:write(string.char(table.unpack(bin)))
f:close()
end
@ -180,7 +178,10 @@ M.writesym = function(filename)
table.sort(symbols)
local ins,fmt,rep = table.insert,string.format,string.rep
local s ={'--- Symbol List'}
for k,v in pairs(symbols) do ins(s, fmt("%s%s %04x", k, rep(' ',24-#k), type(v)=='table' and v.org or v)) end
local sym_rev = {}
for k,v in pairs(symbols) do if type(v) == 'number' then ins(sym_rev,k) end end
table.sort(sym_rev, function(a,b) local x,y=symbols[a],symbols[b] return x==y and a<b or x<y end)
for _,v in ipairs(sym_rev) do local k=symbols[v] ins(s, fmt("%s%s %04x", v, rep(' ',24-#v), k)) end
s[#s+1] = '--- End of Symbol List.'
f:write(table.concat(s, '\n'))
f:close()
@ -243,8 +244,9 @@ M.section = function(t)
end
M.label = function(name)
local eval,resolve,label,offset
label = { type='label', size=eval, resolve=resolve }
local label,offset
local section = M.section_current
label = { type='label' }
if name:sub(1,1) == '_' then -- local label
name = M.label_current .. name
else
@ -252,13 +254,13 @@ M.label = function(name)
end
if symbols[name] then error("duplicate symbol: " .. name) end
symbols[name] = label
eval = function()
offset = M.section_current.size
label.size = function()
offset = section.size
label.size = 0
return 0
end
resolve = function() return M.section_current.org + offset end
table.insert(M.section_current.instructions, label)
label.resolve = function() return section.org + offset end
table.insert(section.instructions, label)
return label
end
@ -638,7 +640,7 @@ for k,v in pairs(oprel) do
if x:sub(1,1) == '_' then x = parent .. x end
x = symbols[x]
end
if type(x) ~= 'number' then error("unresolved branch target: " .. x) end
if type(x) ~= 'number' then error("unresolved branch target: " .. tostring(x)) end
if x < -128 or x > 127 then error("branch target out of range: " .. x) end
b[#b+1]=v.opc b[#b+1]=x&0xff
end

36
asm.l65
View File

@ -64,13 +64,13 @@ ptr_table("ptrs", \(message), data, 0)
lda data+3,12
lda data+3,12,x
lda data+3,12,y
lda (INTIM,5,x)
lda (\a(a+2),INTIM,x)
lda (INTIM,5),y
lda (\a(a&3),INTIM),y
jmp (INTIM)
jmp (INTIM,12)
jmp (INTIM-4)
lda (VBLANK,5,x)
lda (\a(a+2),VBLANK,x)
lda (VBLANK,5),y
lda (\a(a&3),VBLANK),y
jmp (VBLANK)
jmp (VBLANK,12)
jmp (VBLANK-4)
-- cycles are counted without taking any branch
table.insert(section_current.instructions, { asbin=function() print('kernel cycles: ', cycles-kernel_cycles, 'kernel size: ', size-kernel_size) end })
@ -89,30 +89,30 @@ ptr_table("ptrs", \(message), data, 0)
samepage
lda #0xac
lda #INTIM
lda #VBLANK
lda 0xbeef
lda INTIM
lda.w INTIM
lda INTIM,x
lda INTIM,y
lda (INTIM,x)
lda (INTIM),y
lda VBLANK
lda.w VBLANK
lda VBLANK,x
lda VBLANK,y
lda (VBLANK,x)
lda (VBLANK),y
end
asl
asl INTIM
asl VBLANK
asl
@_toto
bne "test"
bne "_toto"
bne waitForIntim
f=\("test") bne f()
f=\("_toto") bne f()
bne _toto
jam asl lsr ldx #16 ldy 0xf0f0
rts
writebin()
writesym()
--[[
section "doOverscan"

36
asm.lua
View File

@ -64,13 +64,13 @@ section("waitForIntim") --alt short syntax when no other option
ldazab(function(o) return o+( data+3) end,12)
ldazax(function(o) return o+( data+3) end,12)
ldaaby(function(o) return o+( data+3) end,12)
ldainx (function(o) return o+(INTIM) end,5)
ldainx (function(a) return a+2 end,INTIM)
ldainy (function(o) return o+(INTIM) end,5)
ldainy (function(a) return a&3 end,INTIM)
jmpind (function(o) return o+(INTIM) end)
jmpind (function(o) return o+(INTIM) end,12)
jmpind (function(o) return o+(INTIM-4) end)
ldainx (function(o) return o+(VBLANK) end,5)
ldainx (function(a) return a+2 end,VBLANK)
ldainy (function(o) return o+(VBLANK) end,5)
ldainy (function(a) return a&3 end,VBLANK)
jmpind (function(o) return o+(VBLANK) end)
jmpind (function(o) return o+(VBLANK) end,12)
jmpind (function(o) return o+(VBLANK-4) end)
-- cycles are counted without taking any branch
table.insert(section_current.instructions, { asbin=function() print('kernel cycles: ', cycles-kernel_cycles, 'kernel size: ', size-kernel_size) end })
@ -87,30 +87,30 @@ section("waitForIntim") --alt short syntax when no other option
do samepage()
ldaimm (function(o) return o+(0xac) end)
ldaimm (function(o) return o+(INTIM) end)
ldaimm (function(o) return o+(VBLANK) end)
ldazab(function(o) return o+( 0xbeef) end)
ldazab(function(o) return o+( INTIM) end)
ldaabs(function(o) return o+( INTIM) end)
ldazax(function(o) return o+( INTIM) end)
ldaaby(function(o) return o+( INTIM) end)
ldainx (function(o) return o+(INTIM) end)
ldainy (function(o) return o+(INTIM) end) endpage()
ldazab(function(o) return o+( VBLANK) end)
ldaabs(function(o) return o+( VBLANK) end)
ldazax(function(o) return o+( VBLANK) end)
ldaaby(function(o) return o+( VBLANK) end)
ldainx (function(o) return o+(VBLANK) end)
ldainy (function(o) return o+(VBLANK) end) endpage()
end
aslimp()
aslzab(function(o) return o+( INTIM) end)
aslzab(function(o) return o+( VBLANK) end)
aslimp()
label("_toto")
bnerel( "test")
bnerel( "_toto")
bnerel( "waitForIntim")
f=function() return "test" end bnerel( f())
f=function() return "_toto" end bnerel( f())
bnerel( "_toto")
jamimp() aslimp() lsrimp() ldximm (function(o) return o+(16) end) ldyzab(function(o) return o+( 0xf0f0) end)
rtsimp()
writebin()
writesym()
--[[
section "doOverscan"