|
|
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.