1
0
mirror of https://github.com/g012/l65.git synced 2024-06-11 10:29:27 +00:00

Added shortcut @@name for section "name".

This commit is contained in:
g012 2017-09-10 01:25:51 +02:00
parent 0e9d298606
commit ec93899042
3 changed files with 61 additions and 45 deletions

View File

@ -4,26 +4,7 @@ local symbols={} M.symbols=symbols
local locations={} M.locations=locations local locations={} M.locations=locations
local stats={} M.stats=stats local stats={} M.stats=stats
local byte_normalize = function(v) local section_current -- cache of last location's last section, for faster access
if v < -128 or v > 255 then error("value out of byte range: " .. v) end
if v < 0 then v = v + 0x100 end
return v & 0xff
end
local word_normalize = function(v)
if v < -32768 or v > 65535 then error("value out of word range: " .. v) end
if v < 0 then v = v + 0x10000 end
return v & 0xffff
end
local byte_emit = function(v, bin)
assert(v >=0 and v <= 0xff)
bin[#bin+1] = v
end
local word_emit = function(v, bin)
assert(v >=0 and v <= 0xffff)
bin[#bin+1] = v & 0xff
bin[#bin+1] = (v>>8) & 0xff
end
M.link = function() M.link = function()
assert(not stats.unused, "can't link twice") assert(not stats.unused, "can't link twice")
@ -199,39 +180,63 @@ M.section = function(t)
if section.offset and not section.align then error("section " .. section.label .. " has offset, but no align") end if section.offset and not section.align then error("section " .. section.label .. " has offset, but no align") end
end end
table.insert(location[#locations].sections, section) table.insert(location[#locations].sections, section)
section_current = section
section.constraints = {} section.constraints = {}
section.instructions = {} section.instructions = {}
function section:compute_size() function section:compute_size()
self.size = 0 local instructinos = self.instructions
for _,instruction in ipairs(self.instructions) do local size = 0
-- TODO for _,instruction in ipairs(instructions) do
instruction.offset = size
size = size + #instruction.data
end
self.size = size
-- set start and finish fields of constraints
for _,constraint in ipairs(self.constraints) do
constraint.start = instructions[constraint.from].offset
constraint.finish = instructions[constraint.to].offset
end end
-- TODO update start and finish fields of constraints to actual addresses
end end
end end
M.samepage = function() M.samepage = function()
local section = sections[#sections] local section = section_current
table.insert(section.constraints, { type='samepage', start=#section.instructions }) table.insert(section.constraints, { type='samepage', from=#section.instructions+1 })
end end
M.crosspage = function() M.crosspage = function()
local section = sections[#sections] local section = section_current
table.insert(section.constraints, { type='crosspage', start=#section.instructions }) table.insert(section.constraints, { type='crosspage', from=#section.instructions+1 })
end end
M.endpage = function() M.endpage = function()
local section = sections[#sections] local section = section_current
local constraint = section.constraints[#section.constraints] local constraint = section.constraints[#section.constraints]
assert(constraint and not constraint.finish, "closing constraint, but no constraint is open") assert(constraint and not constraint.finish, "closing constraint, but no constraint is open")
constraint.finish = #section.instructions constraint.to = #section.instructions
end
local byte_normalize = function(v)
if v < -128 or v > 255 then error("value out of byte range: " .. v) end
if v < 0 then v = v + 0x100 end
return v & 0xff
end
local word_normalize = function(v)
if v < -32768 or v > 65535 then error("value out of word range: " .. v) end
if v < 0 then v = v + 0x10000 end
return v & 0xffff
end end
M.byte = function(...) M.byte = function(...)
local data = {...} local data = {...}
for _,v in ipairs(data) do byte_emit(byte_normalize(v)) end for i=1,#data do data[i] = byte_normalize(data[i]) end
table.insert(section_current.instructions, { data=data })
end end
M.word = function(...) M.word = function(...)
local data = {...} local src,data = {...}, {}
for _,v in ipairs(data) do word_emit(word_normalize(v)) end for i=1,#src do
local v = word_normalize(data[i])
table.insert(data, v & 0xff) table.insert(data, v >> 8)
end
table.insert(section_current.instructions, { data=data })
end end
return M return M

21
asm.l65
View File

@ -21,7 +21,8 @@ lda = 5 if lda < 6 then print('yep') end
--section{ "toto", align = 256, offset = 16 } --section{ "toto", align = 256, offset = 16 }
--section{ "toto", org = 0xf100 } --section{ "toto", org = 0xf100 }
section "waitForIntim" --alt short syntax when no other option: @@waitForIntim ? --section "waitForIntim"
@@waitForIntim --alt short syntax when no other option
-- n_{ a=INTIM } ? -- n_{ a=INTIM } ?
--lda(INTIM) -- or a=INTIM --lda(INTIM) -- or a=INTIM
--bne "waitForIntim" --bne "waitForIntim"
@ -30,15 +31,15 @@ section "waitForIntim" --alt short syntax when no other option: @@waitForIntim ?
ldy #0xAB - 16 + 0b11011 & 3 | 6 ~ 0xf >> ~3 << 1 // 5 ldy #0xAB - 16 + 0b11011 & 3 | 6 ~ 0xf >> ~3 << 1 // 5
samepage samepage
lda #0xac lda #0xac
lda #INTIM lda #INTIM
lda 0xbeef lda 0xbeef
lda INTIM lda INTIM
lda.w INTIM lda.w INTIM
lda INTIM,x lda INTIM,x
lda INTIM,y lda INTIM,y
lda (INTIM,x) lda (INTIM,x)
lda (INTIM),y lda (INTIM),y
end end
asl asl

14
l65.lua
View File

@ -538,7 +538,11 @@ local function LexLua(src)
toEmit = {Type = 'Symbol', Data = consume('/') and '//' or '/'} toEmit = {Type = 'Symbol', Data = consume('/') and '//' or '/'}
elseif syntax6502_on and consume('@') then elseif syntax6502_on and consume('@') then
toEmit = {Type = 'Symbol', Data = '@'} if consume('@') then
toEmit = {Type = 'Symbol', Data = '@@'}
else
toEmit = {Type = 'Symbol', Data = '@'}
end
elseif Symbols[c] then elseif Symbols[c] then
get() get()
@ -1153,7 +1157,13 @@ local function ParseLua(src)
-- label declarations -- label declarations
if not stat then if not stat then
if tok:ConsumeSymbol('@', tokenList) then if tok:ConsumeSymbol('@@', tokenList) then
if not tok:Is('Ident') then return false, GenerateError("<ident> expected.") end
local label_name = tok:Get(tokenList)
opcode_tok = tokenList[1]
label_name = as_string_expr(label_name, label_name.Data)
stat = emit_call('section', label_name)
elseif tok:ConsumeSymbol('@', tokenList) then
local is_local local is_local
if tok:ConsumeSymbol('.', tokenList) then is_local = true end if tok:ConsumeSymbol('.', tokenList) then is_local = true end
if not tok:Is('Ident') then return false, GenerateError("<ident> expected.") end if not tok:Is('Ident') then return false, GenerateError("<ident> expected.") end