Annotation of qemu/roms/qemu-palcode/vgaio.c, revision 1.1.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