First attempt to add k65 style syntax.

This commit is contained in:
g012 2017-09-22 23:58:01 +02:00
parent 378667685d
commit 7eabbe80a6
6 changed files with 113 additions and 116 deletions

View File

@ -277,6 +277,7 @@ M.location = function(start, finish)
end
location.start = start[1]
location.finish = start[2]
location.name = start.name
location.rorg = start.rorg
if type(location.rorg) == 'number' then
local offset = location.rorg - location.start

86
l65.lua
View File

@ -54,6 +54,7 @@ local Keywords_6502 = {
'lax', 'rla', 'rra', 'sax', 'sbx', 'sha', 'shs', 'shx',
'shy', 'slo', 'sre',
}
local Registers_6502 = { a=8, x=8, y=8 }
local syntax6502_on
local function syntax6502(on)
@ -64,6 +65,11 @@ local function syntax6502(on)
end
syntax6502(true)
local syntax6502k_on
local function syntax6502k(on)
syntax6502k_on = on
end
local opcode_arg_encapsulate_on
local function opcode_arg_encapsulate(on)
opcode_arg_encapsulate_on = not opcode_arg_encapsulate_on
@ -257,6 +263,15 @@ local function LexLua(src)
repeat get() c = peek() until not (UpperChars[c] or LowerChars[c] or Digits[c] or c == '_')
return src:sub(start, p-1)
end
local function peek_ident(i, spaces)
if not spaces then spaces = Spaces end
local c
while true do c=peek(i) if not spaces[c] then break end i=i+1 end
if not (UpperChars[c] or LowerChars[c] or c == '_') then return end
local start = p+i
repeat i=i+1 c = peek(i) until not (UpperChars[c] or LowerChars[c] or Digits[c] or c == '_')
return src:sub(start, p+i-1),i,c
end
--shared stuff
local function generateError(err)
@ -454,6 +469,9 @@ local function LexLua(src)
if dat == 'syntax6502' then
onoff(syntax6502)
toEmit = {Type = 'Symbol', Data = ';'}
elseif dat == 'syntax6502k' then
onoff(syntax6502k)
toEmit = {Type = 'Symbol', Data = ';'}
elseif dat == 'encapsulate' then
onoff(function() end)
toEmit = {Type = 'Keyword', Data = 'encapsulate_' .. opt}
@ -476,7 +494,35 @@ local function LexLua(src)
if Keywords[dat] then
toEmit = {Type = 'Keyword', Data = dat}
else
toEmit = {Type = 'Ident', Data = dat}
if syntax6502k_on then
local i=0
while true do c=peek(i) if not Spaces[c] then break end i=i+1 end
if c == '=' then
local idents,ident = {dat}
repeat
i = i+1
ident,i,c = peek_ident(i)
if not ident then break end
table.insert(idents, ident)
until c ~= '='
local reg = idents[#idents]
if Registers_6502[reg] then
-- list of assignements ends with =a, =x, or =y
get_n(i)
-- TODO find a=expr, emit lda expr
local st = 'st'..reg
idents[#idents] = nil
toEmit = {}
for k,v in ipairs(idents) do
table.insert(toEmit, { Type='Keyword', Data=st })
table.insert(toEmit, { Type='Ident', Data=v })
end
end
end
end
if not toEmit then
toEmit = {Type = 'Ident', Data = dat}
end
end
elseif Digits[c] or (peek() == '.' and Digits[peek(1)]) then
@ -594,21 +640,33 @@ local function LexLua(src)
end
end
--add the emitted symbol, after adding some common data
toEmit.LeadingWhite = leading -- table of leading whitespace/comments
--for k, tok in pairs(leading) do
-- tokens[#tokens + 1] = tok
--end
if toEmit[1] then
toEmit[1].LeadingWhite = leading
for k,v in ipairs(toEmit) do
v.Line = thisLine
v.Char = thisChar
v.Print = function()
return "<"..(v.Type..string.rep(' ', 7-#v.Type)).." "..(v.Data or '').." >"
end
tokens[#tokens+1] = v
end
else
--add the emitted symbol, after adding some common data
toEmit.LeadingWhite = leading -- table of leading whitespace/comments
--for k, tok in pairs(leading) do
-- tokens[#tokens + 1] = tok
--end
toEmit.Line = thisLine
toEmit.Char = thisChar
toEmit.Print = function()
return "<"..(toEmit.Type..string.rep(' ', 7-#toEmit.Type)).." "..(toEmit.Data or '').." >"
toEmit.Line = thisLine
toEmit.Char = thisChar
toEmit.Print = function()
return "<"..(toEmit.Type..string.rep(' ', 7-#toEmit.Type)).." "..(toEmit.Data or '').." >"
end
tokens[#tokens+1] = toEmit
--halt after eof has been emitted
if toEmit.Type == 'Eof' then break end
end
tokens[#tokens+1] = toEmit
--halt after eof has been emitted
if toEmit.Type == 'Eof' then break end
end
end)
if not st then

35
samples/vcs1k.l65 Normal file
View File

@ -0,0 +1,35 @@
require'vcs'
#pragma syntax6502k on
TIM_OVERSCAN = 50 -- TIM64T, 3200 cycles = ~ 42 scanlines
TIM_VBLANK = 61 -- TIM64T, 3904 cycles = ~ 51 scanlines
TIM_KERNEL = 17 -- T1024T, 17408 cycles = ~229 scanlines
location(0xf000, 0xffff)
section{'vectors', org=0xfffc} dc.w start,start
local kernel = function()
ldx#0xd0 @_loop sta WSYNC stx COLUBK dex bne _loop
end
local wait = function() local l=label() lda INTIM bne l end
@@start
-- clear zeropage
cld ldx#0 txa @_clear dex tsx pha bne _clear
@main
-- overscan
WSYNC=a lda#2 VBLANK=a lda#TIM_OVERSCAN sta TIM64T wait()
-- vblank
lda#0b1110 @_vsync sta WSYNC sta VSYNC lsr bne _vsync
lda#2 sta VBLANK lda#TIM_VBLANK sta TIM64T wait() sta WSYNC sta VBLANK
-- kernel
lda#TIM_KERNEL sta T1024T kernel() wait()
jmp main
local filename=string.match(arg[0], ".-([^\\/]-)%.?[^%.\\/]*$")
writebin(filename..'.bin')
writesym(filename..'.sym')
print(stats)

View File

@ -83,3 +83,8 @@ do
local symbols = cpu.symbols
for k,v in pairs(vcs) do symbols[k] = v end
end
-- forbid globals of same key as system address constants
cpu.__newindex = function(t,k,v)
if vcs[k] then error("attempt to modify read only symbol " .. k) end
rawset(t,k,v)
end

View File

@ -1,45 +0,0 @@
dofile "vcs.lua"
TIM_OVERSCAN = 50 -- TIM64T, 3200 cycles = ~ 42 scanlines
TIM_VBLANK = 61 -- TIM64T, 3904 cycles = ~ 51 scanlines
TIM_KERNEL = 17 -- T1024T, 17408 cycles = ~229 scanlines
location(0xf000, 0xffff)
section waitForIntim
lda INTIM
bne waitForIntim
rts
-- alternate syntax
section waitForIntim
{ a=INTIM }!=
rts
section waitForIntim
repeat a=INTIM until N
@{ a=INTIM }~0
rts
-- interop: generate stubs at fixed addresses
-- stub(0xff10, waitForIntim[, altname])
-- and dumps all generated code/data into opaque data
function inca() asm("clc; adc #0") end
section "testMacro" {
lda #0
inca()
}
=>
section("testMacro")
label("testMacro")
lda{imm=0}
inca()
=>
clc()
adc{imm=0}
endsection()
require_ "6502-def"

View File

@ -1,57 +0,0 @@
dofile "vcs.lua"
TIM_OVERSCAN = 50 -- TIM64T, 3200 cycles = ~ 42 scanlines
TIM_VBLANK = 61 -- TIM64T, 3904 cycles = ~ 51 scanlines
TIM_KERNEL = 17 -- T1024T, 17408 cycles = ~229 scanlines
location(0xf000, 0xffff)
section "waitForIntim"
-- n_{ a=INTIM } ?
lda(INTIM) -- or a=INTIM
bne "waitForIntim"
rts
section "doOverscan"
sta{WSYNC} -- WSYNC=a
lda(2) sta{VBLANK} -- a=2 VBLANK=a
lda(TIM_OVERSCAN) sta{TIM64T} -- a=TIM_OVERSCAN TIM64T=a
jsr "waitForIntim"
section "doVBlank"
lda(0x0e)
label ".vsyncLoop"
sta{WSYNC}
sta{VSYNC}
lsr()
bne ".vsyncLoop"
lda(2)
sta{VBLANK}
lda(TIM_VBLANK)
sta{TIM64T}
jsr "waitForIntim"
section "doKernel"
lda(TIM_KERNEL)
sta{T1024T}
jsr "waitForIntim"
section "start"
-- clear zeropage
cld()
ldx(0)
txa()
label ".clearLoop"
dex()
tsx()
pha()
bne ".clearLoop"
-- main
label "mainLoop"
jsr "doOverscan"
jsr "doVBlank"
jsr "doKernel"
jmp "mainLoop"
section{ name="vectors", org=0xfffc }
word{ "start", "start" }