|
|
1.1 ! root 1: // Video Bios Extensions handlers ! 2: // ! 3: // Copyright (C) 2012 Kevin O'Connor <[email protected]> ! 4: // Copyright (C) 2011 Julian Pidancet <[email protected]> ! 5: // Copyright (C) 2001-2008 the LGPL VGABios developers Team ! 6: // ! 7: // This file may be distributed under the terms of the GNU LGPLv3 license. ! 8: ! 9: #include "vgabios.h" // handle_104f ! 10: #include "config.h" // CONFIG_* ! 11: #include "bregs.h" // struct bregs ! 12: #include "vbe.h" // struct vbe_info ! 13: #include "util.h" // dprintf ! 14: #include "biosvar.h" // GET_GLOBAL ! 15: #include "vgahw.h" // vgahw_set_mode ! 16: ! 17: u32 VBE_total_memory VAR16 = 256 * 1024; ! 18: u32 VBE_capabilities VAR16; ! 19: u32 VBE_framebuffer VAR16; ! 20: u16 VBE_win_granularity VAR16 = 64; ! 21: ! 22: static void ! 23: vbe_104f00(struct bregs *regs) ! 24: { ! 25: u16 seg = regs->es; ! 26: struct vbe_info *info = (void*)(regs->di+0); ! 27: ! 28: if (GET_FARVAR(seg, info->signature) == VBE2_SIGNATURE) { ! 29: dprintf(4, "Get VBE Controller: VBE2 Signature found\n"); ! 30: } else if (GET_FARVAR(seg, info->signature) == VESA_SIGNATURE) { ! 31: dprintf(4, "Get VBE Controller: VESA Signature found\n"); ! 32: } else { ! 33: dprintf(4, "Get VBE Controller: Invalid Signature\n"); ! 34: } ! 35: ! 36: memset_far(seg, info, 0, sizeof(*info)); ! 37: ! 38: SET_FARVAR(seg, info->signature, VESA_SIGNATURE); ! 39: ! 40: SET_FARVAR(seg, info->version, 0x0300); ! 41: ! 42: SET_FARVAR(seg, info->oem_string, ! 43: SEGOFF(get_global_seg(), (u32)VBE_OEM_STRING)); ! 44: SET_FARVAR(seg, info->capabilities, GET_GLOBAL(VBE_capabilities)); ! 45: ! 46: /* We generate our mode list in the reserved field of the info block */ ! 47: u16 *destmode = (void*)info->reserved; ! 48: SET_FARVAR(seg, info->video_mode, SEGOFF(seg, (u32)destmode)); ! 49: ! 50: /* Total memory (in 64k blocks) */ ! 51: SET_FARVAR(seg, info->total_memory ! 52: , GET_GLOBAL(VBE_total_memory) / (64*1024)); ! 53: ! 54: SET_FARVAR(seg, info->oem_vendor_string, ! 55: SEGOFF(get_global_seg(), (u32)VBE_VENDOR_STRING)); ! 56: SET_FARVAR(seg, info->oem_product_string, ! 57: SEGOFF(get_global_seg(), (u32)VBE_PRODUCT_STRING)); ! 58: SET_FARVAR(seg, info->oem_revision_string, ! 59: SEGOFF(get_global_seg(), (u32)VBE_REVISION_STRING)); ! 60: ! 61: /* Fill list of modes */ ! 62: u16 *last = (void*)&info->reserved[sizeof(info->reserved)]; ! 63: vgahw_list_modes(seg, destmode, last - 1); ! 64: ! 65: regs->ax = 0x004f; ! 66: } ! 67: ! 68: static void ! 69: vbe_104f01(struct bregs *regs) ! 70: { ! 71: u16 seg = regs->es; ! 72: struct vbe_mode_info *info = (void*)(regs->di+0); ! 73: u16 mode = regs->cx; ! 74: ! 75: dprintf(1, "VBE mode info request: %x\n", mode); ! 76: ! 77: struct vgamode_s *vmode_g = vgahw_find_mode(mode); ! 78: if (! vmode_g) { ! 79: dprintf(1, "VBE mode %x not found\n", mode); ! 80: regs->ax = 0x014f; ! 81: return; ! 82: } ! 83: ! 84: memset_far(seg, info, 0, sizeof(*info)); ! 85: u16 mode_attr = VBE_MODE_ATTRIBUTE_SUPPORTED | ! 86: VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE | ! 87: VBE_MODE_ATTRIBUTE_COLOR_MODE | ! 88: VBE_MODE_ATTRIBUTE_GRAPHICS_MODE | ! 89: VBE_MODE_ATTRIBUTE_NOT_VGA_COMPATIBLE; ! 90: u32 framebuffer = GET_GLOBAL(VBE_framebuffer); ! 91: if (framebuffer) ! 92: mode_attr |= VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE; ! 93: SET_FARVAR(seg, info->mode_attributes, mode_attr); ! 94: SET_FARVAR(seg, info->winA_attributes, ! 95: VBE_WINDOW_ATTRIBUTE_RELOCATABLE | ! 96: VBE_WINDOW_ATTRIBUTE_READABLE | ! 97: VBE_WINDOW_ATTRIBUTE_WRITEABLE); ! 98: SET_FARVAR(seg, info->winB_attributes, 0); ! 99: SET_FARVAR(seg, info->win_granularity, GET_GLOBAL(VBE_win_granularity)); ! 100: SET_FARVAR(seg, info->win_size, 64); /* Bank size 64K */ ! 101: SET_FARVAR(seg, info->winA_seg, GET_GLOBAL(vmode_g->sstart)); ! 102: SET_FARVAR(seg, info->winB_seg, 0x0); ! 103: extern void entry_104f05(void); ! 104: SET_FARVAR(seg, info->win_func_ptr ! 105: , SEGOFF(get_global_seg(), (u32)entry_104f05)); ! 106: int width = GET_GLOBAL(vmode_g->width); ! 107: int height = GET_GLOBAL(vmode_g->height); ! 108: int linesize = DIV_ROUND_UP(width * vga_bpp(vmode_g), 8); ! 109: SET_FARVAR(seg, info->bytes_per_scanline, linesize); ! 110: SET_FARVAR(seg, info->xres, width); ! 111: SET_FARVAR(seg, info->yres, height); ! 112: SET_FARVAR(seg, info->xcharsize, GET_GLOBAL(vmode_g->cwidth)); ! 113: SET_FARVAR(seg, info->ycharsize, GET_GLOBAL(vmode_g->cheight)); ! 114: int depth = GET_GLOBAL(vmode_g->depth); ! 115: int planes = (depth == 4) ? 4 : 1; ! 116: SET_FARVAR(seg, info->planes, planes); ! 117: SET_FARVAR(seg, info->bits_per_pixel, depth); ! 118: SET_FARVAR(seg, info->banks, 1); ! 119: SET_FARVAR(seg, info->mem_model, GET_GLOBAL(vmode_g->memmodel)); ! 120: SET_FARVAR(seg, info->bank_size, 0); ! 121: u32 pages = GET_GLOBAL(VBE_total_memory) / ALIGN(height * linesize, 64*1024); ! 122: SET_FARVAR(seg, info->pages, (pages / planes) - 1); ! 123: SET_FARVAR(seg, info->reserved0, 1); ! 124: ! 125: u8 r_size, r_pos, g_size, g_pos, b_size, b_pos, a_size, a_pos; ! 126: ! 127: switch (depth) { ! 128: case 15: r_size = 5; r_pos = 10; g_size = 5; g_pos = 5; ! 129: b_size = 5; b_pos = 0; a_size = 1; a_pos = 15; break; ! 130: case 16: r_size = 5; r_pos = 11; g_size = 6; g_pos = 5; ! 131: b_size = 5; b_pos = 0; a_size = 0; a_pos = 0; break; ! 132: case 24: r_size = 8; r_pos = 16; g_size = 8; g_pos = 8; ! 133: b_size = 8; b_pos = 0; a_size = 0; a_pos = 0; break; ! 134: case 32: r_size = 8; r_pos = 16; g_size = 8; g_pos = 8; ! 135: b_size = 8; b_pos = 0; a_size = 8; a_pos = 24; break; ! 136: default: r_size = 0; r_pos = 0; g_size = 0; g_pos = 0; ! 137: b_size = 0; b_pos = 0; a_size = 0; a_pos = 0; break; ! 138: } ! 139: ! 140: SET_FARVAR(seg, info->red_size, r_size); ! 141: SET_FARVAR(seg, info->red_pos, r_pos); ! 142: SET_FARVAR(seg, info->green_size, g_size); ! 143: SET_FARVAR(seg, info->green_pos, g_pos); ! 144: SET_FARVAR(seg, info->blue_size, b_size); ! 145: SET_FARVAR(seg, info->blue_pos, b_pos); ! 146: SET_FARVAR(seg, info->alpha_size, a_size); ! 147: SET_FARVAR(seg, info->alpha_pos, a_pos); ! 148: ! 149: if (depth == 32) ! 150: SET_FARVAR(seg, info->directcolor_info, ! 151: VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE); ! 152: else ! 153: SET_FARVAR(seg, info->directcolor_info, 0); ! 154: ! 155: if (depth > 4) ! 156: SET_FARVAR(seg, info->phys_base, GET_GLOBAL(VBE_framebuffer)); ! 157: else ! 158: SET_FARVAR(seg, info->phys_base, 0); ! 159: ! 160: SET_FARVAR(seg, info->reserved1, 0); ! 161: SET_FARVAR(seg, info->reserved2, 0); ! 162: SET_FARVAR(seg, info->linear_bytes_per_scanline, linesize); ! 163: SET_FARVAR(seg, info->bank_pages, 0); ! 164: SET_FARVAR(seg, info->linear_pages, 0); ! 165: SET_FARVAR(seg, info->linear_red_size, r_size); ! 166: SET_FARVAR(seg, info->linear_red_pos, r_pos); ! 167: SET_FARVAR(seg, info->linear_green_size, g_size); ! 168: SET_FARVAR(seg, info->linear_green_pos, g_pos); ! 169: SET_FARVAR(seg, info->linear_blue_size, b_size); ! 170: SET_FARVAR(seg, info->linear_blue_pos, b_pos); ! 171: SET_FARVAR(seg, info->linear_alpha_size, a_size); ! 172: SET_FARVAR(seg, info->linear_alpha_pos, a_pos); ! 173: SET_FARVAR(seg, info->pixclock_max, 0); ! 174: ! 175: regs->ax = 0x004f; ! 176: } ! 177: ! 178: static void ! 179: vbe_104f02(struct bregs *regs) ! 180: { ! 181: dprintf(1, "VBE mode set: %x\n", regs->bx); ! 182: ! 183: int mode = regs->bx & ~MF_VBEFLAGS; ! 184: int flags = regs->bx & MF_VBEFLAGS; ! 185: int ret = vga_set_mode(mode, flags); ! 186: ! 187: regs->ah = ret; ! 188: regs->al = 0x4f; ! 189: } ! 190: ! 191: static void ! 192: vbe_104f03(struct bregs *regs) ! 193: { ! 194: regs->bx = GET_BDA(vbe_mode); ! 195: dprintf(1, "VBE current mode=%x\n", regs->bx); ! 196: regs->ax = 0x004f; ! 197: } ! 198: ! 199: static void ! 200: vbe_104f04(struct bregs *regs) ! 201: { ! 202: u16 seg = regs->es; ! 203: void *data = (void*)(regs->bx+0); ! 204: u16 states = regs->cx; ! 205: if (states & ~0x0f) ! 206: goto fail; ! 207: int ret; ! 208: switch (regs->dl) { ! 209: case 0x00: ! 210: ret = vgahw_size_state(states); ! 211: if (ret < 0) ! 212: goto fail; ! 213: regs->bx = ret / 64; ! 214: break; ! 215: case 0x01: ! 216: ret = vgahw_save_state(seg, data, states); ! 217: if (ret) ! 218: goto fail; ! 219: break; ! 220: case 0x02: ! 221: ret = vgahw_restore_state(seg, data, states); ! 222: if (ret) ! 223: goto fail; ! 224: break; ! 225: default: ! 226: goto fail; ! 227: } ! 228: regs->ax = 0x004f; ! 229: return; ! 230: fail: ! 231: regs->ax = 0x014f; ! 232: } ! 233: ! 234: void VISIBLE16 ! 235: vbe_104f05(struct bregs *regs) ! 236: { ! 237: if (regs->bh > 1 || regs->bl > 1) ! 238: goto fail; ! 239: if (GET_BDA(vbe_mode) & MF_LINEARFB) { ! 240: regs->ah = VBE_RETURN_STATUS_INVALID; ! 241: return; ! 242: } ! 243: struct vgamode_s *vmode_g = get_current_mode(); ! 244: if (! vmode_g) ! 245: goto fail; ! 246: if (regs->bh) { ! 247: int ret = vgahw_get_window(vmode_g, regs->bl); ! 248: if (ret < 0) ! 249: goto fail; ! 250: regs->dx = ret; ! 251: regs->ax = 0x004f; ! 252: return; ! 253: } ! 254: int ret = vgahw_set_window(vmode_g, regs->bl, regs->dx); ! 255: if (ret) ! 256: goto fail; ! 257: regs->ax = 0x004f; ! 258: return; ! 259: fail: ! 260: regs->ax = 0x014f; ! 261: } ! 262: ! 263: static void ! 264: vbe_104f06(struct bregs *regs) ! 265: { ! 266: if (regs->bl > 0x02) ! 267: goto fail; ! 268: struct vgamode_s *vmode_g = get_current_mode(); ! 269: if (! vmode_g) ! 270: goto fail; ! 271: int bpp = vga_bpp(vmode_g); ! 272: ! 273: if (regs->bl == 0x00) { ! 274: int ret = vgahw_set_linelength(vmode_g, DIV_ROUND_UP(regs->cx * bpp, 8)); ! 275: if (ret) ! 276: goto fail; ! 277: } else if (regs->bl == 0x02) { ! 278: int ret = vgahw_set_linelength(vmode_g, regs->cx); ! 279: if (ret) ! 280: goto fail; ! 281: } ! 282: int linelength = vgahw_get_linelength(vmode_g); ! 283: if (linelength < 0) ! 284: goto fail; ! 285: ! 286: regs->bx = linelength; ! 287: regs->cx = (linelength * 8) / bpp; ! 288: regs->dx = GET_GLOBAL(VBE_total_memory) / linelength; ! 289: regs->ax = 0x004f; ! 290: return; ! 291: fail: ! 292: regs->ax = 0x014f; ! 293: } ! 294: ! 295: static void ! 296: vbe_104f07(struct bregs *regs) ! 297: { ! 298: struct vgamode_s *vmode_g = get_current_mode(); ! 299: if (! vmode_g) ! 300: goto fail; ! 301: int bpp = vga_bpp(vmode_g); ! 302: int linelength = vgahw_get_linelength(vmode_g); ! 303: if (linelength < 0) ! 304: goto fail; ! 305: ! 306: int ret; ! 307: switch (regs->bl) { ! 308: case 0x80: ! 309: case 0x00: ! 310: ret = vgahw_set_displaystart( ! 311: vmode_g, DIV_ROUND_UP(regs->cx * bpp, 8) + linelength * regs->dx); ! 312: if (ret) ! 313: goto fail; ! 314: break; ! 315: case 0x01: ! 316: ret = vgahw_get_displaystart(vmode_g); ! 317: if (ret < 0) ! 318: goto fail; ! 319: regs->dx = ret / linelength; ! 320: regs->cx = (ret % linelength) * 8 / bpp; ! 321: break; ! 322: default: ! 323: goto fail; ! 324: } ! 325: regs->ax = 0x004f; ! 326: return; ! 327: fail: ! 328: regs->ax = 0x014f; ! 329: } ! 330: ! 331: static void ! 332: vbe_104f08(struct bregs *regs) ! 333: { ! 334: struct vgamode_s *vmode_g = get_current_mode(); ! 335: if (! vmode_g) ! 336: goto fail; ! 337: u8 memmodel = GET_GLOBAL(vmode_g->memmodel); ! 338: if (memmodel == MM_DIRECT || memmodel == MM_YUV) { ! 339: regs->ax = 0x034f; ! 340: return; ! 341: } ! 342: if (regs->bl > 1) ! 343: goto fail; ! 344: if (regs->bl == 0) { ! 345: int ret = vgahw_set_dacformat(vmode_g, regs->bh); ! 346: if (ret < 0) ! 347: goto fail; ! 348: } ! 349: int ret = vgahw_get_dacformat(vmode_g); ! 350: if (ret < 0) ! 351: goto fail; ! 352: regs->bh = ret; ! 353: regs->ax = 0x004f; ! 354: return; ! 355: fail: ! 356: regs->ax = 0x014f; ! 357: } ! 358: ! 359: static void ! 360: vbe_104f0a(struct bregs *regs) ! 361: { ! 362: debug_stub(regs); ! 363: regs->ax = 0x0100; ! 364: } ! 365: ! 366: static void ! 367: vbe_104f10(struct bregs *regs) ! 368: { ! 369: switch (regs->bl) { ! 370: case 0x00: ! 371: regs->bx = 0x0f30; ! 372: break; ! 373: case 0x01: ! 374: SET_BDA(vbe_flag, regs->bh); ! 375: break; ! 376: case 0x02: ! 377: regs->bh = GET_BDA(vbe_flag); ! 378: break; ! 379: default: ! 380: regs->ax = 0x014f; ! 381: return; ! 382: } ! 383: regs->ax = 0x004f; ! 384: } ! 385: ! 386: static void ! 387: vbe_104fXX(struct bregs *regs) ! 388: { ! 389: debug_stub(regs); ! 390: regs->ax = 0x0100; ! 391: } ! 392: ! 393: void noinline ! 394: handle_104f(struct bregs *regs) ! 395: { ! 396: if (!CONFIG_VGA_VBE) { ! 397: vbe_104fXX(regs); ! 398: return; ! 399: } ! 400: ! 401: switch (regs->al) { ! 402: case 0x00: vbe_104f00(regs); break; ! 403: case 0x01: vbe_104f01(regs); break; ! 404: case 0x02: vbe_104f02(regs); break; ! 405: case 0x03: vbe_104f03(regs); break; ! 406: case 0x04: vbe_104f04(regs); break; ! 407: case 0x05: vbe_104f05(regs); break; ! 408: case 0x06: vbe_104f06(regs); break; ! 409: case 0x07: vbe_104f07(regs); break; ! 410: case 0x08: vbe_104f08(regs); break; ! 411: case 0x0a: vbe_104f0a(regs); break; ! 412: case 0x10: vbe_104f10(regs); break; ! 413: default: vbe_104fXX(regs); break; ! 414: } ! 415: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.