added gfx2.text_charset()

This commit is contained in:
Irmen de Jong 2020-12-26 03:10:53 +01:00
parent ab495fe6e1
commit c62ff16f8b
3 changed files with 77 additions and 40 deletions

View File

@ -2,12 +2,11 @@
; Bitmap pixel graphics module for the CommanderX16 ; Bitmap pixel graphics module for the CommanderX16
; Custom routines to use the full-screen 640x480 and 320x240 screen modes. ; Custom routines to use the full-screen 640x480 and 320x240 screen modes.
; This is only compatible with the Cx16. ; This only works on the Cx16. No text layer is currently shown, text can be drawn as part of the bitmap itself.
; For compatible graphics code that words on C64 too, use the "graphics" module instead. ; Note: for compatible graphics code that words on C64 too, use the "graphics" module instead.
; TODO this is in development. Add line drawing, circles and discs (like the graphics module has) ; TODO this is in development. Add line drawing, circles and discs (like the graphics module has)
; TODO enable text layer too?
gfx2 { gfx2 {
@ -17,11 +16,6 @@ gfx2 {
uword height = 0 uword height = 0
ubyte bpp = 0 ubyte bpp = 0
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) { sub screen_mode(ubyte mode) {
; mode 0 = bitmap 320 x 240 x 1c monochrome ; mode 0 = bitmap 320 x 240 x 1c monochrome
; mode 1 = bitmap 320 x 240 x 256c ; mode 1 = bitmap 320 x 240 x 256c
@ -29,12 +23,6 @@ gfx2 {
; ...other modes? ; ...other modes?
; copy the lower-case charset to the upper part of the vram, so we can use it later to plot text ; 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 { when mode {
0 -> { 0 -> {
@ -127,13 +115,12 @@ gfx2 {
} }
1 -> { 1 -> {
void addr_mul_320_add_24(y, x) ; 24 bits result is in r0 and r1L void addr_mul_320_add_24(y, x) ; 24 bits result is in r0 and r1L
ubyte bank = lsb(cx16.r1) value = lsb(cx16.r1)
cx16.vpoke(bank, cx16.r0, color) cx16.vpoke(value, cx16.r0, color)
} }
} }
; activate vera auto-increment mode so next_pixel() can be used after this ; activate vera auto-increment mode so next_pixel() can be used after this
cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) | %00010000 cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) | %00010000
return
} }
sub position(uword x, uword y) { sub position(uword x, uword y) {
@ -164,6 +151,8 @@ gfx2 {
} }
sub next_pixels(uword pixels, uword amount) { sub next_pixels(uword pixels, uword amount) {
; -- sets the next bunch of pixels from a prepared array of bytes.
; for 8 bpp screens this will plot 1 pixel per byte, but for 1 bpp screens the bytes contain 8 pixels each.
repeat msb(amount) { repeat msb(amount) {
repeat 256 { repeat 256 {
cx16.VERA_DATA0 = @(pixels) cx16.VERA_DATA0 = @(pixels)
@ -177,6 +166,7 @@ gfx2 {
} }
asmsub set_8_pixels_from_bits(ubyte bits @R0, ubyte oncolor @A, ubyte offcolor @Y) { asmsub set_8_pixels_from_bits(ubyte bits @R0, ubyte oncolor @A, ubyte offcolor @Y) {
; this is only useful in 256 color mode where one pixel equals one byte value.
%asm {{ %asm {{
phx phx
ldx #8 ldx #8
@ -192,28 +182,63 @@ gfx2 {
}} }}
} }
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 text_charset(ubyte charset) {
; -- make a copy of the selected character set to use with text()
; the charset number is the same as for the cx16.screen_set_charset() ROM function.
; 1 = ISO charset, 2 = PETSCII uppercase+graphs, 3= PETSCII uppercase+lowercase.
cx16.screen_set_charset(charset, 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
}
}
sub text(uword x, uword y, ubyte color, uword sctextptr) { sub text(uword x, uword y, ubyte color, uword sctextptr) {
; -- Write some text at the given pixel position. ; -- Write some text at the given pixel position. The text string must be in screencode encoding (not petscii!).
; The text string must be in screencode encoding (not petscii!). ; You must also have called text_charset() first to select and prepare the character set to use.
; NOTE: in monochrome (1bpp) screen modes, x position is currently constrained to mulitples of 8 ! ; NOTE: in monochrome (1bpp) screen modes, x position is currently constrained to mulitples of 8 !
uword chardataptr uword chardataptr
ubyte cy ubyte cy222 ; TODO why not removed by compiler???
ubyte cb ubyte cb222 ; TODO why not removed by compiler???
when active_mode { when active_mode {
0, 128 -> { 0, 128 -> {
; 1-bitplane modes ; 1-bitplane modes
cy = 11<<4 ; auto increment 40 cx16.r2 = 40
if active_mode>=128 if active_mode>=128
cy = 12<<4 ; auto increment 80 cx16.r2 = 80
while @(sctextptr) { while @(sctextptr) {
chardataptr = charset_addr + (@(sctextptr) as uword)*8 chardataptr = charset_addr + (@(sctextptr) as uword)*8
cx16.vaddr(charset_bank, chardataptr, 1, 1) cx16.vaddr(charset_bank, chardataptr, 1, 1)
position(x,y) position(x,y)
cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) | cy ; enable auto increment 40 or 80 %asm {{
repeat 8 { lda cx16.VERA_ADDR_H
cx16.VERA_DATA0 = cx16.VERA_DATA1 and #%111 ; don't auto-increment, we have to do that manually because of the ora
x++ sta cx16.VERA_ADDR_H
} ldy #8
- lda cx16.VERA_DATA0
ora cx16.VERA_DATA1
sta cx16.VERA_DATA0
lda cx16.VERA_ADDR_L
clc
adc cx16.r2
sta cx16.VERA_ADDR_L
bcc +
inc cx16.VERA_ADDR_M
+ lda x
clc
adc #1
sta x
bcc +
inc x+1
+ dey
bne -
}}
sctextptr++ sctextptr++
} }
} }
@ -226,15 +251,19 @@ gfx2 {
position(x,y) position(x,y)
y++ y++
%asm {{ %asm {{
phx
ldx #1
lda cx16.VERA_DATA1 lda cx16.VERA_DATA1
sta P8ZP_SCRATCH_B1 sta P8ZP_SCRATCH_B1
ldy #8 ldy #8
- lda #0 - asl P8ZP_SCRATCH_B1
asl P8ZP_SCRATCH_B1 bcc +
adc #0 stx cx16.VERA_DATA0 ; write a pixel
sta cx16.VERA_DATA0 bra ++
dey + lda cx16.VERA_DATA0 ; don't write a pixel, but do advance to the next address
+ dey
bne - bne -
plx
}} }}
} }
x+=8 x+=8

View File

@ -6,7 +6,9 @@
main { main {
sub start () { sub start () {
ubyte[] modes = [128, 0, 1] gfx2.text_charset(3)
ubyte[] modes = [0, 1, 128]
ubyte mode ubyte mode
for mode in modes { for mode in modes {
gfx2.screen_mode(mode) gfx2.screen_mode(mode)

View File

@ -8,13 +8,19 @@ main {
sub start () { sub start () {
;gfx2.screen_mode(0) void cx16.screen_set_mode($80)
gfx2.screen_mode(255) cx16.GRAPH_init(0)
cx16.GRAPH_set_colors(13, 6, 6)
cx16.GRAPH_clear()
uword address uword cp
for address in gfx2.charset_addr to gfx2.charset_addr+4*8-1 {
txt.print_ubbin(cx16.vpeek(gfx2.charset_bank, address),0) for cp in 0 to 15 {
txt.chrout('\n') cx16.r0 = 10+cp*2
cx16.r1 = 10+cp*11
ubyte cc
for cc in "Hello world, 123456789<>-=!#$%"
cx16.GRAPH_put_next_char(cc)
} }
test_stack.test() test_stack.test()