diff --git a/compiler/res/prog8lib/cx16/gfx2.p8 b/compiler/res/prog8lib/cx16/gfx2.p8 index 50185675f..760df0783 100644 --- a/compiler/res/prog8lib/cx16/gfx2.p8 +++ b/compiler/res/prog8lib/cx16/gfx2.p8 @@ -7,54 +7,7 @@ ; TODO this is in development. Add line drawing, circles and discs (like the graphics module has) - - -;main { -; -; sub start () { -; ubyte[] modes = [0, 1, 128] -; ubyte mode -; for mode in modes { -; gfx2.set_mode(mode) -; -; gfx2.position(20, 50) -; repeat 200 { -; gfx2.next_pixel(255) -; } -; -; draw() -; cx16.wait(120) -; } -; } -; -; sub draw() { -; uword offset -; ubyte angle -; uword x -; uword y -; when gfx2.active_mode { -; 0, 1 -> { -; for offset in 0 to 90 step 3 { -; for angle in 0 to 255 { -; x = $0008+sin8u(angle)/2 -; y = $0008+cos8u(angle)/2 -; gfx2.plot(x+offset*2,y+offset, lsb(x+y)) -; } -; } -; } -; 128 -> { -; for offset in 0 to 190 step 6 { -; for angle in 0 to 255 { -; x = $0008+sin8u(angle) -; y = $0008+cos8u(angle) -; gfx2.plot(x+offset*2,y+offset, 1) -; } -; } -; } -; } -; } -;} - +; TODO enable text layer too? gfx2 { @@ -64,12 +17,25 @@ gfx2 { uword height = 0 ubyte bpp = 0 - sub set_mode(ubyte mode) { + const ubyte charset_orig_bank = $0 + const uword charset_orig_addr = $f800 ; in bank 0, so $0f800 + const ubyte charset_bank = $1 + const uword charset_addr = $f000 ; in bank 1, so $1f000 + + sub screen_mode(ubyte mode) { ; mode 0 = bitmap 320 x 240 x 1c monochrome ; mode 1 = bitmap 320 x 240 x 256c ; mode 128 = bitmap 640 x 480 x 1c monochrome ; ...other modes? + ; copy the lower-case charset to the upper part of the vram, so we can use it later to plot text + cx16.screen_set_charset(3, 0) + cx16.vaddr(charset_orig_bank, charset_orig_addr, 0, 1) + cx16.vaddr(charset_bank, charset_addr, 1, 1) + repeat 256*8 { + cx16.VERA_DATA1 = cx16.VERA_DATA0 + } + when mode { 0 -> { ; 320 x 240 x 1c @@ -116,6 +82,7 @@ gfx2 { bpp = 0 } } + active_mode = mode if bpp clear_screen() @@ -170,15 +137,14 @@ gfx2 { } sub position(uword x, uword y) { - uword address when active_mode { 0 -> { - address = y*(320/8) + x/8 - cx16.vaddr(0, address, 0, 1) + cx16.r0 = y*(320/8) + x/8 + cx16.vaddr(0, cx16.r0, 0, 1) } 128 -> { - address = y*(640/8) + x/8 - cx16.vaddr(0, address, 0, 1) + cx16.r0 = y*(640/8) + x/8 + cx16.vaddr(0, cx16.r0, 0, 1) } 1 -> { void addr_mul_320_add_24(y, x) ; 24 bits result is in r0 and r1L @@ -226,6 +192,59 @@ gfx2 { }} } + sub text(uword x, uword y, ubyte color, uword sctextptr) { + ; -- Write some text at the given pixel position. + ; The text string must be in screencode encoding (not petscii!). + ; NOTE: in monochrome (1bpp) screen modes, x position is currently constrained to mulitples of 8 ! + uword chardataptr + ubyte cy + ubyte cb + when active_mode { + 0, 128 -> { + ; 1-bitplane modes + cy = 11<<4 ; auto increment 40 + if active_mode>=128 + cy = 12<<4 ; auto increment 80 + while @(sctextptr) { + chardataptr = charset_addr + (@(sctextptr) as uword)*8 + cx16.vaddr(charset_bank, chardataptr, 1, 1) + position(x,y) + cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) | cy ; enable auto increment 40 or 80 + repeat 8 { + cx16.VERA_DATA0 = cx16.VERA_DATA1 + x++ + } + sctextptr++ + } + } + 1 -> { + ; 320 x 240 x 256c + while @(sctextptr) { + chardataptr = charset_addr + (@(sctextptr) as uword)*8 + cx16.vaddr(charset_bank, chardataptr, 1, 1) + repeat 8 { + position(x,y) + y++ + %asm {{ + lda cx16.VERA_DATA1 + sta P8ZP_SCRATCH_B1 + ldy #8 +- lda #0 + asl P8ZP_SCRATCH_B1 + adc #0 + sta cx16.VERA_DATA0 + dey + bne - + }} + } + x+=8 + y-=8 + sctextptr++ + } + } + } + } + asmsub cs_innerloop640() { %asm {{ ldy #80 diff --git a/compiler/res/prog8lib/cx16/syslib.p8 b/compiler/res/prog8lib/cx16/syslib.p8 index d475d5ead..f9eab2ee5 100644 --- a/compiler/res/prog8lib/cx16/syslib.p8 +++ b/compiler/res/prog8lib/cx16/syslib.p8 @@ -268,19 +268,22 @@ asmsub vpeek(ubyte bank @A, uword address @XY) -> ubyte @A { ; -- get a byte from VERA's video memory ; note: inefficient when reading multiple sequential bytes! %asm {{ - stz cx16.VERA_CTRL + pha + lda #1 + sta cx16.VERA_CTRL + pla and #1 sta cx16.VERA_ADDR_H sty cx16.VERA_ADDR_M stx cx16.VERA_ADDR_L - lda cx16.VERA_DATA0 + lda cx16.VERA_DATA1 rts }} } -asmsub vaddr(ubyte bank @A, uword address @R0, ubyte addrsel @R1, byte incrdecr @Y) { - ; -- setup the VERA's address register 0 or 1 +asmsub vaddr(ubyte bank @A, uword address @R0, ubyte addrsel @R1, byte autoIncrOrDecrByOne @Y) { + ; -- setup the VERA's data address register 0 or 1 %asm {{ and #1 pha diff --git a/examples/cx16/imageviewer/imageviewer.p8 b/examples/cx16/imageviewer/imageviewer.p8 index 87f2f07ed..dab1a5336 100644 --- a/examples/cx16/imageviewer/imageviewer.p8 +++ b/examples/cx16/imageviewer/imageviewer.p8 @@ -17,7 +17,7 @@ main { if strlen(diskio.status(8)) { txt.print("enter image file name or just enter for all on disk: ") ubyte i = txt.input_chars(diskio.filename) - gfx2.set_mode(1) ; 320*240, 256c + gfx2.screen_mode(1) ; 320*240, 256c if i attempt_load(diskio.filename) else @@ -28,7 +28,7 @@ main { else txt.print("files are read with sequential file loading.\nin the emulator this currently only works with files on an sd-card image.\nsorry :(\n") - gfx2.set_mode(255) ; back to default text mode and palette + gfx2.screen_mode(255) ; back to default text mode and palette txt.print("that was all folks!\n") } @@ -109,7 +109,7 @@ main { } sub load_error(uword filenameptr) { - gfx2.set_mode(255) ; back to default text mode and palette + gfx2.screen_mode(255) ; back to default text mode and palette txt.print(filenameptr) txt.print(": load error\n") exit(1) diff --git a/examples/cx16/testgfx2.p8 b/examples/cx16/testgfx2.p8 index 0208d1d41..d2f2f8a53 100644 --- a/examples/cx16/testgfx2.p8 +++ b/examples/cx16/testgfx2.p8 @@ -6,14 +6,18 @@ main { sub start () { - ubyte[] modes = [0, 1, 128] + ubyte[] modes = [128, 0, 1] ubyte mode for mode in modes { - gfx2.set_mode(mode) + gfx2.screen_mode(mode) draw() + ubyte tp + for tp in 0 to 15 { + gfx2.text(19+tp,20+tp*11, 5, @"ScreenCODE text! 1234![]<>#$%&*()") + } cx16.wait(120) } - gfx2.set_mode(255) + gfx2.screen_mode(255) txt.print("done!\n") } diff --git a/examples/test.p8 b/examples/test.p8 index 49f4a7430..4b7ca6611 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,11 +1,23 @@ %import test_stack +%import gfx2 %zeropage basicsafe %option no_sysinit main { + sub start () { + ;gfx2.screen_mode(0) + gfx2.screen_mode(255) + + uword address + for address in gfx2.charset_addr to gfx2.charset_addr+4*8-1 { + txt.print_ubbin(cx16.vpeek(gfx2.charset_bank, address),0) + txt.chrout('\n') + } + test_stack.test() } + }