From c054cadd1e4b4f2c487df57e50ec2e0ef715ccea Mon Sep 17 00:00:00 2001 From: g012 Date: Wed, 6 Sep 2017 00:45:51 +0200 Subject: [PATCH] Started 6502 code. --- 6502.lua | 118 +++++++++++++++++++++----------------------------- asm.lua | 4 +- l65.lua | 129 ++++++++++--------------------------------------------- 3 files changed, 74 insertions(+), 177 deletions(-) diff --git a/6502.lua b/6502.lua index e9c4dda..730509a 100644 --- a/6502.lua +++ b/6502.lua @@ -1,3 +1,51 @@ +local M = {} + +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] = 0xff & (v % 0x100) + bin[#bin+1] = 0xff & (v // 0x100) +end + +M.byte = function(...) + local data = {...} + for _,v in ipairs(data) do byte_emit(byte_normalize(v)) end +end +M.word = function(...) + local data = {...} + for _,v in ipairs(data) do word_emit(word_normalize(v)) end +end + +M.section = function(t) + local s = {} + if (type(t) == 'string') then s.name = t + else + assert(type(t) == 'table') + assert(type(t.name) == 'string' and string.len(t.name) > 0) + s = t + end + s.instructions = {} +end + +return M + +--[===[ + + adressing = { imm=0x09, zp=0x05, zpx=0x15, ab=0x0d, abx=0x1d, aby=0x19, inx=0x01, iny=0x11, acc=0x09, @@ -11,72 +59,4 @@ encode = { --lda = { imm=0xa9, zp=0xa5, zpx=0xb5, ab=0xad, abx=0xbd, aby=0xb9, inx=0xa1, iny=0xb1 }, } - ---[=[ -adressages: - lda #10 lda(10) lda"#10" - lda 10 lda{10} lda"10" - lda 10,x lda{10,"x"} ldax{10} lda{x=10} lda"10,x" - lda $1000 lda{0x1000} - lda $1000,x lda{0x1000,"x"} ldax{0x1000} - lda $1000,y lda{0x1000,"y"} lday{0x1000} - lda (10,x) lda{10,"(x)"} lda_x{10} a=(10,x) a=mem[zp[10+x]] lda"(10,x)" - lda (10),y lda{10,"(y)"} lda_y{10} a=(10),y a=mem[zp[10]+y] lda"(10),y" - - sta 10 sta{10} - sta 10,x sta{10,"x"} - sta $1000 sta{0x1000} - sta $1000,x sta{0x1000,"x"} - sta $1000,y sta{0x1000,"y"} - sta (10,x) sta{10,"(x)"} - sta (10),y sta{10,"(y)"} -]=] - -local function setfenv(fn, env) - local i = 1 - while true do - local name = debug.getupvalue(fn, i) - if name == "_ENV" then - debug.upvaluejoin(fn, i, (function() return env end), 1) - break - elseif not name then break end - i = i + 1 - end - - return fn -end - -local function getfenv(fn) - local i = 1 - while true do - local name, val = debug.getupvalue(fn, i) - if name == "_ENV" then return val - elseif not name then break end - i = i + 1 - end -end - -asm6502_env = { - lda = function(v) - emit(0xa9, v) - end, -} -function asm(f, ...) - setfenv(f, asm6502_env) - f(...) -end - -a,x,y = 0,0,0 -do - local regs = { a="a", x="x", y="y" } - setmetatable(_G, { - __index = function(t,k,v) - if regs[k] then assert(loadstring("ld" .. k .. "(" .. v .. ")"))() end - return t[k] - end, - __newindex = function(t,k,v) - if regs[k] then assert(loadstring("st" .. k .. "(" .. v .. ")"))() end - t[k] = v - end, - }) -end +]===] diff --git a/asm.lua b/asm.lua index 91a2572..52e32c5 100644 --- a/asm.lua +++ b/asm.lua @@ -13,9 +13,9 @@ xyz = 1 << 2 x:f() ::lualabel:: -syntax6502_off +#pragma syntax6502 off lda = 5 if lda < 6 then print('yep') end -syntax6502_on +#pragma syntax6502 on --@@data samepage byte(1, 2) crosspage byte(3, 4) diff --git a/l65.lua b/l65.lua index 90f14f8..e6a189b 100644 --- a/l65.lua +++ b/l65.lua @@ -2046,112 +2046,29 @@ local function Format65(ast) return table.concat(out.rope) end - - - - -local function splitFilename(name) - if name:find(".") then - local p, ext = name:match("()%.([^%.]*)$") - if p and ext then - if #ext == 0 then - return name, nil - else - local filename = name:sub(1,p-1) - return filename, ext - end - else - return name, nil - end - else - return name, nil - end +if #arg ~= 2 then + print("Invalid arguments, usage:\nl65 source destination") + return end -if #arg == 1 then - local name, ext = splitFilename(arg[1]) - local outname = name.."_min" - if ext then outname = outname.."."..ext end - -- - local inf = io.open(arg[1], 'r') - if not inf then - print("Failed to open '"..arg[1].."' for reading") - return - end - -- - local sourceText = inf:read('*all') - inf:close() - -- - local st, ast = ParseLua(sourceText) - if not st then - --we failed to parse the file, show why - print(ast) - return - end - -- - local outf = io.open(outname, 'w') - if not outf then - print("Failed to open '"..outname.."' for writing") - return - end - -- - outf:write(Format65(ast)) - outf:close() - -- - -elseif #arg == 2 then - --keep the user from accidentally overwriting their non-minified file with - if arg[1]:find("_min") then - print("Did you mix up the argument order?\n".. - "Current command will minify '"..arg[1].."' and OVERWRITE '"..arg[2].."' with the results") - while true do - io.write("Confirm (yes/cancel): ") - local msg = io.read('*line') - if msg == 'yes' then - break - elseif msg == 'cancel' then - return - end - end - end - local inf = io.open(arg[1], 'r') - if not inf then - print("Failed to open '"..arg[1].."' for reading") - return - end - -- - local sourceText = inf:read('*all') - inf:close() - -- - local st, ast = ParseLua(sourceText) - if not st then - --we failed to parse the file, show why - print(ast) - return - end - -- - if arg[1] == arg[2] then - print("Are you SURE you want to overwrite the source file?") - while true do - io.write("Confirm (yes/cancel): ") - local msg = io.read('*line') - if msg == 'yes' then - break - elseif msg == 'cancel' then - return - end - end - end - local outf = io.open(arg[2], 'w') - if not outf then - print("Failed to open '"..arg[2].."' for writing") - return - end - -- - outf:write(Format65(ast)) - outf:close() - -- - -else - print("Invalid arguments, usage:\nl65 source [destination]") +local inf = io.open(arg[1], 'r') +if not inf then + print("Failed to open '"..arg[1].."' for reading") + return end +local outf = io.open(arg[2], 'w') +if not outf then + print("Failed to open '"..arg[2].."' for writing") + return +end + +local sourceText = inf:read('*all') +inf:close() +local st, ast = ParseLua(sourceText) +if not st then + print(ast) + return +end + +outf:write(Format65(ast)) +outf:close()