|
|
1.1 root 1: // ============================================================================================
2: //
3: // Copyright (C) 2002 Jeroen Janssen
4: //
5: // This library is free software; you can redistribute it and/or
6: // modify it under the terms of the GNU Lesser General Public
7: // License as published by the Free Software Foundation; either
8: // version 2 of the License, or (at your option) any later version.
9: //
10: // This library is distributed in the hope that it will be useful,
11: // but WITHOUT ANY WARRANTY; without even the implied warranty of
12: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13: // Lesser General Public License for more details.
14: //
15: // You should have received a copy of the GNU Lesser General Public
16: // License along with this library; if not, write to the Free Software
17: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18: //
19: // ============================================================================================
20: //
21: // This VBE is part of the VGA Bios specific to the plex86/bochs Emulated VGA card.
22: // You can NOT drive any physical vga card with it.
23: //
24: // ============================================================================================
25: //
26: // This VBE Bios is based on information taken from :
27: // - VESA BIOS EXTENSION (VBE) Core Functions Standard Version 3.0 located at www.vesa.org
28: //
29: // ============================================================================================
30:
31:
32: // defines available
33:
34: // disable VESA/VBE2 check in vbe info
35: //#define VBE2_NO_VESA_CHECK
36:
37:
38: #include "vbe.h"
39: #include "vbetables.h"
40:
41: // The current OEM Software Revision of this VBE Bios
42: #define VBE_OEM_SOFTWARE_REV 0x0002;
43:
44: extern char vbebios_copyright;
45: extern char vbebios_vendor_name;
46: extern char vbebios_product_name;
47: extern char vbebios_product_revision;
48:
49: ASM_START
50: // FIXME: 'merge' these (c) etc strings with the vgabios.c strings?
51: _vbebios_copyright:
52: .ascii "Bochs/Plex86 VBE(C) 2003 http://savannah.nongnu.org/projects/vgabios/"
53: .byte 0x00
54:
55: _vbebios_vendor_name:
56: .ascii "Bochs/Plex86 Developers"
57: .byte 0x00
58:
59: _vbebios_product_name:
60: .ascii "Bochs/Plex86 VBE Adapter"
61: .byte 0x00
62:
63: _vbebios_product_revision:
64: .ascii "$Id$"
65: .byte 0x00
66:
67: _vbebios_info_string:
68: .ascii "Bochs VBE Display Adapter enabled"
69: .byte 0x0a,0x0d
70: .byte 0x0a,0x0d
71: .byte 0x00
72:
73: _no_vbebios_info_string:
74: .ascii "NO Bochs VBE Support available!"
75: .byte 0x0a,0x0d
76: .byte 0x0a,0x0d
77: .byte 0x00
78:
79: #if defined(USE_BX_INFO) || defined(DEBUG)
80: msg_vbe_init:
81: .ascii "VBE Bios $Id$"
82: .byte 0x0a,0x0d, 0x00
83: #endif
84:
85: .align 2
86: vesa_pm_start:
87: dw vesa_pm_set_window - vesa_pm_start
88: dw vesa_pm_set_display_start - vesa_pm_start
89: dw vesa_pm_unimplemented - vesa_pm_start
90: dw vesa_pm_io_ports_table - vesa_pm_start
91: vesa_pm_io_ports_table:
92: dw VBE_DISPI_IOPORT_INDEX
93: dw VBE_DISPI_IOPORT_INDEX + 1
94: dw VBE_DISPI_IOPORT_DATA
95: dw VBE_DISPI_IOPORT_DATA + 1
96: dw 0xffff
97: dw 0xffff
98:
99: USE32
100: vesa_pm_set_window:
101: cmp bx, #0x00
102: je vesa_pm_set_display_window1
103: mov ax, #0x0100
104: ret
105: vesa_pm_set_display_window1:
106: mov ax, dx
107: push dx
108: push ax
109: mov dx, # VBE_DISPI_IOPORT_INDEX
110: mov ax, # VBE_DISPI_INDEX_BANK
111: out dx, ax
112: pop ax
113: mov dx, # VBE_DISPI_IOPORT_DATA
114: out dx, ax
115: in ax, dx
116: pop dx
117: cmp dx, ax
118: jne illegal_window
119: mov ax, #0x004f
120: ret
121: illegal_window:
122: mov ax, #0x014f
123: ret
124:
125: vesa_pm_set_display_start:
126: cmp bl, #0x80
127: je vesa_pm_set_display_start1
128: cmp bl, #0x00
129: je vesa_pm_set_display_start1
130: mov ax, #0x0100
131: ret
132: vesa_pm_set_display_start1:
133: ; convert offset to (X, Y) coordinate
134: ; (would be simpler to change Bochs VBE API...)
135: push eax
136: push ecx
137: push edx
138: push esi
139: push edi
140: shl edx, #16
141: and ecx, #0xffff
142: or ecx, edx
143: shl ecx, #2
144: mov eax, ecx
145:
146: push eax
147: mov dx, # VBE_DISPI_IOPORT_INDEX
148: mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH
149: out dx, ax
150: mov dx, # VBE_DISPI_IOPORT_DATA
151: in ax, dx
152: movzx ecx, ax
153:
154: mov dx, # VBE_DISPI_IOPORT_INDEX
155: mov ax, # VBE_DISPI_INDEX_BPP
156: out dx, ax
157: mov dx, # VBE_DISPI_IOPORT_DATA
158: in ax, dx
159: movzx esi, ax
160: pop eax
161:
162: cmp esi, #4
163: jz bpp4_mode
164: add esi, #7
165: shr esi, #3
166: imul ecx, esi
167: xor edx, edx
168: div ecx
169: mov edi, eax
170: mov eax, edx
171: xor edx, edx
172: div esi
173: jmp set_xy_regs
174:
175: bpp4_mode:
176: shr ecx, #1
177: xor edx, edx
178: div ecx
179: mov edi, eax
180: mov eax, edx
181: shl eax, #1
182:
183: set_xy_regs:
184: push dx
185: push ax
186: mov dx, # VBE_DISPI_IOPORT_INDEX
187: mov ax, # VBE_DISPI_INDEX_X_OFFSET
188: out dx, ax
189: pop ax
190: mov dx, # VBE_DISPI_IOPORT_DATA
191: out dx, ax
192: pop dx
193:
194: mov ax, di
195: push dx
196: push ax
197: mov dx, # VBE_DISPI_IOPORT_INDEX
198: mov ax, # VBE_DISPI_INDEX_Y_OFFSET
199: out dx, ax
200: pop ax
201: mov dx, # VBE_DISPI_IOPORT_DATA
202: out dx, ax
203: pop dx
204:
205: pop edi
206: pop esi
207: pop edx
208: pop ecx
209: pop eax
210: mov ax, #0x004f
211: ret
212:
213: vesa_pm_unimplemented:
214: mov ax, #0x014f
215: ret
216: USE16
217: vesa_pm_end:
218:
219: ; DISPI ioport functions
220:
221: dispi_get_id:
222: push dx
223: mov dx, # VBE_DISPI_IOPORT_INDEX
224: mov ax, # VBE_DISPI_INDEX_ID
225: out dx, ax
226: mov dx, # VBE_DISPI_IOPORT_DATA
227: in ax, dx
228: pop dx
229: ret
230:
231: dispi_set_id:
232: push dx
233: push ax
234: mov dx, # VBE_DISPI_IOPORT_INDEX
235: mov ax, # VBE_DISPI_INDEX_ID
236: out dx, ax
237: pop ax
238: mov dx, # VBE_DISPI_IOPORT_DATA
239: out dx, ax
240: pop dx
241: ret
242: ASM_END
243:
244: static void dispi_set_xres(xres)
245: Bit16u xres;
246: {
247: ASM_START
248: push bp
249: mov bp, sp
250: push ax
251: push dx
252:
253: mov dx, # VBE_DISPI_IOPORT_INDEX
254: mov ax, # VBE_DISPI_INDEX_XRES
255: out dx, ax
256: mov dx, # VBE_DISPI_IOPORT_DATA
257: mov ax, 4[bp] ; xres
258: out dx, ax
259:
260: pop dx
261: pop ax
262: pop bp
263: ASM_END
264: }
265:
266: static void dispi_set_yres(yres)
267: Bit16u yres;
268: {
269: outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_YRES);
270: outw(VBE_DISPI_IOPORT_DATA,yres);
271: }
272:
273: static void dispi_set_bpp(bpp)
274: Bit16u bpp;
275: {
276: outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_BPP);
277: outw(VBE_DISPI_IOPORT_DATA,bpp);
278: }
279:
280: ASM_START
281: ; AL = bits per pixel / AH = bytes per pixel
282: dispi_get_bpp:
283: push dx
284: mov dx, # VBE_DISPI_IOPORT_INDEX
285: mov ax, # VBE_DISPI_INDEX_BPP
286: out dx, ax
287: mov dx, # VBE_DISPI_IOPORT_DATA
288: in ax, dx
289: mov ah, al
290: shr ah, 3
291: test al, #0x07
292: jz get_bpp_noinc
293: inc ah
294: get_bpp_noinc:
295: pop dx
296: ret
297:
298: ; get display capabilities
299:
300: _dispi_get_max_xres:
301: push dx
302: push bx
303: call dispi_get_enable
304: mov bx, ax
305: or ax, # VBE_DISPI_GETCAPS
306: call _dispi_set_enable
307: mov dx, # VBE_DISPI_IOPORT_INDEX
308: mov ax, # VBE_DISPI_INDEX_XRES
309: out dx, ax
310: mov dx, # VBE_DISPI_IOPORT_DATA
311: in ax, dx
312: push ax
313: mov ax, bx
314: call _dispi_set_enable
315: pop ax
316: pop bx
317: pop dx
318: ret
319:
320: _dispi_get_max_bpp:
321: push dx
322: push bx
323: call dispi_get_enable
324: mov bx, ax
325: or ax, # VBE_DISPI_GETCAPS
326: call _dispi_set_enable
327: mov dx, # VBE_DISPI_IOPORT_INDEX
328: mov ax, # VBE_DISPI_INDEX_BPP
329: out dx, ax
330: mov dx, # VBE_DISPI_IOPORT_DATA
331: in ax, dx
332: push ax
333: mov ax, bx
334: call _dispi_set_enable
335: pop ax
336: pop bx
337: pop dx
338: ret
339:
340: _dispi_set_enable:
341: push dx
342: push ax
343: mov dx, # VBE_DISPI_IOPORT_INDEX
344: mov ax, # VBE_DISPI_INDEX_ENABLE
345: out dx, ax
346: pop ax
347: mov dx, # VBE_DISPI_IOPORT_DATA
348: out dx, ax
349: pop dx
350: ret
351:
352: dispi_get_enable:
353: push dx
354: mov dx, # VBE_DISPI_IOPORT_INDEX
355: mov ax, # VBE_DISPI_INDEX_ENABLE
356: out dx, ax
357: mov dx, # VBE_DISPI_IOPORT_DATA
358: in ax, dx
359: pop dx
360: ret
361:
362: _dispi_set_bank:
363: push dx
364: push ax
365: mov dx, # VBE_DISPI_IOPORT_INDEX
366: mov ax, # VBE_DISPI_INDEX_BANK
367: out dx, ax
368: pop ax
369: mov dx, # VBE_DISPI_IOPORT_DATA
370: out dx, ax
371: pop dx
372: ret
373:
374: dispi_get_bank:
375: push dx
376: mov dx, # VBE_DISPI_IOPORT_INDEX
377: mov ax, # VBE_DISPI_INDEX_BANK
378: out dx, ax
379: mov dx, # VBE_DISPI_IOPORT_DATA
380: in ax, dx
381: pop dx
382: ret
383: ASM_END
384:
385: static void dispi_set_bank_farcall()
386: {
387: ASM_START
388: cmp bx,#0x0100
389: je dispi_set_bank_farcall_get
390: or bx,bx
391: jnz dispi_set_bank_farcall_error
392: mov ax,dx
393: push dx
394: push ax
395: mov ax,# VBE_DISPI_INDEX_BANK
396: mov dx,# VBE_DISPI_IOPORT_INDEX
397: out dx,ax
398: pop ax
399: mov dx,# VBE_DISPI_IOPORT_DATA
400: out dx,ax
401: in ax,dx
402: pop dx
403: cmp dx,ax
404: jne dispi_set_bank_farcall_error
405: mov ax, #0x004f
406: retf
407: dispi_set_bank_farcall_get:
408: mov ax,# VBE_DISPI_INDEX_BANK
409: mov dx,# VBE_DISPI_IOPORT_INDEX
410: out dx,ax
411: mov dx,# VBE_DISPI_IOPORT_DATA
412: in ax,dx
413: mov dx,ax
414: retf
415: dispi_set_bank_farcall_error:
416: mov ax,#0x014F
417: retf
418: ASM_END
419: }
420:
421: ASM_START
422: dispi_set_x_offset:
423: push dx
424: push ax
425: mov dx, # VBE_DISPI_IOPORT_INDEX
426: mov ax, # VBE_DISPI_INDEX_X_OFFSET
427: out dx, ax
428: pop ax
429: mov dx, # VBE_DISPI_IOPORT_DATA
430: out dx, ax
431: pop dx
432: ret
433:
434: dispi_get_x_offset:
435: push dx
436: mov dx, # VBE_DISPI_IOPORT_INDEX
437: mov ax, # VBE_DISPI_INDEX_X_OFFSET
438: out dx, ax
439: mov dx, # VBE_DISPI_IOPORT_DATA
440: in ax, dx
441: pop dx
442: ret
443:
444: dispi_set_y_offset:
445: push dx
446: push ax
447: mov dx, # VBE_DISPI_IOPORT_INDEX
448: mov ax, # VBE_DISPI_INDEX_Y_OFFSET
449: out dx, ax
450: pop ax
451: mov dx, # VBE_DISPI_IOPORT_DATA
452: out dx, ax
453: pop dx
454: ret
455:
456: dispi_get_y_offset:
457: push dx
458: mov dx, # VBE_DISPI_IOPORT_INDEX
459: mov ax, # VBE_DISPI_INDEX_Y_OFFSET
460: out dx, ax
461: mov dx, # VBE_DISPI_IOPORT_DATA
462: in ax, dx
463: pop dx
464: ret
465:
466: vga_set_virt_width:
467: push ax
468: push bx
469: push dx
470: mov bx, ax
471: call dispi_get_bpp
472: cmp al, #0x04
473: ja set_width_svga
474: shr bx, #1
475: set_width_svga:
476: shr bx, #3
477: mov dx, # VGAREG_VGA_CRTC_ADDRESS
478: mov ah, bl
479: mov al, #0x13
480: out dx, ax
481: pop dx
482: pop bx
483: pop ax
484: ret
485:
486: dispi_set_virt_width:
487: call vga_set_virt_width
488: push dx
489: push ax
490: mov dx, # VBE_DISPI_IOPORT_INDEX
491: mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH
492: out dx, ax
493: pop ax
494: mov dx, # VBE_DISPI_IOPORT_DATA
495: out dx, ax
496: pop dx
497: ret
498:
499: dispi_get_virt_width:
500: push dx
501: mov dx, # VBE_DISPI_IOPORT_INDEX
502: mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH
503: out dx, ax
504: mov dx, # VBE_DISPI_IOPORT_DATA
505: in ax, dx
506: pop dx
507: ret
508:
509: dispi_get_virt_height:
510: push dx
511: mov dx, # VBE_DISPI_IOPORT_INDEX
512: mov ax, # VBE_DISPI_INDEX_VIRT_HEIGHT
513: out dx, ax
514: mov dx, # VBE_DISPI_IOPORT_DATA
515: in ax, dx
516: pop dx
517: ret
518:
519: _vga_compat_setup:
520: push ax
521: push dx
522:
523: ; set CRT X resolution
524: mov dx, # VBE_DISPI_IOPORT_INDEX
525: mov ax, # VBE_DISPI_INDEX_XRES
526: out dx, ax
527: mov dx, # VBE_DISPI_IOPORT_DATA
528: in ax, dx
529: push ax
530: mov dx, # VGAREG_VGA_CRTC_ADDRESS
531: mov ax, #0x0011
532: out dx, ax
533: pop ax
534: push ax
535: shr ax, #3
536: dec ax
537: mov ah, al
538: mov al, #0x01
539: out dx, ax
540: pop ax
541: call vga_set_virt_width
542:
543: ; set CRT Y resolution
544: mov dx, # VBE_DISPI_IOPORT_INDEX
545: mov ax, # VBE_DISPI_INDEX_YRES
546: out dx, ax
547: mov dx, # VBE_DISPI_IOPORT_DATA
548: in ax, dx
549: dec ax
550: push ax
551: mov dx, # VGAREG_VGA_CRTC_ADDRESS
552: mov ah, al
553: mov al, #0x12
554: out dx, ax
555: pop ax
556: mov al, #0x07
557: out dx, al
558: inc dx
559: in al, dx
560: and al, #0xbd
561: test ah, #0x01
562: jz bit8_clear
563: or al, #0x02
564: bit8_clear:
565: test ah, #0x02
566: jz bit9_clear
567: or al, #0x40
568: bit9_clear:
569: out dx, al
570:
571: ; other settings
572: mov dx, # VGAREG_VGA_CRTC_ADDRESS
573: mov ax, #0x0009
574: out dx, ax
575: mov al, #0x17
576: out dx, al
577: mov dx, # VGAREG_VGA_CRTC_DATA
578: in al, dx
579: or al, #0x03
580: out dx, al
581: mov dx, # VGAREG_ACTL_RESET
582: in al, dx
583: mov dx, # VGAREG_ACTL_ADDRESS
584: mov al, #0x10
585: out dx, al
586: mov dx, # VGAREG_ACTL_READ_DATA
587: in al, dx
588: or al, #0x01
589: mov dx, # VGAREG_ACTL_ADDRESS
590: out dx, al
591: mov al, #0x20
592: out dx, al
593: mov dx, # VGAREG_GRDC_ADDRESS
594: mov ax, #0x0506
595: out dx, ax
596: mov dx, # VGAREG_SEQU_ADDRESS
597: mov ax, #0x0f02
598: out dx, ax
599:
600: ; settings for >= 8bpp
601: mov dx, # VBE_DISPI_IOPORT_INDEX
602: mov ax, # VBE_DISPI_INDEX_BPP
603: out dx, ax
604: mov dx, # VBE_DISPI_IOPORT_DATA
605: in ax, dx
606: cmp al, #0x08
607: jb vga_compat_end
608: mov dx, # VGAREG_VGA_CRTC_ADDRESS
609: mov al, #0x14
610: out dx, al
611: mov dx, # VGAREG_VGA_CRTC_DATA
612: in al, dx
613: or al, #0x40
614: out dx, al
615: mov dx, # VGAREG_ACTL_RESET
616: in al, dx
617: mov dx, # VGAREG_ACTL_ADDRESS
618: mov al, #0x10
619: out dx, al
620: mov dx, # VGAREG_ACTL_READ_DATA
621: in al, dx
622: or al, #0x40
623: mov dx, # VGAREG_ACTL_ADDRESS
624: out dx, al
625: mov al, #0x20
626: out dx, al
627: mov dx, # VGAREG_SEQU_ADDRESS
628: mov al, #0x04
629: out dx, al
630: mov dx, # VGAREG_SEQU_DATA
631: in al, dx
632: or al, #0x08
633: out dx, al
634: mov dx, # VGAREG_GRDC_ADDRESS
635: mov al, #0x05
636: out dx, al
637: mov dx, # VGAREG_GRDC_DATA
638: in al, dx
639: and al, #0x9f
640: or al, #0x40
641: out dx, al
642:
643: vga_compat_end:
644: pop dx
645: pop ax
646: ASM_END
647:
648:
649: // ModeInfo helper function
650: static ModeInfoListItem* mode_info_find_mode(mode, using_lfb)
651: Bit16u mode; Boolean using_lfb;
652: {
653: ModeInfoListItem *cur_info=&mode_info_list;
654:
655: while (cur_info->mode != VBE_VESA_MODE_END_OF_LIST)
656: {
657: if (cur_info->mode == mode)
658: {
659: if (!using_lfb)
660: {
661: return cur_info;
662: }
663: else if (cur_info->info.ModeAttributes & VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE)
664: {
665: return cur_info;
666: }
667: else
668: {
669: cur_info++;
670: }
671: }
672: else
673: {
674: cur_info++;
675: }
676: }
677:
678: return 0;
679: }
680:
681: ASM_START
682:
683: ; Has VBE display - Returns true if VBE display detected
684:
685: _vbe_has_vbe_display:
686: push ds
687: push bx
688: mov ax, # BIOSMEM_SEG
689: mov ds, ax
690: mov bx, # BIOSMEM_VBE_FLAG
691: mov al, [bx]
692: and al, #0x01
693: xor ah, ah
694: pop bx
695: pop ds
696: ret
697:
698: ; VBE Init - Initialise the Vesa Bios Extension Code
699: ; This function does a sanity check on the host side display code interface.
700:
701: vbe_init:
702: mov ax, # VBE_DISPI_ID0
703: call dispi_set_id
704: call dispi_get_id
705: cmp ax, # VBE_DISPI_ID0
706: jne no_vbe_interface
707: push ds
708: push bx
709: mov ax, # BIOSMEM_SEG
710: mov ds, ax
711: mov bx, # BIOSMEM_VBE_FLAG
712: mov al, #0x01
713: mov [bx], al
714: pop bx
715: pop ds
1.1.1.2 ! root 716: mov ax, # VBE_DISPI_ID5
1.1 root 717: call dispi_set_id
718: no_vbe_interface:
719: #if defined(USE_BX_INFO) || defined(DEBUG)
720: mov bx, #msg_vbe_init
721: push bx
722: call _printf
723: inc sp
724: inc sp
725: #endif
726: ret
727:
728: ; VBE Display Info - Display information on screen about the VBE
729:
730: vbe_display_info:
731: call _vbe_has_vbe_display
732: test ax, ax
733: jz no_vbe_flag
734: mov ax, #0xc000
735: mov ds, ax
736: mov si, #_vbebios_info_string
737: jmp _display_string
738: no_vbe_flag:
739: mov ax, #0xc000
740: mov ds, ax
741: mov si, #_no_vbebios_info_string
742: jmp _display_string
1.1.1.2 ! root 743:
! 744: ; helper function for memory size calculation
! 745:
! 746: lmulul:
! 747: and eax, #0x0000FFFF
! 748: shl ebx, #16
! 749: or eax, ebx
! 750: SEG SS
! 751: mul eax, dword ptr [di]
! 752: mov ebx, eax
! 753: shr ebx, #16
! 754: ret
! 755: ASM_END
1.1 root 756:
757: /** Function 00h - Return VBE Controller Information
758: *
759: * Input:
760: * AX = 4F00h
761: * ES:DI = Pointer to buffer in which to place VbeInfoBlock structure
762: * (VbeSignature should be VBE2 when VBE 2.0 information is desired and
763: * the info block is 512 bytes in size)
764: * Output:
765: * AX = VBE Return Status
766: *
767: */
768: void vbe_biosfn_return_controller_information(AX, ES, DI)
769: Bit16u *AX;Bit16u ES;Bit16u DI;
770: {
771: Bit16u ss=get_SS();
772: VbeInfoBlock vbe_info_block;
773: Bit16u status;
774: Bit16u result;
775: Bit16u vbe2_info;
776: Bit16u cur_mode=0;
777: Bit16u cur_ptr=34;
1.1.1.2 ! root 778: Bit16u size_64k;
1.1 root 779: ModeInfoListItem *cur_info=&mode_info_list;
1.1.1.2 ! root 780:
1.1 root 781: status = read_word(ss, AX);
1.1.1.2 ! root 782:
1.1 root 783: #ifdef DEBUG
784: printf("VBE vbe_biosfn_return_vbe_info ES%x DI%x AX%x\n",ES,DI,status);
785: #endif
786:
787: vbe2_info = 0;
788: #ifdef VBE2_NO_VESA_CHECK
789: #else
790: // get vbe_info_block into local variable
791: memcpyb(ss, &vbe_info_block, ES, DI, sizeof(vbe_info_block));
792:
793: // check for VBE2 signature
794: if (((vbe_info_block.VbeSignature[0] == 'V') &&
795: (vbe_info_block.VbeSignature[1] == 'B') &&
796: (vbe_info_block.VbeSignature[2] == 'E') &&
797: (vbe_info_block.VbeSignature[3] == '2')) ||
1.1.1.2 ! root 798:
1.1 root 799: ((vbe_info_block.VbeSignature[0] == 'V') &&
800: (vbe_info_block.VbeSignature[1] == 'E') &&
801: (vbe_info_block.VbeSignature[2] == 'S') &&
802: (vbe_info_block.VbeSignature[3] == 'A')) )
803: {
804: vbe2_info = 1;
805: #ifdef DEBUG
806: printf("VBE correct VESA/VBE2 signature found\n");
807: #endif
808: }
809: #endif
1.1.1.2 ! root 810:
1.1 root 811: // VBE Signature
812: vbe_info_block.VbeSignature[0] = 'V';
813: vbe_info_block.VbeSignature[1] = 'E';
814: vbe_info_block.VbeSignature[2] = 'S';
815: vbe_info_block.VbeSignature[3] = 'A';
1.1.1.2 ! root 816:
1.1 root 817: // VBE Version supported
818: vbe_info_block.VbeVersion = 0x0200;
1.1.1.2 ! root 819:
1.1 root 820: // OEM String
821: vbe_info_block.OemStringPtr_Seg = 0xc000;
822: vbe_info_block.OemStringPtr_Off = &vbebios_copyright;
1.1.1.2 ! root 823:
1.1 root 824: // Capabilities
825: vbe_info_block.Capabilities[0] = VBE_CAPABILITY_8BIT_DAC;
826: vbe_info_block.Capabilities[1] = 0;
827: vbe_info_block.Capabilities[2] = 0;
828: vbe_info_block.Capabilities[3] = 0;
829:
830: // VBE Video Mode Pointer (dynamicly generated from the mode_info_list)
831: vbe_info_block.VideoModePtr_Seg= ES ;
832: vbe_info_block.VideoModePtr_Off= DI + 34;
833:
1.1.1.2 ! root 834: // VBE Total Memory (in 64k blocks)
! 835: outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIDEO_MEMORY_64K);
! 836: vbe_info_block.TotalMemory = inw(VBE_DISPI_IOPORT_DATA);
1.1 root 837:
838: if (vbe2_info)
1.1.1.2 ! root 839: {
1.1 root 840: // OEM Stuff
841: vbe_info_block.OemSoftwareRev = VBE_OEM_SOFTWARE_REV;
842: vbe_info_block.OemVendorNamePtr_Seg = 0xc000;
843: vbe_info_block.OemVendorNamePtr_Off = &vbebios_vendor_name;
844: vbe_info_block.OemProductNamePtr_Seg = 0xc000;
845: vbe_info_block.OemProductNamePtr_Off = &vbebios_product_name;
846: vbe_info_block.OemProductRevPtr_Seg = 0xc000;
847: vbe_info_block.OemProductRevPtr_Off = &vbebios_product_revision;
848:
849: // copy updates in vbe_info_block back
850: memcpyb(ES, DI, ss, &vbe_info_block, sizeof(vbe_info_block));
851: }
1.1.1.2 ! root 852: else
! 853: {
1.1 root 854: // copy updates in vbe_info_block back (VBE 1.x compatibility)
855: memcpyb(ES, DI, ss, &vbe_info_block, 256);
1.1.1.2 ! root 856: }
! 857:
1.1 root 858: do
859: {
1.1.1.2 ! root 860: size_64k = (Bit16u)((Bit32u)cur_info->info.XResolution * cur_info->info.XResolution * cur_info->info.BitsPerPixel) >> 19;
! 861:
1.1 root 862: if ((cur_info->info.XResolution <= dispi_get_max_xres()) &&
1.1.1.2 ! root 863: (cur_info->info.BitsPerPixel <= dispi_get_max_bpp()) &&
! 864: (size_64k <= vbe_info_block.TotalMemory)) {
1.1 root 865: #ifdef DEBUG
866: printf("VBE found mode %x => %x\n", cur_info->mode,cur_mode);
867: #endif
868: write_word(ES, DI + cur_ptr, cur_info->mode);
869: cur_mode++;
870: cur_ptr+=2;
871: } else {
872: #ifdef DEBUG
1.1.1.2 ! root 873: printf("VBE mode %x (xres=%x / bpp=%02x) not supported \n", cur_info->mode,cur_info->info.XResolution,cur_info->info.BitsPerPixel);
1.1 root 874: #endif
875: }
876: cur_info++;
877: } while (cur_info->mode != VBE_VESA_MODE_END_OF_LIST);
1.1.1.2 ! root 878:
1.1 root 879: // Add vesa mode list terminator
880: write_word(ES, DI + cur_ptr, cur_info->mode);
881:
882: result = 0x4f;
883:
884: write_word(ss, AX, result);
885: }
886:
887:
888: /** Function 01h - Return VBE Mode Information
889: *
890: * Input:
891: * AX = 4F01h
892: * CX = Mode Number
893: * ES:DI = Pointer to buffer in which to place ModeInfoBlock structure
894: * Output:
895: * AX = VBE Return Status
896: *
897: */
898: void vbe_biosfn_return_mode_information(AX, CX, ES, DI)
899: Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI;
900: {
901: Bit16u result=0x0100;
902: Bit16u ss=get_SS();
903: ModeInfoBlock info;
904: ModeInfoListItem *cur_info;
905: Boolean using_lfb;
1.1.1.2 ! root 906: Bit16u lfb_addr;
1.1 root 907:
908: #ifdef DEBUG
909: printf("VBE vbe_biosfn_return_mode_information ES%x DI%x CX%x\n",ES,DI,CX);
910: #endif
911:
912: using_lfb=((CX & VBE_MODE_LINEAR_FRAME_BUFFER) == VBE_MODE_LINEAR_FRAME_BUFFER);
1.1.1.2 ! root 913:
1.1 root 914: CX = (CX & 0x1ff);
1.1.1.2 ! root 915:
1.1 root 916: cur_info = mode_info_find_mode(CX, using_lfb, &cur_info);
917:
918: if (cur_info != 0)
919: {
920: #ifdef DEBUG
921: printf("VBE found mode %x\n",CX);
1.1.1.2 ! root 922: #endif
1.1 root 923: memsetb(ss, &info, 0, sizeof(ModeInfoBlock));
924: memcpyb(ss, &info, 0xc000, &(cur_info->info), sizeof(ModeInfoBlockCompact));
925: if (using_lfb) {
926: info.NumberOfBanks = 1;
927: }
1.1.1.2 ! root 928: #ifdef PCI_VID
! 929: lfb_addr = pci_get_lfb_addr(PCI_VID);
! 930: #else
! 931: lfb_addr = 0;
! 932: #endif
! 933: if (lfb_addr > 0) {
! 934: info.PhysBasePtr = ((Bit32u)lfb_addr << 16);
! 935: }
1.1 root 936: if (info.WinAAttributes & VBE_WINDOW_ATTRIBUTE_RELOCATABLE) {
937: info.WinFuncPtr = 0xC0000000UL;
938: *(Bit16u *)&(info.WinFuncPtr) = (Bit16u)(dispi_set_bank_farcall);
939: }
1.1.1.2 ! root 940:
1.1 root 941: result = 0x4f;
942: }
943: else
944: {
945: #ifdef DEBUG
946: printf("VBE *NOT* found mode %x\n",CX);
947: #endif
948: result = 0x100;
949: }
1.1.1.2 ! root 950:
1.1 root 951: if (result == 0x4f)
952: {
953: // copy updates in mode_info_block back
954: memcpyb(ES, DI, ss, &info, sizeof(info));
955: }
956:
957: write_word(ss, AX, result);
958: }
959:
960: /** Function 02h - Set VBE Mode
961: *
962: * Input:
963: * AX = 4F02h
964: * BX = Desired Mode to set
965: * ES:DI = Pointer to CRTCInfoBlock structure
966: * Output:
967: * AX = VBE Return Status
968: *
969: */
970: void vbe_biosfn_set_mode(AX, BX, ES, DI)
971: Bit16u *AX;Bit16u BX; Bit16u ES;Bit16u DI;
972: {
973: Bit16u ss = get_SS();
974: Bit16u result;
975: ModeInfoListItem *cur_info;
976: Boolean using_lfb;
977: Bit8u no_clear;
978: Bit8u lfb_flag;
979:
980: using_lfb=((BX & VBE_MODE_LINEAR_FRAME_BUFFER) == VBE_MODE_LINEAR_FRAME_BUFFER);
981: lfb_flag=using_lfb?VBE_DISPI_LFB_ENABLED:0;
982: no_clear=((BX & VBE_MODE_PRESERVE_DISPLAY_MEMORY) == VBE_MODE_PRESERVE_DISPLAY_MEMORY)?VBE_DISPI_NOCLEARMEM:0;
983:
984: BX = (BX & 0x1ff);
985:
986: //result=read_word(ss,AX);
1.1.1.2 ! root 987:
1.1 root 988: // check for non vesa mode
989: if (BX<VBE_MODE_VESA_DEFINED)
990: {
991: Bit8u mode;
1.1.1.2 ! root 992:
1.1 root 993: dispi_set_enable(VBE_DISPI_DISABLED);
994: // call the vgabios in order to set the video mode
995: // this allows for going back to textmode with a VBE call (some applications expect that to work)
1.1.1.2 ! root 996:
1.1 root 997: mode=(BX & 0xff);
998: biosfn_set_video_mode(mode);
999: result = 0x4f;
1000: }
1.1.1.2 ! root 1001:
1.1 root 1002: cur_info = mode_info_find_mode(BX, using_lfb, &cur_info);
1003:
1004: if (cur_info != 0)
1005: {
1006: #ifdef DEBUG
1007: printf("VBE found mode %x, setting:\n", BX);
1008: printf("\txres%x yres%x bpp%x\n",
1009: cur_info->info.XResolution,
1010: cur_info->info.YResolution,
1011: cur_info->info.BitsPerPixel);
1012: #endif
1.1.1.2 ! root 1013:
1.1 root 1014: // first disable current mode (when switching between vesa modi)
1015: dispi_set_enable(VBE_DISPI_DISABLED);
1016:
1017: if (cur_info->info.BitsPerPixel == 4)
1018: {
1019: biosfn_set_video_mode(0x6a);
1020: }
1021:
1022: dispi_set_bpp(cur_info->info.BitsPerPixel);
1023: dispi_set_xres(cur_info->info.XResolution);
1024: dispi_set_yres(cur_info->info.YResolution);
1025: dispi_set_bank(0);
1026: dispi_set_enable(VBE_DISPI_ENABLED | no_clear | lfb_flag);
1027: vga_compat_setup();
1028:
1029: write_word(BIOSMEM_SEG,BIOSMEM_VBE_MODE,BX);
1030: write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60 | no_clear));
1031:
1.1.1.2 ! root 1032: result = 0x4f;
1.1 root 1033: }
1034: else
1035: {
1036: #ifdef DEBUG
1037: printf("VBE *NOT* found mode %x\n" , BX);
1.1.1.2 ! root 1038: #endif
1.1 root 1039: result = 0x100;
1.1.1.2 ! root 1040:
1.1 root 1041: // FIXME: redirect non VBE modi to normal VGA bios operation
1042: // (switch back to VGA mode
1043: if (BX == 3)
1044: result = 0x4f;
1045: }
1046:
1047: write_word(ss, AX, result);
1048: }
1049:
1050: /** Function 03h - Return Current VBE Mode
1051: *
1052: * Input:
1053: * AX = 4F03h
1054: * Output:
1055: * AX = VBE Return Status
1056: * BX = Current VBE Mode
1057: *
1058: */
1059: ASM_START
1060: vbe_biosfn_return_current_mode:
1061: push ds
1062: mov ax, # BIOSMEM_SEG
1063: mov ds, ax
1064: call dispi_get_enable
1065: and ax, # VBE_DISPI_ENABLED
1066: jz no_vbe_mode
1067: mov bx, # BIOSMEM_VBE_MODE
1068: mov ax, [bx]
1069: mov bx, ax
1070: jnz vbe_03_ok
1071: no_vbe_mode:
1072: mov bx, # BIOSMEM_CURRENT_MODE
1073: mov al, [bx]
1074: mov bl, al
1075: xor bh, bh
1076: vbe_03_ok:
1077: mov ax, #0x004f
1078: pop ds
1079: ret
1080: ASM_END
1081:
1082:
1083: Bit16u vbe_biosfn_read_video_state_size()
1084: {
1085: return 9 * 2;
1086: }
1087:
1088: void vbe_biosfn_save_video_state(ES, BX)
1089: Bit16u ES; Bit16u BX;
1090: {
1091: Bit16u enable, i;
1092:
1093: outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE);
1094: enable = inw(VBE_DISPI_IOPORT_DATA);
1095: write_word(ES, BX, enable);
1096: BX += 2;
1097: if (!(enable & VBE_DISPI_ENABLED))
1098: return;
1099: for(i = VBE_DISPI_INDEX_XRES; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) {
1100: if (i != VBE_DISPI_INDEX_ENABLE) {
1101: outw(VBE_DISPI_IOPORT_INDEX, i);
1102: write_word(ES, BX, inw(VBE_DISPI_IOPORT_DATA));
1103: BX += 2;
1104: }
1105: }
1106: }
1107:
1108:
1109: void vbe_biosfn_restore_video_state(ES, BX)
1110: Bit16u ES; Bit16u BX;
1111: {
1112: Bit16u enable, i;
1113:
1114: enable = read_word(ES, BX);
1115: BX += 2;
1.1.1.2 ! root 1116:
1.1 root 1117: if (!(enable & VBE_DISPI_ENABLED)) {
1118: outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE);
1119: outw(VBE_DISPI_IOPORT_DATA, enable);
1120: } else {
1121: outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES);
1122: outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX));
1123: BX += 2;
1124: outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES);
1125: outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX));
1126: BX += 2;
1127: outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_BPP);
1128: outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX));
1129: BX += 2;
1130: outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE);
1131: outw(VBE_DISPI_IOPORT_DATA, enable);
1132:
1133: for(i = VBE_DISPI_INDEX_BANK; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) {
1134: outw(VBE_DISPI_IOPORT_INDEX, i);
1135: outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX));
1136: BX += 2;
1137: }
1138: }
1139: }
1140:
1141: /** Function 04h - Save/Restore State
1142: *
1143: * Input:
1144: * AX = 4F04h
1145: * DL = 00h Return Save/Restore State buffer size
1146: * 01h Save State
1147: * 02h Restore State
1148: * CX = Requested states
1149: * ES:BX = Pointer to buffer (if DL <> 00h)
1150: * Output:
1151: * AX = VBE Return Status
1152: * BX = Number of 64-byte blocks to hold the state buffer (if DL=00h)
1153: *
1154: */
1155: void vbe_biosfn_save_restore_state(AX, CX, DX, ES, BX)
1156: Bit16u *AX; Bit16u CX; Bit16u DX; Bit16u ES; Bit16u *BX;
1157: {
1158: Bit16u ss=get_SS();
1159: Bit16u result, val;
1160:
1161: result = 0x4f;
1162: switch(GET_DL()) {
1163: case 0x00:
1164: val = biosfn_read_video_state_size2(CX);
1165: #ifdef DEBUG
1166: printf("VGA state size=%x\n", val);
1167: #endif
1168: if (CX & 8)
1169: val += vbe_biosfn_read_video_state_size();
1170: write_word(ss, BX, val);
1171: break;
1172: case 0x01:
1173: val = read_word(ss, BX);
1174: val = biosfn_save_video_state(CX, ES, val);
1175: #ifdef DEBUG
1176: printf("VGA save_state offset=%x\n", val);
1177: #endif
1178: if (CX & 8)
1179: vbe_biosfn_save_video_state(ES, val);
1180: break;
1181: case 0x02:
1182: val = read_word(ss, BX);
1183: val = biosfn_restore_video_state(CX, ES, val);
1184: #ifdef DEBUG
1185: printf("VGA restore_state offset=%x\n", val);
1186: #endif
1187: if (CX & 8)
1188: vbe_biosfn_restore_video_state(ES, val);
1189: break;
1190: default:
1191: // function failed
1192: result = 0x100;
1193: break;
1194: }
1195: write_word(ss, AX, result);
1196: }
1197:
1198: /** Function 05h - Display Window Control
1199: *
1200: * Input:
1201: * AX = 4F05h
1202: * (16-bit) BH = 00h Set memory window
1203: * = 01h Get memory window
1204: * BL = Window number
1205: * = 00h Window A
1206: * = 01h Window B
1207: * DX = Window number in video memory in window
1208: * granularity units (Set Memory Window only)
1209: * Note:
1210: * If this function is called while in a linear frame buffer mode,
1211: * this function must fail with completion code AH=03h
1212: *
1213: * Output:
1214: * AX = VBE Return Status
1215: * DX = Window number in window granularity units
1216: * (Get Memory Window only)
1217: */
1218: ASM_START
1219: vbe_biosfn_display_window_control:
1220: cmp bl, #0x00
1221: jne vbe_05_failed
1222: cmp bh, #0x01
1223: je get_display_window
1224: jb set_display_window
1225: mov ax, #0x0100
1226: ret
1227: set_display_window:
1228: mov ax, dx
1229: call _dispi_set_bank
1230: call dispi_get_bank
1231: cmp ax, dx
1232: jne vbe_05_failed
1233: mov ax, #0x004f
1234: ret
1235: get_display_window:
1236: call dispi_get_bank
1237: mov dx, ax
1238: mov ax, #0x004f
1239: ret
1240: vbe_05_failed:
1241: mov ax, #0x014f
1242: ret
1243: ASM_END
1244:
1245:
1246: /** Function 06h - Set/Get Logical Scan Line Length
1247: *
1248: * Input:
1249: * AX = 4F06h
1250: * BL = 00h Set Scan Line Length in Pixels
1251: * = 01h Get Scan Line Length
1252: * = 02h Set Scan Line Length in Bytes
1253: * = 03h Get Maximum Scan Line Length
1254: * CX = If BL=00h Desired Width in Pixels
1255: * If BL=02h Desired Width in Bytes
1256: * (Ignored for Get Functions)
1257: *
1258: * Output:
1259: * AX = VBE Return Status
1260: * BX = Bytes Per Scan Line
1261: * CX = Actual Pixels Per Scan Line
1262: * (truncated to nearest complete pixel)
1263: * DX = Maximum Number of Scan Lines
1264: */
1265: ASM_START
1266: vbe_biosfn_set_get_logical_scan_line_length:
1267: mov ax, cx
1268: cmp bl, #0x01
1269: je get_logical_scan_line_length
1270: cmp bl, #0x02
1271: je set_logical_scan_line_bytes
1272: jb set_logical_scan_line_pixels
1273: mov ax, #0x0100
1274: ret
1275: set_logical_scan_line_bytes:
1276: push ax
1277: call dispi_get_bpp
1278: xor bh, bh
1279: mov bl, ah
1280: or bl, bl
1281: jnz no_4bpp_1
1282: shl ax, #3
1283: mov bl, #1
1284: no_4bpp_1:
1285: xor dx, dx
1286: pop ax
1287: div bx
1288: set_logical_scan_line_pixels:
1289: call dispi_set_virt_width
1290: get_logical_scan_line_length:
1291: call dispi_get_bpp
1292: xor bh, bh
1293: mov bl, ah
1294: call dispi_get_virt_width
1295: mov cx, ax
1296: or bl, bl
1297: jnz no_4bpp_2
1298: shr ax, #3
1299: mov bl, #1
1300: no_4bpp_2:
1301: mul bx
1302: mov bx, ax
1303: call dispi_get_virt_height
1304: mov dx, ax
1305: mov ax, #0x004f
1306: ret
1307: ASM_END
1308:
1309:
1310: /** Function 07h - Set/Get Display Start
1311: *
1312: * Input(16-bit):
1313: * AX = 4F07h
1314: * BH = 00h Reserved and must be 00h
1315: * BL = 00h Set Display Start
1316: * = 01h Get Display Start
1317: * = 02h Schedule Display Start (Alternate)
1318: * = 03h Schedule Stereoscopic Display Start
1319: * = 04h Get Scheduled Display Start Status
1320: * = 05h Enable Stereoscopic Mode
1321: * = 06h Disable Stereoscopic Mode
1322: * = 80h Set Display Start during Vertical Retrace
1323: * = 82h Set Display Start during Vertical Retrace (Alternate)
1324: * = 83h Set Stereoscopic Display Start during Vertical Retrace
1325: * ECX = If BL=02h/82h Display Start Address in bytes
1326: * If BL=03h/83h Left Image Start Address in bytes
1327: * EDX = If BL=03h/83h Right Image Start Address in bytes
1328: * CX = If BL=00h/80h First Displayed Pixel In Scan Line
1329: * DX = If BL=00h/80h First Displayed Scan Line
1330: *
1331: * Output:
1332: * AX = VBE Return Status
1333: * BH = If BL=01h Reserved and will be 0
1334: * CX = If BL=01h First Displayed Pixel In Scan Line
1335: * If BL=04h 0 if flip has not occurred, not 0 if it has
1336: * DX = If BL=01h First Displayed Scan Line
1337: *
1338: * Input(32-bit):
1339: * BH = 00h Reserved and must be 00h
1340: * BL = 00h Set Display Start
1341: * = 80h Set Display Start during Vertical Retrace
1342: * CX = Bits 0-15 of display start address
1343: * DX = Bits 16-31 of display start address
1344: * ES = Selector for memory mapped registers
1345: */
1346: ASM_START
1347: vbe_biosfn_set_get_display_start:
1348: cmp bl, #0x80
1349: je set_display_start
1350: cmp bl, #0x01
1351: je get_display_start
1352: jb set_display_start
1353: mov ax, #0x0100
1354: ret
1355: set_display_start:
1356: mov ax, cx
1357: call dispi_set_x_offset
1358: mov ax, dx
1359: call dispi_set_y_offset
1360: mov ax, #0x004f
1361: ret
1362: get_display_start:
1363: call dispi_get_x_offset
1364: mov cx, ax
1365: call dispi_get_y_offset
1366: mov dx, ax
1367: xor bh, bh
1368: mov ax, #0x004f
1369: ret
1370: ASM_END
1371:
1372:
1373: /** Function 08h - Set/Get Dac Palette Format
1374: *
1375: * Input:
1376: * AX = 4F08h
1377: * BL = 00h set DAC palette width
1378: * = 01h get DAC palette width
1379: * BH = If BL=00h: desired number of bits per primary color
1380: * Output:
1381: * AX = VBE Return Status
1382: * BH = current number of bits per primary color (06h = standard VGA)
1383: */
1384: ASM_START
1385: vbe_biosfn_set_get_dac_palette_format:
1386: cmp bl, #0x01
1387: je get_dac_palette_format
1388: jb set_dac_palette_format
1389: mov ax, #0x0100
1390: ret
1391: set_dac_palette_format:
1392: call dispi_get_enable
1393: cmp bh, #0x06
1394: je set_normal_dac
1395: cmp bh, #0x08
1396: jne vbe_08_unsupported
1397: or ax, # VBE_DISPI_8BIT_DAC
1398: jnz set_dac_mode
1399: set_normal_dac:
1400: and ax, #~ VBE_DISPI_8BIT_DAC
1401: set_dac_mode:
1402: call _dispi_set_enable
1403: get_dac_palette_format:
1404: mov bh, #0x06
1405: call dispi_get_enable
1406: and ax, # VBE_DISPI_8BIT_DAC
1407: jz vbe_08_ok
1408: mov bh, #0x08
1409: vbe_08_ok:
1410: mov ax, #0x004f
1411: ret
1412: vbe_08_unsupported:
1413: mov ax, #0x014f
1414: ret
1415: ASM_END
1416:
1417:
1418: /** Function 09h - Set/Get Palette Data
1419: *
1420: * Input:
1421: * AX = 4F09h
1422: * Output:
1423: * AX = VBE Return Status
1424: *
1425: * FIXME: incomplete API description, Input & Output
1426: */
1427: void vbe_biosfn_set_get_palette_data(AX)
1428: {
1429: }
1430:
1431: /** Function 0Ah - Return VBE Protected Mode Interface
1432: * Input: AX = 4F0Ah VBE 2.0 Protected Mode Interface
1433: * BL = 00h Return protected mode table
1434: *
1435: *
1436: * Output: AX = Status
1437: * ES = Real Mode Segment of Table
1438: * DI = Offset of Table
1439: * CX = Length of Table including protected mode code
1440: * (for copying purposes)
1441: */
1442: ASM_START
1443: vbe_biosfn_return_protected_mode_interface:
1444: test bl, bl
1445: jnz _fail
1446: mov di, #0xc000
1447: mov es, di
1448: mov di, # vesa_pm_start
1449: mov cx, # vesa_pm_end
1450: sub cx, di
1451: mov ax, #0x004f
1452: ret
1453: _fail:
1454: mov ax, #0x014f
1455: ret
1456: ASM_END
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.