Annotation of qemu/roms/qemu-palcode/vgaio.c, revision 1.1

1.1     ! root        1: // VGA io port access
        !             2: //
        !             3: // Copyright (C) 2009  Kevin O'Connor <kevin@koconnor.net>
        !             4: // Copyright (C) 2001-2008 the LGPL VGABios developers Team
        !             5: //
        !             6: // This file may be distributed under the terms of the GNU LGPLv3 license.
        !             7: 
        !             8: #include "protos.h"
        !             9: #include "ioport.h"
        !            10: #include "pci.h"
        !            11: #include "pci_regs.h"
        !            12: #include "pci_ids.h"
        !            13: #include "vgatables.h"
        !            14: 
        !            15: #define GET_FARVAR(seg, ofs)           (ofs)
        !            16: #define SET_FARVAR(seg, ofs, val)      ((ofs) = (val))
        !            17: 
        !            18: static struct saveBDAstate BDA;
        !            19: 
        !            20: #define GET_BDA(field)                 (BDA.field)
        !            21: #define GET_GLOBAL(val)                        (val)
        !            22: 
        !            23: // TODO
        !            24: //  * replace direct in/out calls with wrapper functions
        !            25: 
        !            26: 
        !            27: /****************************************************************
        !            28:  * Attribute control
        !            29:  ****************************************************************/
        !            30: 
        !            31: void
        !            32: vgahw_screen_disable(void)
        !            33: {
        !            34:     inb(VGAREG_ACTL_RESET);
        !            35:     outb(0x00, VGAREG_ACTL_ADDRESS);
        !            36: }
        !            37: 
        !            38: void
        !            39: vgahw_screen_enable(void)
        !            40: {
        !            41:     inb(VGAREG_ACTL_RESET);
        !            42:     outb(0x20, VGAREG_ACTL_ADDRESS);
        !            43: }
        !            44: 
        !            45: void
        !            46: vgahw_set_border_color(u8 color)
        !            47: {
        !            48:     inb(VGAREG_ACTL_RESET);
        !            49:     outb(0x00, VGAREG_ACTL_ADDRESS);
        !            50:     u8 v1 = color & 0x0f;
        !            51:     if (v1 & 0x08)
        !            52:         v1 += 0x08;
        !            53:     outb(v1, VGAREG_ACTL_WRITE_DATA);
        !            54: 
        !            55:     u8 v2 = color & 0x10;
        !            56:     int i;
        !            57:     for (i = 1; i < 4; i++) {
        !            58:         outb(i, VGAREG_ACTL_ADDRESS);
        !            59: 
        !            60:         u8 cur = inb(VGAREG_ACTL_READ_DATA);
        !            61:         cur &= 0xef;
        !            62:         cur |= v2;
        !            63:         outb(cur, VGAREG_ACTL_WRITE_DATA);
        !            64:     }
        !            65:     outb(0x20, VGAREG_ACTL_ADDRESS);
        !            66: }
        !            67: 
        !            68: void
        !            69: vgahw_set_overscan_border_color(u8 color)
        !            70: {
        !            71:     inb(VGAREG_ACTL_RESET);
        !            72:     outb(0x11, VGAREG_ACTL_ADDRESS);
        !            73:     outb(color, VGAREG_ACTL_WRITE_DATA);
        !            74:     outb(0x20, VGAREG_ACTL_ADDRESS);
        !            75: }
        !            76: 
        !            77: u8
        !            78: vgahw_get_overscan_border_color(void)
        !            79: {
        !            80:     inb(VGAREG_ACTL_RESET);
        !            81:     outb(0x11, VGAREG_ACTL_ADDRESS);
        !            82:     u8 v = inb(VGAREG_ACTL_READ_DATA);
        !            83:     inb(VGAREG_ACTL_RESET);
        !            84:     outb(0x20, VGAREG_ACTL_ADDRESS);
        !            85:     return v;
        !            86: }
        !            87: 
        !            88: void
        !            89: vgahw_set_palette(u8 palid)
        !            90: {
        !            91:     inb(VGAREG_ACTL_RESET);
        !            92:     palid &= 0x01;
        !            93:     int i;
        !            94:     for (i = 1; i < 4; i++) {
        !            95:         outb(i, VGAREG_ACTL_ADDRESS);
        !            96: 
        !            97:         u8 v = inb(VGAREG_ACTL_READ_DATA);
        !            98:         v &= 0xfe;
        !            99:         v |= palid;
        !           100:         outb(v, VGAREG_ACTL_WRITE_DATA);
        !           101:     }
        !           102:     outb(0x20, VGAREG_ACTL_ADDRESS);
        !           103: }
        !           104: 
        !           105: void
        !           106: vgahw_set_single_palette_reg(u8 reg, u8 val)
        !           107: {
        !           108:     inb(VGAREG_ACTL_RESET);
        !           109:     outb(reg, VGAREG_ACTL_ADDRESS);
        !           110:     outb(val, VGAREG_ACTL_WRITE_DATA);
        !           111:     outb(0x20, VGAREG_ACTL_ADDRESS);
        !           112: }
        !           113: 
        !           114: u8
        !           115: vgahw_get_single_palette_reg(u8 reg)
        !           116: {
        !           117:     inb(VGAREG_ACTL_RESET);
        !           118:     outb(reg, VGAREG_ACTL_ADDRESS);
        !           119:     u8 v = inb(VGAREG_ACTL_READ_DATA);
        !           120:     inb(VGAREG_ACTL_RESET);
        !           121:     outb(0x20, VGAREG_ACTL_ADDRESS);
        !           122:     return v;
        !           123: }
        !           124: 
        !           125: void
        !           126: vgahw_set_all_palette_reg(u8 *data_far)
        !           127: {
        !           128:     inb(VGAREG_ACTL_RESET);
        !           129:     int i;
        !           130:     for (i = 0; i < 0x10; i++) {
        !           131:         outb(i, VGAREG_ACTL_ADDRESS);
        !           132:         u8 val = GET_FARVAR(seg, *data_far);
        !           133:         outb(val, VGAREG_ACTL_WRITE_DATA);
        !           134:         data_far++;
        !           135:     }
        !           136:     outb(0x11, VGAREG_ACTL_ADDRESS);
        !           137:     outb(GET_FARVAR(seg, *data_far), VGAREG_ACTL_WRITE_DATA);
        !           138:     outb(0x20, VGAREG_ACTL_ADDRESS);
        !           139: }
        !           140: 
        !           141: void
        !           142: vgahw_get_all_palette_reg(u8 *data_far)
        !           143: {
        !           144:     int i;
        !           145:     for (i = 0; i < 0x10; i++) {
        !           146:         inb(VGAREG_ACTL_RESET);
        !           147:         outb(i, VGAREG_ACTL_ADDRESS);
        !           148:         SET_FARVAR(seg, *data_far, inb(VGAREG_ACTL_READ_DATA));
        !           149:         data_far++;
        !           150:     }
        !           151:     inb(VGAREG_ACTL_RESET);
        !           152:     outb(0x11, VGAREG_ACTL_ADDRESS);
        !           153:     SET_FARVAR(seg, *data_far, inb(VGAREG_ACTL_READ_DATA));
        !           154:     inb(VGAREG_ACTL_RESET);
        !           155:     outb(0x20, VGAREG_ACTL_ADDRESS);
        !           156: }
        !           157: 
        !           158: void
        !           159: vgahw_toggle_intensity(u8 flag)
        !           160: {
        !           161:     inb(VGAREG_ACTL_RESET);
        !           162:     outb(0x10, VGAREG_ACTL_ADDRESS);
        !           163:     u8 val = (inb(VGAREG_ACTL_READ_DATA) & 0xf7) | ((flag & 0x01) << 3);
        !           164:     outb(val, VGAREG_ACTL_WRITE_DATA);
        !           165:     outb(0x20, VGAREG_ACTL_ADDRESS);
        !           166: }
        !           167: 
        !           168: void
        !           169: vgahw_select_video_dac_color_page(u8 flag, u8 data)
        !           170: {
        !           171:     inb(VGAREG_ACTL_RESET);
        !           172:     outb(0x10, VGAREG_ACTL_ADDRESS);
        !           173:     u8 val = inb(VGAREG_ACTL_READ_DATA);
        !           174:     if (!(flag & 0x01)) {
        !           175:         // select paging mode
        !           176:         val = (val & 0x7f) | (data << 7);
        !           177:         outb(val, VGAREG_ACTL_WRITE_DATA);
        !           178:         outb(0x20, VGAREG_ACTL_ADDRESS);
        !           179:         return;
        !           180:     }
        !           181:     // select page
        !           182:     inb(VGAREG_ACTL_RESET);
        !           183:     outb(0x14, VGAREG_ACTL_ADDRESS);
        !           184:     if (!(val & 0x80))
        !           185:         data <<= 2;
        !           186:     data &= 0x0f;
        !           187:     outb(data, VGAREG_ACTL_WRITE_DATA);
        !           188:     outb(0x20, VGAREG_ACTL_ADDRESS);
        !           189: }
        !           190: 
        !           191: void
        !           192: vgahw_read_video_dac_state(u8 *pmode, u8 *curpage)
        !           193: {
        !           194:     inb(VGAREG_ACTL_RESET);
        !           195:     outb(0x10, VGAREG_ACTL_ADDRESS);
        !           196:     u8 val1 = inb(VGAREG_ACTL_READ_DATA) >> 7;
        !           197: 
        !           198:     inb(VGAREG_ACTL_RESET);
        !           199:     outb(0x14, VGAREG_ACTL_ADDRESS);
        !           200:     u8 val2 = inb(VGAREG_ACTL_READ_DATA) & 0x0f;
        !           201:     if (!(val1 & 0x01))
        !           202:         val2 >>= 2;
        !           203: 
        !           204:     inb(VGAREG_ACTL_RESET);
        !           205:     outb(0x20, VGAREG_ACTL_ADDRESS);
        !           206: 
        !           207:     *pmode = val1;
        !           208:     *curpage = val2;
        !           209: }
        !           210: 
        !           211: 
        !           212: /****************************************************************
        !           213:  * DAC control
        !           214:  ****************************************************************/
        !           215: 
        !           216: void
        !           217: vgahw_set_dac_regs(u8 *data_far, u8 start, int count)
        !           218: {
        !           219:     outb(start, VGAREG_DAC_WRITE_ADDRESS);
        !           220:     while (count) {
        !           221:         outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA);
        !           222:         data_far++;
        !           223:         outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA);
        !           224:         data_far++;
        !           225:         outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA);
        !           226:         data_far++;
        !           227:         count--;
        !           228:     }
        !           229: }
        !           230: 
        !           231: void
        !           232: vgahw_get_dac_regs(u8 *data_far, u8 start, int count)
        !           233: {
        !           234:     outb(start, VGAREG_DAC_READ_ADDRESS);
        !           235:     while (count) {
        !           236:         SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA));
        !           237:         data_far++;
        !           238:         SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA));
        !           239:         data_far++;
        !           240:         SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA));
        !           241:         data_far++;
        !           242:         count--;
        !           243:     }
        !           244: }
        !           245: 
        !           246: void
        !           247: vgahw_set_pel_mask(u8 val)
        !           248: {
        !           249:     outb(val, VGAREG_PEL_MASK);
        !           250: }
        !           251: 
        !           252: u8
        !           253: vgahw_get_pel_mask(void)
        !           254: {
        !           255:     return inb(VGAREG_PEL_MASK);
        !           256: }
        !           257: 
        !           258: void
        !           259: vgahw_save_dac_state(struct saveDACcolors *info)
        !           260: {
        !           261:     /* XXX: check this */
        !           262:     SET_FARVAR(seg, info->rwmode, inb(VGAREG_DAC_STATE));
        !           263:     SET_FARVAR(seg, info->peladdr, inb(VGAREG_DAC_WRITE_ADDRESS));
        !           264:     SET_FARVAR(seg, info->pelmask, inb(VGAREG_PEL_MASK));
        !           265:     vgahw_get_dac_regs(info->dac, 0, 256);
        !           266:     SET_FARVAR(seg, info->color_select, 0);
        !           267: }
        !           268: 
        !           269: void
        !           270: vgahw_restore_dac_state(struct saveDACcolors *info)
        !           271: {
        !           272:     outb(GET_FARVAR(seg, info->pelmask), VGAREG_PEL_MASK);
        !           273:     vgahw_set_dac_regs(info->dac, 0, 256);
        !           274:     outb(GET_FARVAR(seg, info->peladdr), VGAREG_DAC_WRITE_ADDRESS);
        !           275: }
        !           276: 
        !           277: 
        !           278: /****************************************************************
        !           279:  * Memory control
        !           280:  ****************************************************************/
        !           281: 
        !           282: void
        !           283: vgahw_sequ_write(u8 index, u8 value)
        !           284: {
        !           285:     outw((value<<8) | index, VGAREG_SEQU_ADDRESS);
        !           286: }
        !           287: 
        !           288: void
        !           289: vgahw_grdc_write(u8 index, u8 value)
        !           290: {
        !           291:     outw((value<<8) | index, VGAREG_GRDC_ADDRESS);
        !           292: }
        !           293: 
        !           294: void
        !           295: vgahw_set_text_block_specifier(u8 spec)
        !           296: {
        !           297:     outw((spec << 8) | 0x03, VGAREG_SEQU_ADDRESS);
        !           298: }
        !           299: 
        !           300: void
        !           301: get_font_access(void)
        !           302: {
        !           303:     outw(0x0100, VGAREG_SEQU_ADDRESS);
        !           304:     outw(0x0402, VGAREG_SEQU_ADDRESS);
        !           305:     outw(0x0704, VGAREG_SEQU_ADDRESS);
        !           306:     outw(0x0300, VGAREG_SEQU_ADDRESS);
        !           307:     outw(0x0204, VGAREG_GRDC_ADDRESS);
        !           308:     outw(0x0005, VGAREG_GRDC_ADDRESS);
        !           309:     outw(0x0406, VGAREG_GRDC_ADDRESS);
        !           310: }
        !           311: 
        !           312: void
        !           313: release_font_access(void)
        !           314: {
        !           315:     outw(0x0100, VGAREG_SEQU_ADDRESS);
        !           316:     outw(0x0302, VGAREG_SEQU_ADDRESS);
        !           317:     outw(0x0304, VGAREG_SEQU_ADDRESS);
        !           318:     outw(0x0300, VGAREG_SEQU_ADDRESS);
        !           319:     u16 v = (inw(VGAREG_READ_MISC_OUTPUT) & 0x01) ? 0x0e : 0x0a;
        !           320:     outw((v << 8) | 0x06, VGAREG_GRDC_ADDRESS);
        !           321:     outw(0x0004, VGAREG_GRDC_ADDRESS);
        !           322:     outw(0x1005, VGAREG_GRDC_ADDRESS);
        !           323: }
        !           324: 
        !           325: 
        !           326: /****************************************************************
        !           327:  * CRTC registers
        !           328:  ****************************************************************/
        !           329: 
        !           330: static u16
        !           331: get_crtc(void)
        !           332: {
        !           333:     return GET_BDA(crtc_address);
        !           334: }
        !           335: 
        !           336: void
        !           337: vgahw_set_cursor_shape(u8 start, u8 end)
        !           338: {
        !           339:     u16 crtc_addr = get_crtc();
        !           340:     outb(0x0a, crtc_addr);
        !           341:     outb(start, crtc_addr + 1);
        !           342:     outb(0x0b, crtc_addr);
        !           343:     outb(end, crtc_addr + 1);
        !           344: }
        !           345: 
        !           346: void
        !           347: vgahw_set_active_page(u16 address)
        !           348: {
        !           349:     u16 crtc_addr = get_crtc();
        !           350:     outb(0x0c, crtc_addr);
        !           351:     outb((address & 0xff00) >> 8, crtc_addr + 1);
        !           352:     outb(0x0d, crtc_addr);
        !           353:     outb(address & 0x00ff, crtc_addr + 1);
        !           354: }
        !           355: 
        !           356: void
        !           357: vgahw_set_cursor_pos(u16 address)
        !           358: {
        !           359:     u16 crtc_addr = get_crtc();
        !           360:     outb(0x0e, crtc_addr);
        !           361:     outb((address & 0xff00) >> 8, crtc_addr + 1);
        !           362:     outb(0x0f, crtc_addr);
        !           363:     outb(address & 0x00ff, crtc_addr + 1);
        !           364: }
        !           365: 
        !           366: void
        !           367: vgahw_set_scan_lines(u8 lines)
        !           368: {
        !           369:     u16 crtc_addr = get_crtc();
        !           370:     outb(0x09, crtc_addr);
        !           371:     u8 crtc_r9 = inb(crtc_addr + 1);
        !           372:     crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1);
        !           373:     outb(crtc_r9, crtc_addr + 1);
        !           374: }
        !           375: 
        !           376: // Get vertical display end
        !           377: u16
        !           378: vgahw_get_vde(void)
        !           379: {
        !           380:     u16 crtc_addr = get_crtc();
        !           381:     outb(0x12, crtc_addr);
        !           382:     u16 vde = inb(crtc_addr + 1);
        !           383:     outb(0x07, crtc_addr);
        !           384:     u8 ovl = inb(crtc_addr + 1);
        !           385:     vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1);
        !           386:     return vde;
        !           387: }
        !           388: 
        !           389: 
        !           390: /****************************************************************
        !           391:  * Save/Restore/Set state
        !           392:  ****************************************************************/
        !           393: 
        !           394: void
        !           395: vgahw_save_state(struct saveVideoHardware *info)
        !           396: {
        !           397:     u16 crtc_addr = get_crtc();
        !           398:     SET_FARVAR(seg, info->sequ_index, inb(VGAREG_SEQU_ADDRESS));
        !           399:     SET_FARVAR(seg, info->crtc_index, inb(crtc_addr));
        !           400:     SET_FARVAR(seg, info->grdc_index, inb(VGAREG_GRDC_ADDRESS));
        !           401:     inb(VGAREG_ACTL_RESET);
        !           402:     u16 ar_index = inb(VGAREG_ACTL_ADDRESS);
        !           403:     SET_FARVAR(seg, info->actl_index, ar_index);
        !           404:     SET_FARVAR(seg, info->feature, inb(VGAREG_READ_FEATURE_CTL));
        !           405: 
        !           406:     u16 i;
        !           407:     for (i=0; i<4; i++) {
        !           408:         outb(i+1, VGAREG_SEQU_ADDRESS);
        !           409:         SET_FARVAR(seg, info->sequ_regs[i], inb(VGAREG_SEQU_DATA));
        !           410:     }
        !           411:     outb(0, VGAREG_SEQU_ADDRESS);
        !           412:     SET_FARVAR(seg, info->sequ0, inb(VGAREG_SEQU_DATA));
        !           413: 
        !           414:     for (i=0; i<25; i++) {
        !           415:         outb(i, crtc_addr);
        !           416:         SET_FARVAR(seg, info->crtc_regs[i], inb(crtc_addr + 1));
        !           417:     }
        !           418: 
        !           419:     for (i=0; i<20; i++) {
        !           420:         inb(VGAREG_ACTL_RESET);
        !           421:         outb(i | (ar_index & 0x20), VGAREG_ACTL_ADDRESS);
        !           422:         SET_FARVAR(seg, info->actl_regs[i], inb(VGAREG_ACTL_READ_DATA));
        !           423:     }
        !           424:     inb(VGAREG_ACTL_RESET);
        !           425: 
        !           426:     for (i=0; i<9; i++) {
        !           427:         outb(i, VGAREG_GRDC_ADDRESS);
        !           428:         SET_FARVAR(seg, info->grdc_regs[i], inb(VGAREG_GRDC_DATA));
        !           429:     }
        !           430: 
        !           431:     SET_FARVAR(seg, info->crtc_addr, crtc_addr);
        !           432: 
        !           433:     /* XXX: read plane latches */
        !           434:     for (i=0; i<4; i++)
        !           435:         SET_FARVAR(seg, info->plane_latch[i], 0);
        !           436: }
        !           437: 
        !           438: void
        !           439: vgahw_restore_state(struct saveVideoHardware *info)
        !           440: {
        !           441:     // Reset Attribute Ctl flip-flop
        !           442:     inb(VGAREG_ACTL_RESET);
        !           443: 
        !           444:     u16 crtc_addr = GET_FARVAR(seg, info->crtc_addr);
        !           445: 
        !           446:     u16 i;
        !           447:     for (i=0; i<4; i++) {
        !           448:         outb(i+1, VGAREG_SEQU_ADDRESS);
        !           449:         outb(GET_FARVAR(seg, info->sequ_regs[i]), VGAREG_SEQU_DATA);
        !           450:     }
        !           451:     outb(0, VGAREG_SEQU_ADDRESS);
        !           452:     outb(GET_FARVAR(seg, info->sequ0), VGAREG_SEQU_DATA);
        !           453: 
        !           454:     // Disable CRTC write protection
        !           455:     outw(0x0011, crtc_addr);
        !           456:     // Set CRTC regs
        !           457:     for (i=0; i<25; i++)
        !           458:         if (i != 0x11) {
        !           459:             outb(i, crtc_addr);
        !           460:             outb(GET_FARVAR(seg, info->crtc_regs[i]), crtc_addr + 1);
        !           461:         }
        !           462:     // select crtc base address
        !           463:     u16 v = inb(VGAREG_READ_MISC_OUTPUT) & ~0x01;
        !           464:     if (crtc_addr == VGAREG_VGA_CRTC_ADDRESS)
        !           465:         v |= 0x01;
        !           466:     outb(v, VGAREG_WRITE_MISC_OUTPUT);
        !           467: 
        !           468:     // enable write protection if needed
        !           469:     outb(0x11, crtc_addr);
        !           470:     outb(GET_FARVAR(seg, info->crtc_regs[0x11]), crtc_addr + 1);
        !           471: 
        !           472:     // Set Attribute Ctl
        !           473:     u16 ar_index = GET_FARVAR(seg, info->actl_index);
        !           474:     inb(VGAREG_ACTL_RESET);
        !           475:     for (i=0; i<20; i++) {
        !           476:         outb(i | (ar_index & 0x20), VGAREG_ACTL_ADDRESS);
        !           477:         outb(GET_FARVAR(seg, info->actl_regs[i]), VGAREG_ACTL_WRITE_DATA);
        !           478:     }
        !           479:     outb(ar_index, VGAREG_ACTL_ADDRESS);
        !           480:     inb(VGAREG_ACTL_RESET);
        !           481: 
        !           482:     for (i=0; i<9; i++) {
        !           483:         outb(i, VGAREG_GRDC_ADDRESS);
        !           484:         outb(GET_FARVAR(seg, info->grdc_regs[i]), VGAREG_GRDC_DATA);
        !           485:     }
        !           486: 
        !           487:     outb(GET_FARVAR(seg, info->sequ_index), VGAREG_SEQU_ADDRESS);
        !           488:     outb(GET_FARVAR(seg, info->crtc_index), crtc_addr);
        !           489:     outb(GET_FARVAR(seg, info->grdc_index), VGAREG_GRDC_ADDRESS);
        !           490:     outb(GET_FARVAR(seg, info->feature), crtc_addr - 0x4 + 0xa);
        !           491: }
        !           492: 
        !           493: void
        !           494: vgahw_set_mode(struct VideoParam_s *vparam_g)
        !           495: {
        !           496:     // Reset Attribute Ctl flip-flop
        !           497:     inb(VGAREG_ACTL_RESET);
        !           498: 
        !           499:     // Set Attribute Ctl
        !           500:     u16 i;
        !           501:     for (i = 0; i <= 0x13; i++) {
        !           502:         outb(i, VGAREG_ACTL_ADDRESS);
        !           503:         outb(GET_GLOBAL(vparam_g->actl_regs[i]), VGAREG_ACTL_WRITE_DATA);
        !           504:     }
        !           505:     outb(0x14, VGAREG_ACTL_ADDRESS);
        !           506:     outb(0x00, VGAREG_ACTL_WRITE_DATA);
        !           507: 
        !           508:     // Set Sequencer Ctl
        !           509:     outb(0, VGAREG_SEQU_ADDRESS);
        !           510:     outb(0x03, VGAREG_SEQU_DATA);
        !           511:     for (i = 1; i <= 4; i++) {
        !           512:         outb(i, VGAREG_SEQU_ADDRESS);
        !           513:         outb(GET_GLOBAL(vparam_g->sequ_regs[i - 1]), VGAREG_SEQU_DATA);
        !           514:     }
        !           515: 
        !           516:     // Set Grafx Ctl
        !           517:     for (i = 0; i <= 8; i++) {
        !           518:         outb(i, VGAREG_GRDC_ADDRESS);
        !           519:         outb(GET_GLOBAL(vparam_g->grdc_regs[i]), VGAREG_GRDC_DATA);
        !           520:     }
        !           521: 
        !           522:     // Set CRTC address VGA or MDA
        !           523:     u8 miscreg = GET_GLOBAL(vparam_g->miscreg);
        !           524:     u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS;
        !           525:     if (!(miscreg & 1))
        !           526:         crtc_addr = VGAREG_MDA_CRTC_ADDRESS;
        !           527: 
        !           528:     // Disable CRTC write protection
        !           529:     outw(0x0011, crtc_addr);
        !           530:     // Set CRTC regs
        !           531:     for (i = 0; i <= 0x18; i++) {
        !           532:         outb(i, crtc_addr);
        !           533:         outb(GET_GLOBAL(vparam_g->crtc_regs[i]), crtc_addr + 1);
        !           534:     }
        !           535: 
        !           536:     // Set the misc register
        !           537:     outb(miscreg, VGAREG_WRITE_MISC_OUTPUT);
        !           538: 
        !           539:     // Enable video
        !           540:     outb(0x20, VGAREG_ACTL_ADDRESS);
        !           541:     inb(VGAREG_ACTL_RESET);
        !           542: }
        !           543: 
        !           544: 
        !           545: /****************************************************************
        !           546:  * Misc
        !           547:  ****************************************************************/
        !           548: 
        !           549: void
        !           550: vgahw_enable_video_addressing(u8 disable)
        !           551: {
        !           552:     u8 v = (disable & 1) ? 0x00 : 0x02;
        !           553:     u8 v2 = inb(VGAREG_READ_MISC_OUTPUT) & ~0x02;
        !           554:     outb(v | v2, VGAREG_WRITE_MISC_OUTPUT);
        !           555: }
        !           556: 
        !           557: void
        !           558: vgahw_init(void)
        !           559: {
        !           560:   struct vgamode_s *vmode_g;
        !           561:   int bdf, max;
        !           562: 
        !           563:   foreachpci(bdf, max)
        !           564:     {
        !           565:       uint16_t class = pci_config_readw(bdf, PCI_CLASS_DEVICE);
        !           566:       if (class == PCI_CLASS_DISPLAY_VGA)
        !           567:         goto found;
        !           568:     }
        !           569:   return;
        !           570: 
        !           571:  found:
        !           572:   have_vga = 1;
        !           573: 
        !           574:   vmode_g = find_vga_entry(3);
        !           575: 
        !           576:   vgahw_sequ_write(0, 1);      // Assert sync reset
        !           577:   
        !           578:   // Switch to color mode and enable CPU access 480 lines
        !           579:   outb(0xc3, VGAREG_WRITE_MISC_OUTPUT);
        !           580: 
        !           581:   vgahw_sequ_write(0, 3);      // De-assert sync reset
        !           582: 
        !           583:   vgahw_set_mode(vmode_g->vparam);
        !           584: 
        !           585:   vgahw_sequ_write(4, 0x06); // disable odd/even + chain4
        !           586:   vgahw_sequ_write(1, vmode_g->vparam->sequ_regs[1] | 0x20); // disable video
        !           587:   vgahw_grdc_write(5, vmode_g->vparam->grdc_regs[5] & 0xef); // disable odd/even
        !           588:   vgahw_grdc_write(6, 0x05); // set mem map to 0xa0000 and graphics mode
        !           589:   vgahw_sequ_write(2, 0x04); // enable write plane 2
        !           590: 
        !           591:   {
        !           592:     unsigned char *font_ptr = pci_mem_base + SEG_GRAPH*16;
        !           593:     int i;
        !           594: 
        !           595:     for (i = 0; i < 0x100; i++)
        !           596:       __builtin_memcpy(font_ptr + i*32, vgafont16 + i*16, 16);
        !           597:   }
        !           598: 
        !           599:   {
        !           600:     int i = vmode_g->dacsize / 3;
        !           601:     vgahw_set_dac_regs(vmode_g->dac, 0, i);
        !           602:   }
        !           603: 
        !           604:   vgahw_sequ_write(4, 0x2); // enable odd/even
        !           605:   vgahw_set_mode(vmode_g->vparam);
        !           606: }

unix.superglobalmegacorp.com