HW-acceel big pattern (not sure about alignment...), add basic Icon w/ ShowInitIcon

This commit is contained in:
Romain Dolbeau 2022-06-25 08:51:17 +02:00
parent 173c87ea02
commit 733f446b27
5 changed files with 145 additions and 53 deletions

View File

@ -6,6 +6,8 @@
#include "NuBusFPGA_HW.h"
#include "ShowInitIcon.h"
#define kINITid 0
#define _BitBlt 0xAB00
@ -45,7 +47,7 @@ static inline unsigned long brev(const unsigned long r) {
#include "NuBusFPGA_QD.h"
#ifdef QEMU
#define DLOG(x) bt->debug - (x);
#define DLOG(x) bt->debug = (x);
#else
#define DLOG(X)
#endif
@ -57,68 +59,53 @@ 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;
short srcshift = qdstack->SRCSHIFT;
short expat_size = 0;
if ((mode != 0) && (mode != 8)) { // only copy handled for now
#ifdef QEMU
#if 0
DLOG(-2L)
DLOG(mode)
if (mode == 8) {
DLOG(qdstack->PATROW)
#if 0
DLOG(pat->pat[0])
DLOG(pat->pat[1])
DLOG(pat->pat[2])
DLOG(pat->pat[3])
DLOG(pat->pat[4])
DLOG(pat->pat[5])
DLOG(pat->pat[6])
DLOG(pat->pat[7])
#endif
}
#endif
return 0;
}
if (mode == 8) {
register int i;
register int i, n;
register unsigned long expat0 = qdstack->EXPAT[0];
if (qdstack->PATROW != 0) {
DLOG(-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]) {
DLOG(-7L)
DLOG(i)
DLOG(expat0)
DLOG(qdstack->EXPAT[i])
return 0;
DLOG((unsigned long)qdstack->EXPAT)
expat_size = (qdstack->PATVMASK+1) >> 2;
DLOG(expat_size)
for (i = 0 ; i < expat_size ; i++) {
DLOG(qdstack->EXPAT[i])
}
// PATROW is the stride between lines (bytes)
DLOG(qdstack->PATROW)
// PATVMASK has the number of bytes-1 in the pattern?
DLOG(qdstack->PATVMASK)
// PATHMASK has ???
DLOG(qdstack->PATHMASK)
DLOG(qdstack->PATVPOS)
DLOG(qdstack->PATHPOS)
if (expat_size > 16384)
return 0;
} else {
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]) {
DLOG(-7L)
DLOG(i)
DLOG(expat0)
DLOG(qdstack->EXPAT[i])
return 0;
}
}
}
#if 0
if (dstshift < 3) { // only 8/16/32 bits for now
#ifdef QEMU
DLOG(-3L)
DLOG(dstshift)
#endif
return 0;
}
dstshift -= 3;
if (srcshift < 3) { // only 8/16/32 bits for now
#ifdef QEMU
DLOG(-8L)
DLOG(srcshift)
#endif
return 0;
}
srcshift -= 3;
#endif
if (srcshift != dstshift) {
DLOG(-9L)
@ -133,7 +120,7 @@ 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
#if 0//def QEMU
DLOG(-4L)
DLOG((unsigned long)dstpix->baseAddr)
#endif
@ -143,7 +130,7 @@ int hwblit(char* stack, char* p_fb_base, /* short dstshift, */ short mode, Patte
if ((srcpix->baseAddr != p_fb_base)
// && ((unsigned long)srcpix->baseAddr >= 0x40000000) // and neither is main memory
){
#ifdef QEMU
#if 0//def QEMU
DLOG(-5L)
DLOG((unsigned long)srcpix->baseAddr)
#endif
@ -210,6 +197,8 @@ int hwblit(char* stack, char* p_fb_base, /* short dstshift, */ short mode, Patte
DLOG(qdstack->EXPAT[15])
}
#endif
#if 0
DLOG(-1L)
DLOG(srcpix->rowBytes)
@ -226,6 +215,7 @@ int hwblit(char* stack, char* p_fb_base, /* short dstshift, */ short mode, Patte
DLOG((long)dstpix->baseAddr)
DLOG((long)srcpix->baseAddr)
#endif
return 0;
#else
@ -251,8 +241,19 @@ int hwblit(char* stack, char* p_fb_base, /* short dstshift, */ short mode, Patte
accel_le->reg_src_stride = (srcpix->rowBytes); // bytes // we should strip the high-order bit, but the HW ignore that for us anyway
accel_le->reg_cmd = (1<<DO_BLIT_BIT);
} else if (mode == 8) {
accel_le->reg_fgcolor = (qdstack->EXPAT[0]);
accel_le->reg_cmd = (1<<DO_FILL_BIT);
if (qdstack->PATROW == 0) { // not big pattern, need to improve for non-constant?
accel_le->reg_fgcolor = (qdstack->EXPAT[0]);
accel_le->reg_cmd = (1<<DO_FILL_BIT);
} else { // big pattern
register unsigned short i;
for (i = 0 ; i < expat_size ; i++) {
((unsigned long*)(p_fb_base + GOBLIN_PATTERN_OFFSET))[i] = qdstack->EXPAT[i];
}
accel_le->reg_bitblt_src_x = qdstack->PATROW - 1;
accel_le->reg_bitblt_src_y = ((qdstack->PATVMASK+1)/qdstack->PATROW)-1;
accel_le->reg_src_stride = qdstack->PATROW;
accel_le->reg_cmd = (1<<DO_PATT_BIT);
}
}
WAIT_FOR_HW_LE(accel_le);
@ -348,6 +349,8 @@ void main(void)
//*debug_ptr = (unsigned long)oldBitBlt;
SetToolTrapAddress((UniversalProcPtr)myBitBlt, _BitBlt);
ShowInitIcon(128, true);
/* restore the a4 world */
SetA4(oldA4);
// *debug_ptr = 0xBEEFDEAD;

View File

@ -7,6 +7,10 @@
#define GOBLIN_ACCEL_OFFSET 0x00901000
#define GOBLIN_ACCEL_OFFSET_LE 0x00901800
#define GOBLIN_FB_OFFSET 0x00000000
#define GOBLIN_PATTERN_OFFSET 0x007F0000 // 8 MiB - 64 KiB
#define u_int32_t volatile unsigned long
// status
@ -15,6 +19,7 @@
// cmd
#define DO_BLIT_BIT 0 // hardwired in goblin_accel.py
#define DO_FILL_BIT 1 // hardwired in goblin_accel.py
#define DO_PATT_BIT 2 // hardwired in goblin_accel.py
#define DO_TEST_BIT 3 // hardwired in goblin_accel.py

View File

@ -33,10 +33,13 @@ 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_PATT_BIT 2 // hardwired in goblin_accel.py
#define FUN_TEST_BIT 3 // 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_PATT (1<<FUN_PATT_BIT)
#define FUN_TEST (1<<FUN_TEST_BIT)
#define FUN_DONE (1<<FUN_DONE_BIT)
@ -146,6 +149,18 @@ static void bitblit(const unsigned_param_type xs,
const unsigned_param_type dst_stride
);
static void patternrectfill(const unsigned_param_type xd,
const unsigned_param_type yd,
const unsigned_param_type wi,
const unsigned_param_type re,
unsigned char *pat_ptr,
const unsigned_param_type pat_xmask,
const unsigned_param_type pat_ymask,
const unsigned_param_type pat_stride,
unsigned char* dst_ptr,
const unsigned_param_type dst_stride
);
static void print_hexword(unsigned int v, unsigned int bx, unsigned int by);
static void show_status_on_screen(void);
@ -244,6 +259,16 @@ void from_reset(void) {
fbc->reg_dst_ptr ? (unsigned char*)fbc->reg_dst_ptr : (unsigned char*)BASE_FB,
fbc->reg_dst_stride); // assumed to be scaled already
} break;
case FUN_PATT: {
patternrectfill(dstx, fbc->reg_bitblt_dst_y,
wi , fbc->reg_height,
(unsigned char*)BASE_FB + (8*1024*1024) - (64*1024), // FIXME
fbc->reg_bitblt_src_x, // unscaled
fbc->reg_bitblt_src_y, // unscaled
fbc->reg_src_stride,
fbc->reg_dst_ptr ? (unsigned char*)fbc->reg_dst_ptr : (unsigned char*)BASE_FB,
fbc->reg_dst_stride); // assumed to be scaled already
} break;
default:
break;
}
@ -881,3 +906,52 @@ static void bitblit_fwd_fwd_copy(const unsigned_param_type xs,
dptr_line += dst_stride;
}
}
static void patternrectfill(const unsigned_param_type xd,
const unsigned_param_type yd,
const unsigned_param_type wi,
const unsigned_param_type re,
unsigned char *pat_ptr,
const unsigned_param_type pat_xmask,
const unsigned_param_type pat_ymask,
const unsigned_param_type pat_stride,
unsigned char* dst_ptr,
const unsigned_param_type dst_stride
) {
struct goblin_accel_regs* fbc = (struct goblin_accel_regs*)BASE_ACCEL_REGS;
unsigned int i, j;
unsigned int io, jo;
unsigned char *dptr = (dst_ptr + (yd * dst_stride) + xd);
unsigned char *dptr_line = dptr;
unsigned char *pat_ptr_line;
io = xd & pat_xmask;
jo = yd & pat_ymask;
pat_ptr_line = pat_ptr + (jo & pat_ymask) * pat_stride;
for (j = 0 ; j < re ; j++) {
unsigned char *dptr_elt = dptr_line;
i = 0;
for ( ; i < wi && ((unsigned int)dptr_elt&0x3)!=0; i++) {
dptr_elt[0] = pat_ptr_line[(i+io) & pat_xmask];
dptr_elt ++;
}
unsigned int fsr_cst = 8*((i+io) & 0x3);
unsigned int src0 = ((unsigned int*)pat_ptr_line)[((i+io) & pat_xmask) >> 2];
for ( ; i < (wi-3) ; i+=4) {
unsigned int src1 = ((unsigned int*)pat_ptr_line)[((i+io+4) & pat_xmask) >> 2];
unsigned int val;
asm("fsr %0, %1, %2, %3\n" : "=r"(val) : "r"(src0), "r"(src1), "r"(fsr_cst));
((unsigned int*)dptr_elt)[0] = val;
src0 = src1;
dptr_elt += 4;
}
for ( ; i < wi ; i++) {
dptr_elt[0] = pat_ptr_line[(i+io) & pat_xmask];
dptr_elt ++;
}
dptr_line += dst_stride;
pat_ptr_line = pat_ptr + ((j+jo) & pat_ymask) * pat_stride;
}
}

View File

@ -37,11 +37,13 @@ class GoblinAccel(Module): # AutoCSR ?
# do-some-work flags
do_blit = Signal()
do_fill = Signal()
do_patt = Signal()
do_test = Signal()
# cmd register reg_cmd
DO_BLIT_BIT = 0
DO_FILL_BIT = 1
DO_PATT_BIT = 2
DO_TEST_BIT = 3
# global status register reg_status
@ -80,6 +82,7 @@ class GoblinAccel(Module): # AutoCSR ?
1: [ NextValue(reg_cmd, bus_dat_w_endian),
NextValue(do_blit, bus_dat_w_endian[DO_BLIT_BIT] & ~reg_status[WORK_IN_PROGRESS_BIT]),
NextValue(do_fill, bus_dat_w_endian[DO_FILL_BIT] & ~reg_status[WORK_IN_PROGRESS_BIT]),
NextValue(do_patt, bus_dat_w_endian[DO_PATT_BIT] & ~reg_status[WORK_IN_PROGRESS_BIT]),
NextValue(do_test, bus_dat_w_endian[DO_TEST_BIT] & ~reg_status[WORK_IN_PROGRESS_BIT]),
],
2: [ NextValue(reg_r5_cmd, bus_dat_w_endian) ],
@ -128,6 +131,7 @@ class GoblinAccel(Module): # AutoCSR ?
FUN_DONE_BIT = 31
FUN_BLIT_BIT = 0
FUN_FILL_BIT = 1
FUN_PATT_BIT = 2
FUN_TEST_BIT = 3
# to hold the Vex in reset
local_reset = Signal(reset = 1)
@ -150,6 +154,12 @@ class GoblinAccel(Module): # AutoCSR ?
reg_status[WORK_IN_PROGRESS_BIT].eq(1),
local_reset.eq(0),
#timeout.eq(timeout_rst),
).Elif(do_patt & ~reg_status[WORK_IN_PROGRESS_BIT],
do_patt.eq(0),
reg_r5_cmd[FUN_PATT_BIT].eq(1),
reg_status[WORK_IN_PROGRESS_BIT].eq(1),
local_reset.eq(0),
#timeout.eq(timeout_rst),
).Elif(do_test & ~reg_status[WORK_IN_PROGRESS_BIT],
do_test.eq(0),
reg_r5_cmd[FUN_TEST_BIT].eq(1),