mirror of
https://github.com/g012/l65.git
synced 2025-01-30 14:34:25 +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
|
||||
/tmp
|
||||
*.bin
|
||||
*.sym
|
||||
|
42
6502.lua
42
6502.lua
@ -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
36
asm.l65
@ -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
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)
|
||||
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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user