VirtualBox

source: vbox/trunk/src/VBox/Devices/Graphics/BIOS/vberom.asm@ 54153

Last change on this file since 54153 was 53100, checked in by vboxsync, 10 years ago

BIOS: Use safer port access.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.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; Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
33; other than GPL or LGPL is available it will apply instead, Oracle elects to use only
34; the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
35; a choice of LGPL license versions is made available with the language indicating
36; that LGPLv2 or any later version may be used, or where a choice of which version
37; of the LGPL is applied is otherwise unspecified.
38
39include vgadefs.inc
40
41public _vga_compat_setup
42public dispi_set_enable_
43public dispi_set_bank_
44public _dispi_set_bank_farcall
45public _dispi_get_max_bpp
46public _vbe_has_vbe_display
47
48public vbe_biosfn_return_current_mode
49public vbe_biosfn_display_window_control
50public vbe_biosfn_set_get_logical_scan_line_length
51public vbe_biosfn_set_get_display_start
52public vbe_biosfn_set_get_dac_palette_format
53public vbe_biosfn_set_get_palette_data
54public vbe_biosfn_return_protected_mode_interface
55
56VGAROM segment public 'CODE'
57
58.386
59
60VBE_BYTEWISE_IO EQU 1
61
62;; Bytewise in/out
63ifdef VBE_BYTEWISE_IO
64
65public do_out_dx_ax
66public do_in_ax_dx
67
68do_out_dx_ax:
69 xchg ah, al
70 out dx, al
71 xchg ah, al
72 out dx, al
73 ret
74
75do_in_ax_dx:
76 in al, dx
77 xchg ah, al
78 in al, dx
79 ret
80
81 out_dx_ax EQU call do_out_dx_ax
82 in_ax_dx EQU call do_in_ax_dx
83else
84 out_dx_ax EQU out dx, ax
85 in_ax_dx EQU in ax, dx
86endif
87
88;; Vertical retrace waiting
89wait_vsync:
90 push ax
91 push dx
92 mov dx, 03DAh ; @todo use a symbolic constant!
93wv_loop:
94 in al, dx
95 test al, 8
96 jz wv_loop
97 pop dx
98 pop ax
99 ret
100
101wait_not_vsync:
102 push ax
103 push dx
104 mov dx, 03DAh ; @todo use a symbolic constant!
105wnv_loop:
106 in al, dx
107 test al, 8
108 jnz wnv_loop
109 pop dx
110 pop ax
111 ret
112
113
114; AL = bits per pixel / AH = bytes per pixel
115dispi_get_bpp:
116 push dx
117 mov dx, VBE_DISPI_IOPORT_INDEX
118 mov ax, VBE_DISPI_INDEX_BPP
119 out_dx_ax
120 mov dx, VBE_DISPI_IOPORT_DATA
121 in_ax_dx
122 cmp al, 4
123 jbe get_bpp_noinc
124 mov ah, al
125 shr ah, 3
126 test al, 07
127 jz get_bpp_noinc
128 inc ah
129get_bpp_noinc:
130 pop dx
131 ret
132
133; get display capabilities
134
135_dispi_get_max_bpp:
136 push dx
137 push bx
138 call dispi_get_enable
139 mov bx, ax
140 or ax, VBE_DISPI_GETCAPS
141 call dispi_set_enable_
142 mov dx, VBE_DISPI_IOPORT_INDEX
143 mov ax, VBE_DISPI_INDEX_BPP
144 out_dx_ax
145 mov dx, VBE_DISPI_IOPORT_DATA
146 in_ax_dx
147 push ax
148 mov ax, bx
149 call dispi_set_enable_
150 pop ax
151 pop bx
152 pop dx
153 ret
154
155dispi_set_enable_:
156 push dx
157 push ax
158 mov dx, VBE_DISPI_IOPORT_INDEX
159 mov ax, VBE_DISPI_INDEX_ENABLE
160 out_dx_ax
161 pop ax
162 mov dx, VBE_DISPI_IOPORT_DATA
163 out_dx_ax
164 pop dx
165 ret
166
167dispi_get_enable:
168 push dx
169 mov dx, VBE_DISPI_IOPORT_INDEX
170 mov ax, VBE_DISPI_INDEX_ENABLE
171 out_dx_ax
172 mov dx, VBE_DISPI_IOPORT_DATA
173 in_ax_dx
174 pop dx
175 ret
176
177dispi_set_bank_:
178 push dx
179 push ax
180 mov dx, VBE_DISPI_IOPORT_INDEX
181 mov ax, VBE_DISPI_INDEX_BANK
182 out_dx_ax
183 pop ax
184 mov dx, VBE_DISPI_IOPORT_DATA
185 out_dx_ax
186 pop dx
187 ret
188
189dispi_get_bank:
190 push dx
191 mov dx, VBE_DISPI_IOPORT_INDEX
192 mov ax, VBE_DISPI_INDEX_BANK
193 out_dx_ax
194 mov dx, VBE_DISPI_IOPORT_DATA
195 in_ax_dx
196 pop dx
197 ret
198
199_dispi_set_bank_farcall:
200 cmp bx, 0100h
201 je dispi_set_bank_farcall_get
202 or bx,bx
203 jnz dispi_set_bank_farcall_error
204 mov ax, dx
205 push dx
206 push ax
207 mov ax, VBE_DISPI_INDEX_BANK
208 mov dx, VBE_DISPI_IOPORT_INDEX
209 out_dx_ax
210 pop ax
211 mov dx, VBE_DISPI_IOPORT_DATA
212 out_dx_ax
213 in_ax_dx
214 pop dx
215 cmp dx,ax
216 jne dispi_set_bank_farcall_error
217 mov ax, 004Fh
218 retf
219dispi_set_bank_farcall_get:
220 mov ax, VBE_DISPI_INDEX_BANK
221 mov dx, VBE_DISPI_IOPORT_INDEX
222 out_dx_ax
223 mov dx, VBE_DISPI_IOPORT_DATA
224 in_ax_dx
225 mov dx,ax
226 retf
227dispi_set_bank_farcall_error:
228 mov ax, 014Fh
229 retf
230
231dispi_set_x_offset:
232 push dx
233 push ax
234 mov dx, VBE_DISPI_IOPORT_INDEX
235 mov ax, VBE_DISPI_INDEX_X_OFFSET
236 out_dx_ax
237 pop ax
238 mov dx, VBE_DISPI_IOPORT_DATA
239 out_dx_ax
240 pop dx
241 ret
242
243dispi_get_x_offset:
244 push dx
245 mov dx, VBE_DISPI_IOPORT_INDEX
246 mov ax, VBE_DISPI_INDEX_X_OFFSET
247 out_dx_ax
248 mov dx, VBE_DISPI_IOPORT_DATA
249 in_ax_dx
250 pop dx
251 ret
252
253dispi_set_y_offset:
254 push dx
255 push ax
256 mov dx, VBE_DISPI_IOPORT_INDEX
257 mov ax, VBE_DISPI_INDEX_Y_OFFSET
258 out_dx_ax
259 pop ax
260 mov dx, VBE_DISPI_IOPORT_DATA
261 out_dx_ax
262 pop dx
263 ret
264
265dispi_get_y_offset:
266 push dx
267 mov dx, VBE_DISPI_IOPORT_INDEX
268 mov ax, VBE_DISPI_INDEX_Y_OFFSET
269 out_dx_ax
270 mov dx, VBE_DISPI_IOPORT_DATA
271 in_ax_dx
272 pop dx
273 ret
274
275vga_set_virt_width:
276 push ax
277 push bx
278 push dx
279 mov bx, ax
280 call dispi_get_bpp
281 cmp al, 4
282 ja set_width_svga
283 shr bx, 1
284set_width_svga:
285 shr bx, 3
286 mov dx, VGAREG_VGA_CRTC_ADDRESS
287 mov ah, bl
288 mov al, 13h
289 out dx, ax
290 pop dx
291 pop bx
292 pop ax
293 ret
294
295dispi_set_virt_width:
296 call vga_set_virt_width
297 push dx
298 push ax
299 mov dx, VBE_DISPI_IOPORT_INDEX
300 mov ax, VBE_DISPI_INDEX_VIRT_WIDTH
301 out_dx_ax
302 pop ax
303 mov dx, VBE_DISPI_IOPORT_DATA
304 out_dx_ax
305 pop dx
306 ret
307
308dispi_get_virt_width:
309 push dx
310 mov dx, VBE_DISPI_IOPORT_INDEX
311 mov ax, VBE_DISPI_INDEX_VIRT_WIDTH
312 out_dx_ax
313 mov dx, VBE_DISPI_IOPORT_DATA
314 in_ax_dx
315 pop dx
316 ret
317
318dispi_get_virt_height:
319 push dx
320 mov dx, VBE_DISPI_IOPORT_INDEX
321 mov ax, VBE_DISPI_INDEX_VIRT_HEIGHT
322 out_dx_ax
323 mov dx, VBE_DISPI_IOPORT_DATA
324 in_ax_dx
325 pop dx
326 ret
327
328_vga_compat_setup:
329 push ax
330 push dx
331
332 ; set CRT X resolution
333 mov dx, VBE_DISPI_IOPORT_INDEX
334 mov ax, VBE_DISPI_INDEX_XRES
335 out_dx_ax
336 mov dx, VBE_DISPI_IOPORT_DATA
337 in_ax_dx
338 push ax
339 mov dx, VGAREG_VGA_CRTC_ADDRESS
340 mov ax, 0011h
341 out dx, ax
342 pop ax
343 push ax
344 shr ax, 3
345 dec ax
346 mov ah, al
347 mov al, 01
348 out dx, ax
349 pop ax
350 call vga_set_virt_width
351
352 ; set CRT Y resolution
353 mov dx, VBE_DISPI_IOPORT_INDEX
354 mov ax, VBE_DISPI_INDEX_YRES
355 out_dx_ax
356 mov dx, VBE_DISPI_IOPORT_DATA
357 in_ax_dx
358 dec ax
359 push ax
360 mov dx, VGAREG_VGA_CRTC_ADDRESS
361 mov ah, al
362 mov al, 12h
363 out dx, ax
364 pop ax
365 mov al, 07
366 out dx, al
367 inc dx
368 in al, dx
369 and al, 0BDh
370 test ah, 01
371 jz bit8_clear
372 or al, 02
373bit8_clear:
374 test ah, 02
375 jz bit9_clear
376 or al, 40h
377bit9_clear:
378 out dx, al
379
380 ; other settings
381 mov dx, VGAREG_VGA_CRTC_ADDRESS
382 mov ax, 0009
383 out dx, al
384 mov dx, VGAREG_VGA_CRTC_DATA
385 in al, dx
386 and al, 60h ; clear double scan bit and cell height
387 out dx, al
388 mov dx, VGAREG_VGA_CRTC_ADDRESS
389 mov al, 17h
390 out dx, al
391 mov dx, VGAREG_VGA_CRTC_DATA
392 in al, dx
393 or al, 03
394 out dx, al
395 mov dx, VGAREG_ACTL_RESET
396 in al, dx
397 mov dx, VGAREG_ACTL_ADDRESS
398 mov al, 10h
399 out dx, al
400 mov dx, VGAREG_ACTL_READ_DATA
401 in al, dx
402 or al, 01
403 mov dx, VGAREG_ACTL_ADDRESS
404 out dx, al
405 mov al, 20h
406 out dx, al
407 mov dx, VGAREG_GRDC_ADDRESS
408 mov ax, 0506h
409 out dx, ax
410 mov dx, VGAREG_SEQU_ADDRESS
411 mov ax, 0F02h
412 out dx, ax
413
414 ; settings for >= 8bpp
415 mov dx, VBE_DISPI_IOPORT_INDEX
416 mov ax, VBE_DISPI_INDEX_BPP
417 out_dx_ax
418 mov dx, VBE_DISPI_IOPORT_DATA
419 in_ax_dx
420 cmp al, 08
421 jb vga_compat_end
422 mov dx, VGAREG_VGA_CRTC_ADDRESS
423 mov al, 14h
424 out dx, al
425 mov dx, VGAREG_VGA_CRTC_DATA
426 in al, dx
427 or al, 40h
428 out dx, al
429 mov dx, VGAREG_ACTL_RESET
430 in al, dx
431 mov dx, VGAREG_ACTL_ADDRESS
432 mov al, 10h
433 out dx, al
434 mov dx, VGAREG_ACTL_READ_DATA
435 in al, dx
436 or al, 40h
437 mov dx, VGAREG_ACTL_ADDRESS
438 out dx, al
439 mov al, 20h
440 out dx, al
441 mov dx, VGAREG_SEQU_ADDRESS
442 mov al, 04
443 out dx, al
444 mov dx, VGAREG_SEQU_DATA
445 in al, dx
446 or al, 08
447 out dx, al
448 mov dx, VGAREG_GRDC_ADDRESS
449 mov al, 05
450 out dx, al
451 mov dx, VGAREG_GRDC_DATA
452 in al, dx
453 and al, 9Fh
454 or al, 40h
455 out dx, al
456
457vga_compat_end:
458 pop dx
459 pop ax
460
461
462; Has VBE display - Returns true if VBE display detected
463
464_vbe_has_vbe_display:
465 push ds
466 push bx
467 mov ax, BIOSMEM_SEG
468 mov ds, ax
469 mov bx, BIOSMEM_VBE_FLAG
470 mov al, [bx]
471 and al, 01
472 xor ah, ah
473 pop bx
474 pop ds
475 ret
476
477
478; Function 03h - Return Current VBE Mode
479;
480; Input:
481; AX = 4F03h
482; Output:
483; AX = VBE Return Status
484; BX = Current VBE Mode
485;
486;
487vbe_biosfn_return_current_mode:
488 push ds
489 mov ax, BIOSMEM_SEG
490 mov ds, ax
491 call dispi_get_enable
492 and ax, VBE_DISPI_ENABLED
493 jz no_vbe_mode
494 mov bx, BIOSMEM_VBE_MODE
495 mov ax, [bx]
496 mov bx, ax
497 jnz vbe_03_ok
498no_vbe_mode:
499 mov bx, BIOSMEM_CURRENT_MODE
500 mov al, [bx]
501 mov bl, al
502 xor bh, bh
503vbe_03_ok:
504 mov ax, 004Fh
505 pop ds
506 ret
507
508
509; Function 05h - Display Window Control
510;
511; Input:
512; AX = 4F05h
513; (16-bit) BH = 00h Set memory window
514; = 01h Get memory window
515; BL = Window number
516; = 00h Window A
517; = 01h Window B
518; DX = Window number in video memory in window
519; granularity units (Set Memory Window only)
520; Note:
521; If this function is called while in a linear frame buffer mode,
522; this function must fail with completion code AH=03h
523;
524; Output:
525; AX = VBE Return Status
526; DX = Window number in window granularity units
527; (Get Memory Window only)
528
529vbe_biosfn_display_window_control:
530 cmp bl, 0
531 jne vbe_05_failed
532 cmp bh, 1
533 je get_display_window
534 jb set_display_window
535 mov ax, 0100h
536 ret
537set_display_window:
538 mov ax, dx
539 call dispi_set_bank_
540 call dispi_get_bank
541 cmp ax, dx
542 jne vbe_05_failed
543 mov ax, 004Fh
544 ret
545get_display_window:
546 call dispi_get_bank
547 mov dx, ax
548 mov ax, 004Fh
549 ret
550vbe_05_failed:
551 mov ax, 014Fh
552 ret
553
554
555; Function 06h - Set/Get Logical Scan Line Length
556;
557; Input:
558; AX = 4F06h
559; BL = 00h Set Scan Line Length in Pixels
560; = 01h Get Scan Line Length
561; = 02h Set Scan Line Length in Bytes
562; = 03h Get Maximum Scan Line Length
563; CX = If BL=00h Desired Width in Pixels
564; If BL=02h Desired Width in Bytes
565; (Ignored for Get Functions)
566;
567; Output:
568; AX = VBE Return Status
569; BX = Bytes Per Scan Line
570; CX = Actual Pixels Per Scan Line
571; (truncated to nearest complete pixel)
572; DX = Maximum Number of Scan Lines
573;
574vbe_biosfn_set_get_logical_scan_line_length:
575 mov ax, cx
576 cmp bl, 1
577 je get_logical_scan_line_length
578 cmp bl, 2
579 je set_logical_scan_line_bytes
580 jb set_logical_scan_line_pixels
581 mov ax, 0100h
582 ret
583set_logical_scan_line_bytes:
584 push ax
585 call dispi_get_bpp
586 xor bh, bh
587 mov bl, ah
588 or bl, bl
589 jnz no_4bpp_1
590 shl ax, 3
591 mov bl, 1
592no_4bpp_1:
593 xor dx, dx
594 pop ax
595 div bx
596set_logical_scan_line_pixels:
597 call dispi_set_virt_width
598get_logical_scan_line_length:
599 call dispi_get_bpp
600 xor bh, bh
601 mov bl, ah
602 call dispi_get_virt_width
603 mov cx, ax
604 or bl, bl
605 jnz no_4bpp_2
606 shr ax, 3
607 mov bl, 1
608no_4bpp_2:
609 mul bx
610 mov bx, ax
611 call dispi_get_virt_height
612 mov dx, ax
613 mov ax, 004Fh
614 ret
615
616
617; Function 07h - Set/Get Display Start
618;
619; Input(16-bit):
620; AX = 4F07h
621; BH = 00h Reserved and must be 00h
622; BL = 00h Set Display Start
623; = 01h Get Display Start
624; = 02h Schedule Display Start (Alternate)
625; = 03h Schedule Stereoscopic Display Start
626; = 04h Get Scheduled Display Start Status
627; = 05h Enable Stereoscopic Mode
628; = 06h Disable Stereoscopic Mode
629; = 80h Set Display Start during Vertical Retrace
630; = 82h Set Display Start during Vertical Retrace (Alternate)
631; = 83h Set Stereoscopic Display Start during Vertical Retrace
632; ECX = If BL=02h/82h Display Start Address in bytes
633; If BL=03h/83h Left Image Start Address in bytes
634; EDX = If BL=03h/83h Right Image Start Address in bytes
635; CX = If BL=00h/80h First Displayed Pixel In Scan Line
636; DX = If BL=00h/80h First Displayed Scan Line
637;
638; Output:
639; AX = VBE Return Status
640; BH = If BL=01h Reserved and will be 0
641; CX = If BL=01h First Displayed Pixel In Scan Line
642; If BL=04h 0 if flip has not occurred, not 0 if it has
643; DX = If BL=01h First Displayed Scan Line
644;
645; Input(32-bit):
646; BH = 00h Reserved and must be 00h
647; BL = 00h Set Display Start
648; = 80h Set Display Start during Vertical Retrace
649; CX = Bits 0-15 of display start address
650; DX = Bits 16-31 of display start address
651; ES = Selector for memory mapped registers
652;
653vbe_biosfn_set_get_display_start:
654 cmp bl, 80h
655 je set_display_start_wait
656 cmp bl, 1
657 je get_display_start
658 jb set_display_start
659 mov ax, 0100h
660 ret
661set_display_start_wait:
662 call wait_not_vsync
663 call wait_vsync
664set_display_start:
665 mov ax, cx
666 call dispi_set_x_offset
667 mov ax, dx
668 call dispi_set_y_offset
669 mov ax, 004Fh
670 ret
671get_display_start:
672 call dispi_get_x_offset
673 mov cx, ax
674 call dispi_get_y_offset
675 mov dx, ax
676 xor bh, bh
677 mov ax, 004Fh
678 ret
679
680
681; Function 08h - Set/Get Dac Palette Format
682;
683; Input:
684; AX = 4F08h
685; BL = 00h set DAC palette width
686; = 01h get DAC palette width
687; BH = If BL=00h: desired number of bits per primary color
688; Output:
689; AX = VBE Return Status
690; BH = current number of bits per primary color (06h = standard VGA)
691;
692vbe_biosfn_set_get_dac_palette_format:
693 cmp bl, 1
694 je get_dac_palette_format
695 jb set_dac_palette_format
696 mov ax, 0100h
697 ret
698set_dac_palette_format:
699 call dispi_get_enable
700 cmp bh, 6
701 je set_normal_dac
702 cmp bh, 8
703 jne vbe_08_unsupported
704 or ax, VBE_DISPI_8BIT_DAC
705 jnz set_dac_mode
706set_normal_dac:
707 and ax, NOT VBE_DISPI_8BIT_DAC
708set_dac_mode:
709 call dispi_set_enable_
710get_dac_palette_format:
711 mov bh, 6
712 call dispi_get_enable
713 and ax, VBE_DISPI_8BIT_DAC
714 jz vbe_08_ok
715 mov bh, 8
716vbe_08_ok:
717 mov ax, 004Fh
718 ret
719vbe_08_unsupported:
720 mov ax, 014Fh
721 ret
722
723
724; Function 09h - Set/Get Palette Data
725;
726; Input:
727; AX = 4F09h
728; (16-bit) BL = 00h Set palette data
729; = 01h Get palette data
730; = 02h Set secondary palette data
731; = 03h Get secondary palette data
732; = 80h Set palette data during VRetrace
733; CX = Number of entries to update (<= 256)
734; DX = First entry to update
735; ES:DI = Table of palette values
736; Output:
737; AX = VBE Return Status
738;
739; Notes:
740; Secondary palette support is a "future extension".
741; Attempts to set/get it should return status 02h.
742;
743; In VBE 3.0, reading palette data is optional and
744; subfunctions 01h and 03h may return failure.
745;
746; The format of palette entries is as follows:
747;
748; PaletteEntry struc
749; Blue db ? ; Blue channel value (6 or 8 bits)
750; Green db ? ; Green channel value (6 or 8 bits)
751; Red db ? ; Red channel value (6 or 8 bits)
752; Padding db ? ; DWORD alignment byte (unused)
753; PaletteEntry ends
754;
755; Most applications use VGA DAC registers directly to
756; set/get palette in VBE modes. However, subfn 4F09h is
757; required for NonVGA controllers (eg. XGA).
758;
759vbe_biosfn_set_get_palette_data:
760 test bl, bl
761 jz set_palette_data
762 cmp bl, 01
763 je get_palette_data
764 cmp bl, 03
765 jbe vbe_09_nohw
766 cmp bl, 80h
767 jne vbe_09_unsupported
768if 0
769 ; this is where we could wait for vertical retrace
770endif
771set_palette_data:
772 pushad
773 push ds
774 push es
775 pop ds
776 mov al, dl
777 mov dx, VGAREG_DAC_WRITE_ADDRESS
778 out dx, al
779 inc dx
780 mov si, di
781set_pal_loop:
782 lodsd
783 ror eax, 16
784 out dx, al
785 rol eax, 8
786 out dx, al
787 rol eax, 8
788 out dx, al
789 loop set_pal_loop
790 pop ds
791 popad
792vbe_09_ok:
793 mov ax, 004Fh
794 ret
795
796get_palette_data:
797 pushad
798 mov al, dl
799 mov dx, VGAREG_DAC_READ_ADDRESS
800 out dx, al
801 add dl, 2
802get_pal_loop:
803 xor eax, eax
804 in al, dx
805 shl eax, 8
806 in al, dx
807 shl eax, 8
808 in al, dx
809 stosd
810 loop get_pal_loop
811 popad
812 jmp vbe_09_ok
813
814vbe_09_unsupported:
815 mov ax, 014Fh
816 ret
817vbe_09_nohw:
818 mov ax, 024Fh
819 ret
820
821
822; Function 0Ah - Return VBE Protected Mode Interface
823;
824; Input: AX = 4F0Ah VBE 2.0 Protected Mode Interface
825; BL = 00h Return protected mode table
826; Output: AX = Status
827; ES = Real Mode Segment of Table
828; DI = Offset of Table
829; CX = Length of Table including protected mode code
830; (for copying purposes)
831;
832vbe_biosfn_return_protected_mode_interface:
833 test bl, bl
834 jnz _fail
835 mov di, 0C000h
836 mov es, di
837 mov di, offset vesa_pm_start
838 mov cx, vesa_pm_end - vesa_pm_start
839 sub cx, di
840 mov ax, 004Fh
841 ret
842_fail:
843 mov ax, 014fh
844 ret
845
846VGAROM ends
847
848;;
849;; 32-bit VBE interface
850;;
851
852.386
853
854public vesa_pm_start
855public vesa_pm_end
856
857VBE32 segment public use32 'CODE'
858
859 align 2
860
861vesa_pm_start:
862 dw vesa_pm_set_window - vesa_pm_start
863 dw vesa_pm_set_display_start - vesa_pm_start
864 dw vesa_pm_unimplemented - vesa_pm_start
865 dw vesa_pm_io_ports_table - vesa_pm_start
866vesa_pm_io_ports_table:
867 dw VBE_DISPI_IOPORT_INDEX
868 dw VBE_DISPI_IOPORT_INDEX + 1
869 dw VBE_DISPI_IOPORT_DATA
870 dw VBE_DISPI_IOPORT_DATA + 1
871 dw 3B6h
872 dw 3B7h
873 dw 0FFFFh
874 dw 0FFFFh
875
876vesa_pm_set_window:
877 cmp bx, 0
878 je vesa_pm_set_display_window1
879 mov ax, 0100h
880 ret
881vesa_pm_set_display_window1:
882 mov ax, dx
883 push dx
884 push ax
885 mov dx, VBE_DISPI_IOPORT_INDEX
886 mov ax, VBE_DISPI_INDEX_BANK
887 out dx, ax
888 pop ax
889 mov dx, VBE_DISPI_IOPORT_DATA
890 out dx, ax
891 in ax, dx
892 pop dx
893 cmp dx, ax
894 jne illegal_window
895 mov ax, 004Fh
896 ret
897illegal_window:
898 mov ax, 014Fh
899 ret
900vesa_pm_set_display_start:
901 cmp bl, 80h
902 je vesa_pm_set_display_start1_wait
903 cmp bl, 00
904 je vesa_pm_set_display_start1
905 mov ax, 0100h
906 ret
907vesa_pm_set_display_start1_wait:
908 push edx
909 mov dx, 03DAh ; @todo: use symbolic constant
910wnv_loop_32:
911 in al, dx
912 test al, 8
913 jnz wnv_loop_32
914wv_loop_32:
915 in al, dx
916 test al, 8
917 jz wv_loop_32
918 pop edx
919vesa_pm_set_display_start1:
920; convert offset to (X, Y) coordinate
921; (would be simpler to change Bochs VBE API...)
922 push eax
923 push ecx
924 push edx
925 push esi
926 push edi
927 shl edx, 16
928 and ecx, 0FFFFh
929 or ecx, edx
930 shl ecx, 2
931 mov eax, ecx
932 push eax
933 mov dx, VBE_DISPI_IOPORT_INDEX
934 mov ax, VBE_DISPI_INDEX_VIRT_WIDTH
935 out dx, ax
936 mov dx, VBE_DISPI_IOPORT_DATA
937 in ax, dx
938 movzx ecx, ax
939 mov dx, VBE_DISPI_IOPORT_INDEX
940 mov ax, VBE_DISPI_INDEX_BPP
941 out dx, ax
942 mov dx, VBE_DISPI_IOPORT_DATA
943 in ax, dx
944 movzx esi, ax
945 pop eax
946
947 cmp esi, 4
948 jz bpp4_mode
949 add esi, 7
950 shr esi, 3
951 imul ecx, esi
952 xor edx, edx
953 div ecx
954 mov edi, eax
955 mov eax, edx
956 xor edx, edx
957 div esi
958 jmp set_xy_regs
959
960bpp4_mode:
961 shr ecx, 1
962 xor edx, edx
963 div ecx
964 mov edi, eax
965 mov eax, edx
966 shl eax, 1
967
968set_xy_regs:
969 push dx
970 push ax
971 mov dx, VBE_DISPI_IOPORT_INDEX
972 mov ax, VBE_DISPI_INDEX_X_OFFSET
973 out dx, ax
974 pop ax
975 mov dx, VBE_DISPI_IOPORT_DATA
976 out dx, ax
977 pop dx
978
979 mov ax, di
980 push dx
981 push ax
982 mov dx, VBE_DISPI_IOPORT_INDEX
983 mov ax, VBE_DISPI_INDEX_Y_OFFSET
984 out dx, ax
985 pop ax
986 mov dx, VBE_DISPI_IOPORT_DATA
987 out dx, ax
988 pop dx
989
990 pop edi
991 pop esi
992 pop edx
993 pop ecx
994 pop eax
995 mov ax, 004fh
996 ret
997
998vesa_pm_unimplemented:
999 mov ax, 014Fh
1000 ret
1001vesa_pm_end:
1002
1003VBE32 ends
1004
1005 end
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