diff --git a/.travis.yml b/.travis.yml index 2eed917..99efc26 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,9 +9,11 @@ script: - cmake . -DCMAKE_BUILD_TYPE=Release - make - cd samples - - ../l65 vcs0.l65 - - ../l65 vcs1.l65 + - ../l65 vcs_banks.l65 + - ../l65 vcs_basic.l65 + - ../l65 vcs_flush.l65 - ../l65 vcs_hello.l65 + - ../l65 vcs_hooks.l65 - cd .. deploy: provider: releases diff --git a/6502.lua b/6502.lua index a7a7a75..c0923c5 100644 --- a/6502.lua +++ b/6502.lua @@ -480,7 +480,7 @@ M.section = function(t) end for _,constraint in ipairs(self.constraints) do constraint.start = instructions[constraint.from].offset - constraint.finish = instructions[constraint.to].offset + constraint.finish = constraint.to==#instructions and self.size or instructions[constraint.to+1].offset end end return section diff --git a/samples/flush.png b/samples/flush.png new file mode 100644 index 0000000..27f3a7b Binary files /dev/null and b/samples/flush.png differ diff --git a/samples/flushbg.png b/samples/flushbg.png new file mode 100644 index 0000000..fd4e332 Binary files /dev/null and b/samples/flushbg.png differ diff --git a/samples/vcs1k.l65 b/samples/vcs1k.l65 deleted file mode 100644 index 715a671..0000000 --- a/samples/vcs1k.l65 +++ /dev/null @@ -1,35 +0,0 @@ -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) diff --git a/samples/vcs2.l65 b/samples/vcs2.l65 deleted file mode 100644 index 9f1fad8..0000000 --- a/samples/vcs2.l65 +++ /dev/null @@ -1,31 +0,0 @@ -require'vcs' -#pragma encapsulate far farcall -#pragma encapsulate xsr xcall -#pragma add_opcode rtx imp - -mappers.jmpfar=true -mappers.F4() -local bank_core,bank_fx = rom0,rom1 - -location(bank_core) -@@main - init() -@_frame - overscan() vblank() screen_begin() - far kernel - sta WSYNC lda#0xaa sta COLUBK for i=1,10 do sta WSYNC end - xsr kernel2 - --lda#kernel2&0xff sta 0x8a lda#kernel2>>8 sta 0x8b jsr jmpfar - screen_end() - jmp _frame - -location(bank_fx) -@@kernel - ldx#0x50 @_loop sta WSYNC stx COLUBK dex bne _loop rts -@@kernel2 - ldx#0x50 @_loop sta WSYNC stx COLUBK dex bne _loop rtx --jmp rtsfar - -; -writebin(filename..'.bin') -writesym(filename..'.sym') -print(stats) diff --git a/samples/vcs_banks.l65 b/samples/vcs_banks.l65 new file mode 100644 index 0000000..d758dae --- /dev/null +++ b/samples/vcs_banks.l65 @@ -0,0 +1,43 @@ +require'vcs' -- import vcs.l65 +-- translate 'far x' to 'farcall(function() return x end)', farcall is defined in vcs.l65 +#pragma encapsulate far farcall +-- translate 'xsr x' to 'xcall(function() return x end)', xcall is defined in vcs.l65 +#pragma encapsulate xsr xcall +-- translate 'rtx' to 'rtximp()', rtximp is defined in vcs.l65 +#pragma add_opcode rtx imp + +-- enable generation of cross banks code sections using xsr/rtx method (3 MSB of address = bank index) +mappers.jmpfar=true +mappers.F8() -- use F8 (2 * 4Kb) bank mapper +local bank_core,bank_fx = rom0,rom1 -- bank name aliases + +-- main bank content +location(bank_core) +@@main + init() +@_frame + overscan() vblank() screen_begin() + -- call section 'kernel' in bank_fx using per-function generated stubs + far kernel + -- make a separation + sta WSYNC lda#0xaa sta COLUBK for i=1,10 do sta WSYNC end + -- call section 'kernel2' in bank_fx using shared stub with bank index in 3 MSB of address + xsr kernel2 + screen_end() + jmp _frame + +-- secondary bank content +location(bank_fx) +-- regular function, can be called inside the same bank with a jsr or from +-- another bank using automatic stubs generation for caller/callee pair +@@kernel + ldx#0x50 @_loop sta WSYNC stx COLUBK dex bne _loop rts +-- function only callable using xsr method, from any bank without additional +-- stub generation, but higher cycle count overhead +@@kernel2 + ldx#0x50 @_loop sta WSYNC stx COLUBK dex bne _loop rtx -- note the 'rtx' instead of 'rts'! + +; +writebin(filename..'.bin') +writesym(filename..'.sym') +print(stats) diff --git a/samples/vcs0.l65 b/samples/vcs_basic.l65 similarity index 100% rename from samples/vcs0.l65 rename to samples/vcs_basic.l65 diff --git a/samples/vcs_flush.l65 b/samples/vcs_flush.l65 new file mode 100644 index 0000000..a985b2e --- /dev/null +++ b/samples/vcs_flush.l65 @@ -0,0 +1,113 @@ +require'vcs' +mappers['4K']() + +local HEADER_LEN = 92 +local PICTURE_LEN = 64 +local STEP_COUNT = 32 + +-- FLUSH text as playfield +local logo_img = assert(l65.image("flush.png")) -- analyse the image twice, so load it separately +@@logo_col samepage byte(0x00, 0xd4, 0x72, linecol(logo_img)) end +local pfs = playfield(logo_img) +for i=1,#pfs do + local pf = pfs[i] + section("logo_pf"..(i-1)) samepage byte(0, pf[1], pf[#pf], pf) end +end +local LOGO_HEIGHT = #pfs[1] + +-- background +local bg = linecol("flushbg.png") +@@logo_bg_all +samepage + @logo_bg_pre for i=1,8 do dc.b bg[1] end + @logo_bg + for i=1,13 do dc.b bg[1] end + byte(bg) + for i=1,13 do dc.b bg[#bg] end + @logo_bg_post for i=1,8 do dc.b bg[#bg] end +end + +-- generate offset tables into logo_pf* +do + local DISP_HEIGHT = PICTURE_LEN + local transfo,bgshift = {},{} + for x=0,STEP_COUNT-1 do + local theta = x/(STEP_COUNT-1) * math.pi/2 - math.pi/4 + local s,c = math.sin(theta),math.cos(theta) + local ra,rb,rc,rd = -c, s-c, s+c, c + for y=0,DISP_HEIGHT-1 do + local r = DISP_HEIGHT / LOGO_HEIGHT + local yn = r * (2 * y/(DISP_HEIGHT-1) - 1) + local function f() + local y = (s-yn) / c + return math.min(math.floor((y+1)/2*LOGO_HEIGHT), LOGO_HEIGHT-1) + 3 + end + local v + if rd < rc then v = yn>rc and 0 or yn>rb and f(yn) or yn>ra and 2 or 0 + else v = yn>rd and 0 or yn>rc and 1 or yn>rb and f(yn) or 0 end + transfo[x*DISP_HEIGHT+DISP_HEIGHT-y] = v + end + bgshift[#bgshift+1] = math.floor(math.sin(math.pi+theta)*LOGO_HEIGHT/4) + end + @@logo_transfo byte(transfo) + @@logo_bgshift byte(bgshift) +end + +-- rotation anim +do + local PERIOD = 128 + local f = \x((math.sin(x*2*math.pi/PERIOD)+1)/2 * (STEP_COUNT-1)) + local rotation = {} + for x=1,128 do + rotation[#rotation+1] = math.floor(math.min(f(x-1), (STEP_COUNT-1))) + end + @@logo_rotation byte(rotation) +end + +local bg_ptr = 0x80 +local trans_ptr = 0x82 +local time = 0x84 +local tmp = 0x85 + +local on_vblank = function() + inc time asl time lsr time + ldy time lda logo_rotation,y sta tmp + + ldy tmp lda logo_bgshift,y sta bg_ptr + lda#logo_bg&0xff clc adc bg_ptr sta bg_ptr lda#logo_bg>>8 sta bg_ptr+1 + + setptr(logo_transfo, trans_ptr) + lda tmp asl asl asl asl asl asl clc adc trans_ptr sta trans_ptr + lda trans_ptr+1 adc#0 sta trans_ptr+1 + lda tmp lsr lsr clc adc trans_ptr+1 sta trans_ptr+1 + + ldy#PICTURE_LEN-1 lda (bg_ptr),y sta COLUBK +end + +local kernel = function() + ldy#HEADER_LEN @_header sta WSYNC dey bne _header + samepage @_line + lda (trans_ptr),y tax + lda (bg_ptr),y + sta WSYNC sta COLUBK + lda logo_col,x sta COLUPF + lda logo_pf0,x sta PF0 + lda logo_pf1,x sta PF1 + lda logo_pf2,x sta PF2 + lda logo_pf3,x sta PF0 + lda logo_pf4,x sta PF1 + lda logo_pf5,x sta PF2 + iny cpy#PICTURE_LEN bne _line + end + lda#0 sta WSYNC sta PF0 sta PF1 sta PF2 +end + +@@main + init() +@_frame + overscan() vblank(on_vblank) screen(kernel) jmp _frame + +; +writebin(filename..'.bin') +writesym(filename..'.sym') +print(stats) diff --git a/samples/vcs1.l65 b/samples/vcs_hooks.l65 similarity index 100% rename from samples/vcs1.l65 rename to samples/vcs_hooks.l65 diff --git a/samples/vcspal.act b/samples/vcspal.act new file mode 100644 index 0000000..2acbddc Binary files /dev/null and b/samples/vcspal.act differ diff --git a/vcs.l65 b/vcs.l65 index caedee6..f2436e4 100644 --- a/vcs.l65 +++ b/vcs.l65 @@ -386,7 +386,7 @@ image_scan = function(img, opt) assert(y1>=y0 and x1>=x0 and x1 w and w-1 or o+7 local i,color = 7,0 for x=o,e do - if b[y*w+x] ~= 0 then color = color | 1</ syn match l65Opcode /\/ syn match l65Opcode /\/ +" These are only if defined by user for VCS cross bank calls. +" Remove these lines if desired. syn match l65Opcode /\/ +syn match l65Opcode /\/ +syn match l65Opcode /\/ " Define the default highlighting. " For version 5.7 and earlier: only when not done already