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