From 6e7b9fa8909429d09e3ea21156c11760ad652272 Mon Sep 17 00:00:00 2001 From: g012 Date: Sat, 16 Sep 2017 23:43:21 +0200 Subject: [PATCH] Added functions for immediate and implied opcodes. --- 6502.lua | 51 ++++++++++++++++--------- asm.l65 | 13 +++++-- asm.lua | 111 ++++++++++++++++++++++++++++--------------------------- l65.lua | 34 ++++++++++------- 4 files changed, 120 insertions(+), 89 deletions(-) diff --git a/6502.lua b/6502.lua index caf0b41..58e86eb 100644 --- a/6502.lua +++ b/6502.lua @@ -354,22 +354,37 @@ M.word = function(...) table.insert(section_current.instructions, { data=data, size=#data*2, asbin=asbin }) end +local op = function(code, cycles, extra_on_crosspage) + return { opc=code, cycles=cycles or 2, xcross=extra_on_crosspage or 0 } +end +local opimp = { + asl=op(0x0a), brk=op(0x00,7), clc=op(0x18), cld=op(0xd8), cli=op(0x58), clv=op(0xb8), dex=op(0xca), dey=op(0x88), + inx=op(0xe8), iny=op(0xc8), lsr=op(0x4a), nop=op(0xea), pha=op(0x48,3), php=op(0x08,3), pla=op(0x68,4), plp=op(0x28,4), + rol=op(0x2a), ror=op(0x6a), rti=op(0x40,6), rts=op(0x60,6), sec=op(0x38), sei=op(0x78), tax=op(0xaa), tay=op(0xa8), + tsx=op(0xba), txa=op(0x8a), txs=op(0x9a), tya=op(0x98), + jam=op(0x02), +} M.opimm = opimm +for k,v in pairs(opimp) do + M[k .. 'imp'] = function() + local asbin = function(b) b[#b+1] = v.opc end + table.insert(section_current.instructions, { size=1, cycles=v.cycles, asbin=asbin }) + end +end +local opimm = { + lda=op(0xa9), ldx=op(0xa2), ldy=op(0xa0), cmp=op(0xc9), cpx=op(0xe0), cpy=op(0xc0), ora=op(0x09), ['and']=op(0x29), + eor=op(0x49), adc=op(0x69), sbc=op(0xe9), + anc=op(0x0b), ane=op(0x8b), arr=op(0x6b), asr=op(0x4b), jam=op(0x12), lax=op(0xab), nop=op(0x80), sbx=op(0xcb), +} M.opimm = opimm +for k,v in pairs(opimm) do + M[k .. 'imm'] = function(late, early) + local asbin = function(b) + local x = early or 0 + x = byte_normalize(type(late) == 'function' and late(x) or x+late) + b[#b+1] = v.opc + b[#b+1] = x + end + table.insert(section_current.instructions, { size=2, cycles=2, asbin=asbin }) + end +end + return M - ---[===[ - - -adressing = { - imm=0x09, zp=0x05, zpx=0x15, ab=0x0d, abx=0x1d, aby=0x19, inx=0x01, iny=0x11, - acc=0x09, -} -encode = { - adc=0x60, - ['and']=0x20, - asl=0x01, - lda=0xa0, - sta=0x80, - --lda = { imm=0xa9, zp=0xa5, zpx=0xb5, ab=0xad, abx=0xbd, aby=0xb9, inx=0xa1, iny=0xb1 }, -} - -]===] diff --git a/asm.l65 b/asm.l65 index 8ece87e..1c3b679 100644 --- a/asm.l65 +++ b/asm.l65 @@ -50,6 +50,10 @@ ptr_table("ptrs", message, data, 0) ldx #0xf0 ldx #0b1101 ldy #0xAB - 16 + 0b11011 & 3 | 6 ~ 0xf >> ~3 << 1 // 5 + ldx #15,3 + + local kernel_cycles,kernel_size + -- hook(\(kernel_cycles=cycles, kernel_size=size)) lda data lda data,5 @@ -59,12 +63,15 @@ ptr_table("ptrs", message, data, 0) lda data+3,12,x lda data+3,12,y lda (INTIM,5,x) - lda (INTIM,\a(a+2),x) + lda (\a(a+2),INTIM,x) lda (INTIM,5),y - lda (INTIM,\a(a+2)),y + lda (\a(a&3),INTIM),y jmp (INTIM) jmp (INTIM,12) - jmp (INTIM,\a(a-4)) + jmp (INTIM-4) + + -- cycles are counted without taking any branch + --hook(\(print('kernel cycles: ', cycles-kernel_cycles, 'kernel size: ', size-kernel_size))) lda function(c) return data * c end, v lda \c(data*c), v diff --git a/asm.lua b/asm.lua index 4115ebb..e5ecea5 100644 --- a/asm.lua +++ b/asm.lua @@ -17,17 +17,16 @@ x:f() lda = 5 if lda < 6 then print('yep') end ; ---[[ local function ptr_table(label, ...) local vals = {...} - section(label .. "_lo") - for _,v in ipairs(vals) do byte_lo(v) end - section(label .. "_hi") - for _,v in ipairs(vals) do byte_hi(v) end + section(label .. "_lo") byte_lo(vals) + section(label .. "_hi") byte_hi(vals) end -]] ---@@message byte(4) "test" byte(0) +charset(" abcdefghijklmnopqrstuvwxyz-") +section(function(o) return o+("message2") end) byte(4, "test", 0) +charset() +section(function(o) return o+("message") end) byte(4, "test", 0) section(function(o) return o+("data") end) do crosspage() @@ -35,15 +34,12 @@ section(function(o) return o+("data") end) end word(0xf080) byte(16, 3, 4, 5, 6, 24, 32) - --[[ - word(message) + word(message2) byte_lo(message) byte_hi(message) - --]] byte(function() return message&0xff end, function() return message>>8 end) - --[[ ptr_table("ptrs", message, data, 0) ---]] + --section{ "toto", align = 256, offset = 16 } --section{ "toto", org = 0xf100 } --section "waitForIntim" @@ -51,59 +47,66 @@ section(function(o) return o+("waitForIntim") end) --alt short syntax when no ot -- n_{ a=INTIM } ? --lda(INTIM) -- or a=INTIM --bne "waitForIntim" - ldx_immediate (function(o) return o+(0xf0) end) - ldx_immediate (function(o) return o+(13) end) - ldy_immediate (function(o) return o+(0xAB - 16 + 27 & 3 | 6 ~ 0xf >> ~3 << 1 // 5) end) + ldximm (function(o) return o+(0xf0) end) + ldximm (function(o) return o+(13) end) + ldyimm (function(o) return o+(0xAB - 16 + 27 & 3 | 6 ~ 0xf >> ~3 << 1 // 5) end) + ldximm (function(o) return o+(15) end,3) - lda_absolute(function(o) return o+( data) end) - lda_absolute(function(o) return o+( data) end,5) - lda_absolute_x(function(o) return o+( data) end,5) - lda_absolute_y(function(o) return o+( data) end,5) - lda_absolute(function(o) return o+( data+3) end,12) - lda_absolute_x(function(o) return o+( data+3) end,12) - lda_absolute_y(function(o) return o+( data+3) end,12) - lda_indirect_x (function(o) return o+(INTIM) end,5) - lda_indirect_x (function(o) return o+(INTIM) end,function(a) return a+2 end) - lda_indirect_y (function(o) return o+(INTIM) end,5) - lda_indirect_y (function(o) return o+(INTIM) end,function(a) return a+2 end) - jmp_indirect (function(o) return o+(INTIM) end) - jmp_indirect (function(o) return o+(INTIM) end,12) - jmp_indirect (function(o) return o+(INTIM) end,function(a) return a-4 end) + local kernel_cycles,kernel_size + -- hook(\(kernel_cycles=cycles, kernel_size=size)) - lda_absolute( function(c) return data * c end, v) - lda_absolute( function(c) return data*c end, v) - local f = function(c) return data*c end v=5 lda_absolute(f,v) v=12 lda_absolute(f,v) + ldaabs(function(o) return o+( data) end) + ldaabs(function(o) return o+( data) end,5) + ldaabx(function(o) return o+( data) end,5) + ldaaby(function(o) return o+( data) end,5) + ldaabs(function(o) return o+( data+3) end,12) + ldaabx(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) + + -- cycles are counted without taking any branch + --hook(\(print('kernel cycles: ', cycles-kernel_cycles, 'kernel size: ', size-kernel_size))) + + ldaabs( function(c) return data * c end, v) + ldaabs( function(c) return data*c end, v) + local f = function(c) return data*c end v=5 ldaabs(f,v) v=12 ldaabs(f,v) local g = function() return function(c) return data * c end end - lda_absolute(g(),v) - lda_absolute( f,v) - lda_absolute_x (function(o) return o+(_toto+15) end,16) - lda_immediate (15) + ldaabs(g(),v) + ldaabs( f,v) + ldaabx (function(o) return o+(_toto+15) end,16) + ldaimm (15) do samepage() - lda_immediate (function(o) return o+(0xac) end) - lda_immediate (function(o) return o+(INTIM) end) - lda_absolute(function(o) return o+( 0xbeef) end) - lda_absolute(function(o) return o+( INTIM) end) - lda_absolute_nozp(function(o) return o+( INTIM) end) - lda_absolute_x(function(o) return o+( INTIM) end) - lda_absolute_y(function(o) return o+( INTIM) end) - lda_indirect_x (function(o) return o+(INTIM) end) - lda_indirect_y (function(o) return o+(INTIM) end) endpage() + ldaimm (function(o) return o+(0xac) end) + ldaimm (function(o) return o+(INTIM) end) + ldaabs(function(o) return o+( 0xbeef) end) + ldaabs(function(o) return o+( INTIM) end) + ldaabsw(function(o) return o+( INTIM) end) + ldaabx(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() end - asl_implied() - asl_absolute(function(o) return o+( INTIM) end) - asl_implied() + aslimp() + aslabs(function(o) return o+( INTIM) end) + aslimp() label(function(o) return o+("_toto") end) - bne_relative(function(o) return o+( "test") end) - bne_relative(function(o) return o+( "waitForIntim") end) - bne_relative(function(o) return o+( f()) end) - bne_relative(function(o) return o+( "_toto") end) + bnerel(function(o) return o+( "test") end) + bnerel(function(o) return o+( "waitForIntim") end) + bnerel(function(o) return o+( f()) end) + bnerel(function(o) return o+( "_toto") end) - jam_implied() asl_implied() lsr_implied() ldx_immediate (function(o) return o+(16) end) ldy_absolute(function(o) return o+( 0xf0f0) end) + jamimp() aslimp() lsrimp() ldximm (function(o) return o+(16) end) ldyabs(function(o) return o+( 0xf0f0) end) - rts_implied() + rtsimp() --[[ section "doOverscan" diff --git a/l65.lua b/l65.lua index c8b90f3..3a5b724 100644 --- a/l65.lua +++ b/l65.lua @@ -1289,6 +1289,7 @@ local function ParseLua(src) -- 6502 opcodes if not stat then + local mod_st, mod_expr for _,op in pairs(Keywords_6502) do if tok:ConsumeKeyword(op, tokenList) then if opcode_relative[op] then @@ -1296,7 +1297,7 @@ local function ParseLua(src) if expr.AstType == 'VarExpr' and expr.Variable.IsGlobal then expr = as_string_expr(expr, expr.Name) end - stat = emit_call{name=op .. "_relative", args={expr}} break + stat = emit_call{name=op .. "rel", args={expr}} break end if opcode_immediate[op] and tok:ConsumeSymbol('#', tokenList) then if tok:ConsumeSymbol('!', tokenList) then inverse_encapsulate = true end @@ -1304,7 +1305,12 @@ local function ParseLua(src) local paren_open_whites = {} if inverse_encapsulate then for _,v in ipairs(tokenList[#tokenList-1].LeadingWhite) do table.insert(paren_open_whites, v) end end for _,v in ipairs(tokenList[#tokenList].LeadingWhite) do table.insert(paren_open_whites, v) end - stat = emit_call{name=op .. "_immediate", args={expr}, paren_open_white=paren_open_whites} break + if tok:ConsumeSymbol(',', tokenList) then + commaTokenList[1] = tokenList[#tokenList] + mod_st, mod_expr = ParseExpr(scope) + if not mod_st then return false, mod_expr end + end + stat = emit_call{name=op .. "imm", args={expr, mod_expr}, paren_open_white=paren_open_whites} break end if (opcode_indirect[op] or opcode_indirect_x[op] or opcode_indirect_y[op]) and tok:ConsumeSymbol('(', tokenList) then if tok:ConsumeSymbol('!', tokenList) then inverse_encapsulate = true end @@ -1325,7 +1331,7 @@ local function ParseLua(src) then return false, expr end for _,v in ipairs(tokenList[#tokenList-1].LeadingWhite) do table.insert(paren_close_whites, v) end for _,v in ipairs(tokenList[#tokenList].LeadingWhite) do table.insert(paren_close_whites, v) end - stat = emit_call{name=op .. "_indirect_x", args={expr, mod_expr}, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break + stat = emit_call{name=op .. "inx", args={expr, mod_expr}, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break elseif not tok:ConsumeSymbol(')', tokenList) then return false, expr else if tok:ConsumeSymbol(',', tokenList) then @@ -1333,10 +1339,10 @@ local function ParseLua(src) then return false, expr end for _,v in ipairs(tokenList[#tokenList-1].LeadingWhite) do table.insert(paren_close_whites, v) end for _,v in ipairs(tokenList[#tokenList].LeadingWhite) do table.insert(paren_close_whites, v) end - stat = emit_call{name=op .. "_indirect_y", args={expr, mod_expr}, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break + stat = emit_call{name=op .. "iny", args={expr, mod_expr}, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break else if not opcode_indirect[op] then return false, expr end - stat = emit_call{name=op .. "_indirect", args={expr, mod_expr}, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break + stat = emit_call{name=op .. "ind", args={expr, mod_expr}, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break end end end @@ -1345,8 +1351,8 @@ local function ParseLua(src) tok:Save() if tok:ConsumeSymbol('.', tokenList) then local t = tok:Get(tokenList).Data - if t == 'w' then suffix = '_nozp' - elseif t == 'b' then suffix = '_zp' + if t == 'w' then suffix = 'w' + elseif t == 'b' then suffix = 'b' else tok:Restore() tok:Save() end end local paren_open_whites = {} @@ -1360,7 +1366,7 @@ local function ParseLua(src) tok:Commit() if not tok:ConsumeSymbol(',', tokenList) then if not opcode_absolute[op] then return false, expr end - stat = emit_call{name=op .. "_absolute" .. suffix, args={expr}} break + stat = emit_call{name=op .. "abs" .. suffix, args={expr}} break end if tok:Peek().Data == 'x' then if not opcode_absolute_x[op] then return false, expr end @@ -1368,7 +1374,7 @@ local function ParseLua(src) local paren_close_whites = {} for _,v in ipairs(tokenList[#tokenList-1].LeadingWhite) do table.insert(paren_close_whites, v) end for _,v in ipairs(tokenList[#tokenList].LeadingWhite) do table.insert(paren_close_whites, v) end - stat = emit_call{name=op .. "_absolute_x" .. suffix, args={expr}, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break + stat = emit_call{name=op .. "abx" .. suffix, args={expr}, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break end if tok:Peek().Data == 'y' then if not opcode_absolute_y[op] then return false, expr end @@ -1376,14 +1382,14 @@ local function ParseLua(src) local paren_close_whites = {} for _,v in ipairs(tokenList[#tokenList-1].LeadingWhite) do table.insert(paren_close_whites, v) end for _,v in ipairs(tokenList[#tokenList].LeadingWhite) do table.insert(paren_close_whites, v) end - stat = emit_call{name=op .. "_absolute_y" .. suffix, args={expr}, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break + stat = emit_call{name=op .. "aby" .. suffix, args={expr}, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break end commaTokenList[1] = tokenList[#tokenList] local mod_st, mod_expr = ParseExpr(scope) if not mod_st then return false, mod_expr end if not tok:ConsumeSymbol(',', tokenList) then if not opcode_absolute[op] then return false, expr end - stat = emit_call{name=op .. "_absolute" .. suffix, args={expr, mod_expr}} break + stat = emit_call{name=op .. "abs" .. suffix, args={expr, mod_expr}} break end if tok:Peek().Data == 'x' then if not opcode_absolute_x[op] then return false, expr end @@ -1391,7 +1397,7 @@ local function ParseLua(src) local paren_close_whites = {} for _,v in ipairs(tokenList[#tokenList-1].LeadingWhite) do table.insert(paren_close_whites, v) end for _,v in ipairs(tokenList[#tokenList].LeadingWhite) do table.insert(paren_close_whites, v) end - stat = emit_call{name=op .. "_absolute_x" .. suffix, args={expr, mod_expr}, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break + stat = emit_call{name=op .. "abx" .. suffix, args={expr, mod_expr}, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break end if tok:Peek().Data == 'y' then if not opcode_absolute_y[op] then return false, expr end @@ -1399,13 +1405,13 @@ local function ParseLua(src) local paren_close_whites = {} for _,v in ipairs(tokenList[#tokenList-1].LeadingWhite) do table.insert(paren_close_whites, v) end for _,v in ipairs(tokenList[#tokenList].LeadingWhite) do table.insert(paren_close_whites, v) end - stat = emit_call{name=op .. "_absolute_y" .. suffix, args={expr, mod_expr}, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break + stat = emit_call{name=op .. "aby" .. suffix, args={expr, mod_expr}, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break end return false, expr end end - if opcode_implied[op] then stat = emit_call{name=op .. "_implied"} break end + if opcode_implied[op] then stat = emit_call{name=op .. "imp"} break end end end end