1 /*****************************************************************************\
2 * Tseng Labs ET6000, ET6100 and ET6300 graphics driver for BeOS 5.
3 * Copyright (c) 2003-2004, Evgeniy Vladimirovich Bobkov.
4 \*****************************************************************************/
6 #include "GlobalData.h"
10 /*****************************************************************************/
12 * Set bits in a byte pointed by addr; mask must contain 0s at the bits
13 * positions to be set and must contain 1s at all other bits; val must
14 * contain the values of bits to be set.
16 static __inline
void set8(volatile unsigned char *addr
, unsigned char mask
,
22 *addr
= (*addr
& mask
) | (val
& ~mask
);
24 /*****************************************************************************/
25 static __inline
unsigned char get8(volatile unsigned char *addr
)
29 /*****************************************************************************/
30 static __inline
void et6000aclTerminate(void) {
31 set8(mmRegs
+0x31, 0xef, 0x10); /* let ACL to operate */
33 set8(mmRegs
+0x30, 0, 0x00);
34 set8(mmRegs
+0x30, 0, 0x01);
36 set8(mmRegs
+0x30, 0, 0x00);
37 set8(mmRegs
+0x30, 0, 0x10);
39 set8(mmRegs
+0x30, 0, 0x00);
41 /*****************************************************************************/
43 * bpp must be bytes per pixel, not bits!
45 void et6000aclInit(uint8 bpp
) {
49 set8(mmRegs
+0x31, 0xef, 0x10); /* let ACL to operate */
50 set8(mmRegs
+0x32, 0x99, 0x00); /* maximize the performance */
51 set8(mmRegs
+0x8e, 0xcf, (bpp
- 1) << 4); /* set pixel color depth */
52 set8(mmRegs
+0x91, 0x80, 0x00); /* maximize the performance */
53 set8(mmRegs
+0x9d, 0x00, 0x00); /* maximize the performance */
55 /*****************************************************************************/
57 * Wait until ACL becomes idle.
59 void et6000aclWaitIdle(void) {
60 while ((get8(mmRegs
+0x36) & 0x02) == 0x02);
62 /*****************************************************************************/
64 * Wait until ACL queue becomes not full.
66 static __inline
void et6000aclWaitQueueNotFull(void) {
67 while ((get8(mmRegs
+0x36) & 0x01) == 0x01);
69 /*****************************************************************************/
71 * Move the specified list of rectangular regions from one location in
72 * the frame buffer to another in the order they are specified in the
73 * blit_params *list. The list is uint32 count elements in length.
75 void SCREEN_TO_SCREEN_BLIT(engine_token
*et
,
79 uint16 screenWidth
= si
->dm
.virtual_width
;
80 uint8 bpp
= si
->bytesPerPixel
;
82 uint16 src_left
, src_top
, dest_left
, dest_top
, width
, height
;
83 uint32 srcAddr
= 0, destAddr
= 0;
85 et6000aclWaitQueueNotFull();
87 set8(mmRegs
+0x92, 0x80, 0x77); /* no source wrap */
88 set8(mmRegs
+0x9c, 0x00, 0x33); /* mask=1 always, always use FGR */
89 set8(mmRegs
+0x9f, 0x00, 0xcc); /* FGR ROP = copy of source */
91 /* Set the source Y offset */
92 *((vuint16
*)(mmRegs
+0x8a)) = screenWidth
* bpp
- 1;
94 /* Set the destination Y offset */
95 *((vuint16
*)(mmRegs
+0x8c)) = screenWidth
* bpp
- 1;
98 src_left
= list
->src_left
;
99 src_top
= list
->src_top
;
100 dest_left
= list
->dest_left
;
101 dest_top
= list
->dest_top
;
103 height
= list
->height
;
105 et6000aclWaitQueueNotFull();
107 /* Set the direction and opcode(BitBLT) register */
109 if (src_left
< dest_left
) bltDir
|= 0x01;
110 if (src_top
< dest_top
) bltDir
|= 0x02;
111 set8(mmRegs
+0x8f, 0x3c, bltDir
);
113 /* Set the X count register */
114 *((vuint16
*)(mmRegs
+0x98)) = (width
+ 1) * bpp
- 1;
116 /* Set the Y count register */
117 *((vuint16
*)(mmRegs
+0x9a)) = height
;
119 switch (bltDir
& 0x03) {
121 srcAddr
= (src_top
* screenWidth
+ src_left
) * bpp
;
122 destAddr
= (dest_top
* screenWidth
+ dest_left
) * bpp
;
126 srcAddr
= (src_top
* screenWidth
+ src_left
+ width
) * bpp
+ bpp
-1;
127 destAddr
= (dest_top
* screenWidth
+ dest_left
+ width
) * bpp
+ bpp
-1;
131 srcAddr
= ((src_top
+ height
)*screenWidth
+ src_left
) * bpp
;
132 destAddr
= ((dest_top
+ height
)*screenWidth
+ dest_left
) * bpp
;
136 srcAddr
= ((src_top
+ height
)*screenWidth
+ src_left
+ width
) * bpp
+ bpp
-1;
137 destAddr
= ((dest_top
+ height
)*screenWidth
+ dest_left
+ width
) * bpp
+ bpp
-1;
141 /* Set the source address */
142 *((vuint32
*)(mmRegs
+0x84)) = srcAddr
;
145 * Set the destination address -
146 * this action starts the BitBLT operation.
148 *((vuint32
*)(mmRegs
+0xa0)) = destAddr
;
155 /*****************************************************************************/
157 * Fill the specified list of rectangular regions with the specified color.
158 * The list is uint32 count elements in length. The rectangular regions are
159 * inclusive. The uint32 color is specified in the same configuration and
160 * byte order as the current display_mode. All coordinates in the list of
161 * rectangles is guaranteed to have been clipped to the virtual limits of
164 void FILL_RECTANGLE(engine_token
*et
,
166 fill_rect_params
*list
,
169 uint16 screenWidth
= si
->dm
.virtual_width
;
170 uint8 bpp
= si
->bytesPerPixel
;
171 uint16 left
, top
, right
, bottom
;
176 * Normally WaitQueueNotFull should be required & enough, but in reality
177 * this is somewhy sometimes not enough for pixel depth of 3 bytes.
180 et6000aclWaitQueueNotFull();
185 * We'll put the color at 4 bytes just after the framebuffer.
186 * The srcAddr must be 4 bytes aligned and is always for standard
189 srcAddr
= (uint32
)si
->framebuffer
- (uint32
)si
->memory
+
190 si
->dm
.virtual_width
* si
->dm
.virtual_height
* bpp
;
194 set8(mmRegs
+0x92, 0x80, 0x02); /* 4x1 source wrap */
195 for (i
= 0; i
< 2; i
++) /* copy the color to source address */
196 ((vuint16
*)((uint32
)si
->memory
+ srcAddr
))[i
] = (uint16
)color
;
199 set8(mmRegs
+0x92, 0x80, 0x0a); /* 3x1 source wrap */
200 for (i
= 0; i
< 3; i
++) /* copy the color to source address */
201 ((vuint8
*)((uint32
)si
->memory
+ srcAddr
))[i
] = ((uint8
*)&color
)[i
];
206 set8(mmRegs
+0x9c, 0x00, 0x33); /* mask=1 always, always use FGR */
207 set8(mmRegs
+0x9f, 0x00, 0xcc); /* FGR ROP = copy of source */
209 /* Set the source Y offset */
210 *((vuint16
*)(mmRegs
+0x8a)) = screenWidth
* bpp
- 1;
211 /* Set the destination Y offset */
212 *((vuint16
*)(mmRegs
+0x8c)) = screenWidth
* bpp
- 1;
214 /* Set the direction and opcode(trapezoid) register (primary edge) */
215 set8(mmRegs
+0x8f, 0x18, 0x40);
216 /* Set the secondary edge register */
217 set8(mmRegs
+0x93, 0x1a, 0x00);
219 /* Set the primary delta minor register */
220 *((vuint16
*)(mmRegs
+0xac)) = 0;
221 /* Set the secondary delta minor register */
222 *((vuint16
*)(mmRegs
+0xb4)) = 0;
228 bottom
= list
->bottom
;
230 et6000aclWaitQueueNotFull();
232 /* Set the X count register */
233 *((vuint16
*)(mmRegs
+0x98)) = (right
-left
+1)*bpp
- 1;
234 /* Set the Y count register */
235 *((vuint16
*)(mmRegs
+0x9a)) = bottom
-top
;
237 /* Set the primary delta major register */
238 *((vuint16
*)(mmRegs
+0xae)) = bottom
-top
;
240 /* Set the secondary delta major register */
241 *((vuint16
*)(mmRegs
+0xb6)) = bottom
-top
;
243 /* Set the source address */
244 *((vuint32
*)(mmRegs
+0x84)) = srcAddr
;
247 * Set the destination address -
248 * this action starts the trapezoid operation.
250 *((vuint32
*)(mmRegs
+0xa0)) = (top
* screenWidth
+ left
) * bpp
;
257 /*****************************************************************************/