Annotation of qemu/roms/seabios/vgasrc/stdvga.c, revision 1.1.1.1

1.1       root        1: // Standard VGA driver code
                      2: //
                      3: // Copyright (C) 2009  Kevin O'Connor <[email protected]>
                      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 "vgabios.h" // struct vgamode_s
                      9: #include "stdvga.h" // stdvga_init
                     10: #include "ioport.h" // outb
                     11: #include "farptr.h" // SET_FARVAR
                     12: #include "biosvar.h" // GET_GLOBAL
                     13: #include "util.h" // memcpy_far
                     14: 
                     15: 
                     16: /****************************************************************
                     17:  * Attribute control
                     18:  ****************************************************************/
                     19: 
                     20: void
                     21: stdvga_set_border_color(u8 color)
                     22: {
                     23:     u8 v1 = color & 0x0f;
                     24:     if (v1 & 0x08)
                     25:         v1 += 0x08;
                     26:     stdvga_attr_write(0x00, v1);
                     27: 
                     28:     int i;
                     29:     for (i = 1; i < 4; i++)
                     30:         stdvga_attr_mask(i, 0x10, color & 0x10);
                     31: }
                     32: 
                     33: void
                     34: stdvga_set_overscan_border_color(u8 color)
                     35: {
                     36:     stdvga_attr_write(0x11, color);
                     37: }
                     38: 
                     39: u8
                     40: stdvga_get_overscan_border_color(void)
                     41: {
                     42:     return stdvga_attr_read(0x11);
                     43: }
                     44: 
                     45: void
                     46: stdvga_set_palette(u8 palid)
                     47: {
                     48:     int i;
                     49:     for (i = 1; i < 4; i++)
                     50:         stdvga_attr_mask(i, 0x01, palid & 0x01);
                     51: }
                     52: 
                     53: void
                     54: stdvga_set_all_palette_reg(u16 seg, u8 *data_far)
                     55: {
                     56:     int i;
                     57:     for (i = 0; i < 0x10; i++) {
                     58:         stdvga_attr_write(i, GET_FARVAR(seg, *data_far));
                     59:         data_far++;
                     60:     }
                     61:     stdvga_attr_write(0x11, GET_FARVAR(seg, *data_far));
                     62: }
                     63: 
                     64: void
                     65: stdvga_get_all_palette_reg(u16 seg, u8 *data_far)
                     66: {
                     67:     int i;
                     68:     for (i = 0; i < 0x10; i++) {
                     69:         SET_FARVAR(seg, *data_far, stdvga_attr_read(i));
                     70:         data_far++;
                     71:     }
                     72:     SET_FARVAR(seg, *data_far, stdvga_attr_read(0x11));
                     73: }
                     74: 
                     75: void
                     76: stdvga_toggle_intensity(u8 flag)
                     77: {
                     78:     stdvga_attr_mask(0x10, 0x08, (flag & 0x01) << 3);
                     79: }
                     80: 
                     81: void
                     82: stdvga_select_video_dac_color_page(u8 flag, u8 data)
                     83: {
                     84:     if (!(flag & 0x01)) {
                     85:         // select paging mode
                     86:         stdvga_attr_mask(0x10, 0x80, data << 7);
                     87:         return;
                     88:     }
                     89:     // select page
                     90:     u8 val = stdvga_attr_read(0x10);
                     91:     if (!(val & 0x80))
                     92:         data <<= 2;
                     93:     data &= 0x0f;
                     94:     stdvga_attr_write(0x14, data);
                     95: }
                     96: 
                     97: void
                     98: stdvga_read_video_dac_state(u8 *pmode, u8 *curpage)
                     99: {
                    100:     u8 val1 = stdvga_attr_read(0x10) >> 7;
                    101:     u8 val2 = stdvga_attr_read(0x14) & 0x0f;
                    102:     if (!(val1 & 0x01))
                    103:         val2 >>= 2;
                    104:     *pmode = val1;
                    105:     *curpage = val2;
                    106: }
                    107: 
                    108: 
                    109: /****************************************************************
                    110:  * DAC control
                    111:  ****************************************************************/
                    112: 
                    113: void
                    114: stdvga_perform_gray_scale_summing(u16 start, u16 count)
                    115: {
                    116:     stdvga_attrindex_write(0x00);
                    117:     int i;
                    118:     for (i = start; i < start+count; i++) {
                    119:         u8 rgb[3];
                    120:         stdvga_dac_read(GET_SEG(SS), rgb, i, 1);
                    121: 
                    122:         // intensity = ( 0.3 * Red ) + ( 0.59 * Green ) + ( 0.11 * Blue )
                    123:         u16 intensity = ((77 * rgb[0] + 151 * rgb[1] + 28 * rgb[2]) + 0x80) >> 8;
                    124:         if (intensity > 0x3f)
                    125:             intensity = 0x3f;
                    126: 
                    127:         stdvga_dac_write(GET_SEG(SS), rgb, i, 1);
                    128:     }
                    129:     stdvga_attrindex_write(0x20);
                    130: }
                    131: 
                    132: 
                    133: /****************************************************************
                    134:  * Memory control
                    135:  ****************************************************************/
                    136: 
                    137: void
                    138: stdvga_set_text_block_specifier(u8 spec)
                    139: {
                    140:     stdvga_sequ_write(0x03, spec);
                    141: }
                    142: 
                    143: // Enable reads and writes to the given "plane" when in planar4 mode.
                    144: void
                    145: stdvga_planar4_plane(int plane)
                    146: {
                    147:     if (plane < 0) {
                    148:         // Return to default mode (read plane0, write all planes)
                    149:         stdvga_sequ_write(0x02, 0x0f);
                    150:         stdvga_grdc_write(0x04, 0);
                    151:     } else {
                    152:         stdvga_sequ_write(0x02, 1<<plane);
                    153:         stdvga_grdc_write(0x04, plane);
                    154:     }
                    155: }
                    156: 
                    157: 
                    158: /****************************************************************
                    159:  * Font loading
                    160:  ****************************************************************/
                    161: 
                    162: static void
                    163: get_font_access(void)
                    164: {
                    165:     stdvga_sequ_write(0x00, 0x01);
                    166:     stdvga_sequ_write(0x02, 0x04);
                    167:     stdvga_sequ_write(0x04, 0x07);
                    168:     stdvga_sequ_write(0x00, 0x03);
                    169:     stdvga_grdc_write(0x04, 0x02);
                    170:     stdvga_grdc_write(0x05, 0x00);
                    171:     stdvga_grdc_write(0x06, 0x04);
                    172: }
                    173: 
                    174: static void
                    175: release_font_access(void)
                    176: {
                    177:     stdvga_sequ_write(0x00, 0x01);
                    178:     stdvga_sequ_write(0x02, 0x03);
                    179:     stdvga_sequ_write(0x04, 0x03);
                    180:     stdvga_sequ_write(0x00, 0x03);
                    181:     u16 v = (stdvga_misc_read() & 0x01) ? 0x0e : 0x0a;
                    182:     stdvga_grdc_write(0x06, v);
                    183:     stdvga_grdc_write(0x04, 0x00);
                    184:     stdvga_grdc_write(0x05, 0x10);
                    185: }
                    186: 
                    187: void
                    188: stdvga_load_font(u16 seg, void *src_far, u16 count
                    189:                  , u16 start, u8 destflags, u8 fontsize)
                    190: {
                    191:     get_font_access();
                    192:     u16 blockaddr = ((destflags & 0x03) << 14) + ((destflags & 0x04) << 11);
                    193:     void *dest_far = (void*)(blockaddr + start*32);
                    194:     u16 i;
                    195:     for (i = 0; i < count; i++)
                    196:         memcpy_far(SEG_GRAPH, dest_far + i*32
                    197:                    , seg, src_far + i*fontsize, fontsize);
                    198:     release_font_access();
                    199: }
                    200: 
                    201: 
                    202: /****************************************************************
                    203:  * CRTC registers
                    204:  ****************************************************************/
                    205: 
                    206: u16
                    207: stdvga_get_crtc(void)
                    208: {
                    209:     if (stdvga_misc_read() & 1)
                    210:         return VGAREG_VGA_CRTC_ADDRESS;
                    211:     return VGAREG_MDA_CRTC_ADDRESS;
                    212: }
                    213: 
                    214: // Return the multiplication factor needed for the vga offset register.
                    215: int
                    216: stdvga_bpp_factor(struct vgamode_s *vmode_g)
                    217: {
                    218:     switch (GET_GLOBAL(vmode_g->memmodel)) {
                    219:     case MM_TEXT:
                    220:         return 2;
                    221:     case MM_CGA:
                    222:         return GET_GLOBAL(vmode_g->depth);
                    223:     case MM_PLANAR:
                    224:         return 1;
                    225:     default:
                    226:         return 4;
                    227:     }
                    228: }
                    229: 
                    230: void
                    231: stdvga_set_cursor_shape(u8 start, u8 end)
                    232: {
                    233:     u16 crtc_addr = stdvga_get_crtc();
                    234:     stdvga_crtc_write(crtc_addr, 0x0a, start);
                    235:     stdvga_crtc_write(crtc_addr, 0x0b, end);
                    236: }
                    237: 
                    238: void
                    239: stdvga_set_cursor_pos(int address)
                    240: {
                    241:     u16 crtc_addr = stdvga_get_crtc();
                    242:     address /= 2;  // Assume we're in text mode.
                    243:     stdvga_crtc_write(crtc_addr, 0x0e, address >> 8);
                    244:     stdvga_crtc_write(crtc_addr, 0x0f, address);
                    245: }
                    246: 
                    247: void
                    248: stdvga_set_scan_lines(u8 lines)
                    249: {
                    250:     stdvga_crtc_mask(stdvga_get_crtc(), 0x09, 0x1f, lines - 1);
                    251: }
                    252: 
                    253: // Get vertical display end
                    254: u16
                    255: stdvga_get_vde(void)
                    256: {
                    257:     u16 crtc_addr = stdvga_get_crtc();
                    258:     u16 vde = stdvga_crtc_read(crtc_addr, 0x12);
                    259:     u8 ovl = stdvga_crtc_read(crtc_addr, 0x07);
                    260:     vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1);
                    261:     return vde;
                    262: }
                    263: 
                    264: int
                    265: stdvga_get_window(struct vgamode_s *vmode_g, int window)
                    266: {
                    267:     return -1;
                    268: }
                    269: 
                    270: int
                    271: stdvga_set_window(struct vgamode_s *vmode_g, int window, int val)
                    272: {
                    273:     return -1;
                    274: }
                    275: 
                    276: int
                    277: stdvga_get_linelength(struct vgamode_s *vmode_g)
                    278: {
                    279:     u8 val = stdvga_crtc_read(stdvga_get_crtc(), 0x13);
                    280:     return val * stdvga_bpp_factor(vmode_g) * 2;
                    281: }
                    282: 
                    283: int
                    284: stdvga_set_linelength(struct vgamode_s *vmode_g, int val)
                    285: {
                    286:     int factor = stdvga_bpp_factor(vmode_g) * 2;
                    287:     stdvga_crtc_write(stdvga_get_crtc(), 0x13, DIV_ROUND_UP(val, factor));
                    288:     return 0;
                    289: }
                    290: 
                    291: int
                    292: stdvga_get_displaystart(struct vgamode_s *vmode_g)
                    293: {
                    294:     u16 crtc_addr = stdvga_get_crtc();
                    295:     int addr = (stdvga_crtc_read(crtc_addr, 0x0c) << 8
                    296:                 | stdvga_crtc_read(crtc_addr, 0x0d));
                    297:     return addr * stdvga_bpp_factor(vmode_g);
                    298: }
                    299: 
                    300: int
                    301: stdvga_set_displaystart(struct vgamode_s *vmode_g, int val)
                    302: {
                    303:     u16 crtc_addr = stdvga_get_crtc();
                    304:     val /= stdvga_bpp_factor(vmode_g);
                    305:     stdvga_crtc_write(crtc_addr, 0x0c, val >> 8);
                    306:     stdvga_crtc_write(crtc_addr, 0x0d, val);
                    307:     return 0;
                    308: }
                    309: 
                    310: int
                    311: stdvga_get_dacformat(struct vgamode_s *vmode_g)
                    312: {
                    313:     return -1;
                    314: }
                    315: 
                    316: int
                    317: stdvga_set_dacformat(struct vgamode_s *vmode_g, int val)
                    318: {
                    319:     return -1;
                    320: }
                    321: 
                    322: 
                    323: /****************************************************************
                    324:  * Save/Restore state
                    325:  ****************************************************************/
                    326: 
                    327: struct saveVideoHardware {
                    328:     u8 sequ_index;
                    329:     u8 crtc_index;
                    330:     u8 grdc_index;
                    331:     u8 actl_index;
                    332:     u8 feature;
                    333:     u8 sequ_regs[4];
                    334:     u8 sequ0;
                    335:     u8 crtc_regs[25];
                    336:     u8 actl_regs[20];
                    337:     u8 grdc_regs[9];
                    338:     u16 crtc_addr;
                    339:     u8 plane_latch[4];
                    340: };
                    341: 
                    342: static void
                    343: stdvga_save_hw_state(u16 seg, struct saveVideoHardware *info)
                    344: {
                    345:     u16 crtc_addr = stdvga_get_crtc();
                    346:     SET_FARVAR(seg, info->sequ_index, inb(VGAREG_SEQU_ADDRESS));
                    347:     SET_FARVAR(seg, info->crtc_index, inb(crtc_addr));
                    348:     SET_FARVAR(seg, info->grdc_index, inb(VGAREG_GRDC_ADDRESS));
                    349:     SET_FARVAR(seg, info->actl_index, stdvga_attrindex_read());
                    350:     SET_FARVAR(seg, info->feature, inb(VGAREG_READ_FEATURE_CTL));
                    351: 
                    352:     int i;
                    353:     for (i=0; i<4; i++)
                    354:         SET_FARVAR(seg, info->sequ_regs[i], stdvga_sequ_read(i+1));
                    355:     SET_FARVAR(seg, info->sequ0, stdvga_sequ_read(0));
                    356: 
                    357:     for (i=0; i<25; i++)
                    358:         SET_FARVAR(seg, info->crtc_regs[i], stdvga_crtc_read(crtc_addr, i));
                    359: 
                    360:     for (i=0; i<20; i++)
                    361:         SET_FARVAR(seg, info->actl_regs[i], stdvga_attr_read(i));
                    362: 
                    363:     for (i=0; i<9; i++)
                    364:         SET_FARVAR(seg, info->grdc_regs[i], stdvga_grdc_read(i));
                    365: 
                    366:     SET_FARVAR(seg, info->crtc_addr, crtc_addr);
                    367: 
                    368:     /* XXX: read plane latches */
                    369:     for (i=0; i<4; i++)
                    370:         SET_FARVAR(seg, info->plane_latch[i], 0);
                    371: }
                    372: 
                    373: static void
                    374: stdvga_restore_hw_state(u16 seg, struct saveVideoHardware *info)
                    375: {
                    376:     int i;
                    377:     for (i=0; i<4; i++)
                    378:         stdvga_sequ_write(i+1, GET_FARVAR(seg, info->sequ_regs[i]));
                    379:     stdvga_sequ_write(0x00, GET_FARVAR(seg, info->sequ0));
                    380: 
                    381:     // Disable CRTC write protection
                    382:     u16 crtc_addr = GET_FARVAR(seg, info->crtc_addr);
                    383:     stdvga_crtc_write(crtc_addr, 0x11, 0x00);
                    384:     // Set CRTC regs
                    385:     for (i=0; i<25; i++)
                    386:         if (i != 0x11)
                    387:             stdvga_crtc_write(crtc_addr, i, GET_FARVAR(seg, info->crtc_regs[i]));
                    388:     // select crtc base address
                    389:     stdvga_misc_mask(0x01, crtc_addr == VGAREG_VGA_CRTC_ADDRESS ? 0x01 : 0x00);
                    390: 
                    391:     // enable write protection if needed
                    392:     stdvga_crtc_write(crtc_addr, 0x11, GET_FARVAR(seg, info->crtc_regs[0x11]));
                    393: 
                    394:     // Set Attribute Ctl
                    395:     for (i=0; i<20; i++)
                    396:         stdvga_attr_write(i, GET_FARVAR(seg, info->actl_regs[i]));
                    397:     stdvga_attrindex_write(GET_FARVAR(seg, info->actl_index));
                    398: 
                    399:     for (i=0; i<9; i++)
                    400:         stdvga_grdc_write(i, GET_FARVAR(seg, info->grdc_regs[i]));
                    401: 
                    402:     outb(GET_FARVAR(seg, info->sequ_index), VGAREG_SEQU_ADDRESS);
                    403:     outb(GET_FARVAR(seg, info->crtc_index), crtc_addr);
                    404:     outb(GET_FARVAR(seg, info->grdc_index), VGAREG_GRDC_ADDRESS);
                    405:     outb(GET_FARVAR(seg, info->feature), crtc_addr - 0x4 + 0xa);
                    406: }
                    407: 
                    408: struct saveDACcolors {
                    409:     u8 rwmode;
                    410:     u8 peladdr;
                    411:     u8 pelmask;
                    412:     u8 dac[768];
                    413:     u8 color_select;
                    414: };
                    415: 
                    416: static void
                    417: stdvga_save_dac_state(u16 seg, struct saveDACcolors *info)
                    418: {
                    419:     /* XXX: check this */
                    420:     SET_FARVAR(seg, info->rwmode, inb(VGAREG_DAC_STATE));
                    421:     SET_FARVAR(seg, info->peladdr, inb(VGAREG_DAC_WRITE_ADDRESS));
                    422:     SET_FARVAR(seg, info->pelmask, stdvga_pelmask_read());
                    423:     stdvga_dac_read(seg, info->dac, 0, 256);
                    424:     SET_FARVAR(seg, info->color_select, 0);
                    425: }
                    426: 
                    427: static void
                    428: stdvga_restore_dac_state(u16 seg, struct saveDACcolors *info)
                    429: {
                    430:     stdvga_pelmask_write(GET_FARVAR(seg, info->pelmask));
                    431:     stdvga_dac_write(seg, info->dac, 0, 256);
                    432:     outb(GET_FARVAR(seg, info->peladdr), VGAREG_DAC_WRITE_ADDRESS);
                    433: }
                    434: 
                    435: int
                    436: stdvga_size_state(int states)
                    437: {
                    438:     int size = 0;
                    439:     if (states & 1)
                    440:         size += sizeof(struct saveVideoHardware);
                    441:     if (states & 2)
                    442:         size += sizeof(struct saveBDAstate);
                    443:     if (states & 4)
                    444:         size += sizeof(struct saveDACcolors);
                    445:     return size;
                    446: }
                    447: 
                    448: int
                    449: stdvga_save_state(u16 seg, void *data, int states)
                    450: {
                    451:     if (states & 1) {
                    452:         stdvga_save_hw_state(seg, data);
                    453:         data += sizeof(struct saveVideoHardware);
                    454:     }
                    455:     if (states & 2) {
                    456:         save_bda_state(seg, data);
                    457:         data += sizeof(struct saveBDAstate);
                    458:     }
                    459:     if (states & 4)
                    460:         stdvga_save_dac_state(seg, data);
                    461:     return 0;
                    462: }
                    463: 
                    464: int
                    465: stdvga_restore_state(u16 seg, void *data, int states)
                    466: {
                    467:     if (states & 1) {
                    468:         stdvga_restore_hw_state(seg, data);
                    469:         data += sizeof(struct saveVideoHardware);
                    470:     }
                    471:     if (states & 2) {
                    472:         restore_bda_state(seg, data);
                    473:         data += sizeof(struct saveBDAstate);
                    474:     }
                    475:     if (states & 4)
                    476:         stdvga_restore_dac_state(seg, data);
                    477:     return 0;
                    478: }
                    479: 
                    480: 
                    481: /****************************************************************
                    482:  * Misc
                    483:  ****************************************************************/
                    484: 
                    485: void
                    486: stdvga_enable_video_addressing(u8 disable)
                    487: {
                    488:     u8 v = (disable & 1) ? 0x00 : 0x02;
                    489:     stdvga_misc_mask(0x02, v);
                    490: }
                    491: 
                    492: int
                    493: stdvga_init(void)
                    494: {
                    495:     // switch to color mode and enable CPU access 480 lines
                    496:     stdvga_misc_write(0xc3);
                    497:     // more than 64k 3C4/04
                    498:     stdvga_sequ_write(0x04, 0x02);
                    499: 
                    500:     return 0;
                    501: }

unix.superglobalmegacorp.com

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