1/*
2 * Id: newport_shadow.c,v 1.3 2000/11/29 20:58:10 agx Exp $
3 */
4/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/newport_shadow.c,v 1.2 2001/11/23 19:50:45 dawes Exp $ */
5
6#ifdef HAVE_CONFIG_H
7#include "config.h"
8#endif
9
10#include "newport.h"
11
12void
13NewportRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
14{
15	int dx, dy, x;
16	CARD32 *base, *src;
17	NewportPtr pNewport = NEWPORTPTR(pScrn);
18	NewportRegsPtr pNewportRegs = pNewport->pNewportRegs;
19
20#define RA8_BYTES	4	/* burst 4 pixels each time */
21#define RA8_BYTE_SHIFT  2 	/* 4 Pixels on each burst, so divide ShadowPitch by 4 */
22#define RA8_MASK        0xffc   /* move to 4 byte boundary   */
23
24	TRACE_ENTER("NewportRefreshArea8");
25	NewportWait(pNewportRegs);
26	pNewportRegs->set.drawmode0 = (NPORT_DMODE0_DRAW |
27					NPORT_DMODE0_BLOCK |
28					NPORT_DMODE0_CHOST);
29	while(num--) {
30		NewportWait(pNewportRegs);
31		x = pbox->x1 & RA8_MASK;  	/* move x to 4 byte boundary */
32		base = pNewport->ShadowPtr
33				+ (pbox->y1 * (pNewport->ShadowPitch >> RA8_BYTE_SHIFT) )
34				+ ( x >> RA8_BYTE_SHIFT);
35
36		pNewportRegs->set.xystarti = (x << 16) | pbox->y1;
37		pNewportRegs->set.xyendi = ((pbox->x2-1) << 16) | (pbox->y2-1);
38
39		for ( dy = pbox->y1; dy < pbox->y2; dy++) {
40
41			src = base;
42			for ( dx = x; dx < pbox->x2; dx += RA8_BYTES) {
43				pNewportRegs->go.hostrw0 = *src;
44				src++;
45			}
46			base += ( pNewport->ShadowPitch >> RA8_BYTE_SHIFT );
47		}
48		pbox++;
49	}
50	TRACE_EXIT("NewportRefreshArea8");
51}
52
53
54void
55NewportRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
56{
57	int dx, dy;
58	CARD8 *src, *base;
59#ifndef NEWPORT_USE32BPP
60	CARD32 dest;
61#endif
62	NewportPtr pNewport = NEWPORTPTR(pScrn);
63	NewportRegsPtr pNewportRegs = pNewport->pNewportRegs;
64
65	TRACE_ENTER("NewportRefreshArea24");
66	NewportWait(pNewportRegs);
67
68	/* block transfers */
69	pNewportRegs->set.drawmode0 = (NPORT_DMODE0_DRAW |
70					NPORT_DMODE0_BLOCK |
71					NPORT_DMODE0_CHOST);
72
73	while(num--) {
74
75		base = (CARD8*)pNewport->ShadowPtr + pbox->y1 * pNewport->ShadowPitch + pbox->x1
76#ifdef NEWPORT_USE32BPP
77		* 4;
78#else
79		* 3;
80#endif
81		pNewportRegs->set.xystarti = (pbox->x1 << 16) | pbox->y1;
82		pNewportRegs->set.xyendi = ((pbox->x2-1) << 16) | (pbox->y2-1);
83
84		for ( dy = pbox->y1; dy < pbox->y2; dy++) {
85			src = base;
86			for ( dx = pbox->x1 ;  dx < pbox->x2 ; dx++) {
87				/* Removing these shifts by using 32bpp fb
88				 * yields < 2% percent performance gain and wastes 25% memory
89				 */
90#ifdef NEWPORT_USE32BPP
91				pNewportRegs->go.hostrw0 = *(CARD32 *)src;
92				src += 4;
93#else
94				dest = src[0] | src[1] << 8 | src[2] << 16;
95				pNewportRegs->go.hostrw0 = dest;
96				src+=3;
97#endif
98 			}
99			base += pNewport->ShadowPitch;
100 		}
101 		pbox++;
102 	}
103	TRACE_EXIT("NewportRefreshArea24");
104}
105
106