mirror of
https://github.com/irmen/prog8.git
synced 2024-09-07 03:54:27 +00:00
gfx2 highres 4colors
This commit is contained in:
parent
fd55611cac
commit
a910c0fddb
@ -19,6 +19,9 @@
|
|||||||
|
|
||||||
; TODO can we make a FB vector table and emulation routines for the Cx16s' GRAPH_init() call? to replace the builtin 320x200 fb driver?
|
; TODO can we make a FB vector table and emulation routines for the Cx16s' GRAPH_init() call? to replace the builtin 320x200 fb driver?
|
||||||
|
|
||||||
|
; TODO split out the various when blocks in to their own subroutines so the assembler can omit unused code.
|
||||||
|
|
||||||
|
|
||||||
gfx2 {
|
gfx2 {
|
||||||
|
|
||||||
; read-only control variables:
|
; read-only control variables:
|
||||||
@ -67,7 +70,18 @@ gfx2 {
|
|||||||
height = 480
|
height = 480
|
||||||
bpp = 1
|
bpp = 1
|
||||||
}
|
}
|
||||||
; TODO mode 6 highres 4c
|
6 -> {
|
||||||
|
; highres 4c
|
||||||
|
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 = %00000101
|
||||||
|
cx16.VERA_L1_MAPBASE = 0
|
||||||
|
cx16.VERA_L1_TILEBASE = %00000001
|
||||||
|
width = 640
|
||||||
|
height = 480
|
||||||
|
bpp = 2
|
||||||
|
}
|
||||||
; modes 7 and 8 not supported due to lack of VRAM
|
; modes 7 and 8 not supported due to lack of VRAM
|
||||||
else -> {
|
else -> {
|
||||||
; back to default text mode and colors
|
; back to default text mode and colors
|
||||||
@ -105,7 +119,11 @@ gfx2 {
|
|||||||
repeat 480/8
|
repeat 480/8
|
||||||
cs_innerloop640()
|
cs_innerloop640()
|
||||||
}
|
}
|
||||||
; TODO mode 6 highres 4c
|
6 -> {
|
||||||
|
; highres 4c
|
||||||
|
repeat 480/4
|
||||||
|
cs_innerloop640()
|
||||||
|
}
|
||||||
; modes 7 and 8 not supported due to lack of VRAM
|
; modes 7 and 8 not supported due to lack of VRAM
|
||||||
}
|
}
|
||||||
position(0, 0)
|
position(0, 0)
|
||||||
@ -141,28 +159,6 @@ gfx2 {
|
|||||||
if length==0
|
if length==0
|
||||||
return
|
return
|
||||||
when active_mode {
|
when active_mode {
|
||||||
4 -> {
|
|
||||||
; lores 256c
|
|
||||||
position(x, y)
|
|
||||||
%asm {{
|
|
||||||
lda color
|
|
||||||
phx
|
|
||||||
ldx length+1
|
|
||||||
beq +
|
|
||||||
ldy #0
|
|
||||||
- sta cx16.VERA_DATA0
|
|
||||||
iny
|
|
||||||
bne -
|
|
||||||
dex
|
|
||||||
bne -
|
|
||||||
+ ldy length ; remaining
|
|
||||||
beq +
|
|
||||||
- sta cx16.VERA_DATA0
|
|
||||||
dey
|
|
||||||
bne -
|
|
||||||
+ plx
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
1, 5 -> {
|
1, 5 -> {
|
||||||
; monochrome modes, either resolution
|
; monochrome modes, either resolution
|
||||||
ubyte separate_pixels = (8-lsb(x)) & 7
|
ubyte separate_pixels = (8-lsb(x)) & 7
|
||||||
@ -218,27 +214,57 @@ _done
|
|||||||
}
|
}
|
||||||
cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) ; vera auto-increment off again
|
cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) ; vera auto-increment off again
|
||||||
}
|
}
|
||||||
|
4 -> {
|
||||||
|
; lores 256c
|
||||||
|
position(x, y)
|
||||||
|
%asm {{
|
||||||
|
lda color
|
||||||
|
phx
|
||||||
|
ldx length+1
|
||||||
|
beq +
|
||||||
|
ldy #0
|
||||||
|
- sta cx16.VERA_DATA0
|
||||||
|
iny
|
||||||
|
bne -
|
||||||
|
dex
|
||||||
|
bne -
|
||||||
|
+ ldy length ; remaining
|
||||||
|
beq +
|
||||||
|
- sta cx16.VERA_DATA0
|
||||||
|
dey
|
||||||
|
bne -
|
||||||
|
+ plx
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
6 -> {
|
||||||
|
; highres 4c
|
||||||
|
; TODO also mostly usable for lores 4c?
|
||||||
|
cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) ; no auto advance
|
||||||
|
color &=3
|
||||||
|
color <<= gfx2.plot.shift4c[lsb(x) & 3]
|
||||||
|
ubyte mask = gfx2.plot.mask4c[lsb(x) & 3]
|
||||||
|
void addr_mul_24_for_highres_4c(y, x) ; 24 bits result is in r0 and r1L (highest byte)
|
||||||
|
repeat length {
|
||||||
|
; TODO optimize the vera memory manipulation in pure assembly
|
||||||
|
ubyte cbits4 = cx16.vpeek(lsb(cx16.r1), cx16.r0) & mask | color
|
||||||
|
cx16.vpoke(lsb(cx16.r1), cx16.r0, cbits4)
|
||||||
|
x++
|
||||||
|
if x & 3 == 0
|
||||||
|
cx16.r0++ ; next x byte
|
||||||
|
ror2(color)
|
||||||
|
ror2(color)
|
||||||
|
ror2(mask)
|
||||||
|
ror2(mask)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub vertical_line(uword x, uword y, uword height, ubyte color) {
|
sub vertical_line(uword x, uword y, uword height, ubyte color) {
|
||||||
position(x,y)
|
position(x,y)
|
||||||
if active_mode==4 {
|
when active_mode {
|
||||||
; lores 256c
|
1, 5 -> {
|
||||||
; set vera auto-increment to 320 pixel increment (=next line)
|
; monochrome, either resolution
|
||||||
cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) | (14<<4)
|
|
||||||
%asm {{
|
|
||||||
ldy height
|
|
||||||
beq +
|
|
||||||
lda color
|
|
||||||
- sta cx16.VERA_DATA0
|
|
||||||
dey
|
|
||||||
bne -
|
|
||||||
+
|
|
||||||
}}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
; note for the 1 bpp modes we can't use vera's auto increment mode because we have to 'or' the pixel data in place.
|
; note for the 1 bpp modes we can't use vera's auto increment mode because we have to 'or' the pixel data in place.
|
||||||
cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) ; no auto advance
|
cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) ; no auto advance
|
||||||
cx16.r15 = gfx2.plot.bits[x as ubyte & 7] ; bitmask
|
cx16.r15 = gfx2.plot.bits[x as ubyte & 7] ; bitmask
|
||||||
@ -280,11 +306,11 @@ _done
|
|||||||
lda cx16.VERA_ADDR_M
|
lda cx16.VERA_ADDR_M
|
||||||
adc #0
|
adc #0
|
||||||
sta cx16.VERA_ADDR_M
|
sta cx16.VERA_ADDR_M
|
||||||
+
|
+
|
||||||
asl cx16.r14
|
asl cx16.r14
|
||||||
ldy height
|
ldy height
|
||||||
beq +
|
beq +
|
||||||
- lda cx16.VERA_DATA0
|
- lda cx16.VERA_DATA0
|
||||||
ora cx16.r15
|
ora cx16.r15
|
||||||
sta cx16.VERA_DATA0
|
sta cx16.VERA_DATA0
|
||||||
lda cx16.VERA_ADDR_L
|
lda cx16.VERA_ADDR_L
|
||||||
@ -299,7 +325,7 @@ _done
|
|||||||
; sta cx16.VERA_ADDR_H
|
; sta cx16.VERA_ADDR_H
|
||||||
dey
|
dey
|
||||||
bne -
|
bne -
|
||||||
+
|
+
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -323,6 +349,40 @@ _done
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4 -> {
|
||||||
|
; lores 256c
|
||||||
|
; set vera auto-increment to 320 pixel increment (=next line)
|
||||||
|
cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) | (14<<4)
|
||||||
|
%asm {{
|
||||||
|
ldy height
|
||||||
|
beq +
|
||||||
|
lda color
|
||||||
|
- sta cx16.VERA_DATA0
|
||||||
|
dey
|
||||||
|
bne -
|
||||||
|
+
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
6 -> {
|
||||||
|
; highres 4c
|
||||||
|
; note for this mode we can't use vera's auto increment mode because we have to 'or' the pixel data in place.
|
||||||
|
cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) ; no auto advance
|
||||||
|
; TODO also mostly usable for lores 4c?
|
||||||
|
void addr_mul_24_for_highres_4c(y, x) ; 24 bits result is in r0 and r1L (highest byte)
|
||||||
|
color &= 3
|
||||||
|
color <<= gfx2.plot.shift4c[lsb(x) & 3]
|
||||||
|
ubyte mask = gfx2.plot.mask4c[lsb(x) & 3]
|
||||||
|
|
||||||
|
repeat height {
|
||||||
|
; TODO optimize the vera memory manipulation in pure assembly
|
||||||
|
ubyte value = cx16.vpeek(lsb(cx16.r1), cx16.r0) & mask | color
|
||||||
|
cx16.vpoke(lsb(cx16.r1), cx16.r0, value)
|
||||||
|
cx16.r0 += 640/4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
sub line(uword @zp x1, uword @zp y1, uword @zp x2, uword @zp y2, ubyte color) {
|
sub line(uword @zp x1, uword @zp y1, uword @zp x2, uword @zp y2, ubyte color) {
|
||||||
; Bresenham algorithm.
|
; Bresenham algorithm.
|
||||||
@ -480,6 +540,8 @@ _done
|
|||||||
|
|
||||||
sub plot(uword @zp x, uword y, ubyte color) {
|
sub plot(uword @zp x, uword y, ubyte color) {
|
||||||
ubyte[8] bits = [128, 64, 32, 16, 8, 4, 2, 1]
|
ubyte[8] bits = [128, 64, 32, 16, 8, 4, 2, 1]
|
||||||
|
ubyte[4] mask4c = [%00111111, %11001111, %11110011, %11111100]
|
||||||
|
ubyte[4] shift4c = [6,4,2,0]
|
||||||
uword addr
|
uword addr
|
||||||
ubyte value
|
ubyte value
|
||||||
|
|
||||||
@ -503,6 +565,14 @@ _done
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4 -> {
|
||||||
|
; lores 256c
|
||||||
|
void addr_mul_24_for_lores_256c(y, x) ; 24 bits result is in r0 and r1L (highest byte)
|
||||||
|
cx16.vpoke(lsb(cx16.r1), cx16.r0, color)
|
||||||
|
; activate vera auto-increment mode so next_pixel() can be used after this
|
||||||
|
cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) | %00010000
|
||||||
|
color = cx16.VERA_DATA0
|
||||||
|
}
|
||||||
5 -> {
|
5 -> {
|
||||||
; highres monochrome
|
; highres monochrome
|
||||||
%asm {{
|
%asm {{
|
||||||
@ -522,14 +592,15 @@ _done
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
4 -> {
|
6 -> {
|
||||||
; lores 256c
|
; highres 4c
|
||||||
void addr_mul_320_add_24(y, x) ; 24 bits result is in r0 and r1L
|
; TODO also mostly usable for lores 4c?
|
||||||
value = lsb(cx16.r1)
|
void addr_mul_24_for_highres_4c(y, x) ; 24 bits result is in r0 and r1L (highest byte)
|
||||||
cx16.vpoke(value, cx16.r0, color)
|
color &= 3
|
||||||
; activate vera auto-increment mode so next_pixel() can be used after this
|
color <<= shift4c[lsb(x) & 3]
|
||||||
cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) | %00010000
|
; TODO optimize the vera memory manipulation in pure assembly
|
||||||
color = cx16.VERA_DATA0
|
value = cx16.vpeek(lsb(cx16.r1), cx16.r0) & mask4c[lsb(x) & 3] | color
|
||||||
|
cx16.vpoke(lsb(cx16.r1), cx16.r0, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -541,16 +612,21 @@ _done
|
|||||||
cx16.r0 = y*(320/8) + x/8
|
cx16.r0 = y*(320/8) + x/8
|
||||||
cx16.vaddr(0, cx16.r0, 0, 1)
|
cx16.vaddr(0, cx16.r0, 0, 1)
|
||||||
}
|
}
|
||||||
|
4 -> {
|
||||||
|
; lores 256c
|
||||||
|
void addr_mul_24_for_lores_256c(y, x) ; 24 bits result is in r0 and r1L (highest byte)
|
||||||
|
ubyte bank = lsb(cx16.r1)
|
||||||
|
cx16.vaddr(bank, cx16.r0, 0, 1)
|
||||||
|
}
|
||||||
5 -> {
|
5 -> {
|
||||||
; highres monochrome
|
; highres monochrome
|
||||||
cx16.r0 = y*(640/8) + x/8
|
cx16.r0 = y*(640/8) + x/8
|
||||||
cx16.vaddr(0, cx16.r0, 0, 1)
|
cx16.vaddr(0, cx16.r0, 0, 1)
|
||||||
}
|
}
|
||||||
4 -> {
|
6 -> {
|
||||||
; lores 256c
|
; highres 4c
|
||||||
void addr_mul_320_add_24(y, x) ; 24 bits result is in r0 and r1L
|
cx16.r0 = y*(640/4) + x/8
|
||||||
ubyte bank = lsb(cx16.r1)
|
cx16.vaddr(0, cx16.r0, 0, 1)
|
||||||
cx16.vaddr(bank, cx16.r0, 0, 1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -727,7 +803,15 @@ _done
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
asmsub addr_mul_320_add_24(uword address @R0, uword value @AY) clobbers(A) -> uword @R0, ubyte @R1 {
|
sub addr_mul_24_for_highres_4c(uword yy, uword xx) {
|
||||||
|
; TODO asmsub, 24 bits calc
|
||||||
|
; 24 bits result is in r0 and r1L (highest byte)
|
||||||
|
cx16.r0 = xx/4 + yy*(640/4)
|
||||||
|
cx16.r1 = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub addr_mul_24_for_lores_256c(uword yy @R0, uword xx @AY) clobbers(A) -> uword @R0, ubyte @R1 {
|
||||||
|
; yy * 320 + xx (24 bits calculation)
|
||||||
%asm {{
|
%asm {{
|
||||||
sta P8ZP_SCRATCH_W1
|
sta P8ZP_SCRATCH_W1
|
||||||
sty P8ZP_SCRATCH_W1+1
|
sty P8ZP_SCRATCH_W1+1
|
||||||
|
@ -11,7 +11,10 @@ main {
|
|||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
palette.set_monochrome($0aaa, $0000)
|
palette.set_monochrome($0aaa, $0000)
|
||||||
gfx2.screen_mode(5) ; select 640*480 mode
|
gfx2.screen_mode(6) ; select 640*480 mode
|
||||||
|
|
||||||
|
sys.wait(200)
|
||||||
|
|
||||||
cx16.VERA_DC_VSCALE = 64 ; have the vertical resolution so it is 640*240 - more or less Amiga's default non interlaced mode
|
cx16.VERA_DC_VSCALE = 64 ; have the vertical resolution so it is 640*240 - more or less Amiga's default non interlaced mode
|
||||||
cx16.mouse_config(1, 1) ; enable mouse TODO make it an Amiga mouse pointer if possible
|
cx16.mouse_config(1, 1) ; enable mouse TODO make it an Amiga mouse pointer if possible
|
||||||
gfx2.text_charset(3)
|
gfx2.text_charset(3)
|
||||||
|
40
examples/cx16/highresbitmap-4c.p8
Normal file
40
examples/cx16/highresbitmap-4c.p8
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
%target cx16
|
||||||
|
%import gfx2
|
||||||
|
%import textio
|
||||||
|
%zeropage basicsafe
|
||||||
|
|
||||||
|
main {
|
||||||
|
|
||||||
|
sub start () {
|
||||||
|
gfx2.text_charset(3)
|
||||||
|
|
||||||
|
test()
|
||||||
|
|
||||||
|
gfx2.screen_mode(0)
|
||||||
|
txt.print("done!\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
sub test() {
|
||||||
|
gfx2.screen_mode(6)
|
||||||
|
|
||||||
|
ubyte color
|
||||||
|
uword yy
|
||||||
|
for color in 3 downto 0 {
|
||||||
|
for yy in 100 to 120 {
|
||||||
|
uword xx
|
||||||
|
for xx in 10 to 500 {
|
||||||
|
gfx2.plot(xx, yy, color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for color in 3 downto 0 {
|
||||||
|
for yy in 130 to 150 {
|
||||||
|
gfx2.horizontal_line(10, yy, 400, color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sys.wait(5*60)
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +1,20 @@
|
|||||||
%import textio
|
%import textio
|
||||||
|
%import syslib
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
uword xx
|
ubyte value
|
||||||
uword iter = 1000
|
ubyte bb1
|
||||||
repeat iter {
|
|
||||||
xx++
|
|
||||||
}
|
|
||||||
|
|
||||||
txt.print_uw(xx)
|
; TODO why is this generating so much larger code: (only with asmsub btw)
|
||||||
|
value = cx16.vpeek(lsb(cx16.r0), mkword(value, bb1))
|
||||||
|
value = cx16.vpeek(lsb(cx16.r0), mkword(value, bb1))
|
||||||
|
|
||||||
|
ubyte lx = lsb(cx16.r0)
|
||||||
|
value = cx16.vpeek(lx, mkword(value, bb1))
|
||||||
|
value = cx16.vpeek(lx, mkword(value, bb1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user