Annotation of lucent/sys/src/9/pc/vgas3.c, 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: /*
                     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: }

unix.superglobalmegacorp.com

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