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 19 static inline void WaitForSync() 20 { 21 while ((IN_SUBSYS_STAT() & 0x2000) == 0) ; 22 } 23 24 25 26 void 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 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 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 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