Annotation of qemu/roms/seabios/vgasrc/stdvga.c, revision 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.