1 /*
2 Haiku S3 Trio64 driver adapted from the X.org S3 driver.
3
4 Copyright 2001 Ani Joshi <ajoshi@unixbox.com>
5
6 Copyright 2008 Haiku, Inc. All rights reserved.
7 Distributed under the terms of the MIT license.
8
9 Authors:
10 Gerald Zajac 2008
11 */
12
13
14 #include "accel.h"
15 #include "trio64.h"
16
17
18
19 void
Trio64_FillRectangle(engine_token * et,uint32 color,fill_rect_params * pList,uint32 count)20 Trio64_FillRectangle(engine_token* et, uint32 color, fill_rect_params* pList,
21 uint32 count)
22 {
23 (void)et; // avoid compiler warning for unused arg
24
25 gInfo.WaitQueue(3);
26 WriteReg16(MULTIFUNC_CNTL, 0xa000);
27 WriteReg32(FRGD_COLOR, color);
28 WriteReg16(FRGD_MIX, FSS_FRGDCOL | 0x07); // 7 = GXcopy rop
29
30 while (count--) {
31 int x = pList->left;
32 int y = pList->top;
33 int w = pList->right - x;
34 int h = pList->bottom - y;
35
36 gInfo.WaitQueue(5);
37 WriteReg16(CUR_X, x);
38 WriteReg16(CUR_Y, y);
39 WriteReg16(CUR_WIDTH, w);
40 WriteReg16(MULTIFUNC_CNTL, h);
41 WriteReg16(CMD, CMD_RECT | DRAW | INC_X | INC_Y | WRTDATA);
42
43 pList++;
44 }
45 }
46
47
48 void
Trio64_FillSpan(engine_token * et,uint32 color,uint16 * pList,uint32 count)49 Trio64_FillSpan(engine_token* et, uint32 color, uint16* pList, uint32 count)
50 {
51 (void)et; // avoid compiler warning for unused arg
52
53 gInfo.WaitQueue(3);
54 WriteReg16(MULTIFUNC_CNTL, 0xa000);
55 WriteReg32(FRGD_COLOR, color);
56 WriteReg16(FRGD_MIX, FSS_FRGDCOL | 0x07); // 7 = GXcopy rop
57
58 while (count--) {
59 int y = *pList++;
60 int x = *pList++;
61 int w = *pList++ - x;
62
63 // Some S3 chips display a line completely across the screen when a
64 // span has zero width; thus, the following if statement discards any
65 // span with zero or negative width.
66
67 if (w < 0)
68 continue;
69
70 // Draw the span as a rectangle with a height of 1 to avoid the
71 // extra complexity of drawing a line.
72
73 gInfo.WaitQueue(5);
74 WriteReg16(CUR_X, x);
75 WriteReg16(CUR_Y, y);
76 WriteReg16(CUR_WIDTH, w);
77 WriteReg16(MULTIFUNC_CNTL, 0); // height is 1; but as computed it is 0
78 WriteReg16(CMD, CMD_RECT | DRAW | INC_X | INC_Y | WRTDATA);
79 }
80 }
81
82
83 void
Trio64_InvertRectangle(engine_token * et,fill_rect_params * pList,uint32 count)84 Trio64_InvertRectangle(engine_token* et, fill_rect_params* pList, uint32 count)
85 {
86 (void)et; // avoid compiler warning for unused arg
87
88 gInfo.WaitQueue(2);
89 WriteReg16(MULTIFUNC_CNTL, 0xa000);
90 WriteReg16(FRGD_MIX, FSS_FRGDCOL | 0x00); // 0 = GXinvert rop
91
92 while (count--) {
93 int x = pList->left;
94 int y = pList->top;
95 int w = pList->right - x;
96 int h = pList->bottom - y;
97
98 gInfo.WaitQueue(5);
99 WriteReg16(CUR_X, x);
100 WriteReg16(CUR_Y, y);
101 WriteReg16(CUR_WIDTH, w);
102 WriteReg16(MULTIFUNC_CNTL, h);
103 WriteReg16(CMD, CMD_RECT | DRAW | INC_X | INC_Y | WRTDATA);
104
105 pList++;
106 }
107 }
108
109
110 void
Trio64_ScreenToScreenBlit(engine_token * et,blit_params * pList,uint32 count)111 Trio64_ScreenToScreenBlit(engine_token* et, blit_params* pList, uint32 count)
112 {
113 (void)et; // avoid compiler warning for unused arg
114
115 gInfo.WaitQueue(2);
116 WriteReg16(MULTIFUNC_CNTL, 0xa000);
117 WriteReg16(FRGD_MIX, FSS_BITBLT | 0x07); // 7 = GXcopy rop
118
119 while (count--) {
120 int src_x = pList->src_left;
121 int src_y = pList->src_top;
122 int dest_x = pList->dest_left;
123 int dest_y = pList->dest_top;
124 int width = pList->width;
125 int height = pList->height;
126
127 if (src_x == dest_x && src_y == dest_y)
128 continue;
129
130 int cmd = CMD_BITBLT | DRAW | INC_X | INC_Y | WRTDATA;
131
132 if (src_x < dest_x) {
133 src_x += width;
134 dest_x += width;
135 cmd &= ~INC_X;
136 }
137
138 if (src_y < dest_y) {
139 src_y += height;
140 dest_y += height;
141 cmd &= ~INC_Y;
142 }
143
144 gInfo.WaitQueue(7);
145 WriteReg16(CUR_X, src_x);
146 WriteReg16(CUR_Y, src_y);
147 WriteReg16(DESTX_DIASTP, dest_x);
148 WriteReg16(DESTY_AXSTP, dest_y);
149 WriteReg16(CUR_WIDTH, width);
150 WriteReg16(MULTIFUNC_CNTL, height);
151 WriteReg16(CMD, cmd);
152
153 pList ++;
154 }
155 }
156