summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/Graphics/BIOS/vgarom.asm
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/Graphics/BIOS/vgarom.asm')
-rw-r--r--src/VBox/Devices/Graphics/BIOS/vgarom.asm1102
1 files changed, 1102 insertions, 0 deletions
diff --git a/src/VBox/Devices/Graphics/BIOS/vgarom.asm b/src/VBox/Devices/Graphics/BIOS/vgarom.asm
new file mode 100644
index 00000000..f5bffcc4
--- /dev/null
+++ b/src/VBox/Devices/Graphics/BIOS/vgarom.asm
@@ -0,0 +1,1102 @@
+;; ============================================================================================
+;;
+;; Copyright (C) 2001,2002 the LGPL VGABios developers Team
+;;
+;; This library is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU Lesser General Public
+;; License as published by the Free Software Foundation; either
+;; version 2 of the License, or (at your option) any later version.
+;;
+;; This library is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; Lesser General Public License for more details.
+;;
+;; You should have received a copy of the GNU Lesser General Public
+;; License along with this library; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+;;
+;; ============================================================================================
+;;
+;; This VGA Bios is specific to the plex86/bochs Emulated VGA card.
+;; You can NOT drive any physical vga card with it.
+;;
+;; ============================================================================================
+;;
+
+
+; Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+; other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+; the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+; a choice of LGPL license versions is made available with the language indicating
+; that LGPLv2 or any later version may be used, or where a choice of which version
+; of the LGPL is applied is otherwise unspecified.
+
+include vgadefs.inc
+include commondefs.inc
+
+public vgabios_int10_handler
+
+VGAROM segment public 'CODE'
+
+; Implemented in C
+extrn _int10_func:near
+extrn _vgabios_init_func:near
+
+ifdef VBE
+; Implemented in separate assembly module
+extrn vbe_biosfn_return_current_mode:near
+extrn vbe_biosfn_display_window_control:near
+extrn vbe_biosfn_set_get_display_start:near
+extrn vbe_biosfn_set_get_dac_palette_format:near
+extrn vbe_biosfn_set_get_palette_data:near
+extrn vbe_biosfn_return_protected_mode_interface:near
+endif
+
+ifdef VGA_DEBUG
+extrn _int10_debugmsg:near
+extrn _printf:near
+extrn _unimplemented:near
+extrn _unknown:near
+endif
+
+vgabios_start:
+
+db 055h, 0AAh ; ROM signature, required for expansion ROMs
+db 40h ; ROM module length in units of 512 bytes */
+
+
+vgabios_entry_point:
+
+ jmp vgabios_init
+
+ org 1Eh
+
+ db 'IBM',0
+
+vgabios_init:
+;; We have to set ds to access the right data segment
+ push cs
+ pop ds
+ cld
+ jmp _vgabios_init_func
+
+;;
+;; int10 handled here
+;;
+
+SET_DEFAULT_CPU_286
+
+vgabios_int10_handler:
+ pushf
+ifdef VGA_DEBUG
+ push es
+ push ds
+ DO_pusha
+ push cs
+ pop ds
+ cld
+ call _int10_debugmsg
+ DO_popa
+ pop ds
+ pop es
+endif
+ cmp ah, 0Fh
+ jne int10_test_1A
+ call biosfn_get_video_mode
+ jmp int10_end
+int10_test_1A:
+ cmp ah, 1Ah
+ jne int10_test_0B
+ call biosfn_group_1A
+ jmp int10_end
+int10_test_0B:
+ cmp ah, 0Bh
+ jne int10_test_1103
+ call biosfn_group_0B
+ jmp int10_end
+int10_test_1103:
+ cmp ax, 1103h
+ jne int10_test_12
+ call biosfn_set_text_block_specifier
+ jmp int10_end
+int10_test_12:
+ cmp ah, 12h
+ jne int10_test_101B
+ cmp bl, 10h
+ jne int10_test_BL30
+ call biosfn_get_ega_info
+ jmp int10_end
+int10_test_BL30:
+ cmp bl, 30h
+ jne int10_test_BL31
+ call biosfn_select_vert_res
+ jmp int10_end
+int10_test_BL31:
+ cmp bl, 31h
+ jne int10_test_BL32
+ call biosfn_enable_default_palette_loading
+ jmp int10_end
+int10_test_BL32:
+ cmp bl, 32h
+ jne int10_test_BL33
+ call biosfn_enable_video_addressing
+ jmp int10_end
+int10_test_BL33:
+ cmp bl, 33h
+ jne int10_test_BL34
+ call biosfn_enable_grayscale_summing
+ jmp int10_end
+int10_test_BL34:
+ cmp bl, 34h
+ jne int10_normal
+ call biosfn_enable_cursor_emulation
+ jmp int10_end
+int10_test_101B:
+ cmp ax, 101Bh
+ je int10_normal
+ cmp ah, 10h
+ifndef VBE
+ jne int10_normal
+else
+ jne int10_test_4F
+endif
+ call biosfn_group_10
+ jmp int10_end
+ifdef VBE
+int10_test_4F:
+ cmp ah, 4Fh
+ jne int10_normal
+ cmp al, 3
+ jne int10_test_vbe_05
+ call vbe_biosfn_return_current_mode
+ jmp int10_end
+int10_test_vbe_05:
+ cmp al, 5
+ jne int10_test_vbe_07
+ call vbe_biosfn_display_window_control
+ jmp int10_end
+int10_test_vbe_07:
+ cmp al, 7
+ jne int10_test_vbe_08
+ call vbe_biosfn_set_get_display_start
+ jmp int10_end
+int10_test_vbe_08:
+ cmp al, 8
+ jne int10_test_vbe_09
+ call vbe_biosfn_set_get_dac_palette_format
+ jmp int10_end
+int10_test_vbe_09:
+ cmp al, 9
+ jne int10_test_vbe_0A
+ call vbe_biosfn_set_get_palette_data
+ jmp int10_end
+int10_test_vbe_0A:
+ cmp al, 0Ah
+ jne int10_normal
+ call vbe_biosfn_return_protected_mode_interface
+ jmp int10_end
+endif
+
+int10_normal:
+ push es
+ push ds
+ DO_pusha
+
+;; We have to set ds to access the right data segment
+ push cs
+ pop ds
+ cld
+ call _int10_func
+
+ DO_popa
+ pop ds
+ pop es
+int10_end:
+ popf
+ iret
+
+;;--------------------------------------------------------------------------------------------
+
+biosfn_group_0B:
+ cmp bh, 0
+ je biosfn_set_border_color
+ cmp bh, 1
+ je biosfn_set_palette
+ifdef VGA_DEBUG
+ call _unknown
+endif
+ ret
+biosfn_set_border_color:
+ push ax
+ push bx
+ push cx
+ push dx
+ push ds
+ mov dx, BIOSMEM_SEG
+ mov ds, dx
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+ cmp byte ptr ds:[BIOSMEM_CURRENT_MODE], 3
+ jbe set_border_done
+ mov dx, VGAREG_ACTL_ADDRESS
+ mov al, 00h
+ out dx, al
+ mov al, bl
+ and al, 0Fh
+ test al, 08h
+ jz set_low_border
+ add al, 08h
+set_low_border:
+ out dx, al
+ mov cl, 1
+ and bl, 10h
+set_intensity_loop:
+ mov dx, VGAREG_ACTL_ADDRESS
+ mov al, cl
+ out dx, al
+ mov dx, VGAREG_ACTL_READ_DATA
+ in al, dx
+ and al, 0EFh
+ or al, bl
+ mov dx, VGAREG_ACTL_ADDRESS
+ out dx, al
+ inc cl
+ cmp cl, 4
+ jne set_intensity_loop
+set_border_done:
+ mov al, 20h
+ out dx, al
+ifdef VBOX
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+endif ; VBOX
+ pop ds
+ pop dx
+ pop cx
+ pop bx
+ pop ax
+ ret
+biosfn_set_palette:
+ push ax
+ push bx
+ push cx
+ push dx
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+ mov cl, 01
+ and bl, 01
+set_cga_palette_loop:
+ mov dx, VGAREG_ACTL_ADDRESS
+ mov al, cl
+ out dx, al
+ mov dx, VGAREG_ACTL_READ_DATA
+ in al, dx
+ and al, 0FEh
+ or al, bl
+ mov dx, VGAREG_ACTL_ADDRESS
+ out dx, al
+ inc cl
+ cmp cl, 4
+ jne set_cga_palette_loop
+ mov al, 20h
+ out dx, al
+ifdef VBOX
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+endif ; VBOX
+ pop dx
+ pop cx
+ pop bx
+ pop ax
+ ret
+
+;;--------------------------------------------------------------------------------------------
+
+biosfn_get_video_mode:
+ push ds
+ mov ax, BIOSMEM_SEG
+ mov ds, ax
+ push bx
+ mov bx, BIOSMEM_CURRENT_PAGE
+ mov al, [bx]
+ pop bx
+ mov bh, al
+ push bx
+ mov bx, BIOSMEM_VIDEO_CTL
+ mov ah, [bx]
+ and ah, 80h
+ mov bx, BIOSMEM_CURRENT_MODE
+ mov al, [bx]
+ or al, ah
+ mov bx, BIOSMEM_NB_COLS
+ mov ah, [bx]
+ pop bx
+ pop ds
+ ret
+
+;--------------------------------------------------------------------------------------------
+
+biosfn_group_10:
+ cmp al, 0
+ jne int10_test_1001
+ jmp biosfn_set_single_palette_reg
+int10_test_1001:
+ cmp al, 1
+ jne int10_test_1002
+ jmp biosfn_set_overscan_border_color
+int10_test_1002:
+ cmp al, 2
+ jne int10_test_1003
+ jmp biosfn_set_all_palette_reg
+int10_test_1003:
+ cmp al, 3
+ jne int10_test_1007
+ jmp biosfn_toggle_intensity
+int10_test_1007:
+ cmp al, 7
+ jne int10_test_1008
+ jmp biosfn_get_single_palette_reg
+int10_test_1008:
+ cmp al, 8
+ jne int10_test_1009
+ jmp biosfn_read_overscan_border_color
+int10_test_1009:
+ cmp al, 9
+ jne int10_test_1010
+ jmp biosfn_get_all_palette_reg
+int10_test_1010:
+ cmp al, 10h
+ jne int10_test_1012
+ jmp biosfn_set_single_dac_reg
+int10_test_1012:
+ cmp al, 12h
+ jne int10_test_1013
+ jmp biosfn_set_all_dac_reg
+int10_test_1013:
+ cmp al, 13h
+ jne int10_test_1015
+ jmp biosfn_select_video_dac_color_page
+int10_test_1015:
+ cmp al, 15h
+ jne int10_test_1017
+ jmp biosfn_read_single_dac_reg
+int10_test_1017:
+ cmp al, 17h
+ jne int10_test_1018
+ jmp biosfn_read_all_dac_reg
+int10_test_1018:
+ cmp al, 18h
+ jne int10_test_1019
+ jmp biosfn_set_pel_mask
+int10_test_1019:
+ cmp al, 19h
+ jne int10_test_101A
+ jmp biosfn_read_pel_mask
+int10_test_101A:
+ cmp al, 1Ah
+ jne int10_group_10_unknown
+ jmp biosfn_read_video_dac_state
+int10_group_10_unknown:
+ifdef VGA_DEBUG
+ call _unknown
+endif
+ ret
+
+biosfn_set_single_palette_reg:
+ cmp bl, 14h
+ ja no_actl_reg1
+ push ax
+ push dx
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+ mov dx, VGAREG_ACTL_ADDRESS
+ mov al, bl
+ out dx, al
+ mov al, bh
+ out dx, al
+ mov al, 20h
+ out dx, al
+ifdef VBOX
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+endif ; VBOX
+ pop dx
+ pop ax
+no_actl_reg1:
+ ret
+
+;--------------------------------------------------------------------------------------------
+
+biosfn_set_overscan_border_color:
+ push bx
+ mov bl, 11h
+ call biosfn_set_single_palette_reg
+ pop bx
+ ret
+
+;--------------------------------------------------------------------------------------------
+
+biosfn_set_all_palette_reg:
+ push ax
+ push bx
+ push cx
+ push dx
+ mov bx, dx
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+ mov cl, 0
+ mov dx, VGAREG_ACTL_ADDRESS
+set_palette_loop:
+ mov al, cl
+ out dx, al
+ mov al, es:[bx]
+ out dx, al
+ inc bx
+ inc cl
+ cmp cl, 10h
+ jne set_palette_loop
+ mov al, 11h
+ out dx, al
+ mov al, es:[bx]
+ out dx, al
+ mov al, 20h
+ out dx, al
+ifdef VBOX
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+endif ; VBOX
+ pop dx
+ pop cx
+ pop bx
+ pop ax
+ ret
+
+;;--------------------------------------------------------------------------------------------
+
+biosfn_toggle_intensity:
+ push ax
+ push bx
+ push dx
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+ mov dx, VGAREG_ACTL_ADDRESS
+ mov al, 10h
+ out dx, al
+ mov dx, VGAREG_ACTL_READ_DATA
+ in al, dx
+ and al, 0F7h
+ and bl, 01
+if VBOX_BIOS_CPU gt 8086
+ shl bl, 3
+else
+ shl bl, 1
+ shl bl, 1
+ shl bl, 1
+endif
+ or al, bl
+ mov dx, VGAREG_ACTL_ADDRESS
+ out dx, al
+ mov al, 20h
+ out dx, al
+ifdef VBOX
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+endif ; VBOX
+ pop dx
+ pop bx
+ pop ax
+ ret
+
+;;--------------------------------------------------------------------------------------------
+
+biosfn_get_single_palette_reg:
+ cmp bl, 14h
+ ja no_actl_reg2
+ push ax
+ push dx
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+ mov dx, VGAREG_ACTL_ADDRESS
+ mov al, bl
+ out dx, al
+ mov dx, VGAREG_ACTL_READ_DATA
+ in al, dx
+ mov bh, al
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+ mov dx, VGAREG_ACTL_ADDRESS
+ mov al, 20h
+ out dx, al
+ifdef VBOX
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+endif ; VBOX
+ pop dx
+ pop ax
+no_actl_reg2:
+ ret
+
+;;--------------------------------------------------------------------------------------------
+
+biosfn_read_overscan_border_color:
+ push ax
+ push bx
+ mov bl, 11h
+ call biosfn_get_single_palette_reg
+ mov al, bh
+ pop bx
+ mov bh, al
+ pop ax
+ ret
+
+;;--------------------------------------------------------------------------------------------
+
+biosfn_get_all_palette_reg:
+ push ax
+ push bx
+ push cx
+ push dx
+ mov bx, dx
+ mov cl, 0
+get_palette_loop:
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+ mov dx, VGAREG_ACTL_ADDRESS
+ mov al, cl
+ out dx, al
+ mov dx, VGAREG_ACTL_READ_DATA
+ in al, dx
+ mov es:[bx], al
+ inc bx
+ inc cl
+ cmp cl, 10h
+ jne get_palette_loop
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+ mov dx, VGAREG_ACTL_ADDRESS
+ mov al, 11h
+ out dx, al
+ mov dx, VGAREG_ACTL_READ_DATA
+ in al, dx
+ mov es:[bx], al
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+ mov dx, VGAREG_ACTL_ADDRESS
+ mov al, 20h
+ out dx, al
+ifdef VBOX
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+endif ; VBOX
+ pop dx
+ pop cx
+ pop bx
+ pop ax
+ ret
+
+;;--------------------------------------------------------------------------------------------
+
+biosfn_set_single_dac_reg:
+ push ax
+ push dx
+ mov dx, VGAREG_DAC_WRITE_ADDRESS
+ mov al, bl
+ out dx, al
+ mov dx, VGAREG_DAC_DATA
+ pop ax
+ push ax
+ mov al, ah
+ out dx, al
+ mov al, ch
+ out dx, al
+ mov al, cl
+ out dx, al
+ pop dx
+ pop ax
+ ret
+
+;;--------------------------------------------------------------------------------------------
+
+biosfn_set_all_dac_reg:
+ push ax
+ push bx
+ push cx
+ push dx
+ mov dx, VGAREG_DAC_WRITE_ADDRESS
+ mov al, bl
+ out dx, al
+ pop dx
+ push dx
+ mov bx, dx
+ mov dx, VGAREG_DAC_DATA
+set_dac_loop:
+ mov al, es:[bx]
+ out dx, al
+ inc bx
+ mov al, es:[bx]
+ out dx, al
+ inc bx
+ mov al, es:[bx]
+ out dx, al
+ inc bx
+ dec cx
+ jnz set_dac_loop
+ pop dx
+ pop cx
+ pop bx
+ pop ax
+ ret
+
+;;--------------------------------------------------------------------------------------------
+
+biosfn_select_video_dac_color_page:
+ push ax
+ push bx
+ push dx
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+ mov dx, VGAREG_ACTL_ADDRESS
+ mov al, 10h
+ out dx, al
+ mov dx, VGAREG_ACTL_READ_DATA
+ in al, dx
+ and bl, 01
+ jnz set_dac_page
+ and al, 07Fh
+if VBOX_BIOS_CPU gt 8086
+ shl bh, 7
+else
+ shl bh, 1
+ shl bh, 1
+ shl bh, 1
+ shl bh, 1
+ shl bh, 1
+ shl bh, 1
+ shl bh, 1
+endif
+ or al, bh
+ mov dx, VGAREG_ACTL_ADDRESS
+ out dx, al
+ jmp set_actl_normal
+set_dac_page:
+ push ax
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+ mov dx, VGAREG_ACTL_ADDRESS
+ mov al, 14h
+ out dx, al
+ pop ax
+ and al, 80h
+ jnz set_dac_16_page
+if VBOX_BIOS_CPU gt 8086
+ shl bh, 2
+else
+ shl bh, 1
+ shl bh, 1
+endif
+set_dac_16_page:
+ and bh, 0Fh
+ mov al, bh
+ out dx, al
+set_actl_normal:
+ mov al, 20h
+ out dx, al
+ifdef VBOX
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+endif ; VBOX
+ pop dx
+ pop bx
+ pop ax
+ ret
+
+;;--------------------------------------------------------------------------------------------
+
+biosfn_read_single_dac_reg:
+ push ax
+ push dx
+ mov dx, VGAREG_DAC_READ_ADDRESS
+ mov al, bl
+ out dx, al
+ pop ax
+ mov ah, al
+ mov dx, VGAREG_DAC_DATA
+ in al, dx
+ xchg al, ah
+ push ax
+ in al, dx
+ mov ch, al
+ in al, dx
+ mov cl, al
+ pop dx
+ pop ax
+ ret
+
+;;--------------------------------------------------------------------------------------------
+
+biosfn_read_all_dac_reg:
+ push ax
+ push bx
+ push cx
+ push dx
+ mov dx, VGAREG_DAC_READ_ADDRESS
+ mov al, bl
+ out dx, al
+ pop dx
+ push dx
+ mov bx, dx
+ mov dx, VGAREG_DAC_DATA
+read_dac_loop:
+ in al, dx
+ mov es:[bx], al
+ inc bx
+ in al, dx
+ mov es:[bx], al
+ inc bx
+ in al, dx
+ mov es:[bx], al
+ inc bx
+ dec cx
+ jnz read_dac_loop
+ pop dx
+ pop cx
+ pop bx
+ pop ax
+ ret
+
+;;--------------------------------------------------------------------------------------------
+
+biosfn_set_pel_mask:
+ push ax
+ push dx
+ mov dx, VGAREG_PEL_MASK
+ mov al, bl
+ out dx, al
+ pop dx
+ pop ax
+ ret
+
+;;--------------------------------------------------------------------------------------------
+
+biosfn_read_pel_mask:
+ push ax
+ push dx
+ mov dx, VGAREG_PEL_MASK
+ in al, dx
+ mov bl, al
+ pop dx
+ pop ax
+ ret
+
+;;--------------------------------------------------------------------------------------------
+
+biosfn_read_video_dac_state:
+ push ax
+ push dx
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+ mov dx, VGAREG_ACTL_ADDRESS
+ mov al, 10h
+ out dx, al
+ mov dx, VGAREG_ACTL_READ_DATA
+ in al, dx
+ mov bl, al
+if VBOX_BIOS_CPU gt 8086
+ shr bl, 7
+else
+ shr bl, 1
+ shr bl, 1
+ shr bl, 1
+ shr bl, 1
+ shr bl, 1
+ shr bl, 1
+ shr bl, 1
+endif
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+ mov dx, VGAREG_ACTL_ADDRESS
+ mov al, 14h
+ out dx, al
+ mov dx, VGAREG_ACTL_READ_DATA
+ in al, dx
+ mov bh, al
+ and bh, 0Fh
+ test bl, 01
+ jnz get_dac_16_page
+if VBOX_BIOS_CPU gt 8086
+ shr bh, 2
+else
+ shr bh, 1
+ shr bh, 1
+endif
+get_dac_16_page:
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+ mov dx, VGAREG_ACTL_ADDRESS
+ mov al, 20h
+ out dx, al
+ifdef VBOX
+ mov dx, VGAREG_ACTL_RESET
+ in al, dx
+endif ; VBOX
+ pop dx
+ pop ax
+ ret
+
+;;--------------------------------------------------------------------------------------------
+
+biosfn_set_text_block_specifier:
+ push ax
+ push dx
+ mov dx, VGAREG_SEQU_ADDRESS
+ mov ah, bl
+ mov al, 03
+ out dx, ax
+ pop dx
+ pop ax
+ ret
+
+;;--------------------------------------------------------------------------------------------
+
+biosfn_get_ega_info:
+ push ds
+ push ax
+ mov ax, BIOSMEM_SEG
+ mov ds, ax
+ xor ch, ch
+ mov bx, BIOSMEM_SWITCHES
+ mov cl, [bx]
+ and cl, 0Fh
+ mov bx, BIOSMEM_CRTC_ADDRESS
+ mov ax, [bx]
+ mov bx, 0003h
+ cmp ax, VGAREG_MDA_CRTC_ADDRESS
+ jne mode_ega_color
+ mov bh, 01
+mode_ega_color:
+ pop ax
+ pop ds
+ ret
+
+;;--------------------------------------------------------------------------------------------
+
+biosfn_select_vert_res:
+
+; res : 00 200 lines, 01 350 lines, 02 400 lines
+
+ push ds
+ push bx
+ push dx
+ mov dl, al
+ mov ax, BIOSMEM_SEG
+ mov ds, ax
+ mov bx, BIOSMEM_MODESET_CTL
+ mov al, [bx]
+ mov bx, BIOSMEM_SWITCHES
+ mov ah, [bx]
+ cmp dl, 1
+ je vert_res_350
+ jb vert_res_200
+ cmp dl, 2
+ je vert_res_400
+ifdef VGA_DEBUG
+ mov al, dl
+ xor ah, ah
+ push ax
+ mov bx, msg_vert_res
+ push bx
+ call _printf
+ add sp, 4
+endif
+ jmp set_retcode
+vert_res_400:
+
+ ; reset modeset ctl bit 7 and set bit 4
+ ; set switches bit 3-0 to 09
+
+ and al, 07Fh
+ or al, 010h
+ and ah, 0F0h
+ or ah, 009h
+ jnz set_vert_res
+vert_res_350:
+
+ ; reset modeset ctl bit 7 and bit 4
+ ; set switches bit 3-0 to 09
+
+ and al, 06Fh
+ and ah, 0F0h
+ or ah, 009h
+ jnz set_vert_res
+vert_res_200:
+
+ ; set modeset ctl bit 7 and reset bit 4
+ ; set switches bit 3-0 to 08
+
+ and al, 0EFh
+ or al, 080h
+ and ah, 0F0h
+ or ah, 008h
+set_vert_res:
+ mov bx, BIOSMEM_MODESET_CTL
+ mov [bx], al
+ mov bx, BIOSMEM_SWITCHES
+ mov [bx], ah
+set_retcode:
+ mov ax, 1212h
+ pop dx
+ pop bx
+ pop ds
+ ret
+
+ifdef VGA_DEBUG
+msg_vert_res:
+db "Select vert res (%02x) was discarded", 13, 10, 0
+endif
+
+
+biosfn_enable_default_palette_loading:
+ push ds
+ push bx
+ push dx
+ mov dl, al
+ and dl, 01
+if VBOX_BIOS_CPU gt 8086
+ shl dl, 3
+else
+ shl dl, 1
+ shl dl, 1
+ shl dl, 1
+endif
+ mov ax, BIOSMEM_SEG
+ mov ds, ax
+ mov bx, BIOSMEM_MODESET_CTL
+ mov al, [bx]
+ and al, 0F7h
+ or al, dl
+ mov [bx], al
+ mov ax, 1212h
+ pop dx
+ pop bx
+ pop ds
+ ret
+
+
+biosfn_enable_video_addressing:
+ push bx
+ push dx
+ mov bl, al
+ and bl, 01
+ xor bl, 01
+ shl bl, 1
+ mov dx, VGAREG_READ_MISC_OUTPUT
+ in al, dx
+ and al, 0FDh
+ or al, bl
+ mov dx, VGAREG_WRITE_MISC_OUTPUT
+ out dx, al
+ mov ax, 1212h
+ pop dx
+ pop bx
+ ret
+
+
+biosfn_enable_grayscale_summing:
+ push ds
+ push bx
+ push dx
+ mov dl, al
+ and dl, 01h
+ xor dl, 01h
+ shl dl, 1
+ mov ax, BIOSMEM_SEG
+ mov ds, ax
+ mov bx, BIOSMEM_MODESET_CTL
+ mov al, [bx]
+ and al, 0FDh
+ or al, dl
+ mov [bx], al
+ mov ax, 1212h
+ pop dx
+ pop bx
+ pop ds
+ ret
+
+
+biosfn_enable_cursor_emulation:
+ push ds
+ push bx
+ push dx
+ mov dl, al
+ and dl, 01
+ xor dl, 01
+ mov ax, BIOSMEM_SEG
+ mov ds, ax
+ mov bx, BIOSMEM_MODESET_CTL
+ mov al, [bx]
+ and al, 0FEh
+ or al, dl
+ mov [bx], al
+ mov ax, 1212h
+ pop dx
+ pop bx
+ pop ds
+ ret
+
+;;--------------------------------------------------------------------------------------------
+
+biosfn_group_1A:
+ cmp al, 0
+ je biosfn_read_display_code
+ cmp al, 1
+ je biosfn_set_display_code
+ifdef VGA_DEBUG
+ call _unknown
+endif
+ ret
+biosfn_read_display_code:
+ push ds
+ push ax
+ mov ax, BIOSMEM_SEG
+ mov ds, ax
+ mov bx, BIOSMEM_DCC_INDEX
+ mov al, [bx]
+ mov bl, al
+ xor bh, bh
+ pop ax
+ mov al, ah
+ pop ds
+ ret
+biosfn_set_display_code:
+ push ds
+ push ax
+ push bx
+ mov ax, BIOSMEM_SEG
+ mov ds, ax
+ mov ax, bx
+ mov bx, BIOSMEM_DCC_INDEX
+ mov [bx], al
+ifdef VGA_DEBUG
+ mov al, ah
+ xor ah, ah
+ push ax
+ mov bx, msg_alt_dcc
+ push bx
+ call _printf
+ add sp, 4
+endif
+ pop bx
+ pop ax
+ mov al, ah
+ pop ds
+ ret
+
+ifdef VGA_DEBUG
+msg_alt_dcc:
+db "Alternate Display code (%02x) was discarded", 13, 10, 0
+endif
+
+VGAROM ends
+
+ end