VirtualBox

source: vbox/trunk/src/VBox/Devices/Graphics/BIOS/vbe.c@ 2980

Last change on this file since 2980 was 2980, checked in by vboxsync, 18 years ago

InnoTek -> innotek: actual code changes (headers follow).

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette