|
|
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: extern GBitmap gscreen; ! 14: extern GBitmap vgascreen; ! 15: ! 16: static Lock et4000pagelock; ! 17: static ulong storage; ! 18: static Point hotpoint; ! 19: ! 20: static void ! 21: setet4000page(int page) ! 22: { ! 23: uchar p; ! 24: ! 25: p = page & 0x0F; ! 26: p |= p<<4; ! 27: outb(0x3CD, p); ! 28: ! 29: p = (page & 0x30); ! 30: p |= p>>4; ! 31: outb(0x3CB, p); ! 32: } ! 33: ! 34: static void ! 35: disable(void) ! 36: { ! 37: uchar imaF7; ! 38: ! 39: outb(0x217A, 0xF7); ! 40: imaF7 = inb(0x217B) & ~0x80; ! 41: outb(0x217B, imaF7); ! 42: } ! 43: ! 44: static void ! 45: enable(void) ! 46: { ! 47: uchar imaF7; ! 48: ! 49: disable(); ! 50: ! 51: /* ! 52: * Configure CRTCB for Sprite, 64x64, ! 53: * CRTC pixel overlay. ! 54: */ ! 55: outb(0x217A, 0xEF); ! 56: outb(0x217B, 0x02); ! 57: ! 58: /* ! 59: * Cursor goes in the top left corner ! 60: * of the Sprite area, so the horizontal and ! 61: * vertical presets are 0. ! 62: */ ! 63: outb(0x217A, 0xE2); ! 64: outb(0x217B, 0x00); ! 65: outb(0x217A, 0xE3); ! 66: outb(0x217B, 0x00); ! 67: ! 68: outb(0x217A, 0xE6); ! 69: outb(0x217B, 0x00); ! 70: outb(0x217A, 0xE7); ! 71: outb(0x217B, 0x00); ! 72: ! 73: /* ! 74: * Find a place for the cursor data in display memory. ! 75: * Must be on a "doubleword" boundary, but put it on a ! 76: * 1024-byte boundary so that there's no danger of it ! 77: * crossing a page. ! 78: */ ! 79: storage = (gscreen.width*BY2WD*gscreen.r.max.y+1023)/1024; ! 80: storage *= 1024/4; ! 81: outb(0x217A, 0xE8); ! 82: outb(0x217B, storage & 0xFF); ! 83: outb(0x217A, 0xE9); ! 84: outb(0x217B, (storage>>8) & 0xFF); ! 85: outb(0x217A, 0xEA); ! 86: outb(0x217B, (storage>>16) & 0x0F); ! 87: storage *= 4; ! 88: ! 89: /* ! 90: * Row offset in "quadwords". Must be 2 for Sprite. ! 91: * Bag the pixel-panning. ! 92: * Colour depth, must be 2 for Sprite. ! 93: */ ! 94: outb(0x217A, 0xEB); ! 95: outb(0x217B, 0x02); ! 96: outb(0x217A, 0xEC); ! 97: outb(0x217B, 0x00); ! 98: ! 99: outb(0x217A, 0xED); ! 100: outb(0x217B, 0x00); ! 101: ! 102: outb(0x217A, 0xEE); ! 103: if(vgascreen.ldepth == 3) ! 104: outb(0x217B, 0x01); ! 105: else ! 106: outb(0x217B, 0x00); ! 107: ! 108: /* ! 109: * Enable the CRTCB/Sprite. ! 110: */ ! 111: outb(0x217A, 0xF7); ! 112: imaF7 = inb(0x217B); ! 113: outb(0x217B, 0x80|imaF7); ! 114: } ! 115: ! 116: static void ! 117: load(Cursor *c) ! 118: { ! 119: uchar p0, p1, *mem; ! 120: int i, x, y; ! 121: ushort p; ! 122: uchar clr[2*16], set[2*16]; ! 123: ! 124: /* ! 125: * Lock the display memory so we can update the ! 126: * cursor bitmap if necessary. ! 127: */ ! 128: lock(&et4000pagelock); ! 129: ! 130: /* ! 131: * Disable the cursor. ! 132: * Set the display page (do we need to restore ! 133: * the current contents when done?) and the ! 134: * pointer to the two planes. What if this crosses ! 135: * into a new page? ! 136: */ ! 137: disable(); ! 138: ! 139: setet4000page(storage>>16); ! 140: mem = ((uchar*)vgascreen.base) + (storage & 0xFFFF); ! 141: ! 142: /* ! 143: * Initialise the 64x64 cursor RAM array. There are 2 planes, ! 144: * p0 and p1. Data is written 4 pixels per byte, with p1 the ! 145: * MS bit of each pixel. ! 146: * The cursor mode gives the following truth table: ! 147: * p1 p0 colour ! 148: * 0 0 Sprite Colour 0 (defined as 0x00) ! 149: * 0 1 Sprite Colour 1 (defined as 0xFF) ! 150: * 1 0 Transparent (allow CRTC pixel pass through) ! 151: * 1 1 Invert (allow CRTC pixel invert through) ! 152: * Put the cursor into the top-left of the 64x64 array. ! 153: */ ! 154: memmove(clr, c->clr, sizeof(clr)); ! 155: pixreverse(clr, sizeof(clr), 0); ! 156: memmove(set, c->set, sizeof(set)); ! 157: pixreverse(set, sizeof(set), 0); ! 158: for(y = 0; y < 64; y++){ ! 159: for(x = 0; x < 64/8; x++){ ! 160: if(x < 16/8 && y < 16){ ! 161: p0 = clr[x+y*2]; ! 162: p1 = set[x+y*2]; ! 163: ! 164: p = 0x0000; ! 165: for(i = 0; i < 8; i++){ ! 166: if(p1 & (1<<(7-i))) ! 167: ; ! 168: else if(p0 & (1<<(7-i))) ! 169: p |= 0x01<<(2*i); ! 170: else ! 171: p |= 0x02<<(2*i); ! 172: } ! 173: *mem++ = p & 0xFF; ! 174: *mem++ = (p>>8) & 0xFF; ! 175: } ! 176: else { ! 177: *mem++ = 0xAA; ! 178: *mem++ = 0xAA; ! 179: } ! 180: } ! 181: } ! 182: ! 183: /* ! 184: * Set the cursor hotpoint and enable the cursor. ! 185: */ ! 186: hotpoint = c->offset; ! 187: outb(0x217A, 0xF7); ! 188: p = inb(0x217B)|0x80; ! 189: outb(0x217B, p); ! 190: ! 191: unlock(&et4000pagelock); ! 192: } ! 193: ! 194: static int ! 195: move(Point p) ! 196: { ! 197: int x, xo, y, yo; ! 198: ! 199: if(canlock(&et4000pagelock) == 0) ! 200: return 1; ! 201: ! 202: /* ! 203: * Mustn't position the cursor offscreen even partially, ! 204: * or it disappears. Therefore, if x or y is -ve, adjust the ! 205: * cursor presets instead. ! 206: */ ! 207: if((x = p.x+hotpoint.x) < 0){ ! 208: xo = -x; ! 209: x = 0; ! 210: } ! 211: else ! 212: xo = 0; ! 213: if((y = p.y+hotpoint.y) < 0){ ! 214: yo = -y; ! 215: y = 0; ! 216: } ! 217: else ! 218: yo = 0; ! 219: ! 220: /* ! 221: * The cursor image is jerky if we don't do this. ! 222: * The cursor information is probably fetched from ! 223: * display memory during the horizontal blank active ! 224: * time and it doesn't like it if the coordinates ! 225: * are changed underneath. ! 226: */ ! 227: while((vgai(Status1) & 0x08) == 0) ! 228: ; ! 229: ! 230: outb(0x217A, 0xE2); ! 231: outb(0x217B, xo); ! 232: ! 233: outb(0x217A, 0xE6); ! 234: outb(0x217B, yo); ! 235: ! 236: outb(0x217A, 0xE1); ! 237: outb(0x217B, (x>>8) & 0xFF); ! 238: outb(0x217A, 0xE0); ! 239: outb(0x217B, x & 0xFF); ! 240: outb(0x217A, 0xE5); ! 241: outb(0x217B, (y>>8) & 0xFF); ! 242: outb(0x217A, 0xE4); ! 243: outb(0x217B, y & 0xFF); ! 244: ! 245: unlock(&et4000pagelock); ! 246: return 0; ! 247: } ! 248: ! 249: static Hwgc et4000hwgc = { ! 250: "et4000hwgc", ! 251: enable, ! 252: load, ! 253: move, ! 254: disable, ! 255: ! 256: 0, ! 257: }; ! 258: ! 259: static void ! 260: et4000page(int page) ! 261: { ! 262: if(hwgc == &et4000hwgc){ ! 263: lock(&et4000pagelock); ! 264: setet4000page(page); ! 265: unlock(&et4000pagelock); ! 266: } ! 267: else ! 268: setet4000page(page); ! 269: } ! 270: ! 271: static Vgac et4000 = { ! 272: "et4000", ! 273: et4000page, ! 274: ! 275: 0, ! 276: }; ! 277: ! 278: void ! 279: vgaet4000link(void) ! 280: { ! 281: addvgaclink(&et4000); ! 282: addhwgclink(&et4000hwgc); ! 283: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.