vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / accelerants / s3 / virge_draw.cpp
blob153fa062bb862175a382b31b9ee46bd2ac0baab2
1 /*
2 Haiku S3 Virge driver adapted from the X.org Virge driver.
4 Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved.
6 Copyright 2007 Haiku, Inc. All rights reserved.
7 Distributed under the terms of the MIT license.
9 Authors:
10 Gerald Zajac 2007
14 #include "accel.h"
15 #include "virge.h"
19 static inline void WaitForSync()
21 while ((IN_SUBSYS_STAT() & 0x2000) == 0) ;
26 void
27 Virge_FillRectangle(engine_token* et, uint32 color, fill_rect_params* pList, uint32 count)
29 int rop = 0xF0;
30 int cmd = DRAW | rop << 17 | CMD_RECT | CMD_XP | CMD_YP ;
32 (void)et; // avoid compiler warning for unused arg
34 cmd |= gInfo.sharedInfo->commonCmd;
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;
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();
49 pList++;
54 void
55 Virge_FillSpan(engine_token* et, uint32 color, uint16* pList, uint32 count)
57 int rop = 0xF0;
58 int cmd = DRAW | rop << 17 | CMD_RECT | CMD_XP | CMD_YP ;
60 (void)et; // avoid compiler warning for unused arg
62 cmd |= gInfo.sharedInfo->commonCmd;
64 while (count--) {
65 int y = *pList++;
66 int x = *pList++;
67 int w = *pList++ - x + 1;
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.
74 if (w <= 0)
75 continue;
77 // Draw the span as a rectangle with a height of 1 to avoid the
78 // extra complexity of drawing a line.
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();
90 void
91 Virge_InvertRectangle(engine_token* et, fill_rect_params* pList, uint32 count)
93 int rop = 0x55; // use GXinvert for rop
94 int cmd = DRAW | rop << 17 | CMD_RECT | CMD_XP | CMD_YP;
96 (void)et; // avoid compiler warning for unused arg
98 cmd |= gInfo.sharedInfo->commonCmd;
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;
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();
112 pList++;
117 void
118 Virge_ScreenToScreenBlit(engine_token* et, blit_params* pList, uint32 count)
120 int rop = 0xCC; // use GXcopy for rop
121 int cmd = DRAW | rop << 17 | CMD_BITBLT | CMD_XP | CMD_YP;
123 (void)et; // avoid compiler warning for unused arg
125 cmd |= gInfo.sharedInfo->commonCmd;
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;
135 if (src_x == dest_x && src_y == dest_y)
136 continue;
138 cmd |= CMD_XP | CMD_YP; // restore these flags in case removed on last iteration
140 if (src_x < dest_x) {
141 src_x += width;
142 dest_x += width;
143 cmd &= ~CMD_XP;
146 if (src_y < dest_y) {
147 src_y += height;
148 dest_y += height;
149 cmd &= ~CMD_YP;
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();
159 pList ++;