1 /*
2 Haiku S3 Virge driver adapted from the X.org Virge driver.
3
4 Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved.
5
6 Copyright 2007 Haiku, Inc. All rights reserved.
7 Distributed under the terms of the MIT license.
8
9 Authors:
10 Gerald Zajac 2007
11 */
12
13
14 #include "accel.h"
15 #include "virge.h"
16
17
18
WaitForSync()19 static inline void WaitForSync()
20 {
21 while ((IN_SUBSYS_STAT() & 0x2000) == 0) ;
22 }
23
24
25
26 void
Virge_FillRectangle(engine_token * et,uint32 color,fill_rect_params * pList,uint32 count)27 Virge_FillRectangle(engine_token* et, uint32 color, fill_rect_params* pList, uint32 count)
28 {
29 int rop = 0xF0;
30 int cmd = DRAW | rop << 17 | CMD_RECT | CMD_XP | CMD_YP ;
31
32 (void)et; // avoid compiler warning for unused arg
33
34 cmd |= gInfo.sharedInfo->commonCmd;
35
36 while (count--) {
37 int x = pList->left;
38 int y = pList->top;
39 int w = pList->right - x + 1;
40 int h = pList->bottom - y + 1;
41
42 gInfo.WaitQueue(4);
43 WriteReg32(PAT_FG_CLR, color);
44 WriteReg32(RWIDTH_HEIGHT, ((w - 1) << 16) | h);
45 WriteReg32(RDEST_XY, (x << 16) | y);
46 WriteReg32(CMD_SET, cmd);
47 WaitForSync();
48
49 pList++;
50 }
51 }
52
53
54 void
Virge_FillSpan(engine_token * et,uint32 color,uint16 * pList,uint32 count)55 Virge_FillSpan(engine_token* et, uint32 color, uint16* pList, uint32 count)
56 {
57 int rop = 0xF0;
58 int cmd = DRAW | rop << 17 | CMD_RECT | CMD_XP | CMD_YP ;
59
60 (void)et; // avoid compiler warning for unused arg
61
62 cmd |= gInfo.sharedInfo->commonCmd;
63
64 while (count--) {
65 int y = *pList++;
66 int x = *pList++;
67 int w = *pList++ - x + 1;
68
69 // The MediaPlayer in Zeta 1.21 displays a window which has 2 zero width
70 // spans which the Virge chips display as a line completely across the
71 // screen; thus, the following if statement discards any span with zero
72 // or negative width.
73
74 if (w <= 0)
75 continue;
76
77 // Draw the span as a rectangle with a height of 1 to avoid the
78 // extra complexity of drawing a line.
79
80 gInfo.WaitQueue(4);
81 WriteReg32(PAT_FG_CLR, color);
82 WriteReg32(RWIDTH_HEIGHT, ((w - 1) << 16) | 1);
83 WriteReg32(RDEST_XY, (x << 16) | y);
84 WriteReg32(CMD_SET, cmd);
85 WaitForSync();
86 }
87 }
88
89
90 void
Virge_InvertRectangle(engine_token * et,fill_rect_params * pList,uint32 count)91 Virge_InvertRectangle(engine_token* et, fill_rect_params* pList, uint32 count)
92 {
93 int rop = 0x55; // use GXinvert for rop
94 int cmd = DRAW | rop << 17 | CMD_RECT | CMD_XP | CMD_YP;
95
96 (void)et; // avoid compiler warning for unused arg
97
98 cmd |= gInfo.sharedInfo->commonCmd;
99
100 while (count--) {
101 int x = pList->left;
102 int y = pList->top;
103 int w = pList->right - x + 1;
104 int h = pList->bottom - y + 1;
105
106 gInfo.WaitQueue(3);
107 WriteReg32(RWIDTH_HEIGHT, ((w - 1) << 16) + h);
108 WriteReg32(RDEST_XY, (x << 16) | y);
109 WriteReg32(CMD_SET, cmd);
110 WaitForSync();
111
112 pList++;
113 }
114 }
115
116
117 void
Virge_ScreenToScreenBlit(engine_token * et,blit_params * pList,uint32 count)118 Virge_ScreenToScreenBlit(engine_token* et, blit_params* pList, uint32 count)
119 {
120 int rop = 0xCC; // use GXcopy for rop
121 int cmd = DRAW | rop << 17 | CMD_BITBLT | CMD_XP | CMD_YP;
122
123 (void)et; // avoid compiler warning for unused arg
124
125 cmd |= gInfo.sharedInfo->commonCmd;
126
127 while (count--) {
128 int src_x = pList->src_left;
129 int src_y = pList->src_top;
130 int dest_x = pList->dest_left;
131 int dest_y = pList->dest_top;
132 int width = pList->width;
133 int height = pList->height;
134
135 if (src_x == dest_x && src_y == dest_y)
136 continue;
137
138 cmd |= CMD_XP | CMD_YP; // restore these flags in case removed on last iteration
139
140 if (src_x < dest_x) {
141 src_x += width;
142 dest_x += width;
143 cmd &= ~CMD_XP;
144 }
145
146 if (src_y < dest_y) {
147 src_y += height;
148 dest_y += height;
149 cmd &= ~CMD_YP;
150 }
151
152 gInfo.WaitQueue(4);
153 WriteReg32(RWIDTH_HEIGHT, ((width) << 16) | (height + 1));
154 WriteReg32(RSRC_XY, (src_x << 16) | src_y);
155 WriteReg32(RDEST_XY, (dest_x << 16) | dest_y);
156 WriteReg32(CMD_SET, cmd);
157 WaitForSync();
158
159 pList ++;
160 }
161 }
162