Annotation of lucent/sys/src/9/pc/f002540, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.