1
// ============================================================================================
3
// Copyright (C) 2002 Jeroen Janssen
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.
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.
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
19
// ============================================================================================
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.
24
// ============================================================================================
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
29
// ============================================================================================
34
// disable VESA/VBE2 check in vbe info
35
//#define VBE2_NO_VESA_CHECK
39
#include "vbetables.h"
41
// The current OEM Software Revision of this VBE Bios
42
#define VBE_OEM_SOFTWARE_REV 0x0002;
44
extern char vbebios_copyright;
45
extern char vbebios_vendor_name;
46
extern char vbebios_product_name;
47
extern char vbebios_product_revision;
50
// FIXME: 'merge' these (c) etc strings with the vgabios.c strings?
52
.ascii "Bochs/Plex86 VBE(C) 2003 http://savannah.nongnu.org/projects/vgabios/"
56
.ascii "Bochs/Plex86 Developers"
59
_vbebios_product_name:
60
.ascii "Bochs/Plex86 VBE Adapter"
63
_vbebios_product_revision:
68
.ascii "Bochs VBE Display Adapter enabled"
73
_no_vbebios_info_string:
74
.ascii "NO Bochs VBE Support available!"
79
#if defined(USE_BX_INFO) || defined(DEBUG)
81
.ascii "VBE Bios $Id$"
87
dw vesa_pm_set_window - vesa_pm_start
88
dw vesa_pm_set_display_start - vesa_pm_start
89
dw vesa_pm_unimplemented - vesa_pm_start
90
dw vesa_pm_io_ports_table - vesa_pm_start
91
vesa_pm_io_ports_table:
92
dw VBE_DISPI_IOPORT_INDEX
93
dw VBE_DISPI_IOPORT_INDEX + 1
94
dw VBE_DISPI_IOPORT_DATA
95
dw VBE_DISPI_IOPORT_DATA + 1
102
je vesa_pm_set_display_window1
105
vesa_pm_set_display_window1:
109
mov dx, # VBE_DISPI_IOPORT_INDEX
110
mov ax, # VBE_DISPI_INDEX_BANK
113
mov dx, # VBE_DISPI_IOPORT_DATA
125
vesa_pm_set_display_start:
127
je vesa_pm_set_display_start1
129
je vesa_pm_set_display_start1
132
vesa_pm_set_display_start1:
133
; convert offset to (X, Y) coordinate
134
; (would be simpler to change Bochs VBE API...)
147
mov dx, # VBE_DISPI_IOPORT_INDEX
148
mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH
150
mov dx, # VBE_DISPI_IOPORT_DATA
154
mov dx, # VBE_DISPI_IOPORT_INDEX
155
mov ax, # VBE_DISPI_INDEX_BPP
157
mov dx, # VBE_DISPI_IOPORT_DATA
186
mov dx, # VBE_DISPI_IOPORT_INDEX
187
mov ax, # VBE_DISPI_INDEX_X_OFFSET
190
mov dx, # VBE_DISPI_IOPORT_DATA
197
mov dx, # VBE_DISPI_IOPORT_INDEX
198
mov ax, # VBE_DISPI_INDEX_Y_OFFSET
201
mov dx, # VBE_DISPI_IOPORT_DATA
213
vesa_pm_unimplemented:
219
; DISPI ioport functions
223
mov dx, # VBE_DISPI_IOPORT_INDEX
224
mov ax, # VBE_DISPI_INDEX_ID
226
mov dx, # VBE_DISPI_IOPORT_DATA
234
mov dx, # VBE_DISPI_IOPORT_INDEX
235
mov ax, # VBE_DISPI_INDEX_ID
238
mov dx, # VBE_DISPI_IOPORT_DATA
244
static void dispi_set_xres(xres)
253
mov dx, # VBE_DISPI_IOPORT_INDEX
254
mov ax, # VBE_DISPI_INDEX_XRES
256
mov dx, # VBE_DISPI_IOPORT_DATA
266
static void dispi_set_yres(yres)
269
outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_YRES);
270
outw(VBE_DISPI_IOPORT_DATA,yres);
273
static void dispi_set_bpp(bpp)
276
outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_BPP);
277
outw(VBE_DISPI_IOPORT_DATA,bpp);
281
; AL = bits per pixel / AH = bytes per pixel
284
mov dx, # VBE_DISPI_IOPORT_INDEX
285
mov ax, # VBE_DISPI_INDEX_BPP
287
mov dx, # VBE_DISPI_IOPORT_DATA
298
; get display capabilities
303
call dispi_get_enable
305
or ax, # VBE_DISPI_GETCAPS
306
call _dispi_set_enable
307
mov dx, # VBE_DISPI_IOPORT_INDEX
308
mov ax, # VBE_DISPI_INDEX_XRES
310
mov dx, # VBE_DISPI_IOPORT_DATA
314
call _dispi_set_enable
323
call dispi_get_enable
325
or ax, # VBE_DISPI_GETCAPS
326
call _dispi_set_enable
327
mov dx, # VBE_DISPI_IOPORT_INDEX
328
mov ax, # VBE_DISPI_INDEX_BPP
330
mov dx, # VBE_DISPI_IOPORT_DATA
334
call _dispi_set_enable
343
mov dx, # VBE_DISPI_IOPORT_INDEX
344
mov ax, # VBE_DISPI_INDEX_ENABLE
347
mov dx, # VBE_DISPI_IOPORT_DATA
354
mov dx, # VBE_DISPI_IOPORT_INDEX
355
mov ax, # VBE_DISPI_INDEX_ENABLE
357
mov dx, # VBE_DISPI_IOPORT_DATA
365
mov dx, # VBE_DISPI_IOPORT_INDEX
366
mov ax, # VBE_DISPI_INDEX_BANK
369
mov dx, # VBE_DISPI_IOPORT_DATA
376
mov dx, # VBE_DISPI_IOPORT_INDEX
377
mov ax, # VBE_DISPI_INDEX_BANK
379
mov dx, # VBE_DISPI_IOPORT_DATA
385
static void dispi_set_bank_farcall()
389
je dispi_set_bank_farcall_get
391
jnz dispi_set_bank_farcall_error
395
mov ax,# VBE_DISPI_INDEX_BANK
396
mov dx,# VBE_DISPI_IOPORT_INDEX
399
mov dx,# VBE_DISPI_IOPORT_DATA
404
jne dispi_set_bank_farcall_error
407
dispi_set_bank_farcall_get:
408
mov ax,# VBE_DISPI_INDEX_BANK
409
mov dx,# VBE_DISPI_IOPORT_INDEX
411
mov dx,# VBE_DISPI_IOPORT_DATA
415
dispi_set_bank_farcall_error:
425
mov dx, # VBE_DISPI_IOPORT_INDEX
426
mov ax, # VBE_DISPI_INDEX_X_OFFSET
429
mov dx, # VBE_DISPI_IOPORT_DATA
436
mov dx, # VBE_DISPI_IOPORT_INDEX
437
mov ax, # VBE_DISPI_INDEX_X_OFFSET
439
mov dx, # VBE_DISPI_IOPORT_DATA
447
mov dx, # VBE_DISPI_IOPORT_INDEX
448
mov ax, # VBE_DISPI_INDEX_Y_OFFSET
451
mov dx, # VBE_DISPI_IOPORT_DATA
458
mov dx, # VBE_DISPI_IOPORT_INDEX
459
mov ax, # VBE_DISPI_INDEX_Y_OFFSET
461
mov dx, # VBE_DISPI_IOPORT_DATA
477
mov dx, # VGAREG_VGA_CRTC_ADDRESS
486
dispi_set_virt_width:
487
call vga_set_virt_width
490
mov dx, # VBE_DISPI_IOPORT_INDEX
491
mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH
494
mov dx, # VBE_DISPI_IOPORT_DATA
499
dispi_get_virt_width:
501
mov dx, # VBE_DISPI_IOPORT_INDEX
502
mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH
504
mov dx, # VBE_DISPI_IOPORT_DATA
509
dispi_get_virt_height:
511
mov dx, # VBE_DISPI_IOPORT_INDEX
512
mov ax, # VBE_DISPI_INDEX_VIRT_HEIGHT
514
mov dx, # VBE_DISPI_IOPORT_DATA
523
; set CRT X resolution
524
mov dx, # VBE_DISPI_IOPORT_INDEX
525
mov ax, # VBE_DISPI_INDEX_XRES
527
mov dx, # VBE_DISPI_IOPORT_DATA
530
mov dx, # VGAREG_VGA_CRTC_ADDRESS
541
call vga_set_virt_width
543
; set CRT Y resolution
544
mov dx, # VBE_DISPI_IOPORT_INDEX
545
mov ax, # VBE_DISPI_INDEX_YRES
547
mov dx, # VBE_DISPI_IOPORT_DATA
551
mov dx, # VGAREG_VGA_CRTC_ADDRESS
572
mov dx, # VGAREG_VGA_CRTC_ADDRESS
577
mov dx, # VGAREG_VGA_CRTC_DATA
581
mov dx, # VGAREG_ACTL_RESET
583
mov dx, # VGAREG_ACTL_ADDRESS
586
mov dx, # VGAREG_ACTL_READ_DATA
589
mov dx, # VGAREG_ACTL_ADDRESS
593
mov dx, # VGAREG_GRDC_ADDRESS
596
mov dx, # VGAREG_SEQU_ADDRESS
600
; settings for >= 8bpp
601
mov dx, # VBE_DISPI_IOPORT_INDEX
602
mov ax, # VBE_DISPI_INDEX_BPP
604
mov dx, # VBE_DISPI_IOPORT_DATA
608
mov dx, # VGAREG_VGA_CRTC_ADDRESS
611
mov dx, # VGAREG_VGA_CRTC_DATA
615
mov dx, # VGAREG_ACTL_RESET
617
mov dx, # VGAREG_ACTL_ADDRESS
620
mov dx, # VGAREG_ACTL_READ_DATA
623
mov dx, # VGAREG_ACTL_ADDRESS
627
mov dx, # VGAREG_SEQU_ADDRESS
630
mov dx, # VGAREG_SEQU_DATA
634
mov dx, # VGAREG_GRDC_ADDRESS
637
mov dx, # VGAREG_GRDC_DATA
649
// ModeInfo helper function
650
static ModeInfoListItem* mode_info_find_mode(mode, using_lfb)
651
Bit16u mode; Boolean using_lfb;
653
ModeInfoListItem *cur_info=&mode_info_list;
655
while (cur_info->mode != VBE_VESA_MODE_END_OF_LIST)
657
if (cur_info->mode == mode)
663
else if (cur_info->info.ModeAttributes & VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE)
683
; Has VBE display - Returns true if VBE display detected
685
_vbe_has_vbe_display:
688
mov ax, # BIOSMEM_SEG
690
mov bx, # BIOSMEM_VBE_FLAG
698
; VBE Init - Initialise the Vesa Bios Extension Code
699
; This function does a sanity check on the host side display code interface.
702
mov ax, # VBE_DISPI_ID0
705
cmp ax, # VBE_DISPI_ID0
709
mov ax, # BIOSMEM_SEG
711
mov bx, # BIOSMEM_VBE_FLAG
716
mov ax, # VBE_DISPI_ID5
719
#if defined(USE_BX_INFO) || defined(DEBUG)
720
mov bx, #msg_vbe_init
728
; VBE Display Info - Display information on screen about the VBE
731
call _vbe_has_vbe_display
736
mov si, #_vbebios_info_string
741
mov si, #_no_vbebios_info_string
744
; helper function for memory size calculation
751
mul eax, dword ptr [di]
757
/** Function 00h - Return VBE Controller Information
761
* ES:DI = Pointer to buffer in which to place VbeInfoBlock structure
762
* (VbeSignature should be VBE2 when VBE 2.0 information is desired and
763
* the info block is 512 bytes in size)
765
* AX = VBE Return Status
768
void vbe_biosfn_return_controller_information(AX, ES, DI)
769
Bit16u *AX;Bit16u ES;Bit16u DI;
772
VbeInfoBlock vbe_info_block;
779
ModeInfoListItem *cur_info=&mode_info_list;
781
status = read_word(ss, AX);
784
printf("VBE vbe_biosfn_return_vbe_info ES%x DI%x AX%x\n",ES,DI,status);
788
#ifdef VBE2_NO_VESA_CHECK
790
// get vbe_info_block into local variable
791
memcpyb(ss, &vbe_info_block, ES, DI, sizeof(vbe_info_block));
793
// check for VBE2 signature
794
if (((vbe_info_block.VbeSignature[0] == 'V') &&
795
(vbe_info_block.VbeSignature[1] == 'B') &&
796
(vbe_info_block.VbeSignature[2] == 'E') &&
797
(vbe_info_block.VbeSignature[3] == '2')) ||
799
((vbe_info_block.VbeSignature[0] == 'V') &&
800
(vbe_info_block.VbeSignature[1] == 'E') &&
801
(vbe_info_block.VbeSignature[2] == 'S') &&
802
(vbe_info_block.VbeSignature[3] == 'A')) )
806
printf("VBE correct VESA/VBE2 signature found\n");
812
vbe_info_block.VbeSignature[0] = 'V';
813
vbe_info_block.VbeSignature[1] = 'E';
814
vbe_info_block.VbeSignature[2] = 'S';
815
vbe_info_block.VbeSignature[3] = 'A';
817
// VBE Version supported
818
vbe_info_block.VbeVersion = 0x0200;
821
vbe_info_block.OemStringPtr_Seg = 0xc000;
822
vbe_info_block.OemStringPtr_Off = &vbebios_copyright;
825
vbe_info_block.Capabilities[0] = VBE_CAPABILITY_8BIT_DAC;
826
vbe_info_block.Capabilities[1] = 0;
827
vbe_info_block.Capabilities[2] = 0;
828
vbe_info_block.Capabilities[3] = 0;
830
// VBE Video Mode Pointer (dynamicly generated from the mode_info_list)
831
vbe_info_block.VideoModePtr_Seg= ES ;
832
vbe_info_block.VideoModePtr_Off= DI + 34;
834
// VBE Total Memory (in 64k blocks)
835
outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIDEO_MEMORY_64K);
836
vbe_info_block.TotalMemory = inw(VBE_DISPI_IOPORT_DATA);
841
vbe_info_block.OemSoftwareRev = VBE_OEM_SOFTWARE_REV;
842
vbe_info_block.OemVendorNamePtr_Seg = 0xc000;
843
vbe_info_block.OemVendorNamePtr_Off = &vbebios_vendor_name;
844
vbe_info_block.OemProductNamePtr_Seg = 0xc000;
845
vbe_info_block.OemProductNamePtr_Off = &vbebios_product_name;
846
vbe_info_block.OemProductRevPtr_Seg = 0xc000;
847
vbe_info_block.OemProductRevPtr_Off = &vbebios_product_revision;
849
// copy updates in vbe_info_block back
850
memcpyb(ES, DI, ss, &vbe_info_block, sizeof(vbe_info_block));
854
// copy updates in vbe_info_block back (VBE 1.x compatibility)
855
memcpyb(ES, DI, ss, &vbe_info_block, 256);
860
size_64k = (Bit16u)((Bit32u)cur_info->info.XResolution * cur_info->info.XResolution * cur_info->info.BitsPerPixel) >> 19;
862
if ((cur_info->info.XResolution <= dispi_get_max_xres()) &&
863
(cur_info->info.BitsPerPixel <= dispi_get_max_bpp()) &&
864
(size_64k <= vbe_info_block.TotalMemory)) {
866
printf("VBE found mode %x => %x\n", cur_info->mode,cur_mode);
868
write_word(ES, DI + cur_ptr, cur_info->mode);
873
printf("VBE mode %x (xres=%x / bpp=%02x) not supported \n", cur_info->mode,cur_info->info.XResolution,cur_info->info.BitsPerPixel);
877
} while (cur_info->mode != VBE_VESA_MODE_END_OF_LIST);
879
// Add vesa mode list terminator
880
write_word(ES, DI + cur_ptr, cur_info->mode);
884
write_word(ss, AX, result);
888
/** Function 01h - Return VBE Mode Information
893
* ES:DI = Pointer to buffer in which to place ModeInfoBlock structure
895
* AX = VBE Return Status
898
void vbe_biosfn_return_mode_information(AX, CX, ES, DI)
899
Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI;
901
Bit16u result=0x0100;
904
ModeInfoListItem *cur_info;
909
printf("VBE vbe_biosfn_return_mode_information ES%x DI%x CX%x\n",ES,DI,CX);
912
using_lfb=((CX & VBE_MODE_LINEAR_FRAME_BUFFER) == VBE_MODE_LINEAR_FRAME_BUFFER);
916
cur_info = mode_info_find_mode(CX, using_lfb, &cur_info);
921
printf("VBE found mode %x\n",CX);
923
memsetb(ss, &info, 0, sizeof(ModeInfoBlock));
924
memcpyb(ss, &info, 0xc000, &(cur_info->info), sizeof(ModeInfoBlockCompact));
926
info.NumberOfBanks = 1;
929
lfb_addr = pci_get_lfb_addr(PCI_VID);
934
info.PhysBasePtr = ((Bit32u)lfb_addr << 16);
936
if (info.WinAAttributes & VBE_WINDOW_ATTRIBUTE_RELOCATABLE) {
937
info.WinFuncPtr = 0xC0000000UL;
938
*(Bit16u *)&(info.WinFuncPtr) = (Bit16u)(dispi_set_bank_farcall);
946
printf("VBE *NOT* found mode %x\n",CX);
953
// copy updates in mode_info_block back
954
memcpyb(ES, DI, ss, &info, sizeof(info));
957
write_word(ss, AX, result);
960
/** Function 02h - Set VBE Mode
964
* BX = Desired Mode to set
965
* ES:DI = Pointer to CRTCInfoBlock structure
967
* AX = VBE Return Status
970
void vbe_biosfn_set_mode(AX, BX, ES, DI)
971
Bit16u *AX;Bit16u BX; Bit16u ES;Bit16u DI;
973
Bit16u ss = get_SS();
975
ModeInfoListItem *cur_info;
980
using_lfb=((BX & VBE_MODE_LINEAR_FRAME_BUFFER) == VBE_MODE_LINEAR_FRAME_BUFFER);
981
lfb_flag=using_lfb?VBE_DISPI_LFB_ENABLED:0;
982
no_clear=((BX & VBE_MODE_PRESERVE_DISPLAY_MEMORY) == VBE_MODE_PRESERVE_DISPLAY_MEMORY)?VBE_DISPI_NOCLEARMEM:0;
986
//result=read_word(ss,AX);
988
// check for non vesa mode
989
if (BX<VBE_MODE_VESA_DEFINED)
993
dispi_set_enable(VBE_DISPI_DISABLED);
994
// call the vgabios in order to set the video mode
995
// this allows for going back to textmode with a VBE call (some applications expect that to work)
998
biosfn_set_video_mode(mode);
1002
cur_info = mode_info_find_mode(BX, using_lfb, &cur_info);
1007
printf("VBE found mode %x, setting:\n", BX);
1008
printf("\txres%x yres%x bpp%x\n",
1009
cur_info->info.XResolution,
1010
cur_info->info.YResolution,
1011
cur_info->info.BitsPerPixel);
1014
// first disable current mode (when switching between vesa modi)
1015
dispi_set_enable(VBE_DISPI_DISABLED);
1017
if (cur_info->info.BitsPerPixel == 4)
1019
biosfn_set_video_mode(0x6a);
1022
dispi_set_bpp(cur_info->info.BitsPerPixel);
1023
dispi_set_xres(cur_info->info.XResolution);
1024
dispi_set_yres(cur_info->info.YResolution);
1026
dispi_set_enable(VBE_DISPI_ENABLED | no_clear | lfb_flag);
1029
write_word(BIOSMEM_SEG,BIOSMEM_VBE_MODE,BX);
1030
write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60 | no_clear));
1037
printf("VBE *NOT* found mode %x\n" , BX);
1041
// FIXME: redirect non VBE modi to normal VGA bios operation
1042
// (switch back to VGA mode
1047
write_word(ss, AX, result);
1050
/** Function 03h - Return Current VBE Mode
1055
* AX = VBE Return Status
1056
* BX = Current VBE Mode
1060
vbe_biosfn_return_current_mode:
1062
mov ax, # BIOSMEM_SEG
1064
call dispi_get_enable
1065
and ax, # VBE_DISPI_ENABLED
1067
mov bx, # BIOSMEM_VBE_MODE
1072
mov bx, # BIOSMEM_CURRENT_MODE
1083
Bit16u vbe_biosfn_read_video_state_size()
1088
void vbe_biosfn_save_video_state(ES, BX)
1089
Bit16u ES; Bit16u BX;
1093
outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE);
1094
enable = inw(VBE_DISPI_IOPORT_DATA);
1095
write_word(ES, BX, enable);
1097
if (!(enable & VBE_DISPI_ENABLED))
1099
for(i = VBE_DISPI_INDEX_XRES; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) {
1100
if (i != VBE_DISPI_INDEX_ENABLE) {
1101
outw(VBE_DISPI_IOPORT_INDEX, i);
1102
write_word(ES, BX, inw(VBE_DISPI_IOPORT_DATA));
1109
void vbe_biosfn_restore_video_state(ES, BX)
1110
Bit16u ES; Bit16u BX;
1114
enable = read_word(ES, BX);
1117
if (!(enable & VBE_DISPI_ENABLED)) {
1118
outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE);
1119
outw(VBE_DISPI_IOPORT_DATA, enable);
1121
outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES);
1122
outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX));
1124
outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES);
1125
outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX));
1127
outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_BPP);
1128
outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX));
1130
outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE);
1131
outw(VBE_DISPI_IOPORT_DATA, enable);
1133
for(i = VBE_DISPI_INDEX_BANK; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) {
1134
outw(VBE_DISPI_IOPORT_INDEX, i);
1135
outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX));
1141
/** Function 04h - Save/Restore State
1145
* DL = 00h Return Save/Restore State buffer size
1148
* CX = Requested states
1149
* ES:BX = Pointer to buffer (if DL <> 00h)
1151
* AX = VBE Return Status
1152
* BX = Number of 64-byte blocks to hold the state buffer (if DL=00h)
1155
void vbe_biosfn_save_restore_state(AX, CX, DX, ES, BX)
1156
Bit16u *AX; Bit16u CX; Bit16u DX; Bit16u ES; Bit16u *BX;
1164
val = biosfn_read_video_state_size2(CX);
1166
printf("VGA state size=%x\n", val);
1169
val += vbe_biosfn_read_video_state_size();
1170
write_word(ss, BX, val);
1173
val = read_word(ss, BX);
1174
val = biosfn_save_video_state(CX, ES, val);
1176
printf("VGA save_state offset=%x\n", val);
1179
vbe_biosfn_save_video_state(ES, val);
1182
val = read_word(ss, BX);
1183
val = biosfn_restore_video_state(CX, ES, val);
1185
printf("VGA restore_state offset=%x\n", val);
1188
vbe_biosfn_restore_video_state(ES, val);
1195
write_word(ss, AX, result);
1198
/** Function 05h - Display Window Control
1202
* (16-bit) BH = 00h Set memory window
1203
* = 01h Get memory window
1204
* BL = Window number
1207
* DX = Window number in video memory in window
1208
* granularity units (Set Memory Window only)
1210
* If this function is called while in a linear frame buffer mode,
1211
* this function must fail with completion code AH=03h
1214
* AX = VBE Return Status
1215
* DX = Window number in window granularity units
1216
* (Get Memory Window only)
1219
vbe_biosfn_display_window_control:
1223
je get_display_window
1224
jb set_display_window
1229
call _dispi_set_bank
1246
/** Function 06h - Set/Get Logical Scan Line Length
1250
* BL = 00h Set Scan Line Length in Pixels
1251
* = 01h Get Scan Line Length
1252
* = 02h Set Scan Line Length in Bytes
1253
* = 03h Get Maximum Scan Line Length
1254
* CX = If BL=00h Desired Width in Pixels
1255
* If BL=02h Desired Width in Bytes
1256
* (Ignored for Get Functions)
1259
* AX = VBE Return Status
1260
* BX = Bytes Per Scan Line
1261
* CX = Actual Pixels Per Scan Line
1262
* (truncated to nearest complete pixel)
1263
* DX = Maximum Number of Scan Lines
1266
vbe_biosfn_set_get_logical_scan_line_length:
1269
je get_logical_scan_line_length
1271
je set_logical_scan_line_bytes
1272
jb set_logical_scan_line_pixels
1275
set_logical_scan_line_bytes:
1288
set_logical_scan_line_pixels:
1289
call dispi_set_virt_width
1290
get_logical_scan_line_length:
1294
call dispi_get_virt_width
1303
call dispi_get_virt_height
1310
/** Function 07h - Set/Get Display Start
1314
* BH = 00h Reserved and must be 00h
1315
* BL = 00h Set Display Start
1316
* = 01h Get Display Start
1317
* = 02h Schedule Display Start (Alternate)
1318
* = 03h Schedule Stereoscopic Display Start
1319
* = 04h Get Scheduled Display Start Status
1320
* = 05h Enable Stereoscopic Mode
1321
* = 06h Disable Stereoscopic Mode
1322
* = 80h Set Display Start during Vertical Retrace
1323
* = 82h Set Display Start during Vertical Retrace (Alternate)
1324
* = 83h Set Stereoscopic Display Start during Vertical Retrace
1325
* ECX = If BL=02h/82h Display Start Address in bytes
1326
* If BL=03h/83h Left Image Start Address in bytes
1327
* EDX = If BL=03h/83h Right Image Start Address in bytes
1328
* CX = If BL=00h/80h First Displayed Pixel In Scan Line
1329
* DX = If BL=00h/80h First Displayed Scan Line
1332
* AX = VBE Return Status
1333
* BH = If BL=01h Reserved and will be 0
1334
* CX = If BL=01h First Displayed Pixel In Scan Line
1335
* If BL=04h 0 if flip has not occurred, not 0 if it has
1336
* DX = If BL=01h First Displayed Scan Line
1339
* BH = 00h Reserved and must be 00h
1340
* BL = 00h Set Display Start
1341
* = 80h Set Display Start during Vertical Retrace
1342
* CX = Bits 0-15 of display start address
1343
* DX = Bits 16-31 of display start address
1344
* ES = Selector for memory mapped registers
1347
vbe_biosfn_set_get_display_start:
1349
je set_display_start
1351
je get_display_start
1352
jb set_display_start
1357
call dispi_set_x_offset
1359
call dispi_set_y_offset
1363
call dispi_get_x_offset
1365
call dispi_get_y_offset
1373
/** Function 08h - Set/Get Dac Palette Format
1377
* BL = 00h set DAC palette width
1378
* = 01h get DAC palette width
1379
* BH = If BL=00h: desired number of bits per primary color
1381
* AX = VBE Return Status
1382
* BH = current number of bits per primary color (06h = standard VGA)
1385
vbe_biosfn_set_get_dac_palette_format:
1387
je get_dac_palette_format
1388
jb set_dac_palette_format
1391
set_dac_palette_format:
1392
call dispi_get_enable
1396
jne vbe_08_unsupported
1397
or ax, # VBE_DISPI_8BIT_DAC
1400
and ax, #~ VBE_DISPI_8BIT_DAC
1402
call _dispi_set_enable
1403
get_dac_palette_format:
1405
call dispi_get_enable
1406
and ax, # VBE_DISPI_8BIT_DAC
1418
/** Function 09h - Set/Get Palette Data
1423
* AX = VBE Return Status
1425
* FIXME: incomplete API description, Input & Output
1427
void vbe_biosfn_set_get_palette_data(AX)
1431
/** Function 0Ah - Return VBE Protected Mode Interface
1432
* Input: AX = 4F0Ah VBE 2.0 Protected Mode Interface
1433
* BL = 00h Return protected mode table
1436
* Output: AX = Status
1437
* ES = Real Mode Segment of Table
1438
* DI = Offset of Table
1439
* CX = Length of Table including protected mode code
1440
* (for copying purposes)
1443
vbe_biosfn_return_protected_mode_interface:
1448
mov di, # vesa_pm_start
1449
mov cx, # vesa_pm_end