cx16: removed monochrome modes from gfx2 (use monogfx instead). New screen mode numbering!

programs will now be a lot smaller than before if they use gfx2 (or monogfx if they were only using monochrome drawing)
monogfx also fixes some drawing errors with small horizontal lines, and stippled vertical lines.
This commit is contained in:
Irmen de Jong 2023-10-04 23:01:00 +02:00
parent 6395d1908e
commit ee81da14d6
9 changed files with 207 additions and 700 deletions

View File

@ -4,6 +4,7 @@
; ;
; No text layer is currently shown, text can be drawn as part of the bitmap itself. ; No text layer is currently shown, text can be drawn as part of the bitmap itself.
; Note: for similar graphics routines that also work on the C-64, use the "graphics" module instead. ; Note: for similar graphics routines that also work on the C-64, use the "graphics" module instead.
; Note: for identical routines for a monochrome 1 bpp screen, use the "monogfx" module instead.
; Note: for color palette manipulation, use the "palette" module or write Vera registers yourself. ; Note: for color palette manipulation, use the "palette" module or write Vera registers yourself.
; Note: this library implements code for various resolutions and color depths. This takes up memory. ; Note: this library implements code for various resolutions and color depths. This takes up memory.
; If you're memory constrained you should probably not use this built-in library, ; If you're memory constrained you should probably not use this built-in library,
@ -12,12 +13,10 @@
; ;
; SCREEN MODE LIST: ; SCREEN MODE LIST:
; mode 0 = reset back to default text mode ; mode 0 = reset back to default text mode
; mode 1 = bitmap 320 x 240 monochrome ; mode 1 = bitmap 320 x 240 x 256c (8 bpp)
; mode 2 = bitmap 320 x 240 x 4c (not yet implemented: just use 256c, there's enough vram for that) ; mode 2 = bitmap 640 x 480 x 4c (2 bpp. there's not enough vram for more colors in hires mode.)
; mode 3 = bitmap 320 x 240 x 16c (not yet implemented: just use 256c, there's enough vram for that) ; mode 3 = bitmap 320 x 240 x 16c (not yet implemented: just use 256c, there's enough vram for that)
; mode 4 = bitmap 320 x 240 x 256c (like SCREEN $80 but using this api instead of kernal) ; mode 4 = bitmap 320 x 240 x 4c (not yet implemented: just use 256c, there's enough vram for that)
; mode 5 = bitmap 640 x 480 monochrome
; mode 6 = bitmap 640 x 480 x 4c
; higher color dephts in highres are not supported due to lack of VRAM ; higher color dephts in highres are not supported due to lack of VRAM
gfx2 { gfx2 {
@ -29,25 +28,11 @@ gfx2 {
uword width = 0 uword width = 0
uword height = 0 uword height = 0
ubyte bpp = 0 ubyte bpp = 0
bool monochrome_dont_stipple_flag = true ; set to false to enable stippling mode in monochrome displaymodes
sub screen_mode(ubyte mode) { sub screen_mode(ubyte mode) {
cx16.VERA_CTRL=0 cx16.VERA_CTRL=0
when mode { when mode {
1 -> { 1 -> {
; lores monochrome
cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11001111) | %00100000 ; enable only layer 1
cx16.VERA_DC_HSCALE = 64
cx16.VERA_DC_VSCALE = 64
cx16.VERA_L1_CONFIG = %00000100
cx16.VERA_L1_MAPBASE = 0
cx16.VERA_L1_TILEBASE = 0
width = 320
height = 240
bpp = 1
}
; TODO modes 2, 3
4 -> {
; lores 256c ; lores 256c
cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11001111) | %00100000 ; enable only layer 1 cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11001111) | %00100000 ; enable only layer 1
cx16.VERA_DC_HSCALE = 64 cx16.VERA_DC_HSCALE = 64
@ -59,19 +44,7 @@ gfx2 {
height = 240 height = 240
bpp = 8 bpp = 8
} }
5 -> { 2 -> {
; highres monochrome
cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11001111) | %00100000 ; enable only layer 1
cx16.VERA_DC_HSCALE = 128
cx16.VERA_DC_VSCALE = 128
cx16.VERA_L1_CONFIG = %00000100
cx16.VERA_L1_MAPBASE = 0
cx16.VERA_L1_TILEBASE = %00000001
width = 640
height = 480
bpp = 1
}
6 -> {
; highres 4c ; highres 4c
cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11001111) | %00100000 ; enable only layer 1 cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11001111) | %00100000 ; enable only layer 1
cx16.VERA_DC_HSCALE = 128 cx16.VERA_DC_HSCALE = 128
@ -101,39 +74,22 @@ gfx2 {
} }
sub clear_screen() { sub clear_screen() {
monochrome_stipple(false)
position(0, 0) position(0, 0)
when active_mode { when active_mode {
1 -> { 1 -> {
; lores monochrome
repeat 240/2/8
cs_innerloop640()
}
; TODO modes 2, 3
4 -> {
; lores 256c ; lores 256c
repeat 240/2 repeat 240/2
cs_innerloop640() cs_innerloop640()
} }
5 -> { 2 -> {
; highres monochrome
repeat 480/8
cs_innerloop640()
}
6 -> {
; highres 4c ; highres 4c
repeat 480/4 repeat 480/4
cs_innerloop640() cs_innerloop640()
} }
; modes 7 and 8 not supported due to lack of VRAM
} }
position(0, 0) position(0, 0)
} }
sub monochrome_stipple(bool enable) {
monochrome_dont_stipple_flag = not enable
}
sub rect(uword xx, uword yy, uword rwidth, uword rheight, ubyte color) { sub rect(uword xx, uword yy, uword rwidth, uword rheight, ubyte color) {
if rwidth==0 or rheight==0 if rwidth==0 or rheight==0
return return
@ -157,87 +113,10 @@ gfx2 {
} }
sub horizontal_line(uword xx, uword yy, uword length, ubyte color) { sub horizontal_line(uword xx, uword yy, uword length, ubyte color) {
ubyte[9] masked_starts = [ 0, %00000001, %00000011, %00000111, %00001111, %00011111, %00111111, %01111111, %11111111]
ubyte[9] masked_ends = [ 0, %10000000, %11000000, %11100000, %11110000, %11111000, %11111100, %11111110, %11111111]
if length==0 if length==0
return return
when active_mode { when active_mode {
1, 5 -> { 1 -> {
; monochrome modes, either resolution
ubyte separate_pixels = (8-lsb(xx)) & 7
if separate_pixels as uword > length
separate_pixels = lsb(length)
if separate_pixels {
if monochrome_dont_stipple_flag {
position(xx,yy)
cx16.VERA_ADDR_H &= %00000111 ; vera auto-increment off
if color
cx16.VERA_DATA0 |= masked_starts[separate_pixels]
else
cx16.VERA_DATA0 &= ~masked_starts[separate_pixels]
xx += separate_pixels
} else {
repeat separate_pixels {
plot(xx, yy, color)
xx++
}
}
length -= separate_pixels
}
if length {
position(xx, yy)
separate_pixels = lsb(length) & 7
xx += length & $fff8
%asm {{
lsr length+1
ror length
lsr length+1
ror length
lsr length+1
ror length
lda color
bne +
ldy #0 ; black
bra _loop
+ lda monochrome_dont_stipple_flag
beq _stipple
ldy #255 ; don't stipple
bra _loop
_stipple lda yy
and #1 ; determine stipple pattern to use
bne +
ldy #%01010101
bra _loop
+ ldy #%10101010
_loop lda length
ora length+1
beq _done
sty cx16.VERA_DATA0
lda length
bne +
dec length+1
+ dec length
bra _loop
_done
}}
if monochrome_dont_stipple_flag {
cx16.VERA_ADDR_H &= %00000111 ; vera auto-increment off
if color
cx16.VERA_DATA0 |= masked_ends[separate_pixels]
else
cx16.VERA_DATA0 &= ~masked_ends[separate_pixels]
} else {
repeat separate_pixels {
plot(xx, yy, color)
xx++
}
}
}
cx16.VERA_ADDR_H &= %00000111 ; vera auto-increment off again
}
4 -> {
; lores 256c ; lores 256c
position(xx, yy) position(xx, yy)
%asm {{ %asm {{
@ -258,8 +137,8 @@ _done
+ +
}} }}
} }
6 -> { 2 -> {
; highres 4c ....also mostly usable for mode 2, lores 4c? ; highres 4c ....also mostly usable for lores 4c?
color &= 3 color &= 3
ubyte[4] colorbits ubyte[4] colorbits
ubyte ii ubyte ii
@ -308,60 +187,7 @@ _done
sub vertical_line(uword xx, uword yy, uword lheight, ubyte color) { sub vertical_line(uword xx, uword yy, uword lheight, ubyte color) {
when active_mode { when active_mode {
1, 5 -> { 1 -> {
; monochrome, lo-res
cx16.r15L = gfx2.plot.maskbits[xx as ubyte & 7] ; bitmask
if color {
if monochrome_dont_stipple_flag {
; draw continuous line.
position2(xx,yy,true)
if active_mode==1
set_both_strides(11) ; 40 increment = 1 line in 320 px monochrome
else
set_both_strides(12) ; 80 increment = 1 line in 640 px monochrome
repeat lheight {
%asm {{
lda cx16.VERA_DATA0
ora cx16.r15L
sta cx16.VERA_DATA1
}}
}
} else {
; draw stippled line.
if xx&1 {
yy++
lheight--
}
position2(xx,yy,true)
if active_mode==1
set_both_strides(12) ; 80 increment = 2 line in 320 px monochrome
else
set_both_strides(13) ; 160 increment = 2 line in 640 px monochrome
repeat lheight/2 {
%asm {{
lda cx16.VERA_DATA0
ora cx16.r15L
sta cx16.VERA_DATA1
}}
}
}
} else {
position2(xx,yy,true)
cx16.r15 = ~cx16.r15 ; erase pixels
if active_mode==1
set_both_strides(11) ; 40 increment = 1 line in 320 px monochrome
else
set_both_strides(12) ; 80 increment = 1 line in 640 px monochrome
repeat lheight {
%asm {{
lda cx16.VERA_DATA0
and cx16.r15L
sta cx16.VERA_DATA1
}}
}
}
}
4 -> {
; lores 256c ; lores 256c
; set vera auto-increment to 320 pixel increment (=next line) ; set vera auto-increment to 320 pixel increment (=next line)
position(xx,yy) position(xx,yy)
@ -376,7 +202,7 @@ _done
+ +
}} }}
} }
6 -> { 2 -> {
; highres 4c ; highres 4c
; use TWO vera adress pointers simultaneously one for reading, one for writing, so auto-increment is possible ; use TWO vera adress pointers simultaneously one for reading, one for writing, so auto-increment is possible
if lheight==0 if lheight==0
@ -571,7 +397,6 @@ _done
} }
sub plot(uword @zp xx, uword @zp yy, ubyte @zp color) { sub plot(uword @zp xx, uword @zp yy, ubyte @zp color) {
ubyte[8] @shared maskbits = [128, 64, 32, 16, 8, 4, 2, 1]
ubyte[4] @shared mask4c = [%00111111, %11001111, %11110011, %11111100] ubyte[4] @shared mask4c = [%00111111, %11001111, %11110011, %11111100]
ubyte[4] @shared shift4c = [6,4,2,0] ubyte[4] @shared shift4c = [6,4,2,0]
ubyte[4] shiftedleft_4c_1 = [1<<6, 1<<4, 1<<2, 1<<0] ubyte[4] shiftedleft_4c_1 = [1<<6, 1<<4, 1<<2, 1<<0]
@ -580,31 +405,6 @@ _done
when active_mode { when active_mode {
1 -> { 1 -> {
; lores monochrome
if color {
; solid color or perhaps stipple
%asm {{
lda xx
eor yy
ora monochrome_dont_stipple_flag
and #1
}}
if_nz {
mode_1_prepare()
%asm {{
tsb cx16.VERA_DATA0
}}
}
} else {
; only erase
mode_1_prepare()
%asm {{
trb cx16.VERA_DATA0
}}
}
}
; TODO modes 2, 3
4 -> {
; lores 256c ; lores 256c
void addr_mul_24_for_lores_256c(yy, xx) ; 24 bits result is in r0 and r1L (highest byte) void addr_mul_24_for_lores_256c(yy, xx) ; 24 bits result is in r0 and r1L (highest byte)
%asm {{ %asm {{
@ -620,32 +420,8 @@ _done
sta cx16.VERA_DATA0 sta cx16.VERA_DATA0
}} }}
} }
5 -> { 2 -> {
; highres monochrome ; highres 4c ....also mostly usable for lores 4c?
if color {
; solid color or perhaps stipple
%asm {{
lda xx
eor yy
ora monochrome_dont_stipple_flag
and #1
}}
if_nz {
mode_5_prepare()
%asm {{
tsb cx16.VERA_DATA0
}}
}
} else {
; only erase
mode_5_prepare()
%asm {{
trb cx16.VERA_DATA0
}}
}
}
6 -> {
; highres 4c ....also mostly usable for mode 2, lores 4c?
void addr_mul_24_for_highres_4c(yy, xx) ; 24 bits result is in r0 and r1L (highest byte) void addr_mul_24_for_highres_4c(yy, xx) ; 24 bits result is in r0 and r1L (highest byte)
cx16.r2L = lsb(xx) & 3 ; xbits cx16.r2L = lsb(xx) & 3 ; xbits
; color &= 3 ; color &= 3
@ -671,76 +447,11 @@ _done
}} }}
} }
} }
sub mode_1_prepare() {
%asm {{
lda xx
and #7
pha ; xbits
}}
xx /= 8
xx += yy*(320/8)
%asm {{
stz cx16.VERA_CTRL
stz cx16.VERA_ADDR_H
lda xx+1
sta cx16.VERA_ADDR_M
lda xx
sta cx16.VERA_ADDR_L
ply ; xbits
lda maskbits,y
}}
}
sub mode_5_prepare() {
%asm {{
lda xx
and #7
pha ; xbits
}}
xx /= 8
xx += yy*(640/8)
%asm {{
stz cx16.VERA_CTRL
stz cx16.VERA_ADDR_H
lda xx+1
sta cx16.VERA_ADDR_M
lda xx
sta cx16.VERA_ADDR_L
ply ; xbits
lda maskbits,y
}}
}
} }
sub pget(uword @zp xx, uword yy) -> ubyte { sub pget(uword @zp xx, uword yy) -> ubyte {
when active_mode { when active_mode {
1 -> { 1 -> {
; lores monochrome
%asm {{
lda xx
and #7
pha ; xbits
}}
xx /= 8
xx += yy*(320/8)
%asm {{
stz cx16.VERA_CTRL
stz cx16.VERA_ADDR_H
lda xx+1
sta cx16.VERA_ADDR_M
lda xx
sta cx16.VERA_ADDR_L
ply ; xbits
lda plot.maskbits,y
and cx16.VERA_DATA0
beq +
lda #1
+
}}
}
; TODO modes 2, 3
4 -> {
; lores 256c ; lores 256c
void addr_mul_24_for_lores_256c(yy, xx) ; 24 bits result is in r0 and r1L (highest byte) void addr_mul_24_for_lores_256c(yy, xx) ; 24 bits result is in r0 and r1L (highest byte)
%asm {{ %asm {{
@ -754,31 +465,7 @@ _done
lda cx16.VERA_DATA0 lda cx16.VERA_DATA0
}} }}
} }
5 -> { 2 -> {
; hires monochrome
%asm {{
lda xx
and #7
pha ; xbits
}}
xx /= 8
xx += yy*(640/8)
%asm {{
stz cx16.VERA_CTRL
stz cx16.VERA_ADDR_H
lda xx+1
sta cx16.VERA_ADDR_M
lda xx
sta cx16.VERA_ADDR_L
ply ; xbits
lda plot.maskbits,y
and cx16.VERA_DATA0
beq +
lda #1
+
}}
}
6 -> {
; hires 4c ; hires 4c
void addr_mul_24_for_highres_4c(yy, xx) ; 24 bits result is in r0 and r1L (highest byte) void addr_mul_24_for_highres_4c(yy, xx) ; 24 bits result is in r0 and r1L (highest byte)
%asm {{ %asm {{
@ -915,29 +602,16 @@ skip:
sub position(uword @zp xx, uword yy) { sub position(uword @zp xx, uword yy) {
when active_mode { when active_mode {
1 -> { 1 -> {
; lores monochrome
cx16.r0 = yy*(320/8) + xx/8
cx16.vaddr(0, cx16.r0, 0, 1)
}
; TODO modes 2, 3
4 -> {
; lores 256c ; lores 256c
void addr_mul_24_for_lores_256c(yy, xx) ; 24 bits result is in r0 and r1L (highest byte) void addr_mul_24_for_lores_256c(yy, xx) ; 24 bits result is in r0 and r1L (highest byte)
cx16.r2L = cx16.r1L
cx16.vaddr(cx16.r2L, cx16.r0, 0, 1)
} }
5 -> { 2 -> {
; highres monochrome
cx16.r0 = yy*(640/8) + xx/8
cx16.vaddr(0, cx16.r0, 0, 1)
}
6 -> {
; highres 4c ; highres 4c
void addr_mul_24_for_highres_4c(yy, xx) ; 24 bits result is in r0 and r1L (highest byte) void addr_mul_24_for_highres_4c(yy, xx) ; 24 bits result is in r0 and r1L (highest byte)
cx16.r2L = cx16.r1L
cx16.vaddr(cx16.r2L, cx16.r0, 0, 1)
} }
} }
cx16.r2L = cx16.r1L
cx16.vaddr(cx16.r2L, cx16.r0, 0, 1)
} }
sub position2(uword @zp xx, uword yy, bool also_port_1) { sub position2(uword @zp xx, uword yy, bool also_port_1) {
@ -949,7 +623,6 @@ skip:
inline asmsub next_pixel(ubyte color @A) { inline asmsub next_pixel(ubyte color @A) {
; -- sets the next pixel byte to the graphics chip. ; -- sets the next pixel byte to the graphics chip.
; for 8 bpp screens this will plot 1 pixel. ; for 8 bpp screens this will plot 1 pixel.
; for 1 bpp screens it will plot 8 pixels at once (color = bit pattern).
; for 2 bpp screens it will plot 4 pixels at once (color = bit pattern). ; for 2 bpp screens it will plot 4 pixels at once (color = bit pattern).
%asm {{ %asm {{
sta cx16.VERA_DATA0 sta cx16.VERA_DATA0
@ -959,7 +632,6 @@ skip:
asmsub next_pixels(uword pixels @AY, uword amount @R0) clobbers(A, X, Y) { asmsub next_pixels(uword pixels @AY, uword amount @R0) clobbers(A, X, Y) {
; -- sets the next bunch of pixels from a prepared array of bytes. ; -- sets the next bunch of pixels from a prepared array of bytes.
; for 8 bpp screens this will plot 1 pixel per byte. ; for 8 bpp screens this will plot 1 pixel per byte.
; for 1 bpp screens it will plot 8 pixels at once (colors are the bit patterns per byte).
; for 2 bpp screens it will plot 4 pixels at once (colors are the bit patterns per byte). ; for 2 bpp screens it will plot 4 pixels at once (colors are the bit patterns per byte).
%asm {{ %asm {{
sta P8ZP_SCRATCH_W1 sta P8ZP_SCRATCH_W1
@ -1020,92 +692,7 @@ skip:
ubyte[8] @shared char_bitmap_bytes_right ubyte[8] @shared char_bitmap_bytes_right
when active_mode { when active_mode {
1, 5 -> { 1 -> {
; monochrome mode, either resolution
cx16.r3 = sctextptr
while @(cx16.r3) {
chardataptr = charset_addr + @(cx16.r3) * $0008
; copy the character bitmap into RAM
cx16.vaddr_autoincr(charset_bank, chardataptr, 0, 1)
%asm {{
; pre-shift the bits
lda text.xx
and #7
sta P8ZP_SCRATCH_B1
ldy #0
- lda cx16.VERA_DATA0
stz P8ZP_SCRATCH_REG
ldx P8ZP_SCRATCH_B1
cpx #0
beq +
- lsr a
ror P8ZP_SCRATCH_REG
dex
bne -
+ sta char_bitmap_bytes_left,y
lda P8ZP_SCRATCH_REG
sta char_bitmap_bytes_right,y
iny
cpy #8
bne --
}}
; left part of shifted char
position2(xx, yy, true)
set_autoincrs_mode1_or_5()
if color {
%asm {{
ldy #0
- lda char_bitmap_bytes_left,y
ora cx16.VERA_DATA1
sta cx16.VERA_DATA0
iny
cpy #8
bne -
}}
} else {
%asm {{
ldy #0
- lda char_bitmap_bytes_left,y
eor #255
and cx16.VERA_DATA1
sta cx16.VERA_DATA0
iny
cpy #8
bne -
}}
}
; right part of shifted char
if lsb(xx) & 7 {
position2(xx+8, yy, true)
set_autoincrs_mode1_or_5()
if color {
%asm {{
ldy #0
- lda char_bitmap_bytes_right,y
ora cx16.VERA_DATA1
sta cx16.VERA_DATA0
iny
cpy #8
bne -
}}
} else {
%asm {{
ldy #0
- lda char_bitmap_bytes_right,y
eor #255
and cx16.VERA_DATA1
sta cx16.VERA_DATA0
iny
cpy #8
bne -
}}
}
}
cx16.r3++
xx += 8
}
}
4 -> {
; lores 256c ; lores 256c
while @(sctextptr) { while @(sctextptr) {
chardataptr = charset_addr + (@(sctextptr) as uword)*8 chardataptr = charset_addr + (@(sctextptr) as uword)*8
@ -1132,7 +719,7 @@ skip:
sctextptr++ sctextptr++
} }
} }
6 -> { 2 -> {
; hires 4c ; hires 4c
; we're going to use a few cx16 registers to make sure every variable is in zeropage in the inner loop. ; we're going to use a few cx16 registers to make sure every variable is in zeropage in the inner loop.
cx16.r11L = color cx16.r11L = color
@ -1195,21 +782,6 @@ skip:
} }
} }
} }
sub set_autoincrs_mode1_or_5() {
; set autoincrements to go to next pixel row (40 or 80 increment)
if active_mode==1 {
cx16.VERA_CTRL = 0
cx16.VERA_ADDR_H = cx16.VERA_ADDR_H & $0f | (11<<4)
cx16.VERA_CTRL = 1
cx16.VERA_ADDR_H = cx16.VERA_ADDR_H & $0f | (11<<4)
} else {
cx16.VERA_CTRL = 0
cx16.VERA_ADDR_H = cx16.VERA_ADDR_H & $0f | (12<<4)
cx16.VERA_CTRL = 1
cx16.VERA_ADDR_H = cx16.VERA_ADDR_H & $0f | (12<<4)
}
}
} }
asmsub cs_innerloop640() clobbers(Y) { asmsub cs_innerloop640() clobbers(Y) {

View File

@ -98,9 +98,65 @@ monogfx {
if length==0 if length==0
return return
if length<=8 {
; just use 2 byte writes with shifted mask
position2(xx,yy,true)
%asm {{
ldy length
lda masked_ends,y
sta cx16.r0L ; save left byte
stz P8ZP_SCRATCH_B1
lda xx
and #7
beq +
tay
lda cx16.r0L
- lsr a
ror P8ZP_SCRATCH_B1
dey
bne -
sta cx16.r0L ; new left byte
+
lda dont_stipple_flag
bne _dontstipple
; determine stipple pattern
lda yy
and #1
beq +
lda #%10101010
bne ++
+ lda #%01010101
+ sta P8ZP_SCRATCH_REG
lda cx16.r0L
and P8ZP_SCRATCH_REG
sta cx16.r0L
lda P8ZP_SCRATCH_B1
and P8ZP_SCRATCH_REG
sta P8ZP_SCRATCH_B1
_dontstipple
lda draw
beq _clear
lda cx16.r0L ; left byte
ora cx16.VERA_DATA1
sta cx16.VERA_DATA0
lda P8ZP_SCRATCH_B1 ; right byte
ora cx16.VERA_DATA1
sta cx16.VERA_DATA0
rts
_clear
lda cx16.r0L ; left byte
eor #255
and cx16.VERA_DATA1
sta cx16.VERA_DATA0
lda P8ZP_SCRATCH_B1 ; right byte
eor #255
and cx16.VERA_DATA1
sta cx16.VERA_DATA0
rts
}}
}
ubyte separate_pixels = (8-lsb(xx)) & 7 ubyte separate_pixels = (8-lsb(xx)) & 7
if separate_pixels as uword > length
separate_pixels = lsb(length)
if separate_pixels { if separate_pixels {
if dont_stipple_flag { if dont_stipple_flag {
position(xx,yy) position(xx,yy)
@ -190,10 +246,11 @@ _done
} }
} else { } else {
; draw stippled line. ; draw stippled line.
if xx&1 { if (xx ^ yy)&1==0 {
yy++ yy++
lheight-- lheight--
} }
lheight++ ; because it is divided by 2 later, don't round off the last pixel
position2(xx,yy,true) position2(xx,yy,true)
if width==320 if width==320
set_both_strides(12) ; 80 increment = 2 line in 320 px monochrome set_both_strides(12) ; 80 increment = 2 line in 320 px monochrome
@ -583,7 +640,7 @@ skip:
cx16.r0 = yy*(320/8) cx16.r0 = yy*(320/8)
else else
cx16.r0 = yy*(640/8) cx16.r0 = yy*(640/8)
cx16.vaddr(0, cx16.r0+xx/8, 0, 1) cx16.vaddr(0, cx16.r0+(xx/8), 0, 1)
} }
sub position2(uword @zp xx, uword yy, bool also_port_1) { sub position2(uword @zp xx, uword yy, bool also_port_1) {

View File

@ -1,7 +1,6 @@
TODO TODO
==== ====
- gfx2 and monogfx rect draw problem in monochrome modes one of the small rectangles is drawn garbled
- make monogfx the new graphics module? also change c64 and c128 graphics modules - make monogfx the new graphics module? also change c64 and c128 graphics modules
- add %option verafxmuls in block to enable transparent verafx muls use for that block only + add warning message to docs to not use it it in prg AND irq code - add %option verafxmuls in block to enable transparent verafx muls use for that block only + add warning message to docs to not use it it in prg AND irq code
@ -57,6 +56,8 @@ Compiler:
Libraries: Libraries:
- port monogfx, gf2, graphics to the vm
- use verafx transparent writes to speed up pixel plotting in gfx2 and monogfx modules (avoids read/mask/write)
- fix the problems in atari target, and flesh out its libraries. - fix the problems in atari target, and flesh out its libraries.
- c128 target: make syslib more complete (missing kernal routines)? - c128 target: make syslib more complete (missing kernal routines)?
- pet32 target: make syslib more complete (missing kernal routines)? - pet32 target: make syslib more complete (missing kernal routines)?

View File

@ -8,7 +8,7 @@
main { main {
sub start() { sub start() {
gfx2.screen_mode(6) ; select 640*480 mode, 4 colors gfx2.screen_mode(2) ; select 640*480 mode, 4 colors
mouse.set_pointer_image() mouse.set_pointer_image()
cx16.mouse_config(-1, 640/8, 240/8) cx16.mouse_config(-1, 640/8, 240/8)
uword[4] amigacolors = [$aaa, $000, $fff, $68c] ; gray, black, white, lightblue uword[4] amigacolors = [$aaa, $000, $fff, $68c] ; gray, black, white, lightblue

View File

@ -22,7 +22,7 @@ main {
] ]
palette.set_rgb(&colors, len(colors)) palette.set_rgb(&colors, len(colors))
gfx2.screen_mode(4) ; lores 256 colors gfx2.screen_mode(1) ; lores 256 colors
cx16.VERA_DC_VSCALE = 0 ; display trick spoiler.......: stretch 1 line of display all the way to the bottom cx16.VERA_DC_VSCALE = 0 ; display trick spoiler.......: stretch 1 line of display all the way to the bottom
sys.set_rasterirq(&irq.irqhandler, 0) sys.set_rasterirq(&irq.irqhandler, 0)

View File

@ -3,7 +3,7 @@
main { main {
sub start() { sub start() {
gfx2.screen_mode(4) gfx2.screen_mode(1)
uword[128] @split flakes1_xx uword[128] @split flakes1_xx
uword[128] @split flakes1_yy uword[128] @split flakes1_yy

View File

@ -9,12 +9,9 @@
main { main {
sub start() { sub start() {
gfx2.screen_mode(4) gfx2.screen_mode(1)
demofill() demofill()
sys.wait(2*60) sys.wait(120)
gfx2.screen_mode(5)
demo1()
sys.wait(2*60)
demo2() demo2()
gfx2.screen_mode(0) gfx2.screen_mode(0)
@ -27,140 +24,24 @@ main {
gfx2.rect(180, 5, 25, 190, 1) gfx2.rect(180, 5, 25, 190, 1)
gfx2.line(100, 150, 240, 10, 1) gfx2.line(100, 150, 240, 10, 1)
gfx2.line(101, 150, 241, 10, 1) gfx2.line(101, 150, 241, 10, 1)
;gfx2.monochrome_stipple(true)
sys.wait(60) sys.wait(60)
gfx2.fill(100,100,2) gfx2.fill(100,100,2)
;gfx2.monochrome_stipple(false)
gfx2.fill(182,140,3) gfx2.fill(182,140,3)
gfx2.fill(182,40,1) gfx2.fill(182,40,1)
} }
sub demo1() {
uword yy = 10
uword xx
uword cnt
gfx2.monochrome_stipple(true)
gfx2.disc(320,240,200,1)
for xx in 0 to 639 {
gfx2.vertical_line(xx, 0, 480, 1)
}
for xx in 0 to 639 {
gfx2.vertical_line(xx, 0, 480, 0)
}
xx=gfx2.width/2
yy=10
gfx2.monochrome_stipple(false)
linesy()
linesx()
gfx2.monochrome_stipple(true)
linesy()
linesx()
sub linesx() {
repeat 8 {
gfx2.horizontal_line(10,yy,300,3)
yy++
}
yy+=4
repeat 8 {
gfx2.line(10,yy,309,yy,4)
yy++
}
yy+=4
repeat 8 {
for cnt in 10 to 309 {
gfx2.plot(cnt, yy, 1)
}
yy+=1
}
yy += 4
repeat 8 {
gfx2.horizontal_line(10,yy,100,3)
yy++
}
yy+=4
repeat 8 {
gfx2.line(10,yy,109,yy,4)
yy++
}
yy+=4
repeat 8 {
for cnt in 10 to 109 {
gfx2.plot(cnt, yy, 1)
}
yy++
}
yy+=4
}
sub linesy() {
repeat 8 {
gfx2.vertical_line(xx,10,300,3)
xx++
}
xx+=4
repeat 8 {
gfx2.line(xx,10, xx, 309, 4)
xx++
}
xx+=4
repeat 8 {
for cnt in 10 to 309 {
gfx2.plot(xx, cnt, 1)
}
xx+=1
}
xx += 4
repeat 8 {
gfx2.vertical_line(xx,10,100,3)
xx++
}
xx+=4
repeat 8 {
gfx2.line(xx,10,xx,109,4)
xx++
}
xx+=4
repeat 8 {
for cnt in 10 to 109 {
gfx2.plot(xx, cnt, 1)
}
xx++
}
xx+=4
}
}
sub demo2 () { sub demo2 () {
gfx2.text_charset(3) gfx2.text_charset(3)
gfx2.screen_mode(1)
ubyte[] modes = [4, 1, 5] draw()
ubyte mode sys.wait(120)
for mode in modes { gfx2.screen_mode(2)
gfx2.screen_mode(mode) draw()
draw() sys.wait(120)
sys.wait(200)
}
} }
sub draw() { sub draw() {
gfx2.rect(10,10, 1, 1, 4) gfx2.rect(10,10, 1, 1, 4)
gfx2.rect(20,10, 2, 1, 4) gfx2.rect(20,10, 2, 1, 4)
gfx2.rect(30,10, 3, 1, 4) gfx2.rect(30,10, 3, 1, 4)

View File

@ -22,13 +22,13 @@ main {
} }
sub demofill() { sub demofill() {
monogfx.circle(160, 120, 110, 1) monogfx.circle(160, 120, 110, true)
monogfx.rect(180, 5, 25, 190, 1) monogfx.rect(180, 5, 25, 190, true)
monogfx.line(100, 150, 240, 10, 1) monogfx.line(100, 150, 240, 10, true)
monogfx.line(101, 150, 241, 10, 1) monogfx.line(101, 150, 241, 10, true)
monogfx.stipple(true) monogfx.stipple(true)
sys.wait(60) sys.wait(60)
monogfx.fill(100,100,2) monogfx.fill(100,100,true)
} }
sub demo1() { sub demo1() {
@ -37,12 +37,12 @@ main {
uword cnt uword cnt
monogfx.stipple(true) monogfx.stipple(true)
monogfx.disc(320,240,200,1) monogfx.disc(320,240,200,true)
for xx in 0 to 639 { for xx in 0 to 639 {
monogfx.vertical_line(xx, 0, 480, 1) monogfx.vertical_line(xx, 0, 480, true)
} }
for xx in 0 to 639 { for xx in 0 to 639 {
monogfx.vertical_line(xx, 0, 480, 0) monogfx.vertical_line(xx, 0, 480, false)
} }
xx=monogfx.width/2 xx=monogfx.width/2
@ -58,40 +58,40 @@ main {
sub linesx() { sub linesx() {
repeat 8 { repeat 8 {
monogfx.horizontal_line(10,yy,300,3) monogfx.horizontal_line(10,yy,300,true)
yy++ yy++
} }
yy+=4 yy+=4
repeat 8 { repeat 8 {
monogfx.line(10,yy,309,yy,4) monogfx.line(10,yy,309,yy,false)
yy++ yy++
} }
yy+=4 yy+=4
repeat 8 { repeat 8 {
for cnt in 10 to 309 { for cnt in 10 to 309 {
monogfx.plot(cnt, yy, 1) monogfx.plot(cnt, yy, true)
} }
yy+=1 yy+=1
} }
yy += 4 yy += 4
repeat 8 { repeat 8 {
monogfx.horizontal_line(10,yy,100,3) monogfx.horizontal_line(10,yy,100,true)
yy++ yy++
} }
yy+=4 yy+=4
repeat 8 { repeat 8 {
monogfx.line(10,yy,109,yy,4) monogfx.line(10,yy,109,yy,false)
yy++ yy++
} }
yy+=4 yy+=4
repeat 8 { repeat 8 {
for cnt in 10 to 109 { for cnt in 10 to 109 {
monogfx.plot(cnt, yy, 1) monogfx.plot(cnt, yy, true)
} }
yy++ yy++
} }
@ -100,40 +100,40 @@ main {
sub linesy() { sub linesy() {
repeat 8 { repeat 8 {
monogfx.vertical_line(xx,10,300,3) monogfx.vertical_line(xx,10,300,true)
xx++ xx++
} }
xx+=4 xx+=4
repeat 8 { repeat 8 {
monogfx.line(xx,10, xx, 309, 4) monogfx.line(xx,10, xx, 309, false)
xx++ xx++
} }
xx+=4 xx+=4
repeat 8 { repeat 8 {
for cnt in 10 to 309 { for cnt in 10 to 309 {
monogfx.plot(xx, cnt, 1) monogfx.plot(xx, cnt, true)
} }
xx+=1 xx+=1
} }
xx += 4 xx += 4
repeat 8 { repeat 8 {
monogfx.vertical_line(xx,10,100,3) monogfx.vertical_line(xx,10,100,true)
xx++ xx++
} }
xx+=4 xx+=4
repeat 8 { repeat 8 {
monogfx.line(xx,10,xx,109,4) monogfx.line(xx,10,xx,109,false)
xx++ xx++
} }
xx+=4 xx+=4
repeat 8 { repeat 8 {
for cnt in 10 to 109 { for cnt in 10 to 109 {
monogfx.plot(xx, cnt, 1) monogfx.plot(xx, cnt, true)
} }
xx++ xx++
} }
@ -153,31 +153,31 @@ main {
sub draw() { sub draw() {
monogfx.rect(10,10, 1, 1, 4) monogfx.rect(10,10, 1, 1, true)
monogfx.rect(20,10, 2, 1, 4) monogfx.rect(20,10, 2, 1, true)
monogfx.rect(30,10, 3, 1, 4) monogfx.rect(30,10, 3, 1, true)
monogfx.rect(40,10, 1, 2, 4) monogfx.rect(40,10, 1, 2, true)
monogfx.rect(50,10, 1, 3, 4) monogfx.rect(50,10, 1, 3, true)
monogfx.rect(60,10, 2, 2, 4) monogfx.rect(60,10, 2, 2, true)
monogfx.rect(70,10, 3, 3, 4) monogfx.rect(70,10, 3, 3, true)
monogfx.rect(80,10, 4, 4, 4) monogfx.rect(80,10, 4, 4, true)
monogfx.rect(90,10, 5, 5, 4) monogfx.rect(90,10, 5, 5, true)
monogfx.rect(100,10, 8, 8, 4) monogfx.rect(100,10, 8, 8, true)
monogfx.rect(110,10, 20, 5, 4) monogfx.rect(110,10, 20, 5, true)
monogfx.rect(80, 80, 200, 140, 4) monogfx.rect(80, 80, 200, 140, true)
monogfx.fillrect(10,40, 1, 1, 5) monogfx.fillrect(10,40, 1, 1, true)
monogfx.fillrect(20,40, 2, 1, 5) monogfx.fillrect(20,40, 2, 1, true)
monogfx.fillrect(30,40, 3, 1, 5) monogfx.fillrect(30,40, 3, 1, true)
monogfx.fillrect(40,40, 1, 2, 5) monogfx.fillrect(40,40, 1, 2, true)
monogfx.fillrect(50,40, 1, 3, 5) monogfx.fillrect(50,40, 1, 3, true)
monogfx.fillrect(60,40, 2, 2, 5) monogfx.fillrect(60,40, 2, 2, true)
monogfx.fillrect(70,40, 3, 3, 5) monogfx.fillrect(70,40, 3, 3, true)
monogfx.fillrect(80,40, 4, 4, 5) monogfx.fillrect(80,40, 4, 4, true)
monogfx.fillrect(90,40, 5, 5, 5) monogfx.fillrect(90,40, 5, 5, true)
monogfx.fillrect(100,40, 8, 8, 5) monogfx.fillrect(100,40, 8, 8, true)
monogfx.fillrect(110,40, 20, 5, 5) monogfx.fillrect(110,40, 20, 5, true)
monogfx.fillrect(82, 82, 200-4, 140-4, 5) monogfx.fillrect(82, 82, 200-4, 140-4, true)
ubyte i ubyte i
for i in 0 to 254 step 4 { for i in 0 to 254 step 4 {
@ -185,7 +185,7 @@ main {
uword y1 = (monogfx.height-128)/2 + math.cos8u(i)/2 uword y1 = (monogfx.height-128)/2 + math.cos8u(i)/2
uword x2 = ((monogfx.width-64)/2 as uword) + math.sin8u(i)/4 uword x2 = ((monogfx.width-64)/2 as uword) + math.sin8u(i)/4
uword y2 = (monogfx.height-64)/2 + math.cos8u(i)/4 uword y2 = (monogfx.height-64)/2 + math.cos8u(i)/4
monogfx.line(x1, y1, x2, y2, i+1) monogfx.line(x1, y1, x2, y2, true)
} }
sys.wait(60) sys.wait(60)
@ -194,10 +194,10 @@ main {
ubyte radius ubyte radius
for radius in 110 downto 8 step -4 { for radius in 110 downto 8 step -4 {
monogfx.circle(monogfx.width/2, (monogfx.height/2 as ubyte), radius, radius) monogfx.circle(monogfx.width/2, (monogfx.height/2 as ubyte), radius, true)
} }
monogfx.disc(monogfx.width/2, monogfx.height/2, 80, 2) monogfx.disc(monogfx.width/2, monogfx.height/2, 80, true)
ubyte tp ubyte tp
for tp in 0 to 15 { for tp in 0 to 15 {

View File

@ -1,80 +1,76 @@
%import textio %import monogfx
;%import math
;%import verafx
%zeropage basicsafe
%option no_sysinit
main { main {
sub start() { sub start() {
word w1 = -123 monogfx.lores()
word w2 = 222 draw()
ubyte b2 = 222 repeat {
byte sb2 = 111 }
txt.print_w(w1*w2) }
txt.nl()
txt.print_w(w1*222)
txt.nl()
w1 = -123
w1 *= 222
txt.print_w(w1)
txt.nl()
w1 = -123
w1 *= w2
txt.print_w(w1)
txt.nl()
w1 = -123
w1 *= (w2-1)
txt.print_w(w1)
txt.nl()
w1 = -123
w1 *= b2
txt.print_w(w1)
txt.nl()
w1 = -123
w1 *= sb2
txt.print_w(w1)
txt.nl()
; txt.print_uw(math.mul16_last_upper()) sub draw() {
; txt.nl() uword xx
; uword value1=5678 monogfx.stipple(true)
; uword value2=9999 monogfx.fillrect(0,0,200,200,true)
; uword result = value1*value2 monogfx.stipple(false)
; uword upper16 = math.mul16_last_upper() for xx in 0 to 255 {
; txt.print_uw(result) monogfx.rect(xx, xx/2, 6, 16, 1)
; txt.spc() sys.waitvsync()
; txt.print_uw(upper16) monogfx.rect(xx, xx/2, 6, 16, 0)
; txt.nl() }
monogfx.rect(100, 100, 16, 16, 1)
monogfx.rect(101, 101, 15, 15, 1)
monogfx.rect(102, 102, 14, 14, 1)
monogfx.rect(103, 103, 13, 13, 1)
monogfx.rect(104, 104, 12, 12, 1)
; const word MULTIPLIER = 431 ; monogfx.rect(10,10, 1, 1, 1)
; ; monogfx.rect(20,10, 2, 1, 1)
; ; verify results: ; monogfx.rect(30,10, 3, 1, 1)
; for value in -50 to 50 { ; monogfx.rect(40,10, 1, 2, 1)
; if value*MULTIPLIER != verafx.muls(value, MULTIPLIER) { ; monogfx.rect(50,10, 1, 3, 1)
; txt.print("verafx muls error\n") ; monogfx.rect(60,10, 2, 2, 1)
; sys.exit(1) ; monogfx.rect(70,10, 3, 3, 1)
; } ; monogfx.rect(80,10, 4, 4, 1)
; } ; monogfx.rect(120,220, 5, 5, 1)
; ; monogfx.rect(90,10, 5, 5, 1)
; ; monogfx.rect(100,10, 8, 8, 1)
; word value ; monogfx.rect(110,10, 20, 5, 1)
; txt.print("verafx muls...") ; monogfx.fillrect(10,40, 1, 1, 1)
; cbm.SETTIM(0,0,0) ; monogfx.fillrect(20,40, 2, 1, 1)
; for value in -50 to 50 { ; monogfx.fillrect(30,40, 3, 1, 1)
; repeat 250 void verafx.muls(value, MULTIPLIER) ; monogfx.fillrect(40,40, 1, 2, 1)
; } ; monogfx.fillrect(50,40, 1, 3, 1)
; txt.print_uw(cbm.RDTIM16()) ; monogfx.fillrect(60,40, 2, 2, 1)
; txt.nl() ; monogfx.fillrect(70,40, 3, 3, 1)
; ; monogfx.fillrect(80,40, 4, 4, 1)
; txt.print("6502 muls...") ; monogfx.fillrect(90,40, 5, 5, 1)
; cbm.SETTIM(0,0,0) ; monogfx.fillrect(100,40, 8, 8, 1)
; for value in -50 to 50 { ; monogfx.fillrect(110,40, 20, 5, 1)
; repeat 250 cx16.r0s = value*MULTIPLIER
; }
; txt.print_uw(cbm.RDTIM16())
; txt.nl()
; monogfx.rect(160, 10, 1, 1, 1)
; monogfx.rect(160, 20, 2, 1, 1)
; monogfx.rect(160, 30, 3, 1, 1)
; monogfx.rect(160, 40, 1, 2, 1)
; monogfx.rect(160, 50, 1, 3, 1)
; monogfx.rect(160, 60, 2, 2, 1)
; monogfx.rect(160, 70, 3, 3, 1)
; monogfx.rect(160, 80, 4, 4, 1)
; monogfx.rect(160, 90, 5, 5, 1)
; monogfx.rect(160, 100, 8, 8, 1)
; monogfx.rect(160, 110, 20, 5, 1)
; monogfx.fillrect(160, 120, 1, 1, 1)
; monogfx.fillrect(160, 130, 2, 1, 1)
; monogfx.fillrect(160, 140, 3, 1, 1)
; monogfx.fillrect(160, 150, 1, 2, 1)
; monogfx.fillrect(160, 160, 1, 3, 1)
; monogfx.fillrect(160, 170, 2, 2, 1)
; monogfx.fillrect(160, 180, 3, 3, 1)
; monogfx.fillrect(160, 190, 4, 4, 1)
; monogfx.fillrect(160, 200, 5, 5, 1)
; monogfx.fillrect(160, 210, 8, 8, 1)
; monogfx.fillrect(160, 220, 20, 5, 1)
} }
} }