preliminary support for pattern-to-screen, reusing single-byte rectfill

This commit is contained in:
Romain Dolbeau 2022-05-16 16:40:05 +02:00
parent 607832abc0
commit c8e8113c81
4 changed files with 117 additions and 40 deletions

View File

@ -344,7 +344,7 @@ struct qdstuff {
uint16_t PATROW; // (must follow PATHMASK) // PATHMASK-2
uint16_t PATHMASK; // (must follow PATVMASK) // PATVMASK-2
uint16_t PATVMASK; // (must follow expat) // EXPAT-2
uint32_t EXPAT; // YES // STACKFREE-4
uint32_t* EXPAT; // YES // STACKFREE-4
// SET UP FOR BITBLT FOR RGNBLT
// (CALLED BY STRETCHBITS, RGNBLT, BITBLT, DRAWARC, DRAWLINE)
@ -383,13 +383,13 @@ int hwblit(char* stack, char* p_fb_base, /* short dstshift, */ short mode, Patte
short height = qdstack->MINRECT.bottom - qdstack->MINRECT.top;
short dstshift = qdstack->DSTSHIFT;
if (mode != 0) { // only copy handled for now
#if 0 //def QEMU
if ((mode != 0) && (mode != 8)) { // only copy handled for now
#ifdef QEMU
bt->debug = -2L;
bt->debug = mode;
if (mode == 8) {
bt->debug = qdstack->PATROW;
bt->debug = -2L;
#if 0
bt->debug = pat->pat[0];
bt->debug = pat->pat[1];
bt->debug = pat->pat[2];
@ -398,11 +398,33 @@ int hwblit(char* stack, char* p_fb_base, /* short dstshift, */ short mode, Patte
bt->debug = pat->pat[5];
bt->debug = pat->pat[6];
bt->debug = pat->pat[7];
#endif
}
#endif
return 0;
}
if (mode == 8) {
register int i;
register unsigned long expat0 = qdstack->EXPAT[0];
if (qdstack->PATROW != 0) {
bt->debug = -6L;
return 0;
}
if ((expat0 & 0xFFFF) != ((expat0 >> 16) & 0xFFFF))
return 0;
if ((expat0 & 0xFF) != ((expat0 >> 8) & 0xFF))
return 0;
for (i = 1 ; i < 16 ; i++)
if (expat0 != qdstack->EXPAT[i]) {
bt->debug = -7L;
return 0;
}
}
if (dstshift < 3) { // only 8/16/32 bits for now
#ifdef QEMU
bt->debug = -3L;
bt->debug = dstshift;
#endif
return 0;
}
dstshift -= 3;
@ -411,9 +433,17 @@ int hwblit(char* stack, char* p_fb_base, /* short dstshift, */ short mode, Patte
}
if (dstpix->baseAddr != p_fb_base) { // we're not destination
#ifdef QEMU
bt->debug = -4L;
bt->debug = (unsigned long)dstpix->baseAddr;
#endif
return 0;
}
if (srcpix->baseAddr != p_fb_base) { // we're not source
#ifdef QEMU
bt->debug = -5L;
bt->debug = (unsigned long)srcpix->baseAddr;
#endif
return 0;
}
@ -440,48 +470,75 @@ int hwblit(char* stack, char* p_fb_base, /* short dstshift, */ short mode, Patte
realrect.left += (srcrect->left - dstrect->left); /* A2 */
/* qdstack->MINRECT is A3 */
srcv.top = realrect.top - srcpix->bounds.top;
srcv.left = realrect.left - srcpix->bounds.left;
srcv.top = realrect.top - srcpix->bounds.top;
srcv.left = realrect.left - srcpix->bounds.left;
dstv.top = qdstack->MINRECT.top - dstpix->bounds.top;
dstv.left = qdstack->MINRECT.left - dstpix->bounds.left;
dstv.top = qdstack->MINRECT.top - dstpix->bounds.top;
dstv.left = qdstack->MINRECT.left - dstpix->bounds.left;
/* if .baseAddr of both pix are different, no overlap */
/*
// the HW can handle that for us
if (dstpix->baseAddr == srcpix->baseAddr) {
}
*/
/* if .baseAddr of both pix are different, no overlap */
/*
// the HW can handle that for us
if (dstpix->baseAddr == srcpix->baseAddr) {
}
*/
#ifdef QEMU
bt->debug = srcv.top;
bt->debug = srcv.left;
#if 0
if ((mode == 8) && (qdstack->PATROW == 0)) {
bt->debug = 0x87654321;
bt->debug = qdstack->EXPAT[ 0];
bt->debug = qdstack->EXPAT[ 1];
bt->debug = qdstack->EXPAT[ 2];
bt->debug = qdstack->EXPAT[ 3];
bt->debug = qdstack->EXPAT[ 4];
bt->debug = qdstack->EXPAT[ 5];
bt->debug = qdstack->EXPAT[ 6];
bt->debug = qdstack->EXPAT[ 7];
bt->debug = qdstack->EXPAT[ 8];
bt->debug = qdstack->EXPAT[ 9];
bt->debug = qdstack->EXPAT[10];
bt->debug = qdstack->EXPAT[11];
bt->debug = qdstack->EXPAT[12];
bt->debug = qdstack->EXPAT[13];
bt->debug = qdstack->EXPAT[14];
bt->debug = qdstack->EXPAT[15];
}
#endif
bt->debug = -1L;
bt->debug = srcv.top;
bt->debug = srcv.left;
bt->debug = height;
bt->debug = width;
bt->debug = height;
bt->debug = width;
bt->debug = dstv.top;
bt->debug = dstv.left;
bt->debug = dstv.top;
bt->debug = dstv.left;
bt->debug = (long)dstpix->baseAddr;
bt->debug = (long)srcpix->baseAddr;
bt->debug = (long)dstpix->baseAddr;
bt->debug = (long)srcpix->baseAddr;
return 0;
#else
WAIT_FOR_HW(accel);
WAIT_FOR_HW(accel);
accel->reg_width = brev(width);
accel->reg_height = brev(height);
accel->reg_width = brev(width);
accel->reg_height = brev(height);
accel->reg_bitblt_dst_x = brev(dstv.left << dstshift);
accel->reg_bitblt_dst_y = brev(dstv.top);
if (mode == 0) {
accel->reg_bitblt_src_x = brev(srcv.left << dstshift);
accel->reg_bitblt_src_y = brev(srcv.top);
accel->reg_bitblt_dst_x = brev(dstv.left << dstshift);
accel->reg_bitblt_dst_y = brev(dstv.top);
accel->reg_cmd = brev(1<<DO_BLIT_BIT);
} else if (mode == 8) {
accel->reg_fgcolor = qdstack->EXPAT[0];
accel->reg_cmd = brev(1<<DO_FILL_BIT);
}
accel->reg_cmd = brev(1<<DO_BLIT_BIT);
WAIT_FOR_HW(accel);
WAIT_FOR_HW(accel);
return 1;
return 1;
#endif
}

View File

@ -13,6 +13,7 @@
// cmd
#define DO_BLIT_BIT 0 // hardwired in goblin_accel.py
#define DO_FILL_BIT 1 // hardwired in goblin_accel.py
#define FUN_DONE_BIT 31
@ -35,7 +36,7 @@ struct goblin_accel_regs {
u_int32_t resv0;
u_int32_t reg_width;
u_int32_t reg_height;
u_int32_t resv1;
u_int32_t reg_fgcolor;
u_int32_t resv2;
u_int32_t reg_bitblt_src_x;
u_int32_t reg_bitblt_src_y;

View File

@ -41,8 +41,10 @@ struct control_blitter {
*/
#define FUN_BLIT_BIT 0 // hardwired in goblin_accel.py
#define FUN_FILL_BIT 1 // hardwired in goblin_accel.py
#define FUN_DONE_BIT 31
#define FUN_BLIT (1<<FUN_BLIT_BIT)
#define FUN_FILL (1<<FUN_FILL_BIT)
#define FUN_DONE (1<<FUN_DONE_BIT)
struct goblin_accel_regs {
@ -52,7 +54,7 @@ struct goblin_accel_regs {
u_int32_t resv0;
u_int32_t reg_width;
u_int32_t reg_height;
u_int32_t resv1;
u_int32_t reg_fgcolor;
u_int32_t resv2;
u_int32_t reg_bitblt_src_x;
u_int32_t reg_bitblt_src_y;
@ -163,7 +165,12 @@ void from_reset(void) {
fbc->reg_width, fbc->reg_height,
fbc->reg_bitblt_dst_x, fbc->reg_bitblt_dst_y,
0xFF, 0x3); // GXcopy
}
} break;
case FUN_FILL: {
rectfill(fbc->reg_bitblt_dst_x, fbc->reg_bitblt_dst_y,
fbc->reg_width, fbc->reg_height,
fbc->reg_fgcolor);
} break;
default:
break;
}

View File

@ -18,9 +18,9 @@ class GoblinAccel(Module): # AutoCSR ?
reg_cmd = Signal(32) # 1
reg_r5_cmd = Signal(32) # 2, to communicate with Vex
# 3 resv0
reg_width = Signal(COORD_BITS)
reg_height = Signal(COORD_BITS)
# 6 resv1
reg_width = Signal(COORD_BITS) # 4
reg_height = Signal(COORD_BITS) # 5
reg_fgcolor = Signal(32) # 6
# 7 resv2
reg_bitblt_src_x = Signal(COORD_BITS) # 8
reg_bitblt_src_y = Signal(COORD_BITS) # 9
@ -29,9 +29,11 @@ class GoblinAccel(Module): # AutoCSR ?
# do-some-work flags
do_blit = Signal()
do_fill = Signal()
# cmd register reg_cmd
DO_BLIT_BIT = 0
DO_FILL_BIT = 1
# global status register reg_status
WORK_IN_PROGRESS_BIT = 0
@ -48,12 +50,14 @@ class GoblinAccel(Module): # AutoCSR ?
0: [ NextValue(reg_status, bus.dat_w) ], # debug, remove me
1: [ NextValue(reg_cmd, bus.dat_w),
NextValue(do_blit, bus.dat_w[DO_BLIT_BIT] & ~reg_status[WORK_IN_PROGRESS_BIT]),
NextValue(do_fill, bus.dat_w[DO_FILL_BIT] & ~reg_status[WORK_IN_PROGRESS_BIT]),
],
2: [ NextValue(reg_r5_cmd, bus.dat_w) ],
# 3
4: [ NextValue(reg_width, bus.dat_w) ],
5: [ NextValue(reg_height, bus.dat_w) ],
# 6,7
6: [ NextValue(reg_fgcolor, bus.dat_w) ],
# 7
8: [ NextValue(reg_bitblt_src_x, bus.dat_w) ],
9: [ NextValue(reg_bitblt_src_y, bus.dat_w) ],
10: [ NextValue(reg_bitblt_dst_x, bus.dat_w) ],
@ -69,7 +73,8 @@ class GoblinAccel(Module): # AutoCSR ?
# 3
4: [ NextValue(bus.dat_r, reg_width) ],
5: [ NextValue(bus.dat_r, reg_height) ],
# 6, 7
6: [ NextValue(bus.dat_r, reg_fgcolor) ],
# 7
8: [ NextValue(bus.dat_r, reg_bitblt_src_x) ],
9: [ NextValue(bus.dat_r, reg_bitblt_src_y) ],
10: [ NextValue(bus.dat_r, reg_bitblt_dst_x) ],
@ -84,6 +89,7 @@ class GoblinAccel(Module): # AutoCSR ?
# also in blit.c, for r5-cmd
FUN_DONE_BIT = 31
FUN_BLIT_BIT = 0
FUN_FILL_BIT = 1
# to hold the Vex in reset
local_reset = Signal(reset = 1)
@ -99,6 +105,12 @@ class GoblinAccel(Module): # AutoCSR ?
reg_status[WORK_IN_PROGRESS_BIT].eq(1),
local_reset.eq(0),
#timeout.eq(timeout_rst),
).Elif(do_fill & ~reg_status[WORK_IN_PROGRESS_BIT],
do_fill.eq(0),
reg_r5_cmd[FUN_FILL_BIT].eq(1),
reg_status[WORK_IN_PROGRESS_BIT].eq(1),
local_reset.eq(0),
#timeout.eq(timeout_rst),
)
]