Added zpg and abs opcodes.

This commit is contained in:
g012 2017-09-17 22:56:39 +02:00
parent 7588e8f51e
commit a602795911
3 changed files with 137 additions and 31 deletions

View File

@ -208,7 +208,8 @@ M.section = function(t)
if not instruction.size then
-- evaluation is needed to get the size (distinguish zpg/abs)
-- labels and sections are not resolved at this point, so
-- evaluation will fail if the size is not explicitly stated (.b/.w)
-- evaluation will fail if the size is not explicitly stated (.b/.w);
-- in that case, assume max size
instruction.bin={} instruction.asbin(instruction.bin)
end
size = size + instruction.size
@ -361,37 +362,103 @@ 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 }
local op,cycles_def = function(code, cycles, extra_on_crosspage)
return { opc=code, cycles=cycles or cycles_def, xcross=extra_on_crosspage or 0 }
end
local opimp = {
cycles_def=2 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
jam=op(0x02,0),
} M.opimp = opimp
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),
cycles_def=2 local opimm={
adc=op(0x69), ['and']=op(0x29), cmp=op(0xc9), cpx=op(0xe0), cpy=op(0xc0), eor=op(0x49), lda=op(0xa9), ldx=op(0xa2),
ldy=op(0xa0), ora=op(0x09), sbc=op(0xe9),
anc=op(0x0b), ane=op(0x8b), arr=op(0x6b), asr=op(0x4b), jam=op(0x12,0), 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
b[#b+1]=v.opc b[#b+1]=x
end
table.insert(section_current.instructions, { size=2, cycles=2, asbin=asbin })
end
end
cycles_def=3 local opzpg={
adc=op(0x65), ['and']=op(0x25), asl=op(0x06,5), bit=op(0x24), cmp=op(0xc5), cpx=op(0xe4), cpy=op(0xc4), dec=op(0xc6,5),
eor=op(0x45), inc=op(0xe6,5), lda=op(0xa5), ldx=op(0xa6), ldy=op(0xa4), lsr=op(0x46,5), ora=op(0x05), rol=op(0x26,5),
ror=op(0x66,5), sbc=op(0xe5), sta=op(0x85), stx=op(0x86), sty=op(0x84),
dcp=op(0xc7,5), isb=op(0xe7,5), jam=op(0x22,0), lax=op(0xa7), nop=op(0x04), rla=op(0x27,5), rra=op(0x67,5), sax=op(0x87),
slo=op(0x07,5), sre=op(0x47,5),
} M.opzpg = opzpg
for k,v in pairs(opzpg) do
M[k .. 'zpg'] = 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=v.cycles, asbin=asbin })
end
end
cycles_def=4 local opabs={
adc=op(0x6d), ['and']=op(0x2d), asl=op(0x0e,6), bit=op(0x2c), cmp=op(0xcd), cpx=op(0xec), cpy=op(0xcc), dec=op(0xce,6),
eor=op(0x4d), inc=op(0xee,6), jmp=op(0x4c,3), jsr=op(0x20,6), lda=op(0xad), ldx=op(0xae), ldy=op(0xac), lsr=op(0x4e,6),
ora=op(0x0d), rol=op(0x2e,6), ror=op(0x6e,6), sbc=op(0xed), sta=op(0x8d), stx=op(0x8e), sty=op(0x8c),
dcp=op(0xcf,6), isb=op(0xef,6), jam=op(0x72,0), lax=op(0xaf), nop=op(0x0c), rla=op(0x2f,6), rra=op(0x6f,6), sax=op(0x8f),
slo=op(0x0f,6), sre=op(0x4f,6),
} M.opabs = opabs
for k,v in pairs(opabs) do
M[k .. 'abs'] = function(late, early)
local asbin = function(b)
local x = early or 0
x = word_normalize(type(late) == 'function' and late(x) or x+late)
b[#b+1]=v.opc b[#b+1]=x&0xff b[#b+1]=x>>8
end
table.insert(section_current.instructions, { size=3, cycles=v.cycles, asbin=asbin })
end
M[k .. 'zab'] = function(late, early)
if type(late) ~= 'function' then
local x = (early or 0) + late
if x >= -128 and x <= 0xff then return M[k .. 'zpg'](late, early) end
if x >= -32768 and x <= 0xffff then return M[k .. 'abs'](late, early) end
error("value out of word range: " .. x)
end
local eval, asbin
local ins = { size=eval, cycles=v.cycles, asbin=asbin }
eval = function()
local r,x = pcall(late(early or 0))
if not r then return 3 end
x = word_normalize(x)
local op = opzpg[k]
if x <= 0xff and op then
ins.size = 2
ins.cycles = op.cycles
ins.asbin = function(b) b[#b+1]=op.opc b[#b+1]=x end
return 2
end
ins.size = 3
ins.asbin = function(b) b[#b+1]=v.opc b[#b+1]=x&0xff b[#b+1]=x>>8 end
return 3
end
asbin = function(b)
-- TODO force absolute ?
local x = word_normalize(late(early or 0))
local op = opzpg[k]
if x <= 0xff and op then b[#b+1]=op.opc b[#b+1]=x
else b[#b+1]=v.opc b[#b+1]=x&0xff b[#b+1]=x>>8 end
end
table.insert(section_current.instructions, ins)
end
end
return M

24
l65.lua
View File

@ -47,9 +47,9 @@ local Keywords_6502 = {
'ror', 'rti', 'rts', 'sbc', 'sec', 'sed', 'sei', 'sta',
'stx', 'sty', 'tax', 'tay', 'tsx', 'txa', 'txs', 'tya',
-- illegal opcodes
'anc', 'ane', 'arr', 'asr', 'axs', 'dcp', 'dop', 'isb',
'jam', 'las', 'lax', 'rla', 'rra', 'sax', 'sbx', 'sha',
'shs', 'shx', 'shy', 'slo', 'sre',
'anc', 'ane', 'arr', 'asr', 'dcp', 'isb', 'jam', 'las',
'lax', 'rla', 'rra', 'sax', 'sbx', 'sha', 'shs', 'shx',
'shy', 'slo', 'sre',
}
local syntax6502_on
@ -1366,7 +1366,8 @@ 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 .. "abs" .. suffix, args={expr}} break
suffix = suffix=='b' and "zpg" or suffix=='w' and "abs" or "zab"
stat = emit_call{name=op .. suffix, args={expr}} break
end
if tok:Peek().Data == 'x' then
if not opcode_absolute_x[op] then return false, expr end
@ -1374,7 +1375,8 @@ 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 .. "abx" .. suffix, args={expr}, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break
suffix = suffix=='b' and "zpx" or suffix=='w' and "abx" or "zax"
stat = emit_call{name=op .. 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
@ -1382,14 +1384,16 @@ 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 .. "aby" .. suffix, args={expr}, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break
suffix = suffix=='b' and "zpy" or suffix=='w' and "aby" or "zay"
stat = emit_call{name=op .. 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 .. "abs" .. suffix, args={expr, mod_expr}} break
suffix = suffix=='b' and "zpg" or suffix=='w' and "abs" or "zab"
stat = emit_call{name=op .. suffix, args={expr, mod_expr}} break
end
if tok:Peek().Data == 'x' then
if not opcode_absolute_x[op] then return false, expr end
@ -1397,7 +1401,8 @@ 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 .. "abx" .. suffix, args={expr, mod_expr}, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break
suffix = suffix=='b' and "zpx" or suffix=='w' and "abx" or "zax"
stat = emit_call{name=op .. 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
@ -1405,7 +1410,8 @@ 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 .. "aby" .. suffix, args={expr, mod_expr}, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break
suffix = suffix=='b' and "zpy" or suffix=='w' and "aby" or "zay"
stat = emit_call{name=op .. suffix, args={expr, mod_expr}, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break
end
return false, expr

View File

@ -241,6 +241,8 @@ syn match l65Keyword /\<adczpx\>/
syn match l65Keyword /\<adcabs\>/
syn match l65Keyword /\<adcabx\>/
syn match l65Keyword /\<adcaby\>/
syn match l65Keyword /\<adczab\>/
syn match l65Keyword /\<adczax\>/
syn match l65Keyword /\<adcinx\>/
syn match l65Keyword /\<adciny\>/
syn match l65Keyword /\<andimm\>/
@ -249,6 +251,8 @@ syn match l65Keyword /\<andzpx\>/
syn match l65Keyword /\<andabs\>/
syn match l65Keyword /\<andabx\>/
syn match l65Keyword /\<andaby\>/
syn match l65Keyword /\<andzab\>/
syn match l65Keyword /\<andzax\>/
syn match l65Keyword /\<andinx\>/
syn match l65Keyword /\<andiny\>/
syn match l65Keyword /\<aslimp\>/
@ -256,11 +260,14 @@ syn match l65Keyword /\<aslzpg\>/
syn match l65Keyword /\<aslzpx\>/
syn match l65Keyword /\<aslabs\>/
syn match l65Keyword /\<aslabx\>/
syn match l65Keyword /\<aslzab\>/
syn match l65Keyword /\<aslzax\>/
syn match l65Keyword /\<bccrel\>/
syn match l65Keyword /\<bcsrel\>/
syn match l65Keyword /\<beqrel\>/
syn match l65Keyword /\<bitzpg\>/
syn match l65Keyword /\<bitabs\>/
syn match l65Keyword /\<bitzab\>/
syn match l65Keyword /\<bmirel\>/
syn match l65Keyword /\<bnerel\>/
syn match l65Keyword /\<bplrel\>/
@ -277,18 +284,24 @@ syn match l65Keyword /\<cmpzpx\>/
syn match l65Keyword /\<cmpabs\>/
syn match l65Keyword /\<cmpabx\>/
syn match l65Keyword /\<cmpaby\>/
syn match l65Keyword /\<cmpzab\>/
syn match l65Keyword /\<cmpzax\>/
syn match l65Keyword /\<cmpinx\>/
syn match l65Keyword /\<cmpiny\>/
syn match l65Keyword /\<cpximm\>/
syn match l65Keyword /\<cpxzpg\>/
syn match l65Keyword /\<cpxabs\>/
syn match l65Keyword /\<cpxzab\>/
syn match l65Keyword /\<cpyimm\>/
syn match l65Keyword /\<cpyzpg\>/
syn match l65Keyword /\<cpyabs\>/
syn match l65Keyword /\<cpyzab\>/
syn match l65Keyword /\<deczpg\>/
syn match l65Keyword /\<deczpx\>/
syn match l65Keyword /\<decabs\>/
syn match l65Keyword /\<decabx\>/
syn match l65Keyword /\<deczab\>/
syn match l65Keyword /\<deczax\>/
syn match l65Keyword /\<deximp\>/
syn match l65Keyword /\<deyimp\>/
syn match l65Keyword /\<eorimm\>/
@ -297,12 +310,16 @@ syn match l65Keyword /\<eorzpx\>/
syn match l65Keyword /\<eorabs\>/
syn match l65Keyword /\<eorabx\>/
syn match l65Keyword /\<eoraby\>/
syn match l65Keyword /\<eorzab\>/
syn match l65Keyword /\<eorzax\>/
syn match l65Keyword /\<eorinx\>/
syn match l65Keyword /\<eoriny\>/
syn match l65Keyword /\<inczpg\>/
syn match l65Keyword /\<inczpx\>/
syn match l65Keyword /\<incabs\>/
syn match l65Keyword /\<incabx\>/
syn match l65Keyword /\<inczab\>/
syn match l65Keyword /\<inczax\>/
syn match l65Keyword /\<inximp\>/
syn match l65Keyword /\<inyimp\>/
syn match l65Keyword /\<jmpabs\>/
@ -314,6 +331,8 @@ syn match l65Keyword /\<ldazpx\>/
syn match l65Keyword /\<ldaabs\>/
syn match l65Keyword /\<ldaabx\>/
syn match l65Keyword /\<ldaaby\>/
syn match l65Keyword /\<ldazab\>/
syn match l65Keyword /\<ldazax\>/
syn match l65Keyword /\<ldainx\>/
syn match l65Keyword /\<ldainy\>/
syn match l65Keyword /\<ldximm\>/
@ -321,15 +340,21 @@ syn match l65Keyword /\<ldxzpg\>/
syn match l65Keyword /\<ldxzpy\>/
syn match l65Keyword /\<ldxabs\>/
syn match l65Keyword /\<ldxaby\>/
syn match l65Keyword /\<ldxzab\>/
syn match l65Keyword /\<ldxzay\>/
syn match l65Keyword /\<ldyzpg\>/
syn match l65Keyword /\<ldyzpx\>/
syn match l65Keyword /\<ldyabs\>/
syn match l65Keyword /\<ldyabx\>/
syn match l65Keyword /\<ldyzab\>/
syn match l65Keyword /\<ldyzax\>/
syn match l65Keyword /\<lsrimp\>/
syn match l65Keyword /\<lsrzpg\>/
syn match l65Keyword /\<lsrzpx\>/
syn match l65Keyword /\<lsrabs\>/
syn match l65Keyword /\<lsrabx\>/
syn match l65Keyword /\<lsrzab\>/
syn match l65Keyword /\<lsrzax\>/
syn match l65Keyword /\<nopimp\>/
syn match l65Keyword /\<oraimm\>/
syn match l65Keyword /\<orazpg\>/
@ -337,6 +362,8 @@ syn match l65Keyword /\<orazpx\>/
syn match l65Keyword /\<oraabs\>/
syn match l65Keyword /\<oraabx\>/
syn match l65Keyword /\<oraaby\>/
syn match l65Keyword /\<orazab\>/
syn match l65Keyword /\<orazax\>/
syn match l65Keyword /\<orainx\>/
syn match l65Keyword /\<orainy\>/
syn match l65Keyword /\<phaimp\>/
@ -348,11 +375,15 @@ syn match l65Keyword /\<rolzpg\>/
syn match l65Keyword /\<rolzpx\>/
syn match l65Keyword /\<rolabs\>/
syn match l65Keyword /\<rolabx\>/
syn match l65Keyword /\<rolzab\>/
syn match l65Keyword /\<rolzax\>/
syn match l65Keyword /\<rorimp\>/
syn match l65Keyword /\<rorzpg\>/
syn match l65Keyword /\<rorzpx\>/
syn match l65Keyword /\<rorabs\>/
syn match l65Keyword /\<rorabx\>/
syn match l65Keyword /\<rorzab\>/
syn match l65Keyword /\<rorzax\>/
syn match l65Keyword /\<rtiimp\>/
syn match l65Keyword /\<rtsimp\>/
syn match l65Keyword /\<sbcimm\>/
@ -361,6 +392,8 @@ syn match l65Keyword /\<sbczpx\>/
syn match l65Keyword /\<sbcabs\>/
syn match l65Keyword /\<sbcabx\>/
syn match l65Keyword /\<sbcaby\>/
syn match l65Keyword /\<sbczab\>/
syn match l65Keyword /\<sbczax\>/
syn match l65Keyword /\<sbcinx\>/
syn match l65Keyword /\<sbciny\>/
syn match l65Keyword /\<secimp\>/
@ -371,14 +404,18 @@ syn match l65Keyword /\<stazpx\>/
syn match l65Keyword /\<staabs\>/
syn match l65Keyword /\<staabx\>/
syn match l65Keyword /\<staaby\>/
syn match l65Keyword /\<stazab\>/
syn match l65Keyword /\<stazax\>/
syn match l65Keyword /\<stainx\>/
syn match l65Keyword /\<stainy\>/
syn match l65Keyword /\<stxzpg\>/
syn match l65Keyword /\<stxzpy\>/
syn match l65Keyword /\<stxabs\>/
syn match l65Keyword /\<stxzab\>/
syn match l65Keyword /\<styzpg\>/
syn match l65Keyword /\<styzpx\>/
syn match l65Keyword /\<styabs\>/
syn match l65Keyword /\<styzab\>/
syn match l65Keyword /\<taximp\>/
syn match l65Keyword /\<tayimp\>/
syn match l65Keyword /\<tsximp\>/
@ -390,10 +427,6 @@ syn match l65Keyword /\<ancimm\>/
syn match l65Keyword /\<aneimm\>/
syn match l65Keyword /\<arrimm\>/
syn match l65Keyword /\<asrimm\>/
syn match l65Keyword /\<axszpg\>/
syn match l65Keyword /\<axszpy\>/
syn match l65Keyword /\<axsabs\>/
syn match l65Keyword /\<axsinx\>/
syn match l65Keyword /\<dcpzpg\>/
syn match l65Keyword /\<dcpzpx\>/
syn match l65Keyword /\<dcpabs\>/
@ -401,9 +434,6 @@ syn match l65Keyword /\<dcpabx\>/
syn match l65Keyword /\<dcpaby\>/
syn match l65Keyword /\<dcpinx\>/
syn match l65Keyword /\<dcpiny\>/
syn match l65Keyword /\<dopimm\>/
syn match l65Keyword /\<dopzpg\>/
syn match l65Keyword /\<dopzpx\>/
syn match l65Keyword /\<isbzpg\>/
syn match l65Keyword /\<isbzpx\>/
syn match l65Keyword /\<isbabs\>/
@ -419,6 +449,11 @@ syn match l65Keyword /\<laxabs\>/
syn match l65Keyword /\<laxaby\>/
syn match l65Keyword /\<laxinx\>/
syn match l65Keyword /\<laxiny\>/
syn match l65Keyword /\<nopimm\>/
syn match l65Keyword /\<nopzpg\>/
syn match l65Keyword /\<nopzpx\>/
syn match l65Keyword /\<nopabs\>/
syn match l65Keyword /\<nopabx\>/
syn match l65Keyword /\<rlazpg\>/
syn match l65Keyword /\<rlazpx\>/
syn match l65Keyword /\<rlaabs\>/
@ -492,7 +527,7 @@ syn match l65Opcode /\<lda\%(.[bw]\)\=\>/
syn match l65Opcode /\<ldx\%(.[bw]\)\=\>/
syn match l65Opcode /\<ldy\%(.[bw]\)\=\>/
syn match l65Opcode /\<lsr\%(.[bw]\)\=\>/
syn match l65Opcode /\<nop\>/
syn match l65Opcode /\<nop\%(.[bw]\)\=\>/
syn match l65Opcode /\<ora\%(.[bw]\)\=\>/
syn match l65Opcode /\<pha\>/
syn match l65Opcode /\<php\>/
@ -520,9 +555,7 @@ syn match l65Opcode /\<anc\>/
syn match l65Opcode /\<ane\>/
syn match l65Opcode /\<arr\>/
syn match l65Opcode /\<asr\>/
syn match l65Opcode /\<axs\>/
syn match l65Opcode /\<dcp\%(.[bw]\)\=\>/
syn match l65Opcode /\<dop\>/
syn match l65Opcode /\<isb\%(.[bw]\)\=\>/
syn match l65Opcode /\<jam\>/
syn match l65Opcode /\<las\>/