VirtualBox

source: vbox/trunk/src/VBox/Devices/Graphics/BIOS-new/vberom.asm@ 43115

Last change on this file since 43115 was 43115, checked in by vboxsync, 13 years ago

export to OSE

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

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