mirror of
https://github.com/rdolbeau/NuBusFPGA.git
synced 2025-02-03 15:32:15 +00:00
HW-acceel big pattern (not sure about alignment...), add basic Icon w/ ShowInitIcon
This commit is contained in:
parent
173c87ea02
commit
733f446b27
@ -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;
|
||||
|
BIN
nubus-to-ztex-gateware/NuBusFPGAInit/NuBusFPGAInit.rsrc.bin
Normal file
BIN
nubus-to-ztex-gateware/NuBusFPGAInit/NuBusFPGAInit.rsrc.bin
Normal file
Binary file not shown.
@ -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
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
|
Loading…
x
Reference in New Issue
Block a user