From ec9389904241292a6084daf103f24e2b4bfad799 Mon Sep 17 00:00:00 2001 From: g012 Date: Sun, 10 Sep 2017 01:25:51 +0200 Subject: [PATCH] Added shortcut @@name for section "name". --- 6502.lua | 71 ++++++++++++++++++++++++++++++-------------------------- asm.l65 | 21 +++++++++-------- l65.lua | 14 +++++++++-- 3 files changed, 61 insertions(+), 45 deletions(-) diff --git a/6502.lua b/6502.lua index d3dc6c1..0734bff 100644 --- a/6502.lua +++ b/6502.lua @@ -4,26 +4,7 @@ local symbols={} M.symbols=symbols local locations={} M.locations=locations local stats={} M.stats=stats -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 - -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 +local section_current -- cache of last location's last section, for faster access M.link = function() 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 end table.insert(location[#locations].sections, section) + section_current = section section.constraints = {} section.instructions = {} function section:compute_size() - self.size = 0 - for _,instruction in ipairs(self.instructions) do - -- TODO + local instructinos = self.instructions + local size = 0 + 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 - -- TODO update start and finish fields of constraints to actual addresses end end M.samepage = function() - local section = sections[#sections] - table.insert(section.constraints, { type='samepage', start=#section.instructions }) + local section = section_current + table.insert(section.constraints, { type='samepage', from=#section.instructions+1 }) end M.crosspage = function() - local section = sections[#sections] - table.insert(section.constraints, { type='crosspage', start=#section.instructions }) + local section = section_current + table.insert(section.constraints, { type='crosspage', from=#section.instructions+1 }) end M.endpage = function() - local section = sections[#sections] + local section = section_current local constraint = section.constraints[#section.constraints] 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 M.byte = function(...) 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 M.word = function(...) - local data = {...} - for _,v in ipairs(data) do word_emit(word_normalize(v)) end + local src,data = {...}, {} + 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 return M diff --git a/asm.l65 b/asm.l65 index 0c28329..4bde620 100644 --- a/asm.l65 +++ b/asm.l65 @@ -21,7 +21,8 @@ lda = 5 if lda < 6 then print('yep') end --section{ "toto", align = 256, offset = 16 } --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 } ? --lda(INTIM) -- or a=INTIM --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 samepage - lda #0xac - lda #INTIM - lda 0xbeef - lda INTIM - lda.w INTIM - lda INTIM,x - lda INTIM,y - lda (INTIM,x) - lda (INTIM),y + lda #0xac + lda #INTIM + lda 0xbeef + lda INTIM + lda.w INTIM + lda INTIM,x + lda INTIM,y + lda (INTIM,x) + lda (INTIM),y end asl diff --git a/l65.lua b/l65.lua index 0ba954f..c9fbf29 100644 --- a/l65.lua +++ b/l65.lua @@ -538,7 +538,11 @@ local function LexLua(src) toEmit = {Type = 'Symbol', Data = consume('/') and '//' or '/'} 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 get() @@ -1153,7 +1157,13 @@ local function ParseLua(src) -- label declarations if not stat then - if tok:ConsumeSymbol('@', tokenList) then + if tok:ConsumeSymbol('@@', tokenList) then + if not tok:Is('Ident') then return false, GenerateError(" 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 if tok:ConsumeSymbol('.', tokenList) then is_local = true end if not tok:Is('Ident') then return false, GenerateError(" expected.") end