Annotation of Examples/DriverKit/QVision/QVision_reloc.tproj/QVisionSetMode.m, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1993 by NeXT Computer, Inc as an unpublished work.
                      2:  * All rights reserved.
                      3:  *
                      4:  * QVisionSetMode.m -- Mode support for the QVision.
                      5:  *
                      6:  * NOTE: view this file with tabs set to 4 spaces
                      7:  *
                      8:  * Author:  Derek B Clegg      21 May 1993
                      9:  *     Based on work by Joe Pasqua.
                     10:  * Tue Aug 16 16:53:03 PDT 1994 James C. Lee
                     11:  *     Add 3.3 bus support & 8-bit color support.
                     12:  * Thu Sep 22 16:39:18 PDT 1994 James C. Lee
                     13:  *     Use the new PCI API that returns IOReturn instead of BOOL.
                     14:  */
                     15: #import <string.h>
                     16: #import <driverkit/generalFuncs.h>
                     17: #import <driverkit/i386/ioPorts.h>
                     18: #import <driverkit/i386/directDevice.h>
                     19: #import <driverkit/i386/IOPCIDeviceDescription.h>
                     20: #import <driverkit/i386/IOPCIDirectDevice.h>
                     21: #import <string.h>
                     22: #import <stdio.h>
                     23: //#import <stdlib.h>
                     24: 
                     25: #import "QVision.h"
                     26: 
                     27: 
                     28: /* private interfaces for SetMode category of QVision */
                     29: /*@interface QVision (SetMode_Private)
                     30: - (ConfigBusType) determineConfigBusType;
                     31: - (QVAdapterType) determineVLCardType;
                     32: - (QVAdapterType) determinePCICardType;
                     33: - (QVAdapterType) determineEISACardType;
                     34: @end
                     35: */
                     36: /* The `SetMode' category of `QVision'. */
                     37: 
                     38: @implementation QVision (SetMode)
                     39: 
                     40: - (ConfigBusType) determineConfigBusType
                     41: {
                     42:        const char              *busTypeName;
                     43:        IOConfigTable   *configTable;
                     44:        
                     45:        configTable = [[self deviceDescription] configTable];
                     46:        busTypeName = [configTable valueForStringKey:"Bus Type"];
                     47:        if (strcmp(busTypeName, "PCI")==0) {
                     48:                busType = BusPCI;
                     49:        } else if (strcmp(busTypeName, "EISA")==0) {
                     50:                busType = BusEISA;
                     51:        } else {
                     52:                /* default to ISA or VL */
                     53:                busType = BusISAorVL;
                     54:        }
                     55:        return busType;
                     56: }
                     57: 
                     58: /* assume dac type is determined already. This method is called by
                     59:  * determineConfiguration only */
                     60: - (QVAdapterType) determineVLCardType
                     61: {
                     62:        QVAdapterType adapterType;
                     63:        
                     64:        adapterType = UnknownAdapter;
                     65:        switch (dac) {
                     66:                case Bt484:
                     67:                        adapterType = OrionAdapter;
                     68:                        break;
                     69:                case Bt485:
                     70:                case Bt485A:
                     71:                case ATT20C505:
                     72:                        adapterType = Orion12Adapter;
                     73:                        break;
                     74:                default:
                     75:                        break;
                     76:        }
                     77:        return adapterType;
                     78: }
                     79: 
                     80: /* TODO: clean up error handling, i.e. return something meaningful rather
                     81:  * than returning [super free]; */
                     82: - (QVAdapterType) determinePCICardType
                     83: {
                     84:     unsigned int               physicalAddress;
                     85:        int                                     numRanges;
                     86:        IOPCIConfigSpace        configSpace;
                     87:        unsigned char           devNum, funcNum, busNum;
                     88:        unsigned long           vendorDeviceID;
                     89:        unsigned short          vendorID, deviceID;
                     90:        char                            idString[11];
                     91:        id                                      deviceDescription;
                     92:        QVAdapterType           adapterType;
                     93:        IOConfigTable           *configTable;
                     94:        IORange                         *oldRange, newRange[3];
                     95: 
                     96:        adapterType = UnknownAdapter;
                     97:        if (![self isPCIPresent]) {
                     98:                IOLog ("%s: No PCI card found.\n", [self name]);
                     99:                return UnknownAdapter;
                    100:        }
                    101:        deviceDescription = [self deviceDescription]; 
                    102:        [deviceDescription getPCIdevice:&devNum function:&funcNum bus:&busNum];
                    103:        IOLog_dbg(("%s: PCI Dev:%d Func:%d Bus:%d\n", [self name], devNum,
                    104:                funcNum, busNum));
                    105:        [self getPCIConfigData:&vendorDeviceID atRegister:0x00];
                    106:        vendorID = (unsigned short) vendorDeviceID;
                    107:        deviceID = (unsigned short) (vendorDeviceID >> 16);
                    108:        IOLog("%s: vendorID=%04x deviceID=%04x\n", [self name], vendorID,
                    109:                deviceID);
                    110: 
                    111:        /* go through "Auto Detect IDs" and make sure we are okay */
                    112:        configTable = [[self deviceDescription] configTable];
                    113:        sprintf(idString, "%08lx", vendorDeviceID);
                    114:        if (strstr([configTable valueForStringKey:"Auto Detect IDs"], idString)
                    115:                == NULL)
                    116:        {
                    117:                IOLog("%s: VenderDeviceID %08lx not found in instance table.\n",
                    118:                        [self name], vendorDeviceID);
                    119:                return UnknownAdapter;
                    120:        } else {
                    121:                /* add more card types here if there are PCI cards other than 1280P
                    122:                 * actually, if there are more than one PCI cards, we should determine
                    123:                 * which PCI card here */
                    124:                adapterType = QVision1280P;
                    125:        }
                    126: 
                    127:        /* need to do set framebuffer address for PCI */
                    128:        [self getPCIConfigSpace:&configSpace];
                    129:        physicalAddress = configSpace.BaseAddress[0];
                    130:        physicalAddress &= 0xfffffff0;  /* mask out lower 4 bits */
                    131: 
                    132:        if (physicalAddress) {
                    133:                IOLog_dbg(("%s: try to set physical address to 0x%08x\n",
                    134:                        [self name], physicalAddress));
                    135:                /* PCI does report where the frame buffer address is */
                    136:                oldRange = [deviceDescription memoryRangeList];
                    137:                numRanges = [deviceDescription numMemoryRanges];
                    138:                if (numRanges==3) {
                    139:                        int     ret;
                    140:                        int     i;
                    141: 
                    142:                        /* replace the address */
                    143:                        for (i=0; i<numRanges; i++) {
                    144:                                newRange[i] = oldRange[i];
                    145:                        }
                    146:                        newRange[0].start = physicalAddress;
                    147:                        ret = [deviceDescription setMemoryRangeList:newRange num:3];
                    148:                        if (ret) {
                    149:                                /* can't set to new memory range */
                    150:                                IOLog("%s: Can't set memory range, using default.\n",
                    151:                                [self name]);
                    152:                                for (i=0; i<numRanges; i++) {
                    153:                                        newRange[i] = oldRange[i];
                    154:                                }
                    155:                                physicalAddress = newRange[0].start;
                    156:                                ret = [deviceDescription setMemoryRangeList:newRange
                    157:                                        num:3];
                    158:                                if (ret) {
                    159:                                        /* can't set to old range-->major problem! */
                    160:                                        IOLog("%s: Can't set to default range either!\n",
                    161:                                                [self name]);
                    162:                                        return UnknownAdapter;
                    163:                                }
                    164:                        }
                    165:                } else {
                    166:                        IOLog("%s: Incorrect number of address ranges: %d.\n",
                    167:                                [self name], numRanges);
                    168:                        return UnknownAdapter;
                    169:                }
                    170:        } else {
                    171:                IOLog_dbg(("%s: PCI doesn't tell us the physical address.\n",
                    172:                        [self name]));
                    173:                physicalAddress = [deviceDescription memoryRangeList] -> start;
                    174:                configSpace.BaseAddress[0] = physicalAddress;
                    175:                [self setPCIConfigSpace:&configSpace];
                    176:        }
                    177:        return adapterType;
                    178: }
                    179: 
                    180: 
                    181: /* helper method to -determineEISACardType */
                    182: - (QVAdapterType)adapterTypeFromEISAID:(unsigned int)cardID
                    183: {
                    184:        QVAdapterType   adapterType;
                    185: 
                    186:        adapterType = UnknownAdapter;
                    187:        IOLog_dbg(("%s: adapterTypeFromEISAID cardID=0x%08x\n", [self name],
                    188:                cardID));
                    189:        switch (cardID) {
                    190:                case QVISION_EISA_ID:
                    191:                        adapterType = QVisionAdapter;
                    192:                        break;
                    193:                case ORION_EISA_ID:
                    194:                        adapterType = OrionAdapter;
                    195:                        break;
                    196:                case ORION12_EISA_ID:
                    197:                        adapterType = Orion12Adapter;
                    198:                        break;
                    199:                case QVISION_ISA_ID:
                    200:                case ORION_ISA_ID:
                    201:                case ORION12_ISA_ID:
                    202:                        IOLog("%s: Sorry, ISA cards are not supported (id=0x%08x).\n",
                    203:                                [self name], cardID);
                    204:                        break;
                    205:                default:
                    206:                        /* We found some other EISA card.  Just ignore it. */
                    207:                        break;
                    208:        }
                    209:        return adapterType;
                    210: }
                    211: 
                    212: /* helper method to -determineEISACardType */
                    213: - (QVAdapterType)autoScanEISAForCardType
                    214: {
                    215:        int                             slot;
                    216:        QVAdapterType   adapterType;
                    217:        unsigned int    cardID;
                    218: 
                    219:        IOLog_dbg(("%s: doing auto-scan on EISA bus.\n", [self name]));
                    220:                
                    221:        adapterType = UnknownAdapter;
                    222:        for (slot=1; slot<16; slot++) {
                    223:                if ([self getEISAId:&cardID forSlot:slot]) {
                    224:                        adapterType = [self adapterTypeFromEISAID:cardID];
                    225:                }
                    226:                if (adapterType != UnknownAdapter) {
                    227:                        IOLog_dbg(("%s: found card in slot %d.\n", [self name], slot));
                    228:                        return adapterType;
                    229:                }
                    230:        }
                    231:        return UnknownAdapter;
                    232: }
                    233: 
                    234: /* can't use atoi() nor sscanf() */
                    235: - (int) getFirstNumber:(char *)s
                    236: {
                    237:        char    *cptr;
                    238:        int             n;
                    239:        
                    240:        cptr = s;
                    241:        n = -1;
                    242:        while(*cptr && ((*cptr<'0') || (*cptr>'9'))) cptr++;
                    243:        while(*cptr && ((*cptr>='0') && (*cptr<='9'))) {
                    244:                if (n==-1) n = 0;
                    245:                n = n*10 + (*cptr - '0');
                    246:                cptr++;
                    247:        }
                    248:        return n;
                    249: }
                    250: 
                    251: /* TODO: clean up error handling, i.e. return something meaningful rather
                    252:  * than returning [super free]; */
                    253: - (QVAdapterType) determineEISACardType
                    254: {
                    255:        QVAdapterType   adapterType;
                    256:        int                             mySlot;
                    257:        id                              deviceDescription;
                    258:        const char              *slotValue;
                    259:        IOConfigTable   *configTable;
                    260:        unsigned int    cardID;
                    261:        
                    262:        adapterType = UnknownAdapter;
                    263:        if (![self isEISAPresent]) {
                    264:                IOLog ("%s: Not an EISA system.\n", [self name]);
                    265:                return UnknownAdapter;
                    266:        }
                    267:        deviceDescription = [self deviceDescription]; 
                    268:        configTable = [[self deviceDescription] configTable];
                    269: 
                    270:        /* see what slot we're supposed be in */
                    271:        slotValue = [configTable valueForStringKey:"Location"];
                    272:        if (strstr(slotValue, "Slot")) {
                    273:                mySlot = [self getFirstNumber:(char *)slotValue];
                    274:                IOLog_dbg(("%s: we should be in slot %d\n", [self name], mySlot));
                    275:        } else {
                    276:                /* instance table doesn't tell us what slot we're in */
                    277:                return [self autoScanEISAForCardType];
                    278:        }
                    279:        
                    280:        /* TODO: need to check for auto detect id's */
                    281:        if (mySlot > 0) {
                    282:                if ([self getEISAId:&cardID forSlot:mySlot]) {
                    283:                        adapterType = [self adapterTypeFromEISAID:cardID];
                    284:                } else {
                    285:                        /* can't find card in the specified slot, do auto-scan */
                    286:                        adapterType = [self autoScanEISAForCardType];
                    287:                }
                    288:        } else {
                    289:                /* slot not specified, do auto-scan */
                    290:                adapterType = [self autoScanEISAForCardType];
                    291:        }
                    292:        return adapterType;
                    293: }
                    294: 
                    295: - (void)reportConfiguration
                    296: {
                    297:        const char *adapterString, *dacString;
                    298: 
                    299:        switch (adapter) {
                    300:                case QVisionAdapter: adapterString = "QVision"; break;
                    301:                case OrionAdapter: adapterString = "Orion"; break;
                    302:                case Orion12Adapter: adapterString = "Orion12"; break;
                    303:                case QVision1280P: adapterString = "QVision1280P"; break;
                    304:                default: adapterString = "unknown"; break;
                    305:        }
                    306: 
                    307:        switch (dac) {
                    308:                case Bt484: dacString = "Brooktree 484"; break;
                    309:                case Bt485: dacString = "Brooktree 485"; break;
                    310:                case Bt485A: dacString = "Brooktree 485A"; break;
                    311:                case ATT20C505: dacString = "AT&T 20C505"; break;
                    312:                default: dacString = "unknown"; break;
                    313:        }
                    314: 
                    315:        IOLog("%s: %s adapter; %s DAC.\n", [self name], adapterString, dacString);
                    316: }
                    317: 
                    318: - determineConfiguration
                    319: {
                    320:        adapter = UnknownAdapter;
                    321: 
                    322:        [self determineConfigBusType];
                    323:        [self determineDACType];
                    324:        switch(busType) {
                    325:                case BusISAorVL:
                    326:                        adapter = [self determineVLCardType];
                    327:                        break;
                    328:                case BusPCI:
                    329:                        adapter = [self determinePCICardType];
                    330:                        break;
                    331:                case BusEISA:
                    332:                        adapter = [self determineEISACardType];
                    333:                        break;
                    334:        }
                    335:        [self reportConfiguration];
                    336:        if (adapter==UnknownAdapter || dac==UnknownDAC) return nil;
                    337:        return self;
                    338: }
                    339: 
                    340: - selectMode
                    341: {
                    342:        int k, mode;
                    343:        const QVisionMode *qvMode;
                    344:        BOOL validModes[QVisionModeTableCount];
                    345: 
                    346:        for (k = 0; k < QVisionModeTableCount; k++) {
                    347:                qvMode = QVisionModeTable[k].parameters;
                    348:                validModes[k] = (qvMode->adapter <= adapter);
                    349:        }
                    350: 
                    351:        mode = [self selectMode:QVisionModeTable count:QVisionModeTableCount
                    352:        valid:validModes];
                    353: 
                    354:        if (mode < 0) {
                    355:                IOLog("%s: Sorry, cannot use requested display mode.\n", [self name]);
                    356:                switch (adapter) {
                    357:                        case Orion12Adapter:
                    358:                                mode = DEFAULT_ORION12_MODE;
                    359:                                break;
                    360:                        case OrionAdapter:
                    361:                                mode = DEFAULT_ORION_MODE;
                    362:                                break;
                    363:                        case QVision1280P:
                    364:                                mode = DEFAULT_1280P_MODE;
                    365:                                break;
                    366:                        case QVisionAdapter:
                    367:                        default:
                    368:                                mode = DEFAULT_QVISION_MODE;
                    369:                                break;
                    370:                }
                    371:        }
                    372:        *[self displayInfo] = QVisionModeTable[mode];
                    373:        return self;
                    374: }
                    375: 
                    376: - initializeMode
                    377: {
                    378:        unsigned int i;
                    379:        const QVisionMode *mode;
                    380:        const IODisplayInfo *displayInfo;
                    381: 
                    382:        displayInfo = [self displayInfo];
                    383:        mode = displayInfo->parameters;
                    384: 
                    385:        /* Turn off video while setting all of the registers. */
                    386:        inb(VGA_INPUT_STATUS_1);
                    387:        outb(VGA_ATTR_INDEX, 0x00);
                    388:        
                    389:        /* Set the sequencer registers. */
                    390:        for (i = 0; i < VGA_SEQ_COUNT; i++) {
                    391:        outb(VGA_SEQ_INDEX, i);
                    392:        outb(VGA_SEQ_DATA, mode->vgaData.seqx[i]);
                    393:        }
                    394:        outb(VGA_SEQ_INDEX, 0x00);
                    395:        outb(VGA_SEQ_DATA, 0x03);       /* Restart the sequencer. */
                    396:        
                    397:        /* Unlock extended graphics registers. */
                    398:        outw(VGA_GRFX_INDEX, 0x050f);
                    399: 
                    400:        /* Unlock more extended registers. */
                    401:        outb(VGA_GRFX_INDEX, 0x10);
                    402:        outb(VGA_GRFX_DATA, 0x08);
                    403: 
                    404:        /* Set Advanced VGA mode (set bit 0 of Ctrl Reg 0). */
                    405:        outb(VGA_GRFX_INDEX, 0x40);
                    406:        outb(VGA_GRFX_DATA, 0x01);
                    407:        
                    408:        /* Fix sequencer pixel mask for 8 bits. */
                    409:        outb(VGA_SEQ_INDEX, SEQ_PIXEL_WR_MSK);
                    410:        outb(VGA_SEQ_DATA, 0xff);
                    411:        
                    412:        outb(CTRL_REG_1, mode->ctrlReg1);
                    413:        if (mode->adapter >= OrionAdapter) {
                    414:        /* Set access level & enable high address map. */
                    415:        outb(QVGA_CTL_2, 0x14);
                    416:        /* Select 2 Meg mode. */
                    417:        outb(QVGA_CTL_3, 0x05);
                    418:        }
                    419:        
                    420:        /* Set miscellaneous output register. */
                    421:        outb(VGA_MISC_OUTPUT, mode->vgaData.miscOutput);
                    422:        
                    423:        [self programDAC];
                    424: 
                    425:        /* Load CRTC registers. */
                    426:        outb(VGA_CRTC_INDEX, 0x11);             /* Unlock CRTC regs 0-7. */
                    427:        outb(VGA_CRTC_DATA, 0x00);
                    428:        for (i = 0; i < VGA_CRTC_COUNT; i++) {
                    429:        outb(VGA_CRTC_INDEX, i);
                    430:        outb(VGA_CRTC_DATA, mode->vgaData.crtc[i]);
                    431:        }
                    432: 
                    433:        /* Load overflow registers. */
                    434:        outb(VGA_GRFX_INDEX, 0x42);
                    435:        outb(VGA_GRFX_DATA, mode->overflow1);
                    436:        outb(VGA_GRFX_INDEX, 0x51);
                    437:        outb(VGA_GRFX_DATA, mode->overflow2);
                    438:        
                    439:        /* Load attribute registers. */
                    440: 
                    441:        inb(VGA_INPUT_STATUS_1);        /* Reset latch. */
                    442:        for (i = 0; i < VGA_ATTR_COUNT; i++) {
                    443:        outb(VGA_ATTR_INDEX, i);
                    444:        outb(VGA_ATTR_DATA, mode->vgaData.attr[i]);
                    445:        }
                    446:        
                    447:        /* Load graphics registers. */
                    448:        for (i = 0; i < VGA_GRFX_COUNT; i++) {
                    449:        outb(VGA_GRFX_INDEX, i);
                    450:        outb(VGA_GRFX_DATA, mode->vgaData.grfx[i]);
                    451:        }
                    452:        
                    453:        [self setGammaTable];
                    454:        
                    455:        /* Re-enable video display. */
                    456:        inb(VGA_INPUT_STATUS_1);
                    457:        outb(VGA_ATTR_INDEX, 0x20);
                    458: 
                    459:        return self;
                    460: }
                    461: 
                    462: - enableLinearFrameBuffer
                    463: {
                    464:        const IODisplayInfo *displayInfo;
                    465:        unsigned char tmp;
                    466:        
                    467:        /* Override the high address map disable, thus allowing access to
                    468:         * the high address map of the current board, even when the board
                    469:         * is disabled. */
                    470: 
                    471:        outb(VGA_GRFX_INDEX, HI_ADDR_MAP+1);
                    472:        tmp = inb(VGA_GRFX_DATA);
                    473:        outb(VGA_GRFX_DATA, tmp | 0x80);
                    474: 
                    475:        /* Map VRAM.  Tell the adapter where to decode the framebuffer. */
                    476: 
                    477:        /* Set low 8 bits */
                    478:        outb(VGA_GRFX_INDEX, HI_ADDR_MAP);
                    479:        outb(VGA_GRFX_DATA, (videoRamAddress >> 20) & 0xFF);
                    480: 
                    481:        /* Set upper 4 bits */
                    482:        outb(VGA_GRFX_INDEX, HI_ADDR_MAP + 1);
                    483:        outb(VGA_GRFX_DATA, (videoRamAddress >> 28) & 0x0F);
                    484: 
                    485:        /* Leave them with a nice clear screen. */
                    486: 
                    487:        displayInfo = [self displayInfo];
                    488:        memset(displayInfo->frameBuffer, 0, 
                    489:           displayInfo->rowBytes * displayInfo->height);
                    490: 
                    491:        return self;
                    492: }
                    493: 
                    494: - resetVGA
                    495: {
                    496:        const IODisplayInfo *displayInfo;
                    497:        const QVisionMode *mode;
                    498: 
                    499:        displayInfo = [self displayInfo];
                    500:        mode = displayInfo->parameters;
                    501: 
                    502:        /* Clear the QVision extended mode bit. This is bit 0 of CTRL_REG_1. */
                    503: 
                    504:        outb(CTRL_REG_1, inb(CTRL_REG_1) & 0xFE);
                    505: 
                    506:        if (mode != 0 && mode->adapter >= OrionAdapter) {
                    507:        /* Select 1 meg mode. */
                    508:        outb(QVGA_CTL_3, 0x00);
                    509:        /* Reset access level & disable high address map. */
                    510:        outb(QVGA_CTL_2, 0x00);
                    511:        }
                    512:        
                    513:        /* Clear the extended 256 color bit. This is bit 0 of 3CF.40. */
                    514:        outb(VGA_GRFX_INDEX, 0x40);
                    515:        outb(VGA_GRFX_DATA, (inb(VGA_GRFX_DATA) & 0xFE));
                    516:        
                    517:        /* Clear the page registers - 3CF.45 and 3CF.46. */
                    518:        outb(VGA_GRFX_INDEX, PAGE_REG_0);
                    519:        outb(VGA_GRFX_DATA, 0x00);
                    520:        outb(VGA_GRFX_INDEX, PAGE_REG_1);
                    521:        outb(VGA_GRFX_DATA, 0x00);
                    522:        
                    523:        [self resetDAC];
                    524: 
                    525:        /* Clear the overflow registers. */
                    526:        outb(VGA_GRFX_INDEX, 0x42);
                    527:        outb(VGA_GRFX_DATA, 0x00);
                    528:        outb(VGA_GRFX_INDEX, 0x51);
                    529:        outb(VGA_GRFX_DATA, 0x00);
                    530: 
                    531:        VGASetMode(0x03);
                    532: 
                    533:        return self;
                    534: }
                    535: @end

unix.superglobalmegacorp.com

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