#include "A4Stuff.h" #include "SetupA4.h" #include #include #include #include "NuBusFPGA_HW.h" #define kINITid 0 #define _BitBlt 0xAB00 // #define QEMU //extern pascal void CopyBits(const BitMap *srcBits, const BitMap *dstBits, const Rect *srcRect, const Rect *dstRect, short mode, RgnHandle maskRgn) ONEWORDINLINE(0xA8EC); //extern pascal void StdBits(const BitMap *srcBits, const Rect *srcRect, const Rect *dstRect, short mode, RgnHandle maskRgn) ONEWORDINLINE(0xA8EB); #if 0 typedef pascal void (*StdBitsProc)(BitMap *srcBits, Rect *srcRect, Rect *dstRect, short mode, RgnHandle maskRgn); StdBitsProc oldStdBits; #endif typedef pascal void (*BitBltProc)(BitMap *srcBits, BitMap *maskBits, BitMap *dstBits, Rect *srcRect, Rect *maskRect, Rect *dstRect, short mode, Pattern *pat, RgnHandle rgnA, RgnHandle rgnB, RgnHandle rgnC, short multColor); static BitBltProc oldBitBlt; void* fb_base; void* bt_base; void* accel_base; static inline unsigned long brev(const unsigned long r) { return (((r&0xFF000000)>>24) | ((r&0xFF0000)>>8) | ((r&0xFF00)<<8) | ((r&0xFF)<<24)); } #define WAIT_FOR_HW(accel) \ while (accel->reg_status & brev(1<reg_status & (1<debug - (x); #else #define DLOG(X) #endif int hwblit(char* stack, char* p_fb_base, /* short dstshift, */ short mode, Pattern* pat, PixMapPtr dstpix, PixMapPtr srcpix, Rect *dstrect, Rect *srcrect) { struct goblin_bt_regs* bt = (struct goblin_bt_regs*)(p_fb_base + GOBLIN_BT_OFFSET); struct goblin_accel_regs* accel_le = (struct goblin_accel_regs*)(p_fb_base + GOBLIN_ACCEL_OFFSET_LE); struct qdstuff* qdstack = (struct qdstuff*)(stack - sizeof(struct qdstuff)); short height = qdstack->MINRECT.bottom - qdstack->MINRECT.top; short dstshift = qdstack->DSTSHIFT; short srcshift = qdstack->SRCSHIFT; if ((mode != 0) && (mode != 8)) { // only copy handled for now #ifdef QEMU 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 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; } } #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) DLOG(srcshift) DLOG(dstshift) return 0; } if (height < 0) { // no height return 0; } if (dstpix->baseAddr != p_fb_base) { // we're not destination #ifdef QEMU DLOG(-4L) DLOG((unsigned long)dstpix->baseAddr) #endif return 0; } if ((srcpix->baseAddr != p_fb_base) // && ((unsigned long)srcpix->baseAddr >= 0x40000000) // and neither is main memory ){ #ifdef QEMU DLOG(-5L) DLOG((unsigned long)srcpix->baseAddr) #endif return 0; } { Rect realrect, srcv, dstv; short width = qdstack->MINRECT.right - qdstack->MINRECT.left; short src_check = 0x07 >> srcshift; short dst_check = 0x07 >> dstshift; //*debug_ptr = -1L; realrect.top = qdstack->MINRECT.top; realrect.left = qdstack->MINRECT.left; //realrect.bottom = qdstack->MINRECT.bottom; //realrect.right = qdstack->MINRECT.right; realrect.top += (srcrect->top - dstrect->top); 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; dstv.top = qdstack->MINRECT.top - dstpix->bounds.top; dstv.left = qdstack->MINRECT.left - dstpix->bounds.left; // must be byte-aligned for now if (width & src_check) return 0; if (srcv.left & src_check) return 0; if (dstv.left & dst_check) return 0; /* if .baseAddr of both pix are different, no overlap */ /* // the HW can handle that for us if (dstpix->baseAddr == srcpix->baseAddr) { } */ #ifdef QEMU #if 0 if ((mode == 8) && (qdstack->PATROW == 0)) { DLOG(0x87654321) DLOG(qdstack->EXPAT[ 0]) DLOG(qdstack->EXPAT[ 1]) DLOG(qdstack->EXPAT[ 2]) DLOG(qdstack->EXPAT[ 3]) DLOG(qdstack->EXPAT[ 4]) DLOG(qdstack->EXPAT[ 5]) DLOG(qdstack->EXPAT[ 6]) DLOG(qdstack->EXPAT[ 7]) DLOG(qdstack->EXPAT[ 8]) DLOG(qdstack->EXPAT[ 9]) DLOG(qdstack->EXPAT[10]) DLOG(qdstack->EXPAT[11]) DLOG(qdstack->EXPAT[12]) DLOG(qdstack->EXPAT[13]) DLOG(qdstack->EXPAT[14]) DLOG(qdstack->EXPAT[15]) } #endif DLOG(-1L) DLOG(srcpix->rowBytes) DLOG(dstpix->rowBytes) DLOG(srcv.top) DLOG(srcv.left) DLOG(height) DLOG(width) DLOG(dstv.top) DLOG(dstv.left) DLOG((long)dstpix->baseAddr) DLOG((long)srcpix->baseAddr) return 0; #else WAIT_FOR_HW_LE(accel_le); accel_le->reg_width = (width); // pixels accel_le->reg_height = (height); accel_le->reg_bitblt_dst_x = (dstv.left); // pixels accel_le->reg_bitblt_dst_y = (dstv.top); if (dstpix->baseAddr != p_fb_base) accel_le->reg_dst_ptr = (unsigned long)(dstpix->baseAddr); else accel_le->reg_dst_ptr = 0; // let the HW pick its internal address accel_le->reg_dst_stride = (dstpix->rowBytes); // bytes // we should strip the high-order bit, but the HW ignore that for us anyway if (mode == 0) { accel_le->reg_bitblt_src_x = (srcv.left); // pixels accel_le->reg_bitblt_src_y = (srcv.top); if (srcpix->baseAddr != p_fb_base) accel_le->reg_src_ptr = (unsigned long)(srcpix->baseAddr); else accel_le->reg_src_ptr = 0; // let the HW pick its internal address 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<reg_fgcolor = (qdstack->EXPAT[0]); accel_le->reg_cmd = (1<