|
|
1.1 ! root 1: #include "u.h" ! 2: #include "../port/lib.h" ! 3: #include "mem.h" ! 4: #include "dat.h" ! 5: #include "fns.h" ! 6: #include "../port/error.h" ! 7: ! 8: #include <libg.h> ! 9: #include <gnot.h> ! 10: #include "screen.h" ! 11: #include "vga.h" ! 12: ! 13: /* ! 14: * Hardware graphics cursor support for ! 15: * generic S3 chipset. ! 16: * Assume we're in enhanced mode. ! 17: */ ! 18: static Lock s3pagelock; ! 19: static ulong storage; ! 20: static Point hotpoint; ! 21: ! 22: extern GBitmap gscreen; ! 23: extern GBitmap vgascreen; ! 24: extern Cursor curcursor; ! 25: ! 26: static void ! 27: sets3page(int page) ! 28: { ! 29: uchar crt51; ! 30: ! 31: if(vgascreen.ldepth == 3){ ! 32: /* ! 33: * The S3 registers need to be unlocked for this. ! 34: * Let's hope they are already: ! 35: * vgaxo(Crtx, 0x38, 0x48); ! 36: * vgaxo(Crtx, 0x39, 0xA0); ! 37: * ! 38: * The page is 6 bits, the lower 4 bits in Crt35<3:0>, ! 39: * the upper 2 in Crt51<3:2>. ! 40: */ ! 41: vgaxo(Crtx, 0x35, page & 0x0F); ! 42: crt51 = vgaxi(Crtx, 0x51) & 0xF3; ! 43: vgaxo(Crtx, 0x51, crt51|((page & 0x30)>>2)); ! 44: } ! 45: else ! 46: vgaxo(Crtx, 0x35, (page<<2) & 0x0C); ! 47: } ! 48: ! 49: static void ! 50: vsyncactive(void) ! 51: { ! 52: /* ! 53: * Hardware cursor information is fetched from display memory ! 54: * during the horizontal blank active time. The 80x chips may hang ! 55: * if the cursor is turned on or off during this period. ! 56: */ ! 57: while((vgai(Status1) & 0x08) == 0) ! 58: ; ! 59: } ! 60: ! 61: static void ! 62: disable(void) ! 63: { ! 64: uchar crt45; ! 65: ! 66: /* ! 67: * Turn cursor off. ! 68: */ ! 69: crt45 = vgaxi(Crtx, 0x45) & 0xFE; ! 70: vsyncactive(); ! 71: vgaxo(Crtx, 0x45, crt45); ! 72: } ! 73: ! 74: static void ! 75: enable(void) ! 76: { ! 77: int i; ! 78: ! 79: disable(); ! 80: ! 81: /* ! 82: * Cursor colours. Set both the CR0[EF] and the colour ! 83: * stack in case we are using a 16-bit RAMDAC. ! 84: * Why are these colours reversed? ! 85: */ ! 86: vgaxo(Crtx, 0x0E, 0x00); ! 87: vgaxo(Crtx, 0x0F, 0xFF); ! 88: vgaxi(Crtx, 0x45); ! 89: for(i = 0; i < 4; i++) ! 90: vgaxo(Crtx, 0x4A, 0x00); ! 91: vgaxi(Crtx, 0x45); ! 92: for(i = 0; i < 4; i++) ! 93: vgaxo(Crtx, 0x4B, 0xFF); ! 94: ! 95: /* ! 96: * Find a place for the cursor data in display memory. ! 97: * Must be on a 1024-byte boundary. ! 98: */ ! 99: storage = (gscreen.width*BY2WD*gscreen.r.max.y+1023)/1024; ! 100: vgaxo(Crtx, 0x4C, (storage>>8) & 0x0F); ! 101: vgaxo(Crtx, 0x4D, storage & 0xFF); ! 102: storage *= 1024; ! 103: ! 104: /* ! 105: * Enable the cursor in X11 mode. ! 106: */ ! 107: vgaxo(Crtx, 0x55, vgaxi(Crtx, 0x55)|0x10); ! 108: vsyncactive(); ! 109: vgaxo(Crtx, 0x45, 0x01); ! 110: } ! 111: ! 112: static void ! 113: load(Cursor *c) ! 114: { ! 115: uchar *p; ! 116: int x, y; ! 117: uchar clr[2*16], set[2*16]; ! 118: ! 119: /* ! 120: * Lock the display memory so we can update the ! 121: * cursor bitmap if necessary. ! 122: * If it's the same as the last cursor we loaded, ! 123: * just make sure it's enabled. ! 124: */ ! 125: lock(&s3pagelock); ! 126: /* ! 127: if(memcmp(c, &curcursor, sizeof(Cursor)) == 0){ ! 128: vsyncactive(); ! 129: vgaxo(Crtx, 0x45, 0x01); ! 130: unlock(&s3pagelock); ! 131: return; ! 132: } ! 133: memmove(&curcursor, c, sizeof(Cursor)); ! 134: */ ! 135: ! 136: /* ! 137: * Disable the cursor. ! 138: * Set the display page (do we need to restore ! 139: * the current contents when done?) and the ! 140: * pointer to the two planes. What if this crosses ! 141: * into a new page? ! 142: */ ! 143: disable(); ! 144: ! 145: sets3page(storage>>16); ! 146: p = ((uchar*)vgascreen.base) + (storage & 0xFFFF); ! 147: ! 148: /* ! 149: * The cursor is set in X11 mode which gives the following ! 150: * truth table: ! 151: * and xor colour ! 152: * 0 0 underlying pixel colour ! 153: * 0 1 underlying pixel colour ! 154: * 1 0 background colour ! 155: * 1 1 foreground colour ! 156: * Put the cursor into the top-left of the 64x64 array. ! 157: * ! 158: * The cursor pattern in memory is interleaved words of ! 159: * AND and XOR patterns. ! 160: */ ! 161: memmove(clr, c->clr, sizeof(clr)); ! 162: pixreverse(clr, sizeof(clr), 0); ! 163: memmove(set, c->set, sizeof(set)); ! 164: pixreverse(set, sizeof(set), 0); ! 165: for(y = 0; y < 64; y++){ ! 166: for(x = 0; x < 64/8; x += 2){ ! 167: if(x < 16/8 && y < 16){ ! 168: *p++ = clr[2*y + x]|set[2*y + x]; ! 169: *p++ = clr[2*y + x+1]|set[2*y + x+1]; ! 170: *p++ = set[2*y + x]; ! 171: *p++ = set[2*y + x+1]; ! 172: } ! 173: else { ! 174: *p++ = 0x00; ! 175: *p++ = 0x00; ! 176: *p++ = 0x00; ! 177: *p++ = 0x00; ! 178: } ! 179: } ! 180: } ! 181: ! 182: /* ! 183: * Set the cursor hotpoint and enable the cursor. ! 184: */ ! 185: hotpoint = c->offset; ! 186: vsyncactive(); ! 187: vgaxo(Crtx, 0x45, 0x01); ! 188: ! 189: unlock(&s3pagelock); ! 190: } ! 191: ! 192: static int ! 193: move(Point p) ! 194: { ! 195: int x, xo, y, yo; ! 196: ! 197: if(canlock(&s3pagelock) == 0) ! 198: return 1; ! 199: ! 200: /* ! 201: * Mustn't position the cursor offscreen even partially, ! 202: * or it disappears. Therefore, if x or y is -ve, adjust the ! 203: * cursor offset instead. ! 204: * There seems to be a bug in that if the offset is 1, the ! 205: * cursor doesn't disappear off the left edge properly, so ! 206: * round it up to be even. ! 207: */ ! 208: if((x = p.x+hotpoint.x) < 0){ ! 209: xo = -x; ! 210: xo = ((xo+1)/2)*2; ! 211: x = 0; ! 212: } ! 213: else ! 214: xo = 0; ! 215: if((y = p.y+hotpoint.y) < 0){ ! 216: yo = -y; ! 217: y = 0; ! 218: } ! 219: else ! 220: yo = 0; ! 221: ! 222: vgaxo(Crtx, 0x46, (x>>8) & 0x07); ! 223: vgaxo(Crtx, 0x47, x & 0xFF); ! 224: vgaxo(Crtx, 0x49, y & 0xFF); ! 225: vgaxo(Crtx, 0x4E, xo); ! 226: vgaxo(Crtx, 0x4F, yo); ! 227: vgaxo(Crtx, 0x48, (y>>8) & 0x07); ! 228: ! 229: unlock(&s3pagelock); ! 230: return 0; ! 231: } ! 232: ! 233: static Hwgc s3hwgc = { ! 234: "s3hwgc", ! 235: enable, ! 236: load, ! 237: move, ! 238: disable, ! 239: ! 240: 0, ! 241: }; ! 242: ! 243: static void ! 244: s3page(int page) ! 245: { ! 246: if(hwgc == &s3hwgc){ ! 247: lock(&s3pagelock); ! 248: sets3page(page); ! 249: unlock(&s3pagelock); ! 250: } ! 251: else ! 252: sets3page(page); ! 253: } ! 254: ! 255: static Vgac s3 = { ! 256: "s3", ! 257: s3page, ! 258: ! 259: 0, ! 260: }; ! 261: ! 262: void ! 263: vgas3link(void) ! 264: { ! 265: addvgaclink(&s3); ! 266: addhwgclink(&s3hwgc); ! 267: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.