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 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 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 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 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