diff --git a/compiler/res/prog8lib/c64/syslib.p8 b/compiler/res/prog8lib/c64/syslib.p8 index da7358b8c..ba58ef10d 100644 --- a/compiler/res/prog8lib/c64/syslib.p8 +++ b/compiler/res/prog8lib/c64/syslib.p8 @@ -500,11 +500,9 @@ sys { ; --- busy wait till the next vsync has occurred (approximately), without depending on custom irq handling. ; note: a more accurate way to wait for vsync is to set up a vsync irq handler instead. %asm {{ -- lda c64.RASTER - beq - -- lda c64.RASTER - bne - - bit c64.SCROLY +- bit c64.SCROLY + bpl - +- bit c64.SCROLY bmi - rts }} diff --git a/examples/cx16/colorbars.p8 b/examples/cx16/colorbars.p8 index 2c7fca9a3..7bd6dd501 100644 --- a/examples/cx16/colorbars.p8 +++ b/examples/cx16/colorbars.p8 @@ -1,36 +1,117 @@ -%import gfx2 -%import palette +%import textio - -; TODO WORK IN PROGRESS... -; want to make Amiga 'copper' bars color cycling effects +; Amiga 'copper' bars color cycling effect main { sub start() { - ;palette.set_all_black() - gfx2.screen_mode(4) + ; make palette color 1 black so we can print black letters over the background color 0 + void cx16.screen_set_mode(0) + cx16.vpoke(1, $fa02, $0) + cx16.vpoke(1, $fa03, $0) + txt.color(1) + txt.plot(13,12) + txt.print("amiga-inspired") + txt.plot(10,14) + txt.print("raster blinds effect") + txt.plot(12,16) + txt.print("random gradients") - ubyte yy - for yy in 0 to 239 - gfx2.horizontal_line(0, yy, 320, yy) + irq.make_new_gradient() + cx16.set_rasterirq(&irq.irqhandler, irq.top_scanline) repeat { - yy = 0 - repeat 8 { - colors.random_half_bar() - colors.mirror_bar() - colors.set_palette(yy) - yy+=32 - } - - repeat 10 - sys.waitvsync() } } } +irq { + const ubyte top_scanline = 0 + ubyte blinds_start_ix = 0 + ubyte color_ix = 0 + uword next_irq_line = top_scanline + ubyte shift_counter = 0 + + ubyte[32+32+16] blinds_lines_reds + ubyte[32+32+16] blinds_lines_greens + ubyte[32+32+16] blinds_lines_blues + + + sub irqhandler() { + set_scanline_color(color_ix) + color_ix++ + + next_irq_line += 2 ; code needs 2 scanlines per color transition + + if next_irq_line == 480 { + ; start over at top + next_irq_line = top_scanline + blinds_start_ix = 0 + color_ix = 0 + shift_counter++ + if shift_counter == 32+32+32 { + make_new_gradient() + shift_counter = 0 + } else if shift_counter & 1 { + shift_gradient() + } + } else if next_irq_line & 15 == 0 { + ; start next blinds + blinds_start_ix++ + color_ix = blinds_start_ix + } + + + + cx16.set_rasterline(next_irq_line) + } + + sub make_new_gradient() { + colors.random_half_bar() + colors.mirror_bar() + sys.memcopy(colors.reds, &blinds_lines_reds+32+16, len(colors.reds)) + sys.memcopy(colors.greens, &blinds_lines_greens+32+16, len(colors.greens)) + sys.memcopy(colors.blues, &blinds_lines_blues+32+16, len(colors.blues)) + } + + sub shift_gradient() { + sys.memcopy(&blinds_lines_reds+1, blinds_lines_reds, len(blinds_lines_reds)-1) + sys.memcopy(&blinds_lines_greens+1, blinds_lines_greens, len(blinds_lines_greens)-1) + sys.memcopy(&blinds_lines_blues+1, blinds_lines_blues, len(blinds_lines_blues)-1) + } + + asmsub set_scanline_color(ubyte color_ix @Y) { + ; uword color = mkword(reds[ix], (greens[ix] << 4) | blues[ix] ) + %asm {{ + lda blinds_lines_reds,y + pha + lda blinds_lines_greens,y + asl a + asl a + asl a + asl a + ora blinds_lines_blues,y + tay + + stz cx16.VERA_CTRL + lda #%00010001 + sta cx16.VERA_ADDR_H + lda #$fa + sta cx16.VERA_ADDR_M + ; lda #$02 + ; sta cx16.VERA_ADDR_L + stz cx16.VERA_ADDR_L + sty cx16.VERA_DATA0 ; gb + pla + sta cx16.VERA_DATA0 ; r + stz cx16.VERA_ADDR_H + rts + }} + } +} + + colors { ubyte target_red ubyte target_green @@ -106,12 +187,4 @@ colors { } } } - - sub set_palette(ubyte offset) { - ubyte ix - for ix in 0 to 31 { - uword color = mkword(reds[ix], (greens[ix] << 4) | blues[ix] ) - palette.set_color(ix+offset, color) - } - } }