1 #include "u.h" 2 #include "../port/lib.h" 3 #include "mem.h" 4 #include "dat.h" 5 #include "fns.h" 6 #include "io.h" 7 #include "../port/error.h" 8 9 #define Image IMAGE 10 #include <draw.h> 11 #include <memdraw.h> 12 #include <cursor.h> 13 #include "screen.h" 14 15 typedef struct Cursor3dfx Cursor3dfx; 16 struct Cursor3dfx { 17 int vidProcCfg; 18 int hwCurPatAddr; 19 int hwCurLoc; 20 int hwCurC0; 21 int hwCurC1; 22 }; 23 24 enum { 25 dramInit0 = 0x18, 26 dramInit1 = 0x1C, 27 28 hwCur = 0x5C, 29 }; 30 31 static void 32 tdfxenable(VGAscr* scr) 33 { 34 Pcidev *p; 35 int i, *mmio; 36 37 if(scr->mmio) 38 return; 39 if(p = pcimatch(nil, 0x121A, 0)){ 40 switch(p->did){ 41 case 0x0003: /* Banshee */ 42 case 0x0005: /* Avenger (a.k.a. Voodoo3) */ 43 break; 44 default: 45 return; 46 } 47 } 48 else 49 return; 50 51 scr->mmio = vmap(p->mem[0].bar&~0x0F, p->mem[0].size); 52 if(scr->mmio == nil) 53 return; 54 scr->pci = p; 55 56 addvgaseg("3dfxmmio", p->mem[0].bar&~0x0F, p->mem[0].size); 57 vgalinearpci(scr); 58 if(scr->apsize) 59 addvgaseg("3dfxscreen", scr->paddr, scr->apsize); 60 61 /* 62 * Find a place for the cursor data in display memory. 63 * If SDRAM then there's 16MB memory else it's SGRAM 64 * and can count it based on the power-on straps - 65 * chip size can be 8Mb or 16Mb, and there can be 4 or 66 * 8 of them. 67 * Use the last 1KB of the framebuffer. 68 */ 69 mmio = (void*)((uchar*)scr->mmio+dramInit0); 70 if(*(mmio+1) & 0x40000000) 71 i = 16*1024*1024; 72 else{ 73 if(*mmio & 0x08000000) 74 i = 16*1024*1024/8; 75 else 76 i = 8*1024*1024/8; 77 if(*mmio & 0x04000000) 78 i *= 8; 79 else 80 i *= 4; 81 } 82 scr->storage = i - 1024; 83 } 84 85 static void 86 tdfxcurdisable(VGAscr* scr) 87 { 88 Cursor3dfx *cursor3dfx; 89 90 if(scr->mmio == 0) 91 return; 92 cursor3dfx = (void*)((uchar*)scr->mmio+hwCur); 93 cursor3dfx->vidProcCfg &= ~0x08000000; 94 } 95 96 static void 97 tdfxcurload(VGAscr* scr, Cursor* curs) 98 { 99 int y; 100 uchar *p; 101 Cursor3dfx *cursor3dfx; 102 103 if(scr->mmio == 0) 104 return; 105 cursor3dfx = (void*)((uchar*)scr->mmio+hwCur); 106 107 /* 108 * Disable the cursor then load the new image in 109 * the top-left of the 64x64 array. 110 * The cursor data is stored in memory as 128-bit 111 * words consisting of plane 0 in the least significant 64-bits 112 * and plane 1 in the most significant. 113 * The X11 cursor truth table is: 114 * p0 p1 colour 115 * 0 0 transparent 116 * 0 1 transparent 117 * 1 0 hwCurC0 118 * 1 1 hwCurC1 119 * Unused portions of the image have been initialised to be 120 * transparent. 121 */ 122 cursor3dfx->vidProcCfg &= ~0x08000000; 123 p = (uchar*)scr->vaddr + scr->storage; 124 for(y = 0; y < 16; y++){ 125 *p++ = curs->clr[2*y]|curs->set[2*y]; 126 *p++ = curs->clr[2*y+1]|curs->set[2*y+1]; 127 p += 6; 128 *p++ = curs->set[2*y]; 129 *p++ = curs->set[2*y+1]; 130 p += 6; 131 } 132 133 /* 134 * Save the cursor hotpoint and enable the cursor. 135 * The 0,0 cursor point is bottom-right. 136 */ 137 scr->offset.x = 63+curs->offset.x; 138 scr->offset.y = 63+curs->offset.y; 139 cursor3dfx->vidProcCfg |= 0x08000000; 140 } 141 142 static int 143 tdfxcurmove(VGAscr* scr, Point p) 144 { 145 Cursor3dfx *cursor3dfx; 146 147 if(scr->mmio == 0) 148 return 1; 149 cursor3dfx = (void*)((uchar*)scr->mmio+hwCur); 150 151 cursor3dfx->hwCurLoc = ((p.y+scr->offset.y)<<16)|(p.x+scr->offset.x); 152 153 return 0; 154 } 155 156 static void 157 tdfxcurenable(VGAscr* scr) 158 { 159 Cursor3dfx *cursor3dfx; 160 161 tdfxenable(scr); 162 if(scr->mmio == 0) 163 return; 164 cursor3dfx = (void*)((uchar*)scr->mmio+hwCur); 165 166 /* 167 * Cursor colours. 168 */ 169 cursor3dfx->hwCurC0 = 0xFFFFFFFF; 170 cursor3dfx->hwCurC1 = 0x00000000; 171 172 /* 173 * Initialise the 64x64 cursor to be transparent (X11 mode). 174 */ 175 cursor3dfx->hwCurPatAddr = scr->storage; 176 memset((uchar*)scr->vaddr + scr->storage, 0, 64*16); 177 178 /* 179 * Load, locate and enable the 64x64 cursor in X11 mode. 180 */ 181 tdfxcurload(scr, &arrow); 182 tdfxcurmove(scr, ZP); 183 cursor3dfx->vidProcCfg |= 0x08000002; 184 } 185 186 VGAdev vga3dfxdev = { 187 "3dfx", 188 189 tdfxenable, 190 nil, 191 nil, 192 nil, 193 }; 194 195 VGAcur vga3dfxcur = { 196 "3dfxhwgc", 197 198 tdfxcurenable, 199 tdfxcurdisable, 200 tdfxcurload, 201 tdfxcurmove, 202 }; 203