mirror of
https://github.com/g012/l65.git
synced 2025-01-31 05:29:44 +00:00
Generates a binary for the first time.
This commit is contained in:
parent
d3cee527f7
commit
8ba7ab6bf6
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,4 @@
|
|||||||
/build
|
/build
|
||||||
/tmp
|
/tmp
|
||||||
|
*.bin
|
||||||
|
*.sym
|
||||||
|
42
6502.lua
42
6502.lua
@ -125,31 +125,30 @@ M.resolve = function()
|
|||||||
|
|
||||||
stats.resolved_count = 0
|
stats.resolved_count = 0
|
||||||
local 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)
|
local t = type(v)
|
||||||
if v == 'function' then symbols[k] = v() count=count+1
|
if t == 'function' then v=v() t=type(v) symbols[k]=v count=count+1 end
|
||||||
elseif v == 'table' and type(v.resolve) == 'function' then symbols[k] = v.resolve() count=count+1 end
|
if t == 'table' and type(v.resolve) == 'function' then symbols[k]=v.resolve() count=count+1
|
||||||
end
|
elseif t == 'string' then symbols[k]=symbols[v] count=count+1 end
|
||||||
|
end end
|
||||||
stats.resolved_count = count
|
stats.resolved_count = count
|
||||||
end
|
end
|
||||||
|
|
||||||
M.genbin = function(filler)
|
M.genbin = function(filler)
|
||||||
if not filler then filler = 0xff end
|
if not filler then filler = 0 end -- brk opcode
|
||||||
M.resolve()
|
M.resolve()
|
||||||
local bin = {}
|
local bin = {}
|
||||||
local ins = table.insert
|
local ins = table.insert
|
||||||
table.sort(locations, function(a,b) return a.start < b.start end)
|
table.sort(locations, function(a,b) return a.start < b.start end)
|
||||||
for _,location in ipairs(locations) do
|
for _,location in ipairs(locations) do
|
||||||
if location.start < #bin then
|
if location.start < #bin then
|
||||||
error(string.format("location [%04x,%04x] overlaps another",
|
error(string.format("location [%04x,%04x] overlaps another", location.start, location.finish))
|
||||||
location.start, math.type(location.size) == 'integer' and (location.size + location.start) or 0xffff))
|
|
||||||
end
|
end
|
||||||
for i=#bin,location.start-1 do ins(bin, filler) end
|
for i=#bin,location.start-1 do ins(bin, filler) end
|
||||||
M.size=0 M.cycles=0
|
M.size=0 M.cycles=0
|
||||||
local sections = location.sections
|
local sections = location.sections
|
||||||
table.sort(sections, function(a,b) return a.org < b.org end)
|
table.sort(sections, function(a,b) return a.org < b.org end)
|
||||||
for _,section in ipairs(sections) do
|
for _,section in ipairs(sections) do
|
||||||
print(section.org, #bin)
|
|
||||||
assert(section.org >= #bin)
|
assert(section.org >= #bin)
|
||||||
for i=#bin,section.org-1 do ins(bin, filler) end
|
for i=#bin,section.org-1 do ins(bin, filler) end
|
||||||
for _,instruction in ipairs(section.instructions) do
|
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)
|
M.size=#bin M.cycles=M.cycles+(instruction.cycles or 0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if math.type(location.size) == 'integer' then
|
if location.finish then
|
||||||
local endpos = location.size+location.start-1
|
for i=#bin,location.finish do ins(bin, filler) end
|
||||||
for i=#bin,endpos do ins(bin, filler) end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return bin
|
return bin
|
||||||
@ -170,7 +168,7 @@ M.writebin = function(filename, bin)
|
|||||||
if not filename then filename = 'main.bin' end
|
if not filename then filename = 'main.bin' end
|
||||||
if not bin then bin = M.genbin() end
|
if not bin then bin = M.genbin() end
|
||||||
local f = assert(io.open(filename, "wb"), "failed to open " .. filename .. " for writing")
|
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()
|
f:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -180,7 +178,10 @@ M.writesym = function(filename)
|
|||||||
table.sort(symbols)
|
table.sort(symbols)
|
||||||
local ins,fmt,rep = table.insert,string.format,string.rep
|
local ins,fmt,rep = table.insert,string.format,string.rep
|
||||||
local s ={'--- Symbol List'}
|
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.'
|
s[#s+1] = '--- End of Symbol List.'
|
||||||
f:write(table.concat(s, '\n'))
|
f:write(table.concat(s, '\n'))
|
||||||
f:close()
|
f:close()
|
||||||
@ -243,8 +244,9 @@ M.section = function(t)
|
|||||||
end
|
end
|
||||||
|
|
||||||
M.label = function(name)
|
M.label = function(name)
|
||||||
local eval,resolve,label,offset
|
local label,offset
|
||||||
label = { type='label', size=eval, resolve=resolve }
|
local section = M.section_current
|
||||||
|
label = { type='label' }
|
||||||
if name:sub(1,1) == '_' then -- local label
|
if name:sub(1,1) == '_' then -- local label
|
||||||
name = M.label_current .. name
|
name = M.label_current .. name
|
||||||
else
|
else
|
||||||
@ -252,13 +254,13 @@ M.label = function(name)
|
|||||||
end
|
end
|
||||||
if symbols[name] then error("duplicate symbol: " .. name) end
|
if symbols[name] then error("duplicate symbol: " .. name) end
|
||||||
symbols[name] = label
|
symbols[name] = label
|
||||||
eval = function()
|
label.size = function()
|
||||||
offset = M.section_current.size
|
offset = section.size
|
||||||
label.size = 0
|
label.size = 0
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
resolve = function() return M.section_current.org + offset end
|
label.resolve = function() return section.org + offset end
|
||||||
table.insert(M.section_current.instructions, label)
|
table.insert(section.instructions, label)
|
||||||
return label
|
return label
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -638,7 +640,7 @@ for k,v in pairs(oprel) do
|
|||||||
if x:sub(1,1) == '_' then x = parent .. x end
|
if x:sub(1,1) == '_' then x = parent .. x end
|
||||||
x = symbols[x]
|
x = symbols[x]
|
||||||
end
|
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
|
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
|
b[#b+1]=v.opc b[#b+1]=x&0xff
|
||||||
end
|
end
|
||||||
|
36
asm.l65
36
asm.l65
@ -64,13 +64,13 @@ ptr_table("ptrs", \(message), data, 0)
|
|||||||
lda data+3,12
|
lda data+3,12
|
||||||
lda data+3,12,x
|
lda data+3,12,x
|
||||||
lda data+3,12,y
|
lda data+3,12,y
|
||||||
lda (INTIM,5,x)
|
lda (VBLANK,5,x)
|
||||||
lda (\a(a+2),INTIM,x)
|
lda (\a(a+2),VBLANK,x)
|
||||||
lda (INTIM,5),y
|
lda (VBLANK,5),y
|
||||||
lda (\a(a&3),INTIM),y
|
lda (\a(a&3),VBLANK),y
|
||||||
jmp (INTIM)
|
jmp (VBLANK)
|
||||||
jmp (INTIM,12)
|
jmp (VBLANK,12)
|
||||||
jmp (INTIM-4)
|
jmp (VBLANK-4)
|
||||||
|
|
||||||
-- cycles are counted without taking any branch
|
-- 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 })
|
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
|
samepage
|
||||||
lda #0xac
|
lda #0xac
|
||||||
lda #INTIM
|
lda #VBLANK
|
||||||
lda 0xbeef
|
lda 0xbeef
|
||||||
lda INTIM
|
lda VBLANK
|
||||||
lda.w INTIM
|
lda.w VBLANK
|
||||||
lda INTIM,x
|
lda VBLANK,x
|
||||||
lda INTIM,y
|
lda VBLANK,y
|
||||||
lda (INTIM,x)
|
lda (VBLANK,x)
|
||||||
lda (INTIM),y
|
lda (VBLANK),y
|
||||||
end
|
end
|
||||||
|
|
||||||
asl
|
asl
|
||||||
asl INTIM
|
asl VBLANK
|
||||||
asl
|
asl
|
||||||
@_toto
|
@_toto
|
||||||
bne "test"
|
bne "_toto"
|
||||||
bne waitForIntim
|
bne waitForIntim
|
||||||
f=\("test") bne f()
|
f=\("_toto") bne f()
|
||||||
bne _toto
|
bne _toto
|
||||||
|
|
||||||
jam asl lsr ldx #16 ldy 0xf0f0
|
jam asl lsr ldx #16 ldy 0xf0f0
|
||||||
|
|
||||||
rts
|
rts
|
||||||
|
|
||||||
writebin()
|
writebin()
|
||||||
|
writesym()
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
section "doOverscan"
|
section "doOverscan"
|
||||||
|
36
asm.lua
36
asm.lua
@ -64,13 +64,13 @@ section("waitForIntim") --alt short syntax when no other option
|
|||||||
ldazab(function(o) return o+( data+3) end,12)
|
ldazab(function(o) return o+( data+3) end,12)
|
||||||
ldazax(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)
|
ldaaby(function(o) return o+( data+3) end,12)
|
||||||
ldainx (function(o) return o+(INTIM) end,5)
|
ldainx (function(o) return o+(VBLANK) end,5)
|
||||||
ldainx (function(a) return a+2 end,INTIM)
|
ldainx (function(a) return a+2 end,VBLANK)
|
||||||
ldainy (function(o) return o+(INTIM) end,5)
|
ldainy (function(o) return o+(VBLANK) end,5)
|
||||||
ldainy (function(a) return a&3 end,INTIM)
|
ldainy (function(a) return a&3 end,VBLANK)
|
||||||
jmpind (function(o) return o+(INTIM) end)
|
jmpind (function(o) return o+(VBLANK) end)
|
||||||
jmpind (function(o) return o+(INTIM) end,12)
|
jmpind (function(o) return o+(VBLANK) end,12)
|
||||||
jmpind (function(o) return o+(INTIM-4) end)
|
jmpind (function(o) return o+(VBLANK-4) end)
|
||||||
|
|
||||||
-- cycles are counted without taking any branch
|
-- 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 })
|
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()
|
do samepage()
|
||||||
ldaimm (function(o) return o+(0xac) end)
|
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+( 0xbeef) end)
|
||||||
ldazab(function(o) return o+( INTIM) end)
|
ldazab(function(o) return o+( VBLANK) end)
|
||||||
ldaabs(function(o) return o+( INTIM) end)
|
ldaabs(function(o) return o+( VBLANK) end)
|
||||||
ldazax(function(o) return o+( INTIM) end)
|
ldazax(function(o) return o+( VBLANK) end)
|
||||||
ldaaby(function(o) return o+( INTIM) end)
|
ldaaby(function(o) return o+( VBLANK) end)
|
||||||
ldainx (function(o) return o+(INTIM) end)
|
ldainx (function(o) return o+(VBLANK) end)
|
||||||
ldainy (function(o) return o+(INTIM) end) endpage()
|
ldainy (function(o) return o+(VBLANK) end) endpage()
|
||||||
end
|
end
|
||||||
|
|
||||||
aslimp()
|
aslimp()
|
||||||
aslzab(function(o) return o+( INTIM) end)
|
aslzab(function(o) return o+( VBLANK) end)
|
||||||
aslimp()
|
aslimp()
|
||||||
label("_toto")
|
label("_toto")
|
||||||
bnerel( "test")
|
bnerel( "_toto")
|
||||||
bnerel( "waitForIntim")
|
bnerel( "waitForIntim")
|
||||||
f=function() return "test" end bnerel( f())
|
f=function() return "_toto" end bnerel( f())
|
||||||
bnerel( "_toto")
|
bnerel( "_toto")
|
||||||
|
|
||||||
jamimp() aslimp() lsrimp() ldximm (function(o) return o+(16) end) ldyzab(function(o) return o+( 0xf0f0) end)
|
jamimp() aslimp() lsrimp() ldximm (function(o) return o+(16) end) ldyzab(function(o) return o+( 0xf0f0) end)
|
||||||
|
|
||||||
rtsimp()
|
rtsimp()
|
||||||
|
|
||||||
writebin()
|
writebin()
|
||||||
|
writesym()
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
section "doOverscan"
|
section "doOverscan"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user